openc3 5.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (307) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +18 -0
  3. data/Guardfile +35 -0
  4. data/LICENSE.txt +727 -0
  5. data/README.md +37 -0
  6. data/Rakefile +131 -0
  7. data/bin/cstol_converter +1178 -0
  8. data/bin/openc3cli +531 -0
  9. data/bin/rubysloc +139 -0
  10. data/data/config/_array_params.yaml +23 -0
  11. data/data/config/_id_items.yaml +24 -0
  12. data/data/config/_id_params.yaml +58 -0
  13. data/data/config/_interfaces.yaml +214 -0
  14. data/data/config/_interfaces.yaml.err +1017 -0
  15. data/data/config/_items.yaml +20 -0
  16. data/data/config/_params.yaml +60 -0
  17. data/data/config/cmd_tlm_server.yaml +136 -0
  18. data/data/config/command.yaml +44 -0
  19. data/data/config/command_modifiers.yaml +160 -0
  20. data/data/config/command_telemetry.yaml +3 -0
  21. data/data/config/interface_modifiers.yaml +104 -0
  22. data/data/config/item_modifiers.yaml +221 -0
  23. data/data/config/microservice.yaml +78 -0
  24. data/data/config/param_item_modifiers.yaml +52 -0
  25. data/data/config/parameter_modifiers.yaml +200 -0
  26. data/data/config/plugins.yaml +80 -0
  27. data/data/config/protocols.yaml +290 -0
  28. data/data/config/screen.yaml +147 -0
  29. data/data/config/table_manager.yaml +89 -0
  30. data/data/config/table_parameter_modifiers.yaml +9 -0
  31. data/data/config/target.yaml +142 -0
  32. data/data/config/target_config.yaml +94 -0
  33. data/data/config/telemetry.yaml +87 -0
  34. data/data/config/telemetry_modifiers.yaml +159 -0
  35. data/data/config/tool.yaml +63 -0
  36. data/data/config/unknown.yaml +3 -0
  37. data/data/config/widgets.yaml +1505 -0
  38. data/ext/mkrf_conf.rb +49 -0
  39. data/ext/openc3/ext/array/array.c +122 -0
  40. data/ext/openc3/ext/array/extconf.rb +13 -0
  41. data/ext/openc3/ext/buffered_file/buffered_file.c +198 -0
  42. data/ext/openc3/ext/buffered_file/extconf.rb +13 -0
  43. data/ext/openc3/ext/config_parser/config_parser.c +280 -0
  44. data/ext/openc3/ext/config_parser/extconf.rb +13 -0
  45. data/ext/openc3/ext/crc/crc.c +351 -0
  46. data/ext/openc3/ext/crc/extconf.rb +13 -0
  47. data/ext/openc3/ext/openc3_io/extconf.rb +13 -0
  48. data/ext/openc3/ext/openc3_io/openc3_io.c +158 -0
  49. data/ext/openc3/ext/packet/extconf.rb +13 -0
  50. data/ext/openc3/ext/packet/packet.c +318 -0
  51. data/ext/openc3/ext/platform/extconf.rb +13 -0
  52. data/ext/openc3/ext/platform/platform.c +134 -0
  53. data/ext/openc3/ext/polynomial_conversion/extconf.rb +13 -0
  54. data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +79 -0
  55. data/ext/openc3/ext/string/extconf.rb +13 -0
  56. data/ext/openc3/ext/string/string.c +63 -0
  57. data/ext/openc3/ext/structure/structure.c +1719 -0
  58. data/ext/openc3/ext/tabbed_plots_config/extconf.rb +13 -0
  59. data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +62 -0
  60. data/ext/openc3/ext/telemetry/extconf.rb +13 -0
  61. data/ext/openc3/ext/telemetry/telemetry.c +336 -0
  62. data/lib/cosmos.rb +20 -0
  63. data/lib/cosmosc2.rb +20 -0
  64. data/lib/openc3/api/api.rb +39 -0
  65. data/lib/openc3/api/authorized_api.rb +30 -0
  66. data/lib/openc3/api/cmd_api.rb +451 -0
  67. data/lib/openc3/api/config_api.rb +58 -0
  68. data/lib/openc3/api/interface_api.rb +117 -0
  69. data/lib/openc3/api/limits_api.rb +375 -0
  70. data/lib/openc3/api/router_api.rb +117 -0
  71. data/lib/openc3/api/settings_api.rb +70 -0
  72. data/lib/openc3/api/target_api.rb +78 -0
  73. data/lib/openc3/api/tlm_api.rb +455 -0
  74. data/lib/openc3/bridge/bridge.rb +54 -0
  75. data/lib/openc3/bridge/bridge_config.rb +167 -0
  76. data/lib/openc3/bridge/bridge_interface_thread.rb +42 -0
  77. data/lib/openc3/bridge/bridge_router_thread.rb +42 -0
  78. data/lib/openc3/ccsds/ccsds_packet.rb +68 -0
  79. data/lib/openc3/ccsds/ccsds_parser.rb +148 -0
  80. data/lib/openc3/config/config_parser.rb +549 -0
  81. data/lib/openc3/config/meta_config_parser.rb +74 -0
  82. data/lib/openc3/conversions/conversion.rb +70 -0
  83. data/lib/openc3/conversions/generic_conversion.rb +83 -0
  84. data/lib/openc3/conversions/packet_time_formatted_conversion.rb +43 -0
  85. data/lib/openc3/conversions/packet_time_seconds_conversion.rb +43 -0
  86. data/lib/openc3/conversions/polynomial_conversion.rb +87 -0
  87. data/lib/openc3/conversions/processor_conversion.rb +70 -0
  88. data/lib/openc3/conversions/received_count_conversion.rb +38 -0
  89. data/lib/openc3/conversions/received_time_formatted_conversion.rb +42 -0
  90. data/lib/openc3/conversions/received_time_seconds_conversion.rb +42 -0
  91. data/lib/openc3/conversions/segmented_polynomial_conversion.rb +171 -0
  92. data/lib/openc3/conversions/unix_time_conversion.rb +68 -0
  93. data/lib/openc3/conversions/unix_time_formatted_conversion.rb +49 -0
  94. data/lib/openc3/conversions/unix_time_seconds_conversion.rb +49 -0
  95. data/lib/openc3/conversions.rb +34 -0
  96. data/lib/openc3/core_ext/array.rb +416 -0
  97. data/lib/openc3/core_ext/binding.rb +29 -0
  98. data/lib/openc3/core_ext/class.rb +72 -0
  99. data/lib/openc3/core_ext/exception.rb +61 -0
  100. data/lib/openc3/core_ext/file.rb +83 -0
  101. data/lib/openc3/core_ext/hash.rb +37 -0
  102. data/lib/openc3/core_ext/io.rb +134 -0
  103. data/lib/openc3/core_ext/kernel.rb +42 -0
  104. data/lib/openc3/core_ext/math.rb +128 -0
  105. data/lib/openc3/core_ext/matrix.rb +156 -0
  106. data/lib/openc3/core_ext/objectspace.rb +36 -0
  107. data/lib/openc3/core_ext/openc3_io.rb +57 -0
  108. data/lib/openc3/core_ext/range.rb +27 -0
  109. data/lib/openc3/core_ext/socket.rb +38 -0
  110. data/lib/openc3/core_ext/string.rb +389 -0
  111. data/lib/openc3/core_ext/stringio.rb +33 -0
  112. data/lib/openc3/core_ext/time.rb +508 -0
  113. data/lib/openc3/core_ext.rb +36 -0
  114. data/lib/openc3/interfaces/interface.rb +498 -0
  115. data/lib/openc3/interfaces/linc_interface.rb +475 -0
  116. data/lib/openc3/interfaces/protocols/burst_protocol.rb +192 -0
  117. data/lib/openc3/interfaces/protocols/crc_protocol.rb +193 -0
  118. data/lib/openc3/interfaces/protocols/fixed_protocol.rb +155 -0
  119. data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +56 -0
  120. data/lib/openc3/interfaces/protocols/length_protocol.rb +165 -0
  121. data/lib/openc3/interfaces/protocols/override_protocol.rb +60 -0
  122. data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +206 -0
  123. data/lib/openc3/interfaces/protocols/protocol.rb +82 -0
  124. data/lib/openc3/interfaces/protocols/template_protocol.rb +261 -0
  125. data/lib/openc3/interfaces/protocols/terminated_protocol.rb +93 -0
  126. data/lib/openc3/interfaces/serial_interface.rb +94 -0
  127. data/lib/openc3/interfaces/simulated_target_interface.rb +168 -0
  128. data/lib/openc3/interfaces/stream_interface.rb +81 -0
  129. data/lib/openc3/interfaces/tcpip_client_interface.rb +69 -0
  130. data/lib/openc3/interfaces/tcpip_server_interface.rb +629 -0
  131. data/lib/openc3/interfaces/udp_interface.rb +169 -0
  132. data/lib/openc3/interfaces.rb +44 -0
  133. data/lib/openc3/io/buffered_file.rb +109 -0
  134. data/lib/openc3/io/io_multiplexer.rb +80 -0
  135. data/lib/openc3/io/json_api_object.rb +208 -0
  136. data/lib/openc3/io/json_drb.rb +335 -0
  137. data/lib/openc3/io/json_drb_object.rb +114 -0
  138. data/lib/openc3/io/json_drb_rack.rb +84 -0
  139. data/lib/openc3/io/json_rpc.rb +420 -0
  140. data/lib/openc3/io/openc3_snmp.rb +58 -0
  141. data/lib/openc3/io/posix_serial_driver.rb +156 -0
  142. data/lib/openc3/io/raw_logger.rb +167 -0
  143. data/lib/openc3/io/raw_logger_pair.rb +77 -0
  144. data/lib/openc3/io/serial_driver.rb +105 -0
  145. data/lib/openc3/io/stderr.rb +43 -0
  146. data/lib/openc3/io/stdout.rb +43 -0
  147. data/lib/openc3/io/udp_sockets.rb +194 -0
  148. data/lib/openc3/io/win32_serial_driver.rb +196 -0
  149. data/lib/openc3/logs/log_writer.rb +302 -0
  150. data/lib/openc3/logs/packet_log_constants.rb +62 -0
  151. data/lib/openc3/logs/packet_log_reader.rb +345 -0
  152. data/lib/openc3/logs/packet_log_writer.rb +299 -0
  153. data/lib/openc3/logs/text_log_writer.rb +68 -0
  154. data/lib/openc3/logs.rb +25 -0
  155. data/lib/openc3/microservices/cleanup_microservice.rb +68 -0
  156. data/lib/openc3/microservices/decom_microservice.rb +136 -0
  157. data/lib/openc3/microservices/interface_microservice.rb +532 -0
  158. data/lib/openc3/microservices/log_microservice.rb +108 -0
  159. data/lib/openc3/microservices/microservice.rb +204 -0
  160. data/lib/openc3/microservices/plugin_microservice.rb +43 -0
  161. data/lib/openc3/microservices/reaction_microservice.rb +541 -0
  162. data/lib/openc3/microservices/reducer_microservice.rb +313 -0
  163. data/lib/openc3/microservices/router_microservice.rb +44 -0
  164. data/lib/openc3/microservices/text_log_microservice.rb +84 -0
  165. data/lib/openc3/microservices/timeline_microservice.rb +363 -0
  166. data/lib/openc3/microservices/trigger_group_microservice.rb +638 -0
  167. data/lib/openc3/models/activity_model.rb +319 -0
  168. data/lib/openc3/models/auth_model.rb +65 -0
  169. data/lib/openc3/models/cvt_model.rb +185 -0
  170. data/lib/openc3/models/environment_model.rb +58 -0
  171. data/lib/openc3/models/gem_model.rb +137 -0
  172. data/lib/openc3/models/info_model.rb +31 -0
  173. data/lib/openc3/models/interface_model.rb +281 -0
  174. data/lib/openc3/models/interface_status_model.rb +117 -0
  175. data/lib/openc3/models/metadata_model.rb +139 -0
  176. data/lib/openc3/models/metric_model.rb +59 -0
  177. data/lib/openc3/models/microservice_model.rb +206 -0
  178. data/lib/openc3/models/microservice_status_model.rb +74 -0
  179. data/lib/openc3/models/model.rb +204 -0
  180. data/lib/openc3/models/note_model.rb +122 -0
  181. data/lib/openc3/models/notification_model.rb +40 -0
  182. data/lib/openc3/models/ping_model.rb +35 -0
  183. data/lib/openc3/models/plugin_model.rb +292 -0
  184. data/lib/openc3/models/process_status_model.rb +76 -0
  185. data/lib/openc3/models/reaction_model.rb +322 -0
  186. data/lib/openc3/models/reducer_model.rb +65 -0
  187. data/lib/openc3/models/router_model.rb +35 -0
  188. data/lib/openc3/models/router_status_model.rb +27 -0
  189. data/lib/openc3/models/scope_model.rb +153 -0
  190. data/lib/openc3/models/settings_model.rb +55 -0
  191. data/lib/openc3/models/sorted_model.rb +167 -0
  192. data/lib/openc3/models/target_model.rb +759 -0
  193. data/lib/openc3/models/timeline_model.rb +154 -0
  194. data/lib/openc3/models/tool_config_model.rb +38 -0
  195. data/lib/openc3/models/tool_model.rb +262 -0
  196. data/lib/openc3/models/trigger_group_model.rb +186 -0
  197. data/lib/openc3/models/trigger_model.rb +330 -0
  198. data/lib/openc3/models/widget_model.rb +138 -0
  199. data/lib/openc3/operators/microservice_operator.rb +128 -0
  200. data/lib/openc3/operators/operator.rb +277 -0
  201. data/lib/openc3/packets/binary_accessor.rb +1207 -0
  202. data/lib/openc3/packets/commands.rb +373 -0
  203. data/lib/openc3/packets/json_packet.rb +134 -0
  204. data/lib/openc3/packets/limits.rb +271 -0
  205. data/lib/openc3/packets/limits_response.rb +53 -0
  206. data/lib/openc3/packets/packet.rb +1168 -0
  207. data/lib/openc3/packets/packet_config.rb +625 -0
  208. data/lib/openc3/packets/packet_item.rb +586 -0
  209. data/lib/openc3/packets/packet_item_limits.rb +162 -0
  210. data/lib/openc3/packets/parsers/format_string_parser.rb +65 -0
  211. data/lib/openc3/packets/parsers/limits_parser.rb +159 -0
  212. data/lib/openc3/packets/parsers/limits_response_parser.rb +61 -0
  213. data/lib/openc3/packets/parsers/packet_item_parser.rb +272 -0
  214. data/lib/openc3/packets/parsers/packet_parser.rb +134 -0
  215. data/lib/openc3/packets/parsers/processor_parser.rb +73 -0
  216. data/lib/openc3/packets/parsers/state_parser.rb +127 -0
  217. data/lib/openc3/packets/parsers/xtce_converter.rb +442 -0
  218. data/lib/openc3/packets/parsers/xtce_parser.rb +722 -0
  219. data/lib/openc3/packets/structure.rb +553 -0
  220. data/lib/openc3/packets/structure_item.rb +365 -0
  221. data/lib/openc3/packets/telemetry.rb +487 -0
  222. data/lib/openc3/processors/processor.rb +86 -0
  223. data/lib/openc3/processors/statistics_processor.rb +82 -0
  224. data/lib/openc3/processors/watermark_processor.rb +58 -0
  225. data/lib/openc3/processors.rb +24 -0
  226. data/lib/openc3/script/api_shared.rb +828 -0
  227. data/lib/openc3/script/calendar.rb +89 -0
  228. data/lib/openc3/script/commands.rb +227 -0
  229. data/lib/openc3/script/exceptions.rb +29 -0
  230. data/lib/openc3/script/extract.rb +161 -0
  231. data/lib/openc3/script/limits.rb +60 -0
  232. data/lib/openc3/script/script.rb +299 -0
  233. data/lib/openc3/script/script_runner.rb +238 -0
  234. data/lib/openc3/script/storage.rb +146 -0
  235. data/lib/openc3/script/suite.rb +542 -0
  236. data/lib/openc3/script/suite_results.rb +196 -0
  237. data/lib/openc3/script/suite_runner.rb +217 -0
  238. data/lib/openc3/script.rb +21 -0
  239. data/lib/openc3/streams/serial_stream.rb +167 -0
  240. data/lib/openc3/streams/stream.rb +63 -0
  241. data/lib/openc3/streams/tcpip_client_stream.rb +116 -0
  242. data/lib/openc3/streams/tcpip_socket_stream.rb +195 -0
  243. data/lib/openc3/system/system.rb +127 -0
  244. data/lib/openc3/system/system_config.rb +411 -0
  245. data/lib/openc3/system/target.rb +269 -0
  246. data/lib/openc3/system.rb +24 -0
  247. data/lib/openc3/tools/cmd_tlm_server/api.rb +20 -0
  248. data/lib/openc3/tools/cmd_tlm_server/cmd_tlm_server_config.rb +320 -0
  249. data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +294 -0
  250. data/lib/openc3/tools/table_manager/table.rb +77 -0
  251. data/lib/openc3/tools/table_manager/table_config.rb +273 -0
  252. data/lib/openc3/tools/table_manager/table_item.rb +90 -0
  253. data/lib/openc3/tools/table_manager/table_item_parser.rb +66 -0
  254. data/lib/openc3/tools/table_manager/table_manager_core.rb +333 -0
  255. data/lib/openc3/tools/table_manager/table_parser.rb +93 -0
  256. data/lib/openc3/tools/test_runner/test.rb +67 -0
  257. data/lib/openc3/top_level.rb +595 -0
  258. data/lib/openc3/topics/autonomic_topic.rb +52 -0
  259. data/lib/openc3/topics/calendar_topic.rb +44 -0
  260. data/lib/openc3/topics/command_decom_topic.rb +76 -0
  261. data/lib/openc3/topics/command_topic.rb +83 -0
  262. data/lib/openc3/topics/config_topic.rb +68 -0
  263. data/lib/openc3/topics/interface_topic.rb +73 -0
  264. data/lib/openc3/topics/limits_event_topic.rb +109 -0
  265. data/lib/openc3/topics/notifications_topic.rb +28 -0
  266. data/lib/openc3/topics/router_topic.rb +85 -0
  267. data/lib/openc3/topics/telemetry_decom_topic.rb +54 -0
  268. data/lib/openc3/topics/telemetry_topic.rb +36 -0
  269. data/lib/openc3/topics/timeline_topic.rb +45 -0
  270. data/lib/openc3/topics/topic.rb +53 -0
  271. data/lib/openc3/utilities/authentication.rb +141 -0
  272. data/lib/openc3/utilities/authorization.rb +51 -0
  273. data/lib/openc3/utilities/crc.rb +278 -0
  274. data/lib/openc3/utilities/csv.rb +153 -0
  275. data/lib/openc3/utilities/logger.rb +187 -0
  276. data/lib/openc3/utilities/message_log.rb +91 -0
  277. data/lib/openc3/utilities/metric.rb +141 -0
  278. data/lib/openc3/utilities/process_manager.rb +139 -0
  279. data/lib/openc3/utilities/quaternion.rb +257 -0
  280. data/lib/openc3/utilities/ruby_lex_utils.rb +568 -0
  281. data/lib/openc3/utilities/s3.rb +202 -0
  282. data/lib/openc3/utilities/s3_autoload.rb +9 -0
  283. data/lib/openc3/utilities/s3_file_cache.rb +274 -0
  284. data/lib/openc3/utilities/simulated_target.rb +117 -0
  285. data/lib/openc3/utilities/sleeper.rb +51 -0
  286. data/lib/openc3/utilities/store.rb +23 -0
  287. data/lib/openc3/utilities/store_autoload.rb +237 -0
  288. data/lib/openc3/utilities/zip.rb +21 -0
  289. data/lib/openc3/utilities.rb +35 -0
  290. data/lib/openc3/version.rb +14 -0
  291. data/lib/openc3/win32/excel.rb +132 -0
  292. data/lib/openc3/win32/win32.rb +402 -0
  293. data/lib/openc3/win32/win32_main.rb +333 -0
  294. data/lib/openc3.rb +49 -0
  295. data/tasks/gemfile_stats.rake +113 -0
  296. data/tasks/spec.rake +30 -0
  297. data/templates/plugin-template/README.md +15 -0
  298. data/templates/plugin-template/Rakefile +12 -0
  299. data/templates/plugin-template/plugin.gemspec +23 -0
  300. data/templates/plugin-template/plugin.txt +9 -0
  301. data/templates/plugin-template/targets/TARGET/cmd_tlm/cmd.txt +8 -0
  302. data/templates/plugin-template/targets/TARGET/cmd_tlm/tlm.txt +8 -0
  303. data/templates/plugin-template/targets/TARGET/lib/target.rb +10 -0
  304. data/templates/plugin-template/targets/TARGET/procedures/procedure.rb +3 -0
  305. data/templates/plugin-template/targets/TARGET/screens/status.txt +9 -0
  306. data/templates/plugin-template/targets/TARGET/target.txt +5 -0
  307. metadata +849 -0
@@ -0,0 +1,542 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU Affero General Public License
8
+ # as published by the Free Software Foundation; version 3 with
9
+ # attribution addendums as found in the LICENSE.txt
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+
16
+ # Modified by OpenC3, Inc.
17
+ # All changes Copyright 2022, OpenC3, Inc.
18
+ # All Rights Reserved
19
+
20
+ require 'openc3/script/exceptions'
21
+ require 'openc3/core_ext/stringio'
22
+ require 'openc3/io/stderr'
23
+ require 'openc3/io/stdout'
24
+
25
+ module OpenC3
26
+ # Base class for Script Runner suites. OpenC3 Suites inherit from Suite
27
+ # and can implement setup and teardown methods. Script groups are added via add_group(Group)
28
+ # and individual scripts added via add_script(Group, script_method).
29
+ class Suite
30
+ attr_reader :scripts
31
+ attr_reader :plans
32
+
33
+ ###########################################################################
34
+ # START PUBLIC API
35
+ ###########################################################################
36
+
37
+ # Create a new Suite
38
+ def initialize
39
+ @scripts = {}
40
+ @plans = []
41
+ end
42
+
43
+ # Add a group to the suite
44
+ def add_group(group_class)
45
+ group_class = Object.const_get(group_class.to_s.intern) unless group_class.class == Class
46
+ @scripts[group_class] = group_class.new unless @scripts[group_class]
47
+ @plans << [:GROUP, group_class, nil]
48
+ end
49
+
50
+ # Add a script to the suite
51
+ def add_script(group_class, script)
52
+ group_class = Object.const_get(group_class.to_s.intern) unless group_class.class == Class
53
+ @scripts[group_class] = group_class.new unless @scripts[group_class]
54
+ @plans << [:SCRIPT, group_class, script]
55
+ end
56
+
57
+ # Add a group setup to the suite
58
+ def add_group_setup(group_class)
59
+ group_class = Object.const_get(group_class.to_s.intern) unless group_class.class == Class
60
+ @scripts[group_class] = group_class.new unless @scripts[group_class]
61
+ @plans << [:GROUP_SETUP, group_class, nil]
62
+ end
63
+
64
+ # Add a group teardown to the suite
65
+ def add_group_teardown(group_class)
66
+ group_class = Object.const_get(group_class.to_s.intern) unless group_class.class == Class
67
+ @scripts[group_class] = group_class.new unless @scripts[group_class]
68
+ @plans << [:GROUP_TEARDOWN, group_class, nil]
69
+ end
70
+
71
+ ###########################################################################
72
+ # END PUBLIC API
73
+ ###########################################################################
74
+
75
+ def <=>(other_suite)
76
+ self.name <=> other_suite.name
77
+ end
78
+
79
+ # Name of the suite
80
+ def name
81
+ if self.class != Suite
82
+ self.class.to_s.split('::')[-1]
83
+ else
84
+ 'UnassignedSuite'
85
+ end
86
+ end
87
+
88
+ # Returns the number of scripts in the suite including setup and teardown methods
89
+ def get_num_scripts
90
+ num_scripts = 0
91
+ @plans.each do |type, group_class, script|
92
+ case type
93
+ when :GROUP
94
+ num_scripts += group_class.get_num_scripts
95
+ when :SCRIPT, :GROUP_SETUP, :GROUP_TEARDOWN
96
+ num_scripts += 1
97
+ end
98
+ end
99
+ num_scripts += 1 if self.class.method_defined?(:setup)
100
+ num_scripts += 1 if self.class.method_defined?(:teardown)
101
+ num_scripts
102
+ end
103
+
104
+ # Run all the scripts
105
+ def run(&block)
106
+ ScriptResult.suite = name()
107
+ ScriptStatus.instance.total = get_num_scripts()
108
+ results = []
109
+
110
+ # Setup the suite
111
+ result = run_setup(true)
112
+ if result
113
+ results << result
114
+ yield result if block_given?
115
+ raise StopScript if result.stopped
116
+ end
117
+
118
+ # Run each script
119
+ @plans.each do |type, group_class, script|
120
+ case type
121
+ when :GROUP
122
+ results.concat(run_group(group_class, true, &block))
123
+ when :SCRIPT
124
+ result = run_script(group_class, script, true)
125
+ results << result
126
+ yield result if block_given?
127
+ raise StopScript if (result.exceptions and group_class.abort_on_exception) or result.stopped
128
+ when :GROUP_SETUP
129
+ result = run_group_setup(group_class, true)
130
+ if result
131
+ results << result
132
+ yield result if block_given?
133
+ raise StopScript if (result.exceptions and group_class.abort_on_exception) or result.stopped
134
+ end
135
+ when :GROUP_TEARDOWN
136
+ result = run_group_teardown(group_class, true)
137
+ if result
138
+ results << result
139
+ yield result if block_given?
140
+ raise StopScript if (result.exceptions and group_class.abort_on_exception) or result.stopped
141
+ end
142
+ end
143
+ end
144
+
145
+ # Teardown the suite
146
+ result = run_teardown(true)
147
+ if result
148
+ results << result
149
+ yield result if block_given?
150
+ raise StopScript if result.stopped
151
+ end
152
+
153
+ ScriptResult.suite = nil
154
+ results
155
+ end
156
+
157
+ # Run a specific group
158
+ def run_group(group_class, internal = false, &block)
159
+ ScriptResult.suite = name() unless internal
160
+
161
+ # Determine if this group_class is in the plan and the number of scripts associated with this group_class
162
+ in_plan = false
163
+ num_scripts = 0
164
+ @plans.each do |plan_type, plan_group_class, plan_script|
165
+ if plan_type == :GROUP and group_class == plan_group_class
166
+ in_plan = true
167
+ end
168
+ if (plan_type == :GROUP_SETUP and group_class == plan_group_class) or
169
+ (plan_type == :GROUP_TEARDOWN and group_class == plan_group_class) or
170
+ (plan_script and group_class == plan_group_class)
171
+ num_scripts += 1
172
+ end
173
+ end
174
+
175
+ if in_plan
176
+ ScriptStatus.instance.total = group_class.get_num_scripts() unless internal
177
+ results = @scripts[group_class].run(&block)
178
+ else
179
+ results = []
180
+ ScriptStatus.instance.total = num_scripts unless internal
181
+
182
+ # Run each setup, teardown, or script associated with this group_class in the order
183
+ # defined in the plan
184
+ @plans.each do |plan_type, plan_group_class, plan_script|
185
+ if plan_group_class == group_class
186
+ case plan_type
187
+ when :SCRIPT
188
+ result = run_script(plan_group_class, plan_script, true)
189
+ results << result
190
+ yield result if block_given?
191
+ when :GROUP_SETUP
192
+ result = run_group_setup(plan_group_class, true)
193
+ if result
194
+ results << result
195
+ yield result if block_given?
196
+ end
197
+ when :GROUP_TEARDOWN
198
+ result = run_group_teardown(plan_group_class, true)
199
+ if result
200
+ results << result
201
+ yield result if block_given?
202
+ end
203
+ end
204
+ end
205
+ end
206
+ end
207
+
208
+ ScriptResult.suite = nil unless internal
209
+ return results
210
+ end
211
+
212
+ # Run a specific script
213
+ def run_script(group_class, script, internal = false)
214
+ ScriptResult.suite = name() unless internal
215
+ ScriptStatus.instance.total = 1 unless internal
216
+ result = @scripts[group_class].run_script(script)
217
+ ScriptResult.suite = nil unless internal
218
+ result
219
+ end
220
+
221
+ def run_setup(internal = false)
222
+ ScriptResult.suite = name() unless internal
223
+ result = nil
224
+ if self.class.method_defined?(:setup) and @scripts.length > 0
225
+ ScriptStatus.instance.total = 1 unless internal
226
+ ScriptStatus.instance.status = "#{self.class} : setup"
227
+ result = @scripts[@scripts.keys[0]].run_method(self, :setup)
228
+ end
229
+ ScriptResult.suite = nil unless internal
230
+ result
231
+ end
232
+
233
+ def run_teardown(internal = false)
234
+ ScriptResult.suite = name() unless internal
235
+ result = nil
236
+ if self.class.method_defined?(:teardown) and @scripts.length > 0
237
+ ScriptStatus.instance.total = 1 unless internal
238
+ ScriptStatus.instance.status = "#{self.class} : teardown"
239
+ result = @scripts[@scripts.keys[0]].run_method(self, :teardown)
240
+ end
241
+ ScriptResult.suite = nil unless internal
242
+ result
243
+ end
244
+
245
+ def run_group_setup(group_class, internal = false)
246
+ ScriptResult.suite = name() unless internal
247
+ ScriptStatus.instance.total = 1 unless internal
248
+ result = @scripts[group_class].run_setup
249
+ ScriptResult.suite = nil unless internal
250
+ result
251
+ end
252
+
253
+ def run_group_teardown(group_class, internal = false)
254
+ ScriptResult.suite = name() unless internal
255
+ ScriptStatus.instance.total = 1 unless internal
256
+ result = @scripts[group_class].run_teardown
257
+ ScriptResult.suite = nil unless internal
258
+ result
259
+ end
260
+ end
261
+
262
+ # Base class for a group. All OpenC3 Script Runner scripts should inherit Group
263
+ # and then implement scripts methods starting with 'script_', 'test_', or 'op_'
264
+ # e.g. script_mech_open, test_mech_open, op_mech_open.
265
+ class Group
266
+ @@abort_on_exception = false
267
+ @@current_result = nil
268
+
269
+ def initialize
270
+ @output_io = StringIO.new('', 'r+')
271
+ $stdout = Stdout.instance
272
+ $stderr = Stderr.instance
273
+ end
274
+
275
+ def self.abort_on_exception
276
+ @@abort_on_exception
277
+ end
278
+
279
+ def self.abort_on_exception=(value)
280
+ @@abort_on_exception = value
281
+ end
282
+
283
+ def self.scripts
284
+ # Find all the script methods
285
+ methods = []
286
+ self.instance_methods.each do |method_name|
287
+ if /^test|^script|op_/.match?(method_name.to_s)
288
+ methods << method_name.to_s
289
+ end
290
+ end
291
+ # Sort by name for all found methods
292
+ methods.sort!
293
+ methods
294
+ end
295
+
296
+ # Name of the script group
297
+ def name
298
+ if self.class != Group
299
+ self.class.to_s.split('::')[-1]
300
+ else
301
+ 'UnnamedGroup'
302
+ end
303
+ end
304
+
305
+ # Run all the scripts
306
+ def run
307
+ results = []
308
+
309
+ # Setup the script group
310
+ result = run_setup()
311
+ if result
312
+ results << result
313
+ yield result if block_given?
314
+ raise StopScript if (results[-1].exceptions and @@abort_on_exception) or results[-1].stopped
315
+ end
316
+
317
+ # Run all the scripts
318
+ self.class.scripts.each do |method_name|
319
+ results << run_script(method_name)
320
+ yield results[-1] if block_given?
321
+ raise StopScript if (results[-1].exceptions and @@abort_on_exception) or results[-1].stopped
322
+ end
323
+
324
+ # Teardown the script group
325
+ result = run_teardown()
326
+ if result
327
+ results << result
328
+ yield result if block_given?
329
+ raise StopScript if (results[-1].exceptions and @@abort_on_exception) or results[-1].stopped
330
+ end
331
+
332
+ results
333
+ end
334
+
335
+ # Run a specific script method
336
+ def run_script(method_name)
337
+ ScriptStatus.instance.status = "#{self.class} : #{method_name}"
338
+ run_method(self, method_name)
339
+ end
340
+
341
+ def run_method(object, method_name)
342
+ # Convert to a symbol to use as a method_name
343
+ method_name = method_name.to_s.intern unless method_name.class == Symbol
344
+
345
+ result = ScriptResult.new
346
+ @@current_result = result
347
+
348
+ # Verify script method exists
349
+ if object.class.method_defined?(method_name)
350
+ # Capture STDOUT and STDERR
351
+ $stdout.add_stream(@output_io)
352
+ $stderr.add_stream(@output_io)
353
+
354
+ result.group = object.class.to_s.split('::')[-1]
355
+ result.script = method_name.to_s
356
+ begin
357
+ object.public_send(method_name)
358
+ result.result = :PASS
359
+
360
+ if RunningScript.instance and RunningScript.instance.exceptions
361
+ result.exceptions = RunningScript.instance.exceptions
362
+ result.result = :FAIL
363
+ RunningScript.instance.exceptions = nil
364
+ end
365
+ rescue StandardError, SyntaxError => error
366
+ # Check that the error belongs to the StopScript inheritance chain
367
+ if error.class <= StopScript
368
+ result.stopped = true
369
+ result.result = :STOP
370
+ end
371
+ # Check that the error belongs to the SkipScript inheritance chain
372
+ if error.class <= SkipScript
373
+ result.result = :SKIP
374
+ result.message ||= ''
375
+ result.message << error.message + "\n"
376
+ else
377
+ if error.class != StopScript and
378
+ (not RunningScript.instance or
379
+ not RunningScript.instance.exceptions or
380
+ not RunningScript.instance.exceptions.include? error)
381
+ result.exceptions ||= []
382
+ result.exceptions << error
383
+ puts "*** Exception in Control Statement:"
384
+ error.formatted.each_line do |line|
385
+ puts ' ' + line
386
+ end
387
+ end
388
+ if RunningScript.instance and RunningScript.instance.exceptions
389
+ result.exceptions ||= []
390
+ result.exceptions.concat(RunningScript.instance.exceptions)
391
+ RunningScript.instance.exceptions = nil
392
+ end
393
+ end
394
+
395
+ result.result = :FAIL if result.exceptions
396
+ ensure
397
+ result.output = @output_io.string
398
+ @output_io.string = ''
399
+ $stdout.remove_stream(@output_io)
400
+ $stderr.remove_stream(@output_io)
401
+
402
+ case result.result
403
+ when :FAIL
404
+ ScriptStatus.instance.fail_count += 1
405
+ when :SKIP
406
+ ScriptStatus.instance.skip_count += 1
407
+ when :PASS
408
+ ScriptStatus.instance.pass_count += 1
409
+ end
410
+ end
411
+
412
+ else
413
+ @@current_result = nil
414
+ raise "Unknown method #{method_name} for #{object.class}"
415
+ end
416
+
417
+ @@current_result = nil
418
+ result
419
+ end
420
+
421
+ def run_setup
422
+ result = nil
423
+ if self.class.method_defined?(:setup)
424
+ ScriptStatus.instance.status = "#{self.class} : setup"
425
+ result = run_script(:setup)
426
+ end
427
+ result
428
+ end
429
+
430
+ def run_teardown
431
+ result = nil
432
+ if self.class.method_defined?(:teardown)
433
+ ScriptStatus.instance.status = "#{self.class} : teardown"
434
+ result = run_script(:teardown)
435
+ end
436
+ result
437
+ end
438
+
439
+ def self.get_num_scripts
440
+ num_scripts = 0
441
+ num_scripts += 1 if self.method_defined?(:setup)
442
+ num_scripts += 1 if self.method_defined?(:teardown)
443
+ num_scripts += self.scripts.length
444
+ num_scripts
445
+ end
446
+
447
+ def self.puts(string)
448
+ $stdout.puts string
449
+ if @@current_result
450
+ @@current_result.message ||= ''
451
+ @@current_result.message << string.chomp
452
+ @@current_result.message << "\n"
453
+ end
454
+ end
455
+
456
+ def self.current_suite
457
+ if @@current_result
458
+ @@current_result.suite
459
+ else
460
+ nil
461
+ end
462
+ end
463
+
464
+ def self.current_group
465
+ if @@current_result
466
+ @@current_result.group
467
+ else
468
+ nil
469
+ end
470
+ end
471
+
472
+ def self.current_script
473
+ if @@current_result
474
+ @@current_result.script
475
+ else
476
+ nil
477
+ end
478
+ end
479
+ end
480
+
481
+ # Helper class to collect information about the running scripts like pass / fail counts
482
+ class ScriptStatus
483
+ attr_accessor :status
484
+ attr_accessor :pass_count
485
+ attr_accessor :skip_count
486
+ attr_accessor :fail_count
487
+ attr_reader :total
488
+
489
+ @@instance = nil
490
+
491
+ def initialize
492
+ @status = ''
493
+ @pass_count = 0
494
+ @skip_count = 0
495
+ @fail_count = 0
496
+ @total = 1
497
+ end
498
+
499
+ def total=(new_total)
500
+ if new_total <= 0
501
+ @total = 1
502
+ else
503
+ @total = new_total
504
+ end
505
+ end
506
+
507
+ def self.instance
508
+ @@instance = self.new unless @@instance
509
+ @@instance
510
+ end
511
+ end
512
+
513
+ # Helper class to collect script result information
514
+ class ScriptResult
515
+ attr_accessor :suite
516
+ attr_accessor :group
517
+ attr_accessor :script
518
+ attr_accessor :output
519
+ attr_accessor :exceptions
520
+ attr_accessor :stopped
521
+ attr_accessor :result
522
+ attr_accessor :message
523
+
524
+ @@suite = nil
525
+
526
+ def initialize
527
+ @suite = nil
528
+ @suite = @@suite.clone if @@suite
529
+ @group = nil
530
+ @script = nil
531
+ @output = nil
532
+ @exceptions = nil
533
+ @stopped = false
534
+ @result = :SKIP
535
+ @message = nil
536
+ end
537
+
538
+ def self.suite=(suite)
539
+ @@suite = suite
540
+ end
541
+ end
542
+ end