Search in sources :

Example 1 with RandomResponseServer

use of io.lettuce.test.server.RandomResponseServer in project lettuce-core by lettuce-io.

the class ConnectionFailureIntegrationTests method failOnReconnect.

/**
 * Simulates a failure on reconnect by changing the port to a invalid server and triggering a reconnect. Meanwhile a command
 * is fired to the connection and the watchdog is triggered afterwards to reconnect.
 *
 * Expectation: Command after failed reconnect contains the reconnect exception.
 *
 * @throws Exception
 */
@Test
void failOnReconnect() throws Exception {
    ClientOptions clientOptions = ClientOptions.builder().suspendReconnectOnProtocolFailure(true).build();
    client.setOptions(clientOptions);
    RandomResponseServer ts = getRandomResponseServer();
    RedisURI redisUri = RedisURI.Builder.redis(TestSettings.host(), TestSettings.port()).build();
    redisUri.setTimeout(Duration.ofSeconds(5));
    try {
        RedisAsyncCommands<String, String> connection = client.connect(redisUri).async();
        ConnectionWatchdog connectionWatchdog = ConnectionTestUtil.getConnectionWatchdog(connection.getStatefulConnection());
        assertThat(connectionWatchdog.isListenOnChannelInactive()).isTrue();
        assertThat(connectionWatchdog.isReconnectSuspended()).isFalse();
        assertThat(clientOptions.isSuspendReconnectOnProtocolFailure()).isTrue();
        assertThat(connectionWatchdog.getReconnectionHandler().getClientOptions()).isSameAs(clientOptions);
        redisUri.setPort(TestSettings.nonexistentPort());
        connection.quit();
        Wait.untilTrue(() -> connectionWatchdog.isReconnectSuspended()).waitOrTimeout();
        assertThat(connectionWatchdog.isListenOnChannelInactive()).isTrue();
        assertThatThrownBy(() -> TestFutures.awaitOrTimeout(connection.info())).hasRootCauseInstanceOf(RedisException.class).hasMessageContaining("Invalid first byte");
        connection.getStatefulConnection().close();
    } finally {
        ts.shutdown();
    }
}
Also used : RandomResponseServer(io.lettuce.test.server.RandomResponseServer) Test(org.junit.jupiter.api.Test)

Example 2 with RandomResponseServer

use of io.lettuce.test.server.RandomResponseServer in project lettuce-core by lettuce-io.

the class ConnectionFailureIntegrationTests method failOnReconnectShouldSendEvents.

/**
 * Simulates a failure on reconnect by changing the port to a invalid server and triggering a reconnect.
 *
 * Expectation: {@link io.lettuce.core.ConnectionEvents.Reconnect} events are sent.
 *
 * @throws Exception
 */
@Test
void failOnReconnectShouldSendEvents() throws Exception {
    client.setOptions(ClientOptions.builder().suspendReconnectOnProtocolFailure(false).build());
    RandomResponseServer ts = getRandomResponseServer();
    RedisURI redisUri = RedisURI.create(defaultRedisUri.toURI());
    redisUri.setTimeout(Duration.ofSeconds(5));
    try {
        final BlockingQueue<ConnectionEvents.Reconnect> events = new LinkedBlockingDeque<>();
        RedisAsyncCommands<String, String> connection = client.connect(redisUri).async();
        ConnectionWatchdog connectionWatchdog = ConnectionTestUtil.getConnectionWatchdog(connection.getStatefulConnection());
        ReconnectionListener reconnectionListener = events::offer;
        Field field = ConnectionWatchdog.class.getDeclaredField("reconnectionListener");
        field.setAccessible(true);
        field.set(connectionWatchdog, reconnectionListener);
        redisUri.setPort(TestSettings.nonexistentPort());
        connection.quit();
        Wait.untilTrue(() -> events.size() > 1).waitOrTimeout();
        connection.getStatefulConnection().close();
        ConnectionEvents.Reconnect event1 = events.take();
        assertThat(event1.getAttempt()).isEqualTo(1);
        ConnectionEvents.Reconnect event2 = events.take();
        assertThat(event2.getAttempt()).isEqualTo(2);
    } finally {
        ts.shutdown();
    }
}
Also used : RandomResponseServer(io.lettuce.test.server.RandomResponseServer) Field(java.lang.reflect.Field) Test(org.junit.jupiter.api.Test)

Example 3 with RandomResponseServer

use of io.lettuce.test.server.RandomResponseServer in project lettuce-core by lettuce-io.

the class ConnectionFailureIntegrationTests method invalidFirstByte.

/**
 * Expect to run into Invalid first byte exception instead of timeout.
 *
 * @throws Exception
 */
@Test
void invalidFirstByte() throws Exception {
    client.setOptions(ClientOptions.builder().build());
    RandomResponseServer ts = getRandomResponseServer();
    RedisURI redisUri = RedisURI.Builder.redis(TestSettings.host(), TestSettings.nonexistentPort()).withTimeout(Duration.ofMinutes(10)).build();
    try {
        client.connect(redisUri);
    } catch (Exception e) {
        assertThat(e).isExactlyInstanceOf(RedisConnectionException.class);
        assertThat(e.getCause()).hasMessageContaining("Invalid first byte:");
    } finally {
        ts.shutdown();
    }
}
Also used : RandomResponseServer(io.lettuce.test.server.RandomResponseServer) Test(org.junit.jupiter.api.Test)

Example 4 with RandomResponseServer

use of io.lettuce.test.server.RandomResponseServer in project lettuce-core by lettuce-io.

the class ConnectionFailureIntegrationTests method getRandomResponseServer.

RandomResponseServer getRandomResponseServer() throws InterruptedException {
    RandomResponseServer ts = new RandomResponseServer();
    ts.initialize(TestSettings.nonexistentPort());
    return ts;
}
Also used : RandomResponseServer(io.lettuce.test.server.RandomResponseServer)

Example 5 with RandomResponseServer

use of io.lettuce.test.server.RandomResponseServer in project lettuce-core by lettuce-io.

the class ConnectionFailureIntegrationTests method cancelCommandsOnReconnectFailure.

/**
 * Simulates a failure on reconnect by changing the port to a invalid server and triggering a reconnect. Meanwhile a command
 * is fired to the connection and the watchdog is triggered afterwards to reconnect.
 *
 * Expectation: Queued commands are canceled (reset), subsequent commands contain the connection exception.
 *
 * @throws Exception
 */
@Test
void cancelCommandsOnReconnectFailure() throws Exception {
    client.setOptions(ClientOptions.builder().cancelCommandsOnReconnectFailure(true).build());
    RandomResponseServer ts = getRandomResponseServer();
    RedisURI redisUri = RedisURI.create(defaultRedisUri.toURI());
    try {
        RedisAsyncCommandsImpl<String, String> connection = (RedisAsyncCommandsImpl<String, String>) client.connect(redisUri).async();
        ConnectionWatchdog connectionWatchdog = ConnectionTestUtil.getConnectionWatchdog(connection.getStatefulConnection());
        assertThat(connectionWatchdog.isListenOnChannelInactive()).isTrue();
        connectionWatchdog.setReconnectSuspended(true);
        redisUri.setPort(TestSettings.nonexistentPort());
        connection.quit();
        Wait.untilTrue(() -> !connection.getStatefulConnection().isOpen()).waitOrTimeout();
        RedisFuture<String> set1 = connection.set(key, value);
        RedisFuture<String> set2 = connection.set(key, value);
        assertThat(set1.isDone()).isFalse();
        assertThat(set1.isCancelled()).isFalse();
        assertThat(connection.getStatefulConnection().isOpen()).isFalse();
        connectionWatchdog.setReconnectSuspended(false);
        connectionWatchdog.run(0);
        Delay.delay(Duration.ofMillis(500));
        assertThat(connection.getStatefulConnection().isOpen()).isFalse();
        assertThatThrownBy(set1::get).isInstanceOf(CancellationException.class).hasNoCause();
        assertThatThrownBy(set2::get).isInstanceOf(CancellationException.class).hasNoCause();
        assertThatThrownBy(() -> TestFutures.awaitOrTimeout(connection.info())).isInstanceOf(RedisException.class).hasMessageContaining("Invalid first byte");
        connection.getStatefulConnection().close();
    } finally {
        ts.shutdown();
    }
}
Also used : RandomResponseServer(io.lettuce.test.server.RandomResponseServer) Test(org.junit.jupiter.api.Test)

Aggregations

RandomResponseServer (io.lettuce.test.server.RandomResponseServer)6 Test (org.junit.jupiter.api.Test)5 Event (io.lettuce.core.event.Event)1 ReconnectFailedEvent (io.lettuce.core.event.connection.ReconnectFailedEvent)1 ClientResources (io.lettuce.core.resource.ClientResources)1 Field (java.lang.reflect.Field)1