cosmos 3.0.0 → 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/CONTRIBUTING.txt +50 -0
- data/Gemfile +1 -0
- data/Manifest.txt +2 -0
- data/README.md +66 -1
- data/cosmos.gemspec +2 -3
- data/data/crc.txt +2 -2
- data/demo/Gemfile +1 -0
- data/ext/cosmos/ext/platform/platform.c +1 -2
- data/ext/mkrf_conf.rb +40 -0
- data/install/Gemfile +1 -0
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +1 -0
- data/lib/cosmos/version.rb +4 -4
- data/spec/core_ext/io_spec.rb +1 -1
- data/spec/core_ext/math_spec.rb +2 -2
- data/spec/interfaces/interface_spec.rb +3 -0
- data/spec/interfaces/udp_interface_spec.rb +2 -0
- data/spec/io/json_drb_object_spec.rb +6 -0
- data/spec/io/json_drb_spec.rb +18 -0
- data/spec/io/tcpip_server_spec.rb +28 -12
- data/spec/packet_logs/packet_log_writer_spec.rb +25 -11
- data/spec/script/script_spec.rb +8 -4
- data/spec/spec_helper.rb +11 -1
- data/spec/tools/cmd_tlm_server/api_spec.rb +33 -10
- data/spec/tools/cmd_tlm_server/background_tasks_spec.rb +9 -10
- data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +5 -0
- data/spec/tools/cmd_tlm_server/cmd_tlm_server_spec.rb +16 -19
- data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +38 -49
- data/spec/tools/cmd_tlm_server/interfaces_spec.rb +17 -7
- data/spec/tools/cmd_tlm_server/router_thread_spec.rb +9 -12
- data/spec/tools/cmd_tlm_server/routers_spec.rb +17 -5
- data/spec/top_level/top_level_spec.rb +4 -3
- metadata +7 -18
@@ -28,6 +28,7 @@ module Cosmos
|
|
28
28
|
sleep 0.2
|
29
29
|
expect { server.connect }.to raise_error(/Error binding/)
|
30
30
|
server.disconnect
|
31
|
+
sleep(0.2)
|
31
32
|
end
|
32
33
|
|
33
34
|
it "should create a listener thread for the read port" do
|
@@ -94,10 +95,11 @@ module Cosmos
|
|
94
95
|
server = TcpipServer.new(8888,8888,nil,nil,'Burst')
|
95
96
|
server.connect
|
96
97
|
sleep 0.2
|
97
|
-
socket = TCPSocket.open("127.0.0.
|
98
|
+
socket = TCPSocket.open("127.0.0.1",8888)
|
98
99
|
sleep 0.2
|
99
100
|
server.disconnect
|
100
101
|
socket.close
|
102
|
+
sleep(0.2)
|
101
103
|
|
102
104
|
stdout.string.should match /Tcpip server listen thread unexpectedly died/
|
103
105
|
end
|
@@ -108,6 +110,8 @@ module Cosmos
|
|
108
110
|
it "should return nil if there is no read port" do
|
109
111
|
server = TcpipServer.new(8888,nil,nil,nil,'Burst')
|
110
112
|
server.read.should be_nil
|
113
|
+
server.disconnect
|
114
|
+
sleep(0.2)
|
111
115
|
end
|
112
116
|
|
113
117
|
#~ it "should block if no data is available" do
|
@@ -123,7 +127,7 @@ module Cosmos
|
|
123
127
|
server.connect
|
124
128
|
sleep 0.2
|
125
129
|
|
126
|
-
socket = TCPSocket.open("127.0.0.
|
130
|
+
socket = TCPSocket.open("127.0.0.1",8889)
|
127
131
|
socket.write("\x00\x01")
|
128
132
|
sleep 0.2
|
129
133
|
server.num_clients.should eql 1
|
@@ -133,6 +137,7 @@ module Cosmos
|
|
133
137
|
sleep 0.2
|
134
138
|
server.num_clients.should eql 0
|
135
139
|
socket.close
|
140
|
+
sleep(0.2)
|
136
141
|
end
|
137
142
|
|
138
143
|
it "should check the client against the ACL" do
|
@@ -144,13 +149,14 @@ module Cosmos
|
|
144
149
|
server = TcpipServer.new(nil,8889,nil,nil,'Burst')
|
145
150
|
server.connect
|
146
151
|
sleep 0.2
|
147
|
-
socket = TCPSocket.open("127.0.0.
|
152
|
+
socket = TCPSocket.open("127.0.0.1",8889)
|
148
153
|
sleep 0.2
|
149
154
|
server.num_clients.should eql 0
|
150
155
|
socket.eof?.should be_truthy
|
151
156
|
server.disconnect
|
152
157
|
sleep 0.2
|
153
158
|
socket.close
|
159
|
+
sleep(0.2)
|
154
160
|
|
155
161
|
stdout.string.should match /Tcpip server rejected connection/
|
156
162
|
end
|
@@ -166,12 +172,13 @@ module Cosmos
|
|
166
172
|
server = TcpipServer.new(nil,8889,nil,nil,'Burst')
|
167
173
|
server.connect
|
168
174
|
sleep 0.2
|
169
|
-
socket = TCPSocket.open("127.0.0.
|
175
|
+
socket = TCPSocket.open("127.0.0.1",8889)
|
170
176
|
sleep 0.2
|
171
177
|
server.disconnect
|
172
178
|
sleep 0.2
|
173
179
|
server.num_clients.should eql 0
|
174
180
|
socket.close
|
181
|
+
sleep(0.2)
|
175
182
|
|
176
183
|
stdout.string.should match /Tcpip server read thread unexpectedly died/
|
177
184
|
end
|
@@ -186,11 +193,12 @@ module Cosmos
|
|
186
193
|
server = TcpipServer.new(8888,8888,nil,nil,'Burst')
|
187
194
|
server.connect
|
188
195
|
sleep 0.2
|
189
|
-
socket = TCPSocket.open("127.0.0.
|
196
|
+
socket = TCPSocket.open("127.0.0.1",8888)
|
190
197
|
socket.write("\x00\x01")
|
191
198
|
sleep 0.2
|
192
199
|
server.disconnect
|
193
200
|
socket.close
|
201
|
+
sleep(0.2)
|
194
202
|
|
195
203
|
stdout.string.should match /Tcpip server read thread unexpectedly died/
|
196
204
|
end
|
@@ -211,7 +219,7 @@ module Cosmos
|
|
211
219
|
server.connect
|
212
220
|
sleep 0.2
|
213
221
|
|
214
|
-
socket = TCPSocket.open("127.0.0.
|
222
|
+
socket = TCPSocket.open("127.0.0.1",8888)
|
215
223
|
sleep 0.2
|
216
224
|
server.num_clients.should eql 1
|
217
225
|
packet = Packet.new("TGT","PKT")
|
@@ -225,6 +233,7 @@ module Cosmos
|
|
225
233
|
sleep 0.2
|
226
234
|
server.num_clients.should eql 0
|
227
235
|
socket.close
|
236
|
+
sleep(0.2)
|
228
237
|
end
|
229
238
|
|
230
239
|
it "should log an error if the write thread dies" do
|
@@ -240,7 +249,7 @@ module Cosmos
|
|
240
249
|
server = MyTcpipServer3.new(8888,nil,nil,nil,'Burst')
|
241
250
|
server.connect
|
242
251
|
sleep 0.2
|
243
|
-
socket = TCPSocket.open("127.0.0.
|
252
|
+
socket = TCPSocket.open("127.0.0.1",8888)
|
244
253
|
sleep 0.2
|
245
254
|
server.num_clients.should eql 1
|
246
255
|
server.write(Packet.new("TGT","PKT"))
|
@@ -248,6 +257,7 @@ module Cosmos
|
|
248
257
|
server.num_clients.should eql 0
|
249
258
|
server.disconnect
|
250
259
|
socket.close
|
260
|
+
sleep(0.2)
|
251
261
|
|
252
262
|
stdout.string.should match /Tcpip server write thread unexpectedly died/
|
253
263
|
end
|
@@ -264,11 +274,12 @@ module Cosmos
|
|
264
274
|
server.connect
|
265
275
|
server.num_clients.should eql 0
|
266
276
|
sleep 0.2
|
267
|
-
socket = TCPSocket.open("127.0.0.
|
277
|
+
socket = TCPSocket.open("127.0.0.1",8888)
|
268
278
|
sleep 0.2
|
269
279
|
server.num_clients.should eql 0
|
270
280
|
server.disconnect
|
271
281
|
socket.close
|
282
|
+
sleep(0.2)
|
272
283
|
|
273
284
|
stdout.string.should match /Tcpip server lost write connection/
|
274
285
|
end
|
@@ -282,11 +293,11 @@ module Cosmos
|
|
282
293
|
|
283
294
|
server = TcpipServer.new(8888,8889,nil,nil,'Burst')
|
284
295
|
server.connect
|
285
|
-
sleep 0.
|
296
|
+
sleep 0.5
|
286
297
|
|
287
|
-
socket1 = TCPSocket.open("127.0.0.
|
288
|
-
socket2 = TCPSocket.open("127.0.0.
|
289
|
-
sleep 0.
|
298
|
+
socket1 = TCPSocket.open("127.0.0.1",8888)
|
299
|
+
socket2 = TCPSocket.open("127.0.0.1",8889)
|
300
|
+
sleep 0.5
|
290
301
|
server.num_clients.should eql 2
|
291
302
|
packet = Packet.new("TGT","PKT")
|
292
303
|
packet.buffer = "\x01\x02\x03\x04"
|
@@ -297,6 +308,7 @@ module Cosmos
|
|
297
308
|
server.disconnect
|
298
309
|
socket1.close
|
299
310
|
socket2.close
|
311
|
+
sleep(0.2)
|
300
312
|
|
301
313
|
stdout.string.should match /Tcpip server lost write connection/
|
302
314
|
end
|
@@ -307,6 +319,8 @@ module Cosmos
|
|
307
319
|
it "should return 0 if there is no read port" do
|
308
320
|
server = TcpipServer.new(8888,nil,nil,nil,'Burst')
|
309
321
|
server.read_queue_size.should eql 0
|
322
|
+
server.disconnect
|
323
|
+
sleep(0.2)
|
310
324
|
end
|
311
325
|
end
|
312
326
|
|
@@ -314,6 +328,8 @@ module Cosmos
|
|
314
328
|
it "should return 0 if there is no write port" do
|
315
329
|
server = TcpipServer.new(nil,8889,nil,nil,'Burst')
|
316
330
|
server.write_queue_size.should eql 0
|
331
|
+
server.disconnect
|
332
|
+
sleep(0.2)
|
317
333
|
end
|
318
334
|
end
|
319
335
|
|
@@ -32,33 +32,37 @@ module Cosmos
|
|
32
32
|
it "should create a command log writer" do
|
33
33
|
plw = PacketLogWriter.new(:CMD,nil,true,nil,10000000,nil,false)
|
34
34
|
plw.write(Packet.new('',''))
|
35
|
-
plw.
|
35
|
+
plw.shutdown
|
36
36
|
expect(Dir[File.join(@log_path,"*.bin")][-1]).to match("_cmd.bin")
|
37
|
+
sleep(0.1)
|
37
38
|
end
|
38
39
|
|
39
40
|
it "should create a telemetry log writer" do
|
40
41
|
plw = PacketLogWriter.new(:TLM,nil,true,nil,10000000,nil,false)
|
41
42
|
plw.write(Packet.new('',''))
|
42
|
-
plw.
|
43
|
+
plw.shutdown
|
43
44
|
expect(Dir[File.join(@log_path,"*.bin")][-1]).to match("_tlm.bin")
|
45
|
+
sleep(0.1)
|
44
46
|
end
|
45
47
|
|
46
48
|
it "should use log_name in the filename" do
|
47
49
|
plw = PacketLogWriter.new(:TLM,'test',true,nil,10000000,nil,false)
|
48
50
|
|
49
51
|
plw.write(Packet.new('',''))
|
50
|
-
plw.
|
52
|
+
plw.shutdown
|
51
53
|
expect(Dir[File.join(@log_path,"*.bin")][-1]).to match("testtlm.bin")
|
54
|
+
sleep(0.1)
|
52
55
|
end
|
53
56
|
|
54
57
|
it "should use the log directory" do
|
55
58
|
plw = PacketLogWriter.new(:TLM,'packet_log_writer_spec_',true,nil,10000000,Cosmos::USERPATH,false)
|
56
59
|
plw.write(Packet.new('',''))
|
57
|
-
plw.
|
60
|
+
plw.shutdown
|
58
61
|
expect(Dir[File.join(Cosmos::USERPATH,"*packet_log_writer_spec*")][-1]).to match("_tlm.bin")
|
59
62
|
Dir[File.join(Cosmos::USERPATH,"*packet_log_writer_spec*")].each do |file|
|
60
63
|
File.delete file
|
61
64
|
end
|
65
|
+
sleep(0.1)
|
62
66
|
end
|
63
67
|
end
|
64
68
|
|
@@ -68,12 +72,13 @@ module Cosmos
|
|
68
72
|
pkt = Packet.new('tgt','pkt')
|
69
73
|
pkt.buffer = "\x01\x02\x03\x04"
|
70
74
|
plw.write(pkt)
|
71
|
-
plw.
|
75
|
+
plw.shutdown
|
72
76
|
data = nil
|
73
77
|
File.open(Dir[File.join(@log_path,"*.bin")][-1],'rb') do |file|
|
74
78
|
data = file.read
|
75
79
|
end
|
76
80
|
data[-4..-1].should eql "\x01\x02\x03\x04"
|
81
|
+
sleep(0.1)
|
77
82
|
end
|
78
83
|
|
79
84
|
it "should not write packets if logging is disabled" do
|
@@ -81,8 +86,9 @@ module Cosmos
|
|
81
86
|
pkt = Packet.new('tgt','pkt')
|
82
87
|
pkt.buffer = "\x01\x02\x03\x04"
|
83
88
|
plw.write(pkt)
|
84
|
-
plw.
|
89
|
+
plw.shutdown
|
85
90
|
Dir[File.join(@log_path,"*.bin")].should be_empty
|
91
|
+
sleep(0.1)
|
86
92
|
end
|
87
93
|
|
88
94
|
it "should cycle the log when it a size" do
|
@@ -98,7 +104,8 @@ module Cosmos
|
|
98
104
|
# This write pushs us past 200 so we should start a new file
|
99
105
|
plw.write(pkt)
|
100
106
|
Dir[File.join(@log_path,"*.bin")].length.should eql 2
|
101
|
-
plw.
|
107
|
+
plw.shutdown
|
108
|
+
sleep(0.1)
|
102
109
|
end
|
103
110
|
|
104
111
|
it "should cycle the log after a set time" do
|
@@ -126,10 +133,11 @@ module Cosmos
|
|
126
133
|
log1_seconds = files[0].split('_')[-3].to_i * 60 + files[0].split('_')[-2].to_i
|
127
134
|
log2_seconds = files[1].split('_')[-3].to_i * 60 + files[1].split('_')[-2].to_i
|
128
135
|
(log2_seconds - log1_seconds).should be_within(2).of(3)
|
129
|
-
plw.
|
136
|
+
plw.shutdown
|
130
137
|
# Monkey patch the constant back to the default
|
131
138
|
PacketLogWriter.__send__(:remove_const,:CYCLE_TIME_INTERVAL)
|
132
139
|
PacketLogWriter.const_set(:CYCLE_TIME_INTERVAL, 2)
|
140
|
+
sleep(0.1)
|
133
141
|
end
|
134
142
|
|
135
143
|
it "should write asynchronously to a log" do
|
@@ -146,6 +154,7 @@ module Cosmos
|
|
146
154
|
end
|
147
155
|
data[-4..-1].should eql "\x01\x02\x03\x04"
|
148
156
|
plw.shutdown
|
157
|
+
sleep(0.1)
|
149
158
|
end
|
150
159
|
|
151
160
|
it "should handle errors creating the log file" do
|
@@ -159,6 +168,7 @@ module Cosmos
|
|
159
168
|
plw.stop
|
160
169
|
stdout.string.should match "Error opening"
|
161
170
|
plw.shutdown
|
171
|
+
sleep(0.1)
|
162
172
|
end
|
163
173
|
end
|
164
174
|
|
@@ -173,6 +183,7 @@ module Cosmos
|
|
173
183
|
plw.stop
|
174
184
|
stdout.string.should match "Error closing"
|
175
185
|
plw.shutdown
|
186
|
+
sleep(0.1)
|
176
187
|
end
|
177
188
|
end
|
178
189
|
end
|
@@ -182,25 +193,28 @@ module Cosmos
|
|
182
193
|
plw = PacketLogWriter.new(:TLM,nil,false,nil,10000000,nil,false)
|
183
194
|
plw.start
|
184
195
|
plw.write(Packet.new('',''))
|
185
|
-
plw.
|
196
|
+
plw.shutdown
|
186
197
|
file = Dir[File.join(@log_path,"*.bin")][-1]
|
187
198
|
File.size(file).should_not eql 0
|
199
|
+
sleep(0.1)
|
188
200
|
end
|
189
201
|
|
190
202
|
it "should add a label to the log file" do
|
191
203
|
plw = PacketLogWriter.new(:TLM,nil,false,nil,10000000,nil,false)
|
192
204
|
plw.start('test')
|
193
205
|
plw.write(Packet.new('',''))
|
194
|
-
plw.
|
206
|
+
plw.shutdown
|
195
207
|
expect(Dir[File.join(@log_path,"*.bin")][-1]).to match("_tlm_test.bin")
|
208
|
+
sleep(0.1)
|
196
209
|
end
|
197
210
|
|
198
211
|
it "should ignore bad label formats" do
|
199
212
|
plw = PacketLogWriter.new(:TLM,nil,false,nil,10000000,nil,false)
|
200
213
|
plw.start('my_test')
|
201
214
|
plw.write(Packet.new('',''))
|
202
|
-
plw.
|
215
|
+
plw.shutdown
|
203
216
|
expect(Dir[File.join(@log_path,"*.bin")][-1]).to match("_tlm.bin")
|
217
|
+
sleep(0.1)
|
204
218
|
end
|
205
219
|
end
|
206
220
|
|
data/spec/script/script_spec.rb
CHANGED
@@ -41,18 +41,22 @@ module Cosmos
|
|
41
41
|
allow_any_instance_of(Interface).to receive(:read)
|
42
42
|
|
43
43
|
@server = CmdTlmServer.new
|
44
|
+
shutdown_cmd_tlm()
|
45
|
+
initialize_script_module()
|
44
46
|
sleep 0.1
|
45
47
|
end
|
46
48
|
|
47
49
|
after(:each) do
|
48
50
|
@server.stop
|
51
|
+
shutdown_cmd_tlm()
|
52
|
+
sleep(0.1)
|
49
53
|
end
|
50
54
|
|
51
55
|
describe "cmd" do
|
52
56
|
it "should send a command" do
|
53
57
|
capture_io do |stdout|
|
54
58
|
cmd("INST ABORT")
|
55
|
-
stdout.string.should match /cmd\(\'INST ABORT\'\)/
|
59
|
+
stdout.string.should match /cmd\(\'INST ABORT\'\)/ #'
|
56
60
|
end
|
57
61
|
end
|
58
62
|
|
@@ -136,7 +140,7 @@ module Cosmos
|
|
136
140
|
end
|
137
141
|
|
138
142
|
it "should check parameter ranges" do
|
139
|
-
expect { cmd_raw("INST COLLECT with TYPE 0, DURATION 20") }.to raise_error(/Command parameter 'INST COLLECT DURATION' = 20 not in valid range/)
|
143
|
+
expect { cmd_raw("INST COLLECT with TYPE 0, DURATION 20") }.to raise_error(/Command parameter 'INST COLLECT DURATION' = 20 not in valid range/) #'
|
140
144
|
end
|
141
145
|
|
142
146
|
it "should prompt for a hazardous command" do
|
@@ -189,7 +193,7 @@ module Cosmos
|
|
189
193
|
capture_io do |stdout|
|
190
194
|
cmd_raw_no_hazardous_check("INST COLLECT with TYPE 1")
|
191
195
|
stdout.string.should match "Command INST COLLECT being sent ignoring hazardous warnings"
|
192
|
-
stdout.string.should match /cmd_raw\(\'INST COLLECT/
|
196
|
+
stdout.string.should match /cmd_raw\(\'INST COLLECT/ #'
|
193
197
|
end
|
194
198
|
end
|
195
199
|
end
|
@@ -199,7 +203,7 @@ module Cosmos
|
|
199
203
|
capture_io do |stdout|
|
200
204
|
cmd_raw_no_checks("INST COLLECT with TYPE 1, DURATION 20")
|
201
205
|
stdout.string.should match "Command INST COLLECT being sent ignoring hazardous warnings"
|
202
|
-
stdout.string.should match /cmd_raw\(\'INST COLLECT/
|
206
|
+
stdout.string.should match /cmd_raw\(\'INST COLLECT/ #'
|
203
207
|
end
|
204
208
|
end
|
205
209
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -74,9 +74,19 @@ RSpec.configure do |config|
|
|
74
74
|
Cosmos.disable_warnings do
|
75
75
|
Object.const_set(:STDOUT, $saved_stdout_const)
|
76
76
|
end
|
77
|
+
# Kill any leftover threads
|
78
|
+
if Thread.list.length > 1
|
79
|
+
Thread.list.each do |t|
|
80
|
+
t.kill if t != Thread.current
|
81
|
+
end
|
82
|
+
sleep(0.2)
|
83
|
+
end
|
77
84
|
end
|
78
85
|
|
79
|
-
|
86
|
+
config.after(:each) do
|
87
|
+
# Make sure we didn't leave any lingering threads
|
88
|
+
Thread.list.length.should eql(1)
|
89
|
+
end
|
80
90
|
end
|
81
91
|
|
82
92
|
# Clean up the spec configuration directory
|
@@ -27,21 +27,43 @@ module Cosmos
|
|
27
27
|
end
|
28
28
|
|
29
29
|
before(:each) do
|
30
|
-
allow_any_instance_of(Interface).to receive(:connected?)
|
31
|
-
allow_any_instance_of(Interface).to receive(:connect)
|
32
|
-
allow_any_instance_of(Interface).to receive(:disconnect)
|
33
|
-
allow_any_instance_of(Interface).to receive(:write_raw)
|
34
|
-
allow_any_instance_of(Interface).to receive(:read)
|
35
30
|
@api = CmdTlmServer.new
|
31
|
+
config = @api.interfaces.instance_variable_get(:@config)
|
32
|
+
# Stub interfaces and routers. Do this like this so that they can still be used in an after hook
|
33
|
+
config.interfaces.each do |interface_name, i|
|
34
|
+
if i.class == Cosmos::Interface
|
35
|
+
def i.connected?(*args)
|
36
|
+
end
|
37
|
+
def i.connect(*args)
|
38
|
+
end
|
39
|
+
def i.disconnect(*args)
|
40
|
+
end
|
41
|
+
def i.write_raw(*args)
|
42
|
+
end
|
43
|
+
def i.read(*args)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
config.routers.each do |router_name, i|
|
48
|
+
if i.class == Cosmos::Interface
|
49
|
+
def i.connected?(*args)
|
50
|
+
end
|
51
|
+
def i.connect(*args)
|
52
|
+
end
|
53
|
+
def i.disconnect(*args)
|
54
|
+
end
|
55
|
+
def i.write_raw(*args)
|
56
|
+
end
|
57
|
+
def i.read(*args)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
36
61
|
allow(@api.commanding).to receive(:send_command_to_target)
|
37
62
|
end
|
38
63
|
|
39
64
|
after(:each) do
|
40
|
-
|
41
|
-
|
42
|
-
rescue
|
43
|
-
# Ignore all errors when trying to stop
|
44
|
-
end
|
65
|
+
@api.stop
|
66
|
+
sleep(0.2)
|
45
67
|
end
|
46
68
|
|
47
69
|
after(:all) do
|
@@ -61,6 +83,7 @@ module Cosmos
|
|
61
83
|
describe "cmd" do
|
62
84
|
it "should complain about unknown targets, commands, and parameters" do
|
63
85
|
test_cmd_unknown(:cmd)
|
86
|
+
sleep(0.5)
|
64
87
|
end
|
65
88
|
|
66
89
|
it "should process a string" do
|