cosmos 4.4.2 → 4.5.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.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +6 -2
  3. data/Manifest.txt +25 -0
  4. data/README.md +4 -0
  5. data/Rakefile +3 -8
  6. data/bin/rubysloc +73 -28
  7. data/cosmos.gemspec +1 -1
  8. data/data/config/interface_modifiers.yaml +3 -2
  9. data/data/config/system.yaml +81 -24
  10. data/data/crc.txt +426 -426
  11. data/demo/config/data/crc.txt +233 -233
  12. data/demo/config/system/system.txt +15 -7
  13. data/demo/config/system/system2.txt +15 -7
  14. data/demo/config/system/system_alt_ports.txt +15 -7
  15. data/demo/config/targets/INST/cmd_tlm/inst_cmds.txt +1 -1
  16. data/extensions/vscode/.gitignore +4 -0
  17. data/extensions/vscode/.vscode/launch.json +32 -0
  18. data/extensions/vscode/.vscode/settings.json +13 -0
  19. data/extensions/vscode/.vscode/tasks.json +79 -0
  20. data/extensions/vscode/License.txt +879 -0
  21. data/extensions/vscode/README.md +9 -0
  22. data/extensions/vscode/client/License.txt +879 -0
  23. data/extensions/vscode/client/README.md +39 -0
  24. data/extensions/vscode/client/cosmos.configuration.json +23 -0
  25. data/extensions/vscode/client/images/icon.png +0 -0
  26. data/extensions/vscode/client/package-lock.json +414 -0
  27. data/extensions/vscode/client/package.json +105 -0
  28. data/extensions/vscode/client/src/extension.ts +132 -0
  29. data/extensions/vscode/client/src/screen_preview.rb +25 -0
  30. data/extensions/vscode/client/syntaxes/cosmos.tmLanguage.json +219 -0
  31. data/extensions/vscode/client/tsconfig.json +17 -0
  32. data/extensions/vscode/package-lock.json +26 -0
  33. data/extensions/vscode/package.json +35 -0
  34. data/extensions/vscode/server/License.txt +879 -0
  35. data/extensions/vscode/server/package-lock.json +236 -0
  36. data/extensions/vscode/server/package.json +29 -0
  37. data/extensions/vscode/server/src/server.ts +59 -0
  38. data/extensions/vscode/server/tsconfig.json +16 -0
  39. data/install/config/data/crc.txt +132 -132
  40. data/install/config/system/system.txt +15 -7
  41. data/lib/cosmos/core_ext/time.rb +3 -1
  42. data/lib/cosmos/dart/examples/dart_decom_client.rb +1 -1
  43. data/lib/cosmos/dart/lib/dart_decommutator.rb +4 -4
  44. data/lib/cosmos/dart/processes/dart_decom_server.rb +1 -1
  45. data/lib/cosmos/dart/processes/dart_master.rb +1 -1
  46. data/lib/cosmos/gui/qt_tool.rb +10 -12
  47. data/lib/cosmos/gui/widgets/dart_meta_frame.rb +1 -1
  48. data/lib/cosmos/interfaces/dart_status_interface.rb +1 -1
  49. data/lib/cosmos/interfaces/serial_interface.rb +7 -1
  50. data/lib/cosmos/io/json_drb.rb +2 -2
  51. data/lib/cosmos/io/json_drb_object.rb +7 -2
  52. data/lib/cosmos/io/json_drb_rack.rb +25 -5
  53. data/lib/cosmos/io/json_rpc.rb +1 -1
  54. data/lib/cosmos/io/posix_serial_driver.rb +60 -22
  55. data/lib/cosmos/io/serial_driver.rb +11 -8
  56. data/lib/cosmos/io/win32_serial_driver.rb +8 -1
  57. data/lib/cosmos/packets/structure.rb +11 -2
  58. data/lib/cosmos/script/api_shared.rb +8 -1
  59. data/lib/cosmos/script/script.rb +2 -9
  60. data/lib/cosmos/streams/serial_stream.rb +11 -6
  61. data/lib/cosmos/system/system.rb +43 -12
  62. data/lib/cosmos/tools/cmd_sender/cmd_param_table_item_delegate.rb +15 -0
  63. data/lib/cosmos/tools/cmd_sender/cmd_params.rb +25 -3
  64. data/lib/cosmos/tools/cmd_sender/cmd_sender.rb +7 -0
  65. data/lib/cosmos/tools/cmd_sequence/sequence_item.rb +0 -5
  66. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +2 -2
  67. data/lib/cosmos/tools/cmd_tlm_server/router_thread.rb +5 -0
  68. data/lib/cosmos/tools/config_editor/config_editor.rb +1 -1
  69. data/lib/cosmos/tools/handbook_creator/handbook_creator_config.rb +1 -1
  70. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_config.rb +1 -4
  71. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_processor.rb +3 -3
  72. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_dart_thread.rb +1 -1
  73. data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +2 -2
  74. data/lib/cosmos/version.rb +5 -5
  75. data/spec/core_ext/time_spec.rb +4 -0
  76. data/spec/io/json_drb_rack_spec.rb +166 -0
  77. data/spec/io/json_rpc_spec.rb +4 -5
  78. data/spec/io/posix_serial_driver_spec.rb +81 -0
  79. data/spec/io/win32_serial_driver_spec.rb +17 -1
  80. data/spec/system/system_spec.rb +108 -0
  81. data/spec/tools/cmd_tlm_server/router_thread_spec.rb +2 -3
  82. metadata +31 -6
@@ -72,13 +72,13 @@ module Cosmos
72
72
  items = []
73
73
  configs.each { |config| config.mode = :dart; items.concat(config.normal_items); config.open_output_file }
74
74
  items.uniq!
75
-
75
+
76
76
  time_start = Time.utc(1970, 1, 1) unless time_start
77
77
  time_end = Time.now unless time_end
78
78
 
79
79
  results = {}
80
80
  begin
81
- server = JsonDRbObject.new(System.connect_hosts['DART_DECOM'], System.ports['DART_DECOM'])
81
+ server = JsonDRbObject.new(System.connect_hosts['DART_DECOM'], System.ports['DART_DECOM'], 1.0, Cosmos::System.x_csrf_token)
82
82
 
83
83
  index = 0
84
84
  items.each do |item_type, target_name, packet_name, item_name, value_type, dart_reduction, dart_reduced_type|
@@ -116,7 +116,7 @@ module Cosmos
116
116
  rescue Exception => error
117
117
  yield(index.to_f / items.length, "Error querying #{query_string} : #{error.class}:#{error.message}\n#{error.backtrace.join("\n")}\n") if block_given?
118
118
  return # Bail out because something bad happened
119
- end
119
+ end
120
120
  end
121
121
 
122
122
  configs.each { |config| config.process_dart(results) }
@@ -45,7 +45,7 @@ module Cosmos
45
45
 
46
46
  # Execute each query
47
47
  results = {}
48
- server = JsonDRbObject.new(System.connect_hosts['DART_DECOM'], System.ports['DART_DECOM'])
48
+ server = JsonDRbObject.new(System.connect_hosts['DART_DECOM'], System.ports['DART_DECOM'], 1.0, Cosmos::System.x_csrf_token)
49
49
  time_start = Time.utc(1970, 1, 1) unless time_start
50
50
  time_end = Time.now unless time_end
51
51
  progress_dialog.set_step_progress(0) if progress_dialog
@@ -146,7 +146,7 @@ module Cosmos
146
146
  'clear_all']
147
147
  @json_drb.method_whitelist = whitelist
148
148
  begin
149
- @json_drb.start_service System.listen_hosts['TLMVIEWER_API'], port, self
149
+ @json_drb.start_service System.listen_hosts['TLMVIEWER_API'], port, self, 1000, System
150
150
  rescue Exception
151
151
  raise FatalError.new("Error starting JsonDRb on port #{port}.\nPerhaps a Telemetry Viewer is already running?")
152
152
  end
@@ -171,7 +171,7 @@ module Cosmos
171
171
 
172
172
  ConfigParser.splash = nil
173
173
  end
174
-
174
+
175
175
  hide() unless options.show_main
176
176
  end
177
177
 
@@ -1,12 +1,12 @@
1
1
  # encoding: ascii-8bit
2
2
 
3
- COSMOS_VERSION = '4.4.2'
3
+ COSMOS_VERSION = '4.5.0'
4
4
  module Cosmos
5
5
  module Version
6
6
  MAJOR = '4'
7
- MINOR = '4'
8
- PATCH = '2'
9
- BUILD = '41a1376a7b11d7bb3498dd6fd0a13c1a9b383946'
7
+ MINOR = '5'
8
+ PATCH = '0'
9
+ BUILD = '627198e20200543f157cc4c2ffde5d7df5180ae2'
10
10
  end
11
- VERSION = '4.4.2'
11
+ VERSION = '4.5.0'
12
12
  end
@@ -183,6 +183,10 @@ describe Time do
183
183
  expect(parts[1]).to eql ccsds_ms
184
184
  expect(parts[2]).to be_within(50).of(ccsds_us)
185
185
  end
186
+
187
+ it "maintains precision" do
188
+ expect(Time.ccsds2sec(22766, 65115943, 552).round(6)).to eql(1967047515.943552)
189
+ end
186
190
  end
187
191
 
188
192
  describe "Time.yds2mdy" do
@@ -0,0 +1,166 @@
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/io/json_drb_rack'
13
+
14
+ module Cosmos
15
+
16
+ describe JsonDrbRack do
17
+ before(:each) do
18
+ @env = {
19
+ "GATEWAY_INTERFACE" => "CGI/1.1",
20
+ "PATH_INFO" => "/index.html",
21
+ "QUERY_STRING" => "",
22
+ "REMOTE_ADDR" => "::1",
23
+ "REMOTE_HOST" => "localhost",
24
+ "REQUEST_METHOD" => "POST",
25
+ "REQUEST_URI" => "http://localhost:3000/index.html",
26
+ "SCRIPT_NAME" => "",
27
+ "SERVER_NAME" => "localhost",
28
+ "SERVER_PORT" => "3000",
29
+ "SERVER_PROTOCOL" => "HTTP/1.1",
30
+ "SERVER_SOFTWARE" => "WEBrick/1.3.1 (Ruby/2.0.0/2013-11-22)",
31
+ "HTTP_HOST" => "127.0.0.1:7777",
32
+ "HTTP_USER_AGENT" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0",
33
+ "HTTP_ACCEPT" => "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
34
+ "HTTP_ACCEPT_LANGUAGE" => "zh-tw,zh;q=0.8,en-us;q=0.5,en;q=0.3",
35
+ "HTTP_ACCEPT_ENCODING" => "gzip, deflate",
36
+ "HTTP_COOKIE" => "jsonrpc.session=3iqp3ydRwFyqjcfO0GT2bzUh.bacc2786c7a81df0d0e950bec8fa1a9b1ba0bb61",
37
+ "HTTP_CONNECTION" => "keep-alive",
38
+ "HTTP_CACHE_CONTROL" => "max-age=0",
39
+ "rack.version" => [1, 2],
40
+ "rack.input" => StringIO.new(""),
41
+ "rack.errors" => nil,
42
+ "rack.multithread" => true,
43
+ "rack.multiprocess" => false,
44
+ "rack.run_once" => false,
45
+ "rack.url_scheme" => "http",
46
+ "HTTP_VERSION" => "HTTP/1.1",
47
+ "REQUEST_PATH" => "/index.html"
48
+ }
49
+ end
50
+
51
+ class MockDRb
52
+ class MockDRbAcl
53
+ def initialize(val = true)
54
+ @val = val
55
+ end
56
+ def allow_addr?(val)
57
+ return @val
58
+ end
59
+ end
60
+
61
+ def initialize(val, response_data = "response", error_code = nil)
62
+ @acl = MockDRbAcl.new(val)
63
+ @response_data = response_data
64
+ @error_code = error_code
65
+ end
66
+
67
+ def acl
68
+ @acl
69
+ end
70
+
71
+ def process_request(request_data, start_time)
72
+ return @response_data, @error_code
73
+ end
74
+ end
75
+
76
+ class MockSystem
77
+ def initialize(token = 'SuperSecret', hosts = ['127.0.0.1:7777'], origins = [])
78
+ @token = token
79
+ @hosts = hosts
80
+ @origins = origins
81
+ end
82
+ def x_csrf_token
83
+ @token
84
+ end
85
+ def allowed_hosts
86
+ @hosts
87
+ end
88
+ def allowed_origins
89
+ @origins
90
+ end
91
+ end
92
+
93
+ describe "call" do
94
+ it "supports the drb acl" do
95
+ json_drb_rack = JsonDrbRack.new(MockDRb.new(false), MockSystem.new)
96
+ status, type, body_array = json_drb_rack.call(@env)
97
+ expect(status).to eql 403
98
+ expect(type).to eql({'Content-Type' => "text/plain"})
99
+ expect(body_array).to eql ["Forbidden"]
100
+ end
101
+
102
+ it "handles X-Csrf-Token" do
103
+ json_drb_rack = JsonDrbRack.new(MockDRb.new(true), MockSystem.new('NeverGuess'))
104
+ @env['HTTP_X_CSRF_TOKEN'] = 'TryToGuess'
105
+ status, type, body_array = json_drb_rack.call(@env)
106
+ expect(status).to eql 403
107
+ expect(type).to eql({'Content-Type' => "text/plain"})
108
+ expect(body_array).to eql ["Forbidden: Bad X-Csrf-Token: #{@env['HTTP_X_CSRF_TOKEN']}"]
109
+
110
+ json_drb_rack = JsonDrbRack.new(MockDRb.new(true), MockSystem.new('NeverGuess'))
111
+ @env['HTTP_X_CSRF_TOKEN'] = 'NeverGuess'
112
+ status, type, body_array = json_drb_rack.call(@env)
113
+ expect(status).to eql 200
114
+ expect(type).to eql({'Content-Type' => "application/json-rpc"})
115
+ expect(body_array).to eql ["response"]
116
+ end
117
+
118
+ it "Handles Allowed Hosts" do
119
+ json_drb_rack = JsonDrbRack.new(MockDRb.new(true), MockSystem.new('NeverGuess'))
120
+ @env['HTTP_X_CSRF_TOKEN'] = 'NeverGuess'
121
+ @env['HTTP_HOST'] = "5.6.7.8:7777"
122
+ status, type, body_array = json_drb_rack.call(@env)
123
+ expect(status).to eql 403
124
+ expect(type).to eql({'Content-Type' => "text/plain"})
125
+ expect(body_array).to eql ["Forbidden: #{@env['HTTP_HOST']} not in allowed hosts"]
126
+
127
+ json_drb_rack = JsonDrbRack.new(MockDRb.new(true), MockSystem.new('NeverGuess', ['5.6.7.8:7777']))
128
+ @env['HTTP_X_CSRF_TOKEN'] = 'NeverGuess'
129
+ @env['HTTP_HOST'] = "5.6.7.8:7777"
130
+ status, type, body_array = json_drb_rack.call(@env)
131
+ expect(status).to eql 200
132
+ expect(type).to eql({'Content-Type' => "application/json-rpc"})
133
+ expect(body_array).to eql ["response"]
134
+ end
135
+
136
+ it "Handles Allowed Origins" do
137
+ json_drb_rack = JsonDrbRack.new(MockDRb.new(true), MockSystem.new('NeverGuess'))
138
+ @env['HTTP_X_CSRF_TOKEN'] = 'NeverGuess'
139
+ @env['HTTP_ORIGIN'] = "5.6.7.8:7777"
140
+ status, type, body_array = json_drb_rack.call(@env)
141
+ expect(status).to eql 403
142
+ expect(type).to eql({'Content-Type' => "text/plain"})
143
+ expect(body_array).to eql ["Forbidden: #{@env['HTTP_ORIGIN']} not in allowed origins"]
144
+
145
+ json_drb_rack = JsonDrbRack.new(MockDRb.new(true), MockSystem.new('NeverGuess', ['127.0.0.1:7777'], ['3.6.7.8:7777']))
146
+ @env['HTTP_X_CSRF_TOKEN'] = 'NeverGuess'
147
+ @env['HTTP_ORIGIN'] = "3.6.7.8:7777"
148
+ status, type, body_array = json_drb_rack.call(@env)
149
+ expect(status).to eql 200
150
+ expect(type).to eql({'Content-Type' => "application/json-rpc"})
151
+ expect(body_array).to eql ["response"]
152
+ end
153
+
154
+ it "Only accepts posts" do
155
+ json_drb_rack = JsonDrbRack.new(MockDRb.new(true), MockSystem.new('NeverGuess'))
156
+ @env['HTTP_X_CSRF_TOKEN'] = 'NeverGuess'
157
+ @env["REQUEST_METHOD"] = "GET"
158
+ status, type, body_array = json_drb_rack.call(@env)
159
+ expect(status).to eql 405
160
+ expect(type).to eql({'Content-Type' => "text/plain"})
161
+ expect(body_array).to eql ["Request not allowed"]
162
+ end
163
+
164
+ end
165
+ end
166
+ end
@@ -238,25 +238,25 @@ module Cosmos
238
238
 
239
239
  it "reports an error if there is no 'result' or 'error' key" do
240
240
  json = JsonRpcResponse.new(10).as_json
241
- expect { JsonRpcResponse.from_json(json.to_json) }.to raise_error("Invalid JSON-RPC 2.0 Response")
241
+ expect { JsonRpcResponse.from_json(json.to_json) }.to raise_error(/Invalid JSON-RPC 2.0 Response/)
242
242
  end
243
243
 
244
244
  it "reports an error if the version isn't 2.0" do
245
245
  json = JsonRpcResponse.new(10).as_json
246
246
  json['jsonrpc'] = "1.1"
247
247
  json['result'] = "true"
248
- expect { JsonRpcResponse.from_json(json.to_json) }.to raise_error("Invalid JSON-RPC 2.0 Response")
248
+ expect { JsonRpcResponse.from_json(json.to_json) }.to raise_error(/Invalid JSON-RPC 2.0 Response/)
249
249
  end
250
250
 
251
251
  it "reports an error if there is both a 'result' and 'error' key" do
252
252
  json = JsonRpcResponse.new(10).as_json
253
253
  json['result'] = "true"
254
254
  json['error'] = {"code"=>-1, "message"=>"error"}
255
- expect { JsonRpcResponse.from_json(json.to_json) }.to raise_error("Invalid JSON-RPC 2.0 Response")
255
+ expect { JsonRpcResponse.from_json(json.to_json) }.to raise_error(/Invalid JSON-RPC 2.0 Response/)
256
256
  end
257
257
 
258
258
  it "reports an error if it is not json" do
259
- expect { JsonRpcResponse.from_json(Object.new) }.to raise_error("Invalid JSON-RPC 2.0 Response")
259
+ expect { JsonRpcResponse.from_json(Object.new) }.to raise_error(/Invalid JSON-RPC 2.0 Response/)
260
260
  end
261
261
 
262
262
  it "reports an error if the error hash is bad" do
@@ -268,4 +268,3 @@ module Cosmos
268
268
 
269
269
  end
270
270
  end
271
-
@@ -0,0 +1,81 @@
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
+ if RbConfig::CONFIG['target_os'] !~ /mswin|mingw|cygwin/i and RUBY_ENGINE == 'ruby' and !ENV['TRAVIS']
12
+
13
+ require 'spec_helper'
14
+ require 'cosmos/io/posix_serial_driver'
15
+
16
+ module Cosmos
17
+
18
+ describe PosixSerialDriver do
19
+ describe "instance" do
20
+ it "enforces the baud rate to a known value" do
21
+ expect { PosixSerialDriver.new('/dev/ttyS0',10,:NONE) }.to raise_error(ArgumentError, "Invalid baud rate: 10")
22
+ end
23
+
24
+ it "supports even, odd, or no parity" do
25
+ expect { PosixSerialDriver.new('/dev/ttyS0',9600,:EVEN).close }.to_not raise_error
26
+ expect { PosixSerialDriver.new('/dev/ttyS0',9600,:ODD).close }.to_not raise_error
27
+ expect { PosixSerialDriver.new('/dev/ttyS0',9600,:NONE).close }.to_not raise_error
28
+ expect { PosixSerialDriver.new('/dev/ttyS0',9600,:BLAH) }.to raise_error(ArgumentError, "Invalid parity: BLAH")
29
+ end
30
+
31
+ it "supports 1 or 2 stop bits" do
32
+ expect { PosixSerialDriver.new('/dev/ttyS0',9600,:NONE,1).close }.to_not raise_error
33
+ expect { PosixSerialDriver.new('/dev/ttyS0',9600,:NONE,2).close }.to_not raise_error
34
+ expect { PosixSerialDriver.new('/dev/ttyS0',9600,:NONE,3) }.to raise_error(ArgumentError, "Invalid stop bits: 3")
35
+ end
36
+
37
+ it "supports 5-8 data bits" do
38
+ (5..8).each do |data_bits|
39
+ driver = PosixSerialDriver.new('/dev/ttyS0',9600,:NONE,1,10,nil,:NONE,data_bits)
40
+ handle = driver.instance_variable_get(:@handle)
41
+ expect(handle.tcgetattr.cflag & Termios::CSIZE).to eq(Termios.const_get("CS#{data_bits}"))
42
+ driver.close
43
+ end
44
+ expect { PosixSerialDriver.new('/dev/ttyS0',9600,:NONE,1,10,nil,:NONE,9) }.to raise_error(ArgumentError, "Invalid data bits: 9")
45
+ end
46
+
47
+ it "sets arbitrary Posix structure elements" do
48
+ driver = PosixSerialDriver.new('/dev/ttyS0',9600,:NONE,1,10,nil,:NONE,8)
49
+ handle = driver.instance_variable_get(:@handle)
50
+ # Verify non of the things we're going to set are already set
51
+ expect(handle.tcgetattr.iflag & Termios::IGNBRK).to eq(0)
52
+ expect(handle.tcgetattr.oflag & Termios::OPOST).to eq(0)
53
+ expect(handle.tcgetattr.cflag & Termios::CLOCAL).to eq(Termios::CLOCAL) # We set this by default
54
+ expect(handle.tcgetattr.lflag & Termios::ECHO).to eq(0)
55
+ expect(handle.tcgetattr.cc[Termios::VMIN]).to eq(1)
56
+ driver.close
57
+ # When setting a field the "1" is optional. When clearing a field the "0" is required.
58
+ # Entries in the "cc" special characters field are automatically converted to integers if they are numbers
59
+ struct = [["iflag", "IGNBRK"], ["oflag", "OPOST", "1"], ["cflag", "CLOCAL", "0"], ["lflag", "ECHO"], ["cc", "VMIN", "2"]]
60
+ driver = PosixSerialDriver.new('/dev/ttyS0',9600,:NONE,1,10,nil,:NONE,8,struct)
61
+ handle = driver.instance_variable_get(:@handle)
62
+ expect(handle.tcgetattr.iflag & Termios::IGNBRK).to eq(Termios::IGNBRK)
63
+ expect(handle.tcgetattr.oflag & Termios::OPOST).to eq(Termios::OPOST)
64
+ expect(handle.tcgetattr.cflag & Termios::CLOCAL).to eq(0)
65
+ expect(handle.tcgetattr.lflag & Termios::ECHO).to eq(Termios::ECHO)
66
+ expect(handle.tcgetattr.cc[Termios::VMIN]).to eq(2)
67
+ driver.close
68
+ end
69
+ end
70
+
71
+ describe "close, closed?" do
72
+ it "closes the handle" do
73
+ driver = PosixSerialDriver.new('/dev/ttyS0',9600)
74
+ expect(driver.closed?).to be false
75
+ driver.close
76
+ expect(driver.closed?).to be true
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -19,7 +19,8 @@ if RUBY_ENGINE == 'ruby' or Gem.win_platform?
19
19
  before(:each) do
20
20
  allow(Win32).to receive(:create_file).and_return(Object.new)
21
21
  state = double("comm_state")
22
- allow(state).to receive(:write)
22
+ @dcb_struct = {}
23
+ allow(state).to receive(:write) { |key, value| @dcb_struct[key] = value }
23
24
  allow(Win32).to receive(:get_comm_state).and_return(state)
24
25
  allow(Win32).to receive(:set_comm_state)
25
26
  allow(Win32).to receive(:set_comm_timeouts)
@@ -34,12 +35,14 @@ if RUBY_ENGINE == 'ruby' or Gem.win_platform?
34
35
  expect { Win32SerialDriver.new('COM1',9600,:EVEN) }.to_not raise_error
35
36
  expect { Win32SerialDriver.new('COM1',9600,:ODD) }.to_not raise_error
36
37
  expect { Win32SerialDriver.new('COM1',9600,:NONE) }.to_not raise_error
38
+ expect(@dcb_struct["Parity"]).to_not be_nil # Simply check that Parity was set
37
39
  expect { Win32SerialDriver.new('COM1',9600,:BLAH) }.to raise_error(ArgumentError, "Invalid parity: BLAH")
38
40
  end
39
41
 
40
42
  it "supports 1 or 2 stop bits" do
41
43
  expect { Win32SerialDriver.new('COM1',9600,:NONE,1) }.to_not raise_error
42
44
  expect { Win32SerialDriver.new('COM1',9600,:NONE,2) }.to_not raise_error
45
+ expect(@dcb_struct["StopBits"]).to_not be_nil # Simply check that StopBits was set
43
46
  expect { Win32SerialDriver.new('COM1',9600,:NONE,3) }.to raise_error(ArgumentError, "Invalid stop bits: 3")
44
47
  end
45
48
 
@@ -49,6 +52,19 @@ if RUBY_ENGINE == 'ruby' or Gem.win_platform?
49
52
  expect { Win32SerialDriver.new('COM1',9600,:NONE,1,10,nil,0.01,1000,:NONE,7) }.to_not raise_error
50
53
  expect { Win32SerialDriver.new('COM1',9600,:NONE,1,10,nil,0.01,1000,:NONE,8) }.to_not raise_error
51
54
  expect { Win32SerialDriver.new('COM1',9600,:NONE,1,10,nil,0.01,1000,:NONE,9) }.to raise_error(ArgumentError, "Invalid data bits: 9")
55
+ expect(@dcb_struct["ByteSize"]).to_not be_nil # Simply check that ByteSize was set
56
+ end
57
+
58
+ it "sets arbitrary Windows DCB structure elements" do
59
+ Win32SerialDriver.new('COM1',9600,:NONE,1,10,nil,0.01,1000,:NONE,8)
60
+ expect(@dcb_struct["fOutxDsrFlow"]).to be_nil # This isn't set by default
61
+ expect(@dcb_struct["Parity"]).to eq(0)
62
+ # Set a new variable in the Windows DCB struct and override the :NONE parity
63
+ # We pass them in as strings because that's how they're parsed
64
+ struct = [["fOutxDsrFlow", "1"], ["Parity", "4"]]
65
+ Win32SerialDriver.new('COM1',9600,:NONE,1,10,nil,0.01,1000,:NONE,8,struct)
66
+ expect(@dcb_struct["fOutxDsrFlow"]).to eq(1)
67
+ expect(@dcb_struct["Parity"]).to eq(4)
52
68
  end
53
69
 
54
70
  it "calculates the correct timeouts" do
@@ -703,6 +703,114 @@ module Cosmos
703
703
  end
704
704
  end
705
705
 
706
+ context "with ALLOW_ROUTER_COMMANDING" do
707
+ it "takes 0 parameters" do
708
+ tf = Tempfile.new('unittest')
709
+ tf.puts("ALLOW_ROUTER_COMMANDING BLAH TRUE")
710
+ tf.close
711
+ expect { System.instance.process_file(tf.path) }.to raise_error(ConfigParser::Error, /Too many parameters for ALLOW_ROUTER_COMMANDING./)
712
+ tf.unlink
713
+ end
714
+
715
+ it "allows router commanding" do
716
+ tf = Tempfile.new('unittest')
717
+ tf.puts("ALLOW_ROUTER_COMMANDING")
718
+ tf.close
719
+ expect(System.allow_router_commanding).to be false
720
+ System.instance.process_file(tf.path)
721
+ expect(System.allow_router_commanding).to be true
722
+ tf.unlink
723
+ end
724
+
725
+ it "it disallows router commanding if not present" do
726
+ tf = Tempfile.new('unittest')
727
+
728
+ tf.close
729
+ expect(System.allow_router_commanding).to be false
730
+ System.instance.process_file(tf.path)
731
+ expect(System.allow_router_commanding).to be false
732
+ tf.unlink
733
+ end
734
+ end
735
+
736
+ context "with X_CSRF_TOKEN" do
737
+ it "takes 1 parameters" do
738
+ tf = Tempfile.new('unittest')
739
+ tf.puts("X_CSRF_TOKEN")
740
+ tf.close
741
+ expect { System.instance.process_file(tf.path) }.to raise_error(ConfigParser::Error, /Not enough parameters for X_CSRF_TOKEN./)
742
+ tf.unlink
743
+
744
+ tf = Tempfile.new('unittest')
745
+ tf.puts("X_CSRF_TOKEN localhost true")
746
+ tf.close
747
+ expect { System.instance.process_file(tf.path) }.to raise_error(ConfigParser::Error, /Too many parameters for X_CSRF_TOKEN./)
748
+ tf.unlink
749
+ end
750
+
751
+ it "updates the CSRF token" do
752
+ tf = Tempfile.new('unittest')
753
+ tf.puts("X_CSRF_TOKEN ExtraSpecial")
754
+ tf.close
755
+ expect(System.x_csrf_token).to eql "SuperSecret"
756
+ System.instance.process_file(tf.path)
757
+ expect(System.x_csrf_token).to eql "ExtraSpecial"
758
+ tf.unlink
759
+ end
760
+ end
761
+
762
+ context "with ALLOW_HOST" do
763
+ it "takes 1 parameters" do
764
+ tf = Tempfile.new('unittest')
765
+ tf.puts("ALLOW_HOST")
766
+ tf.close
767
+ expect { System.instance.process_file(tf.path) }.to raise_error(ConfigParser::Error, /Not enough parameters for ALLOW_HOST./)
768
+ tf.unlink
769
+
770
+ tf = Tempfile.new('unittest')
771
+ tf.puts("ALLOW_HOST localhost true")
772
+ tf.close
773
+ expect { System.instance.process_file(tf.path) }.to raise_error(ConfigParser::Error, /Too many parameters for ALLOW_HOST./)
774
+ tf.unlink
775
+ end
776
+
777
+ it "adds to allowed hosts" do
778
+ tf = Tempfile.new('unittest')
779
+ tf.puts("ALLOW_HOST 1.2.3.4:8888")
780
+ tf.close
781
+ expect(System.allowed_hosts).to_not include("1.2.3.4:8888")
782
+ System.instance.process_file(tf.path)
783
+ expect(System.allowed_hosts).to include("1.2.3.4:8888")
784
+ tf.unlink
785
+ end
786
+ end
787
+
788
+ context "with ALLOW_ORIGIN" do
789
+ it "takes 1 parameters" do
790
+ tf = Tempfile.new('unittest')
791
+ tf.puts("ALLOW_ORIGIN")
792
+ tf.close
793
+ expect { System.instance.process_file(tf.path) }.to raise_error(ConfigParser::Error, /Not enough parameters for ALLOW_ORIGIN./)
794
+ tf.unlink
795
+
796
+ tf = Tempfile.new('unittest')
797
+ tf.puts("ALLOW_ORIGIN localhost true")
798
+ tf.close
799
+ expect { System.instance.process_file(tf.path) }.to raise_error(ConfigParser::Error, /Too many parameters for ALLOW_ORIGIN./)
800
+ tf.unlink
801
+ end
802
+
803
+ it "adds to allowed origins" do
804
+ tf = Tempfile.new('unittest')
805
+ tf.puts("ALLOW_ORIGIN 1.2.3.4:8888")
806
+ tf.close
807
+ expect(System.allowed_origins).to_not include("1.2.3.4:8888")
808
+ System.instance.process_file(tf.path)
809
+ expect(System.allowed_origins).to include("1.2.3.4:8888")
810
+ tf.unlink
811
+ end
812
+ end
813
+
706
814
  context "with ALLOW_ACCESS" do
707
815
  it "takes 1 parameters" do
708
816
  tf = Tempfile.new('unittest')