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,196 @@
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
+ module OpenC3
21
+ class SuiteResults
22
+ attr_accessor :metadata
23
+
24
+ def initialize
25
+ @report = nil
26
+ @context = nil
27
+ @start_time = nil
28
+ @stop_time = nil
29
+ @results = nil
30
+ @settings = nil
31
+ @metadata = nil
32
+ end
33
+
34
+ def start(test_type, test_suite_class, test_class = nil, test_case = nil, settings = nil)
35
+ @results = []
36
+ @start_time = Time.now.sys
37
+ @settings = settings
38
+ @report = []
39
+
40
+ if test_case
41
+ # Executing a single test case
42
+ @context = "#{test_suite_class.name}:#{test_class.name}:#{test_case} #{test_type}"
43
+ elsif test_class
44
+ # Executing an entire test
45
+ @context = "#{test_suite_class.name}:#{test_class.name} #{test_type}"
46
+ else
47
+ # Executing a test suite
48
+ @context = "#{test_suite_class.name} #{test_type}"
49
+ end
50
+
51
+ header()
52
+ end
53
+
54
+ # process_result can handle an array of OpenC3TestResult objects
55
+ # or a single OpenC3TestResult object
56
+ def process_result(results)
57
+ openc3_lib = Regexp.new(File.join(OpenC3::PATH, 'lib'))
58
+ # If we were passed an array we concat it to the results global
59
+ if results.is_a? Array
60
+ @results.concat(results)
61
+ # A single result is appended and then turned into an array
62
+ else
63
+ @results << results
64
+ results = [results]
65
+ end
66
+ # Process all the results (may be just one)
67
+ results.each do |result|
68
+ self.puts("#{result.group}:#{result.script}:#{result.result}")
69
+ if result.message
70
+ result.message.each_line do |line|
71
+ if /[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F-\xFF]/.match?(line)
72
+ line.chomp!
73
+ line = line.inspect.remove_quotes
74
+ end
75
+ @report << ' ' + line.strip
76
+ end
77
+ end
78
+ if result.exceptions
79
+ @report << " Exceptions:"
80
+ result.exceptions.each_with_index do |error, index|
81
+ error.formatted().each_line do |line|
82
+ next if /in run_text/.match?(line)
83
+ next if /running_script.rb/.match?(line)
84
+ next if line&.match?(openc3_lib)
85
+
86
+ if /[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F-\xFF]/.match?(line)
87
+ line.chomp!
88
+ line = line.inspect.remove_quotes
89
+ end
90
+ @report << ' ' + line.strip
91
+ end
92
+ @report << '' if index != (result.exceptions.length - 1)
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+ def complete
99
+ @stop_time = Time.now.sys
100
+ footer()
101
+ end
102
+
103
+ def report
104
+ @report.join("\n")
105
+ end
106
+
107
+ def header
108
+ @report << "--- Test Report ---"
109
+ # @report << ''
110
+ # if @metadata
111
+ # begin
112
+ # items = get_tlm_packet('SYSTEM', 'META')
113
+ # @report << ''
114
+ # @report << "Metadata:"
115
+ # items.each do |item_name, item_value, _|
116
+ # next if SetTlmDialog::IGNORED_ITEMS.include?(item_name)
117
+ # @report << "#{item_name} = #{item_value}"
118
+ # end
119
+ # rescue DRb::DRbConnError
120
+ # # Oh well
121
+ # end
122
+ # end
123
+ if @settings
124
+ @report << ''
125
+ @report << "Settings:"
126
+ @settings.each { |setting_name, setting_value| @report << "#{setting_name} = #{setting_value}" }
127
+ end
128
+ @report << ''
129
+ @report << "Results:"
130
+ self.puts "Executing #{@context}"
131
+ end
132
+
133
+ def footer
134
+ self.puts "Completed #{@context}"
135
+
136
+ @report << ''
137
+ @report << "--- Test Summary ---"
138
+ @report << ''
139
+
140
+ pass_count = 0
141
+ skip_count = 0
142
+ fail_count = 0
143
+ stopped = false
144
+ @results.each do |result|
145
+ if result.result == :PASS
146
+ pass_count += 1
147
+ elsif result.result == :SKIP
148
+ skip_count += 1
149
+ elsif result.result == :FAIL
150
+ fail_count += 1
151
+ end
152
+
153
+ if result.stopped
154
+ stopped = true
155
+ end
156
+ end
157
+ run_time = Time.format_seconds(@stop_time - @start_time)
158
+ run_time << " (#{@stop_time - @start_time} seconds)" if @stop_time - @start_time > 60
159
+ @report << "Run Time: #{run_time}"
160
+ @report << "Total Tests: #{@results.length}"
161
+ @report << "Pass: #{pass_count}"
162
+ @report << "Skip: #{skip_count}"
163
+ @report << "Fail: #{fail_count}"
164
+ @report << ''
165
+ if stopped
166
+ @report << '*** Test was stopped prematurely ***'
167
+ @report << ''
168
+ end
169
+ end
170
+
171
+ def write(string)
172
+ @report << Time.now.sys.formatted + ': ' + string
173
+ end
174
+
175
+ def puts(string)
176
+ @report << Time.now.sys.formatted + ': ' + string
177
+ end
178
+
179
+ # def collect_metadata(parent = nil)
180
+ # success = true
181
+ # if @metadata
182
+ # Qt.execute_in_main_thread(true) do
183
+ # begin
184
+ # success = SetTlmDialog.execute(parent, 'Enter Test Metadata', 'Start Test', 'Cancel Test', 'SYSTEM', 'META')
185
+ # rescue DRb::DRbConnError
186
+ # success = false
187
+ # Qt::MessageBox.critical(parent, 'Error', 'Error Connecting to Command and Telemetry Server')
188
+ # rescue Exception => err
189
+ # OpenC3.handle_fatal_exception(err)
190
+ # end
191
+ # end
192
+ # end
193
+ # success
194
+ # end
195
+ end
196
+ end
@@ -0,0 +1,217 @@
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/suite'
21
+ require 'openc3/script/suite_results'
22
+ require 'openc3/tools/test_runner/test'
23
+
24
+ module OpenC3
25
+ # Placeholder for all Groups discovered without assigned Suites
26
+ class UnassignedSuite < Suite
27
+ end
28
+
29
+ class SuiteRunner
30
+ @@suites = []
31
+ @@settings = {}
32
+ @@suite_results = nil
33
+
34
+ def self.settings
35
+ @@settings
36
+ end
37
+
38
+ def self.settings=(settings)
39
+ @@settings = settings
40
+ end
41
+
42
+ def self.suite_results
43
+ @@suite_results
44
+ end
45
+
46
+ def self.execute(result_string, suite_class, group_class = nil, script = nil)
47
+ @@suite_results = SuiteResults.new
48
+ @@suites.each do |suite|
49
+ if suite.class == suite_class
50
+ @@suite_results.start(result_string, suite_class, group_class, script, @@settings)
51
+ loop do
52
+ yield(suite)
53
+ break if not @@settings['Loop'] or (ScriptStatus.instance.fail_count > 0 and @@settings['Break Loop On Error'])
54
+ end
55
+ break
56
+ end
57
+ end
58
+ end
59
+
60
+ def self.start(suite_class, group_class = nil, script = nil)
61
+ result = []
62
+ execute('', suite_class, group_class, script) do |suite|
63
+ if script
64
+ result = suite.run_script(group_class, script)
65
+ @@suite_results.process_result(result)
66
+ raise StopScript if (result.exceptions and Group.abort_on_exception) or result.stopped
67
+ elsif group_class
68
+ suite.run_group(group_class) { |current_result| @@suite_results.process_result(current_result); raise StopScript if current_result.stopped }
69
+ else
70
+ suite.run { |current_result| @@suite_results.process_result(current_result); raise StopScript if current_result.stopped }
71
+ end
72
+ end
73
+ end
74
+
75
+ def self.setup(suite_class, group_class = nil)
76
+ execute('Manual Setup', suite_class, group_class) do |suite|
77
+ if group_class
78
+ result = suite.run_group_setup(group_class)
79
+ else
80
+ result = suite.run_setup
81
+ end
82
+ if result
83
+ @@suite_results.process_result(result)
84
+ raise StopScript if result.stopped
85
+ end
86
+ end
87
+ end
88
+
89
+ def self.teardown(suite_class, group_class = nil)
90
+ execute('Manual Teardown', suite_class, group_class) do |suite|
91
+ if group_class
92
+ result = suite.run_group_teardown(group_class)
93
+ else
94
+ result = suite.run_teardown
95
+ end
96
+ if result
97
+ @@suite_results.process_result(result)
98
+ raise StopScript if result.stopped
99
+ end
100
+ end
101
+ end
102
+
103
+ # Convert the OpenStruct structure to a simple hash
104
+ # TODO: Maybe just use hashes right from the beginning?
105
+ def self.open_struct_to_hash(object)
106
+ hash = object.to_h
107
+ hash.each do |key1, val1|
108
+ if val1.is_a?(Hash)
109
+ val1.each do |key2, val2|
110
+ if val2.is_a?(OpenStruct)
111
+ hash[key1][key2] = val2.to_h
112
+ end
113
+ end
114
+ end
115
+ end
116
+ hash
117
+ end
118
+
119
+ # Build list of Suites and Groups
120
+ def self.build_suites
121
+ @@suites = []
122
+ # @@suites = @@suites.select { |my_suite| my_suite.name == 'CustomSuite' }
123
+ suites = {}
124
+ groups = []
125
+ ObjectSpace.each_object(Class) do |object|
126
+ # If we inherit from Suite but aren't the deprecated TestSuite
127
+ if object < Suite && object != TestSuite
128
+ # Ensure they didn't override name for some reason
129
+ if object.instance_methods(false).include?(:name)
130
+ raise FatalError.new("#{object} redefined the 'name' method. Delete the 'name' method and try again.")
131
+ end
132
+
133
+ # ObjectSpace.each_object appears to yield objects in the reverse
134
+ # order that they were parsed by the interpreter so push each
135
+ # Suite object to the front of the array to order as encountered
136
+ @@suites.unshift(object.new)
137
+ end
138
+ # If we inherit from Group but aren't the deprecated Test
139
+ if object < Group && object != Test
140
+ # Ensure they didn't override self.name for some reason
141
+ if object.methods(false).include?(:name)
142
+ raise FatalError.new("#{object} redefined the 'self.name' method. Delete the 'self.name' method and try again.")
143
+ end
144
+
145
+ groups << object
146
+ end
147
+ end
148
+ # Raise error if no suites or groups
149
+ if @@suites.empty? || groups.empty?
150
+ return "No Suite or no Group classes found"
151
+ end
152
+
153
+ # Create Suite for unassigned Groups
154
+ @@suites.each do |suite|
155
+ groups_to_delete = []
156
+ groups.each { |group| groups_to_delete << group if suite.scripts[group] }
157
+ groups_to_delete.each { |group| groups.delete(group) }
158
+ end
159
+ if groups.empty?
160
+ @@suites = @@suites.select { |suite| suite.class != UnassignedSuite }
161
+ else
162
+ unassigned_suite = @@suites.select { |suite| suite.class == UnassignedSuite }[0]
163
+ groups.each { |group| unassigned_suite.add_group(group) }
164
+ end
165
+
166
+ @@suites.each do |suite|
167
+ cur_suite = OpenStruct.new(:setup => false, :teardown => false, :groups => {})
168
+ cur_suite.setup = true if suite.class.method_defined?(:setup)
169
+ cur_suite.teardown = true if suite.class.method_defined?(:teardown)
170
+
171
+ suite.plans.each do |type, group_class, script|
172
+ case type
173
+ when :GROUP
174
+ cur_suite.groups[group_class.name] ||=
175
+ OpenStruct.new(:setup => false, :teardown => false, :scripts => [])
176
+ cur_suite.groups[group_class.name].scripts.concat(group_class.scripts)
177
+ cur_suite.groups[group_class.name].scripts.uniq!
178
+ cur_suite.groups[group_class.name].setup = true if group_class.method_defined?(:setup)
179
+ cur_suite.groups[group_class.name].teardown = true if group_class.method_defined?(:teardown)
180
+ when :SCRIPT
181
+ cur_suite.groups[group_class.name] ||=
182
+ OpenStruct.new(:setup => false, :teardown => false, :scripts => [])
183
+ # Explicitly check for this method and raise an error if it does not exist
184
+ if group_class.method_defined?(script.intern)
185
+ cur_suite.groups[group_class.name].scripts << script
186
+ cur_suite.groups[group_class.name].scripts.uniq!
187
+ else
188
+ raise "#{group_class} does not have a #{script} method defined."
189
+ end
190
+ cur_suite.groups[group_class.name].setup = true if group_class.method_defined?(:setup)
191
+ cur_suite.groups[group_class.name].teardown = true if group_class.method_defined?(:teardown)
192
+ when :GROUP_SETUP
193
+ cur_suite.groups[group_class.name] ||=
194
+ OpenStruct.new(:setup => false, :teardown => false, :scripts => [])
195
+ # Explicitly check for the setup method and raise an error if it does not exist
196
+ if group_class.method_defined?(:setup)
197
+ cur_suite.groups[group_class.name].setup = true
198
+ else
199
+ raise "#{group_class} does not have a setup method defined."
200
+ end
201
+ when :GROUP_TEARDOWN
202
+ cur_suite.groups[group_class.name] ||=
203
+ OpenStruct.new(:setup => false, :teardown => false, :scripts => [])
204
+ # Explicitly check for the teardown method and raise an error if it does not exist
205
+ if group_class.method_defined?(:teardown)
206
+ cur_suite.groups[group_class.name].teardown = true
207
+ else
208
+ raise "#{group_class} does not have a teardown method defined."
209
+ end
210
+ end
211
+ end
212
+ suites[suite.name.split('::')[-1]] = open_struct_to_hash(cur_suite) unless suite.name == 'CustomSuite'
213
+ end
214
+ return suites
215
+ end
216
+ end
217
+ end
@@ -0,0 +1,21 @@
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/script'
21
+ include OpenC3::Script
@@ -0,0 +1,167 @@
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 'thread' # For Mutex
21
+ require 'openc3/streams/stream'
22
+ require 'openc3/config/config_parser'
23
+ require 'openc3/io/serial_driver'
24
+
25
+ module OpenC3
26
+ # Stream that reads and writes to serial ports by using {SerialDriver}.
27
+ class SerialStream < Stream
28
+ # @param write_port_name [String] The name of the serial port to write.
29
+ # Pass nil if the stream is to be read only. On Windows the port name
30
+ # is typically 'COMX' where X can be any port number. On UNIX the port
31
+ # name is typically a device such as '/dev/ttyS0'.
32
+ # @param read_port_name [String] The name of the serial port to read.
33
+ # Pass nil if the stream is to be read only. On Windows the port name
34
+ # is typically 'COMX' where X can be any port number. On UNIX the port
35
+ # name is typically a device such as '/dev/ttyS0'.
36
+ # @param baud_rate [Integer] The serial port baud rate
37
+ # @param parity [Symbol] Must be :NONE, :EVEN, or :ODD
38
+ # @param stop_bits [Integer] Number of stop bits. Must be 1 or 2.
39
+ # @param write_timeout [Integer] Number of seconds to wait for the write to
40
+ # complete. Pass nil to create no timeout. The {SerialDriver} will
41
+ # continously try to send the data until it has been sent or an error
42
+ # occurs.
43
+ # @param read_timeout [Integer] Number of seconds to wait for the read to
44
+ # complete. Pass nil to create no timeout. The {SerialDriver} will
45
+ # continously try to read data until it has received data or an error
46
+ # occurs.
47
+ # @param flow_control [Symbol] Currently supported :NONE and :RTSCTS (default :NONE)
48
+ # @param data_bits [Integer] Number of data bits (default 8)
49
+ def initialize(write_port_name,
50
+ read_port_name,
51
+ baud_rate,
52
+ parity,
53
+ stop_bits,
54
+ write_timeout,
55
+ read_timeout,
56
+ flow_control = :NONE,
57
+ data_bits = 8)
58
+ super()
59
+
60
+ # The SerialDriver class will validate the parameters
61
+ @write_port_name = ConfigParser.handle_nil(write_port_name)
62
+ @read_port_name = ConfigParser.handle_nil(read_port_name)
63
+ @baud_rate = Integer(baud_rate)
64
+ @parity = parity
65
+ @stop_bits = stop_bits.to_i
66
+ @write_timeout = ConfigParser.handle_nil(write_timeout)
67
+ @write_timeout = @write_timeout.to_f if @write_timeout
68
+ @read_timeout = ConfigParser.handle_nil(read_timeout)
69
+ @read_timeout = @read_timeout.to_f if @read_timeout
70
+ @flow_control = flow_control.to_s.intern
71
+ @data_bits = data_bits.to_i
72
+
73
+ if @write_port_name
74
+ @write_serial_port = SerialDriver.new(@write_port_name,
75
+ @baud_rate,
76
+ @parity,
77
+ @stop_bits,
78
+ @write_timeout,
79
+ @read_timeout,
80
+ @flow_control,
81
+ @data_bits)
82
+ else
83
+ @write_serial_port = nil
84
+ end
85
+ if @read_port_name
86
+ if @read_port_name == @write_port_name
87
+ @read_serial_port = @write_serial_port
88
+ else
89
+ @read_serial_port = SerialDriver.new(@read_port_name,
90
+ @baud_rate,
91
+ @parity,
92
+ @stop_bits,
93
+ @write_timeout,
94
+ @read_timeout,
95
+ @flow_control,
96
+ @data_bits)
97
+ end
98
+ else
99
+ @read_serial_port = nil
100
+ end
101
+ if @read_serial_port.nil? && @write_serial_port.nil?
102
+ raise "Either a write port or read port must be given"
103
+ end
104
+
105
+ # We 'connect' when we create the stream
106
+ @connected = true
107
+
108
+ # Mutex on write is needed to protect from commands coming in from more
109
+ # than one tool
110
+ @write_mutex = Mutex.new
111
+ end
112
+
113
+ # @return [String] Returns a binary string of data from the serial port
114
+ def read
115
+ raise "Attempt to read from write only stream" unless @read_serial_port
116
+
117
+ # No read mutex is needed because reads happen serially
118
+ @read_serial_port.read
119
+ end
120
+
121
+ # @return [String] Returns a binary string of data from the serial port without blocking
122
+ def read_nonblock
123
+ raise "Attempt to read from write only stream" unless @read_serial_port
124
+
125
+ # No read mutex is needed because reads happen serially
126
+ @read_serial_port.read_nonblock
127
+ end
128
+
129
+ # @param data [String] A binary string of data to write to the serial port
130
+ def write(data)
131
+ raise "Attempt to write to read only stream" unless @write_serial_port
132
+
133
+ @write_mutex.synchronize do
134
+ @write_serial_port.write(data)
135
+ end
136
+ end
137
+
138
+ # Connect the stream
139
+ def connect
140
+ # N/A - Serial streams 'connect' on creation
141
+ end
142
+
143
+ # @return [Boolean] Whether the serial stream is connected to the serial
144
+ # port
145
+ def connected?
146
+ @connected
147
+ end
148
+
149
+ # Disconnect by closing the serial ports
150
+ def disconnect
151
+ if @connected
152
+ begin
153
+ @write_serial_port.close if @write_serial_port && !@write_serial_port.closed?
154
+ rescue IOError
155
+ # Ignore
156
+ end
157
+
158
+ begin
159
+ @read_serial_port.close if @read_serial_port && !@read_serial_port.closed?
160
+ rescue IOError
161
+ # Ignore
162
+ end
163
+ @connected = false
164
+ end
165
+ end
166
+ end # class SerialStream
167
+ end
@@ -0,0 +1,63 @@
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
+ module OpenC3
21
+ # Class that implments the following methods: read, write(data),
22
+ # connect, connected? and disconnect. Streams are simply data sources which
23
+ # {Protocol} classes read and write to. This separation of concerns
24
+ # allows Streams to simply focus on getting and sending raw data while the
25
+ # higher level processing occurs in {Protocol}.
26
+ class Stream
27
+ # Expected to return any amount of data on success, or a blank string on
28
+ # closed/EOF, and may raise Timeout::Error, or other errors
29
+ def read
30
+ raise "read not defined by Stream"
31
+ end
32
+
33
+ # Expected to always return immediately with data if available or an empty string.
34
+ # Should not raise errors
35
+ def read_nonblock
36
+ raise "read_nonblock not defined by Stream"
37
+ end
38
+
39
+ # Expected to write complete set of data. May raise Timeout::Error
40
+ # or other errors.
41
+ #
42
+ # @param data [String] Binary data to write to the stream
43
+ def write(data)
44
+ raise "write not defined by Stream"
45
+ end
46
+
47
+ # Connects the stream
48
+ def connect
49
+ raise "connect not defined by Stream"
50
+ end
51
+
52
+ # @return [Boolean] true if connected or false otherwise
53
+ def connected?
54
+ raise "connected? not defined by Stream"
55
+ end
56
+
57
+ # Disconnects the stream
58
+ # Note that streams are not designed to be reconnected and must be recreated
59
+ def disconnect
60
+ raise "disconnect not defined by Stream"
61
+ end
62
+ end # class Stream
63
+ end