package com.xiaomi.infra.chronos.zookeeper;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.zookeeper.ZKConfig;
import org.apache.zookeeper.KeeperException;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import com.xiaomi.infra.chronos.zookeeper.FailoverServer;
import com.xiaomi.infra.chronos.zookeeper.FailoverWatcher;
import com.xiaomi.infra.chronos.zookeeper.HostPort;
import com.xiaomi.infra.chronos.zookeeper.ZooKeeperUtil;
/**
* Test {@link FailoverServer}
*/
public class TestFailoverServer {
private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(new Configuration());
public class TestableFailoverServer extends FailoverServer {
private final Log LOG = LogFactory.getLog(TestableFailoverServer.class);
private boolean isRunning = false;
public TestableFailoverServer(FailoverWatcher failoverWatcher) {
super(failoverWatcher);
}
public void doAsActiveServer() {
isRunning = true;
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
LOG.info("sever is interruptted to stop");
isRunning = false;
}
isRunning = false;
}
public boolean isRunning() {
return isRunning;
}
}
@BeforeClass
public static void setUpBeforeClass() throws Exception {
TEST_UTIL.startMiniZKCluster(1);
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
TEST_UTIL.shutdownMiniZKCluster();
}
@Before
public void resetZooKeeper() throws IOException, KeeperException {
TestableFailoverServer failoverServer = createFailoverServer(new HostPort("127.0.0.1", 10086));
ZooKeeperUtil.deleteNodeRecursively(failoverServer.getFailoverWatcher(), failoverServer
.getFailoverWatcher().getBaseZnode());
failoverServer.getFailoverWatcher().close();
}
public TestableFailoverServer createFailoverServer(HostPort hostPort) throws IOException {
Properties properties = new Properties();
properties.setProperty(FailoverServer.SERVER_HOST, hostPort.getHost());
properties.setProperty(FailoverServer.SERVER_PORT, String.valueOf(hostPort.getPort()));
properties.setProperty(FailoverServer.BASE_ZNODE, "/test-failover");
properties.setProperty(FailoverServer.ZK_QUORUM,
ZKConfig.getZKQuorumServersString(TEST_UTIL.getConfiguration()));
properties.setProperty(FailoverServer.SESSION_TIMEOUT, String.valueOf(3000));
FailoverWatcher failoverWatcher = new FailoverWatcher(properties);
return new TestableFailoverServer(failoverWatcher);
}
@Test
public void testRun() throws KeeperException, InterruptedException, IOException {
final TestableFailoverServer server1 = createFailoverServer(new HostPort("127.0.0.1", 11111));
Thread thread1 = new Thread() {
@Override
public void run() {
server1.run();
}
};
thread1.start();
final TestableFailoverServer server2 = createFailoverServer(new HostPort("127.0.0.1", 22222));
Thread thread2 = new Thread() {
@Override
public void run() {
server2.run();
}
};
thread2.start();
assertTrue(server1.isRunning());
assertFalse(server2.isRunning());
// stop server1 and server2 can run as active server
thread1.interrupt();
ZooKeeperUtil.deleteNode(server1.getFailoverWatcher(), server1.getFailoverWatcher()
.getMasterZnode());
Thread.sleep(500); // wait for server2 to become active server
assertFalse(server1.isRunning());
assertTrue(server2.isRunning());
thread2.interrupt();
server1.getFailoverWatcher().close();
server2.getFailoverWatcher().close();
}
}