rjr 0.19.1 → 0.19.2

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/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