client_for_poslynx 0.9.0 → 1.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
2
 
3
3
  module ClientForPoslynx
4
- VERSION = '0.9.0'
4
+ VERSION = '1.0.0.pre'
5
5
  end
@@ -0,0 +1,624 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module ClientForPoslynx
6
+
7
+ describe Net::EM_Connector do
8
+ describe "default initialization" do
9
+ subject { described_class.new( :the_server, :the_port ) }
10
+
11
+ it "Has ::EM as its em_system" do
12
+ expect( subject.em_system ).to eq( ::EM )
13
+ end
14
+
15
+ it "Has Net::EM_Connector::ConnectionHandler as its connection_handler" do
16
+ expect( subject.handler_class ).to eq( Net::EM_Connector::ConnectionHandler )
17
+ end
18
+
19
+ it "Sets the connection status to :initial" do
20
+ expect( subject.connection_status ).to eq( :initial )
21
+ end
22
+ end
23
+
24
+ context "actions and events" do
25
+ subject { described_class.new(
26
+ :the_server, :the_port,
27
+ encryption: encryption,
28
+ em_system: em_system,
29
+ handler: handler_class
30
+ ) }
31
+
32
+ let( :em_system ) { double( :em_system ) }
33
+ let( :handler_class ) { Class.new do
34
+ include Net::EM_Connector::HandlesConnection
35
+ end }
36
+
37
+ describe '#connect' do
38
+ context "without SSL" do
39
+ let( :encryption ) { :none }
40
+ before do
41
+ @handler_instance = nil
42
+ allow( em_system ).to receive( :connect ) do |server, port, handler, *handler_args|
43
+ @handler_instance = handler.new( *handler_args )
44
+ nil
45
+ end
46
+ end
47
+
48
+ let( :on_success ) { double(:on_success, call: nil) }
49
+ let( :on_failure ) { double(:on_failure, call: nil) }
50
+
51
+ context "initial connection" do
52
+ before do
53
+ subject.connect on_success: on_success, on_failure: on_failure
54
+ end
55
+
56
+ it "tries to open an EM connection using the connector's handler class" do
57
+ expect( em_system ).to have_received( :connect ) do |server, port, handler, *handler_args|
58
+ expect( server ).to eq( :the_server )
59
+ expect( port ).to eq( :the_port )
60
+ expect( handler ).to eq( handler_class )
61
+ end
62
+ end
63
+
64
+ it "exposes the handler instance" do
65
+ expect( subject.connection ).to eq( @handler_instance )
66
+ end
67
+
68
+ it "sets the connection status to :connecting" do
69
+ expect( subject.connection_status ).to eq( :connecting )
70
+ end
71
+
72
+ context "when connection is completed" do
73
+ before do
74
+ @handler_instance.connection_completed
75
+ end
76
+
77
+ it "reports success and not failure" do
78
+ expect( on_success ).to have_received( :call )
79
+ expect( on_failure ).not_to have_received( :call )
80
+ end
81
+
82
+ it "sets the connection status to :connected" do
83
+ expect( subject.connection_status ).to eq( :connected )
84
+ end
85
+ end
86
+
87
+ context "when the connection attempt fails" do
88
+ before do
89
+ @handler_instance.unbind
90
+ end
91
+
92
+ it "reports failure and not success" do
93
+ expect( on_failure ).to have_received(:call)
94
+ expect( on_success ).not_to have_received(:call)
95
+ end
96
+
97
+ it "sets the connection status to :disconnected" do
98
+ expect( subject.connection_status ).to eq( :disconnected )
99
+ end
100
+ end
101
+
102
+ context "following successful connection" do
103
+ before do
104
+ @handler_instance.connection_completed
105
+ end
106
+
107
+ it "does not report failure later when subsequently disconnected" do
108
+ @handler_instance.unbind
109
+ expect( on_failure ).not_to have_received(:call)
110
+ end
111
+ end
112
+ end
113
+
114
+ context "when previously connected" do
115
+ before do
116
+ # Establish previous connection.
117
+ subject.connect
118
+ @handler_instance.connection_completed
119
+ end
120
+
121
+ context "when currently connected" do
122
+ before do
123
+ subject.connect on_success: on_success, on_failure: on_failure
124
+ end
125
+
126
+ it "reports success and not failure" do
127
+ expect( on_success ).to have_received( :call )
128
+ expect( on_failure ).not_to have_received( :call )
129
+ end
130
+ end
131
+
132
+ context "when not currently connected" do
133
+ before do
134
+ @handler_instance.unbind
135
+ allow( @handler_instance ).to receive( :reconnect )
136
+
137
+ subject.connect on_success: on_success, on_failure: on_failure
138
+ expect( on_success ).not_to have_received( :call ) # Sanity check.
139
+ end
140
+
141
+ it "reconnects" do
142
+ expect( @handler_instance ).to have_received( :reconnect ).with( :the_server, :the_port )
143
+ end
144
+
145
+ it "reports success and not failure when connected" do
146
+ @handler_instance.connection_completed
147
+ expect( on_success ).to have_received( :call )
148
+ expect( on_failure ).not_to have_received( :call )
149
+ end
150
+
151
+ it "reports failure and not success when unbound" do
152
+ @handler_instance.unbind
153
+ expect( on_failure ).to have_received( :call )
154
+ expect( on_success ).not_to have_received( :call )
155
+ end
156
+ end
157
+ end
158
+
159
+ context "when a pending connection is in progress" do
160
+ before do
161
+ # Initiate previously pending connection.
162
+ subject.connect(
163
+ on_success: on_success_of_pending,
164
+ on_failure: on_failure_of_pending,
165
+ )
166
+
167
+ subject.connect on_success: on_success, on_failure: on_failure
168
+ end
169
+
170
+ let( :on_success_of_pending ) { double(:on_success_of_pending, call: nil) }
171
+ let( :on_failure_of_pending ) { double(:on_failure_of_pending, call: nil) }
172
+
173
+ it "does not issue its own separate EM connection request" do
174
+ expect( em_system ).to have_received( :connect ).once
175
+ end
176
+
177
+ context "when connection is completed" do
178
+ before do
179
+ @handler_instance.connection_completed
180
+ end
181
+
182
+ it "reports success for previously pending request" do
183
+ expect( on_success_of_pending ).to have_received( :call )
184
+ end
185
+
186
+ it "reports success for current request" do
187
+ expect( on_success ).to have_received( :call )
188
+ end
189
+ end
190
+
191
+ context "when the connection attempt fails" do
192
+ before do
193
+ @handler_instance.unbind
194
+ end
195
+
196
+ it "reports failure for previously pending request" do
197
+ expect( on_failure_of_pending ).to have_received( :call )
198
+ end
199
+
200
+ it "reports failure for current request" do
201
+ expect( on_failure ).to have_received( :call )
202
+ end
203
+ end
204
+
205
+ end
206
+ end
207
+
208
+ context "with SSL" do
209
+ let( :encryption ) { :use_ssl }
210
+ before do
211
+ @handler_instance = nil
212
+ allow( em_system ).to receive( :connect ) do |server, port, handler, *handler_args|
213
+ @handler_instance = handler.new( *handler_args )
214
+ allow( @handler_instance ).to receive( :start_tls )
215
+ nil
216
+ end
217
+ end
218
+
219
+ let( :on_success ) { double(:on_success, call: nil) }
220
+ let( :on_failure ) { double(:on_failure, call: nil) }
221
+
222
+ context "initial connection" do
223
+ before do
224
+ subject.connect on_success: on_success, on_failure: on_failure
225
+ end
226
+
227
+ it "tries to open an EM connection using the connector's handler class" do
228
+ expect( em_system ).to have_received( :connect ) do |server, port, handler, *handler_args|
229
+ expect( server ).to eq( :the_server )
230
+ expect( port ).to eq( :the_port )
231
+ expect( handler ).to eq( handler_class )
232
+ end
233
+ end
234
+
235
+ it "exposes the handler instance" do
236
+ expect( subject.connection ).to eq( @handler_instance )
237
+ end
238
+
239
+ it "sets the connection status to :connecting" do
240
+ expect( subject.connection_status ).to eq( :connecting )
241
+ end
242
+
243
+ context "when the EM HTTP connection is completed" do
244
+ before do
245
+ @handler_instance.connection_completed
246
+ end
247
+
248
+ it "tries to initiate TLS/SSL on the connection" do
249
+ expect( @handler_instance ).to have_received( :start_tls )
250
+ end
251
+
252
+ context "when the SSL handshake is completed" do
253
+ before do
254
+ @handler_instance.ssl_handshake_completed
255
+ end
256
+
257
+ it "reports success and not failure" do
258
+ expect( on_success ).to have_received( :call )
259
+ expect( on_failure ).not_to have_received( :call )
260
+ end
261
+
262
+ it "sets the connection status to :connected" do
263
+ expect( subject.connection_status ).to eq( :connected )
264
+ end
265
+ end
266
+
267
+ context "when the HTTP connection is lost" do
268
+ before do
269
+ @handler_instance.unbind
270
+ end
271
+
272
+ it "reports failure and not success" do
273
+ expect( on_failure ).to have_received(:call)
274
+ expect( on_success ).not_to have_received(:call)
275
+ end
276
+
277
+ it "sets the connection status to :disconnected" do
278
+ expect( subject.connection_status ).to eq( :disconnected )
279
+ end
280
+ end
281
+
282
+ end
283
+
284
+ context "when the EM HTTP connection attempt fails" do
285
+ before do
286
+ @handler_instance.unbind
287
+ end
288
+
289
+ it "reports failure and not success" do
290
+ expect( on_failure ).to have_received(:call)
291
+ expect( on_success ).not_to have_received(:call)
292
+ end
293
+
294
+ it "sets the connection status to :disconnected" do
295
+ expect( subject.connection_status ).to eq( :disconnected )
296
+ end
297
+ end
298
+
299
+ context "following successful connection and SSL handshake" do
300
+ before do
301
+ @handler_instance.connection_completed
302
+ @handler_instance.ssl_handshake_completed
303
+ end
304
+
305
+ it "does not report failure later when subsequently disconnected" do
306
+ @handler_instance.unbind
307
+ expect( on_failure ).not_to have_received(:call)
308
+ end
309
+ end
310
+ end
311
+ end
312
+ end
313
+
314
+ context "when an open connection is lost or remotely disconnected" do
315
+ let( :encryption ) { :none }
316
+ before do
317
+ @handler_instance = nil
318
+ allow( em_system ).to receive( :connect ) do |server, port, handler, *handler_args|
319
+ @handler_instance = handler.new( *handler_args )
320
+ nil
321
+ end
322
+ subject.connect
323
+ @handler_instance.connection_completed
324
+ @handler_instance.unbind
325
+ end
326
+
327
+ it "sets the connection status to :disconnected" do
328
+ expect( subject.connection_status ).to eq( :disconnected )
329
+ end
330
+ end
331
+
332
+ describe '#disconnect' do
333
+ let( :encryption ) { :none }
334
+ let( :on_completed ) { double(:on_completed, call: nil) }
335
+
336
+ context "when has never been connected" do
337
+ before do
338
+ subject.disconnect on_completed: on_completed
339
+ end
340
+
341
+ it "reports completion" do
342
+ expect( on_completed ).to have_received( :call )
343
+ end
344
+
345
+ it "leaves connection status as :initial" do
346
+ expect( subject.connection_status ).to eq( :initial )
347
+ end
348
+ end
349
+
350
+ context "when previously connected" do
351
+ before do
352
+ @handler_instance = nil
353
+ allow( em_system ).to receive( :connect ) do |server, port, handler, *handler_args|
354
+ @handler_instance = handler.new( *handler_args )
355
+ nil
356
+ end
357
+ subject.connect
358
+ @handler_instance.connection_completed
359
+ end
360
+
361
+ context "when not currently connected" do
362
+ before do
363
+ @handler_instance.unbind
364
+ subject.disconnect on_completed: on_completed
365
+ end
366
+
367
+ it "reports completion" do
368
+ expect( on_completed ).to have_received( :call )
369
+ end
370
+
371
+ it "leaves the connection status as :disconnected" do
372
+ expect( subject.connection_status ).to eq( :disconnected )
373
+ end
374
+ end
375
+
376
+ context "when currently connected" do
377
+ before do
378
+ allow( @handler_instance ).to receive( :close_connection )
379
+ subject.disconnect on_completed: on_completed
380
+ end
381
+
382
+ it "closes the open connection" do
383
+ expect( @handler_instance ).to have_received( :close_connection )
384
+ end
385
+
386
+ it "sets the connection status to :disconnecting" do
387
+ expect( subject.connection_status ).to eq( :disconnecting )
388
+ end
389
+
390
+ context "when done disconnecting" do
391
+ it "reports completion" do
392
+ expect( on_completed ).not_to have_received( :call ) # Sanity check.
393
+ @handler_instance.unbind
394
+ expect( on_completed ).to have_received( :call )
395
+ end
396
+
397
+ it "sets the connection status to :disconnected" do
398
+ @handler_instance.unbind
399
+ expect( subject.connection_status ).to eq( :disconnected )
400
+ end
401
+ end
402
+ end
403
+
404
+ end
405
+ end
406
+
407
+ describe '#send_request' do
408
+ let( :encryption ) { :none }
409
+ let( :opts_for_send_request ) {
410
+ { on_response: on_response, on_failure: on_failure }
411
+ }
412
+ let( :on_response ) { double(:on_response, call: nil) }
413
+ let( :on_failure ) { double(:on_failure , call: nil) }
414
+
415
+ context "while not connected" do
416
+ it "reports failure" do
417
+ subject.send_request :the_request_data, opts_for_send_request
418
+ expect( on_failure ).to have_received( :call )
419
+ end
420
+ end
421
+
422
+ context "while connected" do
423
+ before do
424
+ @handler_instance = nil
425
+ allow( em_system ).to receive( :connect ) do |server, port, handler, *handler_args|
426
+ @handler_instance = handler.new( *handler_args )
427
+ nil
428
+ end
429
+ subject.connect
430
+ @handler_instance.connection_completed
431
+ allow( @handler_instance ).to receive( :send_request )
432
+ subject.send_request :the_request_data, opts_for_send_request
433
+ end
434
+
435
+ it "sends a request to the POSLynx" do
436
+ expect( @handler_instance ).to have_received( :send_request ).with( :the_request_data )
437
+ end
438
+
439
+ it "records the pending request state" do
440
+ expect( subject.latest_request ).to eq( Net::EMC.RequestCall(
441
+ :the_request_data, opts_for_send_request
442
+ ) )
443
+ expect( subject.status_of_request ).to eq( :pending )
444
+ end
445
+
446
+ context "when a response is received" do
447
+ before do
448
+ @handler_instance.receive_response :the_response_data
449
+ end
450
+
451
+ it "records the got-response request state" do
452
+ expect( subject.status_of_request ).to eq( :got_response )
453
+ end
454
+
455
+ it "reports the response data" do
456
+ expect( on_response ).to have_received( :call ).with( :the_response_data )
457
+ end
458
+ end
459
+
460
+ context "when connection is lost w/o response" do
461
+ before do
462
+ @handler_instance.unbind
463
+ end
464
+
465
+ it "records the failed request state" do
466
+ expect( subject.status_of_request ).to eq( :failed )
467
+ end
468
+
469
+ it "reports failure" do
470
+ expect( on_failure ).to have_received( :call )
471
+ end
472
+ end
473
+
474
+ end
475
+ end
476
+
477
+ describe '#get_response' do
478
+ let( :encryption ) { :none }
479
+ let( :opts_for_get_response ) {
480
+ { on_response: on_response, on_failure: on_failure }
481
+ }
482
+ let( :on_response ) { double(:on_response, call: nil) }
483
+ let( :on_failure ) { double(:on_failure , call: nil) }
484
+
485
+ context "while not connected" do
486
+ it "reports failure" do
487
+ subject.get_response opts_for_get_response
488
+ expect( on_failure ).to have_received( :call )
489
+ end
490
+ end
491
+
492
+ context "while connected" do
493
+ before do
494
+ @handler_instance = nil
495
+ allow( em_system ).to receive( :connect ) do |server, port, handler, *handler_args|
496
+ @handler_instance = handler.new( *handler_args )
497
+ nil
498
+ end
499
+ subject.connect
500
+ @handler_instance.connection_completed
501
+ end
502
+
503
+ context "when no request has been previously sent" do
504
+ it "reports failure" do
505
+ subject.get_response opts_for_get_response
506
+ expect( on_failure ).to have_received( :call )
507
+ end
508
+ end
509
+
510
+ context "when a previous request is still pending" do
511
+ before do
512
+ allow( @handler_instance ).to receive( :send_request )
513
+ subject.send_request :prev_request_data, some_prev_option: :some_prev_value
514
+ end
515
+
516
+ it "replaces the previous request options" do
517
+ subject.get_response opts_for_get_response
518
+ expect( subject.latest_request ).to eq( Net::EMC.RequestCall(
519
+ :prev_request_data, opts_for_get_response
520
+ ) )
521
+ end
522
+
523
+ context "when a response is received" do
524
+ before do
525
+ subject.get_response opts_for_get_response
526
+ @handler_instance.receive_response :the_response_data
527
+ end
528
+
529
+ it "records the got-response request state" do
530
+ expect( subject.status_of_request ).to eq( :got_response )
531
+ end
532
+
533
+ it "reports the response data" do
534
+ expect( on_response ).to have_received( :call ).with( :the_response_data )
535
+ end
536
+ end
537
+
538
+ context "when connection is lost w/o response" do
539
+ before do
540
+ subject.get_response opts_for_get_response
541
+ @handler_instance.unbind
542
+ end
543
+
544
+ it "records the failed request state" do
545
+ expect( subject.status_of_request ).to eq( :failed )
546
+ end
547
+
548
+ it "reports failure" do
549
+ expect( on_failure ).to have_received( :call )
550
+ end
551
+ end
552
+ end
553
+
554
+ context "when the previous request failed, there is an open connection" do
555
+ before do
556
+ allow( @handler_instance ).to receive( :send_request )
557
+ subject.send_request :prev_request_data
558
+ @handler_instance.unbind
559
+ @handler_instance.connection_completed
560
+ end
561
+
562
+ it "reports failure" do
563
+ subject.get_response opts_for_get_response
564
+ expect( on_failure ).to have_received( :call )
565
+ end
566
+ end
567
+
568
+ context "when the previous request has completed" do
569
+ before do
570
+ allow( @handler_instance ).to receive( :send_request )
571
+ subject.send_request :prev_request_data, some_prev_option: :some_prev_value
572
+ @handler_instance.receive_response :the_previous_response
573
+ end
574
+
575
+ it "replaces the previous request options" do
576
+ subject.get_response opts_for_get_response
577
+ expect( subject.latest_request ).to eq( Net::EMC.RequestCall(
578
+ :prev_request_data, opts_for_get_response
579
+ ) )
580
+ end
581
+
582
+ it "reverts to a request status of pending" do
583
+ subject.get_response opts_for_get_response
584
+ expect( subject.status_of_request ).to eq( :pending )
585
+ end
586
+
587
+ context "when a response is received" do
588
+ before do
589
+ subject.get_response opts_for_get_response
590
+ @handler_instance.receive_response :the_response_data
591
+ end
592
+
593
+ it "records the got-response request state" do
594
+ expect( subject.status_of_request ).to eq( :got_response )
595
+ end
596
+
597
+ it "reports the response data" do
598
+ expect( on_response ).to have_received( :call ).with( :the_response_data )
599
+ end
600
+ end
601
+
602
+ context "when connection is lost w/o response" do
603
+ before do
604
+ subject.get_response opts_for_get_response
605
+ @handler_instance.unbind
606
+ end
607
+
608
+ it "records the failed request state" do
609
+ expect( subject.status_of_request ).to eq( :failed )
610
+ end
611
+
612
+ it "reports failure" do
613
+ expect( on_failure ).to have_received( :call )
614
+ end
615
+ end
616
+ end
617
+
618
+ end
619
+ end
620
+
621
+ end
622
+ end
623
+
624
+ end