cosmos 3.3.3 → 3.4.0
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.
- checksums.yaml +4 -4
- data/.gitattributes +2 -0
- data/.travis.yml +2 -1
- data/Gemfile +4 -3
- data/Manifest.txt +22 -0
- data/autohotkey/tools/handbook_creator.ahk +9 -0
- data/autohotkey/tools/packet_viewer.ahk +4 -0
- data/bin/exchndl20-x64.dll +0 -0
- data/bin/exchndl20.dll +0 -0
- data/bin/exchndl21-x64.dll +0 -0
- data/bin/exchndl21.dll +0 -0
- data/bin/exchndl22-x64.dll +0 -0
- data/bin/exchndl22.dll +0 -0
- data/bin/mgwhelp-x64.dll +0 -0
- data/bin/mgwhelp.dll +0 -0
- data/cosmos.gemspec +1 -0
- data/data/crc.txt +30 -24
- data/demo/config/data/crc.txt +3 -3
- data/demo/config/tools/handbook_creator/templates/command_packets.html.erb +3 -1
- data/demo/config/tools/handbook_creator/templates/telemetry_packets.html.erb +3 -1
- data/demo/procedures/cosmos_api_test.rb +1 -1
- data/ext/cosmos/ext/low_fragmentation_array/low_fragmentation_array.c +4 -0
- data/ext/cosmos/ext/platform/platform.c +22 -2
- data/ext/cosmos/ext/structure/structure.c +631 -104
- data/ext/cosmos/ext/telemetry/telemetry.c +3 -2
- data/lib/cosmos/gui/line_graph/line_graph_drawing.rb +71 -92
- data/lib/cosmos/gui/line_graph/overview_graph.rb +1 -1
- data/lib/cosmos/gui/qt.rb +38 -24
- data/lib/cosmos/gui/text/ruby_editor.rb +1 -1
- data/lib/cosmos/packets/binary_accessor.rb +1 -288
- data/lib/cosmos/packets/telemetry.rb +2 -1
- data/lib/cosmos/script/cmd_tlm_server.rb +110 -0
- data/lib/cosmos/script/commands.rb +166 -0
- data/lib/cosmos/script/extract.rb +2 -2
- data/lib/cosmos/script/limits.rb +108 -0
- data/lib/cosmos/script/script.rb +28 -1487
- data/lib/cosmos/script/scripting.rb +889 -0
- data/lib/cosmos/script/telemetry.rb +174 -0
- data/lib/cosmos/script/tools.rb +138 -0
- data/lib/cosmos/streams/stream_protocol.rb +9 -6
- data/lib/cosmos/system/target.rb +55 -38
- data/lib/cosmos/tools/cmd_tlm_server/api.rb +6 -3
- data/lib/cosmos/tools/cmd_tlm_server/connections.rb +0 -1
- data/lib/cosmos/tools/cmd_tlm_server/gui/interfaces_tab.rb +17 -7
- data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +15 -4
- data/lib/cosmos/tools/handbook_creator/handbook_creator.rb +15 -8
- data/lib/cosmos/tools/handbook_creator/handbook_creator_config.rb +41 -13
- data/lib/cosmos/tools/packet_viewer/packet_viewer.rb +18 -1
- data/lib/cosmos/tools/tlm_viewer/widgets/canvasline_widget.rb +1 -1
- data/lib/cosmos/tools/tlm_viewer/widgets/canvaslinevalue_widget.rb +1 -1
- data/lib/cosmos/tools/tlm_viewer/widgets/limitsbar_widget.rb +1 -1
- data/lib/cosmos/tools/tlm_viewer/widgets/rangebar_widget.rb +1 -1
- data/lib/cosmos/top_level.rb +1 -1
- data/lib/cosmos/utilities/ruby_lex_utils.rb +1 -1
- data/lib/cosmos/version.rb +5 -5
- data/spec/gui/line_graph/line_clip_spec.rb +6 -6
- data/spec/gui/qt_spec.rb +102 -0
- data/spec/interfaces/interface_spec.rb +9 -9
- data/spec/interfaces/linc_interface_spec.rb +72 -15
- data/spec/interfaces/serial_interface_spec.rb +9 -9
- data/spec/interfaces/simulated_target_interface_spec.rb +7 -7
- data/spec/interfaces/stream_interface_spec.rb +4 -4
- data/spec/interfaces/tcpip_client_interface_spec.rb +8 -8
- data/spec/interfaces/tcpip_server_interface_spec.rb +9 -9
- data/spec/interfaces/udp_interface_spec.rb +20 -20
- data/spec/io/json_drb_spec.rb +4 -4
- data/spec/io/raw_logger_pair_spec.rb +20 -20
- data/spec/io/raw_logger_spec.rb +3 -3
- data/spec/io/tcpip_server_spec.rb +9 -9
- data/spec/io/udp_sockets_spec.rb +2 -2
- data/spec/io/win32_serial_driver_spec.rb +2 -2
- data/spec/packets/binary_accessor_spec.rb +143 -6
- data/spec/packets/commands_spec.rb +5 -5
- data/spec/packets/limits_spec.rb +15 -15
- data/spec/packets/packet_config_spec.rb +19 -19
- data/spec/packets/packet_item_limits_spec.rb +3 -3
- data/spec/packets/packet_item_spec.rb +4 -4
- data/spec/packets/packet_spec.rb +33 -33
- data/spec/packets/structure_item_spec.rb +19 -19
- data/spec/packets/telemetry_spec.rb +6 -6
- data/spec/script/cmd_tlm_server_spec.rb +110 -0
- data/spec/script/commands_disconnect_spec.rb +270 -0
- data/spec/script/commands_spec.rb +288 -0
- data/spec/script/limits_spec.rb +153 -0
- data/spec/script/script_spec.rb +32 -696
- data/spec/script/scripting_spec.rb +436 -0
- data/spec/script/telemetry_spec.rb +130 -0
- data/spec/script/tools_spec.rb +117 -0
- data/spec/spec_helper.rb +10 -5
- data/spec/streams/preidentified_stream_protocol_spec.rb +4 -4
- data/spec/streams/serial_stream_spec.rb +8 -8
- data/spec/streams/stream_protocol_spec.rb +4 -4
- data/spec/streams/tcpip_client_stream_spec.rb +3 -3
- data/spec/streams/tcpip_socket_stream_spec.rb +7 -7
- data/spec/streams/template_stream_protocol_spec.rb +1 -1
- data/spec/system/system_spec.rb +6 -6
- data/spec/system/target_spec.rb +2 -0
- data/spec/tools/cmd_tlm_server/api_spec.rb +17 -17
- data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +5 -5
- data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +3 -3
- data/spec/top_level/top_level_spec.rb +8 -8
- data/spec/utilities/csv_spec.rb +3 -3
- data/spec/utilities/message_log_spec.rb +3 -3
- data/spec/utilities/ruby_lex_utils_spec.rb +7 -7
- data/test/performance/config/tools/launcher/launcher_threads.txt +8 -1
- data/test/performance/tools/CmdTlmServerMemProf +1 -1
- data/test/performance/tools/TlmGrapherMemProf +19 -0
- data/test/performance/tools/TlmGrapherMemProf.bat +59 -0
- 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
|
+
|