@Test
void correctNumberOfRetiesAreLoggedOnFailureAsync()
{

    Clock clock = mock( Clock.class );
    Logging logging = mock( Logging.class );
    Logger logger = mock( Logger.class );
    when( logging.getLog( anyString() ) ).thenReturn( logger );
    RetrySettings settings = RetrySettings.DEFAULT;
    RetryLogic logic = new ExponentialBackoffRetryLogic( settings, eventExecutor, clock, logging );
    SessionExpiredException error = assertThrows( SessionExpiredException.class, () ->
            await( logic.retryAsync( new Supplier<CompletionStage<Void>>()
            {
                volatile boolean invoked;
                @Override
                public CompletionStage<Void> get()
                {
                    // work that always returns failed future and moves clock forward after the first failure
                    if ( invoked )
                    {
                        // move clock forward to stop retries
                        when( clock.millis() ).thenReturn( settings.maxRetryTimeMs() + 42 );
                    }
                    else
                    {
                        invoked = true;
                    }
                    return failedFuture( new SessionExpiredException( "Session no longer valid" ) );
                }
            } ) ) );
    assertEquals( "Session no longer valid", error.getMessage() );
    verify( logger ).warn(
            startsWith( "Async transaction failed and is scheduled to retry" ),
            any( SessionExpiredException.class )
    );
}