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,282 @@
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/limits_parser'
15
+ require 'tempfile'
16
+
17
+ module Cosmos
18
+
19
+ describe LimitsParser do
20
+
21
+ describe "parse" do
22
+ before(:each) do
23
+ @pc = PacketConfig.new
24
+ end
25
+
26
+ it "raises if a current item is not defined" do
27
+ tf = Tempfile.new('unittest')
28
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
29
+ tf.puts ' LIMITS mylimits 1 ENABLED 0 10 20 30 12 18'
30
+ tf.close
31
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "No current item for LIMITS")
32
+ tf.unlink
33
+ end
34
+
35
+ it "raises if there are not enough parameters" do
36
+ tf = Tempfile.new('unittest')
37
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
38
+ tf.puts ' ITEM myitem 0 8 UINT "Test Item"'
39
+ tf.puts ' LIMITS DEFAULT 1 ENABLED 0 10 20 30 12'
40
+ tf.close
41
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Must give both a green low and green high/)
42
+ tf.unlink
43
+
44
+ tf = Tempfile.new('unittest')
45
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
46
+ tf.puts ' ITEM myitem 0 8 UINT "Test Item"'
47
+ tf.puts ' LIMITS DEFAULT 1 ENABLED 0 10 20'
48
+ tf.close
49
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Not enough parameters for LIMITS/)
50
+ tf.unlink
51
+ end
52
+
53
+ it "raises if there are too many parameters" do
54
+ tf = Tempfile.new('unittest')
55
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
56
+ tf.puts ' ITEM myitem 0 8 UINT "Test Item"'
57
+ tf.puts ' LIMITS DEFAULT 1 ENABLED 0 10 20 30 12 18 20'
58
+ tf.close
59
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Too many parameters for LIMITS/)
60
+ tf.unlink
61
+ end
62
+
63
+ it "raises if applied to a command PARAMETER" do
64
+ tf = Tempfile.new('unittest')
65
+ tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Packet"'
66
+ tf.puts ' APPEND_PARAMETER item1 16 UINT 0 0 0 "Item"'
67
+ tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 7 3 5'
68
+ tf.close
69
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /LIMITS only applies to telemetry items/)
70
+ tf.unlink
71
+ end
72
+
73
+ it "raises if a DEFAULT limits set isn't defined" do
74
+ tf = Tempfile.new('unittest')
75
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
76
+ tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
77
+ tf.puts ' LIMITS TVAC 3 ENABLED 1 2 6 7 3 5'
78
+ tf.close
79
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /DEFAULT limits set must be defined/)
80
+ tf.unlink
81
+ end
82
+
83
+ it "sets a warning if a new limits set persistence isn't consistent with DEFAULT" do
84
+ tf = Tempfile.new('unittest')
85
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
86
+ tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
87
+ tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 7 3 5'
88
+ tf.puts ' LIMITS TVAC 1 DISABLED 1 2 6 7 3 5'
89
+ tf.close
90
+ @pc.process_file(tf.path, "TGT1")
91
+ expect(@pc.warnings[-1]).to match(/persistence setting conflict with DEFAULT/)
92
+ tf.unlink
93
+ end
94
+
95
+ it "sets a warning if a new limits set enable isn't consistent with DEFAULT" do
96
+ tf = Tempfile.new('unittest')
97
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
98
+ tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
99
+ tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 7 3 5'
100
+ tf.puts ' LIMITS TVAC 3 DISABLED 1 2 6 7 3 5'
101
+ tf.close
102
+ @pc.process_file(tf.path, "TGT1")
103
+ expect(@pc.warnings[-1]).to match(/enable setting conflict with DEFAULT/)
104
+ tf.unlink
105
+ end
106
+
107
+ it "records 2 warnings if a new limits set persistence and enable isn't consistent with DEFAULT" do
108
+ tf = Tempfile.new('unittest')
109
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
110
+ tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
111
+ tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 7 3 5'
112
+ tf.puts ' LIMITS TVAC 1 DISABLED 1 2 6 7 3 5'
113
+ tf.close
114
+ @pc.process_file(tf.path, "TGT1")
115
+ expect(@pc.warnings.length).to eql 2
116
+ tf.unlink
117
+ end
118
+
119
+ it "raises if the second parameter isn't a number" do
120
+ tf = Tempfile.new('unittest')
121
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
122
+ tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
123
+ tf.puts ' LIMITS DEFAULT TRUE ENABLED 1 2 6 7 3 5'
124
+ tf.close
125
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Persistence must be an integer/)
126
+ tf.unlink
127
+ end
128
+
129
+ it "raises if the third parameter isn't ENABLED or DISABLED" do
130
+ tf = Tempfile.new('unittest')
131
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
132
+ tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
133
+ tf.puts ' LIMITS DEFAULT 3 TRUE 1 2 6 7 3 5'
134
+ tf.close
135
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Initial LIMITS state must be ENABLED or DISABLED/)
136
+ tf.unlink
137
+ end
138
+
139
+ it "raises if the fourth through ninth parameter aren't numbers'" do
140
+ msgs = ['','','','','red low','yellow low','yellow high','red high','green low','green high']
141
+ (4..9).each do |index|
142
+ tf = Tempfile.new('unittest')
143
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
144
+ tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
145
+ limits = %w(LIMITS DEFAULT 3 ENABLED 1 2 6 7 3 5)
146
+ limits[index] = 'X'
147
+ tf.puts limits.join(' ')
148
+ tf.close
149
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Invalid #{msgs[index]} limit value/)
150
+ tf.unlink
151
+ end
152
+ end
153
+
154
+ it "raises if the 4 limits are out of order" do
155
+ tf = Tempfile.new('unittest')
156
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
157
+ tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
158
+ tf.puts ' LIMITS DEFAULT 3 ENABLED 2 1 3 4'
159
+ tf.close
160
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure yellow limits are within red limits.")
161
+ tf.unlink
162
+
163
+ tf = Tempfile.new('unittest')
164
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
165
+ tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
166
+ tf.puts ' LIMITS DEFAULT 3 ENABLED 1 5 3 7'
167
+ tf.close
168
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure yellow limits are within red limits.")
169
+ tf.unlink
170
+
171
+ tf = Tempfile.new('unittest')
172
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
173
+ tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
174
+ tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 5 4'
175
+ tf.close
176
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure yellow limits are within red limits.")
177
+ tf.unlink
178
+
179
+ tf = Tempfile.new('unittest')
180
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
181
+ tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
182
+ tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 3 0'
183
+ tf.close
184
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure yellow limits are within red limits.")
185
+ tf.unlink
186
+ end
187
+
188
+ it "raises if the 6 limits are out of order" do
189
+ tf = Tempfile.new('unittest')
190
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
191
+ tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
192
+ tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 7 0 5'
193
+ tf.close
194
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure green limits are within yellow limits.")
195
+ tf.unlink
196
+
197
+ tf = Tempfile.new('unittest')
198
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
199
+ tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
200
+ tf.puts ' LIMITS DEFAULT 3 ENABLED 1 3 6 7 2 5'
201
+ tf.close
202
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure green limits are within yellow limits.")
203
+ tf.unlink
204
+
205
+ tf = Tempfile.new('unittest')
206
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
207
+ tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
208
+ tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 8 3 7'
209
+ tf.close
210
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure green limits are within yellow limits.")
211
+ tf.unlink
212
+
213
+ tf = Tempfile.new('unittest')
214
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
215
+ tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
216
+ tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 8 3 9'
217
+ tf.close
218
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure green limits are within yellow limits.")
219
+ tf.unlink
220
+
221
+ tf = Tempfile.new('unittest')
222
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
223
+ tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
224
+ tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 8 4 3'
225
+ tf.close
226
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure green limits are within yellow limits.")
227
+ tf.unlink
228
+ end
229
+
230
+ it "should take 4 limits values" do
231
+ tf = Tempfile.new('unittest')
232
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
233
+ tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
234
+ tf.puts ' LIMITS DEFAULT 1 ENABLED 1 2 6 7'
235
+ tf.close
236
+ @pc.process_file(tf.path, "TGT1")
237
+ item = @pc.telemetry["TGT1"]["PKT1"].items["ITEM1"]
238
+ item.limits.values[:DEFAULT].should_not be_nil
239
+ @pc.telemetry["TGT1"]["PKT1"].buffer = "\x04"
240
+ @pc.telemetry["TGT1"]["PKT1"].enable_limits("ITEM1")
241
+ @pc.telemetry["TGT1"]["PKT1"].check_limits
242
+ item.limits.state.should eql :GREEN
243
+ @pc.telemetry["TGT1"]["PKT1"].limits_items.should eql [item]
244
+ tf.unlink
245
+ end
246
+
247
+ it "should take 6 limits values" do
248
+ tf = Tempfile.new('unittest')
249
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
250
+ tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
251
+ tf.puts ' LIMITS DEFAULT 1 ENABLED 1 2 6 7 3 5'
252
+ tf.close
253
+ @pc.process_file(tf.path, "TGT1")
254
+ item = @pc.telemetry["TGT1"]["PKT1"].items["ITEM1"]
255
+ item.limits.values[:DEFAULT].should_not be_nil
256
+ @pc.telemetry["TGT1"]["PKT1"].buffer = "\x04"
257
+ @pc.telemetry["TGT1"]["PKT1"].enable_limits("ITEM1")
258
+ @pc.telemetry["TGT1"]["PKT1"].check_limits
259
+ item.limits.state.should eql :BLUE
260
+ @pc.telemetry["TGT1"]["PKT1"].limits_items.should eql [item]
261
+ tf.unlink
262
+ end
263
+
264
+ it "create multiple limits sets" do
265
+ tf = Tempfile.new('unittest')
266
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
267
+ tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
268
+ tf.puts ' LIMITS DEFAULT 1 ENABLED 1 2 6 7'
269
+ tf.puts ' LIMITS TVAC 1 ENABLED 1 2 6 7'
270
+ tf.close
271
+ @pc.process_file(tf.path, "TGT1")
272
+ item = @pc.telemetry["TGT1"]["PKT1"].items["ITEM1"]
273
+ expect(item.limits.values.length).to eql 2
274
+ expect(item.limits.values[:DEFAULT]).to_not be_nil
275
+ expect(item.limits.values[:TVAC]).to_not be_nil
276
+ tf.unlink
277
+ end
278
+
279
+ end
280
+
281
+ end
282
+ end
@@ -0,0 +1,149 @@
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/limits_response_parser'
15
+ require 'tempfile'
16
+
17
+ module Cosmos
18
+
19
+ describe PacketConfig do
20
+
21
+ describe "parse" 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
+ tf = Tempfile.new('unittest')
28
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
29
+ tf.puts ' LIMITS_RESPONSE'
30
+ tf.close
31
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "No current item for LIMITS_RESPONSE")
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 'ITEM myitem 0 8 UINT "Test Item"'
39
+ tf.puts ' LIMITS_RESPONSE'
40
+ tf.close
41
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Not enough parameters for LIMITS_RESPONSE/)
42
+ tf.unlink
43
+ end
44
+
45
+ it "should complain if applied to a command PARAMETER" do
46
+ tf = Tempfile.new('unittest')
47
+ tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Packet"'
48
+ tf.puts ' APPEND_PARAMETER item1 16 UINT 0 0 0 "Item"'
49
+ tf.puts ' LIMITS_RESPONSE test.rb'
50
+ tf.close
51
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "LIMITS_RESPONSE only applies to telemetry items")
52
+ tf.unlink
53
+ end
54
+
55
+ it "should complain about missing response file" do
56
+ filename = File.join(File.dirname(__FILE__), "../../test_only.rb")
57
+ File.delete(filename) if File.exist?(filename)
58
+ @pc = PacketConfig.new
59
+
60
+ tf = Tempfile.new('unittest')
61
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
62
+ tf.puts ' ITEM item1 0 16 INT "Integer Item"'
63
+ tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 7 3 5'
64
+ tf.puts ' LIMITS_RESPONSE test_only.rb'
65
+ tf.close
66
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /TestOnly class not found/)
67
+ tf.unlink
68
+ end
69
+
70
+ it "should complain about a non Cosmos::LimitsResponse class" do
71
+ filename = File.join(File.dirname(__FILE__), "../../limits_response1.rb")
72
+ File.open(filename, 'w') do |file|
73
+ file.puts "class LimitsResponse1"
74
+ file.puts " def call(target_name, packet_name, item, old_limits_state, new_limits_state)"
75
+ file.puts " end"
76
+ file.puts "end"
77
+ end
78
+ load 'limits_response1.rb'
79
+ File.delete(filename) if File.exist?(filename)
80
+
81
+ tf = Tempfile.new('unittest')
82
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
83
+ tf.puts ' ITEM item1 0 16 INT "Integer Item"'
84
+ tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 7 3 5'
85
+ tf.puts ' LIMITS_RESPONSE limits_response1.rb'
86
+ tf.close
87
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /response must be a Cosmos::LimitsResponse but is a LimitsResponse1/)
88
+ tf.unlink
89
+ end
90
+
91
+ it "should set the response" do
92
+ filename = File.join(File.dirname(__FILE__), "../../limits_response2.rb")
93
+ File.open(filename, 'w') do |file|
94
+ file.puts "require 'cosmos/packets/limits_response'"
95
+ file.puts "class LimitsResponse2 < Cosmos::LimitsResponse"
96
+ file.puts " def call(target_name, packet_name, item, old_limits_state, new_limits_state)"
97
+ file.puts " puts \"\#{target_name} \#{packet_name} \#{item.name} \#{old_limits_state} \#{new_limits_state}\""
98
+ file.puts " end"
99
+ file.puts "end"
100
+ end
101
+ load 'limits_response2.rb'
102
+
103
+ tf = Tempfile.new('unittest')
104
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
105
+ tf.puts ' ITEM item1 0 16 INT "Integer Item"'
106
+ tf.puts ' LIMITS DEFAULT 1 ENABLED 1 2 6 7 3 5'
107
+ tf.puts ' LIMITS_RESPONSE limits_response2.rb'
108
+ tf.close
109
+ @pc.process_file(tf.path, "TGT1")
110
+ pkt = @pc.telemetry["TGT1"]["PKT1"]
111
+ pkt.get_item("ITEM1").limits.response.class.should eql LimitsResponse2
112
+
113
+ File.delete(filename) if File.exist?(filename)
114
+ tf.unlink
115
+ end
116
+
117
+ it "should call the response with parameters" do
118
+ filename = File.join(File.dirname(__FILE__), "../../limits_response2.rb")
119
+ File.open(filename, 'w') do |file|
120
+ file.puts "require 'cosmos/packets/limits_response'"
121
+ file.puts "class LimitsResponse2 < Cosmos::LimitsResponse"
122
+ file.puts " def initialize(val)"
123
+ file.puts " puts \"initialize: \#{val}\""
124
+ file.puts " end"
125
+ file.puts " def call(target_name, packet_name, item, old_limits_state, new_limits_state)"
126
+ file.puts " puts \"\#{target_name} \#{packet_name} \#{item.name} \#{old_limits_state} \#{new_limits_state}\""
127
+ file.puts " end"
128
+ file.puts "end"
129
+ end
130
+ load 'limits_response2.rb'
131
+
132
+ tf = Tempfile.new('unittest')
133
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
134
+ tf.puts ' ITEM item1 0 16 INT "Integer Item"'
135
+ tf.puts ' LIMITS DEFAULT 1 ENABLED 1 2 6 7 3 5'
136
+ tf.puts ' LIMITS_RESPONSE limits_response2.rb 2'
137
+ tf.close
138
+ capture_io do |stdout|
139
+ @pc.process_file(tf.path, "TGT1")
140
+ stdout.string.should eql "initialize: 2\n"
141
+ end
142
+
143
+ File.delete(filename) if File.exist?(filename)
144
+ tf.unlink
145
+ end
146
+
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,184 @@
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/macro_parser'
15
+ require 'tempfile'
16
+
17
+ module Cosmos
18
+
19
+ describe MacroParser do
20
+ before(:each) do
21
+ @pc = PacketConfig.new
22
+ end
23
+
24
+ describe "start" do
25
+ it "complains if a current packet is not defined" do
26
+ # Check for missing TELEMETRY line
27
+ tf = Tempfile.new('unittest')
28
+ tf.puts ' MACRO_APPEND_START'
29
+ tf.close
30
+ expect { @pc.process_file(tf.path, "SYSTEM") }.to raise_error(ConfigParser::Error, "No current packet for MACRO_APPEND_START")
31
+ end
32
+
33
+ it "complains if there are not enough parameters" do
34
+ tf = Tempfile.new('unittest')
35
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
36
+ tf.puts ' MACRO_APPEND_START'
37
+ tf.close
38
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Not enough parameters for MACRO_APPEND_START/)
39
+ tf.unlink
40
+ end
41
+
42
+ it "complains if there are too many parameters" do
43
+ tf = Tempfile.new('unittest')
44
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
45
+ tf.puts 'MACRO_APPEND_START 0 1 "%s_%d" extra'
46
+ tf.close
47
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Too many parameters for MACRO_APPEND_START/)
48
+ tf.unlink
49
+ end
50
+
51
+ it "complains if a previous START hasn't been closed" do
52
+ # Check for missing TELEMETRY line
53
+ tf = Tempfile.new('unittest')
54
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
55
+ tf.puts ' MACRO_APPEND_START 1 5'
56
+ tf.puts ' MACRO_APPEND_START 1 5'
57
+ tf.close
58
+ expect { @pc.process_file(tf.path, "SYSTEM") }.to raise_error(ConfigParser::Error, /First close the previous/)
59
+ end
60
+
61
+ it "swaps reverse ranges to be in order" do
62
+ tf = Tempfile.new('unittest')
63
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
64
+ tf.puts 'MACRO_APPEND_START 4 1' # <-- Note the reverse order
65
+ tf.puts 'APPEND_ITEM BIT 16 UINT "Setting #x"'
66
+ tf.puts ' STATE BAD 0 RED'
67
+ tf.puts ' STATE GOOD 1 GREEN'
68
+ tf.puts 'MACRO_APPEND_END'
69
+ tf.close
70
+ @pc.process_file(tf.path, "TGT1")
71
+ pkt = @pc.telemetry["TGT1"]["PKT1"]
72
+ expect(pkt.items.length).to eql 7 # 4 plus the RECEIVED_XXX items
73
+ expect(pkt.items.keys).to include('BIT1','BIT2','BIT3','BIT4')
74
+ expect(pkt.sorted_items[3].name).to eql 'BIT1'
75
+ expect(pkt.sorted_items[4].name).to eql 'BIT2'
76
+ expect(pkt.sorted_items[5].name).to eql 'BIT3'
77
+ expect(pkt.sorted_items[6].name).to eql 'BIT4'
78
+ limits_items = []
79
+ pkt.items.each do |name, item|
80
+ limits_items << item if name.include?('BIT')
81
+ end
82
+ expect(pkt.limits_items).to eql limits_items
83
+ tf.unlink
84
+ end
85
+ end
86
+
87
+ describe "end" do
88
+ it "complains if there are too many parameters" do
89
+ tf = Tempfile.new('unittest')
90
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
91
+ tf.puts 'MACRO_APPEND_START 0 1 "%s_%d"'
92
+ tf.puts 'MACRO_APPEND_END extra'
93
+ tf.close
94
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Too many parameters for MACRO_APPEND_END/)
95
+ tf.unlink
96
+ end
97
+
98
+ it "complains if there are no items in the macro" do
99
+ tf = Tempfile.new('unittest')
100
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
101
+ tf.puts 'MACRO_APPEND_START 0 1 "%s_%d"'
102
+ tf.puts 'MACRO_APPEND_END'
103
+ tf.close
104
+ expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /No items appended/)
105
+ tf.unlink
106
+ end
107
+ end
108
+
109
+ describe "add_item" do
110
+ it "adds items with states to the packet" do
111
+ tf = Tempfile.new('unittest')
112
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
113
+ tf.puts 'MACRO_APPEND_START 1 5'
114
+ tf.puts 'APPEND_ITEM BIT 16 UINT "Setting #x"'
115
+ tf.puts ' STATE BAD 0 RED'
116
+ tf.puts ' STATE GOOD 1 GREEN'
117
+ tf.puts 'MACRO_APPEND_END'
118
+ tf.close
119
+ @pc.process_file(tf.path, "TGT1")
120
+ pkt = @pc.telemetry["TGT1"]["PKT1"]
121
+ expect(pkt.items.length).to eql 8 # 5 plus the RECEIVED_XXX items
122
+ pkt.items.keys.should include('BIT1','BIT2','BIT3','BIT4','BIT5')
123
+ expect(pkt.sorted_items[3].name).to eql 'BIT1'
124
+ expect(pkt.sorted_items[4].name).to eql 'BIT2'
125
+ expect(pkt.sorted_items[5].name).to eql 'BIT3'
126
+ expect(pkt.sorted_items[6].name).to eql 'BIT4'
127
+ expect(pkt.sorted_items[7].name).to eql 'BIT5'
128
+ limits_items = []
129
+ pkt.items.each do |name, item|
130
+ limits_items << item if name.include?('BIT')
131
+ end
132
+ pkt.limits_items.should eql limits_items
133
+ tf.unlink
134
+ end
135
+
136
+ it "adds items with limits to the packet" do
137
+ tf = Tempfile.new('unittest')
138
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
139
+ tf.puts 'MACRO_APPEND_START 1 5'
140
+ tf.puts 'APPEND_ITEM BIT 16 UINT "Setting #x"'
141
+ tf.puts ' LIMITS DEFAULT 3 ENABLED 0 1 3 4'
142
+ tf.puts 'MACRO_APPEND_END'
143
+ tf.close
144
+ @pc.process_file(tf.path, "TGT1")
145
+ pkt = @pc.telemetry["TGT1"]["PKT1"]
146
+ expect(pkt.items.length).to eql 8 # 5 plus the RECEIVED_XXX items
147
+ expect(pkt.items.keys).to include('BIT1','BIT2','BIT3','BIT4','BIT5')
148
+ expect(pkt.limits_items.collect{|item| item.name}).to include('BIT1','BIT2','BIT3','BIT4','BIT5')
149
+ tf.unlink
150
+ end
151
+
152
+ it "adds array items to the packet" do
153
+ tf = Tempfile.new('unittest')
154
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
155
+ tf.puts 'MACRO_APPEND_START 1 5'
156
+ tf.puts 'APPEND_ARRAY_ITEM BIT 16 INT 64 "Int Array Parameter"'
157
+ tf.puts 'MACRO_APPEND_END'
158
+ tf.close
159
+ @pc.process_file(tf.path, "TGT1")
160
+ pkt = @pc.telemetry["TGT1"]["PKT1"]
161
+ expect(pkt.items.length).to eql 8 # 5 plus the RECEIVED_XXX items
162
+ pkt.items.keys.should include('BIT1','BIT2','BIT3','BIT4','BIT5')
163
+ pkt.limits_items.should be_empty
164
+ tf.unlink
165
+ end
166
+
167
+ it "works with printf format strings" do
168
+ tf = Tempfile.new('unittest')
169
+ tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
170
+ tf.puts 'MACRO_APPEND_START 8 12 "%02d_%s"'
171
+ tf.puts 'APPEND_ID_ITEM BIT 16 UINT 0 "Setting #x"'
172
+ tf.puts 'MACRO_APPEND_END'
173
+ tf.close
174
+ @pc.process_file(tf.path, "TGT1")
175
+ pkt = @pc.telemetry["TGT1"]["PKT1"]
176
+ expect(pkt.items.length).to eql 8 # 5 plus the RECEIVED_XXX items
177
+ pkt.items.keys.should include('08_BIT','09_BIT','10_BIT','11_BIT','12_BIT')
178
+ pkt.limits_items.should be_empty
179
+ tf.unlink
180
+ end
181
+
182
+ end
183
+ end
184
+ end