@@ -393,6 +393,85 @@ public void should_adjust_connection_keyspace_on_dequeue_if_pool_state_is_differ
393393 }
394394 }
395395
396+ /**
397+ * Ensures that if keyspace setup fails while borrowing a connection, the borrow future fails and
398+ * pool accounting is restored.
399+ *
400+ * @test_category connection:connection_pool
401+ */
402+ @ Test (groups = "short" )
403+ public void should_restore_pool_accounting_when_keyspace_setup_fails_on_borrow ()
404+ throws Exception {
405+ Cluster cluster = createClusterBuilder ().build ();
406+ try {
407+ HostConnectionPool pool = createPool (cluster , 1 , 1 );
408+ Connection connection = spy (pool .connections [0 ].get (0 ));
409+ pool .connections [0 ].set (0 , connection );
410+
411+ pool .manager .poolsState .setKeyspace ("newkeyspace" );
412+ ConnectionException failure =
413+ new ConnectionException (pool .host .getEndPoint (), "Write attempt on defunct connection" );
414+ doReturn (Futures .<Connection >immediateFailedFuture (failure ))
415+ .when (connection )
416+ .setKeyspaceAsync ("newkeyspace" );
417+
418+ MockRequest request = MockRequest .send (pool );
419+
420+ try {
421+ Uninterruptibles .getUninterruptibly (request .connectionFuture , 5 , TimeUnit .SECONDS );
422+ fail ("Should have failed to borrow connection" );
423+ } catch (ExecutionException e ) {
424+ assertThat (e .getCause ()).isSameAs (failure );
425+ }
426+ assertThat (connection .inFlight .get ()).isEqualTo (0 );
427+ assertThat (pool .totalInFlight .get ()).isEqualTo (0 );
428+ } finally {
429+ cluster .close ();
430+ }
431+ }
432+
433+ /**
434+ * Ensures that a synchronous write failure while setting the keyspace is reported through the
435+ * returned future and does not leave the failed keyspace attempt in-flight.
436+ *
437+ * @test_category connection:connection_pool
438+ */
439+ @ Test (groups = "short" )
440+ public void should_fail_keyspace_future_and_clear_attempt_when_connection_is_defunct ()
441+ throws Exception {
442+ Cluster cluster = createClusterBuilder ().build ();
443+ try {
444+ HostConnectionPool pool = createPool (cluster , 1 , 1 );
445+ Connection connection = pool .connections [0 ].get (0 );
446+
447+ connection .defunct (
448+ new ConnectionException (pool .host .getEndPoint (), "Test defunct connection" ));
449+
450+ ListenableFuture <Connection > firstAttempt = connection .setKeyspaceAsync ("newkeyspace" );
451+ ListenableFuture <Connection > secondAttempt = connection .setKeyspaceAsync ("newkeyspace" );
452+
453+ assertThat (firstAttempt ).isNotSameAs (secondAttempt );
454+ try {
455+ Uninterruptibles .getUninterruptibly (firstAttempt , 5 , TimeUnit .SECONDS );
456+ fail ("Should have failed keyspace attempt" );
457+ } catch (ExecutionException e ) {
458+ assertThat (e .getCause ())
459+ .isInstanceOf (ConnectionException .class )
460+ .hasMessageContaining ("Write attempt on defunct connection" );
461+ }
462+ try {
463+ Uninterruptibles .getUninterruptibly (secondAttempt , 5 , TimeUnit .SECONDS );
464+ fail ("Should have failed keyspace attempt" );
465+ } catch (ExecutionException e ) {
466+ assertThat (e .getCause ())
467+ .isInstanceOf (ConnectionException .class )
468+ .hasMessageContaining ("Write attempt on defunct connection" );
469+ }
470+ } finally {
471+ cluster .close ();
472+ }
473+ }
474+
396475 /**
397476 * Ensures that on borrowConnection if a set keyspace attempt is in progress on that connection
398477 * for a different keyspace than the pool state that the borrowConnection future returned is
@@ -501,6 +580,9 @@ public void should_adjust_connection_keyspace_on_dequeue_if_pool_state_is_differ
501580 .contains (
502581 "Aborting attempt to set keyspace to 'newkeyspace' since there is already an in flight attempt to set keyspace to 'slowks'." );
503582 }
583+ assertThat (connection .inFlight .get ()).isEqualTo (0 );
584+ assertThat (pool .totalInFlight .get ()).isEqualTo (0 );
585+ assertThat (pool .pendingBorrowCount .get ()).isEqualTo (0 );
504586 } finally {
505587 MockRequest .completeAll (requests );
506588 cluster .close ();
0 commit comments