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,306 @@
|
|
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/packet_item_parser'
|
15
|
+
require 'tempfile'
|
16
|
+
|
17
|
+
module Cosmos
|
18
|
+
|
19
|
+
describe PacketItemParser do
|
20
|
+
|
21
|
+
describe "process_file" do
|
22
|
+
before(:each) do
|
23
|
+
@pc = PacketConfig.new
|
24
|
+
end
|
25
|
+
|
26
|
+
context "with keywords including ITEM" do
|
27
|
+
it "only allows ITEM after TELEMETRY" do
|
28
|
+
tf = Tempfile.new('unittest')
|
29
|
+
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
30
|
+
tf.puts ' ITEM ITEM1 8 0 DERIVED'
|
31
|
+
tf.close
|
32
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /ITEM types are only valid with TELEMETRY/)
|
33
|
+
tf.unlink
|
34
|
+
end
|
35
|
+
|
36
|
+
it "raises if given a bad bit offset" do
|
37
|
+
tf = Tempfile.new('unittest')
|
38
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
39
|
+
tf.puts ' ITEM ITEM1 EIGHT 0 DERIVED'
|
40
|
+
tf.close
|
41
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /invalid value for Integer/)
|
42
|
+
tf.unlink
|
43
|
+
end
|
44
|
+
|
45
|
+
it "raises if given a bad bit size" do
|
46
|
+
tf = Tempfile.new('unittest')
|
47
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
48
|
+
tf.puts ' ITEM ITEM1 8 ZERO DERIVED'
|
49
|
+
tf.close
|
50
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /invalid value for Integer/)
|
51
|
+
tf.unlink
|
52
|
+
end
|
53
|
+
|
54
|
+
it "raises if given a bad array size" do
|
55
|
+
tf = Tempfile.new('unittest')
|
56
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
57
|
+
tf.puts ' ARRAY_ITEM ITEM3 0 32 FLOAT EIGHT'
|
58
|
+
tf.close
|
59
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /invalid value for Integer/)
|
60
|
+
tf.unlink
|
61
|
+
end
|
62
|
+
|
63
|
+
it "only allows DERIVED items with offset 0 and size 0" do
|
64
|
+
tf = Tempfile.new('unittest')
|
65
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
66
|
+
tf.puts ' ITEM ITEM1 8 0 DERIVED'
|
67
|
+
tf.close
|
68
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /DERIVED items must have bit_offset of zero/)
|
69
|
+
tf.unlink
|
70
|
+
|
71
|
+
tf = Tempfile.new('unittest')
|
72
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
73
|
+
tf.puts ' ITEM ITEM1 0 8 DERIVED'
|
74
|
+
tf.close
|
75
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /DERIVED items must have bit_size of zero/)
|
76
|
+
tf.unlink
|
77
|
+
|
78
|
+
tf = Tempfile.new('unittest')
|
79
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
80
|
+
tf.puts ' ITEM ITEM1 0 0 DERIVED'
|
81
|
+
tf.close
|
82
|
+
@pc.process_file(tf.path, "TGT1")
|
83
|
+
expect(@pc.telemetry["TGT1"]["PKT1"].items.keys).to include('ITEM1')
|
84
|
+
tf.unlink
|
85
|
+
end
|
86
|
+
|
87
|
+
it "accepts types INT UINT FLOAT STRING BLOCK" do
|
88
|
+
tf = Tempfile.new('unittest')
|
89
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
90
|
+
tf.puts ' ID_ITEM ITEM1 0 32 INT 0'
|
91
|
+
tf.puts ' ITEM ITEM2 0 32 UINT'
|
92
|
+
tf.puts ' ARRAY_ITEM ITEM3 0 32 FLOAT 64'
|
93
|
+
tf.puts ' APPEND_ID_ITEM ITEM4 32 STRING "ABCD"'
|
94
|
+
tf.puts ' APPEND_ITEM ITEM5 32 BLOCK'
|
95
|
+
tf.puts ' APPEND_ARRAY_ITEM ITEM6 32 BLOCK 64'
|
96
|
+
tf.close
|
97
|
+
@pc.process_file(tf.path, "TGT1")
|
98
|
+
expect(@pc.telemetry["TGT1"]["PKT1"].items.keys).to include('ITEM1','ITEM2','ITEM3','ITEM4','ITEM5','ITEM6')
|
99
|
+
id_items = []
|
100
|
+
id_items << @pc.telemetry["TGT1"]["PKT1"].items["ITEM1"]
|
101
|
+
id_items << @pc.telemetry["TGT1"]["PKT1"].items["ITEM4"]
|
102
|
+
expect(@pc.telemetry["TGT1"]["PKT1"].id_items).to eql id_items
|
103
|
+
tf.unlink
|
104
|
+
end
|
105
|
+
|
106
|
+
it "supports arbitrary endianness per item" do
|
107
|
+
tf = Tempfile.new('unittest')
|
108
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
109
|
+
tf.puts ' ID_ITEM ITEM1 0 32 UINT 0 "" LITTLE_ENDIAN'
|
110
|
+
tf.puts ' ITEM ITEM2 0 32 UINT "" LITTLE_ENDIAN'
|
111
|
+
tf.puts ' ARRAY_ITEM ITEM3 0 32 UINT 64 "" LITTLE_ENDIAN'
|
112
|
+
tf.puts ' APPEND_ID_ITEM ITEM4 32 UINT 1 "" LITTLE_ENDIAN'
|
113
|
+
tf.puts ' APPEND_ITEM ITEM5 32 UINT "" LITTLE_ENDIAN'
|
114
|
+
tf.puts ' APPEND_ARRAY_ITEM ITEM6 32 UINT 64 "" LITTLE_ENDIAN'
|
115
|
+
tf.puts ' ID_ITEM ITEM10 224 32 UINT 0 "" BIG_ENDIAN'
|
116
|
+
tf.puts ' ITEM ITEM20 256 32 UINT "" BIG_ENDIAN'
|
117
|
+
tf.puts ' ARRAY_ITEM ITEM30 0 32 UINT 64 "" BIG_ENDIAN'
|
118
|
+
tf.puts ' APPEND_ID_ITEM ITEM40 32 UINT 1 "" BIG_ENDIAN'
|
119
|
+
tf.puts ' APPEND_ITEM ITEM50 32 UINT "" BIG_ENDIAN'
|
120
|
+
tf.puts ' APPEND_ARRAY_ITEM ITEM60 32 UINT 64 "" BIG_ENDIAN'
|
121
|
+
tf.close
|
122
|
+
@pc.process_file(tf.path, "TGT1")
|
123
|
+
packet = @pc.telemetry["TGT1"]["PKT1"]
|
124
|
+
packet.buffer = "\x00\x00\x00\x01" * 16
|
125
|
+
expect(packet.read("ITEM1")).to eql 0x01000000
|
126
|
+
expect(packet.read("ITEM2")).to eql 0x01000000
|
127
|
+
expect(packet.read("ITEM3")).to eql [0x01000000, 0x01000000]
|
128
|
+
expect(packet.read("ITEM4")).to eql 0x01000000
|
129
|
+
expect(packet.read("ITEM5")).to eql 0x01000000
|
130
|
+
expect(packet.read("ITEM6")).to eql [0x01000000, 0x01000000]
|
131
|
+
expect(packet.read("ITEM10")).to eql 0x00000001
|
132
|
+
expect(packet.read("ITEM20")).to eql 0x00000001
|
133
|
+
expect(packet.read("ITEM30")).to eql [0x00000001, 0x00000001]
|
134
|
+
expect(packet.read("ITEM40")).to eql 0x00000001
|
135
|
+
expect(packet.read("ITEM50")).to eql 0x00000001
|
136
|
+
expect(packet.read("ITEM60")).to eql [0x00000001, 0x00000001]
|
137
|
+
tf.unlink
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context "with keywords including PARAMETER" do
|
142
|
+
it "only allows PARAMETER after COMMAND" do
|
143
|
+
tf = Tempfile.new('unittest')
|
144
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
145
|
+
tf.puts ' PARAMETER ITEM1 8 0 DERIVED 0 0 0'
|
146
|
+
tf.close
|
147
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /PARAMETER types are only valid with COMMAND/)
|
148
|
+
tf.unlink
|
149
|
+
end
|
150
|
+
|
151
|
+
it "only allows DERIVED items with offset 0 and size 0" do
|
152
|
+
tf = Tempfile.new('unittest')
|
153
|
+
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
154
|
+
tf.puts ' PARAMETER ITEM1 8 0 DERIVED 0 0 0'
|
155
|
+
tf.close
|
156
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /DERIVED items must have bit_offset of zero/)
|
157
|
+
tf.unlink
|
158
|
+
|
159
|
+
tf = Tempfile.new('unittest')
|
160
|
+
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
161
|
+
tf.puts ' PARAMETER ITEM1 0 8 DERIVED 0 0 0'
|
162
|
+
tf.close
|
163
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /DERIVED items must have bit_size of zero/)
|
164
|
+
tf.unlink
|
165
|
+
|
166
|
+
tf = Tempfile.new('unittest')
|
167
|
+
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
168
|
+
tf.puts ' PARAMETER ITEM1 0 0 DERIVED 0 0 0'
|
169
|
+
tf.close
|
170
|
+
@pc.process_file(tf.path, "TGT1")
|
171
|
+
expect(@pc.commands["TGT1"]["PKT1"].items.keys).to include('ITEM1')
|
172
|
+
tf.unlink
|
173
|
+
end
|
174
|
+
|
175
|
+
it "doesn't allow ID_PARAMETER with DERIVED type" do
|
176
|
+
tf = Tempfile.new('unittest')
|
177
|
+
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
178
|
+
tf.puts ' ID_PARAMETER ITEM1 0 0 DERIVED 0 0 0'
|
179
|
+
tf.close
|
180
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /DERIVED data type not allowed/)
|
181
|
+
tf.unlink
|
182
|
+
end
|
183
|
+
|
184
|
+
it "doesn't allow APPEND_ID_PARAMETER with DERIVED type" do
|
185
|
+
tf = Tempfile.new('unittest')
|
186
|
+
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
187
|
+
tf.puts ' APPEND_ID_PARAMETER ITEM1 0 DERIVED 0 0 0'
|
188
|
+
tf.close
|
189
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /DERIVED data type not allowed/)
|
190
|
+
tf.unlink
|
191
|
+
end
|
192
|
+
|
193
|
+
it "accepts types INT UINT FLOAT STRING BLOCK" do
|
194
|
+
tf = Tempfile.new('unittest')
|
195
|
+
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
196
|
+
tf.puts ' ID_PARAMETER ITEM1 0 32 INT 0 0 0'
|
197
|
+
tf.puts ' ID_PARAMETER ITEM2 32 32 STRING "ABCD"'
|
198
|
+
tf.puts ' PARAMETER ITEM3 64 32 UINT 0 0 0'
|
199
|
+
tf.puts ' ARRAY_PARAMETER ITEM4 96 32 FLOAT 64'
|
200
|
+
tf.puts ' APPEND_ID_PARAMETER ITEM5 32 UINT 0 0 0'
|
201
|
+
tf.puts ' APPEND_ID_PARAMETER ITEM6 32 STRING "ABCD"'
|
202
|
+
tf.puts ' APPEND_PARAMETER ITEM7 32 BLOCK "1234"'
|
203
|
+
tf.puts ' APPEND_ARRAY_PARAMETER ITEM8 32 BLOCK 64'
|
204
|
+
tf.close
|
205
|
+
@pc.process_file(tf.path, "TGT1")
|
206
|
+
expect(@pc.commands["TGT1"]["PKT1"].items.keys).to include('ITEM1','ITEM2','ITEM3','ITEM4','ITEM5','ITEM6','ITEM7','ITEM8')
|
207
|
+
tf.unlink
|
208
|
+
end
|
209
|
+
|
210
|
+
it "supports arbitrary range, default and endianness per item" do
|
211
|
+
tf = Tempfile.new('unittest')
|
212
|
+
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
213
|
+
tf.puts ' ID_PARAMETER ITEM1 0 32 UINT 1 2 3 "" LITTLE_ENDIAN'
|
214
|
+
tf.puts ' PARAMETER ITEM2 0 32 UINT 4 5 6 "" LITTLE_ENDIAN'
|
215
|
+
tf.puts ' ARRAY_PARAMETER ITEM3 0 32 UINT 64 "" LITTLE_ENDIAN'
|
216
|
+
tf.puts ' APPEND_ID_PARAMETER ITEM4 32 UINT 7 8 9 "" LITTLE_ENDIAN'
|
217
|
+
tf.puts ' APPEND_PARAMETER ITEM5 32 UINT 10 11 12 "" LITTLE_ENDIAN'
|
218
|
+
tf.puts ' APPEND_ARRAY_PARAMETER ITEM6 32 UINT 64 "" LITTLE_ENDIAN'
|
219
|
+
tf.puts ' ID_PARAMETER ITEM10 224 32 UINT 13 14 15 "" BIG_ENDIAN'
|
220
|
+
tf.puts ' PARAMETER ITEM20 256 32 UINT 16 17 18 "" BIG_ENDIAN'
|
221
|
+
tf.puts ' ARRAY_PARAMETER ITEM30 0 32 UINT 64 "" BIG_ENDIAN'
|
222
|
+
tf.puts ' APPEND_ID_PARAMETER ITEM40 32 UINT 19 20 21 "" BIG_ENDIAN'
|
223
|
+
tf.puts ' APPEND_PARAMETER ITEM50 32 UINT 22 23 24 "" BIG_ENDIAN'
|
224
|
+
tf.puts ' APPEND_ARRAY_PARAMETER ITEM60 32 UINT 64 "" BIG_ENDIAN'
|
225
|
+
tf.close
|
226
|
+
@pc.process_file(tf.path, "TGT1")
|
227
|
+
packet = @pc.commands["TGT1"]["PKT1"]
|
228
|
+
packet.buffer = "\x00\x00\x00\x01" * 16
|
229
|
+
expect(packet.get_item("ITEM1").range).to eql (1..2)
|
230
|
+
expect(packet.get_item("ITEM1").default).to eql 3
|
231
|
+
expect(packet.read("ITEM1")).to eql 0x01000000
|
232
|
+
expect(packet.get_item("ITEM2").range).to eql (4..5)
|
233
|
+
expect(packet.get_item("ITEM2").default).to eql 6
|
234
|
+
expect(packet.read("ITEM2")).to eql 0x01000000
|
235
|
+
expect(packet.get_item("ITEM3").range).to be_nil
|
236
|
+
expect(packet.get_item("ITEM3").default).to eql []
|
237
|
+
expect(packet.read("ITEM3")).to eql [0x01000000, 0x01000000]
|
238
|
+
expect(packet.get_item("ITEM4").range).to eql (7..8)
|
239
|
+
expect(packet.get_item("ITEM4").default).to eql 9
|
240
|
+
expect(packet.read("ITEM4")).to eql 0x01000000
|
241
|
+
expect(packet.get_item("ITEM5").range).to eql (10..11)
|
242
|
+
expect(packet.get_item("ITEM5").default).to eql 12
|
243
|
+
expect(packet.read("ITEM5")).to eql 0x01000000
|
244
|
+
expect(packet.get_item("ITEM6").range).to be_nil
|
245
|
+
expect(packet.get_item("ITEM6").default).to eql []
|
246
|
+
expect(packet.read("ITEM6")).to eql [0x01000000, 0x01000000]
|
247
|
+
expect(packet.get_item("ITEM10").range).to eql (13..14)
|
248
|
+
expect(packet.get_item("ITEM10").default).to eql 15
|
249
|
+
expect(packet.read("ITEM10")).to eql 0x00000001
|
250
|
+
expect(packet.get_item("ITEM20").range).to eql (16..17)
|
251
|
+
expect(packet.get_item("ITEM20").default).to eql 18
|
252
|
+
expect(packet.read("ITEM20")).to eql 0x00000001
|
253
|
+
expect(packet.get_item("ITEM30").range).to be_nil
|
254
|
+
expect(packet.get_item("ITEM30").default).to eql []
|
255
|
+
expect(packet.read("ITEM30")).to eql [0x00000001, 0x00000001]
|
256
|
+
expect(packet.get_item("ITEM40").range).to eql (19..20)
|
257
|
+
expect(packet.get_item("ITEM40").default).to eql 21
|
258
|
+
expect(packet.read("ITEM40")).to eql 0x00000001
|
259
|
+
expect(packet.get_item("ITEM50").range).to eql (22..23)
|
260
|
+
expect(packet.get_item("ITEM50").default).to eql 24
|
261
|
+
expect(packet.read("ITEM50")).to eql 0x00000001
|
262
|
+
expect(packet.get_item("ITEM60").range).to be_nil
|
263
|
+
expect(packet.get_item("ITEM60").default).to eql []
|
264
|
+
expect(packet.read("ITEM60")).to eql [0x00000001, 0x00000001]
|
265
|
+
tf.unlink
|
266
|
+
end
|
267
|
+
|
268
|
+
it "only supports BIG_ENDIAN and LITTLE_ENDIAN" do
|
269
|
+
tf = Tempfile.new('unittest')
|
270
|
+
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
271
|
+
tf.puts ' ID_PARAMETER ITEM1 0 32 UINT 0 0 0 "" MIDDLE_ENDIAN'
|
272
|
+
tf.close
|
273
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Invalid endianness MIDDLE_ENDIAN/)
|
274
|
+
tf.unlink
|
275
|
+
end
|
276
|
+
|
277
|
+
context "with a conversion" do
|
278
|
+
it "allows for different default type than the data type" do
|
279
|
+
tf = Tempfile.new('unittest')
|
280
|
+
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
281
|
+
tf.puts ' PARAMETER ITEM1 0 32 UINT 4.5 5.5 6.5 "" LITTLE_ENDIAN'
|
282
|
+
tf.puts ' GENERIC_WRITE_CONVERSION_START'
|
283
|
+
tf.puts ' value / 2.0'
|
284
|
+
tf.puts ' GENERIC_WRITE_CONVERSION_END'
|
285
|
+
tf.close
|
286
|
+
@pc.process_file(tf.path, "TGT1")
|
287
|
+
tf.unlink
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
context "without a conversion" do
|
292
|
+
it "requires the default type matches the data type" do
|
293
|
+
tf = Tempfile.new('unittest')
|
294
|
+
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
295
|
+
tf.puts ' PARAMETER ITEM1 0 32 UINT 4.5 5.5 6.5 "" LITTLE_ENDIAN'
|
296
|
+
tf.close
|
297
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ArgumentError, /TGT1 PKT1 ITEM1: default must be a Integer but is a Float/)
|
298
|
+
tf.unlink
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
end
|
303
|
+
|
304
|
+
end # describe "process_file"
|
305
|
+
end
|
306
|
+
end
|
@@ -0,0 +1,99 @@
|
|
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/packet_parser'
|
15
|
+
require 'tempfile'
|
16
|
+
|
17
|
+
module Cosmos
|
18
|
+
|
19
|
+
describe PacketParser do
|
20
|
+
|
21
|
+
describe "process_file" do
|
22
|
+
before(:each) do
|
23
|
+
@pc = PacketConfig.new
|
24
|
+
end
|
25
|
+
|
26
|
+
it "complains if there are not enough parameters" do
|
27
|
+
%w(COMMAND TELEMETRY).each do |keyword|
|
28
|
+
tf = Tempfile.new('unittest')
|
29
|
+
tf.puts(keyword)
|
30
|
+
tf.close
|
31
|
+
expect { @pc.process_file(tf.path, "SYSTEM") }.to raise_error(ConfigParser::Error, /Not enough parameters for #{keyword}/)
|
32
|
+
tf.unlink
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it "complains if there are too many parameters" do
|
37
|
+
%w(COMMAND TELEMETRY).each do |keyword|
|
38
|
+
tf = Tempfile.new('unittest')
|
39
|
+
tf.puts "#{keyword} tgt1 pkt1 LITTLE_ENDIAN 'Packet' extra"
|
40
|
+
tf.close
|
41
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Too many parameters for #{keyword}/)
|
42
|
+
tf.unlink
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "complains about invalid endianness" do
|
47
|
+
%w(COMMAND TELEMETRY).each do |keyword|
|
48
|
+
tf = Tempfile.new('unittest')
|
49
|
+
tf.puts keyword + ' tgt1 pkt1 MIDDLE_ENDIAN "Packet"'
|
50
|
+
tf.close
|
51
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid endianness MIDDLE_ENDIAN. Must be BIG_ENDIAN or LITTLE_ENDIAN.")
|
52
|
+
tf.unlink
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it "processes target, packet, endianness, description" do
|
57
|
+
%w(COMMAND TELEMETRY).each do |keyword|
|
58
|
+
tf = Tempfile.new('unittest')
|
59
|
+
tf.puts keyword + ' tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
60
|
+
tf.close
|
61
|
+
@pc.process_file(tf.path, "TGT1")
|
62
|
+
pkt = @pc.commands["TGT1"]["PKT1"] if keyword == 'COMMAND'
|
63
|
+
pkt = @pc.telemetry["TGT1"]["PKT1"] if keyword == 'TELEMETRY'
|
64
|
+
pkt.target_name.should eql "TGT1"
|
65
|
+
pkt.packet_name.should eql "PKT1"
|
66
|
+
pkt.default_endianness.should eql :LITTLE_ENDIAN
|
67
|
+
pkt.description.should eql "Packet"
|
68
|
+
tf.unlink
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it "substitutes the target name" do
|
73
|
+
%w(COMMAND TELEMETRY).each do |keyword|
|
74
|
+
tf = Tempfile.new('unittest')
|
75
|
+
tf.puts keyword + ' tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
76
|
+
tf.close
|
77
|
+
@pc.process_file(tf.path, "NEW")
|
78
|
+
pkt = @pc.commands["NEW"]["PKT1"] if keyword == 'COMMAND'
|
79
|
+
pkt = @pc.telemetry["NEW"]["PKT1"] if keyword == 'TELEMETRY'
|
80
|
+
pkt.target_name.should eql "NEW"
|
81
|
+
tf.unlink
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
it "complains if a packet is redefined" do
|
86
|
+
%w(COMMAND TELEMETRY).each do |keyword|
|
87
|
+
tf = Tempfile.new('unittest')
|
88
|
+
tf.puts keyword + ' tgt1 pkt1 LITTLE_ENDIAN "Packet 1"'
|
89
|
+
tf.puts keyword + ' tgt1 pkt1 LITTLE_ENDIAN "Packet 2"'
|
90
|
+
tf.close
|
91
|
+
@pc.process_file(tf.path, "SYSTEM")
|
92
|
+
@pc.warnings.should include("#{keyword.capitalize} Packet TGT1 PKT1 redefined.")
|
93
|
+
tf.unlink
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end # describe "process_file"
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,114 @@
|
|
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/processor_parser'
|
15
|
+
require 'tempfile'
|
16
|
+
|
17
|
+
module Cosmos
|
18
|
+
|
19
|
+
describe ProcessorParser do
|
20
|
+
|
21
|
+
describe "process_file" do
|
22
|
+
before(:each) do
|
23
|
+
@pc = PacketConfig.new
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should complain if a current packet is not defined" do
|
27
|
+
# Check for missing TELEMETRY line
|
28
|
+
tf = Tempfile.new('unittest')
|
29
|
+
tf.puts('PROCESSOR')
|
30
|
+
tf.close
|
31
|
+
expect { @pc.process_file(tf.path, "SYSTEM") }.to raise_error(ConfigParser::Error, "No current packet for PROCESSOR")
|
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 ' PROCESSOR'
|
39
|
+
tf.close
|
40
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Not enough parameters for PROCESSOR/)
|
41
|
+
tf.unlink
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should complain about missing processor file" do
|
45
|
+
filename = File.join(File.dirname(__FILE__), "../../test_only.rb")
|
46
|
+
File.delete(filename) if File.exist?(filename)
|
47
|
+
@pc = PacketConfig.new
|
48
|
+
|
49
|
+
tf = Tempfile.new('unittest')
|
50
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
51
|
+
tf.puts ' PROCESSOR TEST test_only.rb'
|
52
|
+
tf.close
|
53
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /TestOnly class not found/)
|
54
|
+
tf.unlink
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should complain about a non Cosmos::Processor class" do
|
58
|
+
filename = File.join(File.dirname(__FILE__), "../../processor1.rb")
|
59
|
+
File.open(filename, 'w') do |file|
|
60
|
+
file.puts "class Processor1"
|
61
|
+
file.puts " def call(packet,buffer)"
|
62
|
+
file.puts " end"
|
63
|
+
file.puts "end"
|
64
|
+
end
|
65
|
+
load 'processor1.rb'
|
66
|
+
File.delete(filename) if File.exist?(filename)
|
67
|
+
|
68
|
+
tf = Tempfile.new('unittest')
|
69
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
70
|
+
tf.puts ' PROCESSOR P1 processor1.rb'
|
71
|
+
tf.close
|
72
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /processor must be a Cosmos::Processor but is a Processor1/)
|
73
|
+
tf.unlink
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should parse the processor" do
|
77
|
+
filename = File.join(File.dirname(__FILE__), "../../processor2.rb")
|
78
|
+
File.open(filename, 'w') do |file|
|
79
|
+
file.puts "require 'cosmos/processors/processor'"
|
80
|
+
file.puts "class Processor2 < Cosmos::Processor"
|
81
|
+
file.puts " def call(packet,buffer)"
|
82
|
+
file.puts " @results[:TEST] = 5"
|
83
|
+
file.puts " end"
|
84
|
+
file.puts "end"
|
85
|
+
end
|
86
|
+
load 'processor2.rb'
|
87
|
+
|
88
|
+
tf = Tempfile.new('unittest')
|
89
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
90
|
+
tf.puts ' ITEM item1 0 16 INT "Integer Item"'
|
91
|
+
tf.puts ' READ_CONVERSION processor_conversion.rb P2 TEST'
|
92
|
+
tf.puts ' PROCESSOR P2 processor2.rb'
|
93
|
+
tf.puts ' PROCESSOR P3 processor2.rb RAW'
|
94
|
+
tf.close
|
95
|
+
@pc.process_file(tf.path, "TGT1")
|
96
|
+
@pc.telemetry["TGT1"]["PKT1"].buffer = "\x01\x01"
|
97
|
+
@pc.telemetry["TGT1"]["PKT1"].read("ITEM1").should eql 5
|
98
|
+
tf.unlink
|
99
|
+
|
100
|
+
File.delete(filename) if File.exist?(filename)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should complain if applied to a command packet" do
|
104
|
+
tf = Tempfile.new('unittest')
|
105
|
+
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
106
|
+
tf.puts ' PROCESSOR P1 processor1.rb'
|
107
|
+
tf.close
|
108
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "PROCESSOR only applies to telemetry packets")
|
109
|
+
tf.unlink
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|