cql-rb 1.1.0.pre3 → 1.1.0.pre6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/README.md +2 -2
  2. data/lib/cql/client.rb +9 -5
  3. data/lib/cql/client/asynchronous_client.rb +105 -192
  4. data/lib/cql/client/asynchronous_prepared_statement.rb +51 -9
  5. data/lib/cql/client/connection_helper.rb +155 -0
  6. data/lib/cql/client/connection_manager.rb +56 -0
  7. data/lib/cql/client/keyspace_changer.rb +27 -0
  8. data/lib/cql/client/null_logger.rb +21 -0
  9. data/lib/cql/client/request_runner.rb +5 -3
  10. data/lib/cql/client/synchronous_client.rb +5 -5
  11. data/lib/cql/client/synchronous_prepared_statement.rb +4 -8
  12. data/lib/cql/future.rb +320 -210
  13. data/lib/cql/io/connection.rb +5 -5
  14. data/lib/cql/io/io_reactor.rb +21 -23
  15. data/lib/cql/protocol/cql_protocol_handler.rb +69 -38
  16. data/lib/cql/protocol/encoding.rb +5 -1
  17. data/lib/cql/protocol/requests/register_request.rb +2 -0
  18. data/lib/cql/protocol/type_converter.rb +1 -0
  19. data/lib/cql/version.rb +1 -1
  20. data/spec/cql/client/asynchronous_client_spec.rb +368 -175
  21. data/spec/cql/client/asynchronous_prepared_statement_spec.rb +132 -22
  22. data/spec/cql/client/connection_helper_spec.rb +335 -0
  23. data/spec/cql/client/connection_manager_spec.rb +118 -0
  24. data/spec/cql/client/keyspace_changer_spec.rb +50 -0
  25. data/spec/cql/client/request_runner_spec.rb +12 -12
  26. data/spec/cql/client/synchronous_client_spec.rb +15 -15
  27. data/spec/cql/client/synchronous_prepared_statement_spec.rb +15 -11
  28. data/spec/cql/future_spec.rb +529 -301
  29. data/spec/cql/io/connection_spec.rb +12 -12
  30. data/spec/cql/io/io_reactor_spec.rb +61 -61
  31. data/spec/cql/protocol/cql_protocol_handler_spec.rb +26 -12
  32. data/spec/cql/protocol/encoding_spec.rb +5 -0
  33. data/spec/cql/protocol/type_converter_spec.rb +1 -1
  34. data/spec/cql/time_uuid_spec.rb +7 -7
  35. data/spec/integration/client_spec.rb +2 -2
  36. data/spec/integration/io_spec.rb +20 -20
  37. data/spec/integration/protocol_spec.rb +17 -17
  38. data/spec/integration/regression_spec.rb +6 -0
  39. data/spec/integration/uuid_spec.rb +4 -0
  40. data/spec/support/fake_io_reactor.rb +38 -8
  41. data/spec/support/fake_server.rb +3 -3
  42. metadata +12 -2
@@ -11,19 +11,19 @@ module Cql
11
11
  end
12
12
 
13
13
  let :unblocker do
14
- stub(:unblocker, unblock!: nil)
14
+ double(:unblocker, unblock!: nil)
15
15
  end
16
16
 
17
17
  let :socket_impl do
18
- stub(:socket_impl)
18
+ double(:socket_impl)
19
19
  end
20
20
 
21
21
  let :clock do
22
- stub(:clock, now: 0)
22
+ double(:clock, now: 0)
23
23
  end
24
24
 
25
25
  let :socket do
26
- stub(:socket)
26
+ double(:socket)
27
27
  end
28
28
 
29
29
  before do
@@ -76,10 +76,10 @@ module Cql
76
76
  end
77
77
 
78
78
  shared_examples 'on successfull connection' do
79
- it 'completes the returned future and returns itself' do
79
+ it 'fulfilles the returned future and returns itself' do
80
80
  f = handler.connect
81
- f.should be_complete
82
- f.get.should equal(handler)
81
+ f.should be_resolved
82
+ f.value.should equal(handler)
83
83
  end
84
84
 
85
85
  it 'is connected' do
@@ -108,7 +108,7 @@ module Cql
108
108
  it 'it does nothing' do
109
109
  socket.stub(:connect_nonblock).and_raise(Errno::EALREADY)
110
110
  f = handler.connect
111
- f.should_not be_complete
111
+ f.should_not be_resolved
112
112
  f.should_not be_failed
113
113
  end
114
114
  end
@@ -133,7 +133,7 @@ module Cql
133
133
  it 'fails if there are no more addresses to try' do
134
134
  socket.stub(:connect_nonblock).and_raise(Errno::EINVAL)
135
135
  f = handler.connect
136
- expect { f.get }.to raise_error(ConnectionError)
136
+ expect { f.value }.to raise_error(ConnectionError)
137
137
  end
138
138
  end
139
139
 
@@ -145,7 +145,7 @@ module Cql
145
145
 
146
146
  it 'fails the future with a ConnectionError' do
147
147
  f = handler.connect
148
- expect { f.get }.to raise_error(ConnectionError)
148
+ expect { f.value }.to raise_error(ConnectionError)
149
149
  end
150
150
 
151
151
  it 'closes the socket' do
@@ -180,7 +180,7 @@ module Cql
180
180
 
181
181
  it 'fails the returned future with a ConnectionError' do
182
182
  f = handler.connect
183
- expect { f.get }.to raise_error(ConnectionError)
183
+ expect { f.value }.to raise_error(ConnectionError)
184
184
  end
185
185
 
186
186
  it 'calls the close listener' do
@@ -217,7 +217,7 @@ module Cql
217
217
  clock.stub(:now).and_return(7)
218
218
  handler.connect
219
219
  f.should be_failed
220
- expect { f.get }.to raise_error(ConnectionTimeoutError)
220
+ expect { f.value }.to raise_error(ConnectionTimeoutError)
221
221
  end
222
222
 
223
223
  it 'closes the connection' do
@@ -11,7 +11,7 @@ module Cql
11
11
  end
12
12
 
13
13
  let :protocol_handler_factory do
14
- stub(:protocol_handler_factory)
14
+ double(:protocol_handler_factory)
15
15
  end
16
16
 
17
17
  let! :selector do
@@ -19,61 +19,61 @@ module Cql
19
19
  end
20
20
 
21
21
  let :clock do
22
- stub(:clock, now: 0)
22
+ double(:clock, now: 0)
23
23
  end
24
24
 
25
25
  describe '#start' do
26
26
  after do
27
- reactor.stop.get if reactor.running?
27
+ reactor.stop.value if reactor.running?
28
28
  end
29
29
 
30
- it 'returns a future that completes when the reactor has started' do
31
- reactor.start.get
30
+ it 'returns a future that is resolved when the reactor has started' do
31
+ reactor.start.value
32
32
  end
33
33
 
34
34
  it 'returns a future that resolves to the reactor' do
35
- reactor.start.get.should equal(reactor)
35
+ reactor.start.value.should equal(reactor)
36
36
  end
37
37
 
38
38
  it 'is running after being started' do
39
- reactor.start.get
39
+ reactor.start.value
40
40
  reactor.should be_running
41
41
  end
42
42
 
43
43
  it 'cannot be started again once stopped' do
44
- reactor.start.get
45
- reactor.stop.get
44
+ reactor.start.value
45
+ reactor.stop.value
46
46
  expect { reactor.start }.to raise_error(ReactorError)
47
47
  end
48
48
 
49
49
  it 'calls the selector' do
50
50
  called = false
51
51
  selector.handler { called = true; [[], [], []] }
52
- reactor.start.get
52
+ reactor.start.value
53
53
  await { called }
54
- reactor.stop.get
54
+ reactor.stop.value
55
55
  called.should be_true, 'expected the selector to have been called'
56
56
  end
57
57
  end
58
58
 
59
59
  describe '#stop' do
60
60
  after do
61
- reactor.stop.get if reactor.running?
61
+ reactor.stop.value if reactor.running?
62
62
  end
63
63
 
64
- it 'returns a future which completes when the reactor has stopped' do
65
- reactor.start.get
66
- reactor.stop.get
64
+ it 'returns a future that is resolved when the reactor has stopped' do
65
+ reactor.start.value
66
+ reactor.stop.value
67
67
  end
68
68
 
69
69
  it 'returns a future which resolves to the reactor' do
70
- reactor.start.get
71
- reactor.stop.get.should equal(reactor)
70
+ reactor.start.value
71
+ reactor.stop.value.should equal(reactor)
72
72
  end
73
73
 
74
74
  it 'is not running after being stopped' do
75
- reactor.start.get
76
- reactor.stop.get
75
+ reactor.start.value
76
+ reactor.stop.value
77
77
  reactor.should_not be_running
78
78
  end
79
79
 
@@ -81,24 +81,24 @@ module Cql
81
81
  connection = nil
82
82
  protocol_handler_factory.stub(:new) do |sh|
83
83
  connection = sh
84
- stub(:protocol_handler)
84
+ double(:protocol_handler)
85
85
  end
86
- reactor.start.get
86
+ reactor.start.value
87
87
  reactor.connect('example.com', 9999, 5)
88
- reactor.stop.get
88
+ reactor.stop.value
89
89
  connection.should be_closed
90
90
  end
91
91
 
92
92
  it 'cancels all active timers' do
93
- reactor.start.get
93
+ reactor.start.value
94
94
  clock.stub(:now).and_return(1)
95
95
  expired_timer = reactor.schedule_timer(1)
96
96
  active_timer1 = reactor.schedule_timer(999)
97
97
  active_timer2 = reactor.schedule_timer(111)
98
- expired_timer.should_not_receive(:fail!)
98
+ expired_timer.should_not_receive(:fail)
99
99
  clock.stub(:now).and_return(2)
100
- await { expired_timer.complete? }
101
- reactor.stop.get
100
+ await { expired_timer.completed? }
101
+ reactor.stop.value
102
102
  active_timer1.should be_failed
103
103
  active_timer2.should be_failed
104
104
  end
@@ -119,7 +119,7 @@ module Cql
119
119
 
120
120
  it 'calls the listener immediately when the reactor has already crashed' do
121
121
  error = nil
122
- reactor.start.get
122
+ reactor.start.value
123
123
  await { !reactor.running? }
124
124
  reactor.on_error { |e| error = e }
125
125
  await { error }
@@ -137,7 +137,7 @@ module Cql
137
137
 
138
138
  describe '#connect' do
139
139
  let :protocol_handler do
140
- stub(:protocol_handler)
140
+ double(:protocol_handler)
141
141
  end
142
142
 
143
143
  before do
@@ -166,14 +166,14 @@ module Cql
166
166
  end
167
167
 
168
168
  it 'returns a future that resolves to a new protocol handler' do
169
- reactor.start.get
169
+ reactor.start.value
170
170
  f = reactor.connect('example.com', 9999, 5)
171
- f.get.should equal(protocol_handler)
171
+ f.value.should equal(protocol_handler)
172
172
  end
173
173
 
174
174
  it 'returns a new protocol handler which wraps a socket handler' do
175
- reactor.start.get
176
- protocol_handler = reactor.connect('example.com', 9999, 5).get
175
+ reactor.start.value
176
+ protocol_handler = reactor.connect('example.com', 9999, 5).value
177
177
  protocol_handler.connection.should_not be_nil
178
178
  protocol_handler.connection.host.should == 'example.com'
179
179
  protocol_handler.connection.port.should == 9999
@@ -183,18 +183,18 @@ module Cql
183
183
 
184
184
  describe '#schedule_timer' do
185
185
  before do
186
- reactor.start.get
186
+ reactor.start.value
187
187
  end
188
188
 
189
189
  after do
190
- reactor.stop.get
190
+ reactor.stop.value
191
191
  end
192
192
 
193
- it 'returns a future that completes after the specified duration' do
193
+ it 'returns a future that is resolved after the specified duration' do
194
194
  clock.stub(:now).and_return(1)
195
195
  f = reactor.schedule_timer(0.1)
196
196
  clock.stub(:now).and_return(1.1)
197
- await { f.complete? }
197
+ await { f.resolved? }
198
198
  end
199
199
  end
200
200
 
@@ -218,15 +218,15 @@ module Cql
218
218
  end
219
219
 
220
220
  let :selector do
221
- stub(:selector)
221
+ double(:selector)
222
222
  end
223
223
 
224
224
  let :clock do
225
- stub(:clock, now: 0)
225
+ double(:clock, now: 0)
226
226
  end
227
227
 
228
228
  let :socket do
229
- stub(:socket, connected?: false, connecting?: false, writable?: false, closed?: false)
229
+ double(:socket, connected?: false, connecting?: false, writable?: false, closed?: false)
230
230
  end
231
231
 
232
232
  describe '#tick' do
@@ -295,32 +295,32 @@ module Cql
295
295
  it 'completes timers that have expired' do
296
296
  selector.stub(:select).and_return([nil, nil, nil])
297
297
  clock.stub(:now).and_return(1)
298
- future = Future.new
299
- loop_body.schedule_timer(1, future)
298
+ promise = Promise.new
299
+ loop_body.schedule_timer(1, promise)
300
300
  loop_body.tick
301
- future.should_not be_complete
301
+ promise.future.should_not be_completed
302
302
  clock.stub(:now).and_return(2)
303
303
  loop_body.tick
304
- future.should be_complete
304
+ promise.future.should be_completed
305
305
  end
306
306
 
307
307
  it 'clears out timers that have expired' do
308
308
  selector.stub(:select).and_return([nil, nil, nil])
309
309
  clock.stub(:now).and_return(1)
310
- future = Future.new
311
- loop_body.schedule_timer(1, future)
310
+ promise = Promise.new
311
+ loop_body.schedule_timer(1, promise)
312
312
  clock.stub(:now).and_return(2)
313
313
  loop_body.tick
314
- future.should be_complete
315
- future.should_not_receive(:complete!)
314
+ promise.future.should be_completed
315
+ promise.should_not_receive(:fulfill)
316
316
  loop_body.tick
317
317
  end
318
318
  end
319
319
 
320
320
  describe '#close_sockets' do
321
321
  it 'closes all sockets' do
322
- socket1 = stub(:socket1, closed?: false)
323
- socket2 = stub(:socket2, closed?: false)
322
+ socket1 = double(:socket1, closed?: false)
323
+ socket2 = double(:socket2, closed?: false)
324
324
  socket1.should_receive(:close)
325
325
  socket2.should_receive(:close)
326
326
  loop_body.add_socket(socket1)
@@ -329,8 +329,8 @@ module Cql
329
329
  end
330
330
 
331
331
  it 'closes all sockets, even when one of them raises an error' do
332
- socket1 = stub(:socket1, closed?: false)
333
- socket2 = stub(:socket2, closed?: false)
332
+ socket1 = double(:socket1, closed?: false)
333
+ socket2 = double(:socket2, closed?: false)
334
334
  socket1.stub(:close).and_raise('Blurgh')
335
335
  socket2.should_receive(:close)
336
336
  loop_body.add_socket(socket1)
@@ -352,20 +352,20 @@ module Cql
352
352
  end
353
353
 
354
354
  it 'fails all active timers with a CancelledError' do
355
- f1 = Future.new
356
- f2 = Future.new
357
- f3 = Future.new
355
+ p1 = Promise.new
356
+ p2 = Promise.new
357
+ p3 = Promise.new
358
358
  clock.stub(:now).and_return(1)
359
- loop_body.schedule_timer(1, f1)
360
- loop_body.schedule_timer(3, f2)
361
- loop_body.schedule_timer(3, f3)
359
+ loop_body.schedule_timer(1, p1)
360
+ loop_body.schedule_timer(3, p2)
361
+ loop_body.schedule_timer(3, p3)
362
362
  clock.stub(:now).and_return(2)
363
363
  loop_body.tick
364
364
  loop_body.cancel_timers
365
- f1.should be_complete
366
- f2.should be_failed
367
- f3.should be_failed
368
- expect { f3.get }.to raise_error(CancelledError)
365
+ p1.future.should be_completed
366
+ p2.future.should be_failed
367
+ p3.future.should be_failed
368
+ expect { p3.future.value }.to raise_error(CancelledError)
369
369
  end
370
370
  end
371
371
  end
@@ -11,7 +11,7 @@ module Cql
11
11
  end
12
12
 
13
13
  let :connection do
14
- stub(:connection)
14
+ double(:connection)
15
15
  end
16
16
 
17
17
  let :request do
@@ -48,6 +48,20 @@ module Cql
48
48
  end
49
49
  end
50
50
 
51
+ describe '#host' do
52
+ it 'delegates to the connection' do
53
+ connection.stub(:host).and_return('example.com')
54
+ protocol_handler.host.should == 'example.com'
55
+ end
56
+ end
57
+
58
+ describe '#port' do
59
+ it 'delegates to the connection' do
60
+ connection.stub(:port).and_return(9042)
61
+ protocol_handler.port.should == 9042
62
+ end
63
+ end
64
+
51
65
  describe '#send_request' do
52
66
  before do
53
67
  connection.stub(:write).and_yield(buffer)
@@ -71,27 +85,27 @@ module Cql
71
85
  protocol_handler.send_request(request).should be_a(Future)
72
86
  end
73
87
 
74
- it 'completes the future when it receives a response frame with the corresponding stream ID' do
88
+ it 'succeeds the future when it receives a response frame with the corresponding stream ID' do
75
89
  3.times { protocol_handler.send_request(request) }
76
90
  future = protocol_handler.send_request(request)
77
91
  connection.data_listener.call([0x81, 0, 3, 2, 0].pack('C4N'))
78
- await(0.1) { future.complete? }
92
+ await(0.1) { future.resolved? }
79
93
  end
80
94
 
81
95
  it 'handles multiple response frames in the same data packet' do
82
96
  futures = Array.new(4) { protocol_handler.send_request(request) }
83
97
  connection.data_listener.call([0x81, 0, 2, 2, 0].pack('C4N') + [0x81, 0, 3, 2, 0].pack('C4N'))
84
- await(0.1) { futures[2].complete? && futures[3].complete? }
98
+ await(0.1) { futures[2].resolved? && futures[3].resolved? }
85
99
  end
86
100
 
87
101
  it 'queues the request when there are too many in flight, sending it as soon as a stream is available' do
88
102
  connection.stub(:write)
89
103
  futures = Array.new(130) { protocol_handler.send_request(request) }
90
104
  128.times { |i| connection.data_listener.call([0x81, 0, i, 2, 0].pack('C4N')) }
91
- futures[127].should be_complete
92
- futures[128].should_not be_complete
105
+ futures[127].should be_resolved
106
+ futures[128].should_not be_resolved
93
107
  2.times { |i| connection.data_listener.call([0x81, 0, i, 2, 0].pack('C4N')) }
94
- futures[128].should be_complete
108
+ futures[128].should be_resolved
95
109
  end
96
110
 
97
111
  context 'when the protocol handler closes' do
@@ -113,7 +127,7 @@ module Cql
113
127
  connection.data_listener.call([0x81, 0, 0, 2, 0].pack('C4N'))
114
128
  connection.closed_listener.call(nil)
115
129
  begin
116
- future.get
130
+ future.value
117
131
  rescue => e
118
132
  e.should be_a(Cql::Io::ConnectionClosedError)
119
133
  else
@@ -134,7 +148,7 @@ module Cql
134
148
  it 'fails all requests with NotConnectedError' do
135
149
  connection.stub(:closed?).and_return(true)
136
150
  f = protocol_handler.send_request(request)
137
- expect { f.get }.to raise_error(NotConnectedError)
151
+ expect { f.value }.to raise_error(NotConnectedError)
138
152
  end
139
153
  end
140
154
  end
@@ -145,11 +159,11 @@ module Cql
145
159
  protocol_handler.close
146
160
  end
147
161
 
148
- it 'returns a future which completes when the socket has closed' do
162
+ it 'returns a future which succeeds when the socket has closed' do
149
163
  connection.stub(:close) do
150
164
  connection.closed_listener.call(nil)
151
165
  end
152
- protocol_handler.close.get
166
+ protocol_handler.close.value
153
167
  end
154
168
  end
155
169
 
@@ -167,7 +181,7 @@ module Cql
167
181
  it 'registers the keyspace it has changed to' do
168
182
  f = protocol_handler.send_request(Protocol::QueryRequest.new('USE hello', :one))
169
183
  connection.data_listener.call([0x81, 0, 0, 8, 4 + 2 + 5, 3, 5].pack('C4N2n') + 'hello')
170
- f.get
184
+ f.value
171
185
  protocol_handler.keyspace.should == 'hello'
172
186
  end
173
187
  end