}
@Test
public void testKillSessionThenCloseShouldElectNewLeader() throws Exception
{
final Timing timing = new Timing();
CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), timing.session(), timing.connection(), new RetryOneTime(1));
client.start();
try
{
final Semaphore semaphore = new Semaphore(0);
final CountDownLatch interruptedLatch = new CountDownLatch(1);
final AtomicInteger leaderCount = new AtomicInteger(0);
LeaderSelectorListener listener = new LeaderSelectorListenerAdapter()
{
@Override
public void takeLeadership(CuratorFramework client) throws Exception
{
leaderCount.incrementAndGet();
try
{
semaphore.release();
try
{
Thread.currentThread().join();
}
catch ( InterruptedException e )
{
Thread.currentThread().interrupt();
interruptedLatch.countDown();
}
}
finally
{
leaderCount.decrementAndGet();
}
}
};
LeaderSelector leaderSelector1 = new LeaderSelector(client, PATH_NAME, listener);
LeaderSelector leaderSelector2 = new LeaderSelector(client, PATH_NAME, listener);
boolean leaderSelector1Closed = false;
boolean leaderSelector2Closed = false;
leaderSelector1.start();
leaderSelector2.start();
Assert.assertTrue(timing.acquireSemaphore(semaphore, 1));
KillSession.kill(client.getZookeeperClient().getZooKeeper(), server.getConnectString());
Assert.assertTrue(timing.awaitLatch(interruptedLatch));
timing.sleepABit();
boolean requeued1 = leaderSelector1.requeue();
boolean requeued2 = leaderSelector2.requeue();
Assert.assertTrue(requeued1);
Assert.assertTrue(requeued2);
Assert.assertTrue(timing.acquireSemaphore(semaphore, 1));
Assert.assertEquals(leaderCount.get(), 1);
if ( leaderSelector1.hasLeadership() )
{
leaderSelector1.close();
leaderSelector1Closed = true;
}
else if ( leaderSelector2.hasLeadership() )
{
leaderSelector2.close();
leaderSelector2Closed = true;
}
else
{
fail("No leaderselector has leadership!");
}
// Verify that the other leader took over leadership.
Assert.assertTrue(timing.acquireSemaphore(semaphore, 1));
Assert.assertEquals(leaderCount.get(), 1);
if ( !leaderSelector1Closed )
{
leaderSelector1.close();