package voldemort.server; import java.util.Arrays; import java.util.Collections; import java.util.List; import junit.framework.Assert; import org.junit.Test; import voldemort.ServerTestUtils; import voldemort.VoldemortException; import voldemort.cluster.Cluster; import voldemort.cluster.Node; import com.google.common.collect.Lists; public class HostMatcherTest { private static final int PORT = 6666; // No socket is created, so hard coded public static Cluster getCluster(List<String> hostNames, List<Integer> nodeIds) { List<Node> nodes = Lists.newArrayList(); for(int i = 0; i < hostNames.size(); i++) { int nodeId = (nodeIds == null) ? i : nodeIds.get(i); nodes.add(new Node(nodeId, hostNames.get(i), PORT, PORT + 1, PORT + 2, Arrays.asList(i))); } return new Cluster("HostMatcherTest", nodes); } public static Cluster getCluster(List<String> hostNames) { return getCluster(hostNames, null); } private Cluster singleNodeCluster(int nodeId) { return getCluster(Arrays.asList("localhost"), Arrays.asList(nodeId)); } private void validateNodeId(Cluster cluster, HostMatcher matcher, List<Integer> nodeIdsToValidate, int actualNodeId) { NodeIdUtils.validateNodeId(cluster, matcher, actualNodeId); for(Integer nodeId: nodeIdsToValidate) { if(nodeId == actualNodeId) { // validate one more time NodeIdUtils.validateNodeId(cluster, matcher, actualNodeId); continue; } try { // Increment node Id by 1 and make sure it fails NodeIdUtils.validateNodeId(cluster, matcher, nodeId); Assert.fail("Validation should have failed"); } catch(VoldemortException ex) { // Expected Ignore } } } @Test public void testLocalHost() { for(int nodeId = 0; nodeId < 5; nodeId++) { Cluster localCluster = singleNodeCluster(nodeId); HostMatcher matcher = new HostMatcher(); int actual = NodeIdUtils.findNodeId(localCluster, matcher); Assert.assertEquals("Node Id is different", nodeId, actual); validateNodeId(localCluster, matcher, Arrays.asList(nodeId + 1), nodeId); } } private void validateCluster(Cluster cluster, List<String> hostNames, List<Integer> nodeIds, final int NUM_NODES) { HostMatcher invalidMatcher = new MockHostMatcher("invalidHost"); try { NodeIdUtils.findNodeId(cluster, invalidMatcher); Assert.fail("None of the hosts should have matched"); } catch(VoldemortException ex) { // Ignore } for(int i = 0; i < NUM_NODES; i++) { String hostName = hostNames.get(i); int expectedNodeId = nodeIds.get(i); HostMatcher matcher = new MockHostMatcher(hostName); int actulaNodeId = NodeIdUtils.findNodeId(cluster, matcher); Assert.assertEquals("Node Id is different", expectedNodeId, actulaNodeId); validateNodeId(cluster, matcher, nodeIds, actulaNodeId); } } @Test public void testHostMatch() { final int NUM_NODES = 60; List<String> hostNames = Lists.newArrayList(); List<Integer> nodeIds = Lists.newArrayList(); for(int i = 0; i < NUM_NODES; i++) { hostNames.add("host" + i); nodeIds.add(i); } Collections.shuffle(hostNames); Collections.shuffle(nodeIds); Cluster cluster = getCluster(hostNames, nodeIds); validateCluster(cluster, hostNames, nodeIds, NUM_NODES); } private void validateMatchFails(Cluster cluster, HostMatcher matcher) { try { NodeIdUtils.findNodeId(cluster, matcher); Assert.fail("multiple match should have failed"); } catch(VoldemortException ex) { // Ignore. } for(int nodeId: cluster.getNodeIds()) { try { NodeIdUtils.validateNodeId(cluster, matcher, nodeId); Assert.fail("multiple match should have failed"); } catch(VoldemortException ex) { // Ignore. } } } @Test public void testMultipleMatchFails() { final String SOMEHOST = "samehost"; Cluster cluster = getCluster(Arrays.asList(SOMEHOST, SOMEHOST)); HostMatcher matcher = new MockHostMatcher(SOMEHOST); validateMatchFails(cluster, matcher); } @Test public void testConflictingMatchFails() { final String SOMEHOST = "somehost"; Cluster cluster = getCluster(Arrays.asList(SOMEHOST.toLowerCase(), SOMEHOST.toUpperCase())); HostMatcher matcher = new MockHostMatcher(SOMEHOST); validateMatchFails(cluster, matcher); } @Test public void testMultipleLocalHostFails() { Cluster cluster = ServerTestUtils.getLocalCluster(2); HostMatcher matcher = new HostMatcher(); validateMatchFails(cluster, matcher); } }