package org.goldenorb.server;
import static org.junit.Assert.*;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeper;
import org.goldenorb.client.OrbTrackerMemberData;
import org.goldenorb.conf.OrbConfiguration;
import org.goldenorb.jet.OrbTrackerMember;
import org.goldenorb.zookeeper.OrbZKFailure;
import org.goldenorb.zookeeper.ZookeeperUtils;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class TestLeaderGroupMonitor {
private static ZooKeeper zk;
private static String leaderGroupPath;
/**
* Sets up zookeeper and nodes for testing.
*
* @throws Exception
*/
@BeforeClass
public static void setUpBeforeClass() throws Exception {
OrbConfiguration orbConf = new OrbConfiguration(true);
orbConf.setOrbZooKeeperQuorum("localhost:21810");
zk = ZookeeperUtils.connect(orbConf.getOrbZooKeeperQuorum());
ZookeeperUtils.tryToCreateNode(zk, "/GoldenOrb");
ZookeeperUtils.tryToCreateNode(zk, "/GoldenOrb/Test");
ZookeeperUtils.tryToCreateNode(zk, "/GoldenOrb/Test/OrbTrackerLeaderGroup");
leaderGroupPath = "/GoldenOrb/Test/OrbTrackerLeaderGroup";
}
@After
public void cleanUpNodes() throws OrbZKFailure {
ZookeeperUtils.recursiveDelete(zk, leaderGroupPath);
}
/**
* Remove nodes used for testing
*
* @throws Exception
*/
@AfterClass
public static void tearDownAfterClass() throws Exception {
ZookeeperUtils.recursiveDelete(zk, "/GolenOrb");
ZookeeperUtils.deleteNodeIfEmpty(zk, "/GoldenOrb");
}
/**
* Test initializing a monitor on a leader group that already contains members
*
* @throws OrbZKFailure
* @throws InterruptedException
*/
@Test
public void testInitializing() throws OrbZKFailure, InterruptedException {
int num_nodes = 10;
for (int i = 0; i < num_nodes; i++) {
OrbTrackerMember otm = new OrbTrackerMember();
otm.setAvailablePartitions(1);
otm.setHostname("abc");
otm.setInUsePartitions(1);
otm.setLeader(false);
otm.setPartitionCapacity(1);
otm.setPort(1);
otm.setReservedPartitions(1);
ZookeeperUtils.tryToCreateNode(zk, leaderGroupPath + "/member", otm, CreateMode.EPHEMERAL_SEQUENTIAL);
}
CountDownLatch latch = new CountDownLatch(num_nodes);
TServer server = new TServer(latch);
Map<String,OrbTrackerMemberData> map = server.getMemberData();
assertTrue(map.size() == 0);
new LeaderGroupMonitor(leaderGroupPath, server, zk);
latch.await();
map = server.getMemberData();
assertTrue(map.size() == num_nodes);
// ZookeeperUtils.recursiveDelete(zk, leaderGroupPath);
}
/**
* Test adding nodes to alreading initialized watcher
*
* @throws OrbZKFailure
* @throws InterruptedException
*/
@Test
public void testAddingNodes() throws OrbZKFailure, InterruptedException {
int num_nodes = 10;
CountDownLatch latch = new CountDownLatch(num_nodes);
TServer server = new TServer(latch);
Map<String,OrbTrackerMemberData> map = server.getMemberData();
assertTrue(map.size() == 0);
new LeaderGroupMonitor(leaderGroupPath, server, zk);
for (int i = 0; i < num_nodes; i++) {
OrbTrackerMember otm = new OrbTrackerMember();
otm.setAvailablePartitions(1);
otm.setHostname("abc");
otm.setInUsePartitions(1);
otm.setLeader(false);
otm.setPartitionCapacity(1);
otm.setPort(1);
otm.setReservedPartitions(1);
ZookeeperUtils.tryToCreateNode(zk, leaderGroupPath + "/member", otm, CreateMode.EPHEMERAL_SEQUENTIAL);
}
latch.await();
map = server.getMemberData();
assertEquals(num_nodes, map.size());
latch = new CountDownLatch(5); // adding five new nodes
server.setLatcher(latch);
for (int i = 0; i < 5; i++) {
OrbTrackerMember otm = new OrbTrackerMember();
otm.setAvailablePartitions(1);
otm.setHostname("abc");
otm.setInUsePartitions(1);
otm.setLeader(false);
otm.setPartitionCapacity(1);
otm.setPort(1);
otm.setReservedPartitions(1);
ZookeeperUtils.tryToCreateNode(zk, leaderGroupPath + "/member", otm, CreateMode.EPHEMERAL_SEQUENTIAL);
}
latch.await();
map = server.getMemberData();
assertTrue(map.size() == num_nodes + 5);
}
@Test
public void testDeleteAndAdd() throws OrbZKFailure, InterruptedException, KeeperException {
int num_created = 10;
int num_deleted = 7;
CountDownLatch latch = new CountDownLatch(num_created);
TServer server = new TServer(latch);
Map<String,OrbTrackerMemberData> map = server.getMemberData();
assertTrue(map.size() == 0);
new LeaderGroupMonitor(leaderGroupPath, server, zk);
for (int i = 0; i < num_created; i++) {
OrbTrackerMember otm = new OrbTrackerMember();
otm.setAvailablePartitions(1);
otm.setHostname("abc");
otm.setInUsePartitions(1);
otm.setLeader(false);
otm.setPartitionCapacity(1);
otm.setPort(1);
otm.setReservedPartitions(1);
ZookeeperUtils.tryToCreateNode(zk, leaderGroupPath + "/member", otm, CreateMode.EPHEMERAL_SEQUENTIAL);
}
latch.await();
map = server.getMemberData();
assertTrue(map.size() == num_created);
latch = new CountDownLatch(num_deleted);
server.setLatcher(latch);
List<String> children = zk.getChildren(leaderGroupPath, false);
int i = 0;
for (String child : children) {
if (i < num_deleted) {
ZookeeperUtils.deleteNodeIfEmpty(zk, leaderGroupPath + "/" + child);
}
i++;
}
latch.await();
map = server.getMemberData();
assertEquals(num_created - num_deleted, map.size());
}
}