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.
- checksums.yaml +4 -4
- data/Gemfile +3 -0
- data/Manifest.txt +17 -1
- data/autohotkey/tools/test_runner2.ahk +1 -0
- data/autohotkey/tools/tlm_grapher.ahk +13 -1
- data/data/crc.txt +39 -30
- data/demo/config/data/crc.txt +3 -3
- data/demo/config/targets/TEMPLATED/lib/templated_interface.rb +3 -1
- data/demo/config/tools/cmd_tlm_server/cmd_tlm_server.txt +7 -1
- data/demo/config/tools/cmd_tlm_server/cmd_tlm_server2.txt +6 -1
- data/lib/cosmos.rb +2 -2
- data/lib/cosmos/gui/dialogs/about_dialog.rb +18 -5
- data/lib/cosmos/gui/dialogs/tlm_details_dialog.rb +0 -7
- data/lib/cosmos/gui/line_graph/overview_graph.rb +12 -2
- data/lib/cosmos/gui/utilities/script_module_gui.rb +11 -3
- data/lib/cosmos/interfaces/interface.rb +12 -0
- data/lib/cosmos/interfaces/stream_interface.rb +1 -21
- data/lib/cosmos/interfaces/tcpip_server_interface.rb +10 -0
- data/lib/cosmos/io/json_drb_object.rb +75 -56
- data/lib/cosmos/io/tcpip_server.rb +1 -11
- data/lib/cosmos/packet_logs.rb +1 -0
- data/lib/cosmos/packet_logs/ccsds_log_reader.rb +103 -0
- data/lib/cosmos/packets/packet.rb +70 -1
- data/lib/cosmos/packets/packet_config.rb +59 -611
- data/lib/cosmos/packets/parsers/format_string_parser.rb +58 -0
- data/lib/cosmos/packets/parsers/limits_parser.rb +146 -0
- data/lib/cosmos/packets/parsers/limits_response_parser.rb +52 -0
- data/lib/cosmos/packets/parsers/macro_parser.rb +116 -0
- data/lib/cosmos/packets/parsers/packet_item_parser.rb +215 -0
- data/lib/cosmos/packets/parsers/packet_parser.rb +123 -0
- data/lib/cosmos/packets/parsers/processor_parser.rb +63 -0
- data/lib/cosmos/packets/parsers/state_parser.rb +116 -0
- data/lib/cosmos/packets/structure.rb +59 -22
- data/lib/cosmos/packets/structure_item.rb +1 -1
- data/lib/cosmos/script/script.rb +4 -5
- data/lib/cosmos/streams/serial_stream.rb +5 -0
- data/lib/cosmos/streams/stream.rb +8 -2
- data/lib/cosmos/streams/stream_protocol.rb +1 -0
- data/lib/cosmos/streams/tcpip_client_stream.rb +37 -7
- data/lib/cosmos/streams/tcpip_socket_stream.rb +9 -6
- data/lib/cosmos/system/target.rb +3 -6
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +57 -48
- data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +7 -3
- data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +1 -1
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_realtime_thread.rb +7 -1
- data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +1 -2
- data/lib/cosmos/top_level.rb +22 -11
- data/lib/cosmos/utilities/message_log.rb +14 -9
- data/lib/cosmos/version.rb +5 -5
- data/spec/interfaces/cmd_tlm_server_interface_spec.rb +16 -16
- data/spec/interfaces/linc_interface_spec.rb +3 -0
- data/spec/interfaces/tcpip_client_interface_spec.rb +1 -0
- data/spec/interfaces/tcpip_server_interface_spec.rb +9 -0
- data/spec/io/json_drb_object_spec.rb +1 -1
- data/spec/io/serial_driver_spec.rb +0 -1
- data/spec/packet_logs/packet_log_writer_spec.rb +5 -3
- data/spec/packets/packet_config_spec.rb +22 -837
- data/spec/packets/packet_item_spec.rb +10 -10
- data/spec/packets/packet_spec.rb +239 -1
- data/spec/packets/parsers/format_string_parser_spec.rb +122 -0
- data/spec/packets/parsers/limits_parser_spec.rb +282 -0
- data/spec/packets/parsers/limits_response_parser_spec.rb +149 -0
- data/spec/packets/parsers/macro_parser_spec.rb +184 -0
- data/spec/packets/parsers/packet_item_parser_spec.rb +306 -0
- data/spec/packets/parsers/packet_parser_spec.rb +99 -0
- data/spec/packets/parsers/processor_parser_spec.rb +114 -0
- data/spec/packets/parsers/state_parser_spec.rb +156 -0
- data/spec/packets/structure_item_spec.rb +14 -14
- data/spec/packets/structure_spec.rb +162 -16
- data/spec/streams/fixed_stream_protocol_spec.rb +7 -4
- data/spec/streams/length_stream_protocol_spec.rb +3 -0
- data/spec/streams/preidentified_stream_protocol_spec.rb +3 -0
- data/spec/streams/serial_stream_spec.rb +12 -0
- data/spec/streams/stream_protocol_spec.rb +14 -0
- data/spec/streams/stream_spec.rb +1 -0
- data/spec/streams/tcpip_client_stream_spec.rb +3 -0
- data/spec/streams/tcpip_socket_stream_spec.rb +15 -3
- data/spec/streams/template_stream_protocol_spec.rb +5 -0
- data/spec/streams/terminated_stream_protocol_spec.rb +4 -0
- data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +21 -1
- data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +1 -1
- data/spec/tools/cmd_tlm_server/interfaces_spec.rb +1 -1
- metadata +19 -3
|
@@ -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
|