cql-rb 1.1.3 → 1.2.0.pre0
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 +19 -11
- data/lib/cql.rb +1 -0
- data/lib/cql/client.rb +41 -9
- data/lib/cql/client/asynchronous_client.rb +9 -4
- data/lib/cql/client/asynchronous_prepared_statement.rb +2 -2
- data/lib/cql/client/connection_helper.rb +43 -20
- data/lib/cql/client/execute_options_decoder.rb +4 -1
- data/lib/cql/client/query_result.rb +7 -3
- data/lib/cql/client/query_trace.rb +46 -0
- data/lib/cql/client/request_runner.rb +7 -2
- data/lib/cql/client/void_result.rb +42 -0
- data/lib/cql/compression.rb +53 -0
- data/lib/cql/compression/snappy_compressor.rb +42 -0
- data/lib/cql/io/io_reactor.rb +9 -4
- data/lib/cql/protocol.rb +5 -3
- data/lib/cql/protocol/cql_protocol_handler.rb +14 -9
- data/lib/cql/protocol/frame_decoder.rb +106 -0
- data/lib/cql/protocol/frame_encoder.rb +31 -0
- data/lib/cql/protocol/request.rb +7 -11
- data/lib/cql/protocol/requests/execute_request.rb +2 -2
- data/lib/cql/protocol/requests/options_request.rb +4 -0
- data/lib/cql/protocol/requests/prepare_request.rb +2 -2
- data/lib/cql/protocol/requests/query_request.rb +2 -2
- data/lib/cql/protocol/requests/startup_request.rb +12 -5
- data/lib/cql/protocol/response.rb +13 -2
- data/lib/cql/protocol/responses/authenticate_response.rb +5 -1
- data/lib/cql/protocol/responses/detailed_error_response.rb +2 -2
- data/lib/cql/protocol/responses/error_response.rb +7 -2
- data/lib/cql/protocol/responses/event_response.rb +4 -2
- data/lib/cql/protocol/responses/prepared_result_response.rb +20 -4
- data/lib/cql/protocol/responses/ready_response.rb +5 -1
- data/lib/cql/protocol/responses/result_response.rb +10 -2
- data/lib/cql/protocol/responses/rows_result_response.rb +5 -4
- data/lib/cql/protocol/responses/schema_change_event_response.rb +1 -1
- data/lib/cql/protocol/responses/schema_change_result_response.rb +5 -4
- data/lib/cql/protocol/responses/set_keyspace_result_response.rb +4 -3
- data/lib/cql/protocol/responses/{status_change_event_result_response.rb → status_change_event_response.rb} +1 -1
- data/lib/cql/protocol/responses/supported_response.rb +5 -1
- data/lib/cql/protocol/responses/{topology_change_event_result_response.rb → topology_change_event_response.rb} +0 -0
- data/lib/cql/protocol/responses/void_result_response.rb +2 -2
- data/lib/cql/version.rb +1 -1
- data/spec/cql/client/asynchronous_client_spec.rb +52 -31
- data/spec/cql/client/asynchronous_prepared_statement_spec.rb +16 -2
- data/spec/cql/client/connection_helper_spec.rb +90 -12
- data/spec/cql/client/query_trace_spec.rb +138 -0
- data/spec/cql/client/request_runner_spec.rb +44 -7
- data/spec/cql/client/void_result_spec.rb +43 -0
- data/spec/cql/compression/compression_common.rb +59 -0
- data/spec/cql/compression/snappy_compressor_spec.rb +23 -0
- data/spec/cql/io/io_reactor_spec.rb +8 -1
- data/spec/cql/protocol/cql_protocol_handler_spec.rb +40 -0
- data/spec/cql/protocol/frame_decoder_spec.rb +132 -0
- data/spec/cql/protocol/frame_encoder_spec.rb +105 -0
- data/spec/cql/protocol/requests/credentials_request_spec.rb +2 -4
- data/spec/cql/protocol/requests/execute_request_spec.rb +5 -5
- data/spec/cql/protocol/requests/options_request_spec.rb +10 -4
- data/spec/cql/protocol/requests/prepare_request_spec.rb +3 -3
- data/spec/cql/protocol/requests/query_request_spec.rb +10 -5
- data/spec/cql/protocol/requests/register_request_spec.rb +3 -3
- data/spec/cql/protocol/requests/startup_request_spec.rb +11 -5
- data/spec/cql/protocol/responses/authenticate_response_spec.rb +27 -0
- data/spec/cql/protocol/responses/detailed_error_response_spec.rb +78 -0
- data/spec/cql/protocol/responses/error_response_spec.rb +36 -0
- data/spec/cql/protocol/responses/event_response_spec.rb +40 -0
- data/spec/cql/protocol/responses/prepared_result_response_spec.rb +108 -0
- data/spec/cql/protocol/responses/ready_response_spec.rb +39 -0
- data/spec/cql/protocol/responses/result_response_spec.rb +57 -0
- data/spec/cql/protocol/responses/rows_result_response_spec.rb +273 -0
- data/spec/cql/protocol/responses/schema_change_event_response_spec.rb +93 -0
- data/spec/cql/protocol/responses/schema_change_result_response_spec.rb +51 -19
- data/spec/cql/protocol/responses/set_keyspace_result_response_spec.rb +34 -0
- data/spec/cql/protocol/responses/status_change_event_response_spec.rb +35 -0
- data/spec/cql/protocol/responses/supported_response_spec.rb +27 -0
- data/spec/cql/protocol/responses/topology_change_event_response_spec.rb +35 -0
- data/spec/cql/protocol/responses/void_result_response_spec.rb +29 -0
- data/spec/integration/client_spec.rb +45 -0
- data/spec/integration/protocol_spec.rb +46 -0
- data/spec/spec_helper.rb +2 -1
- data/spec/support/fake_io_reactor.rb +1 -1
- metadata +51 -10
- data/lib/cql/protocol/response_frame.rb +0 -129
- data/spec/cql/protocol/request_spec.rb +0 -45
- 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:: | 
| 96 | 
            -
                        c.requests[1]. | 
| 97 | 
            -
                        c.requests[2].cql.should  | 
| 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:: | 
| 312 | 
            -
                      connection.requests[1]. | 
| 313 | 
            -
                      connection.requests[2].cql.should  | 
| 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  | 
| 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  | 
| 87 | 
            +
                    it 'transforms a VoidResultResponse to a VoidResult' do
         | 
| 84 88 | 
             
                      result = run(void_response)
         | 
| 85 | 
            -
                      result.should  | 
| 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
         |