rjr 0.19.1 → 0.19.2

Sign up to get free protection for your applications and to get access to all the features.
data/specs/node_spec.rb CHANGED
@@ -177,7 +177,9 @@ module RJR
177
177
  n = Node.new
178
178
  n.on(:error) {}
179
179
  n.clear_event_handlers
180
- n.connection_event_handlers.should == {:closed => [], :error => []}
180
+ n.connection_event_handlers.should == { :opened => [],
181
+ :closed => [],
182
+ :error => [] }
181
183
  end
182
184
  end
183
185
 
@@ -186,7 +188,9 @@ module RJR
186
188
  bl = proc{}
187
189
  n = Node.new
188
190
  n.on(:error, &bl)
189
- n.connection_event_handlers.should == {:closed => [], :error => [bl]}
191
+ n.connection_event_handlers.should == { :opened => [],
192
+ :closed => [],
193
+ :error => [bl] }
190
194
  end
191
195
  end
192
196
 
@@ -247,6 +251,10 @@ module RJR
247
251
  connection = Object.new
248
252
  request = Messages::Request.new :id => 1, :method => 'foo'
249
253
  request_str = request.to_s
254
+ inter = Messages::Intermediate.parse request_str
255
+ Messages::Intermediate.should_receive(:parse).
256
+ with(request_str).
257
+ and_return(inter)
250
258
 
251
259
  node = Node.new
252
260
  node.tp.should_receive(:<<) { |job|
@@ -254,7 +262,7 @@ module RJR
254
262
  job.exec Mutex.new
255
263
  }
256
264
 
257
- node.should_receive(:handle_request).with(request_str, false, connection)
265
+ node.should_receive(:handle_request).with(inter, false, connection)
258
266
  node.send :handle_message, request_str, connection
259
267
  end
260
268
  end
@@ -264,6 +272,10 @@ module RJR
264
272
  connection = Object.new
265
273
  notification = Messages::Notification.new :method => 'foo'
266
274
  notification_str = notification.to_s
275
+ inter = Messages::Intermediate.parse notification_str
276
+ Messages::Intermediate.should_receive(:parse).
277
+ with(notification_str).
278
+ and_return(inter)
267
279
 
268
280
  node = Node.new
269
281
  node.tp.should_receive(:<<) { |job|
@@ -271,8 +283,7 @@ module RJR
271
283
  job.exec Mutex.new
272
284
  }
273
285
 
274
- node.should_receive(:handle_request).
275
- with(notification_str, true, connection)
286
+ node.should_receive(:handle_request).with(inter, true, connection)
276
287
  node.send :handle_message, notification_str, connection
277
288
  end
278
289
  end
@@ -281,9 +292,13 @@ module RJR
281
292
  it "handles response" do
282
293
  response = Messages::Response.new :result => Result.new
283
294
  response_str = response.to_s
295
+ inter = Messages::Intermediate.parse response_str
296
+ Messages::Intermediate.should_receive(:parse).
297
+ with(response_str).
298
+ and_return(inter)
284
299
 
285
300
  node = Node.new
286
- node.should_receive(:handle_response).with(response_str)
301
+ node.should_receive(:handle_response).with(inter)
287
302
  node.send :handle_message, response_str
288
303
  end
289
304
  end
@@ -297,6 +312,14 @@ module RJR
297
312
  node.send :handle_message, "{}"
298
313
  end
299
314
  end
315
+
316
+ it "returns intermediate message" do
317
+ node = Node.new
318
+ connection = Object.new
319
+ inter = Messages::Intermediate.new
320
+ Messages::Intermediate.should_receive(:parse).and_return(inter)
321
+ node.send(:handle_message, '', connection).should == inter
322
+ end
300
323
  end
301
324
 
302
325
  describe "#handle_request" do
@@ -305,13 +328,14 @@ module RJR
305
328
  Messages::Notification.new :method => 'rjr_method1',
306
329
  :args => ['method', 'args'],
307
330
  :headers => {'msg' => 'headers'}
308
- @notification = notification.to_s
331
+ notification_str = notification.to_s
332
+ @intermediate = Messages::Intermediate.parse notification_str
309
333
  @node = Node.new
310
334
  end
311
335
 
312
336
  it "invokes dispatcher.dispatch" do
313
337
  @node.dispatcher.should_receive(:dispatch)
314
- @node.send :handle_request, @notification, true
338
+ @node.send :handle_request, @intermediate, true
315
339
  end
316
340
 
317
341
  describe "dispatcher.dispatch args" do
@@ -319,21 +343,21 @@ module RJR
319
343
  @node.dispatcher.should_receive(:dispatch) { |args|
320
344
  args[:rjr_method].should == 'rjr_method1'
321
345
  }
322
- @node.send :handle_request, @notification, true
346
+ @node.send :handle_request, @intermediate, true
323
347
  end
324
348
 
325
349
  it "includes :rjr_method_args => msg.jr_args" do
326
350
  @node.dispatcher.should_receive(:dispatch) { |args|
327
351
  args[:rjr_method_args].should == ['method', 'args']
328
352
  }
329
- @node.send :handle_request, @notification, true
353
+ @node.send :handle_request, @intermediate, true
330
354
  end
331
355
 
332
356
  it "includes :rjr_headers => msg.headers" do
333
357
  @node.dispatcher.should_receive(:dispatch) { |args|
334
358
  args[:rjr_headers].should == {'msg' => 'headers'}
335
359
  }
336
- @node.send :handle_request, @notification, true
360
+ @node.send :handle_request, @intermediate, true
337
361
  end
338
362
 
339
363
  it "includes :rjr_client_ip => extracted client ip" do
@@ -343,7 +367,7 @@ module RJR
343
367
  @node.dispatcher.should_receive(:dispatch) { |args|
344
368
  args[:rjr_client_ip].should == '127.0.0.1'
345
369
  }
346
- @node.send :handle_request, @notification, true, connection
370
+ @node.send :handle_request, @intermediate, true, connection
347
371
  end
348
372
 
349
373
  it "includes :rjr_client_port => extracted client port" do
@@ -353,14 +377,14 @@ module RJR
353
377
  @node.dispatcher.should_receive(:dispatch) { |args|
354
378
  args[:rjr_client_port].should == 9999
355
379
  }
356
- @node.send :handle_request, @notification, true, connection
380
+ @node.send :handle_request, @intermediate, true, connection
357
381
  end
358
382
 
359
383
  it "includes :rjr_node => self" do
360
384
  @node.dispatcher.should_receive(:dispatch) { |args|
361
385
  args[:rjr_node].should == @node
362
386
  }
363
- @node.send :handle_request, @notification, true
387
+ @node.send :handle_request, @intermediate, true
364
388
  end
365
389
 
366
390
  it "includes :rjr_node_id => self.node_id" do
@@ -368,7 +392,7 @@ module RJR
368
392
  @node.dispatcher.should_receive(:dispatch) { |args|
369
393
  args[:rjr_node_id].should == 'node_id'
370
394
  }
371
- @node.send :handle_request, @notification, true
395
+ @node.send :handle_request, @intermediate, true
372
396
  end
373
397
 
374
398
  it "includes :rjr_node_type => self.node_type" do
@@ -376,14 +400,14 @@ module RJR
376
400
  @node.dispatcher.should_receive(:dispatch) { |args|
377
401
  args[:rjr_node_type].should == :nt
378
402
  }
379
- @node.send :handle_request, @notification, true
403
+ @node.send :handle_request, @intermediate, true
380
404
  end
381
405
 
382
406
  it "includes :rjr_callback => constructed node callback" do
383
407
  @node.dispatcher.should_receive(:dispatch) { |args|
384
408
  args[:rjr_callback].should be_an_instance_of(NodeCallback)
385
409
  }
386
- @node.send :handle_request, @notification, true
410
+ @node.send :handle_request, @intermediate, true
387
411
  end
388
412
 
389
413
  describe "specified node callback" do
@@ -391,7 +415,7 @@ module RJR
391
415
  @node.dispatcher.should_receive(:dispatch) { |args|
392
416
  args[:rjr_callback].node.should == @node
393
417
  }
394
- @node.send :handle_request, @notification, true
418
+ @node.send :handle_request, @intermediate, true
395
419
  end
396
420
 
397
421
  it "has a handle to the connection" do
@@ -399,17 +423,18 @@ module RJR
399
423
  @node.dispatcher.should_receive(:dispatch) { |args|
400
424
  args[:rjr_callback].connection.should == connection
401
425
  }
402
- @node.send :handle_request, @notification, true, connection
426
+ @node.send :handle_request, @intermediate, true, connection
403
427
  end
404
428
  end
405
429
  end
406
430
 
407
431
  context "handling request / not a notification" do
408
432
  before(:each) do
409
- request = Messages::Request.new :method => 'method1',
410
- :args => ['method', 'args'],
411
- :headers => {'msg' => 'headers'}
412
- @request = request.to_s
433
+ request = Messages::Request.new :method => 'method1',
434
+ :args => ['method', 'args'],
435
+ :headers => {'msg' => 'headers'}
436
+ request_str = request.to_s
437
+ @intermediate = Messages::Intermediate.parse request_str
413
438
 
414
439
  result = Result.new
415
440
  @expected = Messages::Response.new :result => result,
@@ -426,19 +451,19 @@ module RJR
426
451
  response.should == @expected.to_s
427
452
  econnection.should == connection
428
453
  }
429
- @node.send :handle_request, @request, false, connection
454
+ @node.send :handle_request, @intermediate, false, connection
430
455
  end
431
456
 
432
457
  it "returns response" do
433
458
  @node.should_receive(:send_msg) # stub out
434
- response = @node.send(:handle_request, @request, false)
459
+ response = @node.send(:handle_request, @intermediate, false)
435
460
  response.should be_an_instance_of(Messages::Response)
436
461
  response.to_s.should == @expected.to_s
437
462
  end
438
463
  end
439
464
 
440
465
  it "returns nil" do
441
- @node.send(:handle_request, @notification, true).should be_nil
466
+ @node.send(:handle_request, @intermediate, true).should be_nil
442
467
  end
443
468
  end
444
469
 
@@ -448,7 +473,8 @@ module RJR
448
473
 
449
474
  @result = Result.new :result => 42
450
475
  response = Messages::Response.new :id => 'msg1', :result => @result
451
- @response = response.to_s
476
+ response = response.to_s
477
+ @intermediate = Messages::Intermediate.parse response
452
478
  end
453
479
 
454
480
  it "invokes dispatcher.handle_response with response result" do
@@ -456,11 +482,11 @@ module RJR
456
482
  r.should be_an_instance_of(Result)
457
483
  r.result.should == 42
458
484
  }
459
- @node.send :handle_response, @response
485
+ @node.send :handle_response, @intermediate
460
486
  end
461
487
 
462
488
  it "adds response msg_id and result to response queue" do
463
- @node.send :handle_response, @response
489
+ @node.send :handle_response, @intermediate
464
490
  responses = @node.instance_variable_get(:@responses)
465
491
  responses.size.should == 1
466
492
  responses.first[0].should == 'msg1'
@@ -470,7 +496,7 @@ module RJR
470
496
  context "response contains error" do
471
497
  it "adds response error to response queue" do
472
498
  @node.dispatcher.should_receive(:handle_response).and_raise(Exception)
473
- @node.send :handle_response, @response
499
+ @node.send :handle_response, @intermediate
474
500
  responses = @node.instance_variable_get(:@responses)
475
501
  responses.first[2].should be_an_instance_of(Exception)
476
502
  end
@@ -478,7 +504,7 @@ module RJR
478
504
 
479
505
  it "signals response cv" do
480
506
  @node.instance_variable_get(:@response_cv).should_receive(:broadcast)
481
- @node.send :handle_response, @response
507
+ @node.send :handle_response, @intermediate
482
508
  end
483
509
  end
484
510
 
@@ -513,6 +539,28 @@ module RJR
513
539
  node.instance_variable_get(:@response_cv).should_receive(:wait).once
514
540
  node.send(:wait_for_result, @msg)
515
541
  end
542
+ it "throws an error if it times out" do
543
+ node = Node.new :timeout => 0.01
544
+ node.instance_variable_get(:@response_cv).should_receive(:wait).at_least(:once)
545
+ expect { node.send(:wait_for_result, @msg) }.to raise_error(Exception)
546
+ end
547
+ end
548
+
549
+ context "pruning messages" do
550
+ it "deletes unrequested messages" do
551
+ responses = [@response, ['foobar', 'baz']]
552
+ @node.instance_variable_set(:@responses, responses)
553
+ @node.send :wait_for_result, @msg
554
+ @node.instance_variable_get(:@responses).should be_empty
555
+ end
556
+ it "deletes timed out messages" do
557
+ responses = [@response, ['foobar', 'baz']]
558
+ @node.instance_variable_set(:@timeout, 0.01)
559
+ @node.instance_variable_set(:@pending, { 'foobar' => Time.at(0) })
560
+ @node.instance_variable_set(:@responses, responses)
561
+ @node.send :wait_for_result, @msg
562
+ @node.instance_variable_get(:@responses).should be_empty
563
+ end
516
564
  end
517
565
  end
518
566
  end # describe Node
@@ -40,7 +40,7 @@ module RJR::Nodes
40
40
  'test',
41
41
  'myparam'
42
42
  stop_node(node)
43
- invoked.should be_true
43
+ invoked.should be_truthy
44
44
  ci.should be_nil
45
45
  cp.should be_nil
46
46
  rn.should == node
@@ -66,8 +66,8 @@ module RJR::Nodes
66
66
  }
67
67
 
68
68
  node.invoke 'foobar', 'myparam'
69
- foobar_invoked.should be_true
70
- callback_invoked.should be_true
69
+ foobar_invoked.should be_truthy
70
+ callback_invoked.should be_truthy
71
71
  cbp.should == 'cp'
72
72
  end
73
73
 
@@ -51,7 +51,7 @@ module RJR::Nodes
51
51
  :broker => 'localhost'
52
52
  res = amqp_client.invoke 'amqp-queue', 'method1', 'myparam1'
53
53
  res.should == 'retval1'
54
- invoked1.should be_true
54
+ invoked1.should be_truthy
55
55
  rni1.should == 'amqp'
56
56
  rnt1.should == :amqp
57
57
  p1.should == 'myparam1'
@@ -35,41 +35,130 @@ module RJR::Nodes
35
35
  end
36
36
  end
37
37
 
38
- describe "#invoke" do
39
- it "should invoke request" do
40
- server = TCP.new :node_id => 'tcp',
41
- :host => 'localhost', :port => 9987
42
- server.dispatcher.handle('foobar') { |param|
43
- 'retval'
44
- }
38
+ context "simple server" do
39
+ let(:server) do
40
+ TCP.new(:node_id => 'tcp',
41
+ :host => 'localhost',
42
+ :port => 9987)
43
+ end
44
+
45
+ let(:host) { 'jsonrpc://localhost:9987' }
46
+
47
+ let(:client) { TCP.new }
48
+
49
+ before(:each) do
50
+ server.dispatcher.handle('foobar') { |param| 'retval' }
45
51
  server.listen
52
+ end
46
53
 
47
- client = TCP.new
48
- res = client.invoke 'jsonrpc://localhost:9987', 'foobar', 'myparam'
49
- server.halt.join
50
- res.should == 'retval'
54
+ describe "#invoke" do
55
+ it "should invoke request" do
56
+ res = client.invoke host, 'foobar', 'myparam'
57
+ server.halt.join
58
+ res.should == 'retval'
59
+ end
51
60
  end
52
- end
53
61
 
54
- describe "#notify" do
55
- it "should send notification" do
56
- server = TCP.new :node_id => 'tcp',
57
- :host => 'localhost', :port => 9987
58
- server.dispatcher.handle('foobar') { |param|
59
- 'retval'
60
- }
61
- server.listen
62
+ describe "#notify" do
63
+ it "should send notification" do
64
+ res = client.notify host, 'foobar', 'myparam'
65
+ server.halt.join
66
+ res.should == nil
67
+ end
68
+ end
62
69
 
63
- client = TCP.new
64
- res = client.notify 'jsonrpc://localhost:9987', 'foobar', 'myparam'
65
- server.halt.join
66
- res.should == nil
70
+ describe "a node's connections array" do
71
+ it "should be updated when a connection is opened" do
72
+ client.invoke host, 'foobar', 'myparam'
73
+ server.connections.size.should be == 1
74
+ client.connections.size.should be == 1
75
+ server.halt.join
76
+ end
77
+
78
+ it "should be updated when a connection is closed" do
79
+ client.invoke host, 'foobar', 'myparam'
80
+ client.connections.first.unbind
81
+ server.connections.first.unbind
82
+ server.connections.should be_empty
83
+ client.connections.should be_empty
84
+ server.halt.join
85
+ end
86
+
87
+ context "with a client already connected" do
88
+ let(:another_client) { TCP.new }
89
+
90
+ before(:each) do
91
+ client.invoke host, 'foobar', 'myparam'
92
+ end
93
+
94
+ it "should be updated when a new connection is opened" do
95
+ another_client.invoke host, 'foobar', 'myparam'
96
+ server.connections.size.should be == 2
97
+ client.connections.size.should be == 1
98
+ another_client.connections.size.should be == 1
99
+ server.halt.join
100
+ end
101
+
102
+ context "with two clients connected" do
103
+ before(:each) do
104
+ client.invoke host, 'foobar', 'myparam'
105
+ another_client.invoke host, 'foobar', 'myparam'
106
+ end
107
+
108
+ it "should be updated when a connection is closed" do
109
+ another_client.connections.first.unbind
110
+ server.connections.last.unbind
111
+ server.connections.size.should be == 1
112
+ client.connections.size.should be == 1
113
+ another_client.connections.should be_empty
114
+ server.halt.join
115
+ end
116
+ end
117
+ end
118
+ end
119
+
120
+ describe "event handlers" do
121
+ shared_examples "an event handler" do |event|
122
+ it "should be invoked when event is triggered" do
123
+ handler_invoked = false
124
+ server.on(event) { handler_invoked = true }
125
+ client.invoke host, 'foobar', 'myparam'
126
+ server.halt.join
127
+ handler_invoked.should be_truthy
128
+ end
129
+
130
+ it "should receive the node" do
131
+ node_received = false
132
+ server.on(event) do |node|
133
+ node_received = true if node.is_a?(RJR::Node)
134
+ end
135
+ client.invoke host, 'foobar', 'myparam'
136
+ server.halt.join
137
+ node_received.should be_truthy
138
+ end
139
+
140
+ it "should receive the connection" do
141
+ connection_received = false
142
+ server.on(event) do |_, connection|
143
+ connection_received = true if connection.is_a?(EM::Connection)
144
+ end
145
+ client.invoke host, 'foobar', 'myparam'
146
+ server.halt.join
147
+ connection_received.should be_truthy
148
+ end
149
+ end
150
+
151
+ describe "opened event handler" do
152
+ it_behaves_like "an event handler", :opened
153
+ end
154
+
155
+ describe "closed event handler" do
156
+ it_behaves_like "an event handler", :closed
157
+ end
67
158
  end
68
159
  end
69
160
 
70
161
  # TODO test callbacks over tcp interface
71
- # TODO ensure closed / error event handlers are invoked
162
+ # TODO ensure error event handler is invoked
72
163
  end
73
164
  end
74
-
75
-
@@ -29,7 +29,7 @@ module RJR::Nodes
29
29
  # issue request
30
30
  Web.new.invoke 'http://localhost:9678', 'test', 'myparam'
31
31
  node.halt.join
32
- invoked.should be_true
32
+ invoked.should be_truthy
33
33
  ci.should == '127.0.0.1'
34
34
  #cp.should
35
35
  rn.should == node
@@ -29,7 +29,7 @@ module RJR::Nodes
29
29
  # issue request
30
30
  WS.new.invoke 'http://localhost:9678', 'test', 'myparam'
31
31
  node.halt.join
32
- invoked.should be_true
32
+ invoked.should be_truthy
33
33
  ci.should == '127.0.0.1'
34
34
  #cp.should
35
35
  rn.should == node
@@ -63,11 +63,30 @@ module RJR
63
63
  request.rjr_args.args.should == args
64
64
  end
65
65
 
66
+ it "sets default env to nil" do
67
+ Request.new.rjr_env.should be_nil
68
+ end
69
+
66
70
  it "sets default result to nil" do
67
71
  Request.new.result.should be_nil
68
72
  end
69
73
  end
70
74
 
75
+ describe "#set_env" do
76
+ it "extends request w/ specified module" do
77
+ request = Request.new
78
+ request.should_receive(:extend).with('foobar')
79
+ request.set_env('foobar')
80
+ end
81
+
82
+ it "sets rjr_env" do
83
+ request = Request.new
84
+ request.should_receive(:extend)
85
+ request.set_env('foobar')
86
+ request.rjr_env.should == 'foobar'
87
+ end
88
+ end
89
+
71
90
  describe "#handle" do
72
91
  it "invokes the registered handler with args" do
73
92
  received = nil