cosmos 3.1.2 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +3 -0
- data/Manifest.txt +17 -1
- data/autohotkey/tools/test_runner2.ahk +1 -0
- data/autohotkey/tools/tlm_grapher.ahk +13 -1
- data/data/crc.txt +39 -30
- data/demo/config/data/crc.txt +3 -3
- data/demo/config/targets/TEMPLATED/lib/templated_interface.rb +3 -1
- data/demo/config/tools/cmd_tlm_server/cmd_tlm_server.txt +7 -1
- data/demo/config/tools/cmd_tlm_server/cmd_tlm_server2.txt +6 -1
- data/lib/cosmos.rb +2 -2
- data/lib/cosmos/gui/dialogs/about_dialog.rb +18 -5
- data/lib/cosmos/gui/dialogs/tlm_details_dialog.rb +0 -7
- data/lib/cosmos/gui/line_graph/overview_graph.rb +12 -2
- data/lib/cosmos/gui/utilities/script_module_gui.rb +11 -3
- data/lib/cosmos/interfaces/interface.rb +12 -0
- data/lib/cosmos/interfaces/stream_interface.rb +1 -21
- data/lib/cosmos/interfaces/tcpip_server_interface.rb +10 -0
- data/lib/cosmos/io/json_drb_object.rb +75 -56
- data/lib/cosmos/io/tcpip_server.rb +1 -11
- data/lib/cosmos/packet_logs.rb +1 -0
- data/lib/cosmos/packet_logs/ccsds_log_reader.rb +103 -0
- data/lib/cosmos/packets/packet.rb +70 -1
- data/lib/cosmos/packets/packet_config.rb +59 -611
- data/lib/cosmos/packets/parsers/format_string_parser.rb +58 -0
- data/lib/cosmos/packets/parsers/limits_parser.rb +146 -0
- data/lib/cosmos/packets/parsers/limits_response_parser.rb +52 -0
- data/lib/cosmos/packets/parsers/macro_parser.rb +116 -0
- data/lib/cosmos/packets/parsers/packet_item_parser.rb +215 -0
- data/lib/cosmos/packets/parsers/packet_parser.rb +123 -0
- data/lib/cosmos/packets/parsers/processor_parser.rb +63 -0
- data/lib/cosmos/packets/parsers/state_parser.rb +116 -0
- data/lib/cosmos/packets/structure.rb +59 -22
- data/lib/cosmos/packets/structure_item.rb +1 -1
- data/lib/cosmos/script/script.rb +4 -5
- data/lib/cosmos/streams/serial_stream.rb +5 -0
- data/lib/cosmos/streams/stream.rb +8 -2
- data/lib/cosmos/streams/stream_protocol.rb +1 -0
- data/lib/cosmos/streams/tcpip_client_stream.rb +37 -7
- data/lib/cosmos/streams/tcpip_socket_stream.rb +9 -6
- data/lib/cosmos/system/target.rb +3 -6
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +57 -48
- data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +7 -3
- data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +1 -1
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_realtime_thread.rb +7 -1
- data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +1 -2
- data/lib/cosmos/top_level.rb +22 -11
- data/lib/cosmos/utilities/message_log.rb +14 -9
- data/lib/cosmos/version.rb +5 -5
- data/spec/interfaces/cmd_tlm_server_interface_spec.rb +16 -16
- data/spec/interfaces/linc_interface_spec.rb +3 -0
- data/spec/interfaces/tcpip_client_interface_spec.rb +1 -0
- data/spec/interfaces/tcpip_server_interface_spec.rb +9 -0
- data/spec/io/json_drb_object_spec.rb +1 -1
- data/spec/io/serial_driver_spec.rb +0 -1
- data/spec/packet_logs/packet_log_writer_spec.rb +5 -3
- data/spec/packets/packet_config_spec.rb +22 -837
- data/spec/packets/packet_item_spec.rb +10 -10
- data/spec/packets/packet_spec.rb +239 -1
- data/spec/packets/parsers/format_string_parser_spec.rb +122 -0
- data/spec/packets/parsers/limits_parser_spec.rb +282 -0
- data/spec/packets/parsers/limits_response_parser_spec.rb +149 -0
- data/spec/packets/parsers/macro_parser_spec.rb +184 -0
- data/spec/packets/parsers/packet_item_parser_spec.rb +306 -0
- data/spec/packets/parsers/packet_parser_spec.rb +99 -0
- data/spec/packets/parsers/processor_parser_spec.rb +114 -0
- data/spec/packets/parsers/state_parser_spec.rb +156 -0
- data/spec/packets/structure_item_spec.rb +14 -14
- data/spec/packets/structure_spec.rb +162 -16
- data/spec/streams/fixed_stream_protocol_spec.rb +7 -4
- data/spec/streams/length_stream_protocol_spec.rb +3 -0
- data/spec/streams/preidentified_stream_protocol_spec.rb +3 -0
- data/spec/streams/serial_stream_spec.rb +12 -0
- data/spec/streams/stream_protocol_spec.rb +14 -0
- data/spec/streams/stream_spec.rb +1 -0
- data/spec/streams/tcpip_client_stream_spec.rb +3 -0
- data/spec/streams/tcpip_socket_stream_spec.rb +15 -3
- data/spec/streams/template_stream_protocol_spec.rb +5 -0
- data/spec/streams/terminated_stream_protocol_spec.rb +4 -0
- data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +21 -1
- data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +1 -1
- data/spec/tools/cmd_tlm_server/interfaces_spec.rb +1 -1
- metadata +19 -3
@@ -0,0 +1,282 @@
|
|
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/packets/packet_config'
|
14
|
+
require 'cosmos/packets/parsers/limits_parser'
|
15
|
+
require 'tempfile'
|
16
|
+
|
17
|
+
module Cosmos
|
18
|
+
|
19
|
+
describe LimitsParser do
|
20
|
+
|
21
|
+
describe "parse" do
|
22
|
+
before(:each) do
|
23
|
+
@pc = PacketConfig.new
|
24
|
+
end
|
25
|
+
|
26
|
+
it "raises if a current item is not defined" do
|
27
|
+
tf = Tempfile.new('unittest')
|
28
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
29
|
+
tf.puts ' LIMITS mylimits 1 ENABLED 0 10 20 30 12 18'
|
30
|
+
tf.close
|
31
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "No current item for LIMITS")
|
32
|
+
tf.unlink
|
33
|
+
end
|
34
|
+
|
35
|
+
it "raises if there are not enough parameters" do
|
36
|
+
tf = Tempfile.new('unittest')
|
37
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
38
|
+
tf.puts ' ITEM myitem 0 8 UINT "Test Item"'
|
39
|
+
tf.puts ' LIMITS DEFAULT 1 ENABLED 0 10 20 30 12'
|
40
|
+
tf.close
|
41
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Must give both a green low and green high/)
|
42
|
+
tf.unlink
|
43
|
+
|
44
|
+
tf = Tempfile.new('unittest')
|
45
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
46
|
+
tf.puts ' ITEM myitem 0 8 UINT "Test Item"'
|
47
|
+
tf.puts ' LIMITS DEFAULT 1 ENABLED 0 10 20'
|
48
|
+
tf.close
|
49
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Not enough parameters for LIMITS/)
|
50
|
+
tf.unlink
|
51
|
+
end
|
52
|
+
|
53
|
+
it "raises if there are too many parameters" do
|
54
|
+
tf = Tempfile.new('unittest')
|
55
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
56
|
+
tf.puts ' ITEM myitem 0 8 UINT "Test Item"'
|
57
|
+
tf.puts ' LIMITS DEFAULT 1 ENABLED 0 10 20 30 12 18 20'
|
58
|
+
tf.close
|
59
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Too many parameters for LIMITS/)
|
60
|
+
tf.unlink
|
61
|
+
end
|
62
|
+
|
63
|
+
it "raises if applied to a command PARAMETER" do
|
64
|
+
tf = Tempfile.new('unittest')
|
65
|
+
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
66
|
+
tf.puts ' APPEND_PARAMETER item1 16 UINT 0 0 0 "Item"'
|
67
|
+
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 7 3 5'
|
68
|
+
tf.close
|
69
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /LIMITS only applies to telemetry items/)
|
70
|
+
tf.unlink
|
71
|
+
end
|
72
|
+
|
73
|
+
it "raises if a DEFAULT limits set isn't defined" do
|
74
|
+
tf = Tempfile.new('unittest')
|
75
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
76
|
+
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
77
|
+
tf.puts ' LIMITS TVAC 3 ENABLED 1 2 6 7 3 5'
|
78
|
+
tf.close
|
79
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /DEFAULT limits set must be defined/)
|
80
|
+
tf.unlink
|
81
|
+
end
|
82
|
+
|
83
|
+
it "sets a warning if a new limits set persistence isn't consistent with DEFAULT" do
|
84
|
+
tf = Tempfile.new('unittest')
|
85
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
86
|
+
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
87
|
+
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 7 3 5'
|
88
|
+
tf.puts ' LIMITS TVAC 1 DISABLED 1 2 6 7 3 5'
|
89
|
+
tf.close
|
90
|
+
@pc.process_file(tf.path, "TGT1")
|
91
|
+
expect(@pc.warnings[-1]).to match(/persistence setting conflict with DEFAULT/)
|
92
|
+
tf.unlink
|
93
|
+
end
|
94
|
+
|
95
|
+
it "sets a warning if a new limits set enable isn't consistent with DEFAULT" do
|
96
|
+
tf = Tempfile.new('unittest')
|
97
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
98
|
+
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
99
|
+
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 7 3 5'
|
100
|
+
tf.puts ' LIMITS TVAC 3 DISABLED 1 2 6 7 3 5'
|
101
|
+
tf.close
|
102
|
+
@pc.process_file(tf.path, "TGT1")
|
103
|
+
expect(@pc.warnings[-1]).to match(/enable setting conflict with DEFAULT/)
|
104
|
+
tf.unlink
|
105
|
+
end
|
106
|
+
|
107
|
+
it "records 2 warnings if a new limits set persistence and enable isn't consistent with DEFAULT" do
|
108
|
+
tf = Tempfile.new('unittest')
|
109
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
110
|
+
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
111
|
+
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 7 3 5'
|
112
|
+
tf.puts ' LIMITS TVAC 1 DISABLED 1 2 6 7 3 5'
|
113
|
+
tf.close
|
114
|
+
@pc.process_file(tf.path, "TGT1")
|
115
|
+
expect(@pc.warnings.length).to eql 2
|
116
|
+
tf.unlink
|
117
|
+
end
|
118
|
+
|
119
|
+
it "raises if the second parameter isn't a number" do
|
120
|
+
tf = Tempfile.new('unittest')
|
121
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
122
|
+
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
123
|
+
tf.puts ' LIMITS DEFAULT TRUE ENABLED 1 2 6 7 3 5'
|
124
|
+
tf.close
|
125
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Persistence must be an integer/)
|
126
|
+
tf.unlink
|
127
|
+
end
|
128
|
+
|
129
|
+
it "raises if the third parameter isn't ENABLED or DISABLED" do
|
130
|
+
tf = Tempfile.new('unittest')
|
131
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
132
|
+
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
133
|
+
tf.puts ' LIMITS DEFAULT 3 TRUE 1 2 6 7 3 5'
|
134
|
+
tf.close
|
135
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Initial LIMITS state must be ENABLED or DISABLED/)
|
136
|
+
tf.unlink
|
137
|
+
end
|
138
|
+
|
139
|
+
it "raises if the fourth through ninth parameter aren't numbers'" do
|
140
|
+
msgs = ['','','','','red low','yellow low','yellow high','red high','green low','green high']
|
141
|
+
(4..9).each do |index|
|
142
|
+
tf = Tempfile.new('unittest')
|
143
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
144
|
+
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
145
|
+
limits = %w(LIMITS DEFAULT 3 ENABLED 1 2 6 7 3 5)
|
146
|
+
limits[index] = 'X'
|
147
|
+
tf.puts limits.join(' ')
|
148
|
+
tf.close
|
149
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Invalid #{msgs[index]} limit value/)
|
150
|
+
tf.unlink
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
it "raises if the 4 limits are out of order" do
|
155
|
+
tf = Tempfile.new('unittest')
|
156
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
157
|
+
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
158
|
+
tf.puts ' LIMITS DEFAULT 3 ENABLED 2 1 3 4'
|
159
|
+
tf.close
|
160
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure yellow limits are within red limits.")
|
161
|
+
tf.unlink
|
162
|
+
|
163
|
+
tf = Tempfile.new('unittest')
|
164
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
165
|
+
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
166
|
+
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 5 3 7'
|
167
|
+
tf.close
|
168
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure yellow limits are within red limits.")
|
169
|
+
tf.unlink
|
170
|
+
|
171
|
+
tf = Tempfile.new('unittest')
|
172
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
173
|
+
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
174
|
+
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 5 4'
|
175
|
+
tf.close
|
176
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure yellow limits are within red limits.")
|
177
|
+
tf.unlink
|
178
|
+
|
179
|
+
tf = Tempfile.new('unittest')
|
180
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
181
|
+
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
182
|
+
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 3 0'
|
183
|
+
tf.close
|
184
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure yellow limits are within red limits.")
|
185
|
+
tf.unlink
|
186
|
+
end
|
187
|
+
|
188
|
+
it "raises if the 6 limits are out of order" do
|
189
|
+
tf = Tempfile.new('unittest')
|
190
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
191
|
+
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
192
|
+
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 7 0 5'
|
193
|
+
tf.close
|
194
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure green limits are within yellow limits.")
|
195
|
+
tf.unlink
|
196
|
+
|
197
|
+
tf = Tempfile.new('unittest')
|
198
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
199
|
+
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
200
|
+
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 3 6 7 2 5'
|
201
|
+
tf.close
|
202
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure green limits are within yellow limits.")
|
203
|
+
tf.unlink
|
204
|
+
|
205
|
+
tf = Tempfile.new('unittest')
|
206
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
207
|
+
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
208
|
+
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 8 3 7'
|
209
|
+
tf.close
|
210
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure green limits are within yellow limits.")
|
211
|
+
tf.unlink
|
212
|
+
|
213
|
+
tf = Tempfile.new('unittest')
|
214
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
215
|
+
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
216
|
+
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 8 3 9'
|
217
|
+
tf.close
|
218
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure green limits are within yellow limits.")
|
219
|
+
tf.unlink
|
220
|
+
|
221
|
+
tf = Tempfile.new('unittest')
|
222
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
223
|
+
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
224
|
+
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 8 4 3'
|
225
|
+
tf.close
|
226
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure green limits are within yellow limits.")
|
227
|
+
tf.unlink
|
228
|
+
end
|
229
|
+
|
230
|
+
it "should take 4 limits values" do
|
231
|
+
tf = Tempfile.new('unittest')
|
232
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
233
|
+
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
234
|
+
tf.puts ' LIMITS DEFAULT 1 ENABLED 1 2 6 7'
|
235
|
+
tf.close
|
236
|
+
@pc.process_file(tf.path, "TGT1")
|
237
|
+
item = @pc.telemetry["TGT1"]["PKT1"].items["ITEM1"]
|
238
|
+
item.limits.values[:DEFAULT].should_not be_nil
|
239
|
+
@pc.telemetry["TGT1"]["PKT1"].buffer = "\x04"
|
240
|
+
@pc.telemetry["TGT1"]["PKT1"].enable_limits("ITEM1")
|
241
|
+
@pc.telemetry["TGT1"]["PKT1"].check_limits
|
242
|
+
item.limits.state.should eql :GREEN
|
243
|
+
@pc.telemetry["TGT1"]["PKT1"].limits_items.should eql [item]
|
244
|
+
tf.unlink
|
245
|
+
end
|
246
|
+
|
247
|
+
it "should take 6 limits values" do
|
248
|
+
tf = Tempfile.new('unittest')
|
249
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
250
|
+
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
251
|
+
tf.puts ' LIMITS DEFAULT 1 ENABLED 1 2 6 7 3 5'
|
252
|
+
tf.close
|
253
|
+
@pc.process_file(tf.path, "TGT1")
|
254
|
+
item = @pc.telemetry["TGT1"]["PKT1"].items["ITEM1"]
|
255
|
+
item.limits.values[:DEFAULT].should_not be_nil
|
256
|
+
@pc.telemetry["TGT1"]["PKT1"].buffer = "\x04"
|
257
|
+
@pc.telemetry["TGT1"]["PKT1"].enable_limits("ITEM1")
|
258
|
+
@pc.telemetry["TGT1"]["PKT1"].check_limits
|
259
|
+
item.limits.state.should eql :BLUE
|
260
|
+
@pc.telemetry["TGT1"]["PKT1"].limits_items.should eql [item]
|
261
|
+
tf.unlink
|
262
|
+
end
|
263
|
+
|
264
|
+
it "create multiple limits sets" do
|
265
|
+
tf = Tempfile.new('unittest')
|
266
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
267
|
+
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
268
|
+
tf.puts ' LIMITS DEFAULT 1 ENABLED 1 2 6 7'
|
269
|
+
tf.puts ' LIMITS TVAC 1 ENABLED 1 2 6 7'
|
270
|
+
tf.close
|
271
|
+
@pc.process_file(tf.path, "TGT1")
|
272
|
+
item = @pc.telemetry["TGT1"]["PKT1"].items["ITEM1"]
|
273
|
+
expect(item.limits.values.length).to eql 2
|
274
|
+
expect(item.limits.values[:DEFAULT]).to_not be_nil
|
275
|
+
expect(item.limits.values[:TVAC]).to_not be_nil
|
276
|
+
tf.unlink
|
277
|
+
end
|
278
|
+
|
279
|
+
end
|
280
|
+
|
281
|
+
end
|
282
|
+
end
|
@@ -0,0 +1,149 @@
|
|
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/packets/packet_config'
|
14
|
+
require 'cosmos/packets/parsers/limits_response_parser'
|
15
|
+
require 'tempfile'
|
16
|
+
|
17
|
+
module Cosmos
|
18
|
+
|
19
|
+
describe PacketConfig do
|
20
|
+
|
21
|
+
describe "parse" do
|
22
|
+
before(:each) do
|
23
|
+
@pc = PacketConfig.new
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should complain if a current item is not defined" do
|
27
|
+
tf = Tempfile.new('unittest')
|
28
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
29
|
+
tf.puts ' LIMITS_RESPONSE'
|
30
|
+
tf.close
|
31
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "No current item for LIMITS_RESPONSE")
|
32
|
+
tf.unlink
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should complain if there are not enough parameters" do
|
36
|
+
tf = Tempfile.new('unittest')
|
37
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
38
|
+
tf.puts 'ITEM myitem 0 8 UINT "Test Item"'
|
39
|
+
tf.puts ' LIMITS_RESPONSE'
|
40
|
+
tf.close
|
41
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Not enough parameters for LIMITS_RESPONSE/)
|
42
|
+
tf.unlink
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should complain if applied to a command PARAMETER" do
|
46
|
+
tf = Tempfile.new('unittest')
|
47
|
+
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
48
|
+
tf.puts ' APPEND_PARAMETER item1 16 UINT 0 0 0 "Item"'
|
49
|
+
tf.puts ' LIMITS_RESPONSE test.rb'
|
50
|
+
tf.close
|
51
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "LIMITS_RESPONSE only applies to telemetry items")
|
52
|
+
tf.unlink
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should complain about missing response file" do
|
56
|
+
filename = File.join(File.dirname(__FILE__), "../../test_only.rb")
|
57
|
+
File.delete(filename) if File.exist?(filename)
|
58
|
+
@pc = PacketConfig.new
|
59
|
+
|
60
|
+
tf = Tempfile.new('unittest')
|
61
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
62
|
+
tf.puts ' ITEM item1 0 16 INT "Integer Item"'
|
63
|
+
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 7 3 5'
|
64
|
+
tf.puts ' LIMITS_RESPONSE test_only.rb'
|
65
|
+
tf.close
|
66
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /TestOnly class not found/)
|
67
|
+
tf.unlink
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should complain about a non Cosmos::LimitsResponse class" do
|
71
|
+
filename = File.join(File.dirname(__FILE__), "../../limits_response1.rb")
|
72
|
+
File.open(filename, 'w') do |file|
|
73
|
+
file.puts "class LimitsResponse1"
|
74
|
+
file.puts " def call(target_name, packet_name, item, old_limits_state, new_limits_state)"
|
75
|
+
file.puts " end"
|
76
|
+
file.puts "end"
|
77
|
+
end
|
78
|
+
load 'limits_response1.rb'
|
79
|
+
File.delete(filename) if File.exist?(filename)
|
80
|
+
|
81
|
+
tf = Tempfile.new('unittest')
|
82
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
83
|
+
tf.puts ' ITEM item1 0 16 INT "Integer Item"'
|
84
|
+
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 7 3 5'
|
85
|
+
tf.puts ' LIMITS_RESPONSE limits_response1.rb'
|
86
|
+
tf.close
|
87
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /response must be a Cosmos::LimitsResponse but is a LimitsResponse1/)
|
88
|
+
tf.unlink
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should set the response" do
|
92
|
+
filename = File.join(File.dirname(__FILE__), "../../limits_response2.rb")
|
93
|
+
File.open(filename, 'w') do |file|
|
94
|
+
file.puts "require 'cosmos/packets/limits_response'"
|
95
|
+
file.puts "class LimitsResponse2 < Cosmos::LimitsResponse"
|
96
|
+
file.puts " def call(target_name, packet_name, item, old_limits_state, new_limits_state)"
|
97
|
+
file.puts " puts \"\#{target_name} \#{packet_name} \#{item.name} \#{old_limits_state} \#{new_limits_state}\""
|
98
|
+
file.puts " end"
|
99
|
+
file.puts "end"
|
100
|
+
end
|
101
|
+
load 'limits_response2.rb'
|
102
|
+
|
103
|
+
tf = Tempfile.new('unittest')
|
104
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
105
|
+
tf.puts ' ITEM item1 0 16 INT "Integer Item"'
|
106
|
+
tf.puts ' LIMITS DEFAULT 1 ENABLED 1 2 6 7 3 5'
|
107
|
+
tf.puts ' LIMITS_RESPONSE limits_response2.rb'
|
108
|
+
tf.close
|
109
|
+
@pc.process_file(tf.path, "TGT1")
|
110
|
+
pkt = @pc.telemetry["TGT1"]["PKT1"]
|
111
|
+
pkt.get_item("ITEM1").limits.response.class.should eql LimitsResponse2
|
112
|
+
|
113
|
+
File.delete(filename) if File.exist?(filename)
|
114
|
+
tf.unlink
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should call the response with parameters" do
|
118
|
+
filename = File.join(File.dirname(__FILE__), "../../limits_response2.rb")
|
119
|
+
File.open(filename, 'w') do |file|
|
120
|
+
file.puts "require 'cosmos/packets/limits_response'"
|
121
|
+
file.puts "class LimitsResponse2 < Cosmos::LimitsResponse"
|
122
|
+
file.puts " def initialize(val)"
|
123
|
+
file.puts " puts \"initialize: \#{val}\""
|
124
|
+
file.puts " end"
|
125
|
+
file.puts " def call(target_name, packet_name, item, old_limits_state, new_limits_state)"
|
126
|
+
file.puts " puts \"\#{target_name} \#{packet_name} \#{item.name} \#{old_limits_state} \#{new_limits_state}\""
|
127
|
+
file.puts " end"
|
128
|
+
file.puts "end"
|
129
|
+
end
|
130
|
+
load 'limits_response2.rb'
|
131
|
+
|
132
|
+
tf = Tempfile.new('unittest')
|
133
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
134
|
+
tf.puts ' ITEM item1 0 16 INT "Integer Item"'
|
135
|
+
tf.puts ' LIMITS DEFAULT 1 ENABLED 1 2 6 7 3 5'
|
136
|
+
tf.puts ' LIMITS_RESPONSE limits_response2.rb 2'
|
137
|
+
tf.close
|
138
|
+
capture_io do |stdout|
|
139
|
+
@pc.process_file(tf.path, "TGT1")
|
140
|
+
stdout.string.should eql "initialize: 2\n"
|
141
|
+
end
|
142
|
+
|
143
|
+
File.delete(filename) if File.exist?(filename)
|
144
|
+
tf.unlink
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,184 @@
|
|
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/packets/packet_config'
|
14
|
+
require 'cosmos/packets/parsers/macro_parser'
|
15
|
+
require 'tempfile'
|
16
|
+
|
17
|
+
module Cosmos
|
18
|
+
|
19
|
+
describe MacroParser do
|
20
|
+
before(:each) do
|
21
|
+
@pc = PacketConfig.new
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "start" do
|
25
|
+
it "complains if a current packet is not defined" do
|
26
|
+
# Check for missing TELEMETRY line
|
27
|
+
tf = Tempfile.new('unittest')
|
28
|
+
tf.puts ' MACRO_APPEND_START'
|
29
|
+
tf.close
|
30
|
+
expect { @pc.process_file(tf.path, "SYSTEM") }.to raise_error(ConfigParser::Error, "No current packet for MACRO_APPEND_START")
|
31
|
+
end
|
32
|
+
|
33
|
+
it "complains if there are not enough parameters" do
|
34
|
+
tf = Tempfile.new('unittest')
|
35
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
36
|
+
tf.puts ' MACRO_APPEND_START'
|
37
|
+
tf.close
|
38
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Not enough parameters for MACRO_APPEND_START/)
|
39
|
+
tf.unlink
|
40
|
+
end
|
41
|
+
|
42
|
+
it "complains if there are too many parameters" do
|
43
|
+
tf = Tempfile.new('unittest')
|
44
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
45
|
+
tf.puts 'MACRO_APPEND_START 0 1 "%s_%d" extra'
|
46
|
+
tf.close
|
47
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Too many parameters for MACRO_APPEND_START/)
|
48
|
+
tf.unlink
|
49
|
+
end
|
50
|
+
|
51
|
+
it "complains if a previous START hasn't been closed" do
|
52
|
+
# Check for missing TELEMETRY line
|
53
|
+
tf = Tempfile.new('unittest')
|
54
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
55
|
+
tf.puts ' MACRO_APPEND_START 1 5'
|
56
|
+
tf.puts ' MACRO_APPEND_START 1 5'
|
57
|
+
tf.close
|
58
|
+
expect { @pc.process_file(tf.path, "SYSTEM") }.to raise_error(ConfigParser::Error, /First close the previous/)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "swaps reverse ranges to be in order" do
|
62
|
+
tf = Tempfile.new('unittest')
|
63
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
64
|
+
tf.puts 'MACRO_APPEND_START 4 1' # <-- Note the reverse order
|
65
|
+
tf.puts 'APPEND_ITEM BIT 16 UINT "Setting #x"'
|
66
|
+
tf.puts ' STATE BAD 0 RED'
|
67
|
+
tf.puts ' STATE GOOD 1 GREEN'
|
68
|
+
tf.puts 'MACRO_APPEND_END'
|
69
|
+
tf.close
|
70
|
+
@pc.process_file(tf.path, "TGT1")
|
71
|
+
pkt = @pc.telemetry["TGT1"]["PKT1"]
|
72
|
+
expect(pkt.items.length).to eql 7 # 4 plus the RECEIVED_XXX items
|
73
|
+
expect(pkt.items.keys).to include('BIT1','BIT2','BIT3','BIT4')
|
74
|
+
expect(pkt.sorted_items[3].name).to eql 'BIT1'
|
75
|
+
expect(pkt.sorted_items[4].name).to eql 'BIT2'
|
76
|
+
expect(pkt.sorted_items[5].name).to eql 'BIT3'
|
77
|
+
expect(pkt.sorted_items[6].name).to eql 'BIT4'
|
78
|
+
limits_items = []
|
79
|
+
pkt.items.each do |name, item|
|
80
|
+
limits_items << item if name.include?('BIT')
|
81
|
+
end
|
82
|
+
expect(pkt.limits_items).to eql limits_items
|
83
|
+
tf.unlink
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "end" do
|
88
|
+
it "complains if there are too many parameters" do
|
89
|
+
tf = Tempfile.new('unittest')
|
90
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
91
|
+
tf.puts 'MACRO_APPEND_START 0 1 "%s_%d"'
|
92
|
+
tf.puts 'MACRO_APPEND_END extra'
|
93
|
+
tf.close
|
94
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Too many parameters for MACRO_APPEND_END/)
|
95
|
+
tf.unlink
|
96
|
+
end
|
97
|
+
|
98
|
+
it "complains if there are no items in the macro" do
|
99
|
+
tf = Tempfile.new('unittest')
|
100
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
101
|
+
tf.puts 'MACRO_APPEND_START 0 1 "%s_%d"'
|
102
|
+
tf.puts 'MACRO_APPEND_END'
|
103
|
+
tf.close
|
104
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /No items appended/)
|
105
|
+
tf.unlink
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "add_item" do
|
110
|
+
it "adds items with states to the packet" do
|
111
|
+
tf = Tempfile.new('unittest')
|
112
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
113
|
+
tf.puts 'MACRO_APPEND_START 1 5'
|
114
|
+
tf.puts 'APPEND_ITEM BIT 16 UINT "Setting #x"'
|
115
|
+
tf.puts ' STATE BAD 0 RED'
|
116
|
+
tf.puts ' STATE GOOD 1 GREEN'
|
117
|
+
tf.puts 'MACRO_APPEND_END'
|
118
|
+
tf.close
|
119
|
+
@pc.process_file(tf.path, "TGT1")
|
120
|
+
pkt = @pc.telemetry["TGT1"]["PKT1"]
|
121
|
+
expect(pkt.items.length).to eql 8 # 5 plus the RECEIVED_XXX items
|
122
|
+
pkt.items.keys.should include('BIT1','BIT2','BIT3','BIT4','BIT5')
|
123
|
+
expect(pkt.sorted_items[3].name).to eql 'BIT1'
|
124
|
+
expect(pkt.sorted_items[4].name).to eql 'BIT2'
|
125
|
+
expect(pkt.sorted_items[5].name).to eql 'BIT3'
|
126
|
+
expect(pkt.sorted_items[6].name).to eql 'BIT4'
|
127
|
+
expect(pkt.sorted_items[7].name).to eql 'BIT5'
|
128
|
+
limits_items = []
|
129
|
+
pkt.items.each do |name, item|
|
130
|
+
limits_items << item if name.include?('BIT')
|
131
|
+
end
|
132
|
+
pkt.limits_items.should eql limits_items
|
133
|
+
tf.unlink
|
134
|
+
end
|
135
|
+
|
136
|
+
it "adds items with limits to the packet" do
|
137
|
+
tf = Tempfile.new('unittest')
|
138
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
139
|
+
tf.puts 'MACRO_APPEND_START 1 5'
|
140
|
+
tf.puts 'APPEND_ITEM BIT 16 UINT "Setting #x"'
|
141
|
+
tf.puts ' LIMITS DEFAULT 3 ENABLED 0 1 3 4'
|
142
|
+
tf.puts 'MACRO_APPEND_END'
|
143
|
+
tf.close
|
144
|
+
@pc.process_file(tf.path, "TGT1")
|
145
|
+
pkt = @pc.telemetry["TGT1"]["PKT1"]
|
146
|
+
expect(pkt.items.length).to eql 8 # 5 plus the RECEIVED_XXX items
|
147
|
+
expect(pkt.items.keys).to include('BIT1','BIT2','BIT3','BIT4','BIT5')
|
148
|
+
expect(pkt.limits_items.collect{|item| item.name}).to include('BIT1','BIT2','BIT3','BIT4','BIT5')
|
149
|
+
tf.unlink
|
150
|
+
end
|
151
|
+
|
152
|
+
it "adds array items to the packet" do
|
153
|
+
tf = Tempfile.new('unittest')
|
154
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
155
|
+
tf.puts 'MACRO_APPEND_START 1 5'
|
156
|
+
tf.puts 'APPEND_ARRAY_ITEM BIT 16 INT 64 "Int Array Parameter"'
|
157
|
+
tf.puts 'MACRO_APPEND_END'
|
158
|
+
tf.close
|
159
|
+
@pc.process_file(tf.path, "TGT1")
|
160
|
+
pkt = @pc.telemetry["TGT1"]["PKT1"]
|
161
|
+
expect(pkt.items.length).to eql 8 # 5 plus the RECEIVED_XXX items
|
162
|
+
pkt.items.keys.should include('BIT1','BIT2','BIT3','BIT4','BIT5')
|
163
|
+
pkt.limits_items.should be_empty
|
164
|
+
tf.unlink
|
165
|
+
end
|
166
|
+
|
167
|
+
it "works with printf format strings" do
|
168
|
+
tf = Tempfile.new('unittest')
|
169
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
170
|
+
tf.puts 'MACRO_APPEND_START 8 12 "%02d_%s"'
|
171
|
+
tf.puts 'APPEND_ID_ITEM BIT 16 UINT 0 "Setting #x"'
|
172
|
+
tf.puts 'MACRO_APPEND_END'
|
173
|
+
tf.close
|
174
|
+
@pc.process_file(tf.path, "TGT1")
|
175
|
+
pkt = @pc.telemetry["TGT1"]["PKT1"]
|
176
|
+
expect(pkt.items.length).to eql 8 # 5 plus the RECEIVED_XXX items
|
177
|
+
pkt.items.keys.should include('08_BIT','09_BIT','10_BIT','11_BIT','12_BIT')
|
178
|
+
pkt.limits_items.should be_empty
|
179
|
+
tf.unlink
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|