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
@@ -194,19 +194,19 @@ module Cosmos
|
|
194
194
|
it "should complain about default not matching data_type" do
|
195
195
|
pi = PacketItem.new("test", 0, 8, :UINT, :BIG_ENDIAN, 16)
|
196
196
|
pi.default = 1
|
197
|
-
expect { pi.check_default_and_range_data_types }.to raise_error(ArgumentError, "
|
197
|
+
expect { pi.check_default_and_range_data_types }.to raise_error(ArgumentError, "TEST: default must be an Array but is a Fixnum")
|
198
198
|
pi = PacketItem.new("test", 0, 8, :UINT, :BIG_ENDIAN, 16)
|
199
199
|
pi.default = []
|
200
200
|
expect { pi.check_default_and_range_data_types }.to_not raise_error
|
201
201
|
pi = PacketItem.new("test", 0, 32, :UINT, :BIG_ENDIAN, nil)
|
202
202
|
pi.default = 5.5
|
203
|
-
expect { pi.check_default_and_range_data_types }.to raise_error(ArgumentError, "
|
203
|
+
expect { pi.check_default_and_range_data_types }.to raise_error(ArgumentError, "TEST: default must be a Integer but is a Float")
|
204
204
|
pi = PacketItem.new("test", 0, 32, :UINT, :BIG_ENDIAN, nil)
|
205
205
|
pi.default = 5
|
206
206
|
expect { pi.check_default_and_range_data_types }.to_not raise_error
|
207
207
|
pi = PacketItem.new("test", 0, 32, :FLOAT, :BIG_ENDIAN, nil)
|
208
208
|
pi.default = "test"
|
209
|
-
expect { pi.check_default_and_range_data_types }.to raise_error(ArgumentError, "
|
209
|
+
expect { pi.check_default_and_range_data_types }.to raise_error(ArgumentError, "TEST: default must be a Float but is a String")
|
210
210
|
pi = PacketItem.new("test", 0, 32, :FLOAT, :BIG_ENDIAN, nil)
|
211
211
|
pi.default = 5
|
212
212
|
expect { pi.check_default_and_range_data_types }.to_not raise_error
|
@@ -215,13 +215,13 @@ module Cosmos
|
|
215
215
|
expect { pi.check_default_and_range_data_types }.to_not raise_error
|
216
216
|
pi = PacketItem.new("test", 0, 32, :STRING, :BIG_ENDIAN, nil)
|
217
217
|
pi.default = 5
|
218
|
-
expect { pi.check_default_and_range_data_types }.to raise_error(ArgumentError, "
|
218
|
+
expect { pi.check_default_and_range_data_types }.to raise_error(ArgumentError, "TEST: default must be a String but is a Fixnum")
|
219
219
|
pi = PacketItem.new("test", 0, 32, :STRING, :BIG_ENDIAN, nil)
|
220
220
|
pi.default = ''
|
221
221
|
expect { pi.check_default_and_range_data_types }.to_not raise_error
|
222
222
|
pi = PacketItem.new("test", 0, 32, :BLOCK, :BIG_ENDIAN, nil)
|
223
223
|
pi.default = 5.5
|
224
|
-
expect { pi.check_default_and_range_data_types }.to raise_error(ArgumentError, "
|
224
|
+
expect { pi.check_default_and_range_data_types }.to raise_error(ArgumentError, "TEST: default must be a String but is a Float")
|
225
225
|
pi = PacketItem.new("test", 0, 32, :BLOCK, :BIG_ENDIAN, nil)
|
226
226
|
pi.default = ''
|
227
227
|
expect { pi.check_default_and_range_data_types }.to_not raise_error
|
@@ -231,17 +231,17 @@ module Cosmos
|
|
231
231
|
pi = PacketItem.new("test", 0, 32, :UINT, :BIG_ENDIAN, nil)
|
232
232
|
pi.default = 5
|
233
233
|
pi.range = (5.5..10)
|
234
|
-
expect { pi.check_default_and_range_data_types }.to raise_error(ArgumentError, "
|
234
|
+
expect { pi.check_default_and_range_data_types }.to raise_error(ArgumentError, "TEST: minimum must be a Integer but is a Float")
|
235
235
|
pi.range = (5..10.5)
|
236
|
-
expect { pi.check_default_and_range_data_types }.to raise_error(ArgumentError, "
|
236
|
+
expect { pi.check_default_and_range_data_types }.to raise_error(ArgumentError, "TEST: maximum must be a Integer but is a Float")
|
237
237
|
pi = PacketItem.new("test", 0, 32, :FLOAT, :BIG_ENDIAN, nil)
|
238
238
|
pi.default = 5.5
|
239
239
|
pi.range = (5..10)
|
240
240
|
expect { pi.check_default_and_range_data_types }.to_not raise_error
|
241
241
|
pi.range = ('a'..'z')
|
242
|
-
expect { pi.check_default_and_range_data_types }.to raise_error(ArgumentError, "
|
242
|
+
expect { pi.check_default_and_range_data_types }.to raise_error(ArgumentError, "TEST: minimum must be a Float but is a String")
|
243
243
|
pi.range = (1.0..Rational(2))
|
244
|
-
expect { pi.check_default_and_range_data_types }.to raise_error(ArgumentError, "
|
244
|
+
expect { pi.check_default_and_range_data_types }.to raise_error(ArgumentError, "TEST: maximum must be a Float but is a Rational")
|
245
245
|
end
|
246
246
|
end
|
247
247
|
|
@@ -349,7 +349,7 @@ module Cosmos
|
|
349
349
|
hash.keys.length.should eql 22
|
350
350
|
# Check the values from StructureItem
|
351
351
|
hash.keys.should include('name','bit_offset','bit_size','data_type','endianness','array_size','overflow')
|
352
|
-
hash["name"].should eql "
|
352
|
+
hash["name"].should eql "TEST"
|
353
353
|
hash["bit_offset"].should eql 0
|
354
354
|
hash["bit_size"].should eql 32
|
355
355
|
hash["data_type"].should eql :UINT
|
data/spec/packets/packet_spec.rb
CHANGED
@@ -91,6 +91,26 @@ module Cosmos
|
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
94
|
+
describe "set_received_time_fast" do
|
95
|
+
it "sets the received_time to a Time" do
|
96
|
+
p = Packet.new("tgt", "pkt")
|
97
|
+
t = Time.now
|
98
|
+
p.set_received_time_fast(t)
|
99
|
+
expect(p.received_time).to eql t
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should set received_time to nil" do
|
103
|
+
p = Packet.new("tgt","pkt")
|
104
|
+
p.received_time = nil
|
105
|
+
p.received_time.should be_nil
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should complain about non Time received_times" do
|
109
|
+
p = Packet.new("tgt","pkt")
|
110
|
+
expect {p.received_time = "1pm" }.to raise_error(ArgumentError, "received_time must be a Time but is a String")
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
94
114
|
describe "received_time=" do
|
95
115
|
it "should set the received_time to a Time" do
|
96
116
|
p = Packet.new("tgt", "pkt")
|
@@ -219,6 +239,42 @@ module Cosmos
|
|
219
239
|
end
|
220
240
|
end
|
221
241
|
|
242
|
+
describe "define" do
|
243
|
+
it "adds a PacketItem to a packet" do
|
244
|
+
p = Packet.new("tgt","pkt")
|
245
|
+
rc = GenericConversion.new("value / 2")
|
246
|
+
wc = GenericConversion.new("value * 2")
|
247
|
+
pi = PacketItem.new("item1",0,32,:FLOAT,:BIG_ENDIAN,nil,:ERROR)
|
248
|
+
pi.format_string = "%5.1f"
|
249
|
+
pi.read_conversion = rc
|
250
|
+
pi.write_conversion = wc
|
251
|
+
pi.state_colors = {'RED'=>0}
|
252
|
+
pi.id_value = 5
|
253
|
+
p.define(pi)
|
254
|
+
i = p.get_item("ITEM1")
|
255
|
+
i.format_string.should eql "%5.1f"
|
256
|
+
i.read_conversion.to_s.should eql rc.to_s
|
257
|
+
i.write_conversion.to_s.should eql wc.to_s
|
258
|
+
i.id_value.should eql 5.0
|
259
|
+
expect(p.id_items.length).to eq 1
|
260
|
+
expect(p.id_items[0].name).to eq 'ITEM1'
|
261
|
+
expect(p.limits_items[0].name).to eq 'ITEM1'
|
262
|
+
p.defined_length.should eql 4
|
263
|
+
end
|
264
|
+
|
265
|
+
it "allows PacketItems to be defined on top of each other" do
|
266
|
+
p = Packet.new("tgt","pkt")
|
267
|
+
pi = PacketItem.new("item1",0,8,:UINT,:BIG_ENDIAN)
|
268
|
+
p.define(pi)
|
269
|
+
pi = PacketItem.new("item2",0,32,:UINT,:BIG_ENDIAN)
|
270
|
+
p.define(pi)
|
271
|
+
p.defined_length.should eql 4
|
272
|
+
buffer = "\x01\x02\x03\x04"
|
273
|
+
p.read_item(p.get_item("item1"), :RAW, buffer).should eql 1
|
274
|
+
p.read_item(p.get_item("item2"), :RAW, buffer).should eql 0x1020304
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
222
278
|
describe "append_item" do
|
223
279
|
it "should take a format_string, read_conversion, write_conversion, and id_value" do
|
224
280
|
p = Packet.new("tgt","pkt")
|
@@ -243,6 +299,41 @@ module Cosmos
|
|
243
299
|
end
|
244
300
|
end
|
245
301
|
|
302
|
+
describe "append" do
|
303
|
+
it "adds a PacketItem to the end of a packet" do
|
304
|
+
p = Packet.new("tgt","pkt")
|
305
|
+
rc = GenericConversion.new("value / 2")
|
306
|
+
wc = GenericConversion.new("value * 2")
|
307
|
+
pi = PacketItem.new("item1",0,32,:FLOAT,:BIG_ENDIAN,nil,:ERROR)
|
308
|
+
pi.format_string = "%5.1f"
|
309
|
+
pi.read_conversion = rc
|
310
|
+
pi.write_conversion = wc
|
311
|
+
pi.limits.values = {:DEFAULT => [0, 1, 2, 3]}
|
312
|
+
pi.id_value = 5
|
313
|
+
p.append(pi)
|
314
|
+
i = p.get_item("ITEM1")
|
315
|
+
i.format_string.should eql "%5.1f"
|
316
|
+
i.read_conversion.to_s.should eql rc.to_s
|
317
|
+
i.write_conversion.to_s.should eql wc.to_s
|
318
|
+
i.id_value.should eql 5.0
|
319
|
+
expect(p.id_items.length).to eq 1
|
320
|
+
expect(p.id_items[0].name).to eq 'ITEM1'
|
321
|
+
expect(p.limits_items[0].name).to eq 'ITEM1'
|
322
|
+
p.defined_length.should eql 4
|
323
|
+
|
324
|
+
pi = PacketItem.new("item2",0,32,:FLOAT,:BIG_ENDIAN,nil,:ERROR)
|
325
|
+
p.append(pi)
|
326
|
+
i = p.get_item("ITEM2")
|
327
|
+
expect(i.bit_offset).to be 32 # offset updated inside the PacketItem
|
328
|
+
expect(i.format_string).to be nil
|
329
|
+
expect(i.read_conversion).to be nil
|
330
|
+
expect(i.write_conversion).to be nil
|
331
|
+
expect(i.id_value).to be nil
|
332
|
+
expect(p.id_items.length).to eq 1
|
333
|
+
p.defined_length.should eql 8
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
246
337
|
describe "get_item" do
|
247
338
|
it "should complain if an item doesn't exist" do
|
248
339
|
p = Packet.new("tgt","pkt")
|
@@ -383,6 +474,23 @@ module Cosmos
|
|
383
474
|
@buffer.should eql "\x05\x06\x07\x08"
|
384
475
|
end
|
385
476
|
|
477
|
+
it "clears the read cache" do
|
478
|
+
@p.append_item("item",8,:UINT)
|
479
|
+
i = @p.get_item("ITEM")
|
480
|
+
@p.buffer = "\x04"
|
481
|
+
cache = p.instance_variable_get(:@read_conversion_cache)
|
482
|
+
i.read_conversion = GenericConversion.new("value / 2")
|
483
|
+
expect(cache).to be nil
|
484
|
+
expect(@p.read("ITEM")).to be 2
|
485
|
+
cache = @p.instance_variable_get(:@read_conversion_cache)
|
486
|
+
expect(cache[i]).to be 2
|
487
|
+
@p.write("ITEM", 0x08, :RAW)
|
488
|
+
@p.buffer.should eql "\x08"
|
489
|
+
expect(cache[i]).to be nil
|
490
|
+
expect(@p.read("ITEM")).to be 4
|
491
|
+
expect(cache[i]).to be 4
|
492
|
+
end
|
493
|
+
|
386
494
|
it "should write the CONVERTED value" do
|
387
495
|
@p.append_item("item",8,:UINT)
|
388
496
|
i = @p.get_item("ITEM")
|
@@ -409,6 +517,7 @@ module Cosmos
|
|
409
517
|
@buffer.should eql "\x01\x00\x00\x00"
|
410
518
|
@p.write_item(i, "FALSE", :CONVERTED, @buffer)
|
411
519
|
@buffer.should eql "\x02\x00\x00\x00"
|
520
|
+
expect { @p.write_item(i, "BLAH", :CONVERTED, @buffer) }.to raise_error(RuntimeError, "Unknown state BLAH for ITEM")
|
412
521
|
i.write_conversion = GenericConversion.new("value / 2")
|
413
522
|
@p.write("ITEM", 4, :CONVERTED, @buffer)
|
414
523
|
@buffer.should eql "\x02\x00\x00\x00"
|
@@ -502,6 +611,113 @@ module Cosmos
|
|
502
611
|
end
|
503
612
|
end
|
504
613
|
|
614
|
+
describe "check_bit_offsets" do
|
615
|
+
it "should complain about overlapping items" do
|
616
|
+
p = Packet.new("tgt1","pkt1")
|
617
|
+
p.define_item("item1",0,8,:UINT)
|
618
|
+
p.define_item("item2",0,8,:UINT)
|
619
|
+
expect(p.check_bit_offsets[0]).to eql "Bit definition overlap at bit offset 0 for packet TGT1 PKT1 items ITEM2 and ITEM1"
|
620
|
+
end
|
621
|
+
|
622
|
+
it "should not complain with non-overlapping negative offsets" do
|
623
|
+
p = Packet.new("tgt1","pkt1")
|
624
|
+
p.define_item("item1",0,8,:UINT)
|
625
|
+
p.define_item("item2",8,-16,:BLOCK)
|
626
|
+
p.define_item("item3",-16,16,:UINT)
|
627
|
+
expect(p.check_bit_offsets[0]).to be_nil
|
628
|
+
end
|
629
|
+
|
630
|
+
it "should complain with overlapping negative offsets" do
|
631
|
+
p = Packet.new("tgt1","pkt1")
|
632
|
+
p.define_item("item1",0,8,:UINT)
|
633
|
+
p.define_item("item2",8,-16,:BLOCK)
|
634
|
+
p.define_item("item3",-17,16,:UINT)
|
635
|
+
expect(p.check_bit_offsets[0]).to eql "Bit definition overlap at bit offset -17 for packet TGT1 PKT1 items ITEM3 and ITEM2"
|
636
|
+
end
|
637
|
+
|
638
|
+
it "should complain about intersecting items" do
|
639
|
+
p = Packet.new("tgt1","pkt1")
|
640
|
+
p.define_item("item1",0,32,:UINT)
|
641
|
+
p.define_item("item2",16,32,:UINT)
|
642
|
+
expect(p.check_bit_offsets[0]).to eql "Bit definition overlap at bit offset 16 for packet TGT1 PKT1 items ITEM2 and ITEM1"
|
643
|
+
end
|
644
|
+
|
645
|
+
it "should complain about array overlapping items" do
|
646
|
+
p = Packet.new("tgt1","pkt1")
|
647
|
+
p.define_item("item1",0,8,:UINT,32)
|
648
|
+
p.define_item("item2",0,8,:UINT,32)
|
649
|
+
expect(p.check_bit_offsets[0]).to eql "Bit definition overlap at bit offset 0 for packet TGT1 PKT1 items ITEM2 and ITEM1"
|
650
|
+
end
|
651
|
+
|
652
|
+
it "should not complain with array non-overlapping negative offsets" do
|
653
|
+
p = Packet.new("tgt1","pkt1")
|
654
|
+
p.define_item("item1",0,8,:UINT)
|
655
|
+
p.define_item("item2",8,8,:INT,-16)
|
656
|
+
p.define_item("item3",-16,16,:UINT)
|
657
|
+
expect(p.check_bit_offsets[0]).to be_nil
|
658
|
+
end
|
659
|
+
|
660
|
+
it "should complain with array overlapping negative offsets" do
|
661
|
+
p = Packet.new("tgt1","pkt1")
|
662
|
+
p.define_item("item1",0,8,:UINT)
|
663
|
+
p.define_item("item2",8,8,:INT,-16)
|
664
|
+
p.define_item("item3",-17,16,:UINT)
|
665
|
+
expect(p.check_bit_offsets[0]).to eql "Bit definition overlap at bit offset -17 for packet TGT1 PKT1 items ITEM3 and ITEM2"
|
666
|
+
end
|
667
|
+
|
668
|
+
it "should complain about array intersecting items" do
|
669
|
+
p = Packet.new("tgt1","pkt1")
|
670
|
+
p.define_item("item1",0,8,:UINT,32)
|
671
|
+
p.define_item("item2",16,8,:UINT,32)
|
672
|
+
expect(p.check_bit_offsets[0]).to eql "Bit definition overlap at bit offset 16 for packet TGT1 PKT1 items ITEM2 and ITEM1"
|
673
|
+
end
|
674
|
+
|
675
|
+
it "should not complain about nonoverlapping big endian bitfields" do
|
676
|
+
p = Packet.new("tgt1","pkt1")
|
677
|
+
p.define_item("item1",0,12,:UINT,nil,:BIG_ENDIAN)
|
678
|
+
p.define_item("item2",12,4,:UINT,nil,:BIG_ENDIAN)
|
679
|
+
p.define_item("item3",16,16,:UINT,nil,:BIG_ENDIAN)
|
680
|
+
expect(p.check_bit_offsets[0]).to be_nil
|
681
|
+
end
|
682
|
+
|
683
|
+
it "should complain about overlapping big endian bitfields" do
|
684
|
+
p = Packet.new("tgt1","pkt1")
|
685
|
+
p.define_item("item1",0,12,:UINT,nil,:BIG_ENDIAN)
|
686
|
+
p.define_item("item2",10,6,:UINT,nil,:BIG_ENDIAN)
|
687
|
+
p.define_item("item3",16,16,:UINT,nil,:BIG_ENDIAN)
|
688
|
+
expect(p.check_bit_offsets[0]).to eql "Bit definition overlap at bit offset 10 for packet TGT1 PKT1 items ITEM2 and ITEM1"
|
689
|
+
end
|
690
|
+
|
691
|
+
it "should not complain about nonoverlapping little endian bitfields" do
|
692
|
+
p = Packet.new("tgt1","pkt1")
|
693
|
+
# bit offset in LITTLE_ENDIAN refers to MSB
|
694
|
+
p.define_item("item1",12,12,:UINT,nil,:LITTLE_ENDIAN)
|
695
|
+
p.define_item("item2",16,16,:UINT,nil,:LITTLE_ENDIAN)
|
696
|
+
expect(p.check_bit_offsets[0]).to be_nil
|
697
|
+
end
|
698
|
+
|
699
|
+
it "should complain about overlapping little endian bitfields" do
|
700
|
+
p = Packet.new("tgt1","pkt1")
|
701
|
+
# bit offset in LITTLE_ENDIAN refers to MSB
|
702
|
+
p.define_item("item1",12,12,:UINT,nil,:LITTLE_ENDIAN)
|
703
|
+
p.define_item("item2",10,10,:UINT,nil,:LITTLE_ENDIAN)
|
704
|
+
expect(p.check_bit_offsets[0]).to eql "Bit definition overlap at bit offset 12 for packet TGT1 PKT1 items ITEM1 and ITEM2"
|
705
|
+
end
|
706
|
+
end
|
707
|
+
|
708
|
+
describe "id_items" do
|
709
|
+
it "returns an array of the identifying items" do
|
710
|
+
p = Packet.new("tgt","pkt")
|
711
|
+
p.define_item("item1",0,32,:FLOAT,nil,:BIG_ENDIAN,:ERROR,"%5.1f",nil,nil,nil)
|
712
|
+
p.define_item("item2",0,32,:FLOAT,nil,:BIG_ENDIAN,:ERROR,"%5.1f",nil,nil,5)
|
713
|
+
p.define_item("item3",0,32,:FLOAT,nil,:BIG_ENDIAN,:ERROR,"%5.1f",nil,nil,nil)
|
714
|
+
p.define_item("item4",0,32,:FLOAT,nil,:BIG_ENDIAN,:ERROR,"%5.1f",nil,nil,6)
|
715
|
+
expect(p.id_items).to be_a Array
|
716
|
+
expect(p.id_items[0].name).to eq "ITEM2"
|
717
|
+
expect(p.id_items[1].name).to eq "ITEM4"
|
718
|
+
end
|
719
|
+
end
|
720
|
+
|
505
721
|
describe "identify?" do
|
506
722
|
it "should identify a buffer based on id_items" do
|
507
723
|
p = Packet.new("tgt","pkt")
|
@@ -1034,14 +1250,23 @@ module Cosmos
|
|
1034
1250
|
describe "clone" do
|
1035
1251
|
it "should duplicate the packet" do
|
1036
1252
|
p = Packet.new("tgt","pkt")
|
1253
|
+
p.processors['processor'] = Processor.new
|
1254
|
+
p.processors['processor'].name = "TestProcessor"
|
1037
1255
|
p2 = p.clone
|
1256
|
+
# No comparison operator
|
1257
|
+
# expect(p).to eql p2
|
1258
|
+
expect(p).to_not be p2
|
1038
1259
|
p2.target_name.should eql "TGT"
|
1039
1260
|
p2.packet_name.should eql "PKT"
|
1261
|
+
# No comparison operator
|
1262
|
+
# expect(p2.processors['processor']).to eql p.processors['processor']
|
1263
|
+
expect(p2.processors['processor']).to_not be p.processors['processor']
|
1264
|
+
expect(p2.processors['processor'].name).to eql p.processors['processor'].name
|
1040
1265
|
end
|
1041
1266
|
end
|
1042
1267
|
|
1043
1268
|
describe "reset" do
|
1044
|
-
it "
|
1269
|
+
it "resets the received_time and received_count" do
|
1045
1270
|
p = Packet.new("tgt","pkt")
|
1046
1271
|
p.processors['processor'] = double("reset", :reset => true)
|
1047
1272
|
p.received_time = Time.now
|
@@ -1050,6 +1275,19 @@ module Cosmos
|
|
1050
1275
|
p.received_time.should eql nil
|
1051
1276
|
p.received_count.should eql 0
|
1052
1277
|
end
|
1278
|
+
|
1279
|
+
it "clears the read conversion cache" do
|
1280
|
+
p = Packet.new("tgt","pkt")
|
1281
|
+
p.append_item("item",8,:UINT)
|
1282
|
+
i = p.get_item("ITEM")
|
1283
|
+
p.buffer = "\x04"
|
1284
|
+
i.read_conversion = GenericConversion.new("value / 2")
|
1285
|
+
expect(p.read("ITEM")).to be 2
|
1286
|
+
cache = p.instance_variable_get(:@read_conversion_cache)
|
1287
|
+
expect(cache[i]).to be 2
|
1288
|
+
p.reset
|
1289
|
+
expect(cache).to be_empty
|
1290
|
+
end
|
1053
1291
|
end
|
1054
1292
|
|
1055
1293
|
end # describe Packet
|
@@ -0,0 +1,122 @@
|
|
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/format_string_parser'
|
15
|
+
require 'tempfile'
|
16
|
+
|
17
|
+
module Cosmos
|
18
|
+
|
19
|
+
describe PacketConfig 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 item is not defined" do
|
27
|
+
# Check for missing ITEM definitions
|
28
|
+
tf = Tempfile.new('unittest')
|
29
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
30
|
+
tf.puts ' FORMAT_STRING'
|
31
|
+
tf.close
|
32
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "No current item for FORMAT_STRING")
|
33
|
+
tf.unlink
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should complain if there are not enough parameters" do
|
37
|
+
tf = Tempfile.new('unittest')
|
38
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
39
|
+
tf.puts 'ITEM myitem 0 8 UINT "Test Item"'
|
40
|
+
tf.puts ' FORMAT_STRING'
|
41
|
+
tf.close
|
42
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Not enough parameters for FORMAT_STRING/)
|
43
|
+
tf.unlink
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should complain if there are too many parameters" do
|
47
|
+
tf = Tempfile.new('unittest')
|
48
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
49
|
+
tf.puts 'ITEM myitem 0 8 UINT "Test Item"'
|
50
|
+
tf.puts "FORMAT_STRING '0x%x' extra"
|
51
|
+
tf.close
|
52
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Too many parameters for FORMAT_STRING/)
|
53
|
+
tf.unlink
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should complain about invalid format strings" do
|
57
|
+
tf = Tempfile.new('unittest')
|
58
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
59
|
+
tf.puts ' ITEM item1 0 8 INT'
|
60
|
+
tf.puts ' FORMAT_STRING "%*s"'
|
61
|
+
tf.close
|
62
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid FORMAT_STRING specified for type INT: %*s")
|
63
|
+
tf.unlink
|
64
|
+
|
65
|
+
tf = Tempfile.new('unittest')
|
66
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
67
|
+
tf.puts ' ITEM item1 0 8 STRING'
|
68
|
+
tf.puts ' FORMAT_STRING "%d"'
|
69
|
+
tf.close
|
70
|
+
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid FORMAT_STRING specified for type STRING: %d")
|
71
|
+
tf.unlink
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should format integers" do
|
75
|
+
tf = Tempfile.new('unittest')
|
76
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
77
|
+
tf.puts ' ITEM item1 0 8 INT'
|
78
|
+
tf.puts ' FORMAT_STRING "d%d"'
|
79
|
+
tf.puts ' ITEM item2 0 8 UINT'
|
80
|
+
tf.puts ' FORMAT_STRING "u%u"'
|
81
|
+
tf.puts ' ITEM item3 0 8 UINT'
|
82
|
+
tf.puts ' FORMAT_STRING "0x%x"'
|
83
|
+
tf.close
|
84
|
+
@pc.process_file(tf.path, "TGT1")
|
85
|
+
@pc.telemetry["TGT1"]["PKT1"].buffer = "\x0a\x0b\x0c"
|
86
|
+
@pc.telemetry["TGT1"]["PKT1"].read("ITEM1",:FORMATTED).should eql "d10"
|
87
|
+
@pc.telemetry["TGT1"]["PKT1"].read("ITEM2",:FORMATTED).should eql "u10"
|
88
|
+
@pc.telemetry["TGT1"]["PKT1"].read("ITEM3",:FORMATTED).should eql "0xa"
|
89
|
+
tf.unlink
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should format floats" do
|
93
|
+
tf = Tempfile.new('unittest')
|
94
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
95
|
+
tf.puts ' ITEM item1 0 32 FLOAT'
|
96
|
+
tf.puts ' FORMAT_STRING "%3.3f"'
|
97
|
+
tf.close
|
98
|
+
@pc.process_file(tf.path, "TGT1")
|
99
|
+
@pc.telemetry["TGT1"]["PKT1"].write("ITEM1",12345.12345)
|
100
|
+
@pc.telemetry["TGT1"]["PKT1"].read("ITEM1",:FORMATTED).should eql "12345.123"
|
101
|
+
tf.unlink
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should format strings and blocks" do
|
105
|
+
tf = Tempfile.new('unittest')
|
106
|
+
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
107
|
+
tf.puts ' ITEM item1 0 32 STRING'
|
108
|
+
tf.puts ' FORMAT_STRING "String: %s"'
|
109
|
+
tf.puts ' ITEM item2 0 32 BLOCK'
|
110
|
+
tf.puts ' FORMAT_STRING "Block: %s"'
|
111
|
+
tf.close
|
112
|
+
@pc.process_file(tf.path, "TGT1")
|
113
|
+
@pc.telemetry["TGT1"]["PKT1"].write("ITEM1","HI")
|
114
|
+
@pc.telemetry["TGT1"]["PKT1"].read("ITEM1",:FORMATTED).should eql "String: HI"
|
115
|
+
@pc.telemetry["TGT1"]["PKT1"].write("ITEM2","\x00\x01\x02\x03")
|
116
|
+
@pc.telemetry["TGT1"]["PKT1"].read("ITEM2",:FORMATTED).should eql "Block: \x00\x01\x02\x03"
|
117
|
+
tf.unlink
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|