cosmos 3.3.3 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -0
  3. data/.travis.yml +2 -1
  4. data/Gemfile +4 -3
  5. data/Manifest.txt +22 -0
  6. data/autohotkey/tools/handbook_creator.ahk +9 -0
  7. data/autohotkey/tools/packet_viewer.ahk +4 -0
  8. data/bin/exchndl20-x64.dll +0 -0
  9. data/bin/exchndl20.dll +0 -0
  10. data/bin/exchndl21-x64.dll +0 -0
  11. data/bin/exchndl21.dll +0 -0
  12. data/bin/exchndl22-x64.dll +0 -0
  13. data/bin/exchndl22.dll +0 -0
  14. data/bin/mgwhelp-x64.dll +0 -0
  15. data/bin/mgwhelp.dll +0 -0
  16. data/cosmos.gemspec +1 -0
  17. data/data/crc.txt +30 -24
  18. data/demo/config/data/crc.txt +3 -3
  19. data/demo/config/tools/handbook_creator/templates/command_packets.html.erb +3 -1
  20. data/demo/config/tools/handbook_creator/templates/telemetry_packets.html.erb +3 -1
  21. data/demo/procedures/cosmos_api_test.rb +1 -1
  22. data/ext/cosmos/ext/low_fragmentation_array/low_fragmentation_array.c +4 -0
  23. data/ext/cosmos/ext/platform/platform.c +22 -2
  24. data/ext/cosmos/ext/structure/structure.c +631 -104
  25. data/ext/cosmos/ext/telemetry/telemetry.c +3 -2
  26. data/lib/cosmos/gui/line_graph/line_graph_drawing.rb +71 -92
  27. data/lib/cosmos/gui/line_graph/overview_graph.rb +1 -1
  28. data/lib/cosmos/gui/qt.rb +38 -24
  29. data/lib/cosmos/gui/text/ruby_editor.rb +1 -1
  30. data/lib/cosmos/packets/binary_accessor.rb +1 -288
  31. data/lib/cosmos/packets/telemetry.rb +2 -1
  32. data/lib/cosmos/script/cmd_tlm_server.rb +110 -0
  33. data/lib/cosmos/script/commands.rb +166 -0
  34. data/lib/cosmos/script/extract.rb +2 -2
  35. data/lib/cosmos/script/limits.rb +108 -0
  36. data/lib/cosmos/script/script.rb +28 -1487
  37. data/lib/cosmos/script/scripting.rb +889 -0
  38. data/lib/cosmos/script/telemetry.rb +174 -0
  39. data/lib/cosmos/script/tools.rb +138 -0
  40. data/lib/cosmos/streams/stream_protocol.rb +9 -6
  41. data/lib/cosmos/system/target.rb +55 -38
  42. data/lib/cosmos/tools/cmd_tlm_server/api.rb +6 -3
  43. data/lib/cosmos/tools/cmd_tlm_server/connections.rb +0 -1
  44. data/lib/cosmos/tools/cmd_tlm_server/gui/interfaces_tab.rb +17 -7
  45. data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +15 -4
  46. data/lib/cosmos/tools/handbook_creator/handbook_creator.rb +15 -8
  47. data/lib/cosmos/tools/handbook_creator/handbook_creator_config.rb +41 -13
  48. data/lib/cosmos/tools/packet_viewer/packet_viewer.rb +18 -1
  49. data/lib/cosmos/tools/tlm_viewer/widgets/canvasline_widget.rb +1 -1
  50. data/lib/cosmos/tools/tlm_viewer/widgets/canvaslinevalue_widget.rb +1 -1
  51. data/lib/cosmos/tools/tlm_viewer/widgets/limitsbar_widget.rb +1 -1
  52. data/lib/cosmos/tools/tlm_viewer/widgets/rangebar_widget.rb +1 -1
  53. data/lib/cosmos/top_level.rb +1 -1
  54. data/lib/cosmos/utilities/ruby_lex_utils.rb +1 -1
  55. data/lib/cosmos/version.rb +5 -5
  56. data/spec/gui/line_graph/line_clip_spec.rb +6 -6
  57. data/spec/gui/qt_spec.rb +102 -0
  58. data/spec/interfaces/interface_spec.rb +9 -9
  59. data/spec/interfaces/linc_interface_spec.rb +72 -15
  60. data/spec/interfaces/serial_interface_spec.rb +9 -9
  61. data/spec/interfaces/simulated_target_interface_spec.rb +7 -7
  62. data/spec/interfaces/stream_interface_spec.rb +4 -4
  63. data/spec/interfaces/tcpip_client_interface_spec.rb +8 -8
  64. data/spec/interfaces/tcpip_server_interface_spec.rb +9 -9
  65. data/spec/interfaces/udp_interface_spec.rb +20 -20
  66. data/spec/io/json_drb_spec.rb +4 -4
  67. data/spec/io/raw_logger_pair_spec.rb +20 -20
  68. data/spec/io/raw_logger_spec.rb +3 -3
  69. data/spec/io/tcpip_server_spec.rb +9 -9
  70. data/spec/io/udp_sockets_spec.rb +2 -2
  71. data/spec/io/win32_serial_driver_spec.rb +2 -2
  72. data/spec/packets/binary_accessor_spec.rb +143 -6
  73. data/spec/packets/commands_spec.rb +5 -5
  74. data/spec/packets/limits_spec.rb +15 -15
  75. data/spec/packets/packet_config_spec.rb +19 -19
  76. data/spec/packets/packet_item_limits_spec.rb +3 -3
  77. data/spec/packets/packet_item_spec.rb +4 -4
  78. data/spec/packets/packet_spec.rb +33 -33
  79. data/spec/packets/structure_item_spec.rb +19 -19
  80. data/spec/packets/telemetry_spec.rb +6 -6
  81. data/spec/script/cmd_tlm_server_spec.rb +110 -0
  82. data/spec/script/commands_disconnect_spec.rb +270 -0
  83. data/spec/script/commands_spec.rb +288 -0
  84. data/spec/script/limits_spec.rb +153 -0
  85. data/spec/script/script_spec.rb +32 -696
  86. data/spec/script/scripting_spec.rb +436 -0
  87. data/spec/script/telemetry_spec.rb +130 -0
  88. data/spec/script/tools_spec.rb +117 -0
  89. data/spec/spec_helper.rb +10 -5
  90. data/spec/streams/preidentified_stream_protocol_spec.rb +4 -4
  91. data/spec/streams/serial_stream_spec.rb +8 -8
  92. data/spec/streams/stream_protocol_spec.rb +4 -4
  93. data/spec/streams/tcpip_client_stream_spec.rb +3 -3
  94. data/spec/streams/tcpip_socket_stream_spec.rb +7 -7
  95. data/spec/streams/template_stream_protocol_spec.rb +1 -1
  96. data/spec/system/system_spec.rb +6 -6
  97. data/spec/system/target_spec.rb +2 -0
  98. data/spec/tools/cmd_tlm_server/api_spec.rb +17 -17
  99. data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +5 -5
  100. data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +3 -3
  101. data/spec/top_level/top_level_spec.rb +8 -8
  102. data/spec/utilities/csv_spec.rb +3 -3
  103. data/spec/utilities/message_log_spec.rb +3 -3
  104. data/spec/utilities/ruby_lex_utils_spec.rb +7 -7
  105. data/test/performance/config/tools/launcher/launcher_threads.txt +8 -1
  106. data/test/performance/tools/CmdTlmServerMemProf +1 -1
  107. data/test/performance/tools/TlmGrapherMemProf +19 -0
  108. data/test/performance/tools/TlmGrapherMemProf.bat +59 -0
  109. metadata +38 -2
@@ -0,0 +1,436 @@
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 'spec_helper'
12
+ require 'cosmos'
13
+ require 'cosmos/script/script'
14
+ require 'tempfile'
15
+
16
+ module Cosmos
17
+
18
+ describe Script do
19
+
20
+ before(:all) do
21
+ cts = File.join(Cosmos::USERPATH,'config','tools','cmd_tlm_server','cmd_tlm_server.txt')
22
+ FileUtils.mkdir_p(File.dirname(cts))
23
+ File.open(cts,'w') do |file|
24
+ file.puts 'INTERFACE INST_INT interface.rb'
25
+ file.puts 'TARGET INST'
26
+ end
27
+ System.class_eval('@@instance = nil')
28
+
29
+ require 'cosmos/script'
30
+ end
31
+
32
+ after(:all) do
33
+ clean_config()
34
+ FileUtils.rm_rf File.join(Cosmos::USERPATH,'config','tools')
35
+ end
36
+
37
+ before(:each) do
38
+ allow_any_instance_of(Interface).to receive(:connected?).and_return(true)
39
+ allow_any_instance_of(Interface).to receive(:disconnect)
40
+ allow_any_instance_of(Interface).to receive(:write)
41
+ allow_any_instance_of(Interface).to receive(:read)
42
+
43
+ @server = CmdTlmServer.new
44
+ shutdown_cmd_tlm()
45
+ initialize_script_module()
46
+ sleep 0.1
47
+ end
48
+
49
+ after(:each) do
50
+ @server.stop
51
+ shutdown_cmd_tlm()
52
+ sleep(0.1)
53
+ end
54
+
55
+ describe "play_wav_file" do
56
+ it "plays a wav file if Qt is available" do
57
+ module Qt
58
+ def self.execute_in_main_thread(bool); yield; end
59
+ class CoreApplication; def self.instance; true; end; end;
60
+ class Sound; def self.isAvailable; true; end; end
61
+ end
62
+ expect(Qt::Sound).to receive(:play).with("sound.wav")
63
+ play_wav_file("sound.wav")
64
+ end
65
+ end
66
+
67
+ describe "status_bar" do
68
+ it "sets the ScriptRunner status bar" do
69
+ class ScriptRunner; end
70
+ sc = ScriptRunner.new
71
+ expect(sc).to receive(:script_set_status).with("HI")
72
+ status_bar("HI")
73
+ end
74
+ end
75
+
76
+ describe "ask_string, ask" do
77
+ it "gets user input" do
78
+ $stdout = StringIO.new
79
+ expect(self).to receive(:gets) { '10' }
80
+ expect(ask_string("Question", 5)).to eql '10'
81
+ expect(self).to receive(:gets) { '10' }
82
+ expect(ask("")).to eql 10
83
+ $stdout = STDOUT
84
+ end
85
+ end
86
+
87
+ describe "prompt, prompt_message_box" do
88
+ it "prompts the user for input" do
89
+ $stdout = StringIO.new
90
+ expect(self).to receive(:gets) { 'message' }
91
+ expect(prompt("")).to eql 'message'
92
+ expect(self).to receive(:gets) { 'b1' }
93
+ expect(message_box("",["b1","b2"])).to eql 'b1'
94
+ $stdout = STDOUT
95
+ end
96
+ end
97
+
98
+ describe "check, check_formatted, check_with_units, check_raw" do
99
+ it "checks the number of parameters" do
100
+ expect { check("INST HEALTH_STATUS TEMP1", -100.0) }.to raise_error(/Invalid number of arguments/)
101
+ expect { check("INST", "HEALTH_STATUS", "TEMP1") }.to raise_error(/Invalid number of arguments/)
102
+ end
103
+
104
+ it "checks a telemetry item vs a condition" do
105
+ capture_io do |stdout|
106
+ check("INST HEALTH_STATUS TEMP1 == -100")
107
+ expect(stdout.string).to match "CHECK: INST HEALTH_STATUS TEMP1 == -100 success"
108
+ stdout.rewind
109
+
110
+ check("INST","HEALTH_STATUS","TEMP1","== -100")
111
+ expect(stdout.string).to match "CHECK: INST HEALTH_STATUS TEMP1 == -100 success"
112
+ stdout.rewind
113
+
114
+ check_formatted("INST HEALTH_STATUS TEMP1 == '-100.000'")
115
+ expect(stdout.string).to match "CHECK: INST HEALTH_STATUS TEMP1 == '-100.000' success"
116
+ stdout.rewind
117
+
118
+ check_formatted("INST","HEALTH_STATUS","TEMP1","== '-100.000'")
119
+ expect(stdout.string).to match "CHECK: INST HEALTH_STATUS TEMP1 == '-100.000' success"
120
+ stdout.rewind
121
+
122
+ check_with_units("INST HEALTH_STATUS TEMP1 == '-100.000 C'")
123
+ expect(stdout.string).to match "CHECK: INST HEALTH_STATUS TEMP1 == '-100.000 C' success"
124
+ stdout.rewind
125
+
126
+ check_with_units("INST","HEALTH_STATUS","TEMP1","== '-100.000 C'")
127
+ expect(stdout.string).to match "CHECK: INST HEALTH_STATUS TEMP1 == '-100.000 C' success"
128
+ stdout.rewind
129
+
130
+ check_raw("INST HEALTH_STATUS TEMP1")
131
+ expect(stdout.string).to match "CHECK: INST HEALTH_STATUS TEMP1 == 0"
132
+ end
133
+
134
+ check("INST HEALTH_STATUS TEMP1 < 0")
135
+ expect { check("INST HEALTH_STATUS TEMP1 > 0") }.to raise_error(Cosmos::CheckError)
136
+ end
137
+ end
138
+
139
+ describe "check_tolerance, check_tolerance_raw" do
140
+ it "checks the number of parameters" do
141
+ expect { check_tolerance("INST HEALTH_STATUS TEMP1", -100.0) }.to raise_error(/Invalid number of arguments/)
142
+ expect { check_tolerance("INST", "HEALTH_STATUS", "TEMP1", -100.0, 1, 0) }.to raise_error(/Invalid number of arguments/)
143
+ end
144
+
145
+ it "checks a telemetry item vs tolerance" do
146
+ capture_io do |stdout|
147
+ check_tolerance("INST HEALTH_STATUS TEMP1", -100.0, 1)
148
+ expect(stdout.string).to match "CHECK: INST HEALTH_STATUS TEMP1 was within range"
149
+ stdout.rewind
150
+
151
+ check_tolerance("INST", "HEALTH_STATUS", "TEMP1", -100.0, 1)
152
+ expect(stdout.string).to match "CHECK: INST HEALTH_STATUS TEMP1 was within range"
153
+ stdout.rewind
154
+
155
+ expect { check_tolerance("INST HEALTH_STATUS TEMP1", -200.0, 1) }.to raise_error(CheckError, /CHECK: INST HEALTH_STATUS TEMP1 failed to be within range/)
156
+ stdout.rewind
157
+
158
+ check_tolerance_raw("INST HEALTH_STATUS TEMP1", 0, 1)
159
+ expect(stdout.string).to match "CHECK: INST HEALTH_STATUS TEMP1 was within range"
160
+ stdout.rewind
161
+
162
+ expect { check_tolerance_raw("INST HEALTH_STATUS TEMP1", 100, 1) }.to raise_error(CheckError, /CHECK: INST HEALTH_STATUS TEMP1 failed to be within range/)
163
+ stdout.rewind
164
+ end
165
+ end
166
+ end
167
+
168
+ describe "check_expression" do
169
+ it "checks an arbitrary expression" do
170
+ capture_io do |stdout|
171
+ check_expression("true == true")
172
+ expect(stdout.string).to match "CHECK: true == true is TRUE"
173
+ end
174
+
175
+ expect { check_expression("true == false") }.to raise_error(CheckError, "CHECK: true == false is FALSE")
176
+ end
177
+ end
178
+
179
+ describe "wait, wait_raw" do
180
+ it "checks the number of parameters" do
181
+ expect { wait("INST", "HEALTH_STATUS", "TEMP1", -100.0) }.to raise_error(/Invalid number of arguments/)
182
+ expect { wait("INST", "HEALTH_STATUS", "TEMP1", -100.0, 1, 5, nil) }.to raise_error(/Invalid number of arguments/)
183
+ end
184
+
185
+ it "waits for an infinite time" do
186
+ expect(self).to receive(:gets) { "\n" }
187
+ capture_io do |stdout|
188
+ wait()
189
+ expect(stdout.string).to match "WAIT: Indefinite for actual time"
190
+ end
191
+ end
192
+
193
+ it "waits for a specified number of seconds" do
194
+ capture_io do |stdout|
195
+ wait(0.1)
196
+ expect(stdout.string).to match "WAIT: 0.1 seconds with actual time"
197
+ end
198
+ end
199
+
200
+ it "handles a bad wait parameter" do
201
+ expect { wait("1") }.to raise_error(/Non-numeric wait time/)
202
+ end
203
+
204
+ it "waits for telemetry check to be true" do
205
+ capture_io do |stdout|
206
+ # Success
207
+ wait("INST HEALTH_STATUS TEMP1 == -100.0", 5)
208
+ expect(stdout.string).to match "WAIT: INST HEALTH_STATUS TEMP1 == -100.0"
209
+ stdout.rewind
210
+ wait("INST HEALTH_STATUS TEMP1 == -100.0", 5, 0.1) # polling rate
211
+ expect(stdout.string).to match "WAIT: INST HEALTH_STATUS TEMP1 == -100.0"
212
+ stdout.rewind
213
+ wait("INST","HEALTH_STATUS","TEMP1","== -100.0", 5)
214
+ expect(stdout.string).to match "WAIT: INST HEALTH_STATUS TEMP1 == -100.0"
215
+ stdout.rewind
216
+ wait("INST","HEALTH_STATUS","TEMP1","== -100.0", 5, 0.1)
217
+ expect(stdout.string).to match "WAIT: INST HEALTH_STATUS TEMP1 == -100.0"
218
+ stdout.rewind
219
+ wait_raw("INST HEALTH_STATUS TEMP1 == 0", 5)
220
+ expect(stdout.string).to match "WAIT: INST HEALTH_STATUS TEMP1 == 0"
221
+ stdout.rewind
222
+ wait_tolerance("INST HEALTH_STATUS TEMP1", -100.0, 1, 5)
223
+
224
+ # Failure
225
+ wait("INST HEALTH_STATUS TEMP1 == -200.0", 0.1)
226
+ expect(stdout.string).to match "WAIT: INST HEALTH_STATUS TEMP1 == -200.0 failed"
227
+ stdout.rewind
228
+ wait_raw("INST HEALTH_STATUS TEMP1 == 100", 0.1)
229
+ expect(stdout.string).to match "WAIT: INST HEALTH_STATUS TEMP1 == 100 failed"
230
+ stdout.rewind
231
+ end
232
+ end
233
+ end
234
+
235
+ describe "wait_tolerance, wait_tolerance_raw" do
236
+ it "checks the number of parameters" do
237
+ expect { wait_tolerance("INST", "HEALTH_STATUS", "TEMP1", -100.0, 1, 5, 0.1, nil) }.to raise_error(/Invalid number of arguments/)
238
+ end
239
+
240
+ it "waits for telemetry check to be true" do
241
+ capture_io do |stdout|
242
+ # Success
243
+ wait_tolerance("INST HEALTH_STATUS TEMP1", -100.0, 1, 5)
244
+ expect(stdout.string).to match "WAIT: INST HEALTH_STATUS TEMP1 was within"
245
+ stdout.rewind
246
+ wait_tolerance("INST HEALTH_STATUS TEMP1", -100.0, 1, 5, 0.1)
247
+ expect(stdout.string).to match "WAIT: INST HEALTH_STATUS TEMP1 was within"
248
+ stdout.rewind
249
+ wait_tolerance("INST","HEALTH_STATUS","TEMP1", -100.0, 1, 5)
250
+ expect(stdout.string).to match "WAIT: INST HEALTH_STATUS TEMP1 was within"
251
+ stdout.rewind
252
+ wait_tolerance("INST","HEALTH_STATUS","TEMP1", -100.0, 1, 5, 0.1)
253
+ expect(stdout.string).to match "WAIT: INST HEALTH_STATUS TEMP1 was within"
254
+ stdout.rewind
255
+ wait_tolerance_raw("INST HEALTH_STATUS TEMP1", 0, 1, 5)
256
+ expect(stdout.string).to match "WAIT: INST HEALTH_STATUS TEMP1 was within"
257
+ stdout.rewind
258
+
259
+ # Failure
260
+ wait_tolerance("INST HEALTH_STATUS TEMP1", -200.0, 1, 0.1)
261
+ expect(stdout.string).to match "WAIT: INST HEALTH_STATUS TEMP1 failed to be within"
262
+ stdout.rewind
263
+ wait_tolerance_raw("INST HEALTH_STATUS TEMP1", 100, 1, 0.1)
264
+ expect(stdout.string).to match "WAIT: INST HEALTH_STATUS TEMP1 failed to be within"
265
+ stdout.rewind
266
+ end
267
+ end
268
+ end
269
+
270
+ describe "wait_expression" do
271
+ it "waits for an expression to be true" do
272
+ capture_io do |stdout|
273
+ # Success
274
+ wait_expression("true == true", 5)
275
+ expect(stdout.string).to match "WAIT: true == true is TRUE"
276
+ stdout.rewind
277
+
278
+ # Failure
279
+ wait_expression("true == false", 0.1)
280
+ expect(stdout.string).to match "WAIT: true == false is FALSE"
281
+ stdout.rewind
282
+ end
283
+ end
284
+ end
285
+
286
+ describe "wait_check, wait_check_raw" do
287
+ it "checks the number of parameters" do
288
+ expect { wait_check("INST HEALTH_STATUS TEMP1 == -100.0") }.to raise_error(/Invalid number of arguments/)
289
+ expect { wait_check("INST", "HEALTH_STATUS", "TEMP1", -100.0) }.to raise_error(/Invalid number of arguments/)
290
+ expect { wait_check("INST", "HEALTH_STATUS", "TEMP1", -100.0, 5, 0.1, nil) }.to raise_error(/Invalid number of arguments/)
291
+ end
292
+
293
+ it "waits for telemetry check to be true" do
294
+ capture_io do |stdout|
295
+ # Success
296
+ wait_check("INST HEALTH_STATUS TEMP1 == -100.0", 5)
297
+ expect(stdout.string).to match "CHECK: INST HEALTH_STATUS TEMP1 == -100.0"
298
+ stdout.rewind
299
+ wait_check("INST HEALTH_STATUS TEMP1 == -100.0", 5, 0.1)
300
+ expect(stdout.string).to match "CHECK: INST HEALTH_STATUS TEMP1 == -100.0"
301
+ stdout.rewind
302
+ wait_check("INST","HEALTH_STATUS","TEMP1", "== -100.0", 5)
303
+ expect(stdout.string).to match "CHECK: INST HEALTH_STATUS TEMP1 == -100.0"
304
+ stdout.rewind
305
+ wait_check("INST","HEALTH_STATUS","TEMP1", "== -100.0", 5, 0.1)
306
+ expect(stdout.string).to match "CHECK: INST HEALTH_STATUS TEMP1 == -100.0"
307
+ stdout.rewind
308
+ wait_check_raw("INST HEALTH_STATUS TEMP1 == 0", 5)
309
+ expect(stdout.string).to match "CHECK: INST HEALTH_STATUS TEMP1 == 0"
310
+ stdout.rewind
311
+ end
312
+
313
+ # Failure
314
+ expect { wait_check("INST HEALTH_STATUS TEMP1 == -200.0", 0.1) }.to raise_error(CheckError, /CHECK: INST HEALTH_STATUS TEMP1 == -200.0 failed/)
315
+ expect { wait_check_raw("INST HEALTH_STATUS TEMP1 == 100", 0.1) }.to raise_error(CheckError, /CHECK: INST HEALTH_STATUS TEMP1 == 100 failed/)
316
+ end
317
+ end
318
+
319
+ describe "wait_check_tolerance, wait_check_tolerance_raw" do
320
+ it "checks the number of parameters" do
321
+ expect { wait_check_tolerance("INST", "HEALTH_STATUS", "TEMP1", -100.0, 1, 5, 0.1, nil) }.to raise_error(/Invalid number of arguments/)
322
+ end
323
+
324
+ it "waits for telemetry check to be true" do
325
+ capture_io do |stdout|
326
+ # Success
327
+ wait_check_tolerance("INST HEALTH_STATUS TEMP1", -100.0, 1, 5)
328
+ expect(stdout.string).to match "CHECK: INST HEALTH_STATUS TEMP1 was within"
329
+ stdout.rewind
330
+ wait_check_tolerance("INST","HEALTH_STATUS","TEMP1", -100.0, 1, 5)
331
+ expect(stdout.string).to match "CHECK: INST HEALTH_STATUS TEMP1 was within"
332
+ stdout.rewind
333
+ wait_check_tolerance("INST","HEALTH_STATUS","TEMP1", -100.0, 1, 5, 0.1)
334
+ expect(stdout.string).to match "CHECK: INST HEALTH_STATUS TEMP1 was within"
335
+ stdout.rewind
336
+ wait_check_tolerance_raw("INST HEALTH_STATUS TEMP1", 0, 1, 5)
337
+ expect(stdout.string).to match "CHECK: INST HEALTH_STATUS TEMP1 was within"
338
+ stdout.rewind
339
+ end
340
+
341
+ # Failure
342
+ expect { wait_check_tolerance("INST HEALTH_STATUS TEMP1", -200.0, 1, 0.1) }.to raise_error(CheckError, /CHECK: INST HEALTH_STATUS TEMP1 failed to be within/)
343
+
344
+ expect { wait_check_tolerance_raw("INST HEALTH_STATUS TEMP1", 100, 1, 0.1) }.to raise_error(CheckError, /CHECK: INST HEALTH_STATUS TEMP1 failed to be within/)
345
+
346
+ end
347
+ end
348
+
349
+ describe "wait_check_expression" do
350
+ it "waits for an expression to be true" do
351
+ capture_io do |stdout|
352
+ # Success
353
+ wait_check_expression("true == true", 5)
354
+ expect(stdout.string).to match "CHECK: true == true is TRUE"
355
+ stdout.rewind
356
+ end
357
+
358
+ # Failure
359
+ expect { wait_check_expression("true == false", 0.1) }.to raise_error(CheckError, /CHECK: true == false is FALSE/)
360
+ end
361
+ end
362
+
363
+ describe "wait_packet, wait_check_packet" do
364
+ it "waits for a certain number of packets" do
365
+ capture_io do |stdout|
366
+ wait_packet("INST","HEALTH_STATUS",1,0.1)
367
+ end
368
+
369
+ expect { wait_check_packet("INST","HEALTH_STATUS",1,0.1) }.to raise_error(CheckError, /INST HEALTH_STATUS expected to be received 1 times but only received 0 times/)
370
+ end
371
+ end
372
+
373
+ describe "cosmos_script_sleep" do
374
+ it "pauses the running script inside ScriptRunnerFrame" do
375
+ class ScriptRunnerFrame; def self.instance; true; end; end
376
+ allow(ScriptRunnerFrame).to receive_message_chain(:instance, :pause?).and_return(true)
377
+ expect(ScriptRunnerFrame).to receive_message_chain(:instance, :perform_pause)
378
+ cosmos_script_sleep(0.1)
379
+ end
380
+ end
381
+
382
+ describe "start" do
383
+ it "starts a script locally" do
384
+ class ScriptRunnerFrame; def self.instance; false; end; end
385
+ start("cosmos.rb")
386
+ end
387
+
388
+ it "starts a script without the .rb extension" do
389
+ class ScriptRunnerFrame; def self.instance; false; end; end
390
+ start("cosmos")
391
+ end
392
+
393
+ it "raises an error if the script can't be found" do
394
+ class ScriptRunnerFrame; def self.instance; false; end; end
395
+ expect { start("unknown_script.rb") }.to raise_error(RuntimeError)
396
+ end
397
+
398
+ it "starts a script within ScriptRunnerFrame" do
399
+ class ScriptRunnerFrame
400
+ @@instrumented_cache = {}
401
+ def self.instance; true; end
402
+ def self.instrumented_cache; @@instrumented_cache; end
403
+ def self.instrumented_cache=(value); @@instrumented_cache = value; end
404
+ def self.instrument_script(file_text, path, bool); "#"; end
405
+ end
406
+ start("cosmos.rb")
407
+ # This one should use the cached version
408
+ start("cosmos.rb")
409
+ end
410
+ end
411
+
412
+ describe "load_utility" do
413
+ it "requires a script" do
414
+ class ScriptRunnerFrame; def self.instance; false; end; end;
415
+ expect { load_utility("example.rb") }.to raise_error(RuntimeError, /Procedure not found/)
416
+ end
417
+
418
+ it "requires a script within ScriptRunnerFrame" do
419
+ class ScriptRunnerFrame
420
+ @@instrumented_cache = {}
421
+ def self.instance; true; end
422
+ def self.instrumented_cache; @@instrumented_cache; end
423
+ def self.instrumented_cache=(value); @@instrumented_cache = value; end
424
+ def self.instrument_script(file_text, path, bool); "#"; end
425
+ end
426
+ allow(ScriptRunnerFrame).to receive_message_chain(:instance, :use_instrumentation)
427
+ allow(ScriptRunnerFrame).to receive_message_chain(:instance, :use_instrumentation=)
428
+ load_utility("cosmos.rb")
429
+ # This one should use the cached version
430
+ load_utility("cosmos.rb")
431
+ end
432
+ end
433
+
434
+ end
435
+ end
436
+
@@ -0,0 +1,130 @@
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 'spec_helper'
12
+ require 'cosmos'
13
+ require 'cosmos/script/script'
14
+ require 'tempfile'
15
+
16
+ module Cosmos
17
+
18
+ describe Script do
19
+
20
+ before(:all) do
21
+ cts = File.join(Cosmos::USERPATH,'config','tools','cmd_tlm_server','cmd_tlm_server.txt')
22
+ FileUtils.mkdir_p(File.dirname(cts))
23
+ File.open(cts,'w') do |file|
24
+ file.puts 'INTERFACE INST_INT interface.rb'
25
+ file.puts 'TARGET INST'
26
+ end
27
+ System.class_eval('@@instance = nil')
28
+
29
+ require 'cosmos/script'
30
+ end
31
+
32
+ after(:all) do
33
+ clean_config()
34
+ FileUtils.rm_rf File.join(Cosmos::USERPATH,'config','tools')
35
+ end
36
+
37
+ before(:each) do
38
+ allow_any_instance_of(Interface).to receive(:connected?).and_return(true)
39
+ allow_any_instance_of(Interface).to receive(:disconnect)
40
+ allow_any_instance_of(Interface).to receive(:write)
41
+ allow_any_instance_of(Interface).to receive(:read)
42
+
43
+ @server = CmdTlmServer.new
44
+ shutdown_cmd_tlm()
45
+ initialize_script_module()
46
+ sleep 0.1
47
+ end
48
+
49
+ after(:each) do
50
+ @server.stop
51
+ shutdown_cmd_tlm()
52
+ sleep(0.1)
53
+ end
54
+
55
+ describe "tlm, tlm_raw, tlm_formatted, tlm_with_units, tlm_variable, set_tlm, set_tlm_raw" do
56
+ it "passes through to the cmd_tlm_server" do
57
+ expect {
58
+ expect(tlm("INST HEALTH_STATUS TEMP1")).to eql -100.0
59
+ expect(tlm_raw("INST HEALTH_STATUS TEMP1")).to eql 0
60
+ expect(tlm_formatted("INST HEALTH_STATUS TEMP1")).to eql "-100.000"
61
+ expect(tlm_with_units("INST HEALTH_STATUS TEMP1")).to eql "-100.000 C"
62
+ expect(tlm_variable("INST HEALTH_STATUS TEMP1", :RAW)).to eql 0
63
+ set_tlm("INST HEALTH_STATUS TEMP1 = 1")
64
+ set_tlm_raw("INST HEALTH_STATUS TEMP1 = 0")
65
+ }.to_not raise_error
66
+ end
67
+ end
68
+
69
+ describe "get_tlm_packet" do
70
+ it "gets the packet values" do
71
+ expect(get_tlm_packet("INST", "HEALTH_STATUS", :RAW)).to include(["TEMP1", 0, :RED_LOW])
72
+ end
73
+ end
74
+
75
+ describe "get_tlm_values" do
76
+ it "gets the given values" do
77
+ vals = get_tlm_values([["INST", "HEALTH_STATUS", "TEMP1"], ["INST", "HEALTH_STATUS", "TEMP2"]])
78
+ expect(vals[0][0]).to eql -100.0
79
+ expect(vals[1][0]).to eql :RED_LOW
80
+ expect(vals[2][0]).to eql [-80.0, -70.0, 60.0, 80.0, -20.0, 20.0]
81
+ expect(vals[3]).to eql :DEFAULT
82
+ end
83
+ end
84
+
85
+ describe "get_tlm_list" do
86
+ it "gets packets for a given target" do
87
+ expect(get_tlm_list("INST")).to include(["HEALTH_STATUS", "Health and status from the instrument"])
88
+ end
89
+ end
90
+
91
+ describe "get_tlm_item_list" do
92
+ it "gets telemetry for a given packet" do
93
+ expect(get_tlm_item_list("INST", "HEALTH_STATUS")).to include(["TEMP1",nil,"Temperature #1"])
94
+ end
95
+ end
96
+
97
+ describe "get_tlm_details" do
98
+ it "gets telemetry for a given packet" do
99
+ details = get_tlm_details([["INST", "HEALTH_STATUS", "TEMP1"], ["INST", "HEALTH_STATUS", "TEMP2"]])
100
+ expect(details[0]["name"]).to eql "TEMP1"
101
+ expect(details[1]["name"]).to eql "TEMP2"
102
+ end
103
+ end
104
+
105
+ describe "get_target_list" do
106
+ it "returns the list of targets" do
107
+ expect(get_target_list).to include("INST")
108
+ end
109
+ end
110
+
111
+ describe "subscribe_packet_data, get_packet, unsubscribe_packet_data" do
112
+ it "raises an error if non_block and the queue is empty" do
113
+ id = subscribe_packet_data([["INST","HEALTH_STATUS"]])
114
+ expect { get_packet(id, true) }.to raise_error(ThreadError, "queue empty")
115
+ unsubscribe_packet_data(id)
116
+ end
117
+
118
+ it "subscribes and get limits events" do
119
+ id = subscribe_packet_data([["INST","HEALTH_STATUS"]])
120
+ CmdTlmServer.instance.post_packet(System.telemetry.packet("INST","HEALTH_STATUS"))
121
+ packet = get_packet(id, true)
122
+ expect(packet.target_name).to eql "INST"
123
+ expect(packet.packet_name).to eql "HEALTH_STATUS"
124
+ unsubscribe_packet_data(id)
125
+ end
126
+ end
127
+
128
+ end
129
+ end
130
+