cosmos 3.5.1 → 3.5.2

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 (1158) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +1 -1
  3. data/.gitattributes +3 -3
  4. data/.gitignore +48 -48
  5. data/.travis.yml +8 -8
  6. data/CONTRIBUTING.txt +50 -50
  7. data/Gemfile +10 -10
  8. data/Guardfile +27 -27
  9. data/LICENSE.txt +879 -879
  10. data/Manifest.txt +1414 -1414
  11. data/README.md +111 -111
  12. data/Rakefile +218 -214
  13. data/autohotkey/config/data/diamond.STL +57 -57
  14. data/autohotkey/config/system/system.txt +34 -34
  15. data/autohotkey/config/targets/COSMOS/cmd_tlm/cosmos_server_cmds.txt +41 -41
  16. data/autohotkey/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +15 -15
  17. data/autohotkey/config/targets/COSMOS/cmd_tlm_server.txt +6 -6
  18. data/autohotkey/config/targets/COSMOS/target.txt +5 -5
  19. data/autohotkey/config/targets/INST/cmd_tlm/inst_cmds.txt +121 -121
  20. data/autohotkey/config/targets/INST/cmd_tlm/inst_tlm.txt +270 -270
  21. data/autohotkey/config/targets/INST/cmd_tlm_server.txt +5 -5
  22. data/autohotkey/config/targets/INST/lib/example_limits_response.rb +30 -30
  23. data/autohotkey/config/targets/INST/lib/sim_inst.rb +305 -305
  24. data/autohotkey/config/targets/INST/screens/adcs.txt +46 -46
  25. data/autohotkey/config/targets/INST/screens/array.txt +7 -7
  26. data/autohotkey/config/targets/INST/screens/block.txt +8 -8
  27. data/autohotkey/config/targets/INST/screens/commanding.txt +30 -30
  28. data/autohotkey/config/targets/INST/screens/graphs.txt +14 -14
  29. data/autohotkey/config/targets/INST/screens/ground.txt +25 -25
  30. data/autohotkey/config/targets/INST/screens/health_status.txt +33 -33
  31. data/autohotkey/config/targets/INST/screens/hs.txt +49 -49
  32. data/autohotkey/config/targets/INST/screens/image.txt +21 -21
  33. data/autohotkey/config/targets/INST/screens/latest.txt +23 -23
  34. data/autohotkey/config/targets/INST/screens/mech.txt +25 -25
  35. data/autohotkey/config/targets/INST/screens/other.txt +25 -25
  36. data/autohotkey/config/targets/INST/screens/params.txt +25 -25
  37. data/autohotkey/config/targets/INST/screens/tabs.txt +68 -68
  38. data/autohotkey/config/targets/INST/target.txt +26 -26
  39. data/autohotkey/config/targets/META/cmd_tlm/meta_cmd.txt +10 -10
  40. data/autohotkey/config/targets/META/cmd_tlm/meta_tlm.txt +9 -9
  41. data/autohotkey/config/targets/SYSTEM/cmd_tlm/limits_groups.txt +7 -7
  42. data/autohotkey/config/targets/SYSTEM/screens/error.txt +11 -11
  43. data/autohotkey/config/tools/cmd_tlm_server/cmd_tlm_server.txt +22 -22
  44. data/autohotkey/config/tools/data_viewer/data_viewer.txt +11 -11
  45. data/autohotkey/config/tools/handbook_creator/handbook_creator.txt +49 -49
  46. data/autohotkey/config/tools/handbook_creator/templates/command_packets.html.erb +86 -86
  47. data/autohotkey/config/tools/handbook_creator/templates/command_toc.html.erb +38 -38
  48. data/autohotkey/config/tools/handbook_creator/templates/footer.html.erb +9 -9
  49. data/autohotkey/config/tools/handbook_creator/templates/header.html.erb +25 -25
  50. data/autohotkey/config/tools/handbook_creator/templates/limits_groups.html.erb +13 -13
  51. data/autohotkey/config/tools/handbook_creator/templates/nav.html.erb +27 -27
  52. data/autohotkey/config/tools/handbook_creator/templates/overview.html.erb +1 -1
  53. data/autohotkey/config/tools/handbook_creator/templates/pdf_cover.html.erb +23 -23
  54. data/autohotkey/config/tools/handbook_creator/templates/pdf_footer.html.erb +33 -33
  55. data/autohotkey/config/tools/handbook_creator/templates/pdf_header.html.erb +41 -41
  56. data/autohotkey/config/tools/handbook_creator/templates/telemetry_packets.html.erb +80 -80
  57. data/autohotkey/config/tools/handbook_creator/templates/telemetry_toc.html.erb +38 -38
  58. data/autohotkey/config/tools/handbook_creator/templates/title.html.erb +1 -1
  59. data/autohotkey/config/tools/launcher/launcher.txt +38 -38
  60. data/autohotkey/config/tools/script_runner/script_runner.txt +3 -3
  61. data/autohotkey/config/tools/table_manager/ConfigTables_def.txt +8 -8
  62. data/autohotkey/config/tools/table_manager/OneDimensionalTable_def.txt +19 -19
  63. data/autohotkey/config/tools/table_manager/TwoDimensionalTable_def.txt +248 -248
  64. data/autohotkey/config/tools/test_runner/test_runner.txt +8 -8
  65. data/autohotkey/config/tools/test_runner/test_runner2.txt +11 -11
  66. data/autohotkey/config/tools/test_runner/test_runner3.txt +6 -6
  67. data/autohotkey/config/tools/test_runner/test_runner4.txt +1 -1
  68. data/autohotkey/config/tools/tlm_extractor/tlm_extractor.txt +13 -13
  69. data/autohotkey/config/tools/tlm_extractor/tlm_extractor2.txt +9 -9
  70. data/autohotkey/config/tools/tlm_grapher/bad.txt +50 -50
  71. data/autohotkey/config/tools/tlm_grapher/temp1-4.txt +51 -51
  72. data/autohotkey/config/tools/tlm_grapher/test2.txt +111 -111
  73. data/autohotkey/config/tools/tlm_viewer/tlm_viewer.txt +24 -24
  74. data/autohotkey/config/tools/tlm_viewer/tlm_viewer2.txt +4 -4
  75. data/autohotkey/config/tools/tlm_viewer/tlm_viewer3.txt +3 -3
  76. data/autohotkey/lib/example_background_task.rb +42 -42
  77. data/autohotkey/lib/user_version.rb +3 -3
  78. data/autohotkey/procedures/clear_util.rb +7 -7
  79. data/autohotkey/procedures/collect_util.rb +14 -14
  80. data/autohotkey/procedures/example_test.rb +67 -67
  81. data/autohotkey/procedures/example_test2.rb +74 -74
  82. data/autohotkey/procedures/script_test.rb +17 -17
  83. data/autohotkey/procedures/syntax_error.rb +18 -18
  84. data/autohotkey/tools/CmdExtractorAHK +16 -16
  85. data/autohotkey/tools/CmdSender +14 -14
  86. data/autohotkey/tools/CmdSenderAHK +18 -18
  87. data/autohotkey/tools/CmdTlmServer +14 -14
  88. data/autohotkey/tools/CmdTlmServerAHK +28 -28
  89. data/autohotkey/tools/CmdTlmServerAHK2 +17 -17
  90. data/autohotkey/tools/DataViewer +14 -14
  91. data/autohotkey/tools/DataViewerAHK +17 -17
  92. data/autohotkey/tools/HandbookCreatorAHK +20 -20
  93. data/autohotkey/tools/LauncherAHK +17 -17
  94. data/autohotkey/tools/LimitsMonitorAHK +20 -20
  95. data/autohotkey/tools/OpenGLBuilderAHK +24 -24
  96. data/autohotkey/tools/PacketViewer +14 -14
  97. data/autohotkey/tools/PacketViewerAHK +18 -18
  98. data/autohotkey/tools/PacketViewerAHK2 +17 -17
  99. data/autohotkey/tools/Replay +14 -14
  100. data/autohotkey/tools/ReplayAHK +17 -17
  101. data/autohotkey/tools/ScriptRunner +14 -14
  102. data/autohotkey/tools/ScriptRunnerAHK +20 -20
  103. data/autohotkey/tools/ScriptRunnerAHK2 +17 -17
  104. data/autohotkey/tools/TableManager +14 -14
  105. data/autohotkey/tools/TableManagerAHK +30 -30
  106. data/autohotkey/tools/TestRunner +15 -15
  107. data/autohotkey/tools/TestRunnerAHK +17 -17
  108. data/autohotkey/tools/TestRunnerAHK2 +17 -17
  109. data/autohotkey/tools/TestRunnerAHK3 +17 -17
  110. data/autohotkey/tools/TestRunnerAHK4 +17 -17
  111. data/autohotkey/tools/TestRunnerAHK5 +17 -17
  112. data/autohotkey/tools/TestRunnerAHK6 +17 -17
  113. data/autohotkey/tools/TlmExtractor +15 -15
  114. data/autohotkey/tools/TlmExtractorAHK +19 -19
  115. data/autohotkey/tools/TlmExtractorAHK2 +16 -16
  116. data/autohotkey/tools/TlmExtractorAHK3 +16 -16
  117. data/autohotkey/tools/TlmGrapher +14 -14
  118. data/autohotkey/tools/TlmGrapherAHK +19 -19
  119. data/autohotkey/tools/TlmGrapherAHK2 +23 -23
  120. data/autohotkey/tools/TlmGrapherAHK3 +17 -17
  121. data/autohotkey/tools/TlmGrapherAHK4 +17 -17
  122. data/autohotkey/tools/TlmViewer +14 -14
  123. data/autohotkey/tools/TlmViewerAHK +28 -28
  124. data/autohotkey/tools/TlmViewerAHK2 +22 -22
  125. data/autohotkey/tools/TlmViewerAHK3 +23 -23
  126. data/autohotkey/tools/TlmViewerAHK4 +22 -22
  127. data/autohotkey/tools/TlmViewerAHK5 +18 -18
  128. data/autohotkey/tools/autohotkey.rb +37 -37
  129. data/autohotkey/tools/cmd_extractor.ahk +33 -33
  130. data/autohotkey/tools/cmd_sender.ahk +182 -182
  131. data/autohotkey/tools/cmd_tlm_server.ahk +90 -90
  132. data/autohotkey/tools/cmd_tlm_server2.ahk +45 -45
  133. data/autohotkey/tools/data_viewer.ahk +141 -141
  134. data/autohotkey/tools/handbook_creator.ahk +32 -32
  135. data/autohotkey/tools/launcher.ahk +41 -41
  136. data/autohotkey/tools/limits_monitor.ahk +123 -123
  137. data/autohotkey/tools/open_gl_builder.ahk +134 -134
  138. data/autohotkey/tools/packet_viewer.ahk +196 -196
  139. data/autohotkey/tools/packet_viewer2.ahk +9 -9
  140. data/autohotkey/tools/replay.ahk +104 -104
  141. data/autohotkey/tools/script_runner.ahk +589 -589
  142. data/autohotkey/tools/script_runner2.ahk +38 -38
  143. data/autohotkey/tools/table_manager.ahk +220 -220
  144. data/autohotkey/tools/test_runner.ahk +262 -262
  145. data/autohotkey/tools/test_runner2.ahk +53 -53
  146. data/autohotkey/tools/test_runner3.ahk +13 -13
  147. data/autohotkey/tools/test_runner5.ahk +8 -8
  148. data/autohotkey/tools/test_runner6.ahk +5 -5
  149. data/autohotkey/tools/tlm_extractor.ahk +296 -296
  150. data/autohotkey/tools/tlm_grapher.ahk +660 -660
  151. data/autohotkey/tools/tlm_grapher2.ahk +115 -115
  152. data/autohotkey/tools/tlm_grapher3.ahk +24 -24
  153. data/autohotkey/tools/tlm_viewer.ahk +133 -133
  154. data/autohotkey/tools/tlm_viewer2.ahk +50 -50
  155. data/autohotkey/tools/tlm_viewer4.ahk +4 -4
  156. data/autohotkey/tools/tlm_viewer5.ahk +20 -20
  157. data/bin/cosmos +96 -96
  158. data/bin/cstol_converter +1166 -1166
  159. data/bin/rubysloc +85 -85
  160. data/cosmos.gemspec +99 -99
  161. data/data/about.txt +4 -4
  162. data/data/crc.txt +326 -326
  163. data/data/diamond.STL +57 -57
  164. data/data/legal.txt +9 -9
  165. data/demo/Gemfile +10 -10
  166. data/demo/Launcher +16 -16
  167. data/demo/Launcher.bat +0 -0
  168. data/demo/Rakefile +77 -77
  169. data/demo/config/data/crc.txt +224 -226
  170. data/demo/config/data/diamond.STL +57 -57
  171. data/demo/config/data/meta_init.txt +4 -4
  172. data/demo/config/system/system.txt +35 -35
  173. data/demo/config/system/system2.txt +33 -33
  174. data/demo/config/targets/COSMOS/cmd_tlm/cosmos_server_cmds.txt +41 -41
  175. data/demo/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +15 -15
  176. data/demo/config/targets/COSMOS/cmd_tlm_server.txt +6 -6
  177. data/demo/config/targets/COSMOS/screens/limits_change.txt +20 -20
  178. data/demo/config/targets/COSMOS/screens/version.txt +19 -19
  179. data/demo/config/targets/COSMOS/target.txt +11 -11
  180. data/demo/config/targets/EXAMPLE/cmd_tlm/example_cmds.txt +2 -2
  181. data/demo/config/targets/EXAMPLE/cmd_tlm/example_tlm.txt +5 -5
  182. data/demo/config/targets/EXAMPLE/cmd_tlm_server.txt +6 -6
  183. data/demo/config/targets/EXAMPLE/lib/example_interface.rb +22 -22
  184. data/demo/config/targets/EXAMPLE/target.txt +6 -6
  185. data/demo/config/targets/INST/cmd_tlm/inst_cmds.txt +121 -121
  186. data/demo/config/targets/INST/cmd_tlm/inst_tlm.txt +247 -247
  187. data/demo/config/targets/INST/cmd_tlm_server.txt +5 -5
  188. data/demo/config/targets/INST/lib/example_limits_response.rb +30 -30
  189. data/demo/config/targets/INST/lib/sim_inst.rb +305 -305
  190. data/demo/config/targets/INST/screens/adcs.txt +46 -46
  191. data/demo/config/targets/INST/screens/array.txt +15 -15
  192. data/demo/config/targets/INST/screens/block.txt +8 -8
  193. data/demo/config/targets/INST/screens/commanding.txt +30 -30
  194. data/demo/config/targets/INST/screens/graphs.txt +14 -14
  195. data/demo/config/targets/INST/screens/ground.txt +25 -25
  196. data/demo/config/targets/INST/screens/hs.txt +44 -44
  197. data/demo/config/targets/INST/screens/latest.txt +23 -23
  198. data/demo/config/targets/INST/screens/other.txt +29 -29
  199. data/demo/config/targets/INST/screens/tabs.txt +70 -70
  200. data/demo/config/targets/INST/target.txt +33 -33
  201. data/demo/config/targets/META/cmd_tlm/meta_cmd.txt +10 -10
  202. data/demo/config/targets/META/cmd_tlm/meta_tlm.txt +13 -13
  203. data/demo/config/targets/SYSTEM/cmd_tlm/limits_groups.txt +7 -7
  204. data/demo/config/targets/SYSTEM/cmd_tlm/override.txt +29 -29
  205. data/demo/config/targets/SYSTEM/screens/status.txt +12 -12
  206. data/demo/config/targets/TEMPLATED/cmd_tlm/templated_cmds.txt +13 -13
  207. data/demo/config/targets/TEMPLATED/cmd_tlm/templated_tlm.txt +3 -3
  208. data/demo/config/targets/TEMPLATED/cmd_tlm_server.txt +6 -6
  209. data/demo/config/targets/TEMPLATED/lib/templated_interface.rb +56 -56
  210. data/demo/config/targets/TEMPLATED/target.txt +6 -6
  211. data/demo/config/tools/cmd_tlm_server/cmd_tlm_server.txt +39 -39
  212. data/demo/config/tools/cmd_tlm_server/cmd_tlm_server2.txt +34 -34
  213. data/demo/config/tools/data_viewer/data_viewer.txt +11 -11
  214. data/demo/config/tools/handbook_creator/handbook_creator.txt +66 -66
  215. data/demo/config/tools/handbook_creator/templates/command_packets.html.erb +88 -88
  216. data/demo/config/tools/handbook_creator/templates/command_toc.html.erb +38 -38
  217. data/demo/config/tools/handbook_creator/templates/footer.html.erb +9 -9
  218. data/demo/config/tools/handbook_creator/templates/header.html.erb +25 -25
  219. data/demo/config/tools/handbook_creator/templates/limits_groups.html.erb +13 -13
  220. data/demo/config/tools/handbook_creator/templates/nav.html.erb +27 -27
  221. data/demo/config/tools/handbook_creator/templates/overview.html.erb +1 -1
  222. data/demo/config/tools/handbook_creator/templates/pdf_cover.html.erb +23 -23
  223. data/demo/config/tools/handbook_creator/templates/pdf_footer.html.erb +33 -33
  224. data/demo/config/tools/handbook_creator/templates/pdf_header.html.erb +41 -41
  225. data/demo/config/tools/handbook_creator/templates/telemetry_packets.html.erb +82 -82
  226. data/demo/config/tools/handbook_creator/templates/telemetry_toc.html.erb +38 -38
  227. data/demo/config/tools/handbook_creator/templates/title.html.erb +1 -1
  228. data/demo/config/tools/launcher/launcher.txt +45 -45
  229. data/demo/config/tools/launcher/launcher2.txt +45 -45
  230. data/demo/config/tools/script_runner/script_runner.txt +3 -3
  231. data/demo/config/tools/table_manager/ConfigTables_def.txt +8 -8
  232. data/demo/config/tools/table_manager/ExampleTableDefinition.txt +24 -24
  233. data/demo/config/tools/table_manager/MCConfigurationTable_fsw1_def.txt +25 -25
  234. data/demo/config/tools/table_manager/MCConfigurationTable_fsw2_def.txt +25 -25
  235. data/demo/config/tools/table_manager/PPSSelectionTable_def.txt +8 -8
  236. data/demo/config/tools/table_manager/TLMMonitoringTable_def.txt +248 -248
  237. data/demo/config/tools/test_runner/test_runner.txt +17 -17
  238. data/demo/config/tools/tlm_extractor/tlm_extractor.txt +13 -13
  239. data/demo/config/tools/tlm_extractor/tlm_extractor2.txt +2 -2
  240. data/demo/config/tools/tlm_extractor/tlm_extractor3.txt +2 -2
  241. data/demo/config/tools/tlm_extractor/tlm_extractor4.txt +2 -2
  242. data/demo/config/tools/tlm_viewer/tlm_viewer.txt +41 -41
  243. data/demo/lib/example_background_task.rb +57 -57
  244. data/demo/lib/example_target.rb +113 -113
  245. data/demo/lib/scpi_target.rb +74 -74
  246. data/demo/lib/user_version.rb +3 -3
  247. data/demo/procedures/checks.rb +11 -11
  248. data/demo/procedures/clear_util.rb +7 -7
  249. data/demo/procedures/collect.rb +18 -18
  250. data/demo/procedures/collect_util.rb +14 -14
  251. data/demo/procedures/cosmos_api_test.rb +293 -293
  252. data/demo/procedures/disconnect.rb +29 -29
  253. data/demo/procedures/example_test.rb +183 -183
  254. data/demo/procedures/plot_test.rb +8 -8
  255. data/demo/procedures/run_example_test.rb +3 -3
  256. data/demo/procedures/test.rb +51 -51
  257. data/demo/tools/CmdExtractor +16 -16
  258. data/demo/tools/CmdExtractor.bat +0 -0
  259. data/demo/tools/CmdSender +16 -16
  260. data/demo/tools/CmdSender.bat +0 -0
  261. data/demo/tools/CmdTlmServer +16 -16
  262. data/demo/tools/CmdTlmServer.bat +0 -0
  263. data/demo/tools/DataViewer +16 -16
  264. data/demo/tools/DataViewer.bat +0 -0
  265. data/demo/tools/ExampleTarget +16 -16
  266. data/demo/tools/ExampleTarget.bat +0 -0
  267. data/demo/tools/HandbookCreator +16 -16
  268. data/demo/tools/HandbookCreator.bat +0 -0
  269. data/demo/tools/Launcher +16 -16
  270. data/demo/tools/Launcher.bat +0 -0
  271. data/demo/tools/LimitsMonitor +16 -16
  272. data/demo/tools/LimitsMonitor.bat +0 -0
  273. data/demo/tools/OpenGLBuilder +16 -16
  274. data/demo/tools/OpenGLBuilder.bat +0 -0
  275. data/demo/tools/PacketViewer +16 -16
  276. data/demo/tools/PacketViewer.bat +0 -0
  277. data/demo/tools/Replay +16 -16
  278. data/demo/tools/Replay.bat +0 -0
  279. data/demo/tools/ScpiTarget +16 -16
  280. data/demo/tools/ScpiTarget.bat +0 -0
  281. data/demo/tools/ScriptRunner +16 -16
  282. data/demo/tools/ScriptRunner.bat +0 -0
  283. data/demo/tools/TableManager +16 -16
  284. data/demo/tools/TableManager.bat +0 -0
  285. data/demo/tools/TestRunner +16 -16
  286. data/demo/tools/TestRunner.bat +0 -0
  287. data/demo/tools/TlmExtractor +16 -16
  288. data/demo/tools/TlmExtractor.bat +0 -0
  289. data/demo/tools/TlmGrapher +16 -16
  290. data/demo/tools/TlmGrapher.bat +0 -0
  291. data/demo/tools/TlmViewer +16 -16
  292. data/demo/tools/TlmViewer.bat +0 -0
  293. data/demo/tools/ToolLaunch.bat +14 -5
  294. data/demo/tools/mac/CmdExtractor.app/Contents/Info.plist +38 -38
  295. data/demo/tools/mac/CmdExtractor.app/Contents/MacOS/CmdExtractor.rb +16 -16
  296. data/demo/tools/mac/CmdExtractor.app/Contents/MacOS/main.sh +10 -10
  297. data/demo/tools/mac/CmdExtractor.app/Contents/MacOS/tool_launch.rb +38 -38
  298. data/demo/tools/mac/CmdSender.app/Contents/Info.plist +38 -38
  299. data/demo/tools/mac/CmdSender.app/Contents/MacOS/CmdSender.rb +16 -16
  300. data/demo/tools/mac/CmdSender.app/Contents/MacOS/main.sh +10 -10
  301. data/demo/tools/mac/CmdSender.app/Contents/MacOS/tool_launch.rb +38 -38
  302. data/demo/tools/mac/CmdTlmServer.app/Contents/Info.plist +38 -38
  303. data/demo/tools/mac/CmdTlmServer.app/Contents/MacOS/CmdTlmServer.rb +16 -16
  304. data/demo/tools/mac/CmdTlmServer.app/Contents/MacOS/main.sh +10 -10
  305. data/demo/tools/mac/CmdTlmServer.app/Contents/MacOS/tool_launch.rb +38 -38
  306. data/demo/tools/mac/DataViewer.app/Contents/Info.plist +38 -38
  307. data/demo/tools/mac/DataViewer.app/Contents/MacOS/DataViewer.rb +16 -16
  308. data/demo/tools/mac/DataViewer.app/Contents/MacOS/main.sh +10 -10
  309. data/demo/tools/mac/DataViewer.app/Contents/MacOS/tool_launch.rb +38 -38
  310. data/demo/tools/mac/HandbookCreator.app/Contents/Info.plist +38 -38
  311. data/demo/tools/mac/HandbookCreator.app/Contents/MacOS/HandbookCreator.rb +16 -16
  312. data/demo/tools/mac/HandbookCreator.app/Contents/MacOS/main.sh +10 -10
  313. data/demo/tools/mac/HandbookCreator.app/Contents/MacOS/tool_launch.rb +38 -38
  314. data/demo/tools/mac/Launcher.app/Contents/Info.plist +38 -38
  315. data/demo/tools/mac/Launcher.app/Contents/MacOS/Launcher.rb +16 -16
  316. data/demo/tools/mac/Launcher.app/Contents/MacOS/main.sh +10 -10
  317. data/demo/tools/mac/Launcher.app/Contents/MacOS/tool_launch.rb +38 -38
  318. data/demo/tools/mac/LimitsMonitor.app/Contents/Info.plist +38 -38
  319. data/demo/tools/mac/LimitsMonitor.app/Contents/MacOS/LimitsMonitor.rb +16 -16
  320. data/demo/tools/mac/LimitsMonitor.app/Contents/MacOS/main.sh +10 -10
  321. data/demo/tools/mac/LimitsMonitor.app/Contents/MacOS/tool_launch.rb +38 -38
  322. data/demo/tools/mac/OpenGLBuilder.app/Contents/Info.plist +38 -38
  323. data/demo/tools/mac/OpenGLBuilder.app/Contents/MacOS/OpenGLBuilder.rb +16 -16
  324. data/demo/tools/mac/OpenGLBuilder.app/Contents/MacOS/main.sh +10 -10
  325. data/demo/tools/mac/OpenGLBuilder.app/Contents/MacOS/tool_launch.rb +38 -38
  326. data/demo/tools/mac/PacketViewer.app/Contents/Info.plist +38 -38
  327. data/demo/tools/mac/PacketViewer.app/Contents/MacOS/PacketViewer.rb +16 -16
  328. data/demo/tools/mac/PacketViewer.app/Contents/MacOS/main.sh +10 -10
  329. data/demo/tools/mac/PacketViewer.app/Contents/MacOS/tool_launch.rb +38 -38
  330. data/demo/tools/mac/Replay.app/Contents/Info.plist +38 -38
  331. data/demo/tools/mac/Replay.app/Contents/MacOS/Replay.rb +16 -16
  332. data/demo/tools/mac/Replay.app/Contents/MacOS/main.sh +10 -10
  333. data/demo/tools/mac/Replay.app/Contents/MacOS/tool_launch.rb +38 -38
  334. data/demo/tools/mac/ScriptRunner.app/Contents/Info.plist +38 -38
  335. data/demo/tools/mac/ScriptRunner.app/Contents/MacOS/ScriptRunner.rb +16 -16
  336. data/demo/tools/mac/ScriptRunner.app/Contents/MacOS/main.sh +10 -10
  337. data/demo/tools/mac/ScriptRunner.app/Contents/MacOS/tool_launch.rb +38 -38
  338. data/demo/tools/mac/TableManager.app/Contents/Info.plist +38 -38
  339. data/demo/tools/mac/TableManager.app/Contents/MacOS/TableManager.rb +16 -16
  340. data/demo/tools/mac/TableManager.app/Contents/MacOS/main.sh +10 -10
  341. data/demo/tools/mac/TableManager.app/Contents/MacOS/tool_launch.rb +38 -38
  342. data/demo/tools/mac/TestRunner.app/Contents/Info.plist +38 -38
  343. data/demo/tools/mac/TestRunner.app/Contents/MacOS/TestRunner.rb +16 -16
  344. data/demo/tools/mac/TestRunner.app/Contents/MacOS/main.sh +10 -10
  345. data/demo/tools/mac/TestRunner.app/Contents/MacOS/tool_launch.rb +38 -38
  346. data/demo/tools/mac/TlmExtractor.app/Contents/Info.plist +38 -38
  347. data/demo/tools/mac/TlmExtractor.app/Contents/MacOS/TlmExtractor.rb +16 -16
  348. data/demo/tools/mac/TlmExtractor.app/Contents/MacOS/main.sh +10 -10
  349. data/demo/tools/mac/TlmExtractor.app/Contents/MacOS/tool_launch.rb +38 -38
  350. data/demo/tools/mac/TlmGrapher.app/Contents/Info.plist +38 -38
  351. data/demo/tools/mac/TlmGrapher.app/Contents/MacOS/TlmGrapher.rb +16 -16
  352. data/demo/tools/mac/TlmGrapher.app/Contents/MacOS/main.sh +10 -10
  353. data/demo/tools/mac/TlmGrapher.app/Contents/MacOS/tool_launch.rb +38 -38
  354. data/demo/tools/mac/TlmViewer.app/Contents/Info.plist +38 -38
  355. data/demo/tools/mac/TlmViewer.app/Contents/MacOS/TlmViewer.rb +16 -16
  356. data/demo/tools/mac/TlmViewer.app/Contents/MacOS/main.sh +10 -10
  357. data/demo/tools/mac/TlmViewer.app/Contents/MacOS/tool_launch.rb +38 -38
  358. data/demo/tools/tool_launch.rb +38 -38
  359. data/ext/cosmos/ext/array/array.c +111 -111
  360. data/ext/cosmos/ext/array/extconf.rb +13 -13
  361. data/ext/cosmos/ext/buffered_file/buffered_file.c +167 -167
  362. data/ext/cosmos/ext/buffered_file/extconf.rb +13 -13
  363. data/ext/cosmos/ext/config_parser/config_parser.c +237 -237
  364. data/ext/cosmos/ext/config_parser/extconf.rb +13 -13
  365. data/ext/cosmos/ext/cosmos_io/cosmos_io.c +117 -117
  366. data/ext/cosmos/ext/cosmos_io/extconf.rb +13 -13
  367. data/ext/cosmos/ext/crc/crc.c +341 -341
  368. data/ext/cosmos/ext/crc/extconf.rb +12 -12
  369. data/ext/cosmos/ext/line_graph/extconf.rb +13 -13
  370. data/ext/cosmos/ext/line_graph/line_graph.c +501 -501
  371. data/ext/cosmos/ext/low_fragmentation_array/extconf.rb +12 -12
  372. data/ext/cosmos/ext/low_fragmentation_array/low_fragmentation_array.c +265 -265
  373. data/ext/cosmos/ext/packet/extconf.rb +13 -13
  374. data/ext/cosmos/ext/packet/packet.c +339 -339
  375. data/ext/cosmos/ext/platform/extconf.rb +13 -13
  376. data/ext/cosmos/ext/platform/platform.c +101 -101
  377. data/ext/cosmos/ext/polynomial_conversion/extconf.rb +13 -13
  378. data/ext/cosmos/ext/polynomial_conversion/polynomial_conversion.c +73 -73
  379. data/ext/cosmos/ext/string/extconf.rb +13 -13
  380. data/ext/cosmos/ext/string/string.c +49 -49
  381. data/ext/cosmos/ext/structure/structure.c +1428 -1428
  382. data/ext/cosmos/ext/tabbed_plots_config/extconf.rb +13 -13
  383. data/ext/cosmos/ext/tabbed_plots_config/tabbed_plots_config.c +51 -51
  384. data/ext/cosmos/ext/telemetry/extconf.rb +13 -13
  385. data/ext/cosmos/ext/telemetry/telemetry.c +307 -307
  386. data/ext/mkrf_conf.rb +40 -40
  387. data/install/Gemfile +10 -10
  388. data/install/Launcher +16 -16
  389. data/install/Launcher.bat +0 -0
  390. data/install/Rakefile +77 -77
  391. data/install/config/data/crc.txt +151 -151
  392. data/install/config/system/system.txt +29 -29
  393. data/install/config/targets/COSMOS/cmd_tlm/cosmos_server_cmds.txt +41 -41
  394. data/install/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +15 -15
  395. data/install/config/targets/COSMOS/cmd_tlm_server.txt +6 -6
  396. data/install/config/targets/COSMOS/screens/limits_change.txt +20 -20
  397. data/install/config/targets/COSMOS/screens/version.txt +19 -19
  398. data/install/config/targets/COSMOS/target.txt +8 -8
  399. data/install/config/tools/cmd_tlm_server/cmd_tlm_server.txt +2 -2
  400. data/install/config/tools/data_viewer/data_viewer.txt +3 -3
  401. data/install/config/tools/handbook_creator/handbook_creator.txt +49 -49
  402. data/install/config/tools/handbook_creator/templates/command_packets.html.erb +86 -86
  403. data/install/config/tools/handbook_creator/templates/command_toc.html.erb +38 -38
  404. data/install/config/tools/handbook_creator/templates/footer.html.erb +9 -9
  405. data/install/config/tools/handbook_creator/templates/header.html.erb +25 -25
  406. data/install/config/tools/handbook_creator/templates/limits_groups.html.erb +13 -13
  407. data/install/config/tools/handbook_creator/templates/nav.html.erb +27 -27
  408. data/install/config/tools/handbook_creator/templates/overview.html.erb +1 -1
  409. data/install/config/tools/handbook_creator/templates/pdf_cover.html.erb +23 -23
  410. data/install/config/tools/handbook_creator/templates/pdf_footer.html.erb +33 -33
  411. data/install/config/tools/handbook_creator/templates/pdf_header.html.erb +41 -41
  412. data/install/config/tools/handbook_creator/templates/telemetry_packets.html.erb +80 -80
  413. data/install/config/tools/handbook_creator/templates/telemetry_toc.html.erb +38 -38
  414. data/install/config/tools/handbook_creator/templates/title.html.erb +1 -1
  415. data/install/config/tools/launcher/launcher.txt +40 -40
  416. data/install/config/tools/script_runner/script_runner.txt +3 -3
  417. data/install/config/tools/test_runner/test_runner.txt +8 -8
  418. data/install/config/tools/tlm_viewer/tlm_viewer.txt +5 -5
  419. data/install/lib/user_version.rb +3 -3
  420. data/install/tools/CmdExtractor +16 -16
  421. data/install/tools/CmdExtractor.bat +0 -0
  422. data/install/tools/CmdSender +16 -16
  423. data/install/tools/CmdSender.bat +0 -0
  424. data/install/tools/CmdTlmServer +16 -16
  425. data/install/tools/CmdTlmServer.bat +0 -0
  426. data/install/tools/DataViewer +16 -16
  427. data/install/tools/DataViewer.bat +0 -0
  428. data/install/tools/HandbookCreator +16 -16
  429. data/install/tools/HandbookCreator.bat +0 -0
  430. data/install/tools/Launcher +16 -16
  431. data/install/tools/Launcher.bat +0 -0
  432. data/install/tools/LimitsMonitor +16 -16
  433. data/install/tools/LimitsMonitor.bat +0 -0
  434. data/install/tools/OpenGLBuilder +16 -16
  435. data/install/tools/OpenGLBuilder.bat +0 -0
  436. data/install/tools/PacketViewer +16 -16
  437. data/install/tools/PacketViewer.bat +0 -0
  438. data/install/tools/Replay +16 -16
  439. data/install/tools/Replay.bat +0 -0
  440. data/install/tools/ScriptRunner +16 -16
  441. data/install/tools/ScriptRunner.bat +0 -0
  442. data/install/tools/TableManager +16 -16
  443. data/install/tools/TableManager.bat +0 -0
  444. data/install/tools/TestRunner +16 -16
  445. data/install/tools/TestRunner.bat +0 -0
  446. data/install/tools/TlmExtractor +16 -16
  447. data/install/tools/TlmExtractor.bat +0 -0
  448. data/install/tools/TlmGrapher +16 -16
  449. data/install/tools/TlmGrapher.bat +0 -0
  450. data/install/tools/TlmViewer +16 -16
  451. data/install/tools/TlmViewer.bat +0 -0
  452. data/install/tools/ToolLaunch.bat +14 -5
  453. data/install/tools/mac/CmdExtractor.app/Contents/Info.plist +38 -38
  454. data/install/tools/mac/CmdExtractor.app/Contents/MacOS/CmdExtractor.rb +16 -16
  455. data/install/tools/mac/CmdExtractor.app/Contents/MacOS/main.sh +10 -10
  456. data/install/tools/mac/CmdExtractor.app/Contents/MacOS/tool_launch.rb +38 -38
  457. data/install/tools/mac/CmdSender.app/Contents/Info.plist +38 -38
  458. data/install/tools/mac/CmdSender.app/Contents/MacOS/CmdSender.rb +16 -16
  459. data/install/tools/mac/CmdSender.app/Contents/MacOS/main.sh +10 -10
  460. data/install/tools/mac/CmdSender.app/Contents/MacOS/tool_launch.rb +38 -38
  461. data/install/tools/mac/CmdTlmServer.app/Contents/Info.plist +38 -38
  462. data/install/tools/mac/CmdTlmServer.app/Contents/MacOS/CmdTlmServer.rb +16 -16
  463. data/install/tools/mac/CmdTlmServer.app/Contents/MacOS/main.sh +10 -10
  464. data/install/tools/mac/CmdTlmServer.app/Contents/MacOS/tool_launch.rb +38 -38
  465. data/install/tools/mac/DataViewer.app/Contents/Info.plist +38 -38
  466. data/install/tools/mac/DataViewer.app/Contents/MacOS/DataViewer.rb +16 -16
  467. data/install/tools/mac/DataViewer.app/Contents/MacOS/main.sh +10 -10
  468. data/install/tools/mac/DataViewer.app/Contents/MacOS/tool_launch.rb +38 -38
  469. data/install/tools/mac/HandbookCreator.app/Contents/Info.plist +38 -38
  470. data/install/tools/mac/HandbookCreator.app/Contents/MacOS/HandbookCreator.rb +16 -16
  471. data/install/tools/mac/HandbookCreator.app/Contents/MacOS/main.sh +10 -10
  472. data/install/tools/mac/HandbookCreator.app/Contents/MacOS/tool_launch.rb +38 -38
  473. data/install/tools/mac/Launcher.app/Contents/Info.plist +38 -38
  474. data/install/tools/mac/Launcher.app/Contents/MacOS/Launcher.rb +16 -16
  475. data/install/tools/mac/Launcher.app/Contents/MacOS/main.sh +10 -10
  476. data/install/tools/mac/Launcher.app/Contents/MacOS/tool_launch.rb +38 -38
  477. data/install/tools/mac/LimitsMonitor.app/Contents/Info.plist +38 -38
  478. data/install/tools/mac/LimitsMonitor.app/Contents/MacOS/LimitsMonitor.rb +16 -16
  479. data/install/tools/mac/LimitsMonitor.app/Contents/MacOS/main.sh +10 -10
  480. data/install/tools/mac/LimitsMonitor.app/Contents/MacOS/tool_launch.rb +38 -38
  481. data/install/tools/mac/OpenGLBuilder.app/Contents/Info.plist +38 -38
  482. data/install/tools/mac/OpenGLBuilder.app/Contents/MacOS/OpenGLBuilder.rb +16 -16
  483. data/install/tools/mac/OpenGLBuilder.app/Contents/MacOS/main.sh +10 -10
  484. data/install/tools/mac/OpenGLBuilder.app/Contents/MacOS/tool_launch.rb +38 -38
  485. data/install/tools/mac/PacketViewer.app/Contents/Info.plist +38 -38
  486. data/install/tools/mac/PacketViewer.app/Contents/MacOS/PacketViewer.rb +16 -16
  487. data/install/tools/mac/PacketViewer.app/Contents/MacOS/main.sh +10 -10
  488. data/install/tools/mac/PacketViewer.app/Contents/MacOS/tool_launch.rb +38 -38
  489. data/install/tools/mac/Replay.app/Contents/Info.plist +38 -38
  490. data/install/tools/mac/Replay.app/Contents/MacOS/Replay.rb +16 -16
  491. data/install/tools/mac/Replay.app/Contents/MacOS/main.sh +10 -10
  492. data/install/tools/mac/Replay.app/Contents/MacOS/tool_launch.rb +38 -38
  493. data/install/tools/mac/ScriptRunner.app/Contents/Info.plist +38 -38
  494. data/install/tools/mac/ScriptRunner.app/Contents/MacOS/ScriptRunner.rb +16 -16
  495. data/install/tools/mac/ScriptRunner.app/Contents/MacOS/main.sh +10 -10
  496. data/install/tools/mac/ScriptRunner.app/Contents/MacOS/tool_launch.rb +38 -38
  497. data/install/tools/mac/TableManager.app/Contents/Info.plist +38 -38
  498. data/install/tools/mac/TableManager.app/Contents/MacOS/TableManager.rb +16 -16
  499. data/install/tools/mac/TableManager.app/Contents/MacOS/main.sh +10 -10
  500. data/install/tools/mac/TableManager.app/Contents/MacOS/tool_launch.rb +38 -38
  501. data/install/tools/mac/TestRunner.app/Contents/Info.plist +38 -38
  502. data/install/tools/mac/TestRunner.app/Contents/MacOS/TestRunner.rb +16 -16
  503. data/install/tools/mac/TestRunner.app/Contents/MacOS/main.sh +10 -10
  504. data/install/tools/mac/TestRunner.app/Contents/MacOS/tool_launch.rb +38 -38
  505. data/install/tools/mac/TlmExtractor.app/Contents/Info.plist +38 -38
  506. data/install/tools/mac/TlmExtractor.app/Contents/MacOS/TlmExtractor.rb +16 -16
  507. data/install/tools/mac/TlmExtractor.app/Contents/MacOS/main.sh +10 -10
  508. data/install/tools/mac/TlmExtractor.app/Contents/MacOS/tool_launch.rb +38 -38
  509. data/install/tools/mac/TlmGrapher.app/Contents/Info.plist +38 -38
  510. data/install/tools/mac/TlmGrapher.app/Contents/MacOS/TlmGrapher.rb +16 -16
  511. data/install/tools/mac/TlmGrapher.app/Contents/MacOS/main.sh +10 -10
  512. data/install/tools/mac/TlmGrapher.app/Contents/MacOS/tool_launch.rb +38 -38
  513. data/install/tools/mac/TlmViewer.app/Contents/Info.plist +38 -38
  514. data/install/tools/mac/TlmViewer.app/Contents/MacOS/TlmViewer.rb +16 -16
  515. data/install/tools/mac/TlmViewer.app/Contents/MacOS/main.sh +10 -10
  516. data/install/tools/mac/TlmViewer.app/Contents/MacOS/tool_launch.rb +38 -38
  517. data/install/tools/tool_launch.rb +38 -38
  518. data/lib/cosmos.rb +63 -63
  519. data/lib/cosmos/ccsds/ccsds_packet.rb +63 -63
  520. data/lib/cosmos/ccsds/ccsds_parser.rb +143 -143
  521. data/lib/cosmos/config/config_parser.rb +324 -324
  522. data/lib/cosmos/conversions.rb +13 -13
  523. data/lib/cosmos/conversions/conversion.rb +47 -47
  524. data/lib/cosmos/conversions/generic_conversion.rb +55 -55
  525. data/lib/cosmos/conversions/new_packet_log_conversion.rb +45 -45
  526. data/lib/cosmos/conversions/polynomial_conversion.rb +57 -57
  527. data/lib/cosmos/conversions/processor_conversion.rb +46 -46
  528. data/lib/cosmos/conversions/received_count_conversion.rb +33 -33
  529. data/lib/cosmos/conversions/received_time_formatted_conversion.rb +37 -37
  530. data/lib/cosmos/conversions/received_time_seconds_conversion.rb +37 -37
  531. data/lib/cosmos/conversions/segmented_polynomial_conversion.rb +128 -128
  532. data/lib/cosmos/conversions/unix_time_conversion.rb +50 -50
  533. data/lib/cosmos/conversions/unix_time_formatted_conversion.rb +44 -44
  534. data/lib/cosmos/conversions/unix_time_seconds_conversion.rb +44 -44
  535. data/lib/cosmos/core_ext.rb +18 -18
  536. data/lib/cosmos/core_ext/array.rb +354 -354
  537. data/lib/cosmos/core_ext/class.rb +51 -51
  538. data/lib/cosmos/core_ext/cosmos_io.rb +29 -29
  539. data/lib/cosmos/core_ext/exception.rb +52 -52
  540. data/lib/cosmos/core_ext/file.rb +75 -75
  541. data/lib/cosmos/core_ext/hash.rb +28 -28
  542. data/lib/cosmos/core_ext/io.rb +75 -75
  543. data/lib/cosmos/core_ext/kernel.rb +38 -38
  544. data/lib/cosmos/core_ext/math.rb +119 -119
  545. data/lib/cosmos/core_ext/matrix.rb +146 -146
  546. data/lib/cosmos/core_ext/objectspace.rb +29 -29
  547. data/lib/cosmos/core_ext/range.rb +22 -22
  548. data/lib/cosmos/core_ext/socket.rb +32 -32
  549. data/lib/cosmos/core_ext/string.rb +311 -311
  550. data/lib/cosmos/core_ext/stringio.rb +24 -24
  551. data/lib/cosmos/core_ext/time.rb +448 -448
  552. data/lib/cosmos/gui/choosers/combobox_chooser.rb +130 -130
  553. data/lib/cosmos/gui/choosers/file_chooser.rb +68 -68
  554. data/lib/cosmos/gui/choosers/float_chooser.rb +82 -82
  555. data/lib/cosmos/gui/choosers/integer_chooser.rb +80 -80
  556. data/lib/cosmos/gui/choosers/string_chooser.rb +53 -53
  557. data/lib/cosmos/gui/choosers/telemetry_chooser.rb +326 -326
  558. data/lib/cosmos/gui/dialogs/about_dialog.rb +137 -137
  559. data/lib/cosmos/gui/dialogs/calendar_dialog.rb +136 -136
  560. data/lib/cosmos/gui/dialogs/cmd_details_dialog.rb +52 -52
  561. data/lib/cosmos/gui/dialogs/cmd_tlm_raw_dialog.rb +149 -149
  562. data/lib/cosmos/gui/dialogs/details_dialog.rb +174 -174
  563. data/lib/cosmos/gui/dialogs/exception_dialog.rb +97 -97
  564. data/lib/cosmos/gui/dialogs/exception_list_dialog.rb +59 -59
  565. data/lib/cosmos/gui/dialogs/find_replace_dialog.rb +260 -260
  566. data/lib/cosmos/gui/dialogs/legal_dialog.rb +169 -169
  567. data/lib/cosmos/gui/dialogs/packet_log_dialog.rb +118 -118
  568. data/lib/cosmos/gui/dialogs/progress_dialog.rb +276 -276
  569. data/lib/cosmos/gui/dialogs/pry_dialog.rb +165 -165
  570. data/lib/cosmos/gui/dialogs/scroll_text_dialog.rb +37 -37
  571. data/lib/cosmos/gui/dialogs/select_dialog.rb +54 -54
  572. data/lib/cosmos/gui/dialogs/set_tlm_dialog.rb +131 -131
  573. data/lib/cosmos/gui/dialogs/splash.rb +135 -135
  574. data/lib/cosmos/gui/dialogs/tlm_details_dialog.rb +206 -206
  575. data/lib/cosmos/gui/dialogs/tlm_edit_dialog.rb +81 -81
  576. data/lib/cosmos/gui/line_graph/line_graph.rb +456 -456
  577. data/lib/cosmos/gui/line_graph/line_graph_dialog.rb +34 -34
  578. data/lib/cosmos/gui/line_graph/line_graph_drawing.rb +473 -473
  579. data/lib/cosmos/gui/line_graph/line_graph_popups.rb +116 -116
  580. data/lib/cosmos/gui/line_graph/line_graph_scaling.rb +451 -451
  581. data/lib/cosmos/gui/line_graph/line_graph_script.rb +26 -26
  582. data/lib/cosmos/gui/line_graph/lines.rb +290 -290
  583. data/lib/cosmos/gui/line_graph/overview_graph.rb +469 -469
  584. data/lib/cosmos/gui/opengl/earth_model.rb +22 -22
  585. data/lib/cosmos/gui/opengl/gl_bounds.rb +67 -67
  586. data/lib/cosmos/gui/opengl/gl_light.rb +39 -39
  587. data/lib/cosmos/gui/opengl/gl_material.rb +29 -29
  588. data/lib/cosmos/gui/opengl/gl_scene.rb +72 -72
  589. data/lib/cosmos/gui/opengl/gl_shape.rb +146 -146
  590. data/lib/cosmos/gui/opengl/gl_viewer.rb +724 -724
  591. data/lib/cosmos/gui/opengl/gl_viewport.rb +35 -35
  592. data/lib/cosmos/gui/opengl/moon_model.rb +22 -22
  593. data/lib/cosmos/gui/opengl/opengl.rb +8 -8
  594. data/lib/cosmos/gui/opengl/stl_reader.rb +211 -211
  595. data/lib/cosmos/gui/opengl/stl_shape.rb +124 -124
  596. data/lib/cosmos/gui/opengl/texture_mapped_sphere.rb +202 -202
  597. data/lib/cosmos/gui/qt.rb +860 -860
  598. data/lib/cosmos/gui/qt_tool.rb +380 -380
  599. data/lib/cosmos/gui/text/completion.rb +381 -381
  600. data/lib/cosmos/gui/text/completion_line_edit.rb +30 -30
  601. data/lib/cosmos/gui/text/completion_text_edit.rb +179 -179
  602. data/lib/cosmos/gui/text/ruby_editor.rb +415 -415
  603. data/lib/cosmos/gui/utilities/screenshot.rb +25 -25
  604. data/lib/cosmos/gui/utilities/script_module_gui.rb +330 -330
  605. data/lib/cosmos/gui/widgets/full_text_search_line_edit.rb +161 -161
  606. data/lib/cosmos/gui/widgets/packet_log_frame.rb +305 -305
  607. data/lib/cosmos/gui/widgets/realtime_button_bar.rb +98 -98
  608. data/lib/cosmos/interfaces.rb +11 -11
  609. data/lib/cosmos/interfaces/cmd_tlm_server_interface.rb +153 -153
  610. data/lib/cosmos/interfaces/interface.rb +225 -225
  611. data/lib/cosmos/interfaces/linc_interface.rb +360 -360
  612. data/lib/cosmos/interfaces/serial_interface.rb +76 -76
  613. data/lib/cosmos/interfaces/simulated_target_interface.rb +129 -129
  614. data/lib/cosmos/interfaces/stream_interface.rb +136 -136
  615. data/lib/cosmos/interfaces/tcpip_client_interface.rb +60 -60
  616. data/lib/cosmos/interfaces/tcpip_server_interface.rb +164 -164
  617. data/lib/cosmos/interfaces/udp_interface.rb +161 -161
  618. data/lib/cosmos/io/buffered_file.rb +11 -11
  619. data/lib/cosmos/io/cosmos_snmp.rb +50 -50
  620. data/lib/cosmos/io/io_multiplexer.rb +89 -89
  621. data/lib/cosmos/io/json_drb.rb +376 -376
  622. data/lib/cosmos/io/json_drb_object.rb +198 -198
  623. data/lib/cosmos/io/json_rpc.rb +365 -365
  624. data/lib/cosmos/io/posix_serial_driver.rb +145 -145
  625. data/lib/cosmos/io/raw_logger.rb +174 -174
  626. data/lib/cosmos/io/raw_logger_pair.rb +71 -71
  627. data/lib/cosmos/io/serial_driver.rb +85 -85
  628. data/lib/cosmos/io/stderr.rb +36 -36
  629. data/lib/cosmos/io/stdout.rb +36 -36
  630. data/lib/cosmos/io/tcpip_server.rb +571 -571
  631. data/lib/cosmos/io/udp_sockets.rb +152 -152
  632. data/lib/cosmos/io/win32_serial_driver.rb +145 -145
  633. data/lib/cosmos/packet_logs.rb +7 -7
  634. data/lib/cosmos/packet_logs/ccsds_log_reader.rb +104 -104
  635. data/lib/cosmos/packet_logs/meta_packet_log_writer.rb +107 -107
  636. data/lib/cosmos/packet_logs/packet_log_reader.rb +450 -450
  637. data/lib/cosmos/packet_logs/packet_log_writer.rb +323 -323
  638. data/lib/cosmos/packet_logs/packet_log_writer_pair.rb +30 -30
  639. data/lib/cosmos/packets/binary_accessor.rb +634 -634
  640. data/lib/cosmos/packets/commands.rb +293 -293
  641. data/lib/cosmos/packets/limits.rb +267 -267
  642. data/lib/cosmos/packets/limits_response.rb +38 -38
  643. data/lib/cosmos/packets/packet.rb +786 -786
  644. data/lib/cosmos/packets/packet_config.rb +482 -482
  645. data/lib/cosmos/packets/packet_item.rb +317 -317
  646. data/lib/cosmos/packets/packet_item_limits.rb +128 -128
  647. data/lib/cosmos/packets/parsers/format_string_parser.rb +58 -58
  648. data/lib/cosmos/packets/parsers/limits_parser.rb +146 -146
  649. data/lib/cosmos/packets/parsers/limits_response_parser.rb +52 -52
  650. data/lib/cosmos/packets/parsers/macro_parser.rb +116 -116
  651. data/lib/cosmos/packets/parsers/packet_item_parser.rb +215 -215
  652. data/lib/cosmos/packets/parsers/packet_parser.rb +123 -123
  653. data/lib/cosmos/packets/parsers/processor_parser.rb +63 -63
  654. data/lib/cosmos/packets/parsers/state_parser.rb +116 -116
  655. data/lib/cosmos/packets/structure.rb +458 -458
  656. data/lib/cosmos/packets/structure_item.rb +233 -233
  657. data/lib/cosmos/packets/telemetry.rb +350 -350
  658. data/lib/cosmos/processors.rb +6 -6
  659. data/lib/cosmos/processors/new_packet_log_processor.rb +34 -34
  660. data/lib/cosmos/processors/processor.rb +71 -71
  661. data/lib/cosmos/processors/statistics_processor.rb +65 -65
  662. data/lib/cosmos/processors/watermark_processor.rb +44 -44
  663. data/lib/cosmos/script.rb +9 -9
  664. data/lib/cosmos/script/cmd_tlm_server.rb +110 -110
  665. data/lib/cosmos/script/commands.rb +184 -184
  666. data/lib/cosmos/script/extract.rb +123 -123
  667. data/lib/cosmos/script/limits.rb +114 -114
  668. data/lib/cosmos/script/script.rb +76 -76
  669. data/lib/cosmos/script/scripting.rb +897 -897
  670. data/lib/cosmos/script/telemetry.rb +174 -174
  671. data/lib/cosmos/script/tools.rb +138 -138
  672. data/lib/cosmos/streams/burst_stream_protocol.rb +25 -25
  673. data/lib/cosmos/streams/fixed_stream_protocol.rb +111 -111
  674. data/lib/cosmos/streams/length_stream_protocol.rb +140 -140
  675. data/lib/cosmos/streams/preidentified_stream_protocol.rb +118 -118
  676. data/lib/cosmos/streams/serial_stream.rb +157 -157
  677. data/lib/cosmos/streams/stream.rb +63 -63
  678. data/lib/cosmos/streams/stream_protocol.rb +373 -373
  679. data/lib/cosmos/streams/tcpip_client_stream.rb +113 -113
  680. data/lib/cosmos/streams/tcpip_socket_stream.rb +143 -143
  681. data/lib/cosmos/streams/template_stream_protocol.rb +140 -140
  682. data/lib/cosmos/streams/terminated_stream_protocol.rb +81 -81
  683. data/lib/cosmos/system.rb +4 -4
  684. data/lib/cosmos/system/system.rb +618 -618
  685. data/lib/cosmos/system/target.rb +197 -197
  686. data/lib/cosmos/tools/cmd_extractor/cmd_extractor.rb +255 -255
  687. data/lib/cosmos/tools/cmd_sender/cmd_sender.rb +717 -717
  688. data/lib/cosmos/tools/cmd_sender/cmd_sender_item_delegate.rb +77 -77
  689. data/lib/cosmos/tools/cmd_sender/cmd_sender_text_edit.rb +70 -70
  690. data/lib/cosmos/tools/cmd_tlm_server/api.rb +1034 -1034
  691. data/lib/cosmos/tools/cmd_tlm_server/background_task.rb +46 -46
  692. data/lib/cosmos/tools/cmd_tlm_server/background_tasks.rb +67 -67
  693. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +515 -515
  694. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +253 -253
  695. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_gui.rb +408 -408
  696. data/lib/cosmos/tools/cmd_tlm_server/commanding.rb +112 -112
  697. data/lib/cosmos/tools/cmd_tlm_server/connections.rb +175 -175
  698. data/lib/cosmos/tools/cmd_tlm_server/gui/interfaces_tab.rb +200 -200
  699. data/lib/cosmos/tools/cmd_tlm_server/gui/logging_tab.rb +176 -176
  700. data/lib/cosmos/tools/cmd_tlm_server/gui/packets_tab.rb +150 -150
  701. data/lib/cosmos/tools/cmd_tlm_server/gui/status_tab.rb +244 -244
  702. data/lib/cosmos/tools/cmd_tlm_server/gui/targets_tab.rb +90 -90
  703. data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +266 -266
  704. data/lib/cosmos/tools/cmd_tlm_server/interfaces.rb +127 -127
  705. data/lib/cosmos/tools/cmd_tlm_server/packet_logging.rb +132 -132
  706. data/lib/cosmos/tools/cmd_tlm_server/router_thread.rb +66 -66
  707. data/lib/cosmos/tools/cmd_tlm_server/routers.rb +97 -97
  708. data/lib/cosmos/tools/data_viewer/data_viewer.rb +621 -621
  709. data/lib/cosmos/tools/data_viewer/data_viewer_component.rb +134 -134
  710. data/lib/cosmos/tools/data_viewer/dump_component.rb +40 -40
  711. data/lib/cosmos/tools/handbook_creator/handbook_creator.rb +156 -156
  712. data/lib/cosmos/tools/handbook_creator/handbook_creator_config.rb +382 -382
  713. data/lib/cosmos/tools/launcher/launcher.rb +188 -188
  714. data/lib/cosmos/tools/launcher/launcher_config.rb +256 -256
  715. data/lib/cosmos/tools/launcher/launcher_multitool.rb +40 -40
  716. data/lib/cosmos/tools/launcher/launcher_tool.rb +116 -116
  717. data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +837 -837
  718. data/lib/cosmos/tools/opengl_builder/opengl_builder.rb +416 -416
  719. data/lib/cosmos/tools/opengl_builder/scene_config.rb +118 -118
  720. data/lib/cosmos/tools/packet_viewer/packet_viewer.rb +542 -542
  721. data/lib/cosmos/tools/replay/replay.rb +501 -501
  722. data/lib/cosmos/tools/replay/replay_server.rb +91 -91
  723. data/lib/cosmos/tools/script_runner/script_audit.rb +147 -147
  724. data/lib/cosmos/tools/script_runner/script_runner.rb +922 -922
  725. data/lib/cosmos/tools/script_runner/script_runner_config.rb +40 -40
  726. data/lib/cosmos/tools/script_runner/script_runner_frame.rb +1798 -1798
  727. data/lib/cosmos/tools/table_manager/table.rb +70 -70
  728. data/lib/cosmos/tools/table_manager/table_config.rb +764 -764
  729. data/lib/cosmos/tools/table_manager/table_item.rb +74 -74
  730. data/lib/cosmos/tools/table_manager/table_manager.rb +1065 -1065
  731. data/lib/cosmos/tools/table_manager/table_manager_core.rb +539 -539
  732. data/lib/cosmos/tools/test_runner/results_writer.rb +283 -283
  733. data/lib/cosmos/tools/test_runner/test.rb +539 -539
  734. data/lib/cosmos/tools/test_runner/test_runner.rb +1189 -1189
  735. data/lib/cosmos/tools/test_runner/test_runner_chooser.rb +341 -341
  736. data/lib/cosmos/tools/tlm_extractor/text_item_chooser.rb +60 -60
  737. data/lib/cosmos/tools/tlm_extractor/tlm_extractor.rb +1016 -1016
  738. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_config.rb +371 -371
  739. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_processor.rb +60 -60
  740. data/lib/cosmos/tools/tlm_grapher/data_object_adders/housekeeping_data_object_adder.rb +75 -75
  741. data/lib/cosmos/tools/tlm_grapher/data_object_adders/singlexy_data_object_adder.rb +44 -44
  742. data/lib/cosmos/tools/tlm_grapher/data_object_adders/xy_data_object_adder.rb +95 -95
  743. data/lib/cosmos/tools/tlm_grapher/data_object_editors/data_object_editor.rb +61 -61
  744. data/lib/cosmos/tools/tlm_grapher/data_object_editors/housekeeping_data_object_editor.rb +181 -181
  745. data/lib/cosmos/tools/tlm_grapher/data_object_editors/linegraph_data_object_editor.rb +141 -141
  746. data/lib/cosmos/tools/tlm_grapher/data_object_editors/singlexy_data_object_editor.rb +30 -30
  747. data/lib/cosmos/tools/tlm_grapher/data_object_editors/xy_data_object_editor.rb +174 -174
  748. data/lib/cosmos/tools/tlm_grapher/data_objects/data_object.rb +193 -193
  749. data/lib/cosmos/tools/tlm_grapher/data_objects/housekeeping_data_object.rb +407 -407
  750. data/lib/cosmos/tools/tlm_grapher/data_objects/linegraph_data_object.rb +176 -176
  751. data/lib/cosmos/tools/tlm_grapher/data_objects/singlexy_data_object.rb +25 -25
  752. data/lib/cosmos/tools/tlm_grapher/data_objects/xy_data_object.rb +323 -323
  753. data/lib/cosmos/tools/tlm_grapher/plot_editors/linegraph_plot_editor.rb +181 -181
  754. data/lib/cosmos/tools/tlm_grapher/plot_editors/plot_editor.rb +28 -28
  755. data/lib/cosmos/tools/tlm_grapher/plot_editors/singlexy_plot_editor.rb +30 -30
  756. data/lib/cosmos/tools/tlm_grapher/plot_editors/xy_plot_editor.rb +59 -59
  757. data/lib/cosmos/tools/tlm_grapher/plot_gui_objects/linegraph_plot_gui_object.rb +172 -172
  758. data/lib/cosmos/tools/tlm_grapher/plot_gui_objects/singlexy_plot_gui_object.rb +27 -27
  759. data/lib/cosmos/tools/tlm_grapher/plot_gui_objects/xy_plot_gui_object.rb +74 -74
  760. data/lib/cosmos/tools/tlm_grapher/plots/linegraph_plot.rb +201 -201
  761. data/lib/cosmos/tools/tlm_grapher/plots/plot.rb +69 -69
  762. data/lib/cosmos/tools/tlm_grapher/plots/singlexy_plot.rb +20 -20
  763. data/lib/cosmos/tools/tlm_grapher/plots/xy_plot.rb +61 -61
  764. data/lib/cosmos/tools/tlm_grapher/tabbed_plots/overview_tabbed_plots.rb +1291 -1291
  765. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_config.rb +430 -430
  766. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_data_object_editor.rb +107 -107
  767. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_logfile_thread.rb +114 -114
  768. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_plot_editor.rb +101 -101
  769. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_realtime_thread.rb +78 -78
  770. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_tab.rb +57 -57
  771. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_tool.rb +1004 -1004
  772. data/lib/cosmos/tools/tlm_grapher/tlm_grapher.rb +87 -87
  773. data/lib/cosmos/tools/tlm_viewer/screen.rb +486 -486
  774. data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +561 -561
  775. data/lib/cosmos/tools/tlm_viewer/tlm_viewer_config.rb +290 -290
  776. data/lib/cosmos/tools/tlm_viewer/widgets.rb +53 -53
  777. data/lib/cosmos/tools/tlm_viewer/widgets/aging_widget.rb +110 -110
  778. data/lib/cosmos/tools/tlm_viewer/widgets/array_widget.rb +66 -66
  779. data/lib/cosmos/tools/tlm_viewer/widgets/block_widget.rb +57 -57
  780. data/lib/cosmos/tools/tlm_viewer/widgets/button_widget.rb +39 -39
  781. data/lib/cosmos/tools/tlm_viewer/widgets/canvas_widget.rb +62 -62
  782. data/lib/cosmos/tools/tlm_viewer/widgets/canvasimage_widget.rb +41 -41
  783. data/lib/cosmos/tools/tlm_viewer/widgets/canvasimagevalue_widget.rb +57 -57
  784. data/lib/cosmos/tools/tlm_viewer/widgets/canvaslabel_widget.rb +37 -37
  785. data/lib/cosmos/tools/tlm_viewer/widgets/canvaslabelvalue_widget.rb +56 -56
  786. data/lib/cosmos/tools/tlm_viewer/widgets/canvasline_widget.rb +55 -55
  787. data/lib/cosmos/tools/tlm_viewer/widgets/canvaslinevalue_widget.rb +66 -66
  788. data/lib/cosmos/tools/tlm_viewer/widgets/canvasvalue_widget.rb +124 -124
  789. data/lib/cosmos/tools/tlm_viewer/widgets/checkbutton_widget.rb +31 -31
  790. data/lib/cosmos/tools/tlm_viewer/widgets/combobox_widget.rb +30 -30
  791. data/lib/cosmos/tools/tlm_viewer/widgets/formatfontvalue_widget.rb +36 -36
  792. data/lib/cosmos/tools/tlm_viewer/widgets/formatvalue_widget.rb +35 -35
  793. data/lib/cosmos/tools/tlm_viewer/widgets/horizontal_widget.rb +27 -27
  794. data/lib/cosmos/tools/tlm_viewer/widgets/horizontalbox_widget.rb +31 -31
  795. data/lib/cosmos/tools/tlm_viewer/widgets/horizontalline_widget.rb +26 -26
  796. data/lib/cosmos/tools/tlm_viewer/widgets/label_widget.rb +29 -29
  797. data/lib/cosmos/tools/tlm_viewer/widgets/labelformatvalue_widget.rb +39 -39
  798. data/lib/cosmos/tools/tlm_viewer/widgets/labelprogressbar_widget.rb +38 -38
  799. data/lib/cosmos/tools/tlm_viewer/widgets/labeltrendlimitsbar_widget.rb +38 -38
  800. data/lib/cosmos/tools/tlm_viewer/widgets/labelvalue_widget.rb +39 -39
  801. data/lib/cosmos/tools/tlm_viewer/widgets/labelvaluedesc_widget.rb +42 -42
  802. data/lib/cosmos/tools/tlm_viewer/widgets/labelvaluelimitsbar_widget.rb +37 -37
  803. data/lib/cosmos/tools/tlm_viewer/widgets/labelvaluerangebar_widget.rb +37 -37
  804. data/lib/cosmos/tools/tlm_viewer/widgets/layout_widget.rb +34 -34
  805. data/lib/cosmos/tools/tlm_viewer/widgets/limitsbar_widget.rb +178 -178
  806. data/lib/cosmos/tools/tlm_viewer/widgets/linegraph_widget.rb +54 -54
  807. data/lib/cosmos/tools/tlm_viewer/widgets/matrixbycolumns_widget.rb +47 -47
  808. data/lib/cosmos/tools/tlm_viewer/widgets/multi_widget.rb +116 -116
  809. data/lib/cosmos/tools/tlm_viewer/widgets/progressbar_widget.rb +34 -34
  810. data/lib/cosmos/tools/tlm_viewer/widgets/radiobutton_widget.rb +30 -30
  811. data/lib/cosmos/tools/tlm_viewer/widgets/rangebar_widget.rb +57 -57
  812. data/lib/cosmos/tools/tlm_viewer/widgets/screenshotbutton_widget.rb +34 -34
  813. data/lib/cosmos/tools/tlm_viewer/widgets/scrollwindow_widget.rb +35 -35
  814. data/lib/cosmos/tools/tlm_viewer/widgets/sectionheader_widget.rb +33 -33
  815. data/lib/cosmos/tools/tlm_viewer/widgets/tabbook_widget.rb +26 -26
  816. data/lib/cosmos/tools/tlm_viewer/widgets/tabitem_widget.rb +28 -28
  817. data/lib/cosmos/tools/tlm_viewer/widgets/textbox_widget.rb +47 -47
  818. data/lib/cosmos/tools/tlm_viewer/widgets/textfield_widget.rb +26 -26
  819. data/lib/cosmos/tools/tlm_viewer/widgets/timegraph_widget.rb +88 -88
  820. data/lib/cosmos/tools/tlm_viewer/widgets/title_widget.rb +27 -27
  821. data/lib/cosmos/tools/tlm_viewer/widgets/trendbar_widget.rb +130 -130
  822. data/lib/cosmos/tools/tlm_viewer/widgets/trendlimitsbar_widget.rb +46 -46
  823. data/lib/cosmos/tools/tlm_viewer/widgets/value_widget.rb +43 -43
  824. data/lib/cosmos/tools/tlm_viewer/widgets/valuelimitsbar_widget.rb +37 -37
  825. data/lib/cosmos/tools/tlm_viewer/widgets/valuerangebar_widget.rb +37 -37
  826. data/lib/cosmos/tools/tlm_viewer/widgets/vertical_widget.rb +35 -35
  827. data/lib/cosmos/tools/tlm_viewer/widgets/verticalbox_widget.rb +37 -37
  828. data/lib/cosmos/tools/tlm_viewer/widgets/widget.rb +257 -257
  829. data/lib/cosmos/top_level.rb +759 -759
  830. data/lib/cosmos/utilities.rb +11 -11
  831. data/lib/cosmos/utilities/crc.rb +166 -166
  832. data/lib/cosmos/utilities/csv.rb +83 -83
  833. data/lib/cosmos/utilities/logger.rb +137 -137
  834. data/lib/cosmos/utilities/low_fragmentation_array.rb +11 -11
  835. data/lib/cosmos/utilities/message_log.rb +79 -79
  836. data/lib/cosmos/utilities/quaternion.rb +258 -258
  837. data/lib/cosmos/utilities/ruby_lex_utils.rb +313 -313
  838. data/lib/cosmos/utilities/simulated_target.rb +99 -99
  839. data/lib/cosmos/utilities/sleeper.rb +44 -44
  840. data/lib/cosmos/version.rb +12 -12
  841. data/lib/cosmos/win32/excel.rb +66 -66
  842. data/lib/cosmos/win32/win32.rb +387 -387
  843. data/lib/cosmos/win32/win32_main.rb +321 -321
  844. data/roodi.yml +24 -24
  845. data/run_gui_tests.bat +0 -0
  846. data/spec/ccsds/ccsds_packet_spec.rb +67 -67
  847. data/spec/ccsds/ccsds_parser_spec.rb +148 -148
  848. data/spec/config/config_parser_spec.rb +322 -322
  849. data/spec/conversions/conversion_spec.rb +31 -31
  850. data/spec/conversions/generic_conversion_spec.rb +45 -45
  851. data/spec/conversions/new_packet_log_conversion_spec.rb +39 -39
  852. data/spec/conversions/polynomial_conversion_spec.rb +40 -40
  853. data/spec/conversions/processor_conversion_spec.rb +45 -45
  854. data/spec/conversions/received_count_conversion_spec.rb +43 -43
  855. data/spec/conversions/received_time_formatted_conversion_spec.rb +49 -49
  856. data/spec/conversions/received_time_seconds_conversion_spec.rb +50 -50
  857. data/spec/conversions/segmented_polynomial_conversion_spec.rb +51 -51
  858. data/spec/conversions/unix_time_formatted_conversion_spec.rb +74 -74
  859. data/spec/conversions/unix_time_seconds_conversion_spec.rb +76 -76
  860. data/spec/core_ext/array_spec.rb +186 -186
  861. data/spec/core_ext/class_spec.rb +36 -36
  862. data/spec/core_ext/cosmos_io_spec.rb +77 -77
  863. data/spec/core_ext/exception_spec.rb +91 -91
  864. data/spec/core_ext/file_spec.rb +72 -72
  865. data/spec/core_ext/hash_spec.rb +24 -24
  866. data/spec/core_ext/io_spec.rb +46 -46
  867. data/spec/core_ext/kernel_spec.rb +54 -54
  868. data/spec/core_ext/math_spec.rb +116 -116
  869. data/spec/core_ext/matrix_spec.rb +66 -66
  870. data/spec/core_ext/objectspace_spec.rb +29 -29
  871. data/spec/core_ext/range_spec.rb +21 -21
  872. data/spec/core_ext/socket_spec.rb +32 -32
  873. data/spec/core_ext/string_spec.rb +223 -223
  874. data/spec/core_ext/stringio_spec.rb +21 -21
  875. data/spec/core_ext/time_spec.rb +202 -202
  876. data/spec/gui/line_graph/line_clip_spec.rb +322 -322
  877. data/spec/gui/qt_spec.rb +102 -102
  878. data/spec/install/config/system/system.txt +33 -33
  879. data/spec/install/config/targets/COSMOS/cmd_tlm/cosmos_server_cmds.txt +41 -41
  880. data/spec/install/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +15 -15
  881. data/spec/install/config/targets/COSMOS/cmd_tlm_server.txt +6 -6
  882. data/spec/install/config/targets/COSMOS/screens/limits_change.txt +20 -20
  883. data/spec/install/config/targets/COSMOS/screens/version.txt +19 -19
  884. data/spec/install/config/targets/COSMOS/target.txt +5 -5
  885. data/spec/install/config/targets/INST/cmd_tlm/inst_cmd_linc.txt +30 -30
  886. data/spec/install/config/targets/INST/cmd_tlm/inst_cmds.txt +111 -111
  887. data/spec/install/config/targets/INST/cmd_tlm/inst_tlm.txt +236 -236
  888. data/spec/install/config/targets/INST/cmd_tlm/inst_tlm_linc.txt +25 -25
  889. data/spec/install/config/targets/INST/cmd_tlm_server.txt +5 -5
  890. data/spec/install/config/targets/INST/lib/sim_inst.rb +305 -305
  891. data/spec/install/config/targets/INST/target.txt +10 -10
  892. data/spec/install/config/targets/META/cmd_tlm/meta_cmd.txt +4 -4
  893. data/spec/install/config/targets/META/cmd_tlm/meta_tlm.txt +4 -4
  894. data/spec/install/config/targets/SYSTEM/cmd_tlm/limits_groups.txt +7 -7
  895. data/spec/interfaces/cmd_tlm_server_interface_spec.rb +150 -150
  896. data/spec/interfaces/interface_spec.rb +130 -130
  897. data/spec/interfaces/linc_interface_spec.rb +259 -259
  898. data/spec/interfaces/serial_interface_spec.rb +56 -56
  899. data/spec/interfaces/simulated_target_interface_spec.rb +128 -128
  900. data/spec/interfaces/stream_interface_spec.rb +157 -157
  901. data/spec/interfaces/tcpip_client_interface_spec.rb +55 -55
  902. data/spec/interfaces/tcpip_server_interface_spec.rb +160 -160
  903. data/spec/interfaces/udp_interface_spec.rb +175 -175
  904. data/spec/io/buffered_file_spec.rb +113 -113
  905. data/spec/io/io_multiplexer_spec.rb +94 -94
  906. data/spec/io/json_drb_object_spec.rb +119 -119
  907. data/spec/io/json_drb_spec.rb +311 -311
  908. data/spec/io/json_rpc_spec.rb +264 -264
  909. data/spec/io/raw_logger_pair_spec.rb +76 -76
  910. data/spec/io/raw_logger_spec.rb +133 -133
  911. data/spec/io/serial_driver_spec.rb +60 -60
  912. data/spec/io/stderr_spec.rb +32 -32
  913. data/spec/io/stdout_spec.rb +32 -32
  914. data/spec/io/tcpip_server_spec.rb +338 -338
  915. data/spec/io/udp_sockets_spec.rb +94 -94
  916. data/spec/io/win32_serial_driver_spec.rb +88 -88
  917. data/spec/packet_logs/meta_packet_log_writer_spec.rb +170 -170
  918. data/spec/packet_logs/packet_log_reader_spec.rb +468 -468
  919. data/spec/packet_logs/packet_log_writer_pair_spec.rb +30 -30
  920. data/spec/packet_logs/packet_log_writer_spec.rb +225 -225
  921. data/spec/packets/binary_accessor_spec.rb +2326 -2326
  922. data/spec/packets/commands_spec.rb +369 -369
  923. data/spec/packets/limits_response_spec.rb +25 -25
  924. data/spec/packets/limits_spec.rb +344 -344
  925. data/spec/packets/packet_config_spec.rb +805 -805
  926. data/spec/packets/packet_item_limits_spec.rb +161 -161
  927. data/spec/packets/packet_item_spec.rb +386 -386
  928. data/spec/packets/packet_spec.rb +1317 -1317
  929. data/spec/packets/parsers/format_string_parser_spec.rb +122 -122
  930. data/spec/packets/parsers/limits_parser_spec.rb +282 -282
  931. data/spec/packets/parsers/limits_response_parser_spec.rb +149 -149
  932. data/spec/packets/parsers/macro_parser_spec.rb +212 -212
  933. data/spec/packets/parsers/packet_item_parser_spec.rb +306 -306
  934. data/spec/packets/parsers/packet_parser_spec.rb +99 -99
  935. data/spec/packets/parsers/processor_parser_spec.rb +114 -114
  936. data/spec/packets/parsers/state_parser_spec.rb +156 -156
  937. data/spec/packets/structure_item_spec.rb +195 -195
  938. data/spec/packets/structure_spec.rb +565 -565
  939. data/spec/packets/telemetry_spec.rb +578 -578
  940. data/spec/processors/new_packet_log_processor_spec.rb +39 -39
  941. data/spec/processors/processor_spec.rb +55 -55
  942. data/spec/processors/statistics_processor_spec.rb +60 -60
  943. data/spec/processors/watermark_processor_spec.rb +51 -51
  944. data/spec/script/cmd_tlm_server_spec.rb +110 -110
  945. data/spec/script/commands_disconnect_spec.rb +270 -270
  946. data/spec/script/commands_spec.rb +302 -302
  947. data/spec/script/limits_spec.rb +153 -153
  948. data/spec/script/script_spec.rb +86 -86
  949. data/spec/script/scripting_spec.rb +440 -440
  950. data/spec/script/telemetry_spec.rb +165 -165
  951. data/spec/script/tools_spec.rb +117 -117
  952. data/spec/spec_helper.rb +190 -190
  953. data/spec/streams/burst_stream_protocol_spec.rb +32 -32
  954. data/spec/streams/fixed_stream_protocol_spec.rb +113 -113
  955. data/spec/streams/length_stream_protocol_spec.rb +300 -300
  956. data/spec/streams/preidentified_stream_protocol_spec.rb +121 -121
  957. data/spec/streams/serial_stream_spec.rb +117 -117
  958. data/spec/streams/stream_protocol_spec.rb +346 -346
  959. data/spec/streams/stream_spec.rb +30 -30
  960. data/spec/streams/tcpip_client_stream_spec.rb +57 -57
  961. data/spec/streams/tcpip_socket_stream_spec.rb +193 -193
  962. data/spec/streams/template_stream_protocol_spec.rb +156 -156
  963. data/spec/streams/terminated_stream_protocol_spec.rb +127 -127
  964. data/spec/system/system_spec.rb +665 -665
  965. data/spec/system/target_spec.rb +250 -250
  966. data/spec/tools/cmd_tlm_server/api_spec.rb +1117 -1117
  967. data/spec/tools/cmd_tlm_server/background_task_spec.rb +32 -32
  968. data/spec/tools/cmd_tlm_server/background_tasks_spec.rb +81 -81
  969. data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +453 -453
  970. data/spec/tools/cmd_tlm_server/cmd_tlm_server_spec.rb +415 -415
  971. data/spec/tools/cmd_tlm_server/commanding_spec.rb +151 -151
  972. data/spec/tools/cmd_tlm_server/connections_spec.rb +235 -235
  973. data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +306 -306
  974. data/spec/tools/cmd_tlm_server/interfaces_spec.rb +252 -252
  975. data/spec/tools/cmd_tlm_server/packet_logging_spec.rb +143 -143
  976. data/spec/tools/cmd_tlm_server/router_thread_spec.rb +151 -151
  977. data/spec/tools/cmd_tlm_server/routers_spec.rb +223 -223
  978. data/spec/tools/launcher/launcher_config_spec.rb +464 -464
  979. data/spec/top_level/top_level_spec.rb +334 -334
  980. data/spec/utilities/crc_spec.rb +45 -45
  981. data/spec/utilities/csv_spec.rb +97 -97
  982. data/spec/utilities/logger_spec.rb +102 -102
  983. data/spec/utilities/message_log_spec.rb +89 -89
  984. data/spec/utilities/quaternion_spec.rb +107 -107
  985. data/spec/utilities/ruby_lex_utils_spec.rb +86 -86
  986. data/tasks/manifest.rake +22 -22
  987. data/tasks/spec.rake +23 -23
  988. data/test/benchmarks/binary_accessor_benchmark.rb +14 -14
  989. data/test/benchmarks/gsub_benchmark.rb +152 -152
  990. data/test/benchmarks/is_a_benchmark.rb +34 -34
  991. data/test/performance/PACKETS.bat +0 -0
  992. data/test/performance/Rakefile +77 -77
  993. data/test/performance/THREADS.bat +0 -0
  994. data/test/performance/config/data/crc.txt +196 -196
  995. data/test/performance/config/data/diamond.STL +57 -57
  996. data/test/performance/config/data/meta_init.txt +4 -4
  997. data/test/performance/config/system/system_packets.txt +39 -39
  998. data/test/performance/config/system/system_threads.txt +59 -59
  999. data/test/performance/config/targets/COSMOS/cmd_tlm/cosmos_server_cmds.txt +46 -46
  1000. data/test/performance/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +15 -15
  1001. data/test/performance/config/targets/COSMOS/cmd_tlm_server.txt +6 -6
  1002. data/test/performance/config/targets/COSMOS/screens/limits_change.txt +20 -20
  1003. data/test/performance/config/targets/COSMOS/screens/version.txt +19 -19
  1004. data/test/performance/config/targets/COSMOS/target.txt +11 -11
  1005. data/test/performance/config/targets/PACKET/cmd_tlm/packet_cmds.txt +20 -20
  1006. data/test/performance/config/targets/PACKET/cmd_tlm/packet_tlm.txt +98 -98
  1007. data/test/performance/config/targets/PACKET/cmd_tlm_server.txt +6 -6
  1008. data/test/performance/config/targets/PACKET/lib/packet_interface.rb +22 -22
  1009. data/test/performance/config/targets/PACKET/lib/packet_limits_response.rb +24 -24
  1010. data/test/performance/config/targets/PACKET/screens/status.txt +25 -25
  1011. data/test/performance/config/targets/PACKET/target.txt +28 -28
  1012. data/test/performance/config/targets/SYSTEM/screens/status.txt +12 -12
  1013. data/test/performance/config/targets/THREAD/cmd_tlm/thread_cmds.txt +17 -17
  1014. data/test/performance/config/targets/THREAD/cmd_tlm/thread_tlm.txt +18 -18
  1015. data/test/performance/config/targets/THREAD/cmd_tlm_server.txt +6 -6
  1016. data/test/performance/config/targets/THREAD/lib/thread_interface.rb +22 -22
  1017. data/test/performance/config/targets/THREAD/screens/status.txt +25 -25
  1018. data/test/performance/config/targets/THREAD/target.txt +6 -6
  1019. data/test/performance/config/tools/cmd_tlm_server/cmd_tlm_server_packets.txt +28 -28
  1020. data/test/performance/config/tools/cmd_tlm_server/cmd_tlm_server_threads.txt +68 -68
  1021. data/test/performance/config/tools/data_viewer/data_viewer.txt +11 -11
  1022. data/test/performance/config/tools/handbook_creator/handbook_creator.txt +66 -66
  1023. data/test/performance/config/tools/handbook_creator/templates/command_packets.html.erb +86 -86
  1024. data/test/performance/config/tools/handbook_creator/templates/command_toc.html.erb +38 -38
  1025. data/test/performance/config/tools/handbook_creator/templates/footer.html.erb +9 -9
  1026. data/test/performance/config/tools/handbook_creator/templates/header.html.erb +25 -25
  1027. data/test/performance/config/tools/handbook_creator/templates/limits_groups.html.erb +13 -13
  1028. data/test/performance/config/tools/handbook_creator/templates/nav.html.erb +27 -27
  1029. data/test/performance/config/tools/handbook_creator/templates/overview.html.erb +1 -1
  1030. data/test/performance/config/tools/handbook_creator/templates/pdf_cover.html.erb +23 -23
  1031. data/test/performance/config/tools/handbook_creator/templates/pdf_footer.html.erb +33 -33
  1032. data/test/performance/config/tools/handbook_creator/templates/pdf_header.html.erb +41 -41
  1033. data/test/performance/config/tools/handbook_creator/templates/telemetry_packets.html.erb +80 -80
  1034. data/test/performance/config/tools/handbook_creator/templates/telemetry_toc.html.erb +38 -38
  1035. data/test/performance/config/tools/handbook_creator/templates/title.html.erb +1 -1
  1036. data/test/performance/config/tools/launcher/launcher_packets.txt +34 -34
  1037. data/test/performance/config/tools/launcher/launcher_threads.txt +83 -83
  1038. data/test/performance/config/tools/script_runner/script_runner.txt +3 -3
  1039. data/test/performance/config/tools/table_manager/ConfigTables_def.txt +8 -8
  1040. data/test/performance/config/tools/table_manager/ExampleTableDefinition.txt +24 -24
  1041. data/test/performance/config/tools/table_manager/MCConfigurationTable_fsw1_def.txt +25 -25
  1042. data/test/performance/config/tools/table_manager/MCConfigurationTable_fsw2_def.txt +25 -25
  1043. data/test/performance/config/tools/table_manager/PPSSelectionTable_def.txt +8 -8
  1044. data/test/performance/config/tools/table_manager/TLMMonitoringTable_def.txt +248 -248
  1045. data/test/performance/config/tools/test_runner/test_runner.txt +17 -17
  1046. data/test/performance/config/tools/tlm_extractor/tlm_extractor.txt +13 -13
  1047. data/test/performance/config/tools/tlm_extractor/tlm_extractor2.txt +2 -2
  1048. data/test/performance/config/tools/tlm_extractor/tlm_extractor3.txt +2 -2
  1049. data/test/performance/config/tools/tlm_extractor/tlm_extractor4.txt +2 -2
  1050. data/test/performance/config/tools/tlm_grapher/tlm_grapher.txt +204 -204
  1051. data/test/performance/config/tools/tlm_viewer/tlm_viewer.txt +13 -13
  1052. data/test/performance/lib/packet_target.rb +126 -126
  1053. data/test/performance/lib/thread_target.rb +120 -120
  1054. data/test/performance/lib/user_version.rb +3 -3
  1055. data/test/performance/procedures/checks.rb +11 -11
  1056. data/test/performance/procedures/clear_util.rb +7 -7
  1057. data/test/performance/procedures/collect.rb +18 -18
  1058. data/test/performance/procedures/collect_util.rb +14 -14
  1059. data/test/performance/procedures/cosmos_api_test.rb +293 -293
  1060. data/test/performance/procedures/disconnect.rb +29 -29
  1061. data/test/performance/procedures/example_test.rb +182 -182
  1062. data/test/performance/procedures/plot_test.rb +8 -8
  1063. data/test/performance/procedures/procedure.rb +2 -2
  1064. data/test/performance/procedures/run_example_test.rb +3 -3
  1065. data/test/performance/procedures/test.rb +51 -51
  1066. data/test/performance/tools/CmdExtractor +14 -14
  1067. data/test/performance/tools/CmdExtractor.bat +0 -0
  1068. data/test/performance/tools/CmdSender +14 -14
  1069. data/test/performance/tools/CmdSender.bat +0 -0
  1070. data/test/performance/tools/CmdTlmServer +16 -16
  1071. data/test/performance/tools/CmdTlmServer.bat +0 -0
  1072. data/test/performance/tools/CmdTlmServerMemProf +20 -20
  1073. data/test/performance/tools/CmdTlmServerMemProf.bat +0 -0
  1074. data/test/performance/tools/DataViewer +14 -14
  1075. data/test/performance/tools/DataViewer.bat +0 -0
  1076. data/test/performance/tools/HandbookCreator +14 -14
  1077. data/test/performance/tools/HandbookCreator.bat +0 -0
  1078. data/test/performance/tools/Launcher +14 -14
  1079. data/test/performance/tools/Launcher.bat +0 -0
  1080. data/test/performance/tools/LimitsMonitor +14 -14
  1081. data/test/performance/tools/LimitsMonitor.bat +0 -0
  1082. data/test/performance/tools/OpenGLBuilder +14 -14
  1083. data/test/performance/tools/OpenGLBuilder.bat +0 -0
  1084. data/test/performance/tools/PacketTarget +14 -14
  1085. data/test/performance/tools/PacketTarget.bat +0 -0
  1086. data/test/performance/tools/PacketViewer +14 -14
  1087. data/test/performance/tools/PacketViewer.bat +0 -0
  1088. data/test/performance/tools/Replay +14 -14
  1089. data/test/performance/tools/Replay.bat +0 -0
  1090. data/test/performance/tools/ScpiTarget +14 -14
  1091. data/test/performance/tools/ScpiTarget.bat +0 -0
  1092. data/test/performance/tools/ScriptRunner +14 -14
  1093. data/test/performance/tools/ScriptRunner.bat +0 -0
  1094. data/test/performance/tools/TableManager +14 -14
  1095. data/test/performance/tools/TableManager.bat +0 -0
  1096. data/test/performance/tools/TestRunner +14 -14
  1097. data/test/performance/tools/TestRunner.bat +0 -0
  1098. data/test/performance/tools/ThreadTarget +14 -14
  1099. data/test/performance/tools/ThreadTarget.bat +0 -0
  1100. data/test/performance/tools/TlmExtractor +14 -14
  1101. data/test/performance/tools/TlmExtractor.bat +0 -0
  1102. data/test/performance/tools/TlmGrapher +14 -14
  1103. data/test/performance/tools/TlmGrapher.bat +0 -0
  1104. data/test/performance/tools/TlmGrapherMemProf +19 -19
  1105. data/test/performance/tools/TlmGrapherMemProf.bat +0 -0
  1106. data/test/performance/tools/TlmViewer +14 -14
  1107. data/test/performance/tools/TlmViewer.bat +0 -0
  1108. data/test/performance/tools/TlmViewerMemProf +19 -19
  1109. data/test/performance/tools/TlmViewerMemProf.bat +0 -0
  1110. data/test/performance/tools/mac/CmdExtractor.app/Contents/Info.plist +38 -38
  1111. data/test/performance/tools/mac/CmdExtractor.app/Contents/MacOS/CmdExtractor.rb +15 -15
  1112. data/test/performance/tools/mac/CmdExtractor.app/Contents/MacOS/main.sh +6 -6
  1113. data/test/performance/tools/mac/CmdSender.app/Contents/Info.plist +38 -38
  1114. data/test/performance/tools/mac/CmdSender.app/Contents/MacOS/CmdSender.rb +15 -15
  1115. data/test/performance/tools/mac/CmdSender.app/Contents/MacOS/main.sh +6 -6
  1116. data/test/performance/tools/mac/CmdTlmServer.app/Contents/Info.plist +38 -38
  1117. data/test/performance/tools/mac/CmdTlmServer.app/Contents/MacOS/CmdTlmServer.rb +15 -15
  1118. data/test/performance/tools/mac/CmdTlmServer.app/Contents/MacOS/main.sh +6 -6
  1119. data/test/performance/tools/mac/DataViewer.app/Contents/Info.plist +38 -38
  1120. data/test/performance/tools/mac/DataViewer.app/Contents/MacOS/DataViewer.rb +15 -15
  1121. data/test/performance/tools/mac/DataViewer.app/Contents/MacOS/main.sh +6 -6
  1122. data/test/performance/tools/mac/HandbookCreator.app/Contents/Info.plist +38 -38
  1123. data/test/performance/tools/mac/HandbookCreator.app/Contents/MacOS/HandbookCreator.rb +15 -15
  1124. data/test/performance/tools/mac/HandbookCreator.app/Contents/MacOS/main.sh +6 -6
  1125. data/test/performance/tools/mac/Launcher.app/Contents/Info.plist +38 -38
  1126. data/test/performance/tools/mac/Launcher.app/Contents/MacOS/Launcher.rb +15 -15
  1127. data/test/performance/tools/mac/Launcher.app/Contents/MacOS/main.sh +6 -6
  1128. data/test/performance/tools/mac/LimitsMonitor.app/Contents/Info.plist +38 -38
  1129. data/test/performance/tools/mac/LimitsMonitor.app/Contents/MacOS/LimitsMonitor.rb +15 -15
  1130. data/test/performance/tools/mac/LimitsMonitor.app/Contents/MacOS/main.sh +6 -6
  1131. data/test/performance/tools/mac/OpenGLBuilder.app/Contents/Info.plist +38 -38
  1132. data/test/performance/tools/mac/OpenGLBuilder.app/Contents/MacOS/OpenGLBuilder.rb +15 -15
  1133. data/test/performance/tools/mac/OpenGLBuilder.app/Contents/MacOS/main.sh +6 -6
  1134. data/test/performance/tools/mac/PacketViewer.app/Contents/Info.plist +38 -38
  1135. data/test/performance/tools/mac/PacketViewer.app/Contents/MacOS/PacketViewer.rb +15 -15
  1136. data/test/performance/tools/mac/PacketViewer.app/Contents/MacOS/main.sh +6 -6
  1137. data/test/performance/tools/mac/Replay.app/Contents/Info.plist +38 -38
  1138. data/test/performance/tools/mac/Replay.app/Contents/MacOS/Replay.rb +15 -15
  1139. data/test/performance/tools/mac/Replay.app/Contents/MacOS/main.sh +6 -6
  1140. data/test/performance/tools/mac/ScriptRunner.app/Contents/Info.plist +38 -38
  1141. data/test/performance/tools/mac/ScriptRunner.app/Contents/MacOS/ScriptRunner.rb +15 -15
  1142. data/test/performance/tools/mac/ScriptRunner.app/Contents/MacOS/main.sh +6 -6
  1143. data/test/performance/tools/mac/TableManager.app/Contents/Info.plist +38 -38
  1144. data/test/performance/tools/mac/TableManager.app/Contents/MacOS/TableManager.rb +15 -15
  1145. data/test/performance/tools/mac/TableManager.app/Contents/MacOS/main.sh +6 -6
  1146. data/test/performance/tools/mac/TestRunner.app/Contents/Info.plist +38 -38
  1147. data/test/performance/tools/mac/TestRunner.app/Contents/MacOS/TestRunner.rb +15 -15
  1148. data/test/performance/tools/mac/TestRunner.app/Contents/MacOS/main.sh +6 -6
  1149. data/test/performance/tools/mac/TlmExtractor.app/Contents/Info.plist +38 -38
  1150. data/test/performance/tools/mac/TlmExtractor.app/Contents/MacOS/TlmExtractor.rb +15 -15
  1151. data/test/performance/tools/mac/TlmExtractor.app/Contents/MacOS/main.sh +6 -6
  1152. data/test/performance/tools/mac/TlmGrapher.app/Contents/Info.plist +38 -38
  1153. data/test/performance/tools/mac/TlmGrapher.app/Contents/MacOS/TlmGrapher.rb +15 -15
  1154. data/test/performance/tools/mac/TlmGrapher.app/Contents/MacOS/main.sh +6 -6
  1155. data/test/performance/tools/mac/TlmViewer.app/Contents/Info.plist +38 -38
  1156. data/test/performance/tools/mac/TlmViewer.app/Contents/MacOS/TlmViewer.rb +15 -15
  1157. data/test/performance/tools/mac/TlmViewer.app/Contents/MacOS/main.sh +6 -6
  1158. metadata +3 -3
@@ -1,1189 +1,1189 @@
1
- # encoding: ascii-8bit
2
-
3
- # Copyright 2014 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 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
- require 'cosmos'
12
- Cosmos.catch_fatal_exception do
13
- require 'ostruct'
14
- require 'cosmos/gui/qt_tool'
15
- require 'cosmos/tools/test_runner/test'
16
- require 'cosmos/tools/test_runner/results_writer'
17
- require 'cosmos/tools/test_runner/test_runner_chooser'
18
- require 'cosmos/tools/script_runner/script_runner_frame'
19
- require 'cosmos/tools/script_runner/script_audit'
20
- require 'cosmos/gui/dialogs/progress_dialog'
21
- require 'cosmos/gui/dialogs/scroll_text_dialog'
22
- require 'yard'
23
- end
24
-
25
- module Cosmos
26
-
27
- # Placeholder for all tests discovered without assigned TestSuites
28
- class UnassignedTestSuite < TestSuite
29
- end
30
-
31
- # TestRunner provides a framework for running repeatable sets of tests.
32
- # Individual Test Cases are grouped into Test Groups which are collected into
33
- # Test Suites. Test Cases can have manual sections and can be looped
34
- # indefinitely. After all the tests have run a test report is generated which
35
- # lists the pass / fail status of each test case.
36
- class TestRunner < QtTool
37
- slots 'status_timeout()'
38
-
39
- @@test_suites = []
40
- @@suites = {}
41
- @@results_writer = ResultsWriter.new
42
- @@settings = {}
43
- @@started_success = false
44
- @@instance = nil
45
-
46
- UNASSIGNED_SUITE_DESCRIPTION = "This Test Suite is created automatically " \
47
- "by Test Runner to hold all Tests that have not been added to Test " \
48
- "Suites. Consider adding these tests to explicit Test Suites to " \
49
- "eliminate this catch all Test Suite."
50
-
51
- def initialize(options)
52
- # All code before super is executed twice in RubyQt Based classes
53
- super(options) # MUST BE FIRST
54
- Cosmos.load_cosmos_icon("test_runner.png")
55
-
56
- # Add procedures to search path
57
- System.paths['PROCEDURES'].each do |path|
58
- Cosmos.add_to_search_path(path)
59
- end
60
-
61
- initialize_actions()
62
- initialize_menus()
63
- initialize_central_widget()
64
- complete_initialize()
65
-
66
- # Instance variables
67
- @utilities = []
68
- @procedure_dirs = System.paths['PROCEDURES']
69
- @server_config_file = options.server_config_file
70
- @ignore_tests = []
71
- @ignore_test_suites = []
72
- Splash.execute(self) do |splash|
73
- ConfigParser.splash = splash
74
- process_config(options.config_file)
75
- if options.test_suite
76
- Qt.execute_in_main_thread do
77
- # Start the test and don't warn the user about their options
78
- handle_start(options.test_suite, options.test_group, options.test_case, false)
79
- end
80
- end
81
- ConfigParser.splash = nil
82
- end
83
-
84
- # Timeout to update executing test case status
85
- @timer = Qt::Timer.new(self)
86
- connect(@timer, SIGNAL('timeout()'), self, SLOT('status_timeout()'))
87
- @timer.method_missing(:start, 100)
88
-
89
- @@instance = self
90
- end
91
-
92
- def initialize_actions
93
- super()
94
-
95
- # File Actions
96
- @show_last = Qt::Action.new(tr('Show &Results'), self)
97
- @show_last_keyseq = Qt::KeySequence.new(tr('Ctrl+R'))
98
- @show_last.shortcut = @show_last_keyseq
99
- @show_last.statusTip = tr('Show the Results dialog from the last run')
100
- @show_last.connect(SIGNAL('triggered()')) { show_results }
101
-
102
- @select = Qt::Action.new(tr('Test &Selection'), self)
103
- @select_keyseq = Qt::KeySequence.new(tr('Ctrl+S'))
104
- @select.shortcut = @select_keyseq
105
- @select.statusTip = tr('Select Test Suites/Groups/Cases')
106
- @select.connect(SIGNAL('triggered()')) { show_select}
107
-
108
- # Script Actions
109
- @test_results_log_message = Qt::Action.new(tr('Log Message to Test Results'), self)
110
- @test_results_log_message.statusTip = tr('Log Message to Test Results')
111
- @test_results_log_message.connect(SIGNAL('triggered()')) { on_test_results_log_message() }
112
- @test_results_log_message.setEnabled(false)
113
-
114
- @script_log_message = Qt::Action.new(tr('Log Message to Script Log'), self)
115
- @script_log_message.statusTip = tr('Log Message to Script Log')
116
- @script_log_message.connect(SIGNAL('triggered()')) { on_script_log_message() }
117
- @script_log_message.setEnabled(false)
118
-
119
- @show_call_stack = Qt::Action.new(tr('Show Call Stack'), self)
120
- @show_call_stack.statusTip = tr('Show Call Stack')
121
- @show_call_stack.connect(SIGNAL('triggered()')) { on_script_call_stack }
122
- @show_call_stack.setEnabled(false)
123
-
124
- @toggle_debug = Qt::Action.new(Cosmos.get_icon('bug.png'), tr('&Toggle Debug'), self)
125
- @toggle_debug_keyseq = Qt::KeySequence.new(tr('Ctrl+D'))
126
- @toggle_debug.shortcut = @toggle_debug_keyseq
127
- @toggle_debug.statusTip = tr('Toggle Debug')
128
- @toggle_debug.connect(SIGNAL('triggered()')) { on_script_toggle_debug }
129
- @toggle_debug.setEnabled(false)
130
-
131
- @script_disconnect = Qt::Action.new(Cosmos.get_icon('disconnected.png'), tr('&Toggle Disconnect'), self)
132
- @script_disconnect_keyseq = Qt::KeySequence.new(tr('Ctrl+T'))
133
- @script_disconnect.shortcut = @script_disconnect_keyseq
134
- @script_disconnect.statusTip = tr('Toggle disconnect from the server')
135
- @script_disconnect.connect(SIGNAL('triggered()')) { on_script_toggle_disconnect() }
136
-
137
- @script_audit = Qt::Action.new(tr('&Generate Cmd/Tlm Audit'), self)
138
- @script_audit.statusTip = tr('Generate audit about commands sent and telemetry checked')
139
- @script_audit.connect(SIGNAL('triggered()')) { script_audit() }
140
- end
141
-
142
- def initialize_menus
143
- # File Menu
144
- @file_menu = menuBar.addMenu(tr('&File'))
145
- @file_menu.addAction(@show_last)
146
- @file_menu.addAction(@select)
147
- @file_menu.addSeparator()
148
- @file_menu.addAction(@exit_action)
149
-
150
- # Script Menu
151
- @script_menu = menuBar.addMenu(tr('&Script'))
152
- @script_menu.addAction(@test_results_log_message)
153
- @script_menu.addAction(@script_log_message)
154
- @script_menu.addAction(@show_call_stack)
155
- @script_menu.addAction(@toggle_debug)
156
- @script_menu.addAction(@script_disconnect)
157
- @script_menu.addSeparator()
158
- @script_menu.addAction(@script_audit)
159
-
160
- # Help Menu
161
- @about_string = "Test Runner provides a framework for developing high " \
162
- "level tests that interact with a system using commands and telemetry."
163
-
164
- initialize_help_menu()
165
- end
166
-
167
- def initialize_central_widget
168
- # Create the top level vertical layout
169
- @central_widget = Qt::Widget.new()
170
- @frame = Qt::VBoxLayout.new(@central_widget)
171
-
172
- @horizontal_frame = Qt::HBoxLayout.new
173
- @horizontal_frame.setContentsMargins(0,0,0,0)
174
- @frame.addLayout(@horizontal_frame)
175
-
176
- # Check boxes
177
- @pause_on_error = Qt::CheckBox.new('Pause on Error')
178
- @pause_on_error.setChecked(true)
179
- @continue_test_case_after_error = Qt::CheckBox.new('Continue Test Case after Error')
180
- @continue_test_case_after_error.setChecked(true)
181
- @abort_testing_after_error = Qt::CheckBox.new('Abort Testing after Error')
182
- @abort_testing_after_error.setChecked(false)
183
-
184
- @checkbox_frame = Qt::VBoxLayout.new
185
- @checkbox_frame.setContentsMargins(0,0,0,0)
186
- @checkbox_frame.addWidget(@pause_on_error)
187
- @checkbox_frame.addWidget(@continue_test_case_after_error)
188
- @checkbox_frame.addWidget(@abort_testing_after_error)
189
- @horizontal_frame.addLayout(@checkbox_frame)
190
-
191
- # Separator Between checkboxes
192
- @sep1 = Qt::Frame.new(@central_widget)
193
- @sep1.setFrameStyle(Qt::Frame::VLine | Qt::Frame::Sunken)
194
- @horizontal_frame.addWidget(@sep1)
195
-
196
- @manual = Qt::CheckBox.new('Manual')
197
- @manual.setChecked(true)
198
- @manual.connect(SIGNAL('stateChanged(int)')) do
199
- if @manual.isChecked()
200
- $manual = true
201
- else
202
- $manual = false
203
- end
204
- 0
205
- end
206
- $manual = true
207
- @loop_testing = Qt::CheckBox.new('Loop Testing')
208
- @loop_testing.setChecked(false)
209
- @loop_testing.connect(SIGNAL('stateChanged(int)')) do
210
- if @loop_testing.isChecked()
211
- $loop_testing = true
212
- @break_loop_after_error.setEnabled(true)
213
- else
214
- $loop_testing = false
215
- @break_loop_after_error.setEnabled(false)
216
- end
217
- 0
218
- end
219
- $loop_testing = false
220
- @break_loop_after_error = Qt::CheckBox.new('Break Loop after Error')
221
- @break_loop_after_error.setChecked(false)
222
- @break_loop_after_error.setEnabled(false)
223
-
224
- @checkbox_frame = Qt::VBoxLayout.new
225
- @checkbox_frame.setContentsMargins(0,0,0,0)
226
- @checkbox_frame.addWidget(@manual)
227
- @checkbox_frame.addWidget(@loop_testing)
228
- @checkbox_frame.addWidget(@break_loop_after_error)
229
- @horizontal_frame.addLayout(@checkbox_frame)
230
-
231
- # Separator Between checkboxes
232
- @sep2 = Qt::Frame.new(@central_widget)
233
- @sep2.setFrameStyle(Qt::Frame::VLine | Qt::Frame::Sunken)
234
- @horizontal_frame.addStretch
235
- @horizontal_frame.addWidget(@sep2)
236
-
237
- # Create comboboxes and Start buttons
238
- @test_runner_chooser = TestRunnerChooser.new(self)
239
- @test_runner_chooser.setContentsMargins(0,0,0,0)
240
- @test_runner_chooser.test_suite_start_callback = method(:handle_start)
241
- @test_runner_chooser.test_start_callback = method(:handle_start)
242
- @test_runner_chooser.test_case_start_callback = method(:handle_start)
243
- @test_runner_chooser.test_suite_setup_callback = method(:handle_setup)
244
- @test_runner_chooser.test_setup_callback = method(:handle_setup)
245
- @test_runner_chooser.test_suite_teardown_callback = method(:handle_teardown)
246
- @test_runner_chooser.test_teardown_callback = method(:handle_teardown)
247
- @horizontal_frame.addWidget(@test_runner_chooser)
248
-
249
- # Executing Test Case Status
250
- @executing_status = Qt::HBoxLayout.new
251
- @executing_test_case_label = Qt::Label.new('Executing Test Case:')
252
- @executing_status.addWidget(@executing_test_case_label)
253
- @test_status = Qt::LineEdit.new
254
- @test_status.setReadOnly(true)
255
- @executing_status.addWidget(@test_status)
256
- @pass_label = Qt::Label.new('Pass:')
257
- @executing_status.addWidget(@pass_label)
258
- @pass_count = Qt::LineEdit.new
259
- @pass_count.setFixedWidth(40)
260
- @pass_count.setReadOnly(true)
261
- @pass_count.setAlignment(Qt::AlignHCenter)
262
- @pass_count.setColors(Cosmos::GREEN, Cosmos::WHITE)
263
- @executing_status.addWidget(@pass_count)
264
- @skip_label = Qt::Label.new('Skip:')
265
- @executing_status.addWidget(@skip_label)
266
- @skip_count = Qt::LineEdit.new
267
- @skip_count.setFixedWidth(40)
268
- @skip_count.setReadOnly(true)
269
- @skip_count.setAlignment(Qt::AlignHCenter)
270
- @skip_count.setColors(Cosmos::YELLOW, Cosmos::WHITE)
271
- @executing_status.addWidget(@skip_count)
272
- @fail_label = Qt::Label.new('Fail:')
273
- @executing_status.addWidget(@fail_label)
274
- @fail_count = Qt::LineEdit.new
275
- @fail_count.setFixedWidth(40)
276
- @fail_count.setReadOnly(true)
277
- @fail_count.setAlignment(Qt::AlignHCenter)
278
- @fail_count.setColors(Cosmos::RED, Cosmos::WHITE)
279
- @executing_status.addWidget(@fail_count)
280
- @progress_bar = Qt::ProgressBar.new
281
- @progress_bar.setFixedWidth(200)
282
- @progress_bar.setMinimum(0)
283
- @progress_bar.setMaximum(100)
284
- @executing_status.addWidget(@progress_bar)
285
- @frame.addLayout(@executing_status)
286
-
287
- # Separator before ScriptRunnerFrame
288
- @sep3 = Qt::Frame.new(@central_widget)
289
- @sep3.setFrameStyle(Qt::Frame::HLine | Qt::Frame::Sunken)
290
- @frame.addWidget(@sep3)
291
-
292
- @script_runner_frame = ScriptRunnerFrame.new(self)
293
- @script_runner_frame.setContentsMargins(0,0,0,0)
294
- @script_runner_frame.stop_callback = method(:handle_stop)
295
- @script_runner_frame.allow_start = false
296
- ScriptRunnerFrame.pause_on_error = true
297
- @script_runner_frame.continue_after_error = true
298
- @script_runner_frame.error_callback = method(:handle_error)
299
- Test.abort_on_exception = false
300
- @frame.addWidget(@script_runner_frame)
301
-
302
- setCentralWidget(@central_widget)
303
-
304
- # Display a blank message to force the statusBar to show
305
- statusBar.showMessage("")
306
- end
307
-
308
- def status_timeout
309
- pass_count = TestStatus.instance.pass_count
310
- skip_count = TestStatus.instance.skip_count
311
- fail_count = TestStatus.instance.fail_count
312
- @test_status.text = TestStatus.instance.status
313
- @pass_count.text = pass_count.to_s
314
- @skip_count.text = skip_count.to_s
315
- @fail_count.text = fail_count.to_s
316
- if TestStatus.instance.status != ''
317
- run_count = pass_count + skip_count + fail_count
318
- total_count = TestStatus.instance.total
319
- mod_run_count = run_count % total_count
320
- progress = ((mod_run_count.to_f / total_count) * 100.0).to_i
321
- @progress_bar.setValue(progress)
322
- else
323
- @progress_bar.setValue(0)
324
- end
325
- end
326
-
327
- def self.results_writer
328
- @@results_writer
329
- end
330
-
331
- def self.exec_test(result_string, test_suite_class, test_class = nil, test_case = nil)
332
- @@started_success = false
333
- @@test_suites.each do |test_suite|
334
- if test_suite.class == test_suite_class
335
- @@started_success = @@results_writer.collect_metadata(@@instance)
336
- if @@started_success
337
- @@results_writer.start(result_string, test_suite_class, test_class, test_case, @@settings)
338
- loop do
339
- yield(test_suite)
340
- break if not @@settings['Loop Testing'] or (TestStatus.instance.fail_count > 0 and @@settings['Break Loop after Error'])
341
- end
342
- end
343
- break
344
- end
345
- end
346
- end
347
-
348
- def self.start(test_suite_class, test_class = nil, test_case = nil)
349
- result = []
350
- exec_test('', test_suite_class, test_class, test_case) do |test_suite|
351
- if test_case
352
- result = test_suite.run_test_case(test_class, test_case)
353
- @@results_writer.process_result(result)
354
- raise StopScript if (result.exceptions and Test.abort_on_exception) or result.stopped
355
- elsif test_class
356
- test_suite.run_test(test_class) { |current_result| @@results_writer.process_result(current_result); raise StopScript if current_result.stopped }
357
- else
358
- test_suite.run { |current_result| @@results_writer.process_result(current_result); raise StopScript if current_result.stopped }
359
- end
360
- end
361
- end
362
-
363
- def self.start_setup(test_suite_class, test_class = nil)
364
- exec_test('Manual Setup', test_suite_class, test_class) do |test_suite|
365
- if test_class
366
- result = test_suite.run_test_setup(test_class)
367
- else
368
- result = test_suite.run_setup
369
- end
370
- if result
371
- @@results_writer.process_result(result)
372
- raise StopScript if result.stopped
373
- end
374
- end
375
- end
376
-
377
- def self.start_teardown(test_suite_class, test_class = nil)
378
- exec_test('Manual Teardown', test_suite_class, test_class) do |test_suite|
379
- if test_class
380
- result = test_suite.run_test_teardown(test_class)
381
- else
382
- result = test_suite.run_teardown
383
- end
384
- if result
385
- @@results_writer.process_result(result)
386
- raise StopScript if result.stopped
387
- end
388
- end
389
- end
390
-
391
- def continue_without_pausing_on_errors?
392
- if !@pause_on_error.isChecked()
393
- msg = ""
394
- if @continue_test_case_after_error.isChecked() and @abort_testing_after_error.isChecked()
395
- msg = "the currently executing test case will run to completion before aborting"
396
- elsif !@continue_test_case_after_error.isChecked() and @abort_testing_after_error.isChecked()
397
- msg = "all testing will be aborted on an error"
398
- elsif @continue_test_case_after_error.isChecked() and !@abort_testing_after_error.isChecked()
399
- msg = "all testing will run to completion"
400
- else
401
- msg = "the next test case will start executing"
402
- end
403
-
404
- if Qt::MessageBox.warning(self, "Warning", "If an error occurs, testing will not pause and #{msg}. Continue?", Qt::MessageBox::Yes | Qt::MessageBox::No, Qt::MessageBox::Yes) == Qt::MessageBox::No
405
- return false
406
- end
407
- end
408
- true
409
- end
410
-
411
- def continue_loop_testing?
412
- if @loop_testing.isChecked()
413
- msg = ""
414
- if @break_loop_after_error.isChecked()
415
- msg = "unless an error occurs"
416
- else
417
- msg = "until explicitly stopped"
418
- end
419
-
420
- if Qt::MessageBox.warning(self, "Warning", "Loop testing is enabled. Tests will run forever #{msg}. Continue?", Qt::MessageBox::Yes | Qt::MessageBox::No, Qt::MessageBox::Yes) == Qt::MessageBox::No
421
- return false
422
- end
423
- end
424
- true
425
- end
426
-
427
- ###########################################
428
- # Callbacks
429
- ###########################################
430
-
431
- def generic_handler(test_suite, test = nil, test_case = nil, warnings = true)
432
- if warnings
433
- return unless continue_without_pausing_on_errors?
434
- return unless continue_loop_testing?()
435
- end
436
-
437
- # TODO: This can take a while depending on the number of tests and their
438
- # complexity. Consider making a progress bar for this.
439
- begin
440
- require_utilities()
441
- handle_check_buttons()
442
- @script_runner_frame.stop_message_log
443
- yield
444
- @script_runner_frame.run
445
- rescue Exception => error
446
- ExceptionDialog.new(self, error, "Error starting test", false)
447
- end
448
- end
449
-
450
- def handle_start(test_suite, test = nil, test_case = nil, warnings = true)
451
- generic_handler(test_suite, test, test_case, warnings) do
452
- if test_case
453
- @script_runner_frame.set_text("TestRunner.start(#{test_suite}, #{test}, '#{test_case}')", "#{test_suite}_#{test}_#{test_case}")
454
- elsif test
455
- @script_runner_frame.set_text("TestRunner.start(#{test_suite}, #{test})", "#{test_suite}_#{test}")
456
- else
457
- @script_runner_frame.set_text("TestRunner.start(#{test_suite})", test_suite)
458
- end
459
- end
460
- end
461
-
462
- def handle_setup(test_suite, test = nil)
463
- generic_handler(test_suite, test) do
464
- if test
465
- @script_runner_frame.set_text("TestRunner.start_setup(#{test_suite}, #{test})", "#{test_suite}_#{test}_setup")
466
- else
467
- @script_runner_frame.set_text("TestRunner.start_setup(#{test_suite})", "#{test_suite}_setup")
468
- end
469
- end
470
- end
471
-
472
- def handle_teardown(test_suite, test = nil)
473
- generic_handler(test_suite, test) do
474
- if test
475
- @script_runner_frame.set_text("TestRunner.start_teardown(#{test_suite}, #{test})", "#{test_suite}_#{test}_teardown")
476
- else
477
- @script_runner_frame.set_text("TestRunner.start_teardown(#{test_suite})", "#{test_suite}_teardown")
478
- end
479
- end
480
- end
481
-
482
- def handle_check_buttons
483
- if @pause_on_error.isChecked()
484
- ScriptRunnerFrame.pause_on_error = true
485
- else
486
- ScriptRunnerFrame.pause_on_error = false
487
- end
488
-
489
- if @continue_test_case_after_error.isChecked()
490
- @script_runner_frame.continue_after_error = true
491
- else
492
- @script_runner_frame.continue_after_error = false
493
- end
494
-
495
- if @abort_testing_after_error.isChecked()
496
- Test.abort_on_exception = true
497
- else
498
- Test.abort_on_exception = false
499
- end
500
-
501
- @@settings['Pause on Error'] = @pause_on_error.isChecked()
502
- @@settings['Continue Test Case after Error'] = @continue_test_case_after_error.isChecked()
503
- @@settings['Abort Testing after Error'] = @abort_testing_after_error.isChecked()
504
- @@settings['Manual'] = @manual.isChecked()
505
- @@settings['Loop Testing'] = @loop_testing.isChecked()
506
- @@settings['Break Loop after Error'] = @break_loop_after_error.isChecked()
507
-
508
- disable_while_running()
509
- end
510
-
511
- def handle_stop(script_runner_frame)
512
- if @@started_success
513
- @@results_writer.complete
514
- if @@results_writer.data_package
515
- ProgressDialog.execute(self, 'Data Package Creation Progress', 600, 300) do |progress_dialog|
516
- @@results_writer.create_data_package(progress_dialog)
517
- end
518
- end
519
- end
520
- enable_while_stopped()
521
- show_results() if @@started_success
522
- end
523
-
524
- def handle_error(script_runner_frame)
525
- Qt.execute_in_main_thread(true) do
526
- if @@settings['Continue Test Case after Error']
527
- script_runner_frame.enable_retry()
528
- else
529
- script_runner_frame.disable_retry()
530
- end
531
- end
532
- end
533
-
534
- def disable_while_running
535
- TestStatus.instance.status = ''
536
- TestStatus.instance.pass_count = 0
537
- TestStatus.instance.skip_count = 0
538
- TestStatus.instance.fail_count = 0
539
- @manual.setEnabled(false)
540
- @pause_on_error.setEnabled(false)
541
- @continue_test_case_after_error.setEnabled(false)
542
- @abort_testing_after_error.setEnabled(false)
543
- @loop_testing.setEnabled(false)
544
- @break_loop_after_error.setEnabled(false)
545
- @test_runner_chooser.setEnabled(false)
546
- @show_last.setEnabled(false)
547
- @select.setEnabled(false)
548
- @test_results_log_message.setEnabled(true)
549
- @script_log_message.setEnabled(true)
550
- @show_call_stack.setEnabled(true)
551
- end
552
-
553
- def enable_while_stopped
554
- @manual.setEnabled(true)
555
- @pause_on_error.setEnabled(true)
556
- @continue_test_case_after_error.setEnabled(true)
557
- @abort_testing_after_error.setEnabled(true)
558
- @loop_testing.setEnabled(true)
559
- @break_loop_after_error.setEnabled(true) if @loop_testing.isChecked()
560
- @test_runner_chooser.setEnabled(true)
561
- @show_last.setEnabled(true)
562
- @select.setEnabled(true)
563
- @test_results_log_message.setEnabled(false)
564
- @script_log_message.setEnabled(false)
565
- @show_call_stack.setEnabled(false)
566
- TestStatus.instance.status = ''
567
- end
568
-
569
- def closeEvent(event)
570
- if @script_runner_frame.prompt_if_running_on_close()
571
- shutdown_cmd_tlm()
572
- @script_runner_frame.stop_message_log
573
- super(event)
574
- else
575
- event.ignore()
576
- end
577
- end
578
-
579
- def on_test_results_log_message
580
- message = get_scriptrunner_log_message('Test Results Text Entry', 'Enter text to log to the test results file')
581
- if message
582
- Cosmos::Test.puts('User logged: ' + message.to_s)
583
- @script_runner_frame.handle_output_io
584
- end
585
- end
586
-
587
- def on_script_log_message
588
- message = get_scriptrunner_log_message()
589
- if message
590
- @script_runner_frame.scriptrunner_puts 'User logged: ' + message.to_s
591
- @script_runner_frame.handle_output_io
592
- end
593
- end
594
-
595
- def on_script_call_stack
596
- trace = @script_runner_frame.current_backtrace
597
- ScrollTextDialog.new(self, 'Call Stack', trace.join("\n"))
598
- end
599
-
600
- def on_script_toggle_debug
601
- @script_runner_frame.toggle_debug
602
- end
603
-
604
- def on_script_toggle_disconnect
605
- @server_config_file = @script_runner_frame.toggle_disconnect(@server_config_file)
606
- end
607
-
608
- include ScriptAudit # script_audit()
609
-
610
- def require_utilities
611
- ScriptRunnerFrame.instance = @script_runner_frame
612
- build = false
613
- @utilities.each do |utility|
614
- if require_utility(utility)
615
- build = true
616
- end
617
- end
618
- if build
619
- build_test_suites()
620
- end
621
- ScriptRunnerFrame.instance = nil
622
- end
623
-
624
- # Show Dialog box with textfield containing results
625
- def show_results
626
- if @@results_writer.filename
627
- results_text = File.read(@@results_writer.filename)
628
-
629
- dialog = Qt::Dialog.new(self) do |box|
630
- box.setWindowTitle('Results')
631
- box.resize(600, 600)
632
- text_field = Qt::PlainTextEdit.new
633
- text_field.setReadOnly(true)
634
- orig_font = text_field.font
635
- text_field.setFont(Cosmos.getFont(orig_font.family, orig_font.point_size+2))
636
- text_field.setWordWrapMode(Qt::TextOption::NoWrap)
637
- state = :NORMAL
638
- results_text.each_line do |line|
639
- state = :NORMAL if line[0..0] != ' ' and line.strip.length != 0
640
- if line =~ /:PASS/
641
- text_field.appendText(line, Cosmos::GREEN)
642
- state = :PASS
643
- elsif line =~ /:SKIP/
644
- text_field.appendText(line, Cosmos::YELLOW)
645
- state = :SKIP
646
- elsif line =~ /:FAIL/
647
- text_field.appendText(line, Cosmos::RED)
648
- state = :FAIL
649
- else
650
- case state
651
- when :NORMAL
652
- text_field.appendText(line)
653
- when :PASS
654
- text_field.appendText(line, Cosmos::GREEN)
655
- when :SKIP
656
- text_field.appendText(line, Cosmos::YELLOW)
657
- when :FAIL
658
- text_field.appendText(line, Cosmos::RED)
659
- end
660
- end
661
- end
662
-
663
- vframe = Qt::VBoxLayout.new
664
- vframe.addWidget(text_field)
665
-
666
- # Separator Between checkboxes
667
- sep = Qt::Frame.new(box)
668
- sep.setFrameStyle(Qt::Frame::VLine | Qt::Frame::Sunken)
669
- vframe.addWidget(sep)
670
-
671
- ok = Qt::PushButton.new('OK')
672
- ok.setDefault(true)
673
- ok.connect(SIGNAL('clicked(bool)')) { box.accept }
674
- vframe.addWidget(ok)
675
- box.setLayout(vframe)
676
- end
677
- dialog.exec
678
- dialog.dispose
679
- end
680
- end
681
-
682
- def create_node(yard_doc, name, tree)
683
- node = Qt::TreeWidgetItem.new([name])
684
- node.setCheckState(0, Qt::Unchecked)
685
- yield node
686
- description = yard_doc.nil? ? "" : yard_doc.docstring
687
- description = UNASSIGNED_SUITE_DESCRIPTION if name == "UnassignedTestSuite"
688
- desc_label = Qt::Label.new(description.gsub(/\n/,' '))
689
- desc_label.setMinimumHeight(desc_label.fontMetrics.height * 2)
690
- desc_label.setWordWrap(true)
691
- tree.setItemWidget(node, 1, desc_label)
692
- return node
693
- end
694
-
695
- # Show Dialog box with tree of tests to allow the user to select
696
- # a subset of tests. This also shows the Test Descriptions.
697
- def show_select
698
- dialog = Qt::Dialog.new(self) do |box|
699
- box.setWindowTitle('Test Selections')
700
- box.resize(650, 600)
701
- @procedure_dirs.each do |dir|
702
- # Set the logging level to ERROR to avoid output if one of the
703
- # scripts we are parsing has syntax errors
704
- YARD.parse(File.join(dir, '**', '*.rb'), [], YARD::Logger::ERROR)
705
- end
706
-
707
- tree = Qt::TreeWidget.new
708
- tree.setColumnCount(2)
709
- tree.setHeaderLabels(["Name", "Description"])
710
- tree.connect(SIGNAL('itemClicked(QTreeWidgetItem*, int)')) do |widget, column|
711
- tree.topLevelItems do |suite_node|
712
- if suite_node != widget.topLevel
713
- suite_node.setCheckStateAll(Qt::Unchecked)
714
- end
715
- end
716
- end
717
-
718
- orig_font = nil
719
- @@test_suites.each do |suite|
720
- next if suite.name == "CustomTestSuite"
721
- doc = YARD::Registry.resolve(nil, suite.name)
722
- suite_node = create_node(doc, suite.name, tree) do |node|
723
- orig_font = node.font(0)
724
- new_font = Cosmos.getFont(orig_font.family,
725
- orig_font.point_size+5,
726
- Qt::Font::Bold)
727
- node.setFont(0, new_font)
728
- tree.addTopLevelItem(node)
729
- end
730
-
731
- if suite.respond_to? :setup
732
- doc = YARD::Registry.resolve(P(suite.name.to_s), "#setup", true)
733
- create_node(doc, "setup", tree) do |node|
734
- font = Cosmos.getFont(orig_font.family,
735
- orig_font.point_size,
736
- Qt::Font::Normal,
737
- true) # italic
738
- node.setFont(0, font)
739
- suite_node.addChild(node)
740
- end
741
- end
742
-
743
- suite.tests.each do |test_class, test|
744
- doc = YARD::Registry.resolve(nil, test.name)
745
- test_node = create_node(doc, test.name, tree) do |node|
746
- font = Cosmos.getFont(orig_font.family,
747
- orig_font.point_size + 2,
748
- Qt::Font::Bold)
749
- node.setFont(0, font)
750
- suite_node.addChild(node)
751
- node.setExpanded(true)
752
- end
753
-
754
- if test.respond_to? :setup
755
- doc = YARD::Registry.resolve(P(test_class.to_s), "#setup", true)
756
- create_node(doc, "setup", tree) do |node|
757
- font = Cosmos.getFont(orig_font.family,
758
- orig_font.point_size,
759
- Qt::Font::Normal,
760
- true) # italic
761
- node.setFont(0, font)
762
- test_node.addChild(node)
763
- end
764
- end
765
-
766
- test_class.test_cases.each do |tc|
767
- doc = YARD::Registry.resolve(P(test_class.to_s), "##{tc.to_s}", true)
768
- create_node(doc, tc.to_s, tree) do |node|
769
- test_node.addChild(node)
770
- end
771
- end
772
-
773
- if test.respond_to? :teardown
774
- doc = YARD::Registry.resolve(P(test_class.to_s), "#teardown", true)
775
- create_node(doc, "teardown", tree) do |node|
776
- font = Cosmos.getFont(orig_font.family,
777
- orig_font.point_size,
778
- Qt::Font::Normal,
779
- true) # italic
780
- node.setFont(0, font)
781
- test_node.addChild(node)
782
- end
783
- end
784
- end # suite.tests.each
785
-
786
- if suite.respond_to? :teardown
787
- doc = YARD::Registry.resolve(P(suite.name.to_s), "#teardown", true)
788
- create_node(doc, "teardown", tree) do |node|
789
- font = Cosmos.getFont(orig_font.family,
790
- orig_font.point_size,
791
- Qt::Font::Normal,
792
- true) # italic
793
- node.setFont(0, font)
794
- suite_node.addChild(node)
795
- end
796
- end
797
- end
798
-
799
- tree.resizeColumnToContents(0)
800
- dialog_layout = Qt::VBoxLayout.new
801
- text = "Select test cases to be run in a newly created 'CustomTestSuite'. "\
802
- "Note that tests can only be added from a single existing Test Suite. " \
803
- "Thus clicking on something in another Test Suite deselects anything " \
804
- "currently selected."
805
- instructions = Qt::Label.new(text)
806
- instructions.setWordWrap(true)
807
- dialog_layout.addWidget(instructions)
808
- dialog_layout.addWidget(tree)
809
-
810
- # Separator Between checkboxes
811
- sep = Qt::Frame.new(box)
812
- sep.setFrameStyle(Qt::Frame::VLine | Qt::Frame::Sunken)
813
- dialog_layout.addWidget(sep)
814
-
815
- button_box = Qt::DialogButtonBox.new(Qt::DialogButtonBox::Ok |
816
- Qt::DialogButtonBox::Cancel)
817
- connect(button_box, SIGNAL('rejected()'), box, SLOT('reject()'))
818
- connect(button_box, SIGNAL('accepted()')) do
819
- Cosmos.module_eval("class CustomTestSuite < TestSuite; end")
820
- tree.topLevelItems do |suite_node|
821
- next if suite_node.checkState == Qt::Unchecked
822
- cur_suite = OpenStruct.new(:setup=>false, :teardown=>false, :tests=>{})
823
- suite = CustomTestSuite.new
824
- begin
825
- # Remove any previously defined suite setup methods
826
- CustomTestSuite.send(:remove_method, :setup)
827
- rescue NameError
828
- # NameError is raised if no setup method was defined
829
- end
830
- begin
831
- # Remove any previously defined suite teardown methods
832
- CustomTestSuite.send(:remove_method, :teardown)
833
- rescue NameError
834
- # NameError is raised if no teardown method was defined
835
- end
836
-
837
- suite_node.children do |test_node|
838
- if test_node.checkState == Qt::Checked
839
- if test_node.text == 'setup'
840
- cur_suite.setup = true
841
- # Find the suite instance among the test suites
842
- inst = @@test_suites.detect {|my_suite| my_suite.class.to_s == suite_node.text}
843
- # Create a lambda which will call that one setup method
844
- body = lambda { inst.setup }
845
- CustomTestSuite.send(:define_method, :setup, &body)
846
- end
847
- if test_node.text == 'teardown'
848
- cur_suite.teardown = true
849
- # Find the suite instance among the test suites
850
- inst = @@test_suites.detect {|my_suite| my_suite.class.to_s == suite_node.text}
851
- # Create a lambda which will call that one teardown method
852
- body = lambda { inst.teardown}
853
- CustomTestSuite.send(:define_method, :teardown, &body)
854
- end
855
- end
856
-
857
- test_node.children do |test_case|
858
- next if test_case.checkState == Qt::Unchecked
859
- node = cur_suite.tests[test_node.text] ||=
860
- OpenStruct.new(:setup=>false, :teardown=>false, :cases=>[])
861
-
862
- case test_case.text
863
- when 'setup'
864
- suite.add_test_setup(test_node.text)
865
- node.setup = true
866
- when 'teardown'
867
- suite.add_test_teardown(test_node.text)
868
- node.teardown = true
869
- else
870
- suite.add_test_case(test_node.text, test_case.text)
871
- node.cases << test_case.text
872
- end
873
- end
874
- end
875
- @@suites["CustomTestSuite"] = cur_suite
876
- @@test_suites = @@test_suites.select {|my_suite| my_suite.class != CustomTestSuite}
877
- @@test_suites << suite
878
- end
879
- Qt.execute_in_main_thread(true) do
880
- @test_runner_chooser.test_suites = @@suites
881
- @test_runner_chooser.select_suite("CustomTestSuite")
882
- end
883
- box.accept
884
- end
885
- dialog_layout.addWidget(button_box)
886
- box.setLayout(dialog_layout)
887
- end
888
- dialog.raise
889
- dialog.exec
890
- dialog.dispose
891
- end
892
-
893
- def process_config(filename)
894
- ScriptRunnerFrame.instance = @script_runner_frame
895
-
896
- # Remember all the requires that fail and warn the user
897
- require_errors = []
898
-
899
- # Ensure the file exists
900
- raise "Configuration File: #{filename} does not exist" unless test(?f, filename)
901
- parser = ConfigParser.new
902
- parser.parse_file(filename) do |keyword, params|
903
- case keyword
904
- when 'REQUIRE_UTILITY'
905
- parser.verify_num_parameters(1, 1, "REQUIRE_UTILITY <filename>")
906
- begin
907
- require_utility params[0]
908
- @utilities << params[0]
909
- rescue Exception => err
910
- require_errors << "<b>#{params[0]}</b>:\n#{err.formatted}\n"
911
- end
912
-
913
- when 'RESULTS_WRITER'
914
- data_package = @@results_writer.data_package
915
- metadata = @@results_writer.metadata
916
- parser.verify_num_parameters(1, nil, "RESULTS_WRITER <filename> <class specific options>")
917
- results_class = Cosmos.require_class(params[0])
918
- if params[1]
919
- @@results_writer = results_class.new(*params[1..-1])
920
- else
921
- @@results_writer = results_class.new
922
- end
923
- @@results_writer.data_package = data_package
924
- @@results_writer.metadata = metadata
925
-
926
- when 'ALLOW_DEBUG'
927
- parser.verify_num_parameters(0, 0, "ALLOW_DEBUG")
928
- Qt.execute_in_main_thread(true) { @toggle_debug.setEnabled(true) }
929
-
930
- when 'PAUSE_ON_ERROR'
931
- parser.verify_num_parameters(1, 1, "#{keyword} <TRUE or FALSE>")
932
- Qt.execute_in_main_thread(true) do
933
- @pause_on_error.setChecked(ConfigParser.handle_true_false(params[0]))
934
- end
935
-
936
- when 'CONTINUE_TEST_CASE_AFTER_ERROR'
937
- parser.verify_num_parameters(1, 1, "#{keyword} <TRUE or FALSE>")
938
- Qt.execute_in_main_thread(true) { @continue_test_case_after_error.setChecked(ConfigParser.handle_true_false(params[0])) }
939
-
940
- when 'ABORT_TESTING_AFTER_ERROR'
941
- parser.verify_num_parameters(1, 1, "#{keyword} <TRUE or FALSE>")
942
- Qt.execute_in_main_thread(true) { @abort_testing_after_error.setChecked(ConfigParser.handle_true_false(params[0])) }
943
-
944
- when 'MANUAL'
945
- parser.verify_num_parameters(1, 1, "#{keyword} <TRUE or FALSE>")
946
- Qt.execute_in_main_thread(true) do
947
- @manual.setChecked(ConfigParser.handle_true_false(params[0]))
948
- if @manual.isChecked()
949
- $manual = true
950
- else
951
- $manual = false
952
- end
953
- end
954
-
955
- when 'LOOP_TESTING'
956
- parser.verify_num_parameters(1, 1, "#{keyword} <TRUE or FALSE>")
957
- Qt.execute_in_main_thread(true) do
958
- @loop_testing.setChecked(ConfigParser.handle_true_false(params[0]))
959
- if @loop_testing.isChecked()
960
- $loop_testing = true
961
- @break_loop_after_error.setEnabled(true)
962
- else
963
- $loop_testing = false
964
- @break_loop_after_error.setEnabled(false)
965
- end
966
- end
967
-
968
- when 'BREAK_LOOP_AFTER_ERROR'
969
- parser.verify_num_parameters(1, 1, "#{keyword} <TRUE or FALSE>")
970
- Qt.execute_in_main_thread(true) { @break_loop_after_error.setChecked(ConfigParser.handle_true_false(params[0])) }
971
-
972
- when 'IGNORE_TEST'
973
- parser.verify_num_parameters(1, 1, "#{keyword} <Test Class Name (case sensitive)>")
974
- @ignore_tests << params[0]
975
-
976
- when 'IGNORE_TEST_SUITE'
977
- parser.verify_num_parameters(1, 1, "#{keyword} <Test Suite Class Name (case sensitive)>")
978
- @ignore_test_suites << params[0]
979
-
980
- when 'LINE_DELAY'
981
- parser.verify_num_parameters(1, 1, "#{keyword} <Line Delay in Seconds>")
982
- ScriptRunnerFrame.line_delay = params[0].to_f
983
-
984
- when 'MONITOR_LIMITS'
985
- parser.verify_num_parameters(0, 0, keyword)
986
- ScriptRunnerFrame.monitor_limits = true
987
-
988
- when 'PAUSE_ON_RED'
989
- parser.verify_num_parameters(0, 0, keyword)
990
- ScriptRunnerFrame.monitor_limits = true
991
- ScriptRunnerFrame.pause_on_red = true
992
-
993
- when 'CREATE_DATA_PACKAGE'
994
- parser.verify_num_parameters(0, 0, keyword)
995
- @@results_writer.data_package = true
996
-
997
- when 'AUTO_CYCLE_LOGS'
998
- parser.verify_num_parameters(0, 0, keyword)
999
- @@results_writer.auto_cycle_logs = true
1000
-
1001
- # TODO: Deprecate COLLECT_META_DATA
1002
- when 'COLLECT_METADATA', 'COLLECT_META_DATA'
1003
- parser.verify_num_parameters(2, 2, "#{keyword} <Metadata Target Name> <Metadata Packet Name>")
1004
- System.telemetry.packet(params[0], params[1])
1005
- @@results_writer.metadata = [params[0], params[1]]
1006
-
1007
- else
1008
- raise "Unhandled keyword: #{keyword}" if keyword
1009
- end
1010
- end
1011
-
1012
- # Warn the user about all the requires that failed
1013
- unless require_errors.empty?
1014
- Qt.execute_in_main_thread(true) do
1015
- message = "While loading the Test Runner configuration file: #{filename}."
1016
- message << "\n\nThe following errors occurred:\n#{require_errors.join("\n")}" unless require_errors.empty?
1017
- ScrollTextDialog.new(self, "TestRunner Errors", message)
1018
- end
1019
- end
1020
-
1021
- # Build Test objects
1022
- build_test_suites()
1023
-
1024
- ScriptRunnerFrame.instance = nil
1025
- end
1026
-
1027
- def build_test_suites
1028
- ScriptRunnerFrame.instance.use_instrumentation = false
1029
-
1030
- ignored_test_classes = []
1031
- ignored_test_suite_classes = []
1032
-
1033
- @ignore_tests.each do |test_name|
1034
- begin
1035
- klass = Object.const_get(test_name)
1036
- ignored_test_classes << klass if klass
1037
- rescue
1038
- end
1039
- end
1040
-
1041
- @ignore_test_suites.each do |test_suite_name|
1042
- begin
1043
- klass = Object.const_get(test_suite_name)
1044
- ignored_test_suite_classes << klass if klass
1045
- rescue
1046
- end
1047
- end
1048
-
1049
- # Build list of TestSuites and Tests
1050
- @@test_suites = @@test_suites.select {|my_suite| my_suite.name == 'CustomTestSuite'}
1051
- tests = []
1052
- ObjectSpace.each_object(Class) do |object|
1053
- next if object.name == 'CustomTestSuite'
1054
- if (object.ancestors.include?(TestSuite) &&
1055
- object != TestSuite &&
1056
- !ignored_test_suite_classes.include?(object))
1057
- @@test_suites << object.new
1058
- end
1059
- if (object.ancestors.include?(Test) &&
1060
- object != Test &&
1061
- !ignored_test_classes.include?(object))
1062
- tests << object
1063
- end
1064
- end
1065
- # Raise error if no test suites or tests
1066
- if @@test_suites.empty? || tests.empty?
1067
- msg = "No TestSuites or no Test classes found"
1068
- if !ignored_test_suite_classes.empty?
1069
- msg << "\n\nThe following TestSuites were found but ignored:\n#{ignored_test_suite_classes.join(", ")}"
1070
- end
1071
- if !ignored_test_classes.empty?
1072
- msg << "\n\nThe following Tests were found but ignored:\n#{ignored_test_classes.join(", ")}"
1073
- end
1074
- Qt.execute_in_main_thread(true) do
1075
- Qt::MessageBox.critical(self, 'Error', msg)
1076
- end
1077
- exit 1
1078
- end
1079
-
1080
- # Create TestSuite for unassigned Tests
1081
- @@test_suites.sort!
1082
- @@test_suites.each do |test_suite|
1083
- tests_to_delete = []
1084
- tests.each { |test| tests_to_delete << test if test_suite.tests[test] }
1085
- tests_to_delete.each { |test| tests.delete(test) }
1086
- end
1087
- if tests.empty?
1088
- @@test_suites = @@test_suites.select {|suite| suite.class != UnassignedTestSuite}
1089
- else
1090
- uts = @@test_suites.select {|suite| suite.class == UnassignedTestSuite}[0]
1091
- tests.each { |test| uts.add_test(test) }
1092
- end
1093
-
1094
- ScriptRunnerFrame.instance.use_instrumentation = true
1095
- @@test_suites.each do |suite|
1096
- cur_suite = OpenStruct.new(:setup=>false, :teardown=>false, :tests=>{})
1097
- cur_suite.setup = true if suite.class.method_defined?(:setup)
1098
- cur_suite.teardown = true if suite.class.method_defined?(:teardown)
1099
-
1100
- suite.plans.each do |test_type, test_class, test_case|
1101
- case test_type
1102
- when :TEST
1103
- cur_suite.tests[test_class.name] ||=
1104
- OpenStruct.new(:setup=>false, :teardown=>false, :cases=>[])
1105
- cur_suite.tests[test_class.name].cases.concat(test_class.test_cases)
1106
- cur_suite.tests[test_class.name].cases.uniq!
1107
- cur_suite.tests[test_class.name].cases.sort!
1108
- cur_suite.tests[test_class.name].setup = true if test_class.method_defined?(:setup)
1109
- cur_suite.tests[test_class.name].teardown = true if test_class.method_defined?(:teardown)
1110
- when :TEST_CASE
1111
- cur_suite.tests[test_class.name] ||=
1112
- OpenStruct.new(:setup=>false, :teardown=>false, :cases=>[])
1113
- # Explicitly check for this method and raise an error if it does not exist
1114
- if test_class.method_defined?(test_case.intern)
1115
- cur_suite.tests[test_class.name].cases << test_case
1116
- cur_suite.tests[test_class.name].cases.uniq!
1117
- cur_suite.tests[test_class.name].cases.sort!
1118
- else
1119
- raise "#{test_class} does not have a #{test_case} method defined."
1120
- end
1121
- cur_suite.tests[test_class.name].setup = true if test_class.method_defined?(:setup)
1122
- cur_suite.tests[test_class.name].teardown = true if test_class.method_defined?(:teardown)
1123
- when :TEST_SETUP
1124
- cur_suite.tests[test_class.name] ||=
1125
- OpenStruct.new(:setup=>false, :teardown=>false, :cases=>[])
1126
- # Explicitly check for the setup method and raise an error if it does not exist
1127
- if test_class.method_defined?(:setup)
1128
- cur_suite.tests[test_class.name].setup = true
1129
- else
1130
- raise "#{test_class} does not have a setup method defined."
1131
- end
1132
- when :TEST_TEARDOWN
1133
- cur_suite.tests[test_class.name] ||=
1134
- OpenStruct.new(:setup=>false, :teardown=>false, :cases=>[])
1135
- # Explicitly check for the teardown method and raise an error if it does not exist
1136
- if test_class.method_defined?(:teardown)
1137
- cur_suite.tests[test_class.name].teardown = true
1138
- else
1139
- raise "#{test_class} does not have a teardown method defined."
1140
- end
1141
- end
1142
- end
1143
- @@suites[suite.name.split('::')[-1]] = cur_suite unless suite.name == 'CustomTestSuite'
1144
- end
1145
- Qt.execute_in_main_thread(true) { @test_runner_chooser.test_suites = @@suites }
1146
- end
1147
-
1148
- def self.run(option_parser = nil, options = nil)
1149
- Cosmos.catch_fatal_exception do
1150
- unless option_parser and options
1151
- option_parser, options = create_default_options()
1152
- options.width = 800
1153
- options.height = 700
1154
- options.title = "Test Runner"
1155
- options.auto_size = false
1156
- options.config_file = File.join(Cosmos::USERPATH, 'config', 'tools', 'test_runner', 'test_runner.txt')
1157
- options.server_config_file = CmdTlmServer::DEFAULT_CONFIG_FILE
1158
- option_parser.separator "Test Runner Specific Options:"
1159
- option_parser.on("-c", "--config FILE", "Use the specified configuration file") do |arg|
1160
- options.config_file = File.join(Cosmos::USERPATH, 'config', 'tools', 'test_runner', arg)
1161
- end
1162
- option_parser.on("-s", "--server FILE", "Use the specified server configuration file for disconnect mode") do |arg|
1163
- options.server_config_file = arg
1164
- end
1165
- option_parser.on("--suite SUITE", "Start the specified test suite.") do |arg|
1166
- options.test_suite = arg
1167
- end
1168
- option_parser.on("--group GROUP", "Start the specified test group. Requires the --suite option.") do |arg|
1169
- unless options.test_suite
1170
- puts option_parser
1171
- exit
1172
- end
1173
- options.test_group = arg
1174
- end
1175
- option_parser.on("--case CASE", "Start the specified test case. Requires the --suite and --group options.") do |arg|
1176
- unless options.test_suite && options.test_group
1177
- puts option_parser
1178
- exit
1179
- end
1180
- options.test_case = arg
1181
- end
1182
- end
1183
-
1184
- super(option_parser, options)
1185
- end
1186
- end
1187
- end # class TestRunner
1188
-
1189
- end # module Cosmos
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2014 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 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
+ require 'cosmos'
12
+ Cosmos.catch_fatal_exception do
13
+ require 'ostruct'
14
+ require 'cosmos/gui/qt_tool'
15
+ require 'cosmos/tools/test_runner/test'
16
+ require 'cosmos/tools/test_runner/results_writer'
17
+ require 'cosmos/tools/test_runner/test_runner_chooser'
18
+ require 'cosmos/tools/script_runner/script_runner_frame'
19
+ require 'cosmos/tools/script_runner/script_audit'
20
+ require 'cosmos/gui/dialogs/progress_dialog'
21
+ require 'cosmos/gui/dialogs/scroll_text_dialog'
22
+ require 'yard'
23
+ end
24
+
25
+ module Cosmos
26
+
27
+ # Placeholder for all tests discovered without assigned TestSuites
28
+ class UnassignedTestSuite < TestSuite
29
+ end
30
+
31
+ # TestRunner provides a framework for running repeatable sets of tests.
32
+ # Individual Test Cases are grouped into Test Groups which are collected into
33
+ # Test Suites. Test Cases can have manual sections and can be looped
34
+ # indefinitely. After all the tests have run a test report is generated which
35
+ # lists the pass / fail status of each test case.
36
+ class TestRunner < QtTool
37
+ slots 'status_timeout()'
38
+
39
+ @@test_suites = []
40
+ @@suites = {}
41
+ @@results_writer = ResultsWriter.new
42
+ @@settings = {}
43
+ @@started_success = false
44
+ @@instance = nil
45
+
46
+ UNASSIGNED_SUITE_DESCRIPTION = "This Test Suite is created automatically " \
47
+ "by Test Runner to hold all Tests that have not been added to Test " \
48
+ "Suites. Consider adding these tests to explicit Test Suites to " \
49
+ "eliminate this catch all Test Suite."
50
+
51
+ def initialize(options)
52
+ # All code before super is executed twice in RubyQt Based classes
53
+ super(options) # MUST BE FIRST
54
+ Cosmos.load_cosmos_icon("test_runner.png")
55
+
56
+ # Add procedures to search path
57
+ System.paths['PROCEDURES'].each do |path|
58
+ Cosmos.add_to_search_path(path)
59
+ end
60
+
61
+ initialize_actions()
62
+ initialize_menus()
63
+ initialize_central_widget()
64
+ complete_initialize()
65
+
66
+ # Instance variables
67
+ @utilities = []
68
+ @procedure_dirs = System.paths['PROCEDURES']
69
+ @server_config_file = options.server_config_file
70
+ @ignore_tests = []
71
+ @ignore_test_suites = []
72
+ Splash.execute(self) do |splash|
73
+ ConfigParser.splash = splash
74
+ process_config(options.config_file)
75
+ if options.test_suite
76
+ Qt.execute_in_main_thread do
77
+ # Start the test and don't warn the user about their options
78
+ handle_start(options.test_suite, options.test_group, options.test_case, false)
79
+ end
80
+ end
81
+ ConfigParser.splash = nil
82
+ end
83
+
84
+ # Timeout to update executing test case status
85
+ @timer = Qt::Timer.new(self)
86
+ connect(@timer, SIGNAL('timeout()'), self, SLOT('status_timeout()'))
87
+ @timer.method_missing(:start, 100)
88
+
89
+ @@instance = self
90
+ end
91
+
92
+ def initialize_actions
93
+ super()
94
+
95
+ # File Actions
96
+ @show_last = Qt::Action.new(tr('Show &Results'), self)
97
+ @show_last_keyseq = Qt::KeySequence.new(tr('Ctrl+R'))
98
+ @show_last.shortcut = @show_last_keyseq
99
+ @show_last.statusTip = tr('Show the Results dialog from the last run')
100
+ @show_last.connect(SIGNAL('triggered()')) { show_results }
101
+
102
+ @select = Qt::Action.new(tr('Test &Selection'), self)
103
+ @select_keyseq = Qt::KeySequence.new(tr('Ctrl+S'))
104
+ @select.shortcut = @select_keyseq
105
+ @select.statusTip = tr('Select Test Suites/Groups/Cases')
106
+ @select.connect(SIGNAL('triggered()')) { show_select}
107
+
108
+ # Script Actions
109
+ @test_results_log_message = Qt::Action.new(tr('Log Message to Test Results'), self)
110
+ @test_results_log_message.statusTip = tr('Log Message to Test Results')
111
+ @test_results_log_message.connect(SIGNAL('triggered()')) { on_test_results_log_message() }
112
+ @test_results_log_message.setEnabled(false)
113
+
114
+ @script_log_message = Qt::Action.new(tr('Log Message to Script Log'), self)
115
+ @script_log_message.statusTip = tr('Log Message to Script Log')
116
+ @script_log_message.connect(SIGNAL('triggered()')) { on_script_log_message() }
117
+ @script_log_message.setEnabled(false)
118
+
119
+ @show_call_stack = Qt::Action.new(tr('Show Call Stack'), self)
120
+ @show_call_stack.statusTip = tr('Show Call Stack')
121
+ @show_call_stack.connect(SIGNAL('triggered()')) { on_script_call_stack }
122
+ @show_call_stack.setEnabled(false)
123
+
124
+ @toggle_debug = Qt::Action.new(Cosmos.get_icon('bug.png'), tr('&Toggle Debug'), self)
125
+ @toggle_debug_keyseq = Qt::KeySequence.new(tr('Ctrl+D'))
126
+ @toggle_debug.shortcut = @toggle_debug_keyseq
127
+ @toggle_debug.statusTip = tr('Toggle Debug')
128
+ @toggle_debug.connect(SIGNAL('triggered()')) { on_script_toggle_debug }
129
+ @toggle_debug.setEnabled(false)
130
+
131
+ @script_disconnect = Qt::Action.new(Cosmos.get_icon('disconnected.png'), tr('&Toggle Disconnect'), self)
132
+ @script_disconnect_keyseq = Qt::KeySequence.new(tr('Ctrl+T'))
133
+ @script_disconnect.shortcut = @script_disconnect_keyseq
134
+ @script_disconnect.statusTip = tr('Toggle disconnect from the server')
135
+ @script_disconnect.connect(SIGNAL('triggered()')) { on_script_toggle_disconnect() }
136
+
137
+ @script_audit = Qt::Action.new(tr('&Generate Cmd/Tlm Audit'), self)
138
+ @script_audit.statusTip = tr('Generate audit about commands sent and telemetry checked')
139
+ @script_audit.connect(SIGNAL('triggered()')) { script_audit() }
140
+ end
141
+
142
+ def initialize_menus
143
+ # File Menu
144
+ @file_menu = menuBar.addMenu(tr('&File'))
145
+ @file_menu.addAction(@show_last)
146
+ @file_menu.addAction(@select)
147
+ @file_menu.addSeparator()
148
+ @file_menu.addAction(@exit_action)
149
+
150
+ # Script Menu
151
+ @script_menu = menuBar.addMenu(tr('&Script'))
152
+ @script_menu.addAction(@test_results_log_message)
153
+ @script_menu.addAction(@script_log_message)
154
+ @script_menu.addAction(@show_call_stack)
155
+ @script_menu.addAction(@toggle_debug)
156
+ @script_menu.addAction(@script_disconnect)
157
+ @script_menu.addSeparator()
158
+ @script_menu.addAction(@script_audit)
159
+
160
+ # Help Menu
161
+ @about_string = "Test Runner provides a framework for developing high " \
162
+ "level tests that interact with a system using commands and telemetry."
163
+
164
+ initialize_help_menu()
165
+ end
166
+
167
+ def initialize_central_widget
168
+ # Create the top level vertical layout
169
+ @central_widget = Qt::Widget.new()
170
+ @frame = Qt::VBoxLayout.new(@central_widget)
171
+
172
+ @horizontal_frame = Qt::HBoxLayout.new
173
+ @horizontal_frame.setContentsMargins(0,0,0,0)
174
+ @frame.addLayout(@horizontal_frame)
175
+
176
+ # Check boxes
177
+ @pause_on_error = Qt::CheckBox.new('Pause on Error')
178
+ @pause_on_error.setChecked(true)
179
+ @continue_test_case_after_error = Qt::CheckBox.new('Continue Test Case after Error')
180
+ @continue_test_case_after_error.setChecked(true)
181
+ @abort_testing_after_error = Qt::CheckBox.new('Abort Testing after Error')
182
+ @abort_testing_after_error.setChecked(false)
183
+
184
+ @checkbox_frame = Qt::VBoxLayout.new
185
+ @checkbox_frame.setContentsMargins(0,0,0,0)
186
+ @checkbox_frame.addWidget(@pause_on_error)
187
+ @checkbox_frame.addWidget(@continue_test_case_after_error)
188
+ @checkbox_frame.addWidget(@abort_testing_after_error)
189
+ @horizontal_frame.addLayout(@checkbox_frame)
190
+
191
+ # Separator Between checkboxes
192
+ @sep1 = Qt::Frame.new(@central_widget)
193
+ @sep1.setFrameStyle(Qt::Frame::VLine | Qt::Frame::Sunken)
194
+ @horizontal_frame.addWidget(@sep1)
195
+
196
+ @manual = Qt::CheckBox.new('Manual')
197
+ @manual.setChecked(true)
198
+ @manual.connect(SIGNAL('stateChanged(int)')) do
199
+ if @manual.isChecked()
200
+ $manual = true
201
+ else
202
+ $manual = false
203
+ end
204
+ 0
205
+ end
206
+ $manual = true
207
+ @loop_testing = Qt::CheckBox.new('Loop Testing')
208
+ @loop_testing.setChecked(false)
209
+ @loop_testing.connect(SIGNAL('stateChanged(int)')) do
210
+ if @loop_testing.isChecked()
211
+ $loop_testing = true
212
+ @break_loop_after_error.setEnabled(true)
213
+ else
214
+ $loop_testing = false
215
+ @break_loop_after_error.setEnabled(false)
216
+ end
217
+ 0
218
+ end
219
+ $loop_testing = false
220
+ @break_loop_after_error = Qt::CheckBox.new('Break Loop after Error')
221
+ @break_loop_after_error.setChecked(false)
222
+ @break_loop_after_error.setEnabled(false)
223
+
224
+ @checkbox_frame = Qt::VBoxLayout.new
225
+ @checkbox_frame.setContentsMargins(0,0,0,0)
226
+ @checkbox_frame.addWidget(@manual)
227
+ @checkbox_frame.addWidget(@loop_testing)
228
+ @checkbox_frame.addWidget(@break_loop_after_error)
229
+ @horizontal_frame.addLayout(@checkbox_frame)
230
+
231
+ # Separator Between checkboxes
232
+ @sep2 = Qt::Frame.new(@central_widget)
233
+ @sep2.setFrameStyle(Qt::Frame::VLine | Qt::Frame::Sunken)
234
+ @horizontal_frame.addStretch
235
+ @horizontal_frame.addWidget(@sep2)
236
+
237
+ # Create comboboxes and Start buttons
238
+ @test_runner_chooser = TestRunnerChooser.new(self)
239
+ @test_runner_chooser.setContentsMargins(0,0,0,0)
240
+ @test_runner_chooser.test_suite_start_callback = method(:handle_start)
241
+ @test_runner_chooser.test_start_callback = method(:handle_start)
242
+ @test_runner_chooser.test_case_start_callback = method(:handle_start)
243
+ @test_runner_chooser.test_suite_setup_callback = method(:handle_setup)
244
+ @test_runner_chooser.test_setup_callback = method(:handle_setup)
245
+ @test_runner_chooser.test_suite_teardown_callback = method(:handle_teardown)
246
+ @test_runner_chooser.test_teardown_callback = method(:handle_teardown)
247
+ @horizontal_frame.addWidget(@test_runner_chooser)
248
+
249
+ # Executing Test Case Status
250
+ @executing_status = Qt::HBoxLayout.new
251
+ @executing_test_case_label = Qt::Label.new('Executing Test Case:')
252
+ @executing_status.addWidget(@executing_test_case_label)
253
+ @test_status = Qt::LineEdit.new
254
+ @test_status.setReadOnly(true)
255
+ @executing_status.addWidget(@test_status)
256
+ @pass_label = Qt::Label.new('Pass:')
257
+ @executing_status.addWidget(@pass_label)
258
+ @pass_count = Qt::LineEdit.new
259
+ @pass_count.setFixedWidth(40)
260
+ @pass_count.setReadOnly(true)
261
+ @pass_count.setAlignment(Qt::AlignHCenter)
262
+ @pass_count.setColors(Cosmos::GREEN, Cosmos::WHITE)
263
+ @executing_status.addWidget(@pass_count)
264
+ @skip_label = Qt::Label.new('Skip:')
265
+ @executing_status.addWidget(@skip_label)
266
+ @skip_count = Qt::LineEdit.new
267
+ @skip_count.setFixedWidth(40)
268
+ @skip_count.setReadOnly(true)
269
+ @skip_count.setAlignment(Qt::AlignHCenter)
270
+ @skip_count.setColors(Cosmos::YELLOW, Cosmos::WHITE)
271
+ @executing_status.addWidget(@skip_count)
272
+ @fail_label = Qt::Label.new('Fail:')
273
+ @executing_status.addWidget(@fail_label)
274
+ @fail_count = Qt::LineEdit.new
275
+ @fail_count.setFixedWidth(40)
276
+ @fail_count.setReadOnly(true)
277
+ @fail_count.setAlignment(Qt::AlignHCenter)
278
+ @fail_count.setColors(Cosmos::RED, Cosmos::WHITE)
279
+ @executing_status.addWidget(@fail_count)
280
+ @progress_bar = Qt::ProgressBar.new
281
+ @progress_bar.setFixedWidth(200)
282
+ @progress_bar.setMinimum(0)
283
+ @progress_bar.setMaximum(100)
284
+ @executing_status.addWidget(@progress_bar)
285
+ @frame.addLayout(@executing_status)
286
+
287
+ # Separator before ScriptRunnerFrame
288
+ @sep3 = Qt::Frame.new(@central_widget)
289
+ @sep3.setFrameStyle(Qt::Frame::HLine | Qt::Frame::Sunken)
290
+ @frame.addWidget(@sep3)
291
+
292
+ @script_runner_frame = ScriptRunnerFrame.new(self)
293
+ @script_runner_frame.setContentsMargins(0,0,0,0)
294
+ @script_runner_frame.stop_callback = method(:handle_stop)
295
+ @script_runner_frame.allow_start = false
296
+ ScriptRunnerFrame.pause_on_error = true
297
+ @script_runner_frame.continue_after_error = true
298
+ @script_runner_frame.error_callback = method(:handle_error)
299
+ Test.abort_on_exception = false
300
+ @frame.addWidget(@script_runner_frame)
301
+
302
+ setCentralWidget(@central_widget)
303
+
304
+ # Display a blank message to force the statusBar to show
305
+ statusBar.showMessage("")
306
+ end
307
+
308
+ def status_timeout
309
+ pass_count = TestStatus.instance.pass_count
310
+ skip_count = TestStatus.instance.skip_count
311
+ fail_count = TestStatus.instance.fail_count
312
+ @test_status.text = TestStatus.instance.status
313
+ @pass_count.text = pass_count.to_s
314
+ @skip_count.text = skip_count.to_s
315
+ @fail_count.text = fail_count.to_s
316
+ if TestStatus.instance.status != ''
317
+ run_count = pass_count + skip_count + fail_count
318
+ total_count = TestStatus.instance.total
319
+ mod_run_count = run_count % total_count
320
+ progress = ((mod_run_count.to_f / total_count) * 100.0).to_i
321
+ @progress_bar.setValue(progress)
322
+ else
323
+ @progress_bar.setValue(0)
324
+ end
325
+ end
326
+
327
+ def self.results_writer
328
+ @@results_writer
329
+ end
330
+
331
+ def self.exec_test(result_string, test_suite_class, test_class = nil, test_case = nil)
332
+ @@started_success = false
333
+ @@test_suites.each do |test_suite|
334
+ if test_suite.class == test_suite_class
335
+ @@started_success = @@results_writer.collect_metadata(@@instance)
336
+ if @@started_success
337
+ @@results_writer.start(result_string, test_suite_class, test_class, test_case, @@settings)
338
+ loop do
339
+ yield(test_suite)
340
+ break if not @@settings['Loop Testing'] or (TestStatus.instance.fail_count > 0 and @@settings['Break Loop after Error'])
341
+ end
342
+ end
343
+ break
344
+ end
345
+ end
346
+ end
347
+
348
+ def self.start(test_suite_class, test_class = nil, test_case = nil)
349
+ result = []
350
+ exec_test('', test_suite_class, test_class, test_case) do |test_suite|
351
+ if test_case
352
+ result = test_suite.run_test_case(test_class, test_case)
353
+ @@results_writer.process_result(result)
354
+ raise StopScript if (result.exceptions and Test.abort_on_exception) or result.stopped
355
+ elsif test_class
356
+ test_suite.run_test(test_class) { |current_result| @@results_writer.process_result(current_result); raise StopScript if current_result.stopped }
357
+ else
358
+ test_suite.run { |current_result| @@results_writer.process_result(current_result); raise StopScript if current_result.stopped }
359
+ end
360
+ end
361
+ end
362
+
363
+ def self.start_setup(test_suite_class, test_class = nil)
364
+ exec_test('Manual Setup', test_suite_class, test_class) do |test_suite|
365
+ if test_class
366
+ result = test_suite.run_test_setup(test_class)
367
+ else
368
+ result = test_suite.run_setup
369
+ end
370
+ if result
371
+ @@results_writer.process_result(result)
372
+ raise StopScript if result.stopped
373
+ end
374
+ end
375
+ end
376
+
377
+ def self.start_teardown(test_suite_class, test_class = nil)
378
+ exec_test('Manual Teardown', test_suite_class, test_class) do |test_suite|
379
+ if test_class
380
+ result = test_suite.run_test_teardown(test_class)
381
+ else
382
+ result = test_suite.run_teardown
383
+ end
384
+ if result
385
+ @@results_writer.process_result(result)
386
+ raise StopScript if result.stopped
387
+ end
388
+ end
389
+ end
390
+
391
+ def continue_without_pausing_on_errors?
392
+ if !@pause_on_error.isChecked()
393
+ msg = ""
394
+ if @continue_test_case_after_error.isChecked() and @abort_testing_after_error.isChecked()
395
+ msg = "the currently executing test case will run to completion before aborting"
396
+ elsif !@continue_test_case_after_error.isChecked() and @abort_testing_after_error.isChecked()
397
+ msg = "all testing will be aborted on an error"
398
+ elsif @continue_test_case_after_error.isChecked() and !@abort_testing_after_error.isChecked()
399
+ msg = "all testing will run to completion"
400
+ else
401
+ msg = "the next test case will start executing"
402
+ end
403
+
404
+ if Qt::MessageBox.warning(self, "Warning", "If an error occurs, testing will not pause and #{msg}. Continue?", Qt::MessageBox::Yes | Qt::MessageBox::No, Qt::MessageBox::Yes) == Qt::MessageBox::No
405
+ return false
406
+ end
407
+ end
408
+ true
409
+ end
410
+
411
+ def continue_loop_testing?
412
+ if @loop_testing.isChecked()
413
+ msg = ""
414
+ if @break_loop_after_error.isChecked()
415
+ msg = "unless an error occurs"
416
+ else
417
+ msg = "until explicitly stopped"
418
+ end
419
+
420
+ if Qt::MessageBox.warning(self, "Warning", "Loop testing is enabled. Tests will run forever #{msg}. Continue?", Qt::MessageBox::Yes | Qt::MessageBox::No, Qt::MessageBox::Yes) == Qt::MessageBox::No
421
+ return false
422
+ end
423
+ end
424
+ true
425
+ end
426
+
427
+ ###########################################
428
+ # Callbacks
429
+ ###########################################
430
+
431
+ def generic_handler(test_suite, test = nil, test_case = nil, warnings = true)
432
+ if warnings
433
+ return unless continue_without_pausing_on_errors?
434
+ return unless continue_loop_testing?()
435
+ end
436
+
437
+ # TODO: This can take a while depending on the number of tests and their
438
+ # complexity. Consider making a progress bar for this.
439
+ begin
440
+ require_utilities()
441
+ handle_check_buttons()
442
+ @script_runner_frame.stop_message_log
443
+ yield
444
+ @script_runner_frame.run
445
+ rescue Exception => error
446
+ ExceptionDialog.new(self, error, "Error starting test", false)
447
+ end
448
+ end
449
+
450
+ def handle_start(test_suite, test = nil, test_case = nil, warnings = true)
451
+ generic_handler(test_suite, test, test_case, warnings) do
452
+ if test_case
453
+ @script_runner_frame.set_text("TestRunner.start(#{test_suite}, #{test}, '#{test_case}')", "#{test_suite}_#{test}_#{test_case}")
454
+ elsif test
455
+ @script_runner_frame.set_text("TestRunner.start(#{test_suite}, #{test})", "#{test_suite}_#{test}")
456
+ else
457
+ @script_runner_frame.set_text("TestRunner.start(#{test_suite})", test_suite)
458
+ end
459
+ end
460
+ end
461
+
462
+ def handle_setup(test_suite, test = nil)
463
+ generic_handler(test_suite, test) do
464
+ if test
465
+ @script_runner_frame.set_text("TestRunner.start_setup(#{test_suite}, #{test})", "#{test_suite}_#{test}_setup")
466
+ else
467
+ @script_runner_frame.set_text("TestRunner.start_setup(#{test_suite})", "#{test_suite}_setup")
468
+ end
469
+ end
470
+ end
471
+
472
+ def handle_teardown(test_suite, test = nil)
473
+ generic_handler(test_suite, test) do
474
+ if test
475
+ @script_runner_frame.set_text("TestRunner.start_teardown(#{test_suite}, #{test})", "#{test_suite}_#{test}_teardown")
476
+ else
477
+ @script_runner_frame.set_text("TestRunner.start_teardown(#{test_suite})", "#{test_suite}_teardown")
478
+ end
479
+ end
480
+ end
481
+
482
+ def handle_check_buttons
483
+ if @pause_on_error.isChecked()
484
+ ScriptRunnerFrame.pause_on_error = true
485
+ else
486
+ ScriptRunnerFrame.pause_on_error = false
487
+ end
488
+
489
+ if @continue_test_case_after_error.isChecked()
490
+ @script_runner_frame.continue_after_error = true
491
+ else
492
+ @script_runner_frame.continue_after_error = false
493
+ end
494
+
495
+ if @abort_testing_after_error.isChecked()
496
+ Test.abort_on_exception = true
497
+ else
498
+ Test.abort_on_exception = false
499
+ end
500
+
501
+ @@settings['Pause on Error'] = @pause_on_error.isChecked()
502
+ @@settings['Continue Test Case after Error'] = @continue_test_case_after_error.isChecked()
503
+ @@settings['Abort Testing after Error'] = @abort_testing_after_error.isChecked()
504
+ @@settings['Manual'] = @manual.isChecked()
505
+ @@settings['Loop Testing'] = @loop_testing.isChecked()
506
+ @@settings['Break Loop after Error'] = @break_loop_after_error.isChecked()
507
+
508
+ disable_while_running()
509
+ end
510
+
511
+ def handle_stop(script_runner_frame)
512
+ if @@started_success
513
+ @@results_writer.complete
514
+ if @@results_writer.data_package
515
+ ProgressDialog.execute(self, 'Data Package Creation Progress', 600, 300) do |progress_dialog|
516
+ @@results_writer.create_data_package(progress_dialog)
517
+ end
518
+ end
519
+ end
520
+ enable_while_stopped()
521
+ show_results() if @@started_success
522
+ end
523
+
524
+ def handle_error(script_runner_frame)
525
+ Qt.execute_in_main_thread(true) do
526
+ if @@settings['Continue Test Case after Error']
527
+ script_runner_frame.enable_retry()
528
+ else
529
+ script_runner_frame.disable_retry()
530
+ end
531
+ end
532
+ end
533
+
534
+ def disable_while_running
535
+ TestStatus.instance.status = ''
536
+ TestStatus.instance.pass_count = 0
537
+ TestStatus.instance.skip_count = 0
538
+ TestStatus.instance.fail_count = 0
539
+ @manual.setEnabled(false)
540
+ @pause_on_error.setEnabled(false)
541
+ @continue_test_case_after_error.setEnabled(false)
542
+ @abort_testing_after_error.setEnabled(false)
543
+ @loop_testing.setEnabled(false)
544
+ @break_loop_after_error.setEnabled(false)
545
+ @test_runner_chooser.setEnabled(false)
546
+ @show_last.setEnabled(false)
547
+ @select.setEnabled(false)
548
+ @test_results_log_message.setEnabled(true)
549
+ @script_log_message.setEnabled(true)
550
+ @show_call_stack.setEnabled(true)
551
+ end
552
+
553
+ def enable_while_stopped
554
+ @manual.setEnabled(true)
555
+ @pause_on_error.setEnabled(true)
556
+ @continue_test_case_after_error.setEnabled(true)
557
+ @abort_testing_after_error.setEnabled(true)
558
+ @loop_testing.setEnabled(true)
559
+ @break_loop_after_error.setEnabled(true) if @loop_testing.isChecked()
560
+ @test_runner_chooser.setEnabled(true)
561
+ @show_last.setEnabled(true)
562
+ @select.setEnabled(true)
563
+ @test_results_log_message.setEnabled(false)
564
+ @script_log_message.setEnabled(false)
565
+ @show_call_stack.setEnabled(false)
566
+ TestStatus.instance.status = ''
567
+ end
568
+
569
+ def closeEvent(event)
570
+ if @script_runner_frame.prompt_if_running_on_close()
571
+ shutdown_cmd_tlm()
572
+ @script_runner_frame.stop_message_log
573
+ super(event)
574
+ else
575
+ event.ignore()
576
+ end
577
+ end
578
+
579
+ def on_test_results_log_message
580
+ message = get_scriptrunner_log_message('Test Results Text Entry', 'Enter text to log to the test results file')
581
+ if message
582
+ Cosmos::Test.puts('User logged: ' + message.to_s)
583
+ @script_runner_frame.handle_output_io
584
+ end
585
+ end
586
+
587
+ def on_script_log_message
588
+ message = get_scriptrunner_log_message()
589
+ if message
590
+ @script_runner_frame.scriptrunner_puts 'User logged: ' + message.to_s
591
+ @script_runner_frame.handle_output_io
592
+ end
593
+ end
594
+
595
+ def on_script_call_stack
596
+ trace = @script_runner_frame.current_backtrace
597
+ ScrollTextDialog.new(self, 'Call Stack', trace.join("\n"))
598
+ end
599
+
600
+ def on_script_toggle_debug
601
+ @script_runner_frame.toggle_debug
602
+ end
603
+
604
+ def on_script_toggle_disconnect
605
+ @server_config_file = @script_runner_frame.toggle_disconnect(@server_config_file)
606
+ end
607
+
608
+ include ScriptAudit # script_audit()
609
+
610
+ def require_utilities
611
+ ScriptRunnerFrame.instance = @script_runner_frame
612
+ build = false
613
+ @utilities.each do |utility|
614
+ if require_utility(utility)
615
+ build = true
616
+ end
617
+ end
618
+ if build
619
+ build_test_suites()
620
+ end
621
+ ScriptRunnerFrame.instance = nil
622
+ end
623
+
624
+ # Show Dialog box with textfield containing results
625
+ def show_results
626
+ if @@results_writer.filename
627
+ results_text = File.read(@@results_writer.filename)
628
+
629
+ dialog = Qt::Dialog.new(self) do |box|
630
+ box.setWindowTitle('Results')
631
+ box.resize(600, 600)
632
+ text_field = Qt::PlainTextEdit.new
633
+ text_field.setReadOnly(true)
634
+ orig_font = text_field.font
635
+ text_field.setFont(Cosmos.getFont(orig_font.family, orig_font.point_size+2))
636
+ text_field.setWordWrapMode(Qt::TextOption::NoWrap)
637
+ state = :NORMAL
638
+ results_text.each_line do |line|
639
+ state = :NORMAL if line[0..0] != ' ' and line.strip.length != 0
640
+ if line =~ /:PASS/
641
+ text_field.appendText(line, Cosmos::GREEN)
642
+ state = :PASS
643
+ elsif line =~ /:SKIP/
644
+ text_field.appendText(line, Cosmos::YELLOW)
645
+ state = :SKIP
646
+ elsif line =~ /:FAIL/
647
+ text_field.appendText(line, Cosmos::RED)
648
+ state = :FAIL
649
+ else
650
+ case state
651
+ when :NORMAL
652
+ text_field.appendText(line)
653
+ when :PASS
654
+ text_field.appendText(line, Cosmos::GREEN)
655
+ when :SKIP
656
+ text_field.appendText(line, Cosmos::YELLOW)
657
+ when :FAIL
658
+ text_field.appendText(line, Cosmos::RED)
659
+ end
660
+ end
661
+ end
662
+
663
+ vframe = Qt::VBoxLayout.new
664
+ vframe.addWidget(text_field)
665
+
666
+ # Separator Between checkboxes
667
+ sep = Qt::Frame.new(box)
668
+ sep.setFrameStyle(Qt::Frame::VLine | Qt::Frame::Sunken)
669
+ vframe.addWidget(sep)
670
+
671
+ ok = Qt::PushButton.new('OK')
672
+ ok.setDefault(true)
673
+ ok.connect(SIGNAL('clicked(bool)')) { box.accept }
674
+ vframe.addWidget(ok)
675
+ box.setLayout(vframe)
676
+ end
677
+ dialog.exec
678
+ dialog.dispose
679
+ end
680
+ end
681
+
682
+ def create_node(yard_doc, name, tree)
683
+ node = Qt::TreeWidgetItem.new([name])
684
+ node.setCheckState(0, Qt::Unchecked)
685
+ yield node
686
+ description = yard_doc.nil? ? "" : yard_doc.docstring
687
+ description = UNASSIGNED_SUITE_DESCRIPTION if name == "UnassignedTestSuite"
688
+ desc_label = Qt::Label.new(description.gsub(/\n/,' '))
689
+ desc_label.setMinimumHeight(desc_label.fontMetrics.height * 2)
690
+ desc_label.setWordWrap(true)
691
+ tree.setItemWidget(node, 1, desc_label)
692
+ return node
693
+ end
694
+
695
+ # Show Dialog box with tree of tests to allow the user to select
696
+ # a subset of tests. This also shows the Test Descriptions.
697
+ def show_select
698
+ dialog = Qt::Dialog.new(self) do |box|
699
+ box.setWindowTitle('Test Selections')
700
+ box.resize(650, 600)
701
+ @procedure_dirs.each do |dir|
702
+ # Set the logging level to ERROR to avoid output if one of the
703
+ # scripts we are parsing has syntax errors
704
+ YARD.parse(File.join(dir, '**', '*.rb'), [], YARD::Logger::ERROR)
705
+ end
706
+
707
+ tree = Qt::TreeWidget.new
708
+ tree.setColumnCount(2)
709
+ tree.setHeaderLabels(["Name", "Description"])
710
+ tree.connect(SIGNAL('itemClicked(QTreeWidgetItem*, int)')) do |widget, column|
711
+ tree.topLevelItems do |suite_node|
712
+ if suite_node != widget.topLevel
713
+ suite_node.setCheckStateAll(Qt::Unchecked)
714
+ end
715
+ end
716
+ end
717
+
718
+ orig_font = nil
719
+ @@test_suites.each do |suite|
720
+ next if suite.name == "CustomTestSuite"
721
+ doc = YARD::Registry.resolve(nil, suite.name)
722
+ suite_node = create_node(doc, suite.name, tree) do |node|
723
+ orig_font = node.font(0)
724
+ new_font = Cosmos.getFont(orig_font.family,
725
+ orig_font.point_size+5,
726
+ Qt::Font::Bold)
727
+ node.setFont(0, new_font)
728
+ tree.addTopLevelItem(node)
729
+ end
730
+
731
+ if suite.respond_to? :setup
732
+ doc = YARD::Registry.resolve(P(suite.name.to_s), "#setup", true)
733
+ create_node(doc, "setup", tree) do |node|
734
+ font = Cosmos.getFont(orig_font.family,
735
+ orig_font.point_size,
736
+ Qt::Font::Normal,
737
+ true) # italic
738
+ node.setFont(0, font)
739
+ suite_node.addChild(node)
740
+ end
741
+ end
742
+
743
+ suite.tests.each do |test_class, test|
744
+ doc = YARD::Registry.resolve(nil, test.name)
745
+ test_node = create_node(doc, test.name, tree) do |node|
746
+ font = Cosmos.getFont(orig_font.family,
747
+ orig_font.point_size + 2,
748
+ Qt::Font::Bold)
749
+ node.setFont(0, font)
750
+ suite_node.addChild(node)
751
+ node.setExpanded(true)
752
+ end
753
+
754
+ if test.respond_to? :setup
755
+ doc = YARD::Registry.resolve(P(test_class.to_s), "#setup", true)
756
+ create_node(doc, "setup", tree) do |node|
757
+ font = Cosmos.getFont(orig_font.family,
758
+ orig_font.point_size,
759
+ Qt::Font::Normal,
760
+ true) # italic
761
+ node.setFont(0, font)
762
+ test_node.addChild(node)
763
+ end
764
+ end
765
+
766
+ test_class.test_cases.each do |tc|
767
+ doc = YARD::Registry.resolve(P(test_class.to_s), "##{tc.to_s}", true)
768
+ create_node(doc, tc.to_s, tree) do |node|
769
+ test_node.addChild(node)
770
+ end
771
+ end
772
+
773
+ if test.respond_to? :teardown
774
+ doc = YARD::Registry.resolve(P(test_class.to_s), "#teardown", true)
775
+ create_node(doc, "teardown", tree) do |node|
776
+ font = Cosmos.getFont(orig_font.family,
777
+ orig_font.point_size,
778
+ Qt::Font::Normal,
779
+ true) # italic
780
+ node.setFont(0, font)
781
+ test_node.addChild(node)
782
+ end
783
+ end
784
+ end # suite.tests.each
785
+
786
+ if suite.respond_to? :teardown
787
+ doc = YARD::Registry.resolve(P(suite.name.to_s), "#teardown", true)
788
+ create_node(doc, "teardown", tree) do |node|
789
+ font = Cosmos.getFont(orig_font.family,
790
+ orig_font.point_size,
791
+ Qt::Font::Normal,
792
+ true) # italic
793
+ node.setFont(0, font)
794
+ suite_node.addChild(node)
795
+ end
796
+ end
797
+ end
798
+
799
+ tree.resizeColumnToContents(0)
800
+ dialog_layout = Qt::VBoxLayout.new
801
+ text = "Select test cases to be run in a newly created 'CustomTestSuite'. "\
802
+ "Note that tests can only be added from a single existing Test Suite. " \
803
+ "Thus clicking on something in another Test Suite deselects anything " \
804
+ "currently selected."
805
+ instructions = Qt::Label.new(text)
806
+ instructions.setWordWrap(true)
807
+ dialog_layout.addWidget(instructions)
808
+ dialog_layout.addWidget(tree)
809
+
810
+ # Separator Between checkboxes
811
+ sep = Qt::Frame.new(box)
812
+ sep.setFrameStyle(Qt::Frame::VLine | Qt::Frame::Sunken)
813
+ dialog_layout.addWidget(sep)
814
+
815
+ button_box = Qt::DialogButtonBox.new(Qt::DialogButtonBox::Ok |
816
+ Qt::DialogButtonBox::Cancel)
817
+ connect(button_box, SIGNAL('rejected()'), box, SLOT('reject()'))
818
+ connect(button_box, SIGNAL('accepted()')) do
819
+ Cosmos.module_eval("class CustomTestSuite < TestSuite; end")
820
+ tree.topLevelItems do |suite_node|
821
+ next if suite_node.checkState == Qt::Unchecked
822
+ cur_suite = OpenStruct.new(:setup=>false, :teardown=>false, :tests=>{})
823
+ suite = CustomTestSuite.new
824
+ begin
825
+ # Remove any previously defined suite setup methods
826
+ CustomTestSuite.send(:remove_method, :setup)
827
+ rescue NameError
828
+ # NameError is raised if no setup method was defined
829
+ end
830
+ begin
831
+ # Remove any previously defined suite teardown methods
832
+ CustomTestSuite.send(:remove_method, :teardown)
833
+ rescue NameError
834
+ # NameError is raised if no teardown method was defined
835
+ end
836
+
837
+ suite_node.children do |test_node|
838
+ if test_node.checkState == Qt::Checked
839
+ if test_node.text == 'setup'
840
+ cur_suite.setup = true
841
+ # Find the suite instance among the test suites
842
+ inst = @@test_suites.detect {|my_suite| my_suite.class.to_s == suite_node.text}
843
+ # Create a lambda which will call that one setup method
844
+ body = lambda { inst.setup }
845
+ CustomTestSuite.send(:define_method, :setup, &body)
846
+ end
847
+ if test_node.text == 'teardown'
848
+ cur_suite.teardown = true
849
+ # Find the suite instance among the test suites
850
+ inst = @@test_suites.detect {|my_suite| my_suite.class.to_s == suite_node.text}
851
+ # Create a lambda which will call that one teardown method
852
+ body = lambda { inst.teardown}
853
+ CustomTestSuite.send(:define_method, :teardown, &body)
854
+ end
855
+ end
856
+
857
+ test_node.children do |test_case|
858
+ next if test_case.checkState == Qt::Unchecked
859
+ node = cur_suite.tests[test_node.text] ||=
860
+ OpenStruct.new(:setup=>false, :teardown=>false, :cases=>[])
861
+
862
+ case test_case.text
863
+ when 'setup'
864
+ suite.add_test_setup(test_node.text)
865
+ node.setup = true
866
+ when 'teardown'
867
+ suite.add_test_teardown(test_node.text)
868
+ node.teardown = true
869
+ else
870
+ suite.add_test_case(test_node.text, test_case.text)
871
+ node.cases << test_case.text
872
+ end
873
+ end
874
+ end
875
+ @@suites["CustomTestSuite"] = cur_suite
876
+ @@test_suites = @@test_suites.select {|my_suite| my_suite.class != CustomTestSuite}
877
+ @@test_suites << suite
878
+ end
879
+ Qt.execute_in_main_thread(true) do
880
+ @test_runner_chooser.test_suites = @@suites
881
+ @test_runner_chooser.select_suite("CustomTestSuite")
882
+ end
883
+ box.accept
884
+ end
885
+ dialog_layout.addWidget(button_box)
886
+ box.setLayout(dialog_layout)
887
+ end
888
+ dialog.raise
889
+ dialog.exec
890
+ dialog.dispose
891
+ end
892
+
893
+ def process_config(filename)
894
+ ScriptRunnerFrame.instance = @script_runner_frame
895
+
896
+ # Remember all the requires that fail and warn the user
897
+ require_errors = []
898
+
899
+ # Ensure the file exists
900
+ raise "Configuration File: #{filename} does not exist" unless test(?f, filename)
901
+ parser = ConfigParser.new
902
+ parser.parse_file(filename) do |keyword, params|
903
+ case keyword
904
+ when 'REQUIRE_UTILITY'
905
+ parser.verify_num_parameters(1, 1, "REQUIRE_UTILITY <filename>")
906
+ begin
907
+ require_utility params[0]
908
+ @utilities << params[0]
909
+ rescue Exception => err
910
+ require_errors << "<b>#{params[0]}</b>:\n#{err.formatted}\n"
911
+ end
912
+
913
+ when 'RESULTS_WRITER'
914
+ data_package = @@results_writer.data_package
915
+ metadata = @@results_writer.metadata
916
+ parser.verify_num_parameters(1, nil, "RESULTS_WRITER <filename> <class specific options>")
917
+ results_class = Cosmos.require_class(params[0])
918
+ if params[1]
919
+ @@results_writer = results_class.new(*params[1..-1])
920
+ else
921
+ @@results_writer = results_class.new
922
+ end
923
+ @@results_writer.data_package = data_package
924
+ @@results_writer.metadata = metadata
925
+
926
+ when 'ALLOW_DEBUG'
927
+ parser.verify_num_parameters(0, 0, "ALLOW_DEBUG")
928
+ Qt.execute_in_main_thread(true) { @toggle_debug.setEnabled(true) }
929
+
930
+ when 'PAUSE_ON_ERROR'
931
+ parser.verify_num_parameters(1, 1, "#{keyword} <TRUE or FALSE>")
932
+ Qt.execute_in_main_thread(true) do
933
+ @pause_on_error.setChecked(ConfigParser.handle_true_false(params[0]))
934
+ end
935
+
936
+ when 'CONTINUE_TEST_CASE_AFTER_ERROR'
937
+ parser.verify_num_parameters(1, 1, "#{keyword} <TRUE or FALSE>")
938
+ Qt.execute_in_main_thread(true) { @continue_test_case_after_error.setChecked(ConfigParser.handle_true_false(params[0])) }
939
+
940
+ when 'ABORT_TESTING_AFTER_ERROR'
941
+ parser.verify_num_parameters(1, 1, "#{keyword} <TRUE or FALSE>")
942
+ Qt.execute_in_main_thread(true) { @abort_testing_after_error.setChecked(ConfigParser.handle_true_false(params[0])) }
943
+
944
+ when 'MANUAL'
945
+ parser.verify_num_parameters(1, 1, "#{keyword} <TRUE or FALSE>")
946
+ Qt.execute_in_main_thread(true) do
947
+ @manual.setChecked(ConfigParser.handle_true_false(params[0]))
948
+ if @manual.isChecked()
949
+ $manual = true
950
+ else
951
+ $manual = false
952
+ end
953
+ end
954
+
955
+ when 'LOOP_TESTING'
956
+ parser.verify_num_parameters(1, 1, "#{keyword} <TRUE or FALSE>")
957
+ Qt.execute_in_main_thread(true) do
958
+ @loop_testing.setChecked(ConfigParser.handle_true_false(params[0]))
959
+ if @loop_testing.isChecked()
960
+ $loop_testing = true
961
+ @break_loop_after_error.setEnabled(true)
962
+ else
963
+ $loop_testing = false
964
+ @break_loop_after_error.setEnabled(false)
965
+ end
966
+ end
967
+
968
+ when 'BREAK_LOOP_AFTER_ERROR'
969
+ parser.verify_num_parameters(1, 1, "#{keyword} <TRUE or FALSE>")
970
+ Qt.execute_in_main_thread(true) { @break_loop_after_error.setChecked(ConfigParser.handle_true_false(params[0])) }
971
+
972
+ when 'IGNORE_TEST'
973
+ parser.verify_num_parameters(1, 1, "#{keyword} <Test Class Name (case sensitive)>")
974
+ @ignore_tests << params[0]
975
+
976
+ when 'IGNORE_TEST_SUITE'
977
+ parser.verify_num_parameters(1, 1, "#{keyword} <Test Suite Class Name (case sensitive)>")
978
+ @ignore_test_suites << params[0]
979
+
980
+ when 'LINE_DELAY'
981
+ parser.verify_num_parameters(1, 1, "#{keyword} <Line Delay in Seconds>")
982
+ ScriptRunnerFrame.line_delay = params[0].to_f
983
+
984
+ when 'MONITOR_LIMITS'
985
+ parser.verify_num_parameters(0, 0, keyword)
986
+ ScriptRunnerFrame.monitor_limits = true
987
+
988
+ when 'PAUSE_ON_RED'
989
+ parser.verify_num_parameters(0, 0, keyword)
990
+ ScriptRunnerFrame.monitor_limits = true
991
+ ScriptRunnerFrame.pause_on_red = true
992
+
993
+ when 'CREATE_DATA_PACKAGE'
994
+ parser.verify_num_parameters(0, 0, keyword)
995
+ @@results_writer.data_package = true
996
+
997
+ when 'AUTO_CYCLE_LOGS'
998
+ parser.verify_num_parameters(0, 0, keyword)
999
+ @@results_writer.auto_cycle_logs = true
1000
+
1001
+ # TODO: Deprecate COLLECT_META_DATA
1002
+ when 'COLLECT_METADATA', 'COLLECT_META_DATA'
1003
+ parser.verify_num_parameters(2, 2, "#{keyword} <Metadata Target Name> <Metadata Packet Name>")
1004
+ System.telemetry.packet(params[0], params[1])
1005
+ @@results_writer.metadata = [params[0], params[1]]
1006
+
1007
+ else
1008
+ raise "Unhandled keyword: #{keyword}" if keyword
1009
+ end
1010
+ end
1011
+
1012
+ # Warn the user about all the requires that failed
1013
+ unless require_errors.empty?
1014
+ Qt.execute_in_main_thread(true) do
1015
+ message = "While loading the Test Runner configuration file: #{filename}."
1016
+ message << "\n\nThe following errors occurred:\n#{require_errors.join("\n")}" unless require_errors.empty?
1017
+ ScrollTextDialog.new(self, "TestRunner Errors", message)
1018
+ end
1019
+ end
1020
+
1021
+ # Build Test objects
1022
+ build_test_suites()
1023
+
1024
+ ScriptRunnerFrame.instance = nil
1025
+ end
1026
+
1027
+ def build_test_suites
1028
+ ScriptRunnerFrame.instance.use_instrumentation = false
1029
+
1030
+ ignored_test_classes = []
1031
+ ignored_test_suite_classes = []
1032
+
1033
+ @ignore_tests.each do |test_name|
1034
+ begin
1035
+ klass = Object.const_get(test_name)
1036
+ ignored_test_classes << klass if klass
1037
+ rescue
1038
+ end
1039
+ end
1040
+
1041
+ @ignore_test_suites.each do |test_suite_name|
1042
+ begin
1043
+ klass = Object.const_get(test_suite_name)
1044
+ ignored_test_suite_classes << klass if klass
1045
+ rescue
1046
+ end
1047
+ end
1048
+
1049
+ # Build list of TestSuites and Tests
1050
+ @@test_suites = @@test_suites.select {|my_suite| my_suite.name == 'CustomTestSuite'}
1051
+ tests = []
1052
+ ObjectSpace.each_object(Class) do |object|
1053
+ next if object.name == 'CustomTestSuite'
1054
+ if (object.ancestors.include?(TestSuite) &&
1055
+ object != TestSuite &&
1056
+ !ignored_test_suite_classes.include?(object))
1057
+ @@test_suites << object.new
1058
+ end
1059
+ if (object.ancestors.include?(Test) &&
1060
+ object != Test &&
1061
+ !ignored_test_classes.include?(object))
1062
+ tests << object
1063
+ end
1064
+ end
1065
+ # Raise error if no test suites or tests
1066
+ if @@test_suites.empty? || tests.empty?
1067
+ msg = "No TestSuites or no Test classes found"
1068
+ if !ignored_test_suite_classes.empty?
1069
+ msg << "\n\nThe following TestSuites were found but ignored:\n#{ignored_test_suite_classes.join(", ")}"
1070
+ end
1071
+ if !ignored_test_classes.empty?
1072
+ msg << "\n\nThe following Tests were found but ignored:\n#{ignored_test_classes.join(", ")}"
1073
+ end
1074
+ Qt.execute_in_main_thread(true) do
1075
+ Qt::MessageBox.critical(self, 'Error', msg)
1076
+ end
1077
+ exit 1
1078
+ end
1079
+
1080
+ # Create TestSuite for unassigned Tests
1081
+ @@test_suites.sort!
1082
+ @@test_suites.each do |test_suite|
1083
+ tests_to_delete = []
1084
+ tests.each { |test| tests_to_delete << test if test_suite.tests[test] }
1085
+ tests_to_delete.each { |test| tests.delete(test) }
1086
+ end
1087
+ if tests.empty?
1088
+ @@test_suites = @@test_suites.select {|suite| suite.class != UnassignedTestSuite}
1089
+ else
1090
+ uts = @@test_suites.select {|suite| suite.class == UnassignedTestSuite}[0]
1091
+ tests.each { |test| uts.add_test(test) }
1092
+ end
1093
+
1094
+ ScriptRunnerFrame.instance.use_instrumentation = true
1095
+ @@test_suites.each do |suite|
1096
+ cur_suite = OpenStruct.new(:setup=>false, :teardown=>false, :tests=>{})
1097
+ cur_suite.setup = true if suite.class.method_defined?(:setup)
1098
+ cur_suite.teardown = true if suite.class.method_defined?(:teardown)
1099
+
1100
+ suite.plans.each do |test_type, test_class, test_case|
1101
+ case test_type
1102
+ when :TEST
1103
+ cur_suite.tests[test_class.name] ||=
1104
+ OpenStruct.new(:setup=>false, :teardown=>false, :cases=>[])
1105
+ cur_suite.tests[test_class.name].cases.concat(test_class.test_cases)
1106
+ cur_suite.tests[test_class.name].cases.uniq!
1107
+ cur_suite.tests[test_class.name].cases.sort!
1108
+ cur_suite.tests[test_class.name].setup = true if test_class.method_defined?(:setup)
1109
+ cur_suite.tests[test_class.name].teardown = true if test_class.method_defined?(:teardown)
1110
+ when :TEST_CASE
1111
+ cur_suite.tests[test_class.name] ||=
1112
+ OpenStruct.new(:setup=>false, :teardown=>false, :cases=>[])
1113
+ # Explicitly check for this method and raise an error if it does not exist
1114
+ if test_class.method_defined?(test_case.intern)
1115
+ cur_suite.tests[test_class.name].cases << test_case
1116
+ cur_suite.tests[test_class.name].cases.uniq!
1117
+ cur_suite.tests[test_class.name].cases.sort!
1118
+ else
1119
+ raise "#{test_class} does not have a #{test_case} method defined."
1120
+ end
1121
+ cur_suite.tests[test_class.name].setup = true if test_class.method_defined?(:setup)
1122
+ cur_suite.tests[test_class.name].teardown = true if test_class.method_defined?(:teardown)
1123
+ when :TEST_SETUP
1124
+ cur_suite.tests[test_class.name] ||=
1125
+ OpenStruct.new(:setup=>false, :teardown=>false, :cases=>[])
1126
+ # Explicitly check for the setup method and raise an error if it does not exist
1127
+ if test_class.method_defined?(:setup)
1128
+ cur_suite.tests[test_class.name].setup = true
1129
+ else
1130
+ raise "#{test_class} does not have a setup method defined."
1131
+ end
1132
+ when :TEST_TEARDOWN
1133
+ cur_suite.tests[test_class.name] ||=
1134
+ OpenStruct.new(:setup=>false, :teardown=>false, :cases=>[])
1135
+ # Explicitly check for the teardown method and raise an error if it does not exist
1136
+ if test_class.method_defined?(:teardown)
1137
+ cur_suite.tests[test_class.name].teardown = true
1138
+ else
1139
+ raise "#{test_class} does not have a teardown method defined."
1140
+ end
1141
+ end
1142
+ end
1143
+ @@suites[suite.name.split('::')[-1]] = cur_suite unless suite.name == 'CustomTestSuite'
1144
+ end
1145
+ Qt.execute_in_main_thread(true) { @test_runner_chooser.test_suites = @@suites }
1146
+ end
1147
+
1148
+ def self.run(option_parser = nil, options = nil)
1149
+ Cosmos.catch_fatal_exception do
1150
+ unless option_parser and options
1151
+ option_parser, options = create_default_options()
1152
+ options.width = 800
1153
+ options.height = 700
1154
+ options.title = "Test Runner"
1155
+ options.auto_size = false
1156
+ options.config_file = File.join(Cosmos::USERPATH, 'config', 'tools', 'test_runner', 'test_runner.txt')
1157
+ options.server_config_file = CmdTlmServer::DEFAULT_CONFIG_FILE
1158
+ option_parser.separator "Test Runner Specific Options:"
1159
+ option_parser.on("-c", "--config FILE", "Use the specified configuration file") do |arg|
1160
+ options.config_file = File.join(Cosmos::USERPATH, 'config', 'tools', 'test_runner', arg)
1161
+ end
1162
+ option_parser.on("-s", "--server FILE", "Use the specified server configuration file for disconnect mode") do |arg|
1163
+ options.server_config_file = arg
1164
+ end
1165
+ option_parser.on("--suite SUITE", "Start the specified test suite.") do |arg|
1166
+ options.test_suite = arg
1167
+ end
1168
+ option_parser.on("--group GROUP", "Start the specified test group. Requires the --suite option.") do |arg|
1169
+ unless options.test_suite
1170
+ puts option_parser
1171
+ exit
1172
+ end
1173
+ options.test_group = arg
1174
+ end
1175
+ option_parser.on("--case CASE", "Start the specified test case. Requires the --suite and --group options.") do |arg|
1176
+ unless options.test_suite && options.test_group
1177
+ puts option_parser
1178
+ exit
1179
+ end
1180
+ options.test_case = arg
1181
+ end
1182
+ end
1183
+
1184
+ super(option_parser, options)
1185
+ end
1186
+ end
1187
+ end # class TestRunner
1188
+
1189
+ end # module Cosmos