cql-rb 1.1.3 → 1.2.0.pre0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +19 -11
  3. data/lib/cql.rb +1 -0
  4. data/lib/cql/client.rb +41 -9
  5. data/lib/cql/client/asynchronous_client.rb +9 -4
  6. data/lib/cql/client/asynchronous_prepared_statement.rb +2 -2
  7. data/lib/cql/client/connection_helper.rb +43 -20
  8. data/lib/cql/client/execute_options_decoder.rb +4 -1
  9. data/lib/cql/client/query_result.rb +7 -3
  10. data/lib/cql/client/query_trace.rb +46 -0
  11. data/lib/cql/client/request_runner.rb +7 -2
  12. data/lib/cql/client/void_result.rb +42 -0
  13. data/lib/cql/compression.rb +53 -0
  14. data/lib/cql/compression/snappy_compressor.rb +42 -0
  15. data/lib/cql/io/io_reactor.rb +9 -4
  16. data/lib/cql/protocol.rb +5 -3
  17. data/lib/cql/protocol/cql_protocol_handler.rb +14 -9
  18. data/lib/cql/protocol/frame_decoder.rb +106 -0
  19. data/lib/cql/protocol/frame_encoder.rb +31 -0
  20. data/lib/cql/protocol/request.rb +7 -11
  21. data/lib/cql/protocol/requests/execute_request.rb +2 -2
  22. data/lib/cql/protocol/requests/options_request.rb +4 -0
  23. data/lib/cql/protocol/requests/prepare_request.rb +2 -2
  24. data/lib/cql/protocol/requests/query_request.rb +2 -2
  25. data/lib/cql/protocol/requests/startup_request.rb +12 -5
  26. data/lib/cql/protocol/response.rb +13 -2
  27. data/lib/cql/protocol/responses/authenticate_response.rb +5 -1
  28. data/lib/cql/protocol/responses/detailed_error_response.rb +2 -2
  29. data/lib/cql/protocol/responses/error_response.rb +7 -2
  30. data/lib/cql/protocol/responses/event_response.rb +4 -2
  31. data/lib/cql/protocol/responses/prepared_result_response.rb +20 -4
  32. data/lib/cql/protocol/responses/ready_response.rb +5 -1
  33. data/lib/cql/protocol/responses/result_response.rb +10 -2
  34. data/lib/cql/protocol/responses/rows_result_response.rb +5 -4
  35. data/lib/cql/protocol/responses/schema_change_event_response.rb +1 -1
  36. data/lib/cql/protocol/responses/schema_change_result_response.rb +5 -4
  37. data/lib/cql/protocol/responses/set_keyspace_result_response.rb +4 -3
  38. data/lib/cql/protocol/responses/{status_change_event_result_response.rb → status_change_event_response.rb} +1 -1
  39. data/lib/cql/protocol/responses/supported_response.rb +5 -1
  40. data/lib/cql/protocol/responses/{topology_change_event_result_response.rb → topology_change_event_response.rb} +0 -0
  41. data/lib/cql/protocol/responses/void_result_response.rb +2 -2
  42. data/lib/cql/version.rb +1 -1
  43. data/spec/cql/client/asynchronous_client_spec.rb +52 -31
  44. data/spec/cql/client/asynchronous_prepared_statement_spec.rb +16 -2
  45. data/spec/cql/client/connection_helper_spec.rb +90 -12
  46. data/spec/cql/client/query_trace_spec.rb +138 -0
  47. data/spec/cql/client/request_runner_spec.rb +44 -7
  48. data/spec/cql/client/void_result_spec.rb +43 -0
  49. data/spec/cql/compression/compression_common.rb +59 -0
  50. data/spec/cql/compression/snappy_compressor_spec.rb +23 -0
  51. data/spec/cql/io/io_reactor_spec.rb +8 -1
  52. data/spec/cql/protocol/cql_protocol_handler_spec.rb +40 -0
  53. data/spec/cql/protocol/frame_decoder_spec.rb +132 -0
  54. data/spec/cql/protocol/frame_encoder_spec.rb +105 -0
  55. data/spec/cql/protocol/requests/credentials_request_spec.rb +2 -4
  56. data/spec/cql/protocol/requests/execute_request_spec.rb +5 -5
  57. data/spec/cql/protocol/requests/options_request_spec.rb +10 -4
  58. data/spec/cql/protocol/requests/prepare_request_spec.rb +3 -3
  59. data/spec/cql/protocol/requests/query_request_spec.rb +10 -5
  60. data/spec/cql/protocol/requests/register_request_spec.rb +3 -3
  61. data/spec/cql/protocol/requests/startup_request_spec.rb +11 -5
  62. data/spec/cql/protocol/responses/authenticate_response_spec.rb +27 -0
  63. data/spec/cql/protocol/responses/detailed_error_response_spec.rb +78 -0
  64. data/spec/cql/protocol/responses/error_response_spec.rb +36 -0
  65. data/spec/cql/protocol/responses/event_response_spec.rb +40 -0
  66. data/spec/cql/protocol/responses/prepared_result_response_spec.rb +108 -0
  67. data/spec/cql/protocol/responses/ready_response_spec.rb +39 -0
  68. data/spec/cql/protocol/responses/result_response_spec.rb +57 -0
  69. data/spec/cql/protocol/responses/rows_result_response_spec.rb +273 -0
  70. data/spec/cql/protocol/responses/schema_change_event_response_spec.rb +93 -0
  71. data/spec/cql/protocol/responses/schema_change_result_response_spec.rb +51 -19
  72. data/spec/cql/protocol/responses/set_keyspace_result_response_spec.rb +34 -0
  73. data/spec/cql/protocol/responses/status_change_event_response_spec.rb +35 -0
  74. data/spec/cql/protocol/responses/supported_response_spec.rb +27 -0
  75. data/spec/cql/protocol/responses/topology_change_event_response_spec.rb +35 -0
  76. data/spec/cql/protocol/responses/void_result_response_spec.rb +29 -0
  77. data/spec/integration/client_spec.rb +45 -0
  78. data/spec/integration/protocol_spec.rb +46 -0
  79. data/spec/spec_helper.rb +2 -1
  80. data/spec/support/fake_io_reactor.rb +1 -1
  81. metadata +51 -10
  82. data/lib/cql/protocol/response_frame.rb +0 -129
  83. data/spec/cql/protocol/request_spec.rb +0 -45
  84. data/spec/cql/protocol/response_frame_spec.rb +0 -811
@@ -46,9 +46,9 @@ module Cql
46
46
  when Protocol::PrepareRequest
47
47
  statement_id = [rand(2**31)].pack('c*')
48
48
  connection[:last_prepared_statement_id] = statement_id
49
- Protocol::PreparedResultResponse.new(statement_id, raw_metadata)
49
+ Protocol::PreparedResultResponse.new(statement_id, raw_metadata, nil)
50
50
  when Protocol::ExecuteRequest
51
- Protocol::RowsResultResponse.new(rows, raw_metadata)
51
+ Protocol::RowsResultResponse.new(rows, raw_metadata, nil)
52
52
  else
53
53
  raise %(Unexpected request: #{request})
54
54
  end
@@ -190,6 +190,20 @@ module Cql
190
190
  expect { f1.value }.to raise_error(NoMethodError)
191
191
  expect { f2.value }.to raise_error(ArgumentError)
192
192
  end
193
+
194
+ it 'sets the trace flag' do
195
+ tracing = false
196
+ connections.each do |c|
197
+ c.handle_request do |r, t|
198
+ if r.is_a?(Protocol::ExecuteRequest)
199
+ tracing = r.trace
200
+ end
201
+ handle_request(c, r, t)
202
+ end
203
+ end
204
+ statement.execute(11, 'hello', trace: true).value
205
+ tracing.should be_true
206
+ end
193
207
  end
194
208
  end
195
209
  end
@@ -7,7 +7,7 @@ module Cql
7
7
  module Client
8
8
  describe ConnectionHelper do
9
9
  let :connection_helper do
10
- described_class.new(io_reactor, 9876, nil, 1, 7, logger)
10
+ described_class.new(io_reactor, 9876, nil, 1, 7, compressor, logger)
11
11
  end
12
12
 
13
13
  let :io_reactor do
@@ -18,6 +18,10 @@ module Cql
18
18
  NullLogger.new
19
19
  end
20
20
 
21
+ let :compressor do
22
+ nil
23
+ end
24
+
21
25
  describe '#connect' do
22
26
  let :hosts do
23
27
  %w[host0 host1]
@@ -92,10 +96,26 @@ module Cql
92
96
  io_reactor.stub(:connect).with('host1', 9876, 7).and_return(Future.resolved(connection1))
93
97
  connection_helper.connect(hosts, 'some_keyspace')
94
98
  [connection0, connection1].each do |c|
95
- c.requests[0].should be_a(Protocol::StartupRequest)
96
- c.requests[1].cql.should match(/SELECT .* FROM system.local/)
97
- c.requests[2].cql.should == 'USE some_keyspace'
99
+ c.requests[0].should be_a(Protocol::OptionsRequest)
100
+ c.requests[1].should be_a(Protocol::StartupRequest)
101
+ c.requests[2].cql.should match(/SELECT .* FROM system.local/)
102
+ c.requests[3].cql.should == 'USE some_keyspace'
103
+ end
104
+ end
105
+
106
+ it 'saves the supported CQL version and compression algorithms on the connection' do
107
+ connection = FakeConnection.new('host0', 9876, 7)
108
+ connection.handle_request do |request, timeout|
109
+ if request.is_a?(Protocol::OptionsRequest)
110
+ Protocol::SupportedResponse.new('CQL_VERSION' => %w[3.1.1], 'COMPRESSION' => %w[lz4 snappy])
111
+ else
112
+ connection.default_request_handler(request, timeout)
113
+ end
98
114
  end
115
+ io_reactor.stub(:connect).with('host0', 9876, 7).and_return(Future.resolved(connection))
116
+ connection_helper.connect(hosts.take(1), 'some_keyspace')
117
+ connection[:cql_version].should == %w[3.1.1]
118
+ connection[:compression].should == %w[lz4 snappy]
99
119
  end
100
120
 
101
121
  it 'fails if authentication is required and no credentials were specified' do
@@ -114,7 +134,7 @@ module Cql
114
134
 
115
135
  it 'authenticates when authentication is required and credentials were specified' do
116
136
  credentials = {'username' => 'foo', 'password' => 'bar'}
117
- connection_helper = described_class.new(io_reactor, 9876, credentials, 1, 7, logger)
137
+ connection_helper = described_class.new(io_reactor, 9876, credentials, 1, 7, nil, logger)
118
138
  connection = FakeConnection.new('host0', 9876, 7)
119
139
  authentication_sent = false
120
140
  connection.handle_request do |request|
@@ -138,7 +158,7 @@ module Cql
138
158
  connection.handle_request do |request|
139
159
  if request.is_a?(Protocol::QueryRequest) && request.cql =~ /SELECT .* FROM system\.local/
140
160
  row = {'data_center' => 'dc1', 'host_id' => Uuid.new('eac69196-1e28-11e3-8e2b-191b6d153d0c')}
141
- Protocol::RowsResultResponse.new([row], local_metadata)
161
+ Protocol::RowsResultResponse.new([row], local_metadata, nil)
142
162
  else
143
163
  connection.default_request_handler(request)
144
164
  end
@@ -180,11 +200,68 @@ module Cql
180
200
  end
181
201
 
182
202
  it 'connects to each node a configurable number of times' do
183
- connection_helper = described_class.new(io_reactor, 9876, nil, connections_per_node = 3, 7, logger)
203
+ connection_helper = described_class.new(io_reactor, 9876, nil, connections_per_node = 3, 7, nil, logger)
184
204
  connection_helper.connect(hosts, nil)
185
205
  io_reactor.should have_received(:connect).with('host0', 9876, 7).exactly(3).times
186
206
  io_reactor.should have_received(:connect).with('host1', 9876, 7).exactly(3).times
187
207
  end
208
+
209
+ context 'when a compressor is specified' do
210
+ let :compressor do
211
+ double(:compressor, algorithm: 'snappy')
212
+ end
213
+
214
+ let :connection do
215
+ FakeConnection.new('host0', 9876, 7)
216
+ end
217
+
218
+ it 'enables compression by sending the algorithm with the STARTUP request' do
219
+ connection.handle_request do |request, timeout|
220
+ if request.is_a?(Protocol::OptionsRequest)
221
+ Protocol::SupportedResponse.new('CQL_VERSION' => %w[3.1.1], 'COMPRESSION' => %w[lz4 snappy])
222
+ else
223
+ connection.default_request_handler(request, timeout)
224
+ end
225
+ end
226
+ io_reactor.stub(:connect).with('host0', 9876, 7).and_return(Future.resolved(connection))
227
+ connection_helper.connect(hosts.take(1), 'some_keyspace')
228
+ connection.requests[1].options['COMPRESSION'].should == 'snappy'
229
+ end
230
+
231
+ it 'does not enable compression when the algorithm is not supported' do
232
+ connection.handle_request do |request, timeout|
233
+ if request.is_a?(Protocol::OptionsRequest)
234
+ Protocol::SupportedResponse.new('CQL_VERSION' => %w[3.1.1], 'COMPRESSION' => %w[lz4])
235
+ else
236
+ connection.default_request_handler(request, timeout)
237
+ end
238
+ end
239
+ io_reactor.stub(:connect).with('host0', 9876, 7).and_return(Future.resolved(connection))
240
+ connection_helper.connect(hosts.take(1), 'some_keyspace')
241
+ connection.requests[1].options.should_not have_key('COMPRESSION')
242
+ end
243
+
244
+ it 'logs a warning when compression was disabled because the algorithm was not supported' do
245
+ logger.stub(:warn)
246
+ connection.handle_request do |request, timeout|
247
+ if request.is_a?(Protocol::OptionsRequest)
248
+ Protocol::SupportedResponse.new('CQL_VERSION' => %w[3.1.1], 'COMPRESSION' => %w[lz4])
249
+ else
250
+ connection.default_request_handler(request, timeout)
251
+ end
252
+ end
253
+ io_reactor.stub(:connect).with('host0', 9876, 7).and_return(Future.resolved(connection))
254
+ connection_helper.connect(hosts.take(1), 'some_keyspace')
255
+ logger.should have_received(:warn).with(/not supported/)
256
+ end
257
+
258
+ it 'logs the name of the compression algorithm when connecting' do
259
+ logger.stub(:debug)
260
+ io_reactor.stub(:connect).with('host0', 9876, 7).and_return(Future.resolved(connection))
261
+ connection_helper.connect(hosts.take(1), 'some_keyspace')
262
+ logger.should have_received(:debug).with(/using "snappy" compression/)
263
+ end
264
+ end
188
265
  end
189
266
 
190
267
  describe '#discover_peers' do
@@ -232,7 +309,7 @@ module Cql
232
309
  seed_connections.each do |c|
233
310
  c.handle_request do |request|
234
311
  if request.cql =~ /SELECT .* FROM system\.peers/
235
- Protocol::RowsResultResponse.new(yield, peer_metadata)
312
+ Protocol::RowsResultResponse.new(yield, peer_metadata, nil)
236
313
  end
237
314
  end
238
315
  end
@@ -308,9 +385,10 @@ module Cql
308
385
  peer_request_response { seed_connection_rows + extra_connection_rows.take(1) }
309
386
  f = connection_helper.discover_peers(seed_connections, 'some_keyspace')
310
387
  f.value
311
- connection.requests[0].should be_a(Protocol::StartupRequest)
312
- connection.requests[1].cql.should match(/SELECT .* FROM system.local/)
313
- connection.requests[2].cql.should == 'USE some_keyspace'
388
+ connection.requests[0].should be_a(Protocol::OptionsRequest)
389
+ connection.requests[1].should be_a(Protocol::StartupRequest)
390
+ connection.requests[2].cql.should match(/SELECT .* FROM system.local/)
391
+ connection.requests[3].cql.should == 'USE some_keyspace'
314
392
  end
315
393
 
316
394
  it 'connects only to node in the same data centers as the seed nodes' do
@@ -338,7 +416,7 @@ module Cql
338
416
  end
339
417
 
340
418
  it 'connects to each node a configurable number of times' do
341
- connection_helper = described_class.new(io_reactor, 9876, nil, connections_per_node = 3, 7, logger)
419
+ connection_helper = described_class.new(io_reactor, 9876, nil, connections_per_node = 3, 7, nil, logger)
342
420
  connection = FakeConnection.new('host3', 9876, 7)
343
421
  io_reactor.stub(:connect).with('1.0.0.3', 9876, 7).and_return(Future.resolved(connection))
344
422
  peer_request_response { seed_connection_rows + extra_connection_rows.take(1) }
@@ -0,0 +1,138 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+
6
+ module Cql
7
+ module Client
8
+ describe QueryTrace do
9
+ let :trace do
10
+ described_class.new(session_row, event_rows)
11
+ end
12
+
13
+ let :started_at do
14
+ Time.now
15
+ end
16
+
17
+ let :session_row do
18
+ {
19
+ 'session_id' => Uuid.new('a1028490-3f05-11e3-9531-fb72eff05fbb'),
20
+ 'coordinator' => IPAddr.new('127.0.0.1'),
21
+ 'duration' => 1263,
22
+ 'parameters' => {
23
+ 'query' => 'SELECT * FROM something'
24
+ },
25
+ 'request' => 'Execute CQL3 query',
26
+ 'started_at' => started_at
27
+ }
28
+ end
29
+
30
+ let :event_rows do
31
+ [
32
+ {
33
+ 'session_id' => Uuid.new('a1028490-3f05-11e3-9531-fb72eff05fbb'),
34
+ 'event_id' => TimeUuid.new('a1028491-3f05-11e3-9531-fb72eff05fbb'),
35
+ 'activity' => 'Parsing statement',
36
+ 'source' => IPAddr.new('127.0.0.1'),
37
+ 'source_elapsed' => 52,
38
+ 'thread' => 'Native-Transport-Requests:126'
39
+ },
40
+ {
41
+ 'session_id' => Uuid.new('a1028490-3f05-11e3-9531-fb72eff05fbb'),
42
+ 'event_id' => TimeUuid.new('a1028492-3f05-11e3-9531-fb72eff05fbb'),
43
+ 'activity' => 'Peparing statement',
44
+ 'source' => IPAddr.new('127.0.0.1'),
45
+ 'source_elapsed' => 54,
46
+ 'thread' => 'Native-Transport-Requests:126'
47
+ },
48
+ ]
49
+ end
50
+
51
+ context 'when the session is nil' do
52
+ it 'returns nil from all methods' do
53
+ trace = described_class.new(nil, nil)
54
+ trace.coordinator.should be_nil
55
+ trace.cql.should be_nil
56
+ trace.started_at.should be_nil
57
+ trace.events.should be_empty
58
+ end
59
+ end
60
+
61
+ context 'when the duration field of the session is nil' do
62
+ it 'raises an IncompleteTraceError' do
63
+ session_row['duration'] = nil
64
+ expect { described_class.new(session_row, event_rows) }.to raise_error(IncompleteTraceError)
65
+ end
66
+ end
67
+
68
+ describe '#coordinator' do
69
+ it 'returns the IP address of the coordinator node' do
70
+ trace.coordinator.should == IPAddr.new('127.0.0.1')
71
+ end
72
+ end
73
+
74
+ describe '#cql' do
75
+ it 'returns the query' do
76
+ trace.cql.should == 'SELECT * FROM something'
77
+ end
78
+ end
79
+
80
+ describe '#started_at' do
81
+ it 'returns the time the request started' do
82
+ trace.started_at.should eql(started_at)
83
+ end
84
+ end
85
+
86
+ describe '#duration' do
87
+ it 'returns the duration in seconds' do
88
+ trace.duration.should == 0.001263
89
+ end
90
+ end
91
+
92
+ describe '#events' do
93
+ it 'returns a list of TraceEvents' do
94
+ trace.events.should have(2).items
95
+ trace.events.first.should be_a(TraceEvent)
96
+ end
97
+
98
+ it 'returns an unmodifiable list' do
99
+ expect { trace.events << :foo }.to raise_error
100
+ end
101
+
102
+ context 'returns a list of trace events whose' do
103
+ let :events do
104
+ trace.events
105
+ end
106
+
107
+ let :event do
108
+ events.first
109
+ end
110
+
111
+ describe '#activity' do
112
+ it 'returns the event activity' do
113
+ event.activity.should == 'Parsing statement'
114
+ end
115
+ end
116
+
117
+ describe '#source' do
118
+ it 'returns the event source' do
119
+ event.source.should == IPAddr.new('127.0.0.1')
120
+ end
121
+ end
122
+
123
+ describe '#source_elapsed' do
124
+ it 'returns the elapsed time at the source' do
125
+ event.source_elapsed.should == 0.000052
126
+ end
127
+ end
128
+
129
+ describe '#time' do
130
+ it 'returns the time component from the event ID' do
131
+ event.time.to_i.should == TimeUuid.new('a1028492-3f05-11e3-9531-fb72eff05fbb').to_time.to_i
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
@@ -35,27 +35,31 @@ module Cql
35
35
 
36
36
  describe '#execute' do
37
37
  let :rows_response do
38
- Protocol::RowsResultResponse.new(rows, metadata)
38
+ Protocol::RowsResultResponse.new(rows, metadata, nil)
39
39
  end
40
40
 
41
41
  let :void_response do
42
- Protocol::VoidResultResponse.new
42
+ Protocol::VoidResultResponse.new(nil)
43
43
  end
44
44
 
45
45
  let :prepared_response do
46
- Protocol::PreparedResultResponse.new("\x2a", metadata)
46
+ Protocol::PreparedResultResponse.new("\x2a", metadata, nil)
47
47
  end
48
48
 
49
49
  let :error_response do
50
50
  Protocol::ErrorResponse.new(0xbad, 'Bork')
51
51
  end
52
52
 
53
+ let :detailed_error_response do
54
+ Protocol::DetailedErrorResponse.new(0xbad, 'Bork', {:cl => :quorum, :received => 1, :blockfor => 1, :write_type => 'SINGLE'})
55
+ end
56
+
53
57
  let :authenticate_response do
54
58
  Protocol::AuthenticateResponse.new('TheAuthenticator')
55
59
  end
56
60
 
57
61
  let :set_keyspace_response do
58
- Protocol::SetKeyspaceResultResponse.new('some_keyspace')
62
+ Protocol::SetKeyspaceResultResponse.new('some_keyspace', nil)
59
63
  end
60
64
 
61
65
  def run(response, rq=request)
@@ -75,14 +79,14 @@ module Cql
75
79
  connection.should have_received(:send_request).with(request, 7)
76
80
  end
77
81
 
78
- it 'transforms a RowsResultResponse to a query result' do
82
+ it 'transforms a RowsResultResponse to a QueryResult' do
79
83
  result = run(rows_response)
80
84
  result.should have(3).items
81
85
  end
82
86
 
83
- it 'transforms a VoidResultResponse to nil' do
87
+ it 'transforms a VoidResultResponse to a VoidResult' do
84
88
  result = run(void_response)
85
- result.should be_nil
89
+ result.should be_a(VoidResult)
86
90
  end
87
91
 
88
92
  it 'transforms a AuthenticateResponse to an authentication required object' do
@@ -111,6 +115,21 @@ module Cql
111
115
  end
112
116
  end
113
117
 
118
+ it 'sets the #details field of QueryError when the response has details' do
119
+ begin
120
+ run(detailed_error_response)
121
+ rescue QueryError => e
122
+ e.details.should == detailed_error_response.details
123
+ else
124
+ fail('No error was raised')
125
+ end
126
+ end
127
+
128
+ it 'transforms a SupportedResponse into its hash of supported options' do
129
+ result = run(Protocol::SupportedResponse.new('CQL_VERSION' => %w[9.9.9], 'COMPRESSION' => %w[fractal quantum]))
130
+ result.should eql('CQL_VERSION' => %w[9.9.9], 'COMPRESSION' => %w[fractal quantum])
131
+ end
132
+
114
133
  it 'transforms all other responses to nil' do
115
134
  result = run('hibbly hobbly')
116
135
  result.should be_nil
@@ -121,6 +140,24 @@ module Cql
121
140
  result = runner.execute(connection, request) { |response| response.reverse }.value
122
141
  result.should == 'hibbly hobbly'.reverse
123
142
  end
143
+
144
+ context 'when the response has a trace ID' do
145
+ let :trace_id do
146
+ Uuid.new('63a26b40-3f02-11e3-9531-fb72eff05fbb')
147
+ end
148
+
149
+ it 'returns a QueryResult that knows its trace ID' do
150
+ connection.stub(:send_request).with(request, anything).and_return(Future.resolved(Protocol::RowsResultResponse.new(rows, metadata, trace_id)))
151
+ response = runner.execute(connection, request).value
152
+ response.trace_id.should == trace_id
153
+ end
154
+
155
+ it 'returns a VoidResult that knows its trace ID' do
156
+ connection.stub(:send_request).with(request, anything).and_return(Future.resolved(Protocol::VoidResultResponse.new(trace_id)))
157
+ response = runner.execute(connection, request).value
158
+ response.trace_id.should == trace_id
159
+ end
160
+ end
124
161
  end
125
162
  end
126
163
  end
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+
6
+ module Cql
7
+ module Client
8
+ describe VoidResult do
9
+ describe '#empty?' do
10
+ it 'is true' do
11
+ described_class.new.should be_empty
12
+ end
13
+ end
14
+
15
+ describe '#trace_id' do
16
+ it 'is nil' do
17
+ described_class.new.trace_id.should be_nil
18
+ end
19
+
20
+ it 'is set through the constructor' do
21
+ uuid = Uuid.new('63a26b40-3f02-11e3-9531-fb72eff05fbb')
22
+ described_class.new(uuid).trace_id.should == uuid
23
+ end
24
+ end
25
+
26
+ describe '#metadata' do
27
+ it 'is empty' do
28
+ described_class.new.metadata.each.to_a.should be_empty
29
+ end
30
+ end
31
+
32
+ describe '#each' do
33
+ it 'returns an enumerable' do
34
+ described_class.new.each.should be_a(Enumerable)
35
+ end
36
+
37
+ it 'enumerates nothing' do
38
+ described_class.new.each.to_a.should be_empty
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end