package com.lambdaworks.redis.sentinel; import static com.google.code.tempusfugit.temporal.Duration.seconds; import static com.lambdaworks.Delay.delay; import static com.lambdaworks.redis.TestSettings.port; import static org.assertj.core.api.Assertions.assertThat; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.lambdaworks.redis.FastShutdown; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import com.lambdaworks.redis.RedisClient; import com.lambdaworks.redis.RedisURI; import com.lambdaworks.redis.TestSettings; import com.lambdaworks.redis.api.sync.RedisCommands; @Ignore("For manual runs only. Fails too often due to slow sentinel sync") public class SentinelFailoverTest extends AbstractSentinelTest { @Rule public SentinelRule sentinelRule = new SentinelRule(sentinelClient, false, 26379, 26380); @BeforeClass public static void setupClient() { sentinelClient = new RedisClient(RedisURI.Builder.sentinel(TestSettings.host(), 26380, MASTER_ID).build()); } @Before public void openConnection() throws Exception { sentinel = sentinelClient.connectSentinelAsync().getStatefulConnection().sync(); sentinelRule.needMasterWithSlave(MASTER_ID, port(3), port(4)); } @Test public void connectToRedisUsingSentinel() throws Exception { RedisCommands<String, String> connect = sentinelClient.connect().sync(); assertThat(connect.ping()).isEqualToIgnoringCase("PONG"); connect.close(); } @Test public void failover() throws Exception { RedisClient redisClient = new RedisClient(RedisURI.Builder.redis(TestSettings.host(), port(3)).build()); String tcpPort1 = connectUsingSentinelAndGetPort(); sentinelRule.waitForConnectedSlaves(MASTER_ID); sentinel.failover(MASTER_ID); delay(seconds(5)); sentinelRule.waitForConnectedSlaves(MASTER_ID); String tcpPort2 = connectUsingSentinelAndGetPort(); assertThat(tcpPort1).isNotEqualTo(tcpPort2); FastShutdown.shutdown(redisClient); } protected String connectUsingSentinelAndGetPort() { RedisCommands<String, String> connectAfterFailover = sentinelClient.connect().sync(); String tcpPort2 = getTcpPort(connectAfterFailover); connectAfterFailover.close(); return tcpPort2; } protected String getTcpPort(RedisCommands<String, String> commands) { Pattern pattern = Pattern.compile(".*tcp_port\\:(\\d+).*", Pattern.DOTALL); Matcher matcher = pattern.matcher(commands.info("server")); if (matcher.lookingAt()) { return matcher.group(1); } return null; } }