rubarb 0.2.0 → 0.2.11
Sign up to get free protection for your applications and to get access to all the features.
- 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
|