package com.lambdaworks.redis.masterslave; import static com.lambdaworks.redis.TestSettings.port; import static com.lambdaworks.redis.masterslave.MasterSlaveTest.slaveCall; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; import java.net.ConnectException; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.springframework.test.util.ReflectionTestUtils; import com.lambdaworks.TestClientResources; import com.lambdaworks.redis.*; import com.lambdaworks.redis.codec.Utf8StringCodec; import com.lambdaworks.redis.sentinel.AbstractSentinelTest; import com.lambdaworks.redis.sentinel.SentinelRule; import io.netty.channel.group.ChannelGroup; /** * @author Mark Paluch */ public class MasterSlaveSentinelTest extends AbstractSentinelTest { static { sentinelClient = RedisClient.create(TestClientResources.create(), RedisURI.Builder.sentinel(TestSettings.host(), MASTER_ID).build()); } @Rule public SentinelRule sentinelRule = new SentinelRule(sentinelClient, false, 26379, 26380); private RedisURI sentinelUri = RedisURI.Builder.sentinel(TestSettings.host(), 26379, MASTER_ID).build(); private Pattern pattern = Pattern.compile("role:(\\w+)"); @Before public void before() throws Exception { sentinelRule.needMasterWithSlave(MASTER_ID, port(3), port(4)); } @Test public void testMasterSlaveSentinelBasic() throws Exception { RedisURI uri = RedisURI.create( "redis-sentinel://127.0.0.1:21379,127.0.0.1:22379,127.0.0.1:26379?sentinelMasterId=mymaster&timeout=5s"); StatefulRedisMasterSlaveConnection<String, String> connection = MasterSlave.connect(sentinelClient, new Utf8StringCodec(), uri); connection.setReadFrom(ReadFrom.MASTER); String server = slaveCall(connection); assertThatServerIs(server, "master"); connection.close(); } @Test public void testMasterSlaveSentinelWithTwoUnavailableSentinels() throws Exception { RedisURI uri = RedisURI.create( "redis-sentinel://127.0.0.1:21379,127.0.0.1:22379,127.0.0.1:26379?sentinelMasterId=mymaster&timeout=5s"); StatefulRedisMasterSlaveConnection<String, String> connection = MasterSlave.connect(sentinelClient, new Utf8StringCodec(), uri); connection.setReadFrom(ReadFrom.MASTER); String server = connection.sync().info("replication"); assertThatServerIs(server, "master"); connection.close(); } @Test public void testMasterSlaveSentinelWithUnavailableSentinels() throws Exception { RedisURI uri = RedisURI .create("redis-sentinel://127.0.0.1:21379,127.0.0.1:21379?sentinelMasterId=mymaster&timeout=5s"); try { MasterSlave.connect(sentinelClient, new Utf8StringCodec(), uri); fail("Missing RedisConnectionException"); } catch (RedisConnectionException e) { assertThat(e.getCause()).hasCauseInstanceOf(ConnectException.class); } } @Test public void testMasterSlaveSentinelConnectionCount() throws Exception { ChannelGroup channels = (ChannelGroup) ReflectionTestUtils.getField(sentinelClient, "channels"); int count = channels.size(); StatefulRedisMasterSlaveConnection<String, String> connection = MasterSlave.connect(sentinelClient, new Utf8StringCodec(), sentinelUri); connection.sync().ping(); connection.setReadFrom(ReadFrom.SLAVE); slaveCall(connection); assertThat(channels.size()).isEqualTo(count + 2 /* connections */ + 1 /* sentinel connections */); connection.close(); } @Test public void testMasterSlaveSentinelClosesSentinelConnections() throws Exception { ChannelGroup channels = (ChannelGroup) ReflectionTestUtils.getField(sentinelClient, "channels"); int count = channels.size(); StatefulRedisMasterSlaveConnection<String, String> connection = MasterSlave.connect(sentinelClient, new Utf8StringCodec(), sentinelUri); connection.sync().ping(); connection.setReadFrom(ReadFrom.SLAVE); slaveCall(connection); connection.close(); assertThat(channels.size()).isEqualTo(count); } protected void assertThatServerIs(String server, String expectation) { Matcher matcher = pattern.matcher(server); assertThat(matcher.find()).isTrue(); assertThat(matcher.group(1)).isEqualTo(expectation); } }