cosmos 3.1.2 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -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