cosmos 4.0.3-java → 4.1.0-java

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 (123) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -5
  3. data/Manifest.txt +11 -1
  4. data/README.md +3 -2
  5. data/Rakefile +18 -4
  6. data/appveyor.yml +19 -0
  7. data/cosmos.gemspec +12 -3
  8. data/data/config/cmd_tlm_server.yaml +3 -0
  9. data/data/crc.txt +63 -60
  10. data/demo/config/targets/INST/cmd_tlm_server.txt +1 -0
  11. data/demo/config/targets/INST/cmd_tlm_server2.txt +7 -0
  12. data/demo/config/tools/cmd_sequence/cmd_sequence.txt +2 -0
  13. data/demo/config/tools/cmd_tlm_server/cmd_tlm_server.txt +8 -12
  14. data/demo/config/tools/cmd_tlm_server/cmd_tlm_server2.txt +7 -9
  15. data/demo/lib/cmd_sequence_exporter.rb +52 -0
  16. data/demo/lib/example_background_task.rb +1 -0
  17. data/demo/procedures/replay_test.rb +32 -0
  18. data/ext/cosmos/ext/structure/structure.c +39 -3
  19. data/install/config/tools/cmd_tlm_server/cmd_tlm_server.txt +1 -0
  20. data/install/config/tools/launcher/launcher.txt +2 -0
  21. data/lib/cosmos/config/config_parser.rb +2 -0
  22. data/lib/cosmos/core_ext/io.rb +89 -60
  23. data/lib/cosmos/gui/qt.rb +5 -8
  24. data/lib/cosmos/gui/qt_tool.rb +8 -8
  25. data/lib/cosmos/gui/text/ruby_editor.rb +12 -12
  26. data/lib/cosmos/gui/utilities/script_module_gui.rb +9 -9
  27. data/lib/cosmos/gui/widgets/realtime_button_bar.rb +18 -17
  28. data/lib/cosmos/interfaces/protocols/fixed_protocol.rb +2 -2
  29. data/lib/cosmos/interfaces/protocols/template_protocol.rb +3 -0
  30. data/lib/cosmos/interfaces/udp_interface.rb +27 -14
  31. data/lib/cosmos/io/buffered_file.rb +0 -1
  32. data/lib/cosmos/io/json_drb.rb +134 -214
  33. data/lib/cosmos/io/json_drb_object.rb +22 -61
  34. data/lib/cosmos/io/json_drb_rack.rb +79 -0
  35. data/lib/cosmos/io/json_rpc.rb +27 -0
  36. data/lib/cosmos/io/udp_sockets.rb +102 -58
  37. data/lib/cosmos/packets/commands.rb +1 -1
  38. data/lib/cosmos/packets/structure.rb +1 -1
  39. data/lib/cosmos/packets/structure_item.rb +37 -5
  40. data/lib/cosmos/script/cmd_tlm_server.rb +76 -2
  41. data/lib/cosmos/script/replay.rb +60 -0
  42. data/lib/cosmos/script/script.rb +20 -2
  43. data/lib/cosmos/script/scripting.rb +9 -9
  44. data/lib/cosmos/script/tools.rb +14 -0
  45. data/lib/cosmos/system/system.rb +185 -92
  46. data/lib/cosmos/system/target.rb +1 -1
  47. data/lib/cosmos/tools/cmd_sequence/cmd_sequence.rb +44 -4
  48. data/lib/cosmos/tools/cmd_sequence/sequence_item.rb +4 -0
  49. data/lib/cosmos/tools/cmd_sequence/sequence_list.rb +7 -0
  50. data/lib/cosmos/tools/cmd_tlm_server/api.rb +347 -20
  51. data/lib/cosmos/tools/cmd_tlm_server/background_tasks.rb +3 -0
  52. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +329 -111
  53. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +13 -0
  54. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_gui.rb +261 -95
  55. data/lib/cosmos/tools/cmd_tlm_server/gui/interfaces_tab.rb +46 -35
  56. data/lib/cosmos/tools/cmd_tlm_server/gui/logging_tab.rb +18 -8
  57. data/lib/cosmos/tools/cmd_tlm_server/gui/packets_tab.rb +39 -28
  58. data/lib/cosmos/tools/cmd_tlm_server/gui/replay_tab.rb +242 -0
  59. data/lib/cosmos/tools/cmd_tlm_server/gui/status_tab.rb +24 -8
  60. data/lib/cosmos/tools/cmd_tlm_server/gui/targets_tab.rb +18 -6
  61. data/lib/cosmos/tools/cmd_tlm_server/limits_groups_background_task.rb +5 -4
  62. data/lib/cosmos/tools/cmd_tlm_server/replay_backend.rb +375 -0
  63. data/lib/cosmos/tools/cmd_tlm_server/routers.rb +10 -2
  64. data/lib/cosmos/tools/data_viewer/data_viewer.rb +40 -5
  65. data/lib/cosmos/tools/handbook_creator/handbook_creator_config.rb +18 -20
  66. data/lib/cosmos/tools/launcher/launcher_config.rb +5 -16
  67. data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +65 -39
  68. data/lib/cosmos/tools/packet_viewer/packet_viewer.rb +19 -0
  69. data/lib/cosmos/tools/replay/replay.rb +5 -505
  70. data/lib/cosmos/tools/script_runner/script_audit.rb +1 -0
  71. data/lib/cosmos/tools/script_runner/script_runner.rb +3 -4
  72. data/lib/cosmos/tools/script_runner/script_runner_config.rb +3 -4
  73. data/lib/cosmos/tools/script_runner/script_runner_frame.rb +44 -23
  74. data/lib/cosmos/tools/test_runner/results_writer.rb +4 -0
  75. data/lib/cosmos/tools/test_runner/test_runner.rb +0 -3
  76. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_realtime_thread.rb +6 -2
  77. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_tool.rb +26 -1
  78. data/lib/cosmos/tools/tlm_viewer/screen.rb +24 -1
  79. data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +25 -0
  80. data/lib/cosmos/tools/tlm_viewer/tlm_viewer_config.rb +24 -14
  81. data/lib/cosmos/top_level.rb +34 -24
  82. data/lib/cosmos/utilities/csv.rb +60 -8
  83. data/lib/cosmos/version.rb +5 -5
  84. data/spec/config/config_parser_spec.rb +10 -1
  85. data/spec/core_ext/socket_spec.rb +4 -2
  86. data/spec/gui/utilities/script_module_gui_spec.rb +102 -0
  87. data/spec/install/config/data/data.txt +1 -0
  88. data/spec/install/config/targets/INST/cmd_tlm/inst_cmds.txt +2 -0
  89. data/spec/interfaces/cmd_tlm_server_interface_spec.rb +1 -2
  90. data/spec/interfaces/protocols/template_protocol_spec.rb +72 -2
  91. data/spec/interfaces/serial_interface_spec.rb +1 -1
  92. data/spec/interfaces/udp_interface_spec.rb +14 -0
  93. data/spec/io/buffered_file_spec.rb +37 -0
  94. data/spec/io/json_drb_object_spec.rb +2 -15
  95. data/spec/io/json_drb_spec.rb +61 -121
  96. data/spec/io/udp_sockets_spec.rb +42 -2
  97. data/spec/packet_logs/packet_log_reader_spec.rb +5 -2
  98. data/spec/packets/binary_accessor_spec.rb +1 -1
  99. data/spec/packets/packet_item_spec.rb +1 -1
  100. data/spec/packets/structure_item_spec.rb +5 -6
  101. data/spec/script/cmd_tlm_server_spec.rb +39 -4
  102. data/spec/script/commands_disconnect_spec.rb +1 -1
  103. data/spec/script/commands_spec.rb +2 -1
  104. data/spec/script/scripting_spec.rb +18 -3
  105. data/spec/script/telemetry_spec.rb +5 -0
  106. data/spec/spec_helper.rb +43 -26
  107. data/spec/streams/tcpip_socket_stream_spec.rb +2 -2
  108. data/spec/system/system_spec.rb +11 -9
  109. data/spec/system/target_spec.rb +3 -0
  110. data/spec/tools/cmd_tlm_server/api_spec.rb +543 -29
  111. data/spec/tools/cmd_tlm_server/background_task_spec.rb +2 -2
  112. data/spec/tools/cmd_tlm_server/background_tasks_spec.rb +31 -75
  113. data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +199 -66
  114. data/spec/tools/cmd_tlm_server/cmd_tlm_server_spec.rb +85 -9
  115. data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +29 -127
  116. data/spec/tools/cmd_tlm_server/router_thread_spec.rb +10 -50
  117. data/spec/tools/launcher/launcher_config_spec.rb +1 -1
  118. data/spec/tools/table_manager/table_item_spec.rb +1 -1
  119. data/spec/tools/table_manager/tablemanager_core_spec.rb +4 -4
  120. data/spec/top_level/top_level_spec.rb +151 -3
  121. data/spec/utilities/csv_spec.rb +24 -5
  122. metadata +61 -9
  123. data/lib/cosmos/tools/replay/replay_server.rb +0 -91
@@ -41,7 +41,7 @@ if RUBY_ENGINE == 'ruby' or Gem.win_platform?
41
41
  describe "connect" do
42
42
  it "passes a new SerialStream to the stream protocol" do
43
43
  # Ensure the 'NONE' parity is coverted to a symbol
44
- if Kernel.is_windows?
44
+ if Kernel.is_windows? && !ENV['APPVEYOR']
45
45
  i = SerialInterface.new('COM1','COM1','9600','NONE','1','0','0','burst')
46
46
  expect(i.connected?).to be false
47
47
  i.connect
@@ -83,6 +83,20 @@ module Cosmos
83
83
  expect(i.instance_variable_get(:@write_socket)).to be_nil
84
84
  expect(i.instance_variable_get(:@read_socket)).to be_nil
85
85
  end
86
+
87
+ it "creates one socket if read_port == write_src_port" do
88
+ i = UdpInterface.new('localhost','8888','8889', '8889')
89
+ expect(i.connected?).to be false
90
+ i.connect
91
+ expect(i.connected?).to be true
92
+ expect(i.instance_variable_get(:@write_socket)).to_not be_nil
93
+ expect(i.instance_variable_get(:@read_socket)).to_not be_nil
94
+ expect(i.instance_variable_get(:@read_socket)).to eql i.instance_variable_get(:@write_socket)
95
+ i.disconnect
96
+ expect(i.connected?).to be false
97
+ expect(i.instance_variable_get(:@write_socket)).to be_nil
98
+ expect(i.instance_variable_get(:@read_socket)).to be_nil
99
+ end
86
100
  end
87
101
 
88
102
  describe "read" do
@@ -50,6 +50,17 @@ module Cosmos
50
50
  end
51
51
  end
52
52
 
53
+ it "handles trying to read past the end" do
54
+ file = BufferedFile.open(@filename, "rb") do |file|
55
+ file.seek(-16, IO::SEEK_END)
56
+ expect(file.pos).to eql ((2 * BufferedFile::BUFFER_SIZE) - 16)
57
+ expect(file.read(DATA.length * 10)).to eql(DATA)
58
+ expect(file.pos).to eql BufferedFile::BUFFER_SIZE * 2
59
+ expect(file.read(DATA.length)).to be_nil
60
+ expect(file.pos).to eql BufferedFile::BUFFER_SIZE * 2
61
+ end
62
+ end
63
+
53
64
  it "reads equal to the buffer size" do
54
65
  file = BufferedFile.open(@filename, "rb") do |file|
55
66
  expect(file.read(BufferedFile::BUFFER_SIZE)).to eql(DATA * (BufferedFile::BUFFER_SIZE / DATA.length))
@@ -69,9 +80,35 @@ module Cosmos
69
80
  expect(file.read(BufferedFile::BUFFER_SIZE + 1)).to be_nil
70
81
  end
71
82
  end
83
+
84
+ it "reads greater than the buffer size after a previous read" do
85
+ file = BufferedFile.open(@filename, "rb") do |file|
86
+ expect(file.read(DATA.length * 10)).to eql(DATA * 10)
87
+ expect(file.pos).to eql DATA.length * 10
88
+ expect(file.read(BufferedFile::BUFFER_SIZE + 1)).to eql(DATA * ((BufferedFile::BUFFER_SIZE + 10) / DATA.length) << DATA[0])
89
+ expect(file.pos).to eql(DATA.length * 10 + BufferedFile::BUFFER_SIZE + 1)
90
+ end
91
+ end
72
92
  end
73
93
 
74
94
  describe "seek" do
95
+ it "raises if given more than 2 arguments" do
96
+ file = BufferedFile.open(@filename, "rb") do |file|
97
+ expect { file.seek(0, 4, IO::SEEK_CUR) }.to raise_error(ArgumentError)
98
+ end
99
+ end
100
+
101
+ it "implies SEEK_SET with 1 argument" do
102
+ file = BufferedFile.open(@filename, "rb") do |file|
103
+ expect(file.read(8)).to eql DATA[0..7]
104
+ expect(file.pos).to eql 8
105
+ file.seek(4, IO::SEEK_CUR)
106
+ expect(file.pos).to eql 12
107
+ file.seek(0)
108
+ expect(file.pos).to eql 0
109
+ end
110
+ end
111
+
75
112
  it "has reads still work afterwards" do
76
113
  file = BufferedFile.open(@filename, "rb") do |file|
77
114
  expect(file.read(8)).to eql DATA[0..7]
@@ -38,30 +38,17 @@ module Cosmos
38
38
  end
39
39
 
40
40
  it "raises an exception if the remote connection can't be made" do
41
- json = JsonDRb.new
42
- json.start_service('127.0.0.1', 7777, self)
43
- allow_any_instance_of(Socket).to receive(:connect_nonblock) { raise "Error" }
44
41
  obj = JsonDRbObject.new("localhost", 7777)
45
42
  expect { obj.my_method(10) }.to raise_error(DRb::DRbConnError)
46
43
  obj.disconnect
47
- json.stop_service
48
44
  sleep(0.1)
49
45
  end
50
46
 
51
47
  it "retries the request and then raise an exception" do
52
- class JsonDRbObjectServer
53
- def my_method(param)
54
- param * 2
55
- end
56
- end
57
-
58
- json = JsonDRb.new
59
- json.start_service('127.0.0.1', 7777, JsonDRbObjectServer.new)
60
- allow(JsonDRb).to receive(:send_data) { raise "Error" }
48
+ allow_any_instance_of(HTTPClient).to receive(:post) { raise "Error" }
61
49
  obj = JsonDRbObject.new("localhost", 7777)
62
50
  expect { obj.my_method(10) }.to raise_error(DRb::DRbConnError)
63
51
  obj.disconnect
64
- json.stop_service
65
52
  sleep(0.1)
66
53
  end
67
54
 
@@ -86,7 +73,7 @@ module Cosmos
86
73
  json = JsonDRb.new
87
74
  json.start_service('127.0.0.1', 7777, JsonDRbObjectServer.new)
88
75
  obj = JsonDRbObject.new("localhost", 7777)
89
- allow(JsonDRb).to receive(:receive_message) { nil }
76
+ allow_any_instance_of(JsonDrbRack).to receive(:call) { sleep(5.0); nil }
90
77
  expect { obj.my_method(10) }.to raise_error(DRb::DRbConnError)
91
78
  obj.disconnect
92
79
  json.stop_service
@@ -11,6 +11,7 @@
11
11
  require 'spec_helper'
12
12
  require 'cosmos/io/json_drb'
13
13
  require 'cosmos/io/json_rpc'
14
+ require 'httpclient'
14
15
 
15
16
  module Cosmos
16
17
 
@@ -52,6 +53,18 @@ module Cosmos
52
53
  end
53
54
 
54
55
  describe "start_service" do
56
+
57
+ it "can be started again after stopping" do
58
+ @json.start_service('127.0.0.1', 7777, self)
59
+ @json.stop_service
60
+ @json.start_service('127.0.0.1', 7777, self)
61
+ @json.stop_service
62
+ expect { @json.start_service('blah', 7777, self) }.to raise_error(/JsonDRb http server could not be started/)
63
+ @json.stop_service
64
+ @json.start_service('127.0.0.1', 7777, self)
65
+ @json.stop_service
66
+ end
67
+
55
68
  it "does nothing when passed no parameters" do
56
69
  expect(@json.thread).to be_nil
57
70
  @json.start_service()
@@ -69,12 +82,10 @@ module Cosmos
69
82
  capture_io do |stdout|
70
83
  expect(@json.thread).to be_nil
71
84
  system_exit_count = $system_exit_count
72
- @json.start_service('blah', 7777, self)
73
- thread = @json.thread
85
+ expect { @json.start_service('blah', 7777, self) }.to raise_error(/JsonDRb http server could not be started/)
86
+ sleep 5
74
87
  expect($system_exit_count).to eql(system_exit_count + 1)
75
- sleep 0.1
76
-
77
- expect(stdout.string).to match /listen thread/
88
+ expect(stdout.string).to match /JsonDRb http server could not be started or unexpectedly died/
78
89
  @json.stop_service
79
90
  sleep(0.1)
80
91
  end
@@ -84,25 +95,33 @@ module Cosmos
84
95
  end
85
96
  end
86
97
 
98
+ it "raises an error if the server doesn't start" do
99
+ allow(Rack::Handler::Puma).to receive(:run) {}
100
+ expect { @json.start_service('127.0.0.1', 7777, self) }.to raise_error(/JsonDRb http server could not be started/)
101
+ end
102
+
87
103
  it "creates a single listen thread" do
88
104
  expect(@json.thread).to be_nil
89
105
  @json.start_service('127.0.0.1', 7777, self)
106
+ sleep(1)
90
107
  expect(@json.thread.alive?).to be true
91
- expect { @json.start_service('127.0.0.1', 7777, self) }.to raise_error(/Error binding to port/)
108
+ num_threads = running_threads.length
109
+ @json.start_service('127.0.0.1', 7777, self)
110
+ sleep(1)
111
+ expect(running_threads.length).to eql num_threads
92
112
  @json.stop_service
93
113
  sleep(0.1)
94
114
  end
95
115
 
96
116
  it "rescues listen thread exceptions" do
97
117
  capture_io do |stdout|
98
- allow_any_instance_of(TCPServer).to receive(:accept_nonblock) { raise "BLAH" }
99
- @json.start_service('127.0.0.1', 7777, self)
100
- socket = TCPSocket.open('127.0.0.1',7777)
101
- sleep 0.1
118
+ allow(Rack::Handler::Puma).to receive(:run) { raise "BLAH" }
119
+ expect { @json.start_service('127.0.0.1', 7777, self) }.to raise_error(/JsonDRb http server could not be started/)
120
+ sleep(0.1)
102
121
  @json.stop_service
103
122
  sleep(0.1)
104
123
 
105
- expect(stdout.string).to match /JsonDRb listen thread unexpectedly died/
124
+ expect(stdout.string).to match /JsonDRb http server could not be started or unexpectedly died/
106
125
  end
107
126
 
108
127
  Dir[File.join(Cosmos::USERPATH,"*_exception.txt")].each do |file|
@@ -110,19 +129,19 @@ module Cosmos
110
129
  end
111
130
  end
112
131
 
113
- it "ignores connections via the ACL" do
132
+ it "rejects posts via the ACL" do
114
133
  @json.acl = ACL.new(['deny','127.0.0.1'], ACL::ALLOW_DENY)
115
134
  @json.start_service('127.0.0.1', 7777, self)
116
- socket = TCPSocket.open('127.0.0.1',7777)
117
- sleep 0.1
118
- expect(socket.eof?).to be true
119
- socket.close
135
+ client = HTTPClient.new
136
+ res = client.post("http://127.0.0.1:7777", "")
137
+ expect(res.status).to eq 403
138
+ expect(res.body).to match /Forbidden/
120
139
  @json.stop_service
121
140
  sleep(0.1)
122
141
  end
123
142
  end
124
143
 
125
- describe "receive_message" do
144
+ describe "process_request" do
126
145
  it "processes success requests" do
127
146
  class MyServer1
128
147
  def my_method(param)
@@ -130,15 +149,9 @@ module Cosmos
130
149
  end
131
150
 
132
151
  @json.start_service('127.0.0.1', 7777, MyServer1.new)
133
- socket = TCPSocket.open('127.0.0.1',7777)
134
- sleep 0.1
135
- request = JsonRpcRequest.new('my_method', 'param', 1).to_json
136
- JsonDRb.send_data(socket, request)
137
- response_data = JsonDRb.receive_message(socket, '', @pipe_reader)
138
- response = JsonRpcResponse.from_json(response_data)
139
- expect(response).to be_a(JsonRpcSuccessResponse)
140
- socket.close
141
- sleep 0.1
152
+ request_data = JsonRpcRequest.new('my_method', 'param', 1).to_json
153
+ response_data, error_code = @json.process_request(request_data, Time.now)
154
+ expect(error_code).to eq nil
142
155
  @json.stop_service
143
156
  sleep(0.1)
144
157
  end
@@ -148,17 +161,10 @@ module Cosmos
148
161
  end
149
162
 
150
163
  @json.start_service('127.0.0.1', 7777, MyServer2.new)
151
- socket = TCPSocket.open('127.0.0.1',7777)
152
- sleep 0.1
153
- request = JsonRpcRequest.new('my_method', 'param', 1).to_json
154
- JsonDRb.send_data(socket, request)
155
- response_data = JsonDRb.receive_message(socket, '', @pipe_reader)
156
- response = JsonRpcResponse.from_json(response_data)
157
- expect(response).to be_a(JsonRpcErrorResponse)
158
- expect(response.error.code).to eql -32601
159
- expect(response.error.message).to eql "Method not found"
160
- socket.close
161
- sleep 0.1
164
+ request_data = JsonRpcRequest.new('my_method', 'param', 1).to_json
165
+ response_data, error_code = @json.process_request(request_data, Time.now)
166
+ expect(error_code).to eql -32601
167
+ expect(response_data).to match /Method not found/
162
168
  @json.stop_service
163
169
  sleep(0.1)
164
170
  end
@@ -170,17 +176,10 @@ module Cosmos
170
176
  end
171
177
 
172
178
  @json.start_service('127.0.0.1', 7777, MyServer3.new)
173
- socket = TCPSocket.open('127.0.0.1',7777)
174
- sleep 0.1
175
- request = JsonRpcRequest.new('my_method', 'param1', 1).to_json
176
- JsonDRb.send_data(socket, request)
177
- response_data = JsonDRb.receive_message(socket, '', @pipe_reader)
178
- response = JsonRpcResponse.from_json(response_data)
179
- expect(response).to be_a(JsonRpcErrorResponse)
180
- expect(response.error.code).to eql -32602
181
- expect(response.error.message).to eql "Invalid params"
182
- socket.close
183
- sleep 0.1
179
+ request_data = JsonRpcRequest.new('my_method', 'param1', 1).to_json
180
+ response_data, error_code = @json.process_request(request_data, Time.now)
181
+ expect(error_code).to eql -32602
182
+ expect(response_data).to match /Invalid params/
184
183
  @json.stop_service
185
184
  sleep(0.1)
186
185
  end
@@ -193,91 +192,32 @@ module Cosmos
193
192
  end
194
193
 
195
194
  @json.start_service('127.0.0.1', 7777, MyServer4.new)
196
- socket = TCPSocket.open('127.0.0.1',7777)
197
- sleep 0.1
198
- request = JsonRpcRequest.new('my_method', 'param', 1).to_json
199
- JsonDRb.send_data(socket, request)
200
- response_data = JsonDRb.receive_message(socket, '', @pipe_reader)
201
- response = JsonRpcResponse.from_json(response_data)
202
- expect(response).to be_a(JsonRpcErrorResponse)
203
- expect(response.error.code).to eql -1
204
- expect(response.error.message).to eql "Method Error"
205
- socket.close
206
- sleep 0.1
195
+ request_data = JsonRpcRequest.new('my_method', 'param', 1).to_json
196
+ response_data, error_code = @json.process_request(request_data, Time.now)
197
+ expect(error_code).to eql -1
198
+ expect(response_data).to match /Method Error/
207
199
  @json.stop_service
208
200
  sleep(0.1)
209
201
  end
210
202
 
211
203
  it "does not allow dangerous methods" do
212
204
  @json.start_service('127.0.0.1', 7777, self)
213
- socket = TCPSocket.open('127.0.0.1',7777)
214
- sleep 0.1
215
- request = JsonRpcRequest.new('send', 'param', 1).to_json
216
- JsonDRb.send_data(socket, request)
217
- response_data = JsonDRb.receive_message(socket, '', @pipe_reader)
218
- response = JsonRpcResponse.from_json(response_data)
219
- expect(response).to be_a(JsonRpcErrorResponse)
220
- expect(response.error.code).to eql -1
221
- expect(response.error.message).to eql "Cannot call unauthorized methods"
222
- socket.close
223
- sleep 0.1
205
+ request_data = JsonRpcRequest.new('send', 'param', 1).to_json
206
+ response_data, error_code = @json.process_request(request_data, Time.now)
207
+ expect(error_code).to eql -1
208
+ expect(response_data).to match /Cannot call unauthorized methods/
224
209
  @json.stop_service
225
210
  sleep(0.1)
226
211
  end
227
212
 
228
213
  it "handles an invalid JsonDRB request" do
229
214
  @json.start_service('127.0.0.1', 7777, self)
230
- socket = TCPSocket.open('127.0.0.1',7777)
231
- sleep 0.1
232
- request = JsonRpcRequest.new('send', 'param', 1).to_json
233
- request.gsub!("jsonrpc","version")
234
- request.gsub!("2.0","1.1")
235
- JsonDRb.send_data(socket, request)
236
- response_data = JsonDRb.receive_message(socket, '', @pipe_reader)
237
- response = JsonRpcResponse.from_json(response_data)
238
- expect(response).to be_a(JsonRpcErrorResponse)
239
- expect(response.error.code).to eql -32600
240
- expect(response.error.message).to eql "Invalid Request"
241
- socket.close
242
- sleep 0.1
243
- @json.stop_service
244
- sleep(0.1)
245
- end
246
- end
247
-
248
- describe "send_data" do
249
- it "retries if the socket blocks" do
250
- @json.start_service('127.0.0.1', 7777, self)
251
- socket = TCPSocket.open('127.0.0.1',7777)
252
- # Stub write_nonblock so it blocks
253
- $index = 0
254
- allow(socket).to receive(:write_nonblock) do
255
- case $index
256
- when 0
257
- $index += 1
258
- raise Errno::EWOULDBLOCK
259
- when 1
260
- $index += 1
261
- 5
262
- end
263
- end
264
- JsonDRb.send_data(socket, "\x00")
265
- socket.close
266
- @json.stop_service
267
- sleep(0.1)
268
- end
269
-
270
- it "eventuallies timeout if the socket blocks" do
271
- @json.start_service('127.0.0.1', 7777, self)
272
- socket = TCPSocket.open('127.0.0.1',7777)
273
- # Stub write_nonblock so it blocks
274
- $index = 0
275
- allow(socket).to receive(:write_nonblock) do
276
- raise Errno::EWOULDBLOCK
277
- end
278
- allow(IO).to receive(:select) { nil }
279
- expect { JsonDRb.send_data(socket, "\x00", 2) }.to raise_error(Timeout::Error)
280
- socket.close
215
+ request_data = JsonRpcRequest.new('send', 'param', 1).to_json
216
+ request_data.gsub!("jsonrpc","version")
217
+ request_data.gsub!("2.0","1.1")
218
+ response_data, error_code = @json.process_request(request_data, Time.now)
219
+ expect(error_code).to eql -32600
220
+ expect(response_data).to match /Invalid Request/
281
221
  @json.stop_service
282
222
  sleep(0.1)
283
223
  end
@@ -44,7 +44,7 @@ module Cosmos
44
44
 
45
45
  it "handles timeouts" do
46
46
  allow_any_instance_of(UDPSocket).to receive(:write_nonblock) { raise Errno::EWOULDBLOCK }
47
- expect(IO).to receive(:select).at_least(:once).and_return([], nil)
47
+ expect(IO).to receive(:fast_select).at_least(:once).and_return([], nil)
48
48
  udp_write = UdpWriteSocket.new('127.0.0.1', 8888)
49
49
  expect { udp_write.write("\x01\x02",2.0) }.to raise_error(Timeout::Error)
50
50
  udp_write.close
@@ -88,12 +88,52 @@ module Cosmos
88
88
 
89
89
  it "handles timeouts" do
90
90
  allow_any_instance_of(UDPSocket).to receive(:recvfrom_nonblock) { raise Errno::EWOULDBLOCK }
91
- expect(IO).to receive(:select).at_least(:once).and_return([], nil)
91
+ expect(IO).to receive(:fast_select).at_least(:once).and_return([], nil)
92
92
  udp_read = UdpReadSocket.new(8889)
93
93
  expect { udp_read.read(2.0) }.to raise_error(Timeout::Error)
94
94
  end
95
95
  end
96
96
 
97
97
  end
98
+
99
+ describe UdpReadWriteSocket do
100
+
101
+ describe "initialize" do
102
+ it "creates a socket" do
103
+ udp = UdpReadWriteSocket.new(8888)
104
+ expect(udp.local_address.ip_address).to eql '0.0.0.0'
105
+ expect(udp.local_address.ip_port).to eql 8888
106
+ udp.close
107
+ if RUBY_ENGINE == 'ruby' # UDP multicast does not work in Jruby
108
+ udp = UdpReadWriteSocket.new(8888, '0.0.0.0', 0, '224.0.1.1')
109
+ expect(IPAddr.new_ntoh(udp.getsockopt(Socket::IPPROTO_IP, Socket::IP_MULTICAST_IF).data).to_s).to eql "0.0.0.0"
110
+ udp.close
111
+ end
112
+ end
113
+ end
114
+
115
+ describe "read" do
116
+ it "reads data" do
117
+ udp_read = UdpReadWriteSocket.new(8888)
118
+ udp_write = UdpWriteSocket.new('127.0.0.1', 8888)
119
+ udp_write.write("\x01\x02",2.0)
120
+ expect(udp_read.read).to eql "\x01\x02"
121
+ udp_read.close
122
+ udp_write.close
123
+ end
124
+ end
125
+
126
+ describe "write" do
127
+ it "writes data" do
128
+ udp_read = UdpReadSocket.new(8888)
129
+ udp_write = UdpReadWriteSocket.new(0, "0.0.0.0", 8888, '127.0.0.1')
130
+ udp_write.write("\x01\x02",2.0)
131
+ expect(udp_read.read).to eql "\x01\x02"
132
+ udp_read.close
133
+ udp_write.close
134
+ end
135
+ end
136
+
137
+ end
98
138
  end
99
139