cql-rb 2.0.0.pre0 → 2.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +14 -2
- data/lib/cql.rb +8 -3
- data/lib/cql/client.rb +21 -356
- data/lib/cql/client/authenticators.rb +70 -0
- data/lib/cql/client/batch.rb +54 -0
- data/lib/cql/client/{asynchronous_client.rb → client.rb} +241 -6
- data/lib/cql/client/connector.rb +3 -2
- data/lib/cql/client/{asynchronous_prepared_statement.rb → prepared_statement.rb} +103 -0
- data/lib/cql/protocol.rb +1 -2
- data/lib/cql/protocol/cql_byte_buffer.rb +285 -0
- data/lib/cql/protocol/cql_protocol_handler.rb +3 -3
- data/lib/cql/protocol/frame_decoder.rb +3 -3
- data/lib/cql/protocol/frame_encoder.rb +2 -2
- data/lib/cql/protocol/request.rb +0 -2
- data/lib/cql/protocol/requests/auth_response_request.rb +2 -2
- data/lib/cql/protocol/requests/batch_request.rb +10 -10
- data/lib/cql/protocol/requests/credentials_request.rb +2 -2
- data/lib/cql/protocol/requests/execute_request.rb +13 -13
- data/lib/cql/protocol/requests/options_request.rb +2 -2
- data/lib/cql/protocol/requests/prepare_request.rb +2 -2
- data/lib/cql/protocol/requests/query_request.rb +13 -13
- data/lib/cql/protocol/requests/register_request.rb +2 -2
- data/lib/cql/protocol/requests/startup_request.rb +2 -2
- data/lib/cql/protocol/response.rb +2 -4
- data/lib/cql/protocol/responses/auth_challenge_response.rb +2 -2
- data/lib/cql/protocol/responses/auth_success_response.rb +2 -2
- data/lib/cql/protocol/responses/authenticate_response.rb +2 -2
- data/lib/cql/protocol/responses/detailed_error_response.rb +15 -15
- data/lib/cql/protocol/responses/error_response.rb +4 -4
- data/lib/cql/protocol/responses/event_response.rb +3 -3
- data/lib/cql/protocol/responses/prepared_result_response.rb +4 -4
- data/lib/cql/protocol/responses/raw_rows_result_response.rb +1 -1
- data/lib/cql/protocol/responses/ready_response.rb +1 -1
- data/lib/cql/protocol/responses/result_response.rb +3 -3
- data/lib/cql/protocol/responses/rows_result_response.rb +22 -22
- data/lib/cql/protocol/responses/schema_change_event_response.rb +2 -2
- data/lib/cql/protocol/responses/schema_change_result_response.rb +2 -2
- data/lib/cql/protocol/responses/set_keyspace_result_response.rb +2 -2
- data/lib/cql/protocol/responses/status_change_event_response.rb +2 -2
- data/lib/cql/protocol/responses/supported_response.rb +2 -2
- data/lib/cql/protocol/responses/void_result_response.rb +1 -1
- data/lib/cql/protocol/type_converter.rb +78 -81
- data/lib/cql/time_uuid.rb +6 -0
- data/lib/cql/uuid.rb +2 -1
- data/lib/cql/version.rb +1 -1
- data/spec/cql/client/batch_spec.rb +8 -8
- data/spec/cql/client/{asynchronous_client_spec.rb → client_spec.rb} +162 -0
- data/spec/cql/client/connector_spec.rb +13 -3
- data/spec/cql/client/{asynchronous_prepared_statement_spec.rb → prepared_statement_spec.rb} +148 -1
- data/spec/cql/client/request_runner_spec.rb +2 -2
- data/spec/cql/protocol/cql_byte_buffer_spec.rb +895 -0
- data/spec/cql/protocol/cql_protocol_handler_spec.rb +1 -1
- data/spec/cql/protocol/frame_decoder_spec.rb +14 -14
- data/spec/cql/protocol/frame_encoder_spec.rb +7 -7
- data/spec/cql/protocol/requests/auth_response_request_spec.rb +4 -4
- data/spec/cql/protocol/requests/batch_request_spec.rb +21 -21
- data/spec/cql/protocol/requests/credentials_request_spec.rb +2 -2
- data/spec/cql/protocol/requests/execute_request_spec.rb +13 -13
- data/spec/cql/protocol/requests/options_request_spec.rb +1 -1
- data/spec/cql/protocol/requests/prepare_request_spec.rb +2 -2
- data/spec/cql/protocol/requests/query_request_spec.rb +13 -13
- data/spec/cql/protocol/requests/register_request_spec.rb +2 -2
- data/spec/cql/protocol/requests/startup_request_spec.rb +4 -4
- data/spec/cql/protocol/responses/auth_challenge_response_spec.rb +5 -5
- data/spec/cql/protocol/responses/auth_success_response_spec.rb +5 -5
- data/spec/cql/protocol/responses/authenticate_response_spec.rb +3 -3
- data/spec/cql/protocol/responses/detailed_error_response_spec.rb +15 -15
- data/spec/cql/protocol/responses/error_response_spec.rb +5 -5
- data/spec/cql/protocol/responses/event_response_spec.rb +8 -8
- data/spec/cql/protocol/responses/prepared_result_response_spec.rb +7 -7
- data/spec/cql/protocol/responses/raw_rows_result_response_spec.rb +1 -1
- data/spec/cql/protocol/responses/ready_response_spec.rb +2 -2
- data/spec/cql/protocol/responses/result_response_spec.rb +16 -16
- data/spec/cql/protocol/responses/rows_result_response_spec.rb +21 -21
- data/spec/cql/protocol/responses/schema_change_event_response_spec.rb +3 -3
- data/spec/cql/protocol/responses/schema_change_result_response_spec.rb +3 -3
- data/spec/cql/protocol/responses/set_keyspace_result_response_spec.rb +2 -2
- data/spec/cql/protocol/responses/status_change_event_response_spec.rb +3 -3
- data/spec/cql/protocol/responses/supported_response_spec.rb +3 -3
- data/spec/cql/protocol/responses/topology_change_event_response_spec.rb +3 -3
- data/spec/cql/protocol/responses/void_result_response_spec.rb +2 -2
- data/spec/cql/protocol/type_converter_spec.rb +25 -13
- data/spec/cql/time_uuid_spec.rb +17 -4
- data/spec/cql/uuid_spec.rb +5 -1
- data/spec/integration/protocol_spec.rb +48 -42
- data/spec/spec_helper.rb +0 -1
- metadata +27 -39
- data/lib/cql/byte_buffer.rb +0 -177
- data/lib/cql/client/synchronous_client.rb +0 -79
- data/lib/cql/client/synchronous_prepared_statement.rb +0 -63
- data/lib/cql/future.rb +0 -515
- data/lib/cql/io.rb +0 -15
- data/lib/cql/io/connection.rb +0 -220
- data/lib/cql/io/io_reactor.rb +0 -349
- data/lib/cql/protocol/decoding.rb +0 -187
- data/lib/cql/protocol/encoding.rb +0 -114
- data/spec/cql/byte_buffer_spec.rb +0 -337
- data/spec/cql/client/synchronous_client_spec.rb +0 -170
- data/spec/cql/client/synchronous_prepared_statement_spec.rb +0 -155
- data/spec/cql/future_spec.rb +0 -737
- data/spec/cql/io/connection_spec.rb +0 -484
- data/spec/cql/io/io_reactor_spec.rb +0 -402
- data/spec/cql/protocol/decoding_spec.rb +0 -547
- data/spec/cql/protocol/encoding_spec.rb +0 -386
- data/spec/integration/io_spec.rb +0 -283
- data/spec/support/fake_server.rb +0 -106
@@ -1,386 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
|
6
|
-
module Cql
|
7
|
-
module Protocol
|
8
|
-
describe Encoding do
|
9
|
-
let :buffer do
|
10
|
-
ByteBuffer.new
|
11
|
-
end
|
12
|
-
|
13
|
-
describe '#write_int' do
|
14
|
-
it 'encodes an int' do
|
15
|
-
Encoding.write_int(buffer, 2323234234)
|
16
|
-
buffer.should eql_bytes("\x8a\x79\xbd\xba")
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'appends to the buffer' do
|
20
|
-
buffer << "\xab"
|
21
|
-
Encoding.write_int(buffer, 10)
|
22
|
-
buffer.should eql_bytes("\xab\x00\x00\x00\x0a")
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'returns the buffer' do
|
26
|
-
result = Encoding.write_int(buffer, 2323234234)
|
27
|
-
result.should equal(buffer)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
describe '#write_short' do
|
32
|
-
it 'encodes a short' do
|
33
|
-
Encoding.write_short(buffer, 0xabcd)
|
34
|
-
buffer.should eql_bytes("\xab\xcd")
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'appends to the buffer' do
|
38
|
-
buffer << "\xab"
|
39
|
-
Encoding.write_short(buffer, 10)
|
40
|
-
buffer.should eql_bytes("\xab\x00\x0a")
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'returns the buffer' do
|
44
|
-
result = Encoding.write_short(buffer, 42)
|
45
|
-
result.should equal(buffer)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
describe '#write_string' do
|
50
|
-
it 'encodes a string' do
|
51
|
-
Encoding.write_string(buffer, 'hello')
|
52
|
-
buffer.should eql_bytes("\x00\x05hello")
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'encodes a string with multibyte characters' do
|
56
|
-
buffer << "\xff"
|
57
|
-
str = 'I love π'
|
58
|
-
Encoding.write_string(buffer, str)
|
59
|
-
buffer.should eql_bytes("\xff\x00\x09I love π")
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'encodes an empty string' do
|
63
|
-
Encoding.write_string(buffer, '')
|
64
|
-
buffer.should eql_bytes("\x00\x00")
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'encodes a non-string' do
|
68
|
-
Encoding.write_string(buffer, 42)
|
69
|
-
buffer.should eql_bytes("\x00\x0242")
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'appends to the buffer' do
|
73
|
-
buffer << "\xab"
|
74
|
-
Encoding.write_string(buffer, 'foo')
|
75
|
-
buffer.should eql_bytes("\xab\x00\x03foo")
|
76
|
-
end
|
77
|
-
|
78
|
-
it 'returns the buffer' do
|
79
|
-
result = Encoding.write_string(buffer, 'hello')
|
80
|
-
result.should equal(buffer)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
describe '#write_long_string' do
|
85
|
-
it 'encodes a string' do
|
86
|
-
Encoding.write_long_string(buffer, 'hello world ' * 100_000)
|
87
|
-
buffer.read(45).should eql_bytes("\x00\x12\x4f\x80hello world hello world hello world hello")
|
88
|
-
end
|
89
|
-
|
90
|
-
it 'encodes a string with multibyte characters' do
|
91
|
-
buffer << "\xff"
|
92
|
-
str = 'I love π'
|
93
|
-
Encoding.write_long_string(buffer, str)
|
94
|
-
buffer.should eql_bytes("\xff\x00\x00\x00\x09I love π")
|
95
|
-
end
|
96
|
-
|
97
|
-
it 'encodes an empty string' do
|
98
|
-
Encoding.write_long_string(buffer, '')
|
99
|
-
buffer.should eql_bytes("\x00\x00\x00\x00")
|
100
|
-
end
|
101
|
-
|
102
|
-
it 'appends to the buffer' do
|
103
|
-
buffer << "\xab"
|
104
|
-
Encoding.write_long_string(buffer, 'foo')
|
105
|
-
buffer.should eql_bytes("\xab\x00\x00\x00\x03foo")
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'returns the buffer' do
|
109
|
-
result = Encoding.write_long_string(buffer, 'hello')
|
110
|
-
result.should equal(buffer)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
describe '#write_uuid' do
|
115
|
-
let :uuid do
|
116
|
-
Uuid.new('a4a70900-24e1-11df-8924-001ff3591711')
|
117
|
-
end
|
118
|
-
|
119
|
-
it 'encodes an UUID' do
|
120
|
-
Encoding.write_uuid(buffer, uuid)
|
121
|
-
buffer.should eql_bytes("\xA4\xA7\t\x00$\xE1\x11\xDF\x89$\x00\x1F\xF3Y\x17\x11")
|
122
|
-
end
|
123
|
-
|
124
|
-
it 'encodes a UUID as 16 bytes' do
|
125
|
-
Encoding.write_uuid(buffer, Uuid.new('00000000-24e1-11df-8924-001ff3591711'))
|
126
|
-
buffer.size.should eql(16)
|
127
|
-
end
|
128
|
-
|
129
|
-
it 'appends to the buffer' do
|
130
|
-
buffer << 'FOO'
|
131
|
-
Encoding.write_uuid(buffer, uuid)
|
132
|
-
buffer.read(3).should eql_bytes('FOO')
|
133
|
-
end
|
134
|
-
|
135
|
-
it 'returns the buffer' do
|
136
|
-
result = Encoding.write_uuid(buffer, uuid)
|
137
|
-
result.should equal(buffer)
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
describe '#write_string_list' do
|
142
|
-
it 'encodes a string list' do
|
143
|
-
Encoding.write_string_list(buffer, %w[foo bar hello world])
|
144
|
-
buffer.should eql_bytes("\x00\x04\x00\x03foo\x00\x03bar\x00\x05hello\x00\x05world")
|
145
|
-
end
|
146
|
-
|
147
|
-
it 'encodes a string with multibyte characters' do
|
148
|
-
buffer << "\xff"
|
149
|
-
str = %w[I love π]
|
150
|
-
Encoding.write_string_list(buffer, str)
|
151
|
-
buffer.should eql_bytes("\xff\x00\x03\x00\x01I\x00\x04love\x00\x02π")
|
152
|
-
end
|
153
|
-
|
154
|
-
it 'encodes an empty string list' do
|
155
|
-
Encoding.write_string_list(buffer, [])
|
156
|
-
buffer.should eql_bytes("\x00\x00")
|
157
|
-
end
|
158
|
-
|
159
|
-
it 'appends to the buffer' do
|
160
|
-
buffer << "\xab"
|
161
|
-
Encoding.write_string_list(buffer, %w[foo bar])
|
162
|
-
buffer.should eql_bytes("\xab\x00\x02\x00\x03foo\x00\x03bar")
|
163
|
-
end
|
164
|
-
|
165
|
-
it 'returns the buffer' do
|
166
|
-
result = Encoding.write_string_list(buffer, %w[foo])
|
167
|
-
result.should equal(buffer)
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
describe '#write_bytes' do
|
172
|
-
it 'encodes a byte array' do
|
173
|
-
Encoding.write_bytes(buffer, "\xaa" * 2000)
|
174
|
-
buffer.should eql_bytes("\x00\x00\x07\xd0" << ("\xaa" * 2000))
|
175
|
-
end
|
176
|
-
|
177
|
-
it 'encodes a string with multibyte characters' do
|
178
|
-
buffer << "\xff"
|
179
|
-
str = 'I love π'
|
180
|
-
Encoding.write_bytes(buffer, str)
|
181
|
-
buffer.should eql_bytes("\xff\x00\x00\x00\x09I love π")
|
182
|
-
end
|
183
|
-
|
184
|
-
it 'encodes nil' do
|
185
|
-
Encoding.write_bytes(buffer, nil)
|
186
|
-
buffer.should eql_bytes("\xff\xff\xff\xff")
|
187
|
-
end
|
188
|
-
|
189
|
-
it 'appends to the buffer' do
|
190
|
-
buffer << "\xab"
|
191
|
-
Encoding.write_bytes(buffer, "\xf0\x0b\xbar")
|
192
|
-
buffer.should eql_bytes("\xab\x00\x00\x00\x04\xf0\x0b\xbar")
|
193
|
-
end
|
194
|
-
|
195
|
-
it 'returns the buffer' do
|
196
|
-
result = Encoding.write_bytes(buffer, "\xab")
|
197
|
-
result.should equal(buffer)
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
|
-
describe '#write_short_bytes' do
|
202
|
-
it 'encodes a byte array' do
|
203
|
-
Encoding.write_short_bytes(buffer, "\xaa\xbb\xcc")
|
204
|
-
buffer.should eql_bytes("\x00\x03\xaa\xbb\xcc")
|
205
|
-
end
|
206
|
-
|
207
|
-
it 'encodes a string with multibyte characters' do
|
208
|
-
buffer << "\xff"
|
209
|
-
str = 'I love π'
|
210
|
-
Encoding.write_short_bytes(buffer, str)
|
211
|
-
buffer.should eql_bytes("\xff\x00\x09I love π")
|
212
|
-
end
|
213
|
-
|
214
|
-
it 'encodes nil' do
|
215
|
-
Encoding.write_short_bytes(buffer, nil)
|
216
|
-
buffer.should eql_bytes("\xff\xff")
|
217
|
-
end
|
218
|
-
|
219
|
-
it 'appends to the buffer' do
|
220
|
-
buffer << "\xab"
|
221
|
-
Encoding.write_short_bytes(buffer, "\xf0\x0b\xbar")
|
222
|
-
buffer.should eql_bytes("\xab\x00\x04\xf0\x0b\xbar")
|
223
|
-
end
|
224
|
-
|
225
|
-
it 'returns the buffer' do
|
226
|
-
result = Encoding.write_short_bytes(buffer, "\xab")
|
227
|
-
result.should equal(buffer)
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
describe '#write_consistency' do
|
232
|
-
{
|
233
|
-
:any => "\x00\x00",
|
234
|
-
:one => "\x00\x01",
|
235
|
-
:two => "\x00\x02",
|
236
|
-
:three => "\x00\x03",
|
237
|
-
:quorum => "\x00\x04",
|
238
|
-
:all => "\x00\x05",
|
239
|
-
:local_quorum => "\x00\x06",
|
240
|
-
:each_quorum => "\x00\x07",
|
241
|
-
:serial => "\x00\x08",
|
242
|
-
:local_serial => "\x00\x09",
|
243
|
-
:local_one => "\x00\x0a",
|
244
|
-
}.each do |consistency, expected_encoding|
|
245
|
-
it "encodes #{consistency}" do
|
246
|
-
Encoding.write_consistency(buffer, consistency)
|
247
|
-
buffer.should eql_bytes(expected_encoding)
|
248
|
-
end
|
249
|
-
end
|
250
|
-
|
251
|
-
it 'raises an exception for an unknown consistency' do
|
252
|
-
expect { Encoding.write_consistency(buffer, :foo) }.to raise_error(EncodingError)
|
253
|
-
end
|
254
|
-
|
255
|
-
it 'appends to the buffer' do
|
256
|
-
buffer << "\xab"
|
257
|
-
Encoding.write_consistency(buffer, :one)
|
258
|
-
buffer.should eql_bytes("\xab\x00\x01")
|
259
|
-
end
|
260
|
-
|
261
|
-
it 'returns the buffer' do
|
262
|
-
result = Encoding.write_consistency(buffer, :quorum)
|
263
|
-
result.should equal(buffer)
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
describe '#write_string_map' do
|
268
|
-
it 'encodes a string map' do
|
269
|
-
Encoding.write_string_map(buffer, 'HELLO' => 'world', 'foo' => 'bar')
|
270
|
-
buffer.should eql_bytes("\x00\x02\x00\x05HELLO\x00\x05world\x00\x03foo\x00\x03bar")
|
271
|
-
end
|
272
|
-
|
273
|
-
it 'encodes an empty map' do
|
274
|
-
Encoding.write_string_map(buffer, {})
|
275
|
-
buffer.should eql_bytes("\x00\x00")
|
276
|
-
end
|
277
|
-
|
278
|
-
it 'appends to the buffer' do
|
279
|
-
buffer << "\xab"
|
280
|
-
Encoding.write_string_map(buffer, 'foo' => 'bar')
|
281
|
-
buffer.should eql_bytes("\xab\x00\x01\x00\x03foo\x00\x03bar")
|
282
|
-
end
|
283
|
-
|
284
|
-
it 'returns the buffer' do
|
285
|
-
result = Encoding.write_string_map(buffer, 'HELLO' => 'world')
|
286
|
-
result.should equal(buffer)
|
287
|
-
end
|
288
|
-
end
|
289
|
-
|
290
|
-
describe '#write_long' do
|
291
|
-
it 'encodes a long' do
|
292
|
-
Encoding.write_long(buffer, 0x0123456789)
|
293
|
-
buffer.should eql_bytes("\x00\x00\x00\x01\x23\x45\x67\x89")
|
294
|
-
end
|
295
|
-
|
296
|
-
it 'appends to the buffer' do
|
297
|
-
buffer << "\x99"
|
298
|
-
Encoding.write_long(buffer, 0x0123456789)
|
299
|
-
buffer.should eql_bytes("\x99\x00\x00\x00\x01\x23\x45\x67\x89")
|
300
|
-
end
|
301
|
-
|
302
|
-
it 'returns the buffer' do
|
303
|
-
result = Encoding.write_long(buffer, 1)
|
304
|
-
result.should equal(buffer)
|
305
|
-
end
|
306
|
-
end
|
307
|
-
|
308
|
-
describe '#write_varint' do
|
309
|
-
it 'encodes a variable length integer' do
|
310
|
-
Encoding.write_varint(buffer, 1231312312331283012830129382342342412123)
|
311
|
-
buffer.should eql_bytes("\x03\x9EV \x15\f\x03\x9DK\x18\xCDI\\$?\a[")
|
312
|
-
end
|
313
|
-
|
314
|
-
it 'encodes a negative variable length integer' do
|
315
|
-
Encoding.write_varint(buffer, -234234234234)
|
316
|
-
buffer.should eql_bytes("\xC9v\x8D:\x86")
|
317
|
-
end
|
318
|
-
|
319
|
-
it 'appends to the buffer' do
|
320
|
-
buffer << "\x99"
|
321
|
-
Encoding.write_varint(buffer, -234234234234)
|
322
|
-
buffer.should eql_bytes("\x99\xC9v\x8D:\x86")
|
323
|
-
end
|
324
|
-
|
325
|
-
it 'returns the buffer' do
|
326
|
-
result = Encoding.write_varint(buffer, -234234234234)
|
327
|
-
result.should equal(buffer)
|
328
|
-
end
|
329
|
-
end
|
330
|
-
|
331
|
-
describe '#write_decimal' do
|
332
|
-
it 'encodes a BigDecimal as a decimal' do
|
333
|
-
Encoding.write_decimal(buffer, BigDecimal.new('1042342234234.123423435647768234'))
|
334
|
-
buffer.should eql_bytes("\x00\x00\x00\x12\r'\xFDI\xAD\x80f\x11g\xDCfV\xAA")
|
335
|
-
end
|
336
|
-
|
337
|
-
it 'appends to the buffer' do
|
338
|
-
buffer << "\x99"
|
339
|
-
Encoding.write_decimal(buffer, BigDecimal.new('1042342234234.123423435647768234'))
|
340
|
-
buffer.read(1).should eql_bytes("\x99")
|
341
|
-
end
|
342
|
-
|
343
|
-
it 'returns the buffer' do
|
344
|
-
result = Encoding.write_decimal(buffer, BigDecimal.new('3.14'))
|
345
|
-
result.should equal(buffer)
|
346
|
-
end
|
347
|
-
end
|
348
|
-
|
349
|
-
describe '#write_double' do
|
350
|
-
it 'encodes a double' do
|
351
|
-
Encoding.write_double(buffer, 10000.123123123)
|
352
|
-
buffer.should eql_bytes("@\xC3\x88\x0F\xC2\x7F\x9DU")
|
353
|
-
end
|
354
|
-
|
355
|
-
it 'appends to the buffer' do
|
356
|
-
buffer << 'BEFORE'
|
357
|
-
Encoding.write_double(buffer, 10000.123123123)
|
358
|
-
buffer.read(6).should eql_bytes('BEFORE')
|
359
|
-
end
|
360
|
-
|
361
|
-
it 'returns the buffer' do
|
362
|
-
result = Encoding.write_double(buffer, 10000.123123123)
|
363
|
-
result.should equal(buffer)
|
364
|
-
end
|
365
|
-
end
|
366
|
-
|
367
|
-
describe '#write_float' do
|
368
|
-
it 'encodes a float' do
|
369
|
-
Encoding.write_float(buffer, 12.13)
|
370
|
-
buffer.should eql_bytes("AB\x14{")
|
371
|
-
end
|
372
|
-
|
373
|
-
it 'appends to the buffer' do
|
374
|
-
buffer << 'BEFORE'
|
375
|
-
Encoding.write_float(buffer, 12.13)
|
376
|
-
buffer.read(6).should eql_bytes('BEFORE')
|
377
|
-
end
|
378
|
-
|
379
|
-
it 'returns the buffer' do
|
380
|
-
result = Encoding.write_float(buffer, 12.13)
|
381
|
-
result.should equal(buffer)
|
382
|
-
end
|
383
|
-
end
|
384
|
-
end
|
385
|
-
end
|
386
|
-
end
|
data/spec/integration/io_spec.rb
DELETED
@@ -1,283 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
|
6
|
-
describe 'An IO reactor' do
|
7
|
-
context 'with a generic server' do
|
8
|
-
let :io_reactor do
|
9
|
-
Cql::Io::IoReactor.new(IoSpec::TestConnection)
|
10
|
-
end
|
11
|
-
|
12
|
-
let :fake_server do
|
13
|
-
FakeServer.new
|
14
|
-
end
|
15
|
-
|
16
|
-
before do
|
17
|
-
fake_server.start!
|
18
|
-
io_reactor.start
|
19
|
-
end
|
20
|
-
|
21
|
-
after do
|
22
|
-
io_reactor.stop
|
23
|
-
fake_server.stop!
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'connects to the server' do
|
27
|
-
io_reactor.connect(ENV['CASSANDRA_HOST'], fake_server.port, 1)
|
28
|
-
fake_server.await_connects!(1)
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'receives data' do
|
32
|
-
protocol_handler = io_reactor.connect(ENV['CASSANDRA_HOST'], fake_server.port, 1).value
|
33
|
-
fake_server.await_connects!(1)
|
34
|
-
fake_server.broadcast!('hello world')
|
35
|
-
await { protocol_handler.data.bytesize > 0 }
|
36
|
-
protocol_handler.data.should == 'hello world'
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'receives data on multiple connections' do
|
40
|
-
protocol_handlers = Array.new(10) { io_reactor.connect(ENV['CASSANDRA_HOST'], fake_server.port, 1).value }
|
41
|
-
fake_server.await_connects!(10)
|
42
|
-
fake_server.broadcast!('hello world')
|
43
|
-
await { protocol_handlers.all? { |c| c.data.bytesize > 0 } }
|
44
|
-
protocol_handlers.sample.data.should == 'hello world'
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
context 'when talking to Redis' do
|
49
|
-
let :io_reactor do
|
50
|
-
Cql::Io::IoReactor.new(IoSpec::RedisProtocolHandler)
|
51
|
-
end
|
52
|
-
|
53
|
-
let :protocol_handler do
|
54
|
-
begin
|
55
|
-
io_reactor.connect(ENV['CASSANDRA_HOST'], 6379, 1).value
|
56
|
-
rescue Cql::Io::ConnectionError
|
57
|
-
nil
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
before do
|
62
|
-
io_reactor.start.value
|
63
|
-
end
|
64
|
-
|
65
|
-
after do
|
66
|
-
io_reactor.stop.value
|
67
|
-
end
|
68
|
-
|
69
|
-
it 'can set a value' do
|
70
|
-
pending('Redis not running', unless: protocol_handler)
|
71
|
-
response = protocol_handler.send_request('SET', 'foo', 'bar').value
|
72
|
-
response.should == 'OK'
|
73
|
-
end
|
74
|
-
|
75
|
-
it 'can get a value' do
|
76
|
-
pending('Redis not running', unless: protocol_handler)
|
77
|
-
f = protocol_handler.send_request('SET', 'foo', 'bar').flat_map do
|
78
|
-
protocol_handler.send_request('GET', 'foo')
|
79
|
-
end
|
80
|
-
f.value.should == 'bar'
|
81
|
-
end
|
82
|
-
|
83
|
-
it 'can delete values' do
|
84
|
-
pending('Redis not running', unless: protocol_handler)
|
85
|
-
f = protocol_handler.send_request('SET', 'hello', 'world').flat_map do
|
86
|
-
protocol_handler.send_request('DEL', 'hello')
|
87
|
-
end
|
88
|
-
f.value.should == 1
|
89
|
-
end
|
90
|
-
|
91
|
-
it 'handles nil values' do
|
92
|
-
pending('Redis not running', unless: protocol_handler)
|
93
|
-
f = protocol_handler.send_request('DEL', 'hello').flat_map do
|
94
|
-
protocol_handler.send_request('GET', 'hello')
|
95
|
-
end
|
96
|
-
f.value.should be_nil
|
97
|
-
end
|
98
|
-
|
99
|
-
it 'handles errors' do
|
100
|
-
pending('Redis not running', unless: protocol_handler)
|
101
|
-
f = protocol_handler.send_request('SET', 'foo')
|
102
|
-
expect { f.value }.to raise_error("ERR wrong number of arguments for 'set' command")
|
103
|
-
end
|
104
|
-
|
105
|
-
it 'handles replies with multiple elements' do
|
106
|
-
pending('Redis not running', unless: protocol_handler)
|
107
|
-
f = protocol_handler.send_request('DEL', 'stuff')
|
108
|
-
f.value
|
109
|
-
f = protocol_handler.send_request('RPUSH', 'stuff', 'hello', 'world')
|
110
|
-
f.value.should == 2
|
111
|
-
f = protocol_handler.send_request('LRANGE', 'stuff', 0, 2)
|
112
|
-
f.value.should == ['hello', 'world']
|
113
|
-
end
|
114
|
-
|
115
|
-
it 'handles nil values when reading multiple elements' do
|
116
|
-
pending('Redis not running', unless: protocol_handler)
|
117
|
-
protocol_handler.send_request('DEL', 'things')
|
118
|
-
protocol_handler.send_request('HSET', 'things', 'hello', 'world')
|
119
|
-
f = protocol_handler.send_request('HMGET', 'things', 'hello', 'foo')
|
120
|
-
f.value.should == ['world', nil]
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
module IoSpec
|
126
|
-
class TestConnection
|
127
|
-
def initialize(connection, scheduler)
|
128
|
-
@connection = connection
|
129
|
-
@connection.on_data(&method(:receive_data))
|
130
|
-
@lock = Mutex.new
|
131
|
-
@data = Cql::ByteBuffer.new
|
132
|
-
end
|
133
|
-
|
134
|
-
def data
|
135
|
-
@lock.synchronize { @data.to_s }
|
136
|
-
end
|
137
|
-
|
138
|
-
private
|
139
|
-
|
140
|
-
def receive_data(new_data)
|
141
|
-
@lock.synchronize { @data << new_data }
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
class LineProtocolHandler
|
146
|
-
def initialize(connection, scheduler)
|
147
|
-
@connection = connection
|
148
|
-
@connection.on_data(&method(:process_data))
|
149
|
-
@lock = Mutex.new
|
150
|
-
@buffer = ''
|
151
|
-
@requests = []
|
152
|
-
end
|
153
|
-
|
154
|
-
def on_line(&listener)
|
155
|
-
@line_listener = listener
|
156
|
-
end
|
157
|
-
|
158
|
-
def write(command_string)
|
159
|
-
@connection.write(command_string)
|
160
|
-
end
|
161
|
-
|
162
|
-
def process_data(new_data)
|
163
|
-
lines = []
|
164
|
-
@lock.synchronize do
|
165
|
-
@buffer << new_data
|
166
|
-
while newline_index = @buffer.index("\r\n")
|
167
|
-
line = @buffer.slice!(0, newline_index + 2)
|
168
|
-
line.chomp!
|
169
|
-
lines << line
|
170
|
-
end
|
171
|
-
end
|
172
|
-
lines.each do |line|
|
173
|
-
@line_listener.call(line) if @line_listener
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
class RedisProtocolHandler
|
179
|
-
def initialize(connection, scheduler)
|
180
|
-
@line_protocol = LineProtocolHandler.new(connection, scheduler)
|
181
|
-
@line_protocol.on_line(&method(:handle_line))
|
182
|
-
@lock = Mutex.new
|
183
|
-
@responses = []
|
184
|
-
@state = BaseState.new(method(:handle_response))
|
185
|
-
end
|
186
|
-
|
187
|
-
def send_request(*args)
|
188
|
-
promise = Cql::Promise.new
|
189
|
-
@lock.synchronize do
|
190
|
-
@responses << promise
|
191
|
-
end
|
192
|
-
request = "*#{args.size}\r\n"
|
193
|
-
args.each do |arg|
|
194
|
-
arg_str = arg.to_s
|
195
|
-
request << "$#{arg_str.bytesize}\r\n#{arg_str}\r\n"
|
196
|
-
end
|
197
|
-
@line_protocol.write(request)
|
198
|
-
promise.future
|
199
|
-
end
|
200
|
-
|
201
|
-
def handle_response(result, error=false)
|
202
|
-
promise = @lock.synchronize do
|
203
|
-
@responses.shift
|
204
|
-
end
|
205
|
-
if error
|
206
|
-
promise.fail(StandardError.new(result))
|
207
|
-
else
|
208
|
-
promise.fulfill(result)
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
def handle_line(line)
|
213
|
-
@state = @state.handle_line(line)
|
214
|
-
end
|
215
|
-
|
216
|
-
class State
|
217
|
-
def initialize(result_handler)
|
218
|
-
@result_handler = result_handler
|
219
|
-
end
|
220
|
-
|
221
|
-
def complete!(result)
|
222
|
-
@result_handler.call(result)
|
223
|
-
end
|
224
|
-
|
225
|
-
def fail!(message)
|
226
|
-
@result_handler.call(message, true)
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
class BulkState < State
|
231
|
-
def handle_line(line)
|
232
|
-
complete!(line)
|
233
|
-
BaseState.new(@result_handler)
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
|
-
class MultiBulkState < State
|
238
|
-
def initialize(result_handler, expected_elements)
|
239
|
-
super(result_handler)
|
240
|
-
@expected_elements = expected_elements
|
241
|
-
@elements = []
|
242
|
-
end
|
243
|
-
|
244
|
-
def handle_line(line)
|
245
|
-
if line.start_with?('$')
|
246
|
-
line.slice!(0, 1)
|
247
|
-
if line.to_i == -1
|
248
|
-
@elements << nil
|
249
|
-
end
|
250
|
-
else
|
251
|
-
@elements << line
|
252
|
-
end
|
253
|
-
if @elements.size == @expected_elements
|
254
|
-
complete!(@elements)
|
255
|
-
BaseState.new(@result_handler)
|
256
|
-
else
|
257
|
-
self
|
258
|
-
end
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
class BaseState < State
|
263
|
-
def handle_line(line)
|
264
|
-
next_state = self
|
265
|
-
first_char = line.slice!(0, 1)
|
266
|
-
case first_char
|
267
|
-
when '+' then complete!(line)
|
268
|
-
when ':' then complete!(line.to_i)
|
269
|
-
when '-' then fail!(line)
|
270
|
-
when '$'
|
271
|
-
if line.to_i == -1
|
272
|
-
complete!(nil)
|
273
|
-
else
|
274
|
-
next_state = BulkState.new(@result_handler)
|
275
|
-
end
|
276
|
-
when '*'
|
277
|
-
next_state = MultiBulkState.new(@result_handler, line.to_i)
|
278
|
-
end
|
279
|
-
next_state
|
280
|
-
end
|
281
|
-
end
|
282
|
-
end
|
283
|
-
end
|