cosmos 3.1.2 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/Manifest.txt +17 -1
  4. data/autohotkey/tools/test_runner2.ahk +1 -0
  5. data/autohotkey/tools/tlm_grapher.ahk +13 -1
  6. data/data/crc.txt +39 -30
  7. data/demo/config/data/crc.txt +3 -3
  8. data/demo/config/targets/TEMPLATED/lib/templated_interface.rb +3 -1
  9. data/demo/config/tools/cmd_tlm_server/cmd_tlm_server.txt +7 -1
  10. data/demo/config/tools/cmd_tlm_server/cmd_tlm_server2.txt +6 -1
  11. data/lib/cosmos.rb +2 -2
  12. data/lib/cosmos/gui/dialogs/about_dialog.rb +18 -5
  13. data/lib/cosmos/gui/dialogs/tlm_details_dialog.rb +0 -7
  14. data/lib/cosmos/gui/line_graph/overview_graph.rb +12 -2
  15. data/lib/cosmos/gui/utilities/script_module_gui.rb +11 -3
  16. data/lib/cosmos/interfaces/interface.rb +12 -0
  17. data/lib/cosmos/interfaces/stream_interface.rb +1 -21
  18. data/lib/cosmos/interfaces/tcpip_server_interface.rb +10 -0
  19. data/lib/cosmos/io/json_drb_object.rb +75 -56
  20. data/lib/cosmos/io/tcpip_server.rb +1 -11
  21. data/lib/cosmos/packet_logs.rb +1 -0
  22. data/lib/cosmos/packet_logs/ccsds_log_reader.rb +103 -0
  23. data/lib/cosmos/packets/packet.rb +70 -1
  24. data/lib/cosmos/packets/packet_config.rb +59 -611
  25. data/lib/cosmos/packets/parsers/format_string_parser.rb +58 -0
  26. data/lib/cosmos/packets/parsers/limits_parser.rb +146 -0
  27. data/lib/cosmos/packets/parsers/limits_response_parser.rb +52 -0
  28. data/lib/cosmos/packets/parsers/macro_parser.rb +116 -0
  29. data/lib/cosmos/packets/parsers/packet_item_parser.rb +215 -0
  30. data/lib/cosmos/packets/parsers/packet_parser.rb +123 -0
  31. data/lib/cosmos/packets/parsers/processor_parser.rb +63 -0
  32. data/lib/cosmos/packets/parsers/state_parser.rb +116 -0
  33. data/lib/cosmos/packets/structure.rb +59 -22
  34. data/lib/cosmos/packets/structure_item.rb +1 -1
  35. data/lib/cosmos/script/script.rb +4 -5
  36. data/lib/cosmos/streams/serial_stream.rb +5 -0
  37. data/lib/cosmos/streams/stream.rb +8 -2
  38. data/lib/cosmos/streams/stream_protocol.rb +1 -0
  39. data/lib/cosmos/streams/tcpip_client_stream.rb +37 -7
  40. data/lib/cosmos/streams/tcpip_socket_stream.rb +9 -6
  41. data/lib/cosmos/system/target.rb +3 -6
  42. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +57 -48
  43. data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +7 -3
  44. data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +1 -1
  45. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_realtime_thread.rb +7 -1
  46. data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +1 -2
  47. data/lib/cosmos/top_level.rb +22 -11
  48. data/lib/cosmos/utilities/message_log.rb +14 -9
  49. data/lib/cosmos/version.rb +5 -5
  50. data/spec/interfaces/cmd_tlm_server_interface_spec.rb +16 -16
  51. data/spec/interfaces/linc_interface_spec.rb +3 -0
  52. data/spec/interfaces/tcpip_client_interface_spec.rb +1 -0
  53. data/spec/interfaces/tcpip_server_interface_spec.rb +9 -0
  54. data/spec/io/json_drb_object_spec.rb +1 -1
  55. data/spec/io/serial_driver_spec.rb +0 -1
  56. data/spec/packet_logs/packet_log_writer_spec.rb +5 -3
  57. data/spec/packets/packet_config_spec.rb +22 -837
  58. data/spec/packets/packet_item_spec.rb +10 -10
  59. data/spec/packets/packet_spec.rb +239 -1
  60. data/spec/packets/parsers/format_string_parser_spec.rb +122 -0
  61. data/spec/packets/parsers/limits_parser_spec.rb +282 -0
  62. data/spec/packets/parsers/limits_response_parser_spec.rb +149 -0
  63. data/spec/packets/parsers/macro_parser_spec.rb +184 -0
  64. data/spec/packets/parsers/packet_item_parser_spec.rb +306 -0
  65. data/spec/packets/parsers/packet_parser_spec.rb +99 -0
  66. data/spec/packets/parsers/processor_parser_spec.rb +114 -0
  67. data/spec/packets/parsers/state_parser_spec.rb +156 -0
  68. data/spec/packets/structure_item_spec.rb +14 -14
  69. data/spec/packets/structure_spec.rb +162 -16
  70. data/spec/streams/fixed_stream_protocol_spec.rb +7 -4
  71. data/spec/streams/length_stream_protocol_spec.rb +3 -0
  72. data/spec/streams/preidentified_stream_protocol_spec.rb +3 -0
  73. data/spec/streams/serial_stream_spec.rb +12 -0
  74. data/spec/streams/stream_protocol_spec.rb +14 -0
  75. data/spec/streams/stream_spec.rb +1 -0
  76. data/spec/streams/tcpip_client_stream_spec.rb +3 -0
  77. data/spec/streams/tcpip_socket_stream_spec.rb +15 -3
  78. data/spec/streams/template_stream_protocol_spec.rb +5 -0
  79. data/spec/streams/terminated_stream_protocol_spec.rb +4 -0
  80. data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +21 -1
  81. data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +1 -1
  82. data/spec/tools/cmd_tlm_server/interfaces_spec.rb +1 -1
  83. 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, "test: default must be an Array but is a Fixnum")
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, "test: default must be a Integer but is a Float")
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, "test: default must be a Float but is a String")
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, "test: default must be a String but is a Fixnum")
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, "test: default must be a String but is a Float")
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, "test: minimum must be a Integer but is a Float")
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, "test: maximum must be a Integer but is a Float")
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, "test: minimum must be a Float but is a String")
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, "test: maximum must be a Float but is a Rational")
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 "test"
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
@@ -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 "should reset the packet" do
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