Fix race condition in JedisSentinelPoolTest

The test was issuing the failover command and only afterwards
connecting to the pub-sub channel to receive failover notifications.
If the failover occurred fast enought the pub-sub listener would never
get the notification.

Run the failover command on a separate Jedis connection after we're
absolutely sure that we're subscribed to the pub-sub channel.
This commit is contained in:
Nelson Rodrigues
2014-07-28 10:56:21 -07:00
parent 9e128b4520
commit 9013078d40
3 changed files with 11 additions and 7 deletions

View File

@@ -23,6 +23,7 @@ public class HostAndPortUtil {
sentinelHostAndPortList.add(new HostAndPort("localhost", Protocol.DEFAULT_SENTINEL_PORT));
sentinelHostAndPortList.add(new HostAndPort("localhost", Protocol.DEFAULT_SENTINEL_PORT + 1));
sentinelHostAndPortList.add(new HostAndPort("localhost", Protocol.DEFAULT_SENTINEL_PORT + 2));
sentinelHostAndPortList.add(new HostAndPort("localhost", Protocol.DEFAULT_SENTINEL_PORT + 3));
clusterHostAndPortList.add(new HostAndPort("localhost", 7379));
clusterHostAndPortList.add(new HostAndPort("localhost", 7380));

View File

@@ -21,18 +21,24 @@ public class JedisSentinelPoolTest extends JedisTestBase {
.get(2);
protected static HostAndPort slave1 = HostAndPortUtil.getRedisServers()
.get(3);
protected static HostAndPort sentinel1 = HostAndPortUtil
.getSentinelServers().get(1);
protected static HostAndPort sentinel2 = HostAndPortUtil
.getSentinelServers().get(3);
protected static Jedis sentinelJedis1;
protected static Jedis sentinelJedis2;
protected Set<String> sentinels = new HashSet<String>();
@Before
public void setUp() throws Exception {
sentinels.add(sentinel1.toString());
sentinels.add(sentinel2.toString());
sentinelJedis1 = new Jedis(sentinel1.getHost(), sentinel1.getPort());
sentinelJedis2 = new Jedis(sentinel2.getHost(), sentinel2.getPort());
}
@Test
@@ -137,11 +143,6 @@ public class JedisSentinelPoolTest extends JedisTestBase {
Jedis jedis = pool.getResource();
assertEquals("PONG", jedis.ping());
// It can throw JedisDataException while there's no slave to promote
// There's nothing we can do, so we just pass Exception to make test
// fail fast
sentinelJedis1.sentinelFailover(MASTER_NAME);
waitForFailover(pool, oldMaster);
// JedisSentinelPool recognize master but may not changed internal pool
// yet
@@ -156,7 +157,7 @@ public class JedisSentinelPoolTest extends JedisTestBase {
private void waitForFailover(JedisSentinelPool pool, HostAndPort oldMaster)
throws InterruptedException {
HostAndPort newMaster = JedisSentinelTestUtil
.waitForNewPromotedMaster(sentinelJedis1);
.waitForNewPromotedMaster(MASTER_NAME, sentinelJedis1, sentinelJedis2);
waitForJedisSentinelPoolRecognizeNewMaster(pool, newMaster);
}

View File

@@ -8,7 +8,8 @@ import redis.clients.jedis.JedisPubSub;
import redis.clients.jedis.tests.utils.FailoverAbortedException;
public class JedisSentinelTestUtil {
public static HostAndPort waitForNewPromotedMaster(Jedis sentinelJedis)
public static HostAndPort waitForNewPromotedMaster(final String masterName,
final Jedis sentinelJedis, final Jedis commandJedis)
throws InterruptedException {
final AtomicReference<String> newmaster = new AtomicReference<String>(
@@ -47,6 +48,7 @@ public class JedisSentinelTestUtil {
@Override
public void onPSubscribe(String pattern, int subscribedChannels) {
commandJedis.sentinelFailover(masterName);
}
}, "*");