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
|
@@ -32,6 +32,7 @@ module Cosmos
|
|
|
32
32
|
@filename = ''
|
|
33
33
|
@file = nil
|
|
34
34
|
@start_time = nil
|
|
35
|
+
@mutex = Mutex.new
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
# Ensures the log file is opened and ready to write. It then writes the
|
|
@@ -39,34 +40,38 @@ module Cosmos
|
|
|
39
40
|
#
|
|
40
41
|
# @param message [String] Message to write to the log
|
|
41
42
|
def write(message)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
@mutex.synchronize do
|
|
44
|
+
if @file.nil? or @file.closed? or (not File.exist?(@filename))
|
|
45
|
+
start(false)
|
|
46
|
+
end
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
#@file.flush
|
|
48
|
+
@file.write(message)
|
|
49
|
+
end
|
|
49
50
|
end
|
|
50
51
|
|
|
51
52
|
# Closes the message log and marks it read only
|
|
52
|
-
def stop
|
|
53
|
+
def stop(take_mutex = true)
|
|
54
|
+
@mutex.lock if take_mutex
|
|
53
55
|
if @file and not @file.closed?
|
|
54
56
|
@file.close
|
|
55
57
|
Cosmos.set_working_dir do
|
|
56
58
|
File.chmod(0444, @filename)
|
|
57
59
|
end
|
|
58
60
|
end
|
|
61
|
+
@mutex.unlock if take_mutex
|
|
59
62
|
end
|
|
60
63
|
|
|
61
64
|
# Creates a new message log and sets the filename
|
|
62
|
-
def start
|
|
65
|
+
def start(take_mutex = true)
|
|
66
|
+
@mutex.lock if take_mutex
|
|
63
67
|
# Prevent starting files too fast
|
|
64
68
|
sleep(0.1) until !File.exist?(File.join(@log_dir, File.build_timestamped_filename([@tool_name, 'messages'])))
|
|
65
|
-
stop()
|
|
69
|
+
stop(false)
|
|
66
70
|
Cosmos.set_working_dir do
|
|
67
71
|
@filename = File.join(@log_dir, File.build_timestamped_filename([@tool_name, 'messages']))
|
|
68
72
|
@file = File.open(@filename, 'a')
|
|
69
73
|
end
|
|
74
|
+
@mutex.unlock if take_mutex
|
|
70
75
|
end
|
|
71
76
|
|
|
72
77
|
end # class MessageLog
|
data/lib/cosmos/version.rb
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# encoding: ascii-8bit
|
|
2
2
|
|
|
3
|
-
COSMOS_VERSION = '3.
|
|
3
|
+
COSMOS_VERSION = '3.2.0'
|
|
4
4
|
module Cosmos
|
|
5
5
|
module Version
|
|
6
6
|
MAJOR = '3'
|
|
7
|
-
MINOR = '
|
|
8
|
-
PATCH = '
|
|
9
|
-
BUILD = '
|
|
7
|
+
MINOR = '2'
|
|
8
|
+
PATCH = '0'
|
|
9
|
+
BUILD = '29c04013a08ebeab57b88412820e0cd79782c49f'
|
|
10
10
|
end
|
|
11
|
-
VERSION = '3.
|
|
11
|
+
VERSION = '3.2.0'
|
|
12
12
|
end
|
|
@@ -44,31 +44,31 @@ module Cosmos
|
|
|
44
44
|
sleep 0.1 # Give the server time to really stop all the Threads
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
specify { @ctsi.methods.
|
|
47
|
+
specify { expect(@ctsi.methods).to include(:cmd) }
|
|
48
48
|
|
|
49
49
|
describe "connect, connected?, disconnect" do
|
|
50
|
-
it "
|
|
50
|
+
it "subscribes to the server" do
|
|
51
51
|
expect { @ctsi.connect }.to_not raise_error
|
|
52
|
-
@ctsi.connected
|
|
52
|
+
expect(@ctsi.connected?).to be true
|
|
53
53
|
expect { @ctsi.disconnect}.to_not raise_error
|
|
54
|
-
@ctsi.connected
|
|
54
|
+
expect(@ctsi.connected?).to be false
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
describe "write_raw_allowed?" do
|
|
59
|
-
it "
|
|
60
|
-
@ctsi.write_raw_allowed
|
|
59
|
+
it "returns false" do
|
|
60
|
+
expect(@ctsi.write_raw_allowed?).to be false
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
describe "write_raw" do
|
|
65
|
-
it "
|
|
65
|
+
it "raises an error" do
|
|
66
66
|
expect { @ctsi.write_raw(nil) }.to raise_error(/write_raw not implemented/)
|
|
67
67
|
end
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
describe "read" do
|
|
71
|
-
it "
|
|
71
|
+
it "returns the COSMOS VERSION packet and then COSMOS LIMITS_CHANGE" do
|
|
72
72
|
@ctsi.connect
|
|
73
73
|
|
|
74
74
|
pkt = Packet.new("TGT","PKT")
|
|
@@ -78,25 +78,25 @@ module Cosmos
|
|
|
78
78
|
@cts.limits_change_callback(pkt, pi, :RED, 100, true)
|
|
79
79
|
|
|
80
80
|
result = @ctsi.read
|
|
81
|
-
result.read('CTDB').
|
|
81
|
+
expect(result.read('CTDB')).to eql "Demo Version"
|
|
82
82
|
|
|
83
83
|
result = @ctsi.read
|
|
84
|
-
result.read('TARGET').
|
|
85
|
-
result.read('PACKET').
|
|
86
|
-
result.read('ITEM').
|
|
87
|
-
result.read('OLD_STATE').
|
|
88
|
-
result.read('NEW_STATE').
|
|
84
|
+
expect(result.read('TARGET')).to eql "TGT"
|
|
85
|
+
expect(result.read('PACKET')).to eql "PKT"
|
|
86
|
+
expect(result.read('ITEM')).to eql "ITEM"
|
|
87
|
+
expect(result.read('OLD_STATE')).to eql "RED"
|
|
88
|
+
expect(result.read('NEW_STATE')).to eql "GREEN"
|
|
89
89
|
end
|
|
90
90
|
end
|
|
91
91
|
|
|
92
92
|
describe "write" do
|
|
93
|
-
it "
|
|
93
|
+
it "raises an error if the packet is not identified" do
|
|
94
94
|
pkt = Packet.new("COSMOS","STARTLOGGING")
|
|
95
95
|
pkt.buffer = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
96
96
|
expect { @ctsi.write(pkt) }.to raise_error(/Unknown command/)
|
|
97
97
|
end
|
|
98
98
|
|
|
99
|
-
it "
|
|
99
|
+
it "raises an error if the command is not recognized" do
|
|
100
100
|
pkt = Packet.new("COSMOS","DOSOMETHING")
|
|
101
101
|
pkt.buffer = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
102
102
|
expect { @ctsi.write(pkt) }.to raise_error(/Unknown command/)
|
|
@@ -22,6 +22,7 @@ module Cosmos
|
|
|
22
22
|
describe "connect" do
|
|
23
23
|
it "should pass a new TcpipClientStream to the stream protocol" do
|
|
24
24
|
stream = double("stream")
|
|
25
|
+
allow(stream).to receive(:connect)
|
|
25
26
|
expect(TcpipClientStream).to receive(:new) { stream }
|
|
26
27
|
expect(stream).to receive(:connected?) { true }
|
|
27
28
|
expect(stream).to receive(:raw_logger_pair=) { nil }
|
|
@@ -36,6 +37,7 @@ module Cosmos
|
|
|
36
37
|
describe "write" do
|
|
37
38
|
before(:each) do
|
|
38
39
|
stream = double("stream")
|
|
40
|
+
allow(stream).to receive(:connect)
|
|
39
41
|
expect(TcpipClientStream).to receive(:new) { stream }
|
|
40
42
|
allow(stream).to receive(:connected?) { true }
|
|
41
43
|
allow(stream).to receive(:write)
|
|
@@ -159,6 +161,7 @@ module Cosmos
|
|
|
159
161
|
describe "read" do
|
|
160
162
|
before(:each) do
|
|
161
163
|
stream = double("stream")
|
|
164
|
+
allow(stream).to receive(:connect)
|
|
162
165
|
expect(TcpipClientStream).to receive(:new) { stream }
|
|
163
166
|
allow(stream).to receive(:connected?) { true }
|
|
164
167
|
allow(stream).to receive(:write)
|
|
@@ -40,6 +40,7 @@ module Cosmos
|
|
|
40
40
|
describe "connect" do
|
|
41
41
|
it "should pass a new TcpipClientStream to the stream protocol" do
|
|
42
42
|
stream = double("stream")
|
|
43
|
+
allow(stream).to receive(:connect)
|
|
43
44
|
expect(TcpipClientStream).to receive(:new) { stream }
|
|
44
45
|
expect(stream).to receive(:connected?) { true }
|
|
45
46
|
expect(stream).to receive(:raw_logger_pair=) { nil }
|
|
@@ -146,6 +146,15 @@ module Cosmos
|
|
|
146
146
|
expect { i.write_raw('') }.to raise_error("TEST")
|
|
147
147
|
end
|
|
148
148
|
end
|
|
149
|
+
|
|
150
|
+
describe "set_option" do
|
|
151
|
+
it "should set the listen address for the tcpip_server" do
|
|
152
|
+
expect(@stream).to receive(:listen_address=).with('127.0.0.1')
|
|
153
|
+
i = TcpipServerInterface.new('8888','8889','5','5','burst')
|
|
154
|
+
i.set_option('LISTEN_ADDRESS', ['127.0.0.1'])
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
149
158
|
end
|
|
150
159
|
end
|
|
151
160
|
|
|
@@ -40,7 +40,7 @@ module Cosmos
|
|
|
40
40
|
it "should raise an exception if the remote connection can't be made" do
|
|
41
41
|
json = JsonDRb.new
|
|
42
42
|
json.start_service('127.0.0.1', 7777, self)
|
|
43
|
-
|
|
43
|
+
allow_any_instance_of(Socket).to receive(:connect_nonblock) { raise "Error" }
|
|
44
44
|
obj = JsonDRbObject.new("localhost", 7777)
|
|
45
45
|
expect { obj.my_method(10) }.to raise_error(DRb::DRbConnError)
|
|
46
46
|
obj.disconnect
|
|
@@ -130,9 +130,11 @@ module Cosmos
|
|
|
130
130
|
Dir[File.join(@log_path,"*.bin")].length.should eql 2
|
|
131
131
|
# Check that the log files have timestamps which are 3 (or 4) seconds apart
|
|
132
132
|
files = Dir[File.join(@log_path,"*tlm.bin")].sort
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
(
|
|
133
|
+
split1 = files[0].split('_')
|
|
134
|
+
split2 = files[1].split('_')
|
|
135
|
+
log1_time = Time.new(split1[-7].to_i, split1[-6].to_i, split1[-5].to_i, split1[-4].to_i, split1[-3].to_i, split1[-2].to_i)
|
|
136
|
+
log2_time = Time.new(split2[-7].to_i, split2[-6].to_i, split2[-5].to_i, split2[-4].to_i, split2[-3].to_i, split2[-2].to_i)
|
|
137
|
+
(log2_time - log1_time).should be_within(2).of(3)
|
|
136
138
|
plw.shutdown
|
|
137
139
|
# Monkey patch the constant back to the default
|
|
138
140
|
PacketLogWriter.__send__(:remove_const,:CYCLE_TIME_INTERVAL)
|
|
@@ -30,115 +30,12 @@ module Cosmos
|
|
|
30
30
|
tf.unlink
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
it "should complain about overlapping items" do
|
|
34
|
-
tf = Tempfile.new('unittest')
|
|
35
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
36
|
-
tf.puts ' ITEM item1 0 8 UINT'
|
|
37
|
-
tf.puts ' ITEM item2 0 8 UINT'
|
|
38
|
-
tf.close
|
|
39
|
-
@pc.process_file(tf.path, "TGT1")
|
|
40
|
-
@pc.warnings[0].should eql "Bit definition overlap at bit offset 0 for Telemetry packet TGT1 PKT1 items ITEM2 and ITEM1"
|
|
41
|
-
tf.unlink
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
it "should not complain with non-overlapping negative offsets" do
|
|
45
|
-
tf = Tempfile.new('unittest')
|
|
46
|
-
tf.puts 'TELEMETRY tgt1 pkt2 LITTLE_ENDIAN "Description"'
|
|
47
|
-
tf.puts ' ITEM item1 0 8 UINT'
|
|
48
|
-
tf.puts ' ITEM item2 8 -16 BLOCK'
|
|
49
|
-
tf.puts ' ITEM item3 -16 16 UINT'
|
|
50
|
-
tf.close
|
|
51
|
-
@pc.process_file(tf.path, "TGT1")
|
|
52
|
-
@pc.warnings[0].should be_nil
|
|
53
|
-
tf.unlink
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
it "should complain with overlapping negative offsets" do
|
|
57
|
-
tf = Tempfile.new('unittest')
|
|
58
|
-
tf.puts 'TELEMETRY tgt1 pkt2 LITTLE_ENDIAN "Description"'
|
|
59
|
-
tf.puts ' ITEM item1 0 8 UINT'
|
|
60
|
-
tf.puts ' ITEM item2 8 -16 BLOCK'
|
|
61
|
-
tf.puts ' ITEM item3 -17 16 UINT'
|
|
62
|
-
tf.close
|
|
63
|
-
@pc.process_file(tf.path, "TGT1")
|
|
64
|
-
@pc.warnings[0].should eql "Bit definition overlap at bit offset -17 for Telemetry packet TGT1 PKT2 items ITEM3 and ITEM2"
|
|
65
|
-
tf.unlink
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
it "should complain about intersecting items" do
|
|
69
|
-
tf = Tempfile.new('unittest')
|
|
70
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
71
|
-
tf.puts ' ITEM item1 0 32 UINT'
|
|
72
|
-
tf.puts ' ITEM item2 16 32 UINT'
|
|
73
|
-
tf.close
|
|
74
|
-
@pc.process_file(tf.path, "TGT1")
|
|
75
|
-
@pc.warnings[0].should eql "Bit definition overlap at bit offset 16 for Telemetry packet TGT1 PKT1 items ITEM2 and ITEM1"
|
|
76
|
-
tf.unlink
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
it "should complain about array overlapping items" do
|
|
80
|
-
tf = Tempfile.new('unittest')
|
|
81
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
82
|
-
tf.puts ' ARRAY_ITEM item1 0 8 UINT 32'
|
|
83
|
-
tf.puts ' ARRAY_ITEM item2 0 8 UINT 32'
|
|
84
|
-
tf.close
|
|
85
|
-
@pc.process_file(tf.path, "TGT1")
|
|
86
|
-
@pc.warnings[0].should eql "Bit definition overlap at bit offset 0 for Telemetry packet TGT1 PKT1 items ITEM2 and ITEM1"
|
|
87
|
-
tf.unlink
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
it "should not complain with array non-overlapping negative offsets" do
|
|
91
|
-
tf = Tempfile.new('unittest')
|
|
92
|
-
tf.puts 'TELEMETRY tgt1 pkt2 LITTLE_ENDIAN "Description"'
|
|
93
|
-
tf.puts ' ITEM item1 0 8 UINT'
|
|
94
|
-
tf.puts ' ARRAY_ITEM item2 8 8 INT -16'
|
|
95
|
-
tf.puts ' ITEM item3 -16 16 UINT'
|
|
96
|
-
tf.close
|
|
97
|
-
@pc.process_file(tf.path, "TGT1")
|
|
98
|
-
@pc.warnings[0].should be_nil
|
|
99
|
-
tf.unlink
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
it "should complain with array overlapping negative offsets" do
|
|
103
|
-
tf = Tempfile.new('unittest')
|
|
104
|
-
tf.puts 'TELEMETRY tgt1 pkt2 LITTLE_ENDIAN "Description"'
|
|
105
|
-
tf.puts ' ITEM item1 0 8 UINT'
|
|
106
|
-
tf.puts ' ARRAY_ITEM item2 8 8 INT -16'
|
|
107
|
-
tf.puts ' ITEM item3 -17 16 UINT'
|
|
108
|
-
tf.close
|
|
109
|
-
@pc.process_file(tf.path, "TGT1")
|
|
110
|
-
@pc.warnings[0].should eql "Bit definition overlap at bit offset -17 for Telemetry packet TGT1 PKT2 items ITEM3 and ITEM2"
|
|
111
|
-
tf.unlink
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
it "should complain about array intersecting items" do
|
|
115
|
-
tf = Tempfile.new('unittest')
|
|
116
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
117
|
-
tf.puts ' ARRAY_ITEM item1 0 8 UINT 32'
|
|
118
|
-
tf.puts ' ARRAY_ITEM item2 16 8 UINT 32'
|
|
119
|
-
tf.close
|
|
120
|
-
@pc.process_file(tf.path, "TGT1")
|
|
121
|
-
@pc.warnings[0].should eql "Bit definition overlap at bit offset 16 for Telemetry packet TGT1 PKT1 items ITEM2 and ITEM1"
|
|
122
|
-
tf.unlink
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
it "should not complain about nonoverlapping little endian bitfields" do
|
|
126
|
-
tf = Tempfile.new('unittest')
|
|
127
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
128
|
-
tf.puts ' ITEM item1 12 12 UINT'
|
|
129
|
-
tf.puts ' ITEM item2 16 16 UINT'
|
|
130
|
-
tf.close
|
|
131
|
-
@pc.process_file(tf.path, "TGT1")
|
|
132
|
-
@pc.warnings[0].should be_nil
|
|
133
|
-
tf.unlink
|
|
134
|
-
end
|
|
135
|
-
|
|
136
33
|
context "with all telemetry keywords" do
|
|
137
34
|
before(:all) do
|
|
138
35
|
# top level keywords
|
|
139
|
-
@top_keywords = %w(
|
|
36
|
+
@top_keywords = %w(SELECT_COMMAND SELECT_TELEMETRY LIMITS_GROUP LIMITS_GROUP_ITEM)
|
|
140
37
|
# Keywords that require a current packet from TELEMETRY keyword
|
|
141
|
-
@tlm_keywords = %w(SELECT_ITEM ITEM ID_ITEM ARRAY_ITEM APPEND_ITEM APPEND_ID_ITEM APPEND_ARRAY_ITEM
|
|
38
|
+
@tlm_keywords = %w(SELECT_ITEM ITEM ID_ITEM ARRAY_ITEM APPEND_ITEM APPEND_ID_ITEM APPEND_ARRAY_ITEM PROCESSOR META)
|
|
142
39
|
# Keywords that require both a current packet and current item
|
|
143
40
|
@item_keywords = %w(STATE READ_CONVERSION WRITE_CONVERSION POLY_READ_CONVERSION POLY_WRITE_CONVERSION SEG_POLY_READ_CONVERSION SEG_POLY_WRITE_CONVERSION GENERIC_READ_CONVERSION_START GENERIC_WRITE_CONVERSION_START LIMITS LIMITS_RESPONSE UNITS FORMAT_STRING DESCRIPTION META)
|
|
144
41
|
end
|
|
@@ -177,7 +74,6 @@ module Cosmos
|
|
|
177
74
|
end
|
|
178
75
|
|
|
179
76
|
@tlm_keywords.each do |keyword|
|
|
180
|
-
next if %w(MACRO_APPEND_END).include? keyword
|
|
181
77
|
tf = Tempfile.new('unittest')
|
|
182
78
|
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
183
79
|
tf.puts keyword
|
|
@@ -202,8 +98,8 @@ module Cosmos
|
|
|
202
98
|
@top_keywords.each do |keyword|
|
|
203
99
|
tf = Tempfile.new('unittest')
|
|
204
100
|
case keyword
|
|
205
|
-
when "
|
|
206
|
-
tf.puts '
|
|
101
|
+
when "SELECT_COMMAND"
|
|
102
|
+
tf.puts 'SELECT_COMMAND tgt1 pkt1 extra'
|
|
207
103
|
when "SELECT_TELEMETRY"
|
|
208
104
|
tf.puts 'SELECT_TELEMETRY tgt1 pkt1 extra'
|
|
209
105
|
when 'LIMITS_GROUP'
|
|
@@ -217,7 +113,7 @@ module Cosmos
|
|
|
217
113
|
end
|
|
218
114
|
|
|
219
115
|
@tlm_keywords.each do |keyword|
|
|
220
|
-
next if %w(
|
|
116
|
+
next if %w(PROCESSOR META).include? keyword
|
|
221
117
|
tf = Tempfile.new('unittest')
|
|
222
118
|
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
223
119
|
case keyword
|
|
@@ -236,10 +132,6 @@ module Cosmos
|
|
|
236
132
|
when "SELECT_ITEM"
|
|
237
133
|
tf.puts 'ITEM myitem 0 8 UINT'
|
|
238
134
|
tf.puts 'SELECT_ITEM myitem extra'
|
|
239
|
-
when "MACRO_APPEND_START"
|
|
240
|
-
tf.puts 'MACRO_APPEND_START 0 1 "%s_%d" extra'
|
|
241
|
-
when "ACRO_APPEND_END"
|
|
242
|
-
tf.puts 'MACRO_APPEND_END extra'
|
|
243
135
|
end
|
|
244
136
|
tf.close
|
|
245
137
|
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Too many parameters for #{keyword}/)
|
|
@@ -271,47 +163,6 @@ module Cosmos
|
|
|
271
163
|
end
|
|
272
164
|
end
|
|
273
165
|
|
|
274
|
-
context "with COMMAND or TELEMETRY" do
|
|
275
|
-
it "should complain about invalid endianness" do
|
|
276
|
-
%w(COMMAND TELEMETRY).each do |keyword|
|
|
277
|
-
tf = Tempfile.new('unittest')
|
|
278
|
-
tf.puts keyword + ' tgt1 pkt1 MIDDLE_ENDIAN "Packet"'
|
|
279
|
-
tf.close
|
|
280
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid endianness MIDDLE_ENDIAN. Must be BIG_ENDIAN or LITTLE_ENDIAN.")
|
|
281
|
-
tf.unlink
|
|
282
|
-
end
|
|
283
|
-
end
|
|
284
|
-
|
|
285
|
-
it "should process target, packet, endianness, description" do
|
|
286
|
-
%w(COMMAND TELEMETRY).each do |keyword|
|
|
287
|
-
tf = Tempfile.new('unittest')
|
|
288
|
-
tf.puts keyword + ' tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
289
|
-
tf.close
|
|
290
|
-
@pc.process_file(tf.path, "TGT1")
|
|
291
|
-
pkt = @pc.commands["TGT1"]["PKT1"] if keyword == 'COMMAND'
|
|
292
|
-
pkt = @pc.telemetry["TGT1"]["PKT1"] if keyword == 'TELEMETRY'
|
|
293
|
-
pkt.target_name.should eql "TGT1"
|
|
294
|
-
pkt.packet_name.should eql "PKT1"
|
|
295
|
-
pkt.default_endianness.should eql :LITTLE_ENDIAN
|
|
296
|
-
pkt.description.should eql "Packet"
|
|
297
|
-
tf.unlink
|
|
298
|
-
end
|
|
299
|
-
end
|
|
300
|
-
|
|
301
|
-
it "should substitute the target name" do
|
|
302
|
-
%w(COMMAND TELEMETRY).each do |keyword|
|
|
303
|
-
tf = Tempfile.new('unittest')
|
|
304
|
-
tf.puts keyword + ' tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
305
|
-
tf.close
|
|
306
|
-
@pc.process_file(tf.path, "NEW")
|
|
307
|
-
pkt = @pc.commands["NEW"]["PKT1"] if keyword == 'COMMAND'
|
|
308
|
-
pkt = @pc.telemetry["NEW"]["PKT1"] if keyword == 'TELEMETRY'
|
|
309
|
-
pkt.target_name.should eql "NEW"
|
|
310
|
-
tf.unlink
|
|
311
|
-
end
|
|
312
|
-
end
|
|
313
|
-
end
|
|
314
|
-
|
|
315
166
|
context "with SELECT_COMMAND or SELECT_TELEMETRY" do
|
|
316
167
|
it "should complain if the packet is not found" do
|
|
317
168
|
%w(SELECT_COMMAND SELECT_TELEMETRY).each do |keyword|
|
|
@@ -442,176 +293,21 @@ module Cosmos
|
|
|
442
293
|
end
|
|
443
294
|
end
|
|
444
295
|
|
|
445
|
-
context "with
|
|
446
|
-
it "
|
|
447
|
-
tf = Tempfile.new('unittest')
|
|
448
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
449
|
-
tf.puts ' ITEM ITEM1 8 0 DERIVED'
|
|
450
|
-
tf.close
|
|
451
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /DERIVED items must have bit_offset of zero/)
|
|
452
|
-
tf.unlink
|
|
453
|
-
|
|
454
|
-
tf = Tempfile.new('unittest')
|
|
455
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
456
|
-
tf.puts ' ITEM ITEM1 0 8 DERIVED'
|
|
457
|
-
tf.close
|
|
458
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /DERIVED items must have bit_size of zero/)
|
|
459
|
-
tf.unlink
|
|
460
|
-
|
|
296
|
+
context "with MACRO_APPEND" do
|
|
297
|
+
it "creates a range of items" do
|
|
461
298
|
tf = Tempfile.new('unittest')
|
|
462
299
|
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
463
|
-
tf.puts '
|
|
464
|
-
tf.
|
|
465
|
-
|
|
466
|
-
@pc.telemetry["TGT1"]["PKT1"].items.keys.should include('ITEM1')
|
|
467
|
-
tf.unlink
|
|
468
|
-
end
|
|
469
|
-
|
|
470
|
-
it "should accept types INT UINT FLOAT STRING BLOCK" do
|
|
471
|
-
tf = Tempfile.new('unittest')
|
|
472
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
473
|
-
tf.puts ' ID_ITEM ITEM1 0 32 INT 0'
|
|
474
|
-
tf.puts ' ITEM ITEM2 0 32 UINT'
|
|
475
|
-
tf.puts ' ARRAY_ITEM ITEM3 0 32 FLOAT 64'
|
|
476
|
-
tf.puts ' APPEND_ID_ITEM ITEM4 32 STRING "ABCD"'
|
|
477
|
-
tf.puts ' APPEND_ITEM ITEM5 32 BLOCK'
|
|
478
|
-
tf.puts ' APPEND_ARRAY_ITEM ITEM6 32 BLOCK 64'
|
|
479
|
-
tf.close
|
|
480
|
-
@pc.process_file(tf.path, "TGT1")
|
|
481
|
-
@pc.telemetry["TGT1"]["PKT1"].items.keys.should include('ITEM1','ITEM2','ITEM3','ITEM4','ITEM5','ITEM6')
|
|
482
|
-
id_items = []
|
|
483
|
-
id_items << @pc.telemetry["TGT1"]["PKT1"].items["ITEM1"]
|
|
484
|
-
id_items << @pc.telemetry["TGT1"]["PKT1"].items["ITEM4"]
|
|
485
|
-
@pc.telemetry["TGT1"]["PKT1"].id_items.should eql id_items
|
|
486
|
-
tf.unlink
|
|
487
|
-
end
|
|
488
|
-
|
|
489
|
-
it "should support arbitrary endianness per item" do
|
|
490
|
-
tf = Tempfile.new('unittest')
|
|
491
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
492
|
-
tf.puts ' ID_ITEM ITEM1 0 32 UINT 0 "" LITTLE_ENDIAN'
|
|
493
|
-
tf.puts ' ITEM ITEM2 0 32 UINT "" LITTLE_ENDIAN'
|
|
494
|
-
tf.puts ' ARRAY_ITEM ITEM3 0 32 UINT 64 "" LITTLE_ENDIAN'
|
|
495
|
-
tf.puts ' APPEND_ID_ITEM ITEM4 32 UINT 1 "" LITTLE_ENDIAN'
|
|
496
|
-
tf.puts ' APPEND_ITEM ITEM5 32 UINT "" LITTLE_ENDIAN'
|
|
497
|
-
tf.puts ' APPEND_ARRAY_ITEM ITEM6 32 UINT 64 "" LITTLE_ENDIAN'
|
|
498
|
-
tf.puts ' ID_ITEM ITEM10 224 32 UINT 0 "" BIG_ENDIAN'
|
|
499
|
-
tf.puts ' ITEM ITEM20 256 32 UINT "" BIG_ENDIAN'
|
|
500
|
-
tf.puts ' ARRAY_ITEM ITEM30 0 32 UINT 64 "" BIG_ENDIAN'
|
|
501
|
-
tf.puts ' APPEND_ID_ITEM ITEM40 32 UINT 1 "" BIG_ENDIAN'
|
|
502
|
-
tf.puts ' APPEND_ITEM ITEM50 32 UINT "" BIG_ENDIAN'
|
|
503
|
-
tf.puts ' APPEND_ARRAY_ITEM ITEM60 32 UINT 64 "" BIG_ENDIAN'
|
|
504
|
-
tf.close
|
|
505
|
-
@pc.process_file(tf.path, "TGT1")
|
|
506
|
-
packet = @pc.telemetry["TGT1"]["PKT1"]
|
|
507
|
-
packet.buffer = "\x00\x00\x00\x01" * 16
|
|
508
|
-
packet.read("ITEM1").should eql 0x01000000
|
|
509
|
-
packet.read("ITEM2").should eql 0x01000000
|
|
510
|
-
packet.read("ITEM3").should eql [0x01000000, 0x01000000]
|
|
511
|
-
packet.read("ITEM4").should eql 0x01000000
|
|
512
|
-
packet.read("ITEM5").should eql 0x01000000
|
|
513
|
-
packet.read("ITEM6").should eql [0x01000000, 0x01000000]
|
|
514
|
-
packet.read("ITEM10").should eql 0x00000001
|
|
515
|
-
packet.read("ITEM20").should eql 0x00000001
|
|
516
|
-
packet.read("ITEM30").should eql [0x00000001, 0x00000001]
|
|
517
|
-
packet.read("ITEM40").should eql 0x00000001
|
|
518
|
-
packet.read("ITEM50").should eql 0x00000001
|
|
519
|
-
packet.read("ITEM60").should eql [0x00000001, 0x00000001]
|
|
520
|
-
tf.unlink
|
|
521
|
-
end
|
|
522
|
-
end
|
|
523
|
-
|
|
524
|
-
context "with keywords including PARAMETER" do
|
|
525
|
-
it "should only allow DERIVED items with offset 0 and size 0" do
|
|
526
|
-
tf = Tempfile.new('unittest')
|
|
527
|
-
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
528
|
-
tf.puts ' PARAMETER ITEM1 8 0 DERIVED 0 0 0'
|
|
529
|
-
tf.close
|
|
530
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /DERIVED items must have bit_offset of zero/)
|
|
531
|
-
tf.unlink
|
|
532
|
-
|
|
533
|
-
tf = Tempfile.new('unittest')
|
|
534
|
-
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
535
|
-
tf.puts ' PARAMETER ITEM1 0 8 DERIVED 0 0 0'
|
|
536
|
-
tf.close
|
|
537
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /DERIVED items must have bit_size of zero/)
|
|
538
|
-
tf.unlink
|
|
539
|
-
|
|
540
|
-
tf = Tempfile.new('unittest')
|
|
541
|
-
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
542
|
-
tf.puts ' PARAMETER ITEM1 0 0 DERIVED 0 0 0'
|
|
543
|
-
tf.close
|
|
544
|
-
@pc.process_file(tf.path, "TGT1")
|
|
545
|
-
@pc.commands["TGT1"]["PKT1"].items.keys.should include('ITEM1')
|
|
546
|
-
tf.unlink
|
|
547
|
-
end
|
|
548
|
-
|
|
549
|
-
it "should not allow ID_PARAMETER with DERIVED type" do
|
|
550
|
-
tf = Tempfile.new('unittest')
|
|
551
|
-
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
552
|
-
tf.puts ' ID_PARAMETER ITEM1 0 0 DERIVED 0 0 0'
|
|
553
|
-
tf.close
|
|
554
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /DERIVED data type not allowed/)
|
|
555
|
-
tf.unlink
|
|
556
|
-
end
|
|
557
|
-
|
|
558
|
-
it "should not allow APPEND_ID_PARAMETER with DERIVED type" do
|
|
559
|
-
tf = Tempfile.new('unittest')
|
|
560
|
-
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
561
|
-
tf.puts ' APPEND_ID_PARAMETER ITEM1 0 DERIVED 0 0 0'
|
|
562
|
-
tf.close
|
|
563
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /DERIVED data type not allowed/)
|
|
564
|
-
tf.unlink
|
|
565
|
-
end
|
|
566
|
-
|
|
567
|
-
it "should accept types INT UINT FLOAT STRING BLOCK" do
|
|
568
|
-
tf = Tempfile.new('unittest')
|
|
569
|
-
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
570
|
-
tf.puts ' ID_PARAMETER ITEM1 0 32 INT 0 0 0'
|
|
571
|
-
tf.puts ' ID_PARAMETER ITEM2 32 32 STRING "ABCD"'
|
|
572
|
-
tf.puts ' PARAMETER ITEM3 64 32 UINT 0 0 0'
|
|
573
|
-
tf.puts ' ARRAY_PARAMETER ITEM4 96 32 FLOAT 64'
|
|
574
|
-
tf.puts ' APPEND_ID_PARAMETER ITEM5 32 UINT 0 0 0'
|
|
575
|
-
tf.puts ' APPEND_ID_PARAMETER ITEM6 32 STRING "ABCD"'
|
|
576
|
-
tf.puts ' APPEND_PARAMETER ITEM7 32 BLOCK "1234"'
|
|
577
|
-
tf.puts ' APPEND_ARRAY_PARAMETER ITEM8 32 BLOCK 64'
|
|
578
|
-
tf.close
|
|
579
|
-
@pc.process_file(tf.path, "TGT1")
|
|
580
|
-
@pc.commands["TGT1"]["PKT1"].items.keys.should include('ITEM1','ITEM2','ITEM3','ITEM4','ITEM5','ITEM6','ITEM7','ITEM8')
|
|
581
|
-
tf.unlink
|
|
582
|
-
end
|
|
583
|
-
|
|
584
|
-
it "should support arbitrary endianness per item" do
|
|
585
|
-
tf = Tempfile.new('unittest')
|
|
586
|
-
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
587
|
-
tf.puts ' ID_PARAMETER ITEM1 0 32 UINT 0 0 0 "" LITTLE_ENDIAN'
|
|
588
|
-
tf.puts ' PARAMETER ITEM2 0 32 UINT 0 0 0 "" LITTLE_ENDIAN'
|
|
589
|
-
tf.puts ' ARRAY_PARAMETER ITEM3 0 32 UINT 64 "" LITTLE_ENDIAN'
|
|
590
|
-
tf.puts ' APPEND_ID_PARAMETER ITEM4 32 UINT 0 0 0 "" LITTLE_ENDIAN'
|
|
591
|
-
tf.puts ' APPEND_PARAMETER ITEM5 32 UINT 0 0 0 "" LITTLE_ENDIAN'
|
|
592
|
-
tf.puts ' APPEND_ARRAY_PARAMETER ITEM6 32 UINT 64 "" LITTLE_ENDIAN'
|
|
593
|
-
tf.puts ' ID_PARAMETER ITEM10 224 32 UINT 0 0 0 "" BIG_ENDIAN'
|
|
594
|
-
tf.puts ' PARAMETER ITEM20 256 32 UINT 0 0 0 "" BIG_ENDIAN'
|
|
595
|
-
tf.puts ' ARRAY_PARAMETER ITEM30 0 32 UINT 64 "" BIG_ENDIAN'
|
|
596
|
-
tf.puts ' APPEND_ID_PARAMETER ITEM40 32 UINT 0 0 0 "" BIG_ENDIAN'
|
|
597
|
-
tf.puts ' APPEND_PARAMETER ITEM50 32 UINT 0 0 0 "" BIG_ENDIAN'
|
|
598
|
-
tf.puts ' APPEND_ARRAY_PARAMETER ITEM60 32 UINT 64 "" BIG_ENDIAN'
|
|
300
|
+
tf.puts 'MACRO_APPEND_START 1 3'
|
|
301
|
+
tf.puts ' APPEND_ITEM BYTE 8 UINT "Setting #x"'
|
|
302
|
+
tf.puts 'MACRO_APPEND_END'
|
|
599
303
|
tf.close
|
|
600
304
|
@pc.process_file(tf.path, "TGT1")
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
packet.read("ITEM5").should eql 0x01000000
|
|
608
|
-
packet.read("ITEM6").should eql [0x01000000, 0x01000000]
|
|
609
|
-
packet.read("ITEM10").should eql 0x00000001
|
|
610
|
-
packet.read("ITEM20").should eql 0x00000001
|
|
611
|
-
packet.read("ITEM30").should eql [0x00000001, 0x00000001]
|
|
612
|
-
packet.read("ITEM40").should eql 0x00000001
|
|
613
|
-
packet.read("ITEM50").should eql 0x00000001
|
|
614
|
-
packet.read("ITEM60").should eql [0x00000001, 0x00000001]
|
|
305
|
+
pkt = @pc.telemetry["TGT1"]["PKT1"]
|
|
306
|
+
expect(pkt.items.length).to eql 6 # 3 plus the RECEIVED_XXX items
|
|
307
|
+
expect(pkt.items.keys).to include('BYTE1','BYTE2','BYTE3')
|
|
308
|
+
expect(pkt.sorted_items[3].name).to eql 'BYTE1'
|
|
309
|
+
expect(pkt.sorted_items[4].name).to eql 'BYTE2'
|
|
310
|
+
expect(pkt.sorted_items[5].name).to eql 'BYTE3'
|
|
615
311
|
tf.unlink
|
|
616
312
|
end
|
|
617
313
|
end
|
|
@@ -651,56 +347,6 @@ module Cosmos
|
|
|
651
347
|
end
|
|
652
348
|
end
|
|
653
349
|
|
|
654
|
-
context "with MACRO_APPEND_START" do
|
|
655
|
-
it "should add items to the packet" do
|
|
656
|
-
tf = Tempfile.new('unittest')
|
|
657
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
658
|
-
tf.puts 'MACRO_APPEND_START 1 5'
|
|
659
|
-
tf.puts 'APPEND_ITEM BIT 16 UINT "Setting #x"'
|
|
660
|
-
tf.puts ' STATE BAD 0 RED'
|
|
661
|
-
tf.puts ' STATE GOOD 1 GREEN'
|
|
662
|
-
tf.puts 'MACRO_APPEND_END'
|
|
663
|
-
tf.close
|
|
664
|
-
@pc.process_file(tf.path, "TGT1")
|
|
665
|
-
pkt = @pc.telemetry["TGT1"]["PKT1"]
|
|
666
|
-
pkt.items.keys.should include('BIT1','BIT2','BIT3','BIT4','BIT5')
|
|
667
|
-
limits_items = []
|
|
668
|
-
pkt.items.each do |name, item|
|
|
669
|
-
limits_items << item if name =~ /BIT/
|
|
670
|
-
end
|
|
671
|
-
pkt.limits_items.should eql limits_items
|
|
672
|
-
tf.unlink
|
|
673
|
-
end
|
|
674
|
-
|
|
675
|
-
it "should array items to the packet" do
|
|
676
|
-
tf = Tempfile.new('unittest')
|
|
677
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
678
|
-
tf.puts 'MACRO_APPEND_START 1 5'
|
|
679
|
-
tf.puts 'APPEND_ARRAY_ITEM BIT 16 INT 64 "Int Array Parameter"'
|
|
680
|
-
tf.puts 'MACRO_APPEND_END'
|
|
681
|
-
tf.close
|
|
682
|
-
@pc.process_file(tf.path, "TGT1")
|
|
683
|
-
pkt = @pc.telemetry["TGT1"]["PKT1"]
|
|
684
|
-
pkt.items.keys.should include('BIT1','BIT2','BIT3','BIT4','BIT5')
|
|
685
|
-
pkt.limits_items.should be_empty
|
|
686
|
-
tf.unlink
|
|
687
|
-
end
|
|
688
|
-
|
|
689
|
-
it "should work with printf format strings" do
|
|
690
|
-
tf = Tempfile.new('unittest')
|
|
691
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
692
|
-
tf.puts 'MACRO_APPEND_START 1 5 "%d%s"'
|
|
693
|
-
tf.puts 'APPEND_ID_ITEM BIT 16 UINT 0 "Setting #x"'
|
|
694
|
-
tf.puts 'MACRO_APPEND_END'
|
|
695
|
-
tf.close
|
|
696
|
-
@pc.process_file(tf.path, "TGT1")
|
|
697
|
-
pkt = @pc.telemetry["TGT1"]["PKT1"]
|
|
698
|
-
pkt.items.keys.should include('1BIT','2BIT','3BIT','4BIT','5BIT')
|
|
699
|
-
pkt.limits_items.should be_empty
|
|
700
|
-
tf.unlink
|
|
701
|
-
end
|
|
702
|
-
end
|
|
703
|
-
|
|
704
350
|
context "with ALLOW_SHORT" do
|
|
705
351
|
it "should mark the packet as allowing short buffers" do
|
|
706
352
|
tf = Tempfile.new('unittest')
|
|
@@ -806,106 +452,6 @@ module Cosmos
|
|
|
806
452
|
end
|
|
807
453
|
end
|
|
808
454
|
|
|
809
|
-
context "with STATE" do
|
|
810
|
-
it "should support STRING items" do
|
|
811
|
-
tf = Tempfile.new('unittest')
|
|
812
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
813
|
-
tf.puts ' APPEND_ITEM item1 128 STRING "state item"'
|
|
814
|
-
tf.puts ' STATE FALSE "FALSE STRING"'
|
|
815
|
-
tf.puts ' STATE TRUE "TRUE STRING"'
|
|
816
|
-
tf.close
|
|
817
|
-
@pc.process_file(tf.path, "TGT1")
|
|
818
|
-
@pc.telemetry["TGT1"]["PKT1"].write("ITEM1", "TRUE STRING")
|
|
819
|
-
@pc.telemetry["TGT1"]["PKT1"].read("ITEM1").should eql "TRUE"
|
|
820
|
-
@pc.telemetry["TGT1"]["PKT1"].write("ITEM1", "FALSE STRING")
|
|
821
|
-
@pc.telemetry["TGT1"]["PKT1"].read("ITEM1").should eql "FALSE"
|
|
822
|
-
tf.unlink
|
|
823
|
-
end
|
|
824
|
-
|
|
825
|
-
it "should warn about duplicate states and replace the duplicate" do
|
|
826
|
-
tf = Tempfile.new('unittest')
|
|
827
|
-
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
828
|
-
tf.puts ' APPEND_PARAMETER item1 8 UINT 0 2 0 "state item"'
|
|
829
|
-
tf.puts ' STATE FALSE 0'
|
|
830
|
-
tf.puts ' STATE TRUE 1'
|
|
831
|
-
tf.puts ' STATE FALSE 2'
|
|
832
|
-
tf.close
|
|
833
|
-
@pc.process_file(tf.path, "TGT1")
|
|
834
|
-
@pc.warnings.should include("Duplicate state defined on line 5: STATE FALSE 2")
|
|
835
|
-
@pc.commands["TGT1"]["PKT1"].buffer = "\x00"
|
|
836
|
-
@pc.commands["TGT1"]["PKT1"].read("ITEM1").should eql 0
|
|
837
|
-
@pc.commands["TGT1"]["PKT1"].buffer = "\x02"
|
|
838
|
-
@pc.commands["TGT1"]["PKT1"].read("ITEM1").should eql "FALSE"
|
|
839
|
-
tf.unlink
|
|
840
|
-
end
|
|
841
|
-
|
|
842
|
-
context "with telemetry" do
|
|
843
|
-
it "should only allow GREEN YELLOW or RED" do
|
|
844
|
-
tf = Tempfile.new('unittest')
|
|
845
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
846
|
-
tf.puts ' APPEND_ITEM item1 8 UINT "state item"'
|
|
847
|
-
tf.puts ' STATE WORST 1 ORANGE'
|
|
848
|
-
tf.close
|
|
849
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Invalid state color ORANGE/)
|
|
850
|
-
tf.unlink
|
|
851
|
-
end
|
|
852
|
-
|
|
853
|
-
it "should record the state values and colors" do
|
|
854
|
-
tf = Tempfile.new('unittest')
|
|
855
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
856
|
-
tf.puts ' APPEND_ITEM item1 8 UINT "state item"'
|
|
857
|
-
tf.puts ' STATE STATE1 1 RED'
|
|
858
|
-
tf.puts ' STATE STATE2 2 YELLOW'
|
|
859
|
-
tf.puts ' STATE STATE3 3 GREEN'
|
|
860
|
-
tf.puts ' STATE STATE4 4'
|
|
861
|
-
tf.close
|
|
862
|
-
@pc.process_file(tf.path, "TGT1")
|
|
863
|
-
index = 1
|
|
864
|
-
colors = [:RED, :YELLOW, :GREEN]
|
|
865
|
-
@pc.telemetry["TGT1"]["PKT1"].items["ITEM1"].states.each do |name,val|
|
|
866
|
-
name.should eql "STATE#{index}"
|
|
867
|
-
val.should eql index
|
|
868
|
-
@pc.telemetry["TGT1"]["PKT1"].items["ITEM1"].state_colors[name].should eql colors[index - 1]
|
|
869
|
-
|
|
870
|
-
index += 1
|
|
871
|
-
end
|
|
872
|
-
@pc.telemetry["TGT1"]["PKT1"].limits_items.should eql [@pc.telemetry["TGT1"]["PKT1"].items["ITEM1"]]
|
|
873
|
-
tf.unlink
|
|
874
|
-
end
|
|
875
|
-
end
|
|
876
|
-
|
|
877
|
-
context "with command" do
|
|
878
|
-
it "should only allow HAZARDOUS as the third param" do
|
|
879
|
-
tf = Tempfile.new('unittest')
|
|
880
|
-
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
881
|
-
tf.puts ' APPEND_PARAMETER item1 8 UINT 0 0 0'
|
|
882
|
-
tf.puts ' STATE WORST 0 RED'
|
|
883
|
-
tf.close
|
|
884
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /HAZARDOUS expected as third parameter/)
|
|
885
|
-
tf.unlink
|
|
886
|
-
end
|
|
887
|
-
|
|
888
|
-
it "should take HAZARDOUS and an optional description" do
|
|
889
|
-
tf = Tempfile.new('unittest')
|
|
890
|
-
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Description"'
|
|
891
|
-
tf.puts ' APPEND_PARAMETER item1 8 UINT 1 3 1'
|
|
892
|
-
tf.puts ' STATE GOOD 1'
|
|
893
|
-
tf.puts ' STATE BAD 2 HAZARDOUS'
|
|
894
|
-
tf.puts ' STATE WORST 3 HAZARDOUS "Hazardous description"'
|
|
895
|
-
tf.close
|
|
896
|
-
@pc.process_file(tf.path, "TGT1")
|
|
897
|
-
@pc.commands["TGT1"]["PKT1"].buffer = "\x01"
|
|
898
|
-
@pc.commands["TGT1"]["PKT1"].check_limits
|
|
899
|
-
@pc.commands["TGT1"]["PKT1"].items["ITEM1"].hazardous["GOOD"].should be_nil
|
|
900
|
-
@pc.commands["TGT1"]["PKT1"].items["ITEM1"].hazardous["BAD"].should_not be_nil
|
|
901
|
-
@pc.commands["TGT1"]["PKT1"].items["ITEM1"].hazardous["WORST"].should_not be_nil
|
|
902
|
-
@pc.commands["TGT1"]["PKT1"].items["ITEM1"].hazardous["WORST"].should eql "Hazardous description"
|
|
903
|
-
@pc.commands["TGT1"]["PKT1"].limits_items.should be_empty
|
|
904
|
-
tf.unlink
|
|
905
|
-
end
|
|
906
|
-
end
|
|
907
|
-
end
|
|
908
|
-
|
|
909
455
|
context "with READ_CONVERSION and WRITE_CONVERSION" do
|
|
910
456
|
it "should complain about missing conversion file" do
|
|
911
457
|
filename = File.join(File.dirname(__FILE__), "../test_only.rb")
|
|
@@ -993,76 +539,6 @@ module Cosmos
|
|
|
993
539
|
end
|
|
994
540
|
end
|
|
995
541
|
|
|
996
|
-
context "with PROCESSOR" do
|
|
997
|
-
it "should complain about missing processor file" do
|
|
998
|
-
filename = File.join(File.dirname(__FILE__), "../test_only.rb")
|
|
999
|
-
File.delete(filename) if File.exist?(filename)
|
|
1000
|
-
@pc = PacketConfig.new
|
|
1001
|
-
|
|
1002
|
-
tf = Tempfile.new('unittest')
|
|
1003
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1004
|
-
tf.puts ' PROCESSOR TEST test_only.rb'
|
|
1005
|
-
tf.close
|
|
1006
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /TestOnly class not found/)
|
|
1007
|
-
tf.unlink
|
|
1008
|
-
end
|
|
1009
|
-
|
|
1010
|
-
it "should complain about a non Cosmos::Processor class" do
|
|
1011
|
-
filename = File.join(File.dirname(__FILE__), "../processor1.rb")
|
|
1012
|
-
File.open(filename, 'w') do |file|
|
|
1013
|
-
file.puts "class Processor1"
|
|
1014
|
-
file.puts " def call(packet,buffer)"
|
|
1015
|
-
file.puts " end"
|
|
1016
|
-
file.puts "end"
|
|
1017
|
-
end
|
|
1018
|
-
load 'processor1.rb'
|
|
1019
|
-
File.delete(filename) if File.exist?(filename)
|
|
1020
|
-
|
|
1021
|
-
tf = Tempfile.new('unittest')
|
|
1022
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1023
|
-
tf.puts ' PROCESSOR P1 processor1.rb'
|
|
1024
|
-
tf.close
|
|
1025
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /processor must be a Cosmos::Processor but is a Processor1/)
|
|
1026
|
-
tf.unlink
|
|
1027
|
-
end
|
|
1028
|
-
|
|
1029
|
-
it "should parse the processor" do
|
|
1030
|
-
filename = File.join(File.dirname(__FILE__), "../processor2.rb")
|
|
1031
|
-
File.open(filename, 'w') do |file|
|
|
1032
|
-
file.puts "require 'cosmos/processors/processor'"
|
|
1033
|
-
file.puts "class Processor2 < Cosmos::Processor"
|
|
1034
|
-
file.puts " def call(packet,buffer)"
|
|
1035
|
-
file.puts " @results[:TEST] = 5"
|
|
1036
|
-
file.puts " end"
|
|
1037
|
-
file.puts "end"
|
|
1038
|
-
end
|
|
1039
|
-
load 'processor2.rb'
|
|
1040
|
-
|
|
1041
|
-
tf = Tempfile.new('unittest')
|
|
1042
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1043
|
-
tf.puts ' ITEM item1 0 16 INT "Integer Item"'
|
|
1044
|
-
tf.puts ' READ_CONVERSION processor_conversion.rb P2 TEST'
|
|
1045
|
-
tf.puts ' PROCESSOR P2 processor2.rb'
|
|
1046
|
-
tf.puts ' PROCESSOR P3 processor2.rb RAW'
|
|
1047
|
-
tf.close
|
|
1048
|
-
@pc.process_file(tf.path, "TGT1")
|
|
1049
|
-
@pc.telemetry["TGT1"]["PKT1"].buffer = "\x01\x01"
|
|
1050
|
-
@pc.telemetry["TGT1"]["PKT1"].read("ITEM1").should eql 5
|
|
1051
|
-
tf.unlink
|
|
1052
|
-
|
|
1053
|
-
File.delete(filename) if File.exist?(filename)
|
|
1054
|
-
end
|
|
1055
|
-
|
|
1056
|
-
it "should complain if applied to a command packet" do
|
|
1057
|
-
tf = Tempfile.new('unittest')
|
|
1058
|
-
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1059
|
-
tf.puts ' PROCESSOR P1 processor1.rb'
|
|
1060
|
-
tf.close
|
|
1061
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "PROCESSOR only applies to telemetry packets")
|
|
1062
|
-
tf.unlink
|
|
1063
|
-
end
|
|
1064
|
-
end
|
|
1065
|
-
|
|
1066
542
|
context "with POLY_READ_CONVERSION and POLY_WRITE_CONVERSION" do
|
|
1067
543
|
it "should perform a polynomial conversion" do
|
|
1068
544
|
tf = Tempfile.new('unittest')
|
|
@@ -1163,313 +639,22 @@ module Cosmos
|
|
|
1163
639
|
end
|
|
1164
640
|
|
|
1165
641
|
context "with LIMITS" do
|
|
1166
|
-
it "
|
|
1167
|
-
tf = Tempfile.new('unittest')
|
|
1168
|
-
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1169
|
-
tf.puts ' APPEND_PARAMETER item1 16 UINT 0 0 0 "Item"'
|
|
1170
|
-
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 7 3 5'
|
|
1171
|
-
tf.close
|
|
1172
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "LIMITS only applies to telemetry items")
|
|
1173
|
-
tf.unlink
|
|
1174
|
-
end
|
|
1175
|
-
|
|
1176
|
-
it "should complain if the second parameter isn't a number" do
|
|
1177
|
-
tf = Tempfile.new('unittest')
|
|
1178
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1179
|
-
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
|
1180
|
-
tf.puts ' LIMITS DEFAULT TRUE ENABLED 1 2 6 7 3 5'
|
|
1181
|
-
tf.close
|
|
1182
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Ensure persistence is an integer/)
|
|
1183
|
-
tf.unlink
|
|
1184
|
-
end
|
|
1185
|
-
|
|
1186
|
-
it "should complain if the third parameter isn't ENABLED or DISABLED" do
|
|
1187
|
-
tf = Tempfile.new('unittest')
|
|
1188
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1189
|
-
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
|
1190
|
-
tf.puts ' LIMITS DEFAULT 3 TRUE 1 2 6 7 3 5'
|
|
1191
|
-
tf.close
|
|
1192
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /Initial state must be ENABLED or DISABLED/)
|
|
1193
|
-
tf.unlink
|
|
1194
|
-
end
|
|
1195
|
-
|
|
1196
|
-
it "should complain if the 4 limits are out of order" do
|
|
1197
|
-
tf = Tempfile.new('unittest')
|
|
1198
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1199
|
-
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
|
1200
|
-
tf.puts ' LIMITS DEFAULT 3 ENABLED 2 1 3 4'
|
|
1201
|
-
tf.close
|
|
1202
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure yellow limits are within red limits.")
|
|
1203
|
-
tf.unlink
|
|
1204
|
-
|
|
1205
|
-
tf = Tempfile.new('unittest')
|
|
1206
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1207
|
-
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
|
1208
|
-
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 5 3 7'
|
|
1209
|
-
tf.close
|
|
1210
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure yellow limits are within red limits.")
|
|
1211
|
-
tf.unlink
|
|
1212
|
-
|
|
1213
|
-
tf = Tempfile.new('unittest')
|
|
1214
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1215
|
-
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
|
1216
|
-
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 5 4'
|
|
1217
|
-
tf.close
|
|
1218
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure yellow limits are within red limits.")
|
|
1219
|
-
tf.unlink
|
|
1220
|
-
|
|
1221
|
-
tf = Tempfile.new('unittest')
|
|
1222
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1223
|
-
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
|
1224
|
-
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 3 0'
|
|
1225
|
-
tf.close
|
|
1226
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure yellow limits are within red limits.")
|
|
1227
|
-
tf.unlink
|
|
1228
|
-
end
|
|
1229
|
-
|
|
1230
|
-
it "should complain if the 6 limits are out of order" do
|
|
1231
|
-
tf = Tempfile.new('unittest')
|
|
1232
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1233
|
-
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
|
1234
|
-
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 7 0 5'
|
|
1235
|
-
tf.close
|
|
1236
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure green limits are within yellow limits.")
|
|
1237
|
-
tf.unlink
|
|
1238
|
-
|
|
1239
|
-
tf = Tempfile.new('unittest')
|
|
1240
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1241
|
-
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
|
1242
|
-
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 3 6 7 2 5'
|
|
1243
|
-
tf.close
|
|
1244
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure green limits are within yellow limits.")
|
|
1245
|
-
tf.unlink
|
|
1246
|
-
|
|
1247
|
-
tf = Tempfile.new('unittest')
|
|
1248
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1249
|
-
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
|
1250
|
-
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 8 3 7'
|
|
1251
|
-
tf.close
|
|
1252
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure green limits are within yellow limits.")
|
|
1253
|
-
tf.unlink
|
|
1254
|
-
|
|
1255
|
-
tf = Tempfile.new('unittest')
|
|
1256
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1257
|
-
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
|
1258
|
-
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 8 3 9'
|
|
1259
|
-
tf.close
|
|
1260
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure green limits are within yellow limits.")
|
|
1261
|
-
tf.unlink
|
|
1262
|
-
|
|
1263
|
-
tf = Tempfile.new('unittest')
|
|
1264
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1265
|
-
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
|
1266
|
-
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 8 4 3'
|
|
1267
|
-
tf.close
|
|
1268
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid limits specified. Ensure green limits are within yellow limits.")
|
|
1269
|
-
tf.unlink
|
|
1270
|
-
end
|
|
1271
|
-
|
|
1272
|
-
it "should take 4 limits values" do
|
|
642
|
+
it "ensures limits sets have unique names" do
|
|
1273
643
|
tf = Tempfile.new('unittest')
|
|
1274
644
|
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1275
645
|
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
|
1276
646
|
tf.puts ' LIMITS DEFAULT 1 ENABLED 1 2 6 7'
|
|
647
|
+
tf.puts ' LIMITS TVAC 1 ENABLED 1 2 6 7'
|
|
648
|
+
tf.puts ' LIMITS DEFAULT 1 ENABLED 8 9 12 13'
|
|
1277
649
|
tf.close
|
|
1278
650
|
@pc.process_file(tf.path, "TGT1")
|
|
1279
651
|
item = @pc.telemetry["TGT1"]["PKT1"].items["ITEM1"]
|
|
1280
|
-
item.limits.values
|
|
1281
|
-
|
|
1282
|
-
@pc.telemetry["TGT1"]["PKT1"].enable_limits("ITEM1")
|
|
1283
|
-
@pc.telemetry["TGT1"]["PKT1"].check_limits
|
|
1284
|
-
item.limits.state.should eql :GREEN
|
|
1285
|
-
@pc.telemetry["TGT1"]["PKT1"].limits_items.should eql [item]
|
|
1286
|
-
tf.unlink
|
|
1287
|
-
end
|
|
1288
|
-
|
|
1289
|
-
it "should take 6 limits values" do
|
|
1290
|
-
tf = Tempfile.new('unittest')
|
|
1291
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1292
|
-
tf.puts ' APPEND_ITEM item1 16 UINT "Item"'
|
|
1293
|
-
tf.puts ' LIMITS DEFAULT 1 ENABLED 1 2 6 7 3 5'
|
|
1294
|
-
tf.close
|
|
1295
|
-
@pc.process_file(tf.path, "TGT1")
|
|
1296
|
-
item = @pc.telemetry["TGT1"]["PKT1"].items["ITEM1"]
|
|
1297
|
-
item.limits.values[:DEFAULT].should_not be_nil
|
|
652
|
+
expect(item.limits.values.length).to eql 2
|
|
653
|
+
# Verify the last defined DEFAULT limits wins
|
|
1298
654
|
@pc.telemetry["TGT1"]["PKT1"].buffer = "\x04"
|
|
1299
655
|
@pc.telemetry["TGT1"]["PKT1"].enable_limits("ITEM1")
|
|
1300
656
|
@pc.telemetry["TGT1"]["PKT1"].check_limits
|
|
1301
|
-
item.limits.state.should eql :
|
|
1302
|
-
@pc.telemetry["TGT1"]["PKT1"].limits_items.should eql [item]
|
|
1303
|
-
tf.unlink
|
|
1304
|
-
end
|
|
1305
|
-
end
|
|
1306
|
-
|
|
1307
|
-
context "with LIMITS_RESPONSE" do
|
|
1308
|
-
it "should complain if applied to a command PARAMETER" do
|
|
1309
|
-
tf = Tempfile.new('unittest')
|
|
1310
|
-
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1311
|
-
tf.puts ' APPEND_PARAMETER item1 16 UINT 0 0 0 "Item"'
|
|
1312
|
-
tf.puts ' LIMITS_RESPONSE test.rb'
|
|
1313
|
-
tf.close
|
|
1314
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "LIMITS_RESPONSE only applies to telemetry items")
|
|
1315
|
-
tf.unlink
|
|
1316
|
-
end
|
|
1317
|
-
|
|
1318
|
-
it "should complain about missing response file" do
|
|
1319
|
-
filename = File.join(File.dirname(__FILE__), "../test_only.rb")
|
|
1320
|
-
File.delete(filename) if File.exist?(filename)
|
|
1321
|
-
@pc = PacketConfig.new
|
|
1322
|
-
|
|
1323
|
-
tf = Tempfile.new('unittest')
|
|
1324
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1325
|
-
tf.puts ' ITEM item1 0 16 INT "Integer Item"'
|
|
1326
|
-
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 7 3 5'
|
|
1327
|
-
tf.puts ' LIMITS_RESPONSE test_only.rb'
|
|
1328
|
-
tf.close
|
|
1329
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /TestOnly class not found/)
|
|
1330
|
-
tf.unlink
|
|
1331
|
-
end
|
|
1332
|
-
|
|
1333
|
-
it "should complain about a non Cosmos::LimitsResponse class" do
|
|
1334
|
-
filename = File.join(File.dirname(__FILE__), "../limits_response1.rb")
|
|
1335
|
-
File.open(filename, 'w') do |file|
|
|
1336
|
-
file.puts "class LimitsResponse1"
|
|
1337
|
-
file.puts " def call(target_name, packet_name, item, old_limits_state, new_limits_state)"
|
|
1338
|
-
file.puts " end"
|
|
1339
|
-
file.puts "end"
|
|
1340
|
-
end
|
|
1341
|
-
load 'limits_response1.rb'
|
|
1342
|
-
File.delete(filename) if File.exist?(filename)
|
|
1343
|
-
|
|
1344
|
-
tf = Tempfile.new('unittest')
|
|
1345
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1346
|
-
tf.puts ' ITEM item1 0 16 INT "Integer Item"'
|
|
1347
|
-
tf.puts ' LIMITS DEFAULT 3 ENABLED 1 2 6 7 3 5'
|
|
1348
|
-
tf.puts ' LIMITS_RESPONSE limits_response1.rb'
|
|
1349
|
-
tf.close
|
|
1350
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, /response must be a Cosmos::LimitsResponse but is a LimitsResponse1/)
|
|
1351
|
-
tf.unlink
|
|
1352
|
-
end
|
|
1353
|
-
|
|
1354
|
-
it "should set the response" do
|
|
1355
|
-
filename = File.join(File.dirname(__FILE__), "../limits_response2.rb")
|
|
1356
|
-
File.open(filename, 'w') do |file|
|
|
1357
|
-
file.puts "require 'cosmos/packets/limits_response'"
|
|
1358
|
-
file.puts "class LimitsResponse2 < Cosmos::LimitsResponse"
|
|
1359
|
-
file.puts " def call(target_name, packet_name, item, old_limits_state, new_limits_state)"
|
|
1360
|
-
file.puts " puts \"\#{target_name} \#{packet_name} \#{item.name} \#{old_limits_state} \#{new_limits_state}\""
|
|
1361
|
-
file.puts " end"
|
|
1362
|
-
file.puts "end"
|
|
1363
|
-
end
|
|
1364
|
-
load 'limits_response2.rb'
|
|
1365
|
-
|
|
1366
|
-
tf = Tempfile.new('unittest')
|
|
1367
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1368
|
-
tf.puts ' ITEM item1 0 16 INT "Integer Item"'
|
|
1369
|
-
tf.puts ' LIMITS DEFAULT 1 ENABLED 1 2 6 7 3 5'
|
|
1370
|
-
tf.puts ' LIMITS_RESPONSE limits_response2.rb'
|
|
1371
|
-
tf.close
|
|
1372
|
-
@pc.process_file(tf.path, "TGT1")
|
|
1373
|
-
pkt = @pc.telemetry["TGT1"]["PKT1"]
|
|
1374
|
-
pkt.get_item("ITEM1").limits.response.class.should eql LimitsResponse2
|
|
1375
|
-
|
|
1376
|
-
File.delete(filename) if File.exist?(filename)
|
|
1377
|
-
tf.unlink
|
|
1378
|
-
end
|
|
1379
|
-
|
|
1380
|
-
it "should call the response with parameters" do
|
|
1381
|
-
filename = File.join(File.dirname(__FILE__), "../limits_response2.rb")
|
|
1382
|
-
File.open(filename, 'w') do |file|
|
|
1383
|
-
file.puts "require 'cosmos/packets/limits_response'"
|
|
1384
|
-
file.puts "class LimitsResponse2 < Cosmos::LimitsResponse"
|
|
1385
|
-
file.puts " def initialize(val)"
|
|
1386
|
-
file.puts " puts \"initialize: \#{val}\""
|
|
1387
|
-
file.puts " end"
|
|
1388
|
-
file.puts " def call(target_name, packet_name, item, old_limits_state, new_limits_state)"
|
|
1389
|
-
file.puts " puts \"\#{target_name} \#{packet_name} \#{item.name} \#{old_limits_state} \#{new_limits_state}\""
|
|
1390
|
-
file.puts " end"
|
|
1391
|
-
file.puts "end"
|
|
1392
|
-
end
|
|
1393
|
-
load 'limits_response2.rb'
|
|
1394
|
-
|
|
1395
|
-
tf = Tempfile.new('unittest')
|
|
1396
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1397
|
-
tf.puts ' ITEM item1 0 16 INT "Integer Item"'
|
|
1398
|
-
tf.puts ' LIMITS DEFAULT 1 ENABLED 1 2 6 7 3 5'
|
|
1399
|
-
tf.puts ' LIMITS_RESPONSE limits_response2.rb 2'
|
|
1400
|
-
tf.close
|
|
1401
|
-
capture_io do |stdout|
|
|
1402
|
-
@pc.process_file(tf.path, "TGT1")
|
|
1403
|
-
stdout.string.should eql "initialize: 2\n"
|
|
1404
|
-
end
|
|
1405
|
-
|
|
1406
|
-
File.delete(filename) if File.exist?(filename)
|
|
1407
|
-
tf.unlink
|
|
1408
|
-
end
|
|
1409
|
-
end
|
|
1410
|
-
|
|
1411
|
-
context "with FORMAT_STRING" do
|
|
1412
|
-
it "should complain about invalid format strings" do
|
|
1413
|
-
tf = Tempfile.new('unittest')
|
|
1414
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1415
|
-
tf.puts ' ITEM item1 0 8 INT'
|
|
1416
|
-
tf.puts ' FORMAT_STRING "%*s"'
|
|
1417
|
-
tf.close
|
|
1418
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid FORMAT_STRING specified for type INT: %*s")
|
|
1419
|
-
tf.unlink
|
|
1420
|
-
|
|
1421
|
-
tf = Tempfile.new('unittest')
|
|
1422
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1423
|
-
tf.puts ' ITEM item1 0 8 STRING'
|
|
1424
|
-
tf.puts ' FORMAT_STRING "%d"'
|
|
1425
|
-
tf.close
|
|
1426
|
-
expect { @pc.process_file(tf.path, "TGT1") }.to raise_error(ConfigParser::Error, "Invalid FORMAT_STRING specified for type STRING: %d")
|
|
1427
|
-
tf.unlink
|
|
1428
|
-
end
|
|
1429
|
-
|
|
1430
|
-
it "should format integers" do
|
|
1431
|
-
tf = Tempfile.new('unittest')
|
|
1432
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1433
|
-
tf.puts ' ITEM item1 0 8 INT'
|
|
1434
|
-
tf.puts ' FORMAT_STRING "d%d"'
|
|
1435
|
-
tf.puts ' ITEM item2 0 8 UINT'
|
|
1436
|
-
tf.puts ' FORMAT_STRING "u%u"'
|
|
1437
|
-
tf.puts ' ITEM item3 0 8 UINT'
|
|
1438
|
-
tf.puts ' FORMAT_STRING "0x%x"'
|
|
1439
|
-
tf.close
|
|
1440
|
-
@pc.process_file(tf.path, "TGT1")
|
|
1441
|
-
@pc.telemetry["TGT1"]["PKT1"].buffer = "\x0a\x0b\x0c"
|
|
1442
|
-
@pc.telemetry["TGT1"]["PKT1"].read("ITEM1",:FORMATTED).should eql "d10"
|
|
1443
|
-
@pc.telemetry["TGT1"]["PKT1"].read("ITEM2",:FORMATTED).should eql "u10"
|
|
1444
|
-
@pc.telemetry["TGT1"]["PKT1"].read("ITEM3",:FORMATTED).should eql "0xa"
|
|
1445
|
-
tf.unlink
|
|
1446
|
-
end
|
|
1447
|
-
|
|
1448
|
-
it "should format floats" do
|
|
1449
|
-
tf = Tempfile.new('unittest')
|
|
1450
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1451
|
-
tf.puts ' ITEM item1 0 32 FLOAT'
|
|
1452
|
-
tf.puts ' FORMAT_STRING "%3.3f"'
|
|
1453
|
-
tf.close
|
|
1454
|
-
@pc.process_file(tf.path, "TGT1")
|
|
1455
|
-
@pc.telemetry["TGT1"]["PKT1"].write("ITEM1",12345.12345)
|
|
1456
|
-
@pc.telemetry["TGT1"]["PKT1"].read("ITEM1",:FORMATTED).should eql "12345.123"
|
|
1457
|
-
tf.unlink
|
|
1458
|
-
end
|
|
1459
|
-
|
|
1460
|
-
it "should format strings and blocks" do
|
|
1461
|
-
tf = Tempfile.new('unittest')
|
|
1462
|
-
tf.puts 'TELEMETRY tgt1 pkt1 LITTLE_ENDIAN "Packet"'
|
|
1463
|
-
tf.puts ' ITEM item1 0 32 STRING'
|
|
1464
|
-
tf.puts ' FORMAT_STRING "String: %s"'
|
|
1465
|
-
tf.puts ' ITEM item2 0 32 BLOCK'
|
|
1466
|
-
tf.puts ' FORMAT_STRING "Block: %s"'
|
|
1467
|
-
tf.close
|
|
1468
|
-
@pc.process_file(tf.path, "TGT1")
|
|
1469
|
-
@pc.telemetry["TGT1"]["PKT1"].write("ITEM1","HI")
|
|
1470
|
-
@pc.telemetry["TGT1"]["PKT1"].read("ITEM1",:FORMATTED).should eql "String: HI"
|
|
1471
|
-
@pc.telemetry["TGT1"]["PKT1"].write("ITEM2","\x00\x01\x02\x03")
|
|
1472
|
-
@pc.telemetry["TGT1"]["PKT1"].read("ITEM2",:FORMATTED).should eql "Block: \x00\x01\x02\x03"
|
|
657
|
+
item.limits.state.should eql :RED_LOW
|
|
1473
658
|
tf.unlink
|
|
1474
659
|
end
|
|
1475
660
|
end
|