rubarb 0.2.0 → 0.2.11
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.
- data/README.md +89 -0
- data/examples/client.rb +3 -1
- data/examples/server.rb +1 -1
- data/lib/rubarb/connection.rb +61 -24
- data/lib/rubarb/incoming_connection.rb +9 -1
- data/lib/rubarb/outgoing_connection.rb +15 -0
- data/lib/rubarb/server.rb +21 -4
- data/spec/rubarb/connection_failure_spec.rb +0 -8
- data/spec/rubarb/connection_spec.rb +15 -10
- data/spec/rubarb/incoming_connection_spec.rb +6 -0
- data/spec/rubarb/integration_spec.rb +67 -8
- data/spec/rubarb/outgoing_connection_spec.rb +4 -0
- data/spec/rubarb/server_failure_spec.rb +124 -122
- data/spec/rubarb/server_spec.rb +4 -10
- data/spec/spec_helper.rb +28 -7
- metadata +79 -102
- data/.gitignore +0 -7
- data/README +0 -77
- data/Rakefile +0 -51
- data/VERSION +0 -1
@@ -76,4 +76,10 @@ describe Rubarb::IncomingConnection do
|
|
76
76
|
self.should_receive(:send_message).with(marshal_call(["00000002", "result"]))
|
77
77
|
reply("00000002", "result")
|
78
78
|
end
|
79
|
+
|
80
|
+
it "should handle empty message" do
|
81
|
+
self.should_not_receive(:send_message)
|
82
|
+
receive_message(marshal_call(""))
|
83
|
+
end
|
84
|
+
|
79
85
|
end
|
@@ -3,16 +3,48 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
3
3
|
require 'rubarb/server'
|
4
4
|
require 'rubarb/connection'
|
5
5
|
|
6
|
-
|
6
|
+
class TestClientApi
|
7
|
+
def name(responder)
|
8
|
+
responder.reply("Doug")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
describe "With Keep alives enables" do
|
14
|
+
|
15
|
+
before(:each) do
|
16
|
+
@server_api = mock("server")
|
17
|
+
@client_api = TestClientApi.new
|
7
18
|
|
8
|
-
|
9
|
-
|
10
|
-
|
19
|
+
@server = Rubarb::Server.new("127.0.0.1", 9441, @server_api, Rubarb::Default::INSECURE_METHODS, 0.1)
|
20
|
+
@connection = Rubarb::Connection.new("127.0.0.1", 9441, @client_api, Rubarb::Default::INSECURE_METHODS, 0.1)
|
21
|
+
end
|
22
|
+
|
23
|
+
after(:each) do
|
24
|
+
sync_stop(@server)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should communicate with the client" do
|
28
|
+
@callback_called = false
|
29
|
+
|
30
|
+
@server.start do |new_client|
|
31
|
+
new_client.name do|result|
|
32
|
+
result.should == "Doug"
|
33
|
+
@callback_called = true
|
34
|
+
end
|
11
35
|
end
|
36
|
+
|
37
|
+
@connection.start
|
38
|
+
|
39
|
+
wait_for {@callback_called}
|
40
|
+
|
12
41
|
end
|
13
42
|
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "Server to Client communication and response" do
|
46
|
+
|
14
47
|
before(:each) do
|
15
|
-
@reactor = start_reactor
|
16
48
|
@server_api = mock("server")
|
17
49
|
@client_api = TestClientApi.new
|
18
50
|
|
@@ -21,7 +53,7 @@ describe "Server to Client communication and response" do
|
|
21
53
|
end
|
22
54
|
|
23
55
|
after(:each) do
|
24
|
-
|
56
|
+
sync_stop(@server)
|
25
57
|
end
|
26
58
|
|
27
59
|
it "should communicate with the client" do
|
@@ -74,7 +106,6 @@ describe "Client to Server communication and response" do
|
|
74
106
|
end
|
75
107
|
|
76
108
|
before(:each) do
|
77
|
-
@reactor = start_reactor
|
78
109
|
@server_api = TestServerApi.new
|
79
110
|
@client_api = mock("client")
|
80
111
|
|
@@ -83,7 +114,7 @@ describe "Client to Server communication and response" do
|
|
83
114
|
end
|
84
115
|
|
85
116
|
after(:each) do
|
86
|
-
|
117
|
+
sync_stop(@server)
|
87
118
|
end
|
88
119
|
|
89
120
|
it "without a callback" do
|
@@ -171,4 +202,32 @@ describe "Client to Server communication and response" do
|
|
171
202
|
|
172
203
|
end
|
173
204
|
|
205
|
+
it "should close one of the connections" do
|
206
|
+
@server_side_client_proxy = nil
|
207
|
+
@client_side_closed = 0
|
208
|
+
@server.start do |new_connection|
|
209
|
+
@server_side_client_proxy = new_connection
|
210
|
+
end
|
211
|
+
|
212
|
+
@connection.errback do
|
213
|
+
@client_side_closed += 1
|
214
|
+
end
|
215
|
+
@connection.start
|
216
|
+
|
217
|
+
wait_for {!@server_side_client_proxy.nil?}
|
218
|
+
EM::next_tick {@server.connections[1].close_connection}
|
219
|
+
|
220
|
+
wait_for {@client_side_closed >= 1}
|
221
|
+
@client_side_closed.should == 1
|
222
|
+
|
223
|
+
@server_api.stub!(:foo) do |responder|
|
224
|
+
responder.reply("bar")
|
225
|
+
end
|
226
|
+
@connection.foo do |result|
|
227
|
+
@foobar = result
|
228
|
+
end
|
229
|
+
sleep(3)
|
230
|
+
@foobar.should_not == "bar"
|
231
|
+
end
|
232
|
+
|
174
233
|
end
|
@@ -7,8 +7,8 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
7
7
|
|
8
8
|
describe "Server Failures" do
|
9
9
|
|
10
|
-
CONNECTION_ERROR
|
11
|
-
NO_METHOD_ERROR
|
10
|
+
CONNECTION_ERROR = "Connection Failure"
|
11
|
+
NO_METHOD_ERROR = "received unexpected message :not_a_method"
|
12
12
|
INSECURE_METHOD_ERROR = "Remote client attempts to call method class, but was denied."
|
13
13
|
|
14
14
|
before(:all) do
|
@@ -16,11 +16,16 @@ describe "Server Failures" do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
before(:each) do
|
19
|
+
@port += 1
|
19
20
|
@server = Rubarb::Server.new("127.0.0.1", @port, mock("server"))
|
20
21
|
@connection1 = Rubarb::Connection.new("127.0.0.1", @port, mock("client"))
|
21
22
|
@connection2 = Rubarb::Connection.new("127.0.0.1", @port, mock("client"))
|
22
23
|
end
|
23
24
|
|
25
|
+
after(:each) do
|
26
|
+
sync_stop(@server)
|
27
|
+
end
|
28
|
+
|
24
29
|
def wait_for_connections(n, ttl, &block)
|
25
30
|
if ttl <= 0
|
26
31
|
fail("TTL expired")
|
@@ -35,104 +40,50 @@ describe "Server Failures" do
|
|
35
40
|
end
|
36
41
|
end
|
37
42
|
|
43
|
+
|
38
44
|
def check_messages(size, actual, expected)
|
39
45
|
actual.should have(size).items
|
40
46
|
(0...size).each { |i| actual[i].include?(expected[i]).should be_true }
|
41
47
|
end
|
42
48
|
|
43
49
|
def run_server_failure(blocks)
|
44
|
-
server_block
|
45
|
-
client_block
|
50
|
+
server_block = blocks[:server]
|
51
|
+
client_block = blocks[:client]
|
46
52
|
server_errback = blocks[:server_errback]
|
47
53
|
client_errback = blocks[:client_errback]
|
48
54
|
connected = false
|
49
55
|
errbacked = false
|
50
|
-
thread = start_reactor
|
51
56
|
EM.schedule do
|
52
|
-
@server.errback
|
53
|
-
@server.start
|
57
|
+
@server.errback { |e| server_errback.call(e) if server_errback; errbacked = true }
|
58
|
+
@server.start { |connection| server_block.call(connection) if server_block }
|
54
59
|
@connection1.errback { |e| client_errback.call(e) if client_errback; errbacked = true }
|
55
|
-
@connection1.start
|
60
|
+
@connection1.start { client_block.call(@connection1) if client_block; connected = true }
|
56
61
|
end
|
57
|
-
wait_for{connected}
|
58
|
-
wait_for{errbacked}
|
59
|
-
stop_reactor(thread)
|
60
|
-
end
|
61
|
-
|
62
|
-
it "should handle the loss of a client" do
|
63
|
-
EM.run do
|
64
|
-
@cons = 0
|
65
|
-
@server.start do |client|
|
66
|
-
@cons += 1
|
67
|
-
if (@cons == 2)
|
68
|
-
@connection1.stop
|
69
|
-
end
|
70
|
-
client.errback do
|
71
|
-
@cons -= 1
|
72
|
-
if @cons == 1
|
73
|
-
EM.stop
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
@connection1.start
|
79
|
-
@connection2.start
|
80
|
-
|
81
|
-
wait_for_connections(2, 10) do
|
82
|
-
@connection1.stop
|
83
|
-
wait_for_connections(1, 10) do
|
84
|
-
@cons.should == 1
|
85
|
-
EM.stop
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
it "should call errorback when port is already in use" do
|
92
|
-
errback_called = false
|
93
|
-
err_message = ""
|
94
|
-
|
95
|
-
thread = start_reactor
|
96
|
-
EM.run do
|
97
|
-
blocked_server = Rubarb::Server.new("127.0.0.1", @port, mock("server"))
|
98
|
-
|
99
|
-
blocked_server.errback do |e|
|
100
|
-
errback_called = true
|
101
|
-
err_message = e.message
|
102
|
-
end
|
103
|
-
|
104
|
-
@server.start
|
105
|
-
blocked_server.start
|
106
|
-
end
|
107
|
-
|
108
|
-
wait_for{errback_called}
|
109
|
-
stop_reactor(thread)
|
110
|
-
|
111
|
-
errback_called.should be_true
|
112
|
-
err_message.include?("acceptor").should be_true
|
62
|
+
wait_for { connected }
|
63
|
+
wait_for { errbacked }
|
113
64
|
end
|
114
65
|
|
115
66
|
it "handles no method call on server side" do
|
116
67
|
err_messages = []
|
117
|
-
expected_messages = [NO_METHOD_ERROR
|
68
|
+
expected_messages = [NO_METHOD_ERROR]
|
118
69
|
client_errback_block = Proc.new { |e| err_messages << e.message }
|
119
70
|
client_block = Proc.new { |connection| connection.not_a_method }
|
120
71
|
run_server_failure({:client => client_block, :client_errback => client_errback_block})
|
121
|
-
check_messages(
|
72
|
+
check_messages(1, err_messages, expected_messages)
|
122
73
|
end
|
123
74
|
|
124
75
|
it "handles no method call on client side" do
|
125
76
|
err_messages = []
|
126
|
-
expected_messages = [NO_METHOD_ERROR
|
77
|
+
expected_messages = [NO_METHOD_ERROR]
|
127
78
|
server_errback_block = Proc.new { |e| err_messages << e.message }
|
128
79
|
server_block = Proc.new { |connection| connection.not_a_method }
|
129
80
|
run_server_failure({:server => server_block, :server_errback => server_errback_block})
|
130
|
-
check_messages(
|
81
|
+
check_messages(1, err_messages, expected_messages)
|
131
82
|
end
|
132
83
|
|
133
84
|
it "handles insecure method call on server side" do
|
134
85
|
err_messages = []
|
135
|
-
expected_messages = [INSECURE_METHOD_ERROR
|
86
|
+
expected_messages = [INSECURE_METHOD_ERROR]
|
136
87
|
|
137
88
|
client_block = Proc.new do |connection|
|
138
89
|
connection.instance_eval("undef class")
|
@@ -140,15 +91,15 @@ describe "Server Failures" do
|
|
140
91
|
result.should be_a(InsecureMethodCallError)
|
141
92
|
end
|
142
93
|
end
|
143
|
-
|
94
|
+
|
144
95
|
client_errback_block = Proc.new { |e| err_messages << e.message }
|
145
96
|
run_server_failure({:server => client_block, :server_errback => client_errback_block})
|
146
|
-
check_messages(
|
97
|
+
check_messages(1, err_messages, expected_messages)
|
147
98
|
end
|
148
|
-
|
99
|
+
|
149
100
|
it "handles insecure method call on client side" do
|
150
101
|
err_messages = []
|
151
|
-
expected_messages = [INSECURE_METHOD_ERROR
|
102
|
+
expected_messages = [INSECURE_METHOD_ERROR]
|
152
103
|
|
153
104
|
server_block = Proc.new do |connection|
|
154
105
|
connection.instance_eval("undef class")
|
@@ -159,53 +110,9 @@ describe "Server Failures" do
|
|
159
110
|
|
160
111
|
server_errback_block = Proc.new { |e| err_messages << e.message }
|
161
112
|
run_server_failure({:server => server_block, :server_errback => server_errback_block})
|
162
|
-
check_messages(
|
163
|
-
end
|
164
|
-
|
165
|
-
it "removes unbinded connection from connections ivar" do
|
166
|
-
thread = start_reactor
|
167
|
-
connected = false
|
168
|
-
EM.schedule do
|
169
|
-
@server.start
|
170
|
-
@connection1.start {connected = true}
|
171
|
-
end
|
172
|
-
wait_for{connected}
|
173
|
-
@server.connections.size.times { @server.connections.first.unbind }
|
174
|
-
@server.connections.should have(0).items
|
175
|
-
stop_reactor(thread)
|
176
|
-
end
|
177
|
-
|
178
|
-
it "removes one unbinded connection from connections ivar of size two" do
|
179
|
-
thread = start_reactor
|
180
|
-
connected = false
|
181
|
-
@server.start
|
182
|
-
@connection1.start
|
183
|
-
@connection2.start {connected = true}
|
184
|
-
wait_for{connected}
|
185
|
-
2.times { @server.connections.first.unbind }
|
186
|
-
@server.connections.should have(2).items
|
187
|
-
stop_reactor(thread)
|
113
|
+
check_messages(1, err_messages, expected_messages)
|
188
114
|
end
|
189
115
|
|
190
|
-
it "does not error out after calling stop twice consecutively" do
|
191
|
-
EventMachine.should_receive(:stop_server).once
|
192
|
-
thread = start_reactor
|
193
|
-
connected = false
|
194
|
-
@server.start
|
195
|
-
@connection1.start {connected = true}
|
196
|
-
wait_for{connected}
|
197
|
-
stopped = []
|
198
|
-
@server.stop do |result|
|
199
|
-
stopped << result
|
200
|
-
end
|
201
|
-
@server.stop do |result|
|
202
|
-
stopped << result
|
203
|
-
end
|
204
|
-
wait_for{stopped.size == 2}
|
205
|
-
stopped.should == [true, false]
|
206
|
-
stop_reactor(thread)
|
207
|
-
end
|
208
|
-
|
209
116
|
it "executes all errback blocks when exception is thrown on client side" do
|
210
117
|
@errback1 = false
|
211
118
|
@errback2 = false
|
@@ -228,8 +135,8 @@ describe "Server Failures" do
|
|
228
135
|
|
229
136
|
@errback1.should be_true
|
230
137
|
@errback2.should be_true
|
231
|
-
@errback3.should
|
232
|
-
@errback4.should
|
138
|
+
@errback3.should be_false
|
139
|
+
@errback4.should be_false
|
233
140
|
end
|
234
141
|
|
235
142
|
it "executes all errback blocks when exception is thrown on server side" do
|
@@ -252,10 +159,105 @@ describe "Server Failures" do
|
|
252
159
|
run_server_failure({:server => server_block,
|
253
160
|
:client => client_block})
|
254
161
|
|
255
|
-
@errback1.should
|
256
|
-
@errback2.should
|
162
|
+
@errback1.should be_false
|
163
|
+
@errback2.should be_false
|
257
164
|
@errback3.should be_true
|
258
165
|
@errback4.should be_true
|
259
166
|
end
|
260
167
|
|
168
|
+
it "removes unbinded connection from connections ivar" do
|
169
|
+
connected = false
|
170
|
+
EM.schedule do
|
171
|
+
@server.start
|
172
|
+
@connection1.start { connected = true }
|
173
|
+
end
|
174
|
+
wait_for { connected }
|
175
|
+
@server.connections.size.times { @server.connections.first.unbind }
|
176
|
+
@server.connections.should have(0).items
|
177
|
+
end
|
178
|
+
|
179
|
+
it "removes one unbinded connection from connections ivar of size two" do
|
180
|
+
connected = false
|
181
|
+
@server.start
|
182
|
+
@connection1.start
|
183
|
+
@connection2.start { connected = true }
|
184
|
+
wait_for { connected }
|
185
|
+
2.times { @server.connections.first.unbind }
|
186
|
+
@server.connections.should have(2).items
|
187
|
+
end
|
188
|
+
|
189
|
+
it "does not error out after calling stop twice consecutively" do
|
190
|
+
connected = false
|
191
|
+
@server.start
|
192
|
+
@connection1.start { connected = true }
|
193
|
+
wait_for { connected }
|
194
|
+
stopped = []
|
195
|
+
@server.stop do |result|
|
196
|
+
stopped << result
|
197
|
+
end
|
198
|
+
@server.stop do |result|
|
199
|
+
stopped << result
|
200
|
+
end
|
201
|
+
wait_for { stopped.size == 2 }
|
202
|
+
stopped.should == [true, false]
|
203
|
+
end
|
204
|
+
|
205
|
+
|
206
|
+
it "should handle the loss of a client" do
|
207
|
+
pending "messes with Reactor running for all other tests"
|
208
|
+
EM.run do
|
209
|
+
@cons = 0
|
210
|
+
@server.start do |client|
|
211
|
+
@cons += 1
|
212
|
+
if (@cons == 2)
|
213
|
+
@connection1.stop
|
214
|
+
end
|
215
|
+
client.errback do
|
216
|
+
@cons -= 1
|
217
|
+
if @cons == 1
|
218
|
+
EM.stop
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
@connection1.start
|
224
|
+
@connection2.start
|
225
|
+
|
226
|
+
wait_for_connections(2, 10) do
|
227
|
+
@connection1.stop
|
228
|
+
wait_for_connections(1, 10) do
|
229
|
+
@cons.should == 1
|
230
|
+
EM.stop
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
it "should call errorback when port is already in use" do
|
237
|
+
pending "hangs on occasion"
|
238
|
+
errback_called = false
|
239
|
+
err_message = ""
|
240
|
+
|
241
|
+
thread = start_reactor
|
242
|
+
EM.run do
|
243
|
+
blocked_server = Rubarb::Server.new("127.0.0.1", @port, mock("server"))
|
244
|
+
|
245
|
+
blocked_server.errback do |e|
|
246
|
+
errback_called = true
|
247
|
+
err_message = e.message
|
248
|
+
end
|
249
|
+
|
250
|
+
@server.start
|
251
|
+
blocked_server.start
|
252
|
+
end
|
253
|
+
|
254
|
+
wait_for { errback_called }
|
255
|
+
stop_reactor(thread)
|
256
|
+
|
257
|
+
errback_called.should be_true
|
258
|
+
err_message.include?("acceptor").should be_true
|
259
|
+
@server.stop
|
260
|
+
blocked_server.stop
|
261
|
+
end
|
262
|
+
|
261
263
|
end
|