cql-rb 2.0.0.pre0 → 2.0.0.pre1
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.
- 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
|