diff --git a/src/test/java/redis/clients/jedis/misc/AutomaticFailoverTest.java b/src/test/java/redis/clients/jedis/misc/AutomaticFailoverTest.java index cd87689b6c..d87b8a6bc1 100644 --- a/src/test/java/redis/clients/jedis/misc/AutomaticFailoverTest.java +++ b/src/test/java/redis/clients/jedis/misc/AutomaticFailoverTest.java @@ -1,5 +1,6 @@ package redis.clients.jedis.misc; +import java.net.UnknownHostException; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -18,8 +19,11 @@ import redis.clients.jedis.providers.MultiClusterPooledConnectionProvider; import redis.clients.jedis.util.IOUtils; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; public class AutomaticFailoverTest { @@ -87,6 +91,46 @@ public void transactionWithSwitch() { assertEquals("bar", jedis2.hget("thash", "foo")); } + @Test + public void commandFailoverUnresolvableHost() { + int slidingWindowMinCalls = 2; + int slidingWindowSize = 2; + + HostAndPort unresolvableHostAndPort = new HostAndPort("unresolvable", 6379); + MultiClusterClientConfig.Builder builder = new MultiClusterClientConfig.Builder( + getClusterConfigs(clientConfig, unresolvableHostAndPort, + workingEndpoint.getHostAndPort())).retryWaitDuration(1).retryMaxAttempts(1) + .circuitBreakerSlidingWindowMinCalls(slidingWindowMinCalls) + .circuitBreakerSlidingWindowSize(slidingWindowSize); + + RedisFailoverReporter failoverReporter = new RedisFailoverReporter(); + MultiClusterPooledConnectionProvider connectionProvider = new MultiClusterPooledConnectionProvider( + builder.build()); + connectionProvider.setClusterFailoverPostProcessor(failoverReporter); + + UnifiedJedis jedis = new UnifiedJedis(connectionProvider); + + String key = "hash-" + System.nanoTime(); + log.info("Starting calls to Redis"); + assertFalse(failoverReporter.failedOver); + + for (int attempt = 0; attempt < slidingWindowMinCalls; attempt++) { + Throwable thrown = assertThrows(JedisConnectionException.class, + () -> jedis.hset(key, "f1", "v1")); + assertThat(thrown.getCause(), instanceOf(UnknownHostException.class)); + assertFalse(failoverReporter.failedOver); + } + + // should failover now + jedis.hset(key, "f1", "v1"); + assertTrue(failoverReporter.failedOver); + + assertEquals(Collections.singletonMap("f1", "v1"), jedis.hgetAll(key)); + jedis.flushAll(); + + jedis.close(); + } + @Test public void commandFailover() { int slidingWindowMinCalls = 10; @@ -94,14 +138,15 @@ public void commandFailover() { MultiClusterClientConfig.Builder builder = new MultiClusterClientConfig.Builder( getClusterConfigs(clientConfig, hostPortWithFailure, workingEndpoint.getHostAndPort())) - .circuitBreakerSlidingWindowMinCalls(slidingWindowMinCalls) - .circuitBreakerSlidingWindowSize(slidingWindowSize); + .retryWaitDuration(1).circuitBreakerSlidingWindowMinCalls(slidingWindowMinCalls) + .circuitBreakerSlidingWindowSize(slidingWindowSize); RedisFailoverReporter failoverReporter = new RedisFailoverReporter(); - MultiClusterPooledConnectionProvider cacheProvider = new MultiClusterPooledConnectionProvider(builder.build()); - cacheProvider.setClusterFailoverPostProcessor(failoverReporter); + MultiClusterPooledConnectionProvider connectionProvider = new MultiClusterPooledConnectionProvider( + builder.build()); + connectionProvider.setClusterFailoverPostProcessor(failoverReporter); - UnifiedJedis jedis = new UnifiedJedis(cacheProvider); + UnifiedJedis jedis = new UnifiedJedis(connectionProvider); String key = "hash-" + System.nanoTime(); log.info("Starting calls to Redis"); @@ -132,15 +177,16 @@ public void pipelineFailover() { MultiClusterClientConfig.Builder builder = new MultiClusterClientConfig.Builder( getClusterConfigs(clientConfig, hostPortWithFailure, workingEndpoint.getHostAndPort())) - .circuitBreakerSlidingWindowMinCalls(slidingWindowMinCalls) - .circuitBreakerSlidingWindowSize(slidingWindowSize) - .fallbackExceptionList(Collections.singletonList(JedisConnectionException.class)); + .circuitBreakerSlidingWindowMinCalls(slidingWindowMinCalls) + .circuitBreakerSlidingWindowSize(slidingWindowSize) + .fallbackExceptionList(Collections.singletonList(JedisConnectionException.class)); RedisFailoverReporter failoverReporter = new RedisFailoverReporter(); - MultiClusterPooledConnectionProvider cacheProvider = new MultiClusterPooledConnectionProvider(builder.build()); - cacheProvider.setClusterFailoverPostProcessor(failoverReporter); + MultiClusterPooledConnectionProvider connectionProvider = new MultiClusterPooledConnectionProvider( + builder.build()); + connectionProvider.setClusterFailoverPostProcessor(failoverReporter); - UnifiedJedis jedis = new UnifiedJedis(cacheProvider); + UnifiedJedis jedis = new UnifiedJedis(connectionProvider); String key = "hash-" + System.nanoTime(); log.info("Starting calls to Redis"); @@ -164,16 +210,18 @@ public void failoverFromAuthError() { int slidingWindowSize = 10; MultiClusterClientConfig.Builder builder = new MultiClusterClientConfig.Builder( - getClusterConfigs(clientConfig, endpointForAuthFailure.getHostAndPort(), workingEndpoint.getHostAndPort())) - .circuitBreakerSlidingWindowMinCalls(slidingWindowMinCalls) - .circuitBreakerSlidingWindowSize(slidingWindowSize) - .fallbackExceptionList(Collections.singletonList(JedisAccessControlException.class)); + getClusterConfigs(clientConfig, endpointForAuthFailure.getHostAndPort(), + workingEndpoint.getHostAndPort())) + .circuitBreakerSlidingWindowMinCalls(slidingWindowMinCalls) + .circuitBreakerSlidingWindowSize(slidingWindowSize) + .fallbackExceptionList(Collections.singletonList(JedisAccessControlException.class)); RedisFailoverReporter failoverReporter = new RedisFailoverReporter(); - MultiClusterPooledConnectionProvider cacheProvider = new MultiClusterPooledConnectionProvider(builder.build()); - cacheProvider.setClusterFailoverPostProcessor(failoverReporter); + MultiClusterPooledConnectionProvider connectionProvider = new MultiClusterPooledConnectionProvider( + builder.build()); + connectionProvider.setClusterFailoverPostProcessor(failoverReporter); - UnifiedJedis jedis = new UnifiedJedis(cacheProvider); + UnifiedJedis jedis = new UnifiedJedis(connectionProvider); String key = "hash-" + System.nanoTime(); log.info("Starting calls to Redis");