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
@@ -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