Search in sources :

Example 6 with LoggerTestTool

use of org.apache.zookeeper.test.LoggerTestTool in project zookeeper by apache.

the class QuorumPeerMainTest method testBadPeerAddressInQuorum.

/**
 * Verify handling of bad quorum address
 */
@Test
public void testBadPeerAddressInQuorum() throws Exception {
    ClientBase.setupTestEnv();
    try (LoggerTestTool loggerTestTool = new LoggerTestTool("org.apache.zookeeper.server.quorum")) {
        ByteArrayOutputStream os = loggerTestTool.getOutputStream();
        final int CLIENT_PORT_QP1 = PortAssignment.unique();
        final int CLIENT_PORT_QP2 = PortAssignment.unique();
        String quorumCfgSection = "server.1=127.0.0.1:" + PortAssignment.unique() + ":" + PortAssignment.unique() + ";" + CLIENT_PORT_QP1 + "\nserver.2=fee.fii.foo.fum:" + PortAssignment.unique() + ":" + PortAssignment.unique() + ";" + CLIENT_PORT_QP2;
        MainThread q1 = new MainThread(1, CLIENT_PORT_QP1, quorumCfgSection);
        q1.start();
        boolean isup = ClientBase.waitForServerUp("127.0.0.1:" + CLIENT_PORT_QP1, 30000);
        assertFalse(isup, "Server never came up");
        q1.shutdown();
        assertTrue(ClientBase.waitForServerDown("127.0.0.1:" + CLIENT_PORT_QP1, ClientBase.CONNECTION_TIMEOUT), "waiting for server 1 down");
        LineNumberReader r = new LineNumberReader(new StringReader(os.toString()));
        String line;
        boolean found = false;
        Pattern p = Pattern.compile(".*Cannot open channel to .* at election address .*");
        while ((line = r.readLine()) != null) {
            found = p.matcher(line).matches();
            if (found) {
                break;
            }
        }
        assertTrue(found, "complains about host");
    }
}
Also used : Pattern(java.util.regex.Pattern) LoggerTestTool(org.apache.zookeeper.test.LoggerTestTool) StringReader(java.io.StringReader) ByteArrayOutputStream(java.io.ByteArrayOutputStream) LineNumberReader(java.io.LineNumberReader) Test(org.junit.jupiter.api.Test)

Example 7 with LoggerTestTool

use of org.apache.zookeeper.test.LoggerTestTool in project zookeeper by apache.

the class QuorumPeerMainTest method testQuorumDefaults.

/**
 * Verify handling of quorum defaults
 * * default electionAlg is fast leader election
 */
@Test
public void testQuorumDefaults() throws Exception {
    ClientBase.setupTestEnv();
    try (LoggerTestTool loggerTestTool = new LoggerTestTool("org.apache.zookeeper")) {
        ByteArrayOutputStream os = loggerTestTool.getOutputStream();
        final int CLIENT_PORT_QP1 = PortAssignment.unique();
        final int CLIENT_PORT_QP2 = PortAssignment.unique();
        String quorumCfgSection = "server.1=127.0.0.1:" + PortAssignment.unique() + ":" + PortAssignment.unique() + ";" + CLIENT_PORT_QP1 + "\nserver.2=127.0.0.1:" + PortAssignment.unique() + ":" + PortAssignment.unique() + ";" + CLIENT_PORT_QP2;
        MainThread q1 = new MainThread(1, CLIENT_PORT_QP1, quorumCfgSection);
        MainThread q2 = new MainThread(2, CLIENT_PORT_QP2, quorumCfgSection);
        q1.start();
        q2.start();
        assertTrue(ClientBase.waitForServerUp("127.0.0.1:" + CLIENT_PORT_QP1, CONNECTION_TIMEOUT), "waiting for server 1 being up");
        assertTrue(ClientBase.waitForServerUp("127.0.0.1:" + CLIENT_PORT_QP2, CONNECTION_TIMEOUT), "waiting for server 2 being up");
        q1.shutdown();
        q2.shutdown();
        assertTrue(ClientBase.waitForServerDown("127.0.0.1:" + CLIENT_PORT_QP1, ClientBase.CONNECTION_TIMEOUT), "waiting for server 1 down");
        assertTrue(ClientBase.waitForServerDown("127.0.0.1:" + CLIENT_PORT_QP2, ClientBase.CONNECTION_TIMEOUT), "waiting for server 2 down");
        os.close();
        LineNumberReader r = new LineNumberReader(new StringReader(os.toString()));
        String line;
        boolean found = false;
        Pattern p = Pattern.compile(".*FastLeaderElection.*");
        while ((line = r.readLine()) != null) {
            found = p.matcher(line).matches();
            if (found) {
                break;
            }
        }
        assertTrue(found, "fastleaderelection used");
    }
}
Also used : Pattern(java.util.regex.Pattern) LoggerTestTool(org.apache.zookeeper.test.LoggerTestTool) StringReader(java.io.StringReader) ByteArrayOutputStream(java.io.ByteArrayOutputStream) LineNumberReader(java.io.LineNumberReader) Test(org.junit.jupiter.api.Test)

Example 8 with LoggerTestTool

use of org.apache.zookeeper.test.LoggerTestTool in project zookeeper by apache.

the class QuorumPeerMainTest method testInconsistentPeerType.

/**
 * Verify handling of inconsistent peer type
 */
@Test
public void testInconsistentPeerType() throws Exception {
    ClientBase.setupTestEnv();
    // servers list, but there's no "peerType=observer" token in config
    try (LoggerTestTool loggerTestTool = new LoggerTestTool("org.apache.zookeeper.server.quorum")) {
        ByteArrayOutputStream os = loggerTestTool.getOutputStream();
        final int CLIENT_PORT_QP1 = PortAssignment.unique();
        final int CLIENT_PORT_QP2 = PortAssignment.unique();
        final int CLIENT_PORT_QP3 = PortAssignment.unique();
        String quorumCfgSection = "server.1=127.0.0.1:" + PortAssignment.unique() + ":" + PortAssignment.unique() + ";" + CLIENT_PORT_QP1 + "\nserver.2=127.0.0.1:" + PortAssignment.unique() + ":" + PortAssignment.unique() + ";" + CLIENT_PORT_QP2 + "\nserver.3=127.0.0.1:" + PortAssignment.unique() + ":" + PortAssignment.unique() + ":observer" + ";" + CLIENT_PORT_QP3;
        MainThread q1 = new MainThread(1, CLIENT_PORT_QP1, quorumCfgSection);
        MainThread q2 = new MainThread(2, CLIENT_PORT_QP2, quorumCfgSection);
        MainThread q3 = new MainThread(3, CLIENT_PORT_QP3, quorumCfgSection);
        q1.start();
        q2.start();
        q3.start();
        assertTrue(ClientBase.waitForServerUp("127.0.0.1:" + CLIENT_PORT_QP1, CONNECTION_TIMEOUT), "waiting for server 1 being up");
        assertTrue(ClientBase.waitForServerUp("127.0.0.1:" + CLIENT_PORT_QP2, CONNECTION_TIMEOUT), "waiting for server 2 being up");
        assertTrue(ClientBase.waitForServerUp("127.0.0.1:" + CLIENT_PORT_QP3, CONNECTION_TIMEOUT), "waiting for server 3 being up");
        q1.shutdown();
        q2.shutdown();
        q3.shutdown();
        assertTrue(ClientBase.waitForServerDown("127.0.0.1:" + CLIENT_PORT_QP1, ClientBase.CONNECTION_TIMEOUT), "waiting for server 1 down");
        assertTrue(ClientBase.waitForServerDown("127.0.0.1:" + CLIENT_PORT_QP2, ClientBase.CONNECTION_TIMEOUT), "waiting for server 2 down");
        assertTrue(ClientBase.waitForServerDown("127.0.0.1:" + CLIENT_PORT_QP3, ClientBase.CONNECTION_TIMEOUT), "waiting for server 3 down");
        LineNumberReader r = new LineNumberReader(new StringReader(os.toString()));
        String line;
        boolean warningPresent = false;
        boolean defaultedToObserver = false;
        Pattern pWarn = Pattern.compile(".*Peer type from servers list.* doesn't match peerType.*");
        Pattern pObserve = Pattern.compile(".*OBSERVING.*");
        while ((line = r.readLine()) != null) {
            if (pWarn.matcher(line).matches()) {
                warningPresent = true;
            }
            if (pObserve.matcher(line).matches()) {
                defaultedToObserver = true;
            }
            if (warningPresent && defaultedToObserver) {
                break;
            }
        }
        assertTrue(warningPresent && defaultedToObserver, "Should warn about inconsistent peer type");
    }
}
Also used : Pattern(java.util.regex.Pattern) LoggerTestTool(org.apache.zookeeper.test.LoggerTestTool) StringReader(java.io.StringReader) ByteArrayOutputStream(java.io.ByteArrayOutputStream) LineNumberReader(java.io.LineNumberReader) Test(org.junit.jupiter.api.Test)

Example 9 with LoggerTestTool

use of org.apache.zookeeper.test.LoggerTestTool in project zookeeper by apache.

the class QuorumPeerMainTest method testElectionFraud.

/**
 * This test validates that if a quorum member determines that it is leader without the support of the rest of the
 * quorum (the other members do not believe it to be the leader) it will stop attempting to lead and become a follower.
 *
 * @throws IOException
 * @throws InterruptedException
 */
@Test
public void testElectionFraud() throws Exception {
    numServers = 3;
    // used for assertions later
    boolean foundLeading = false;
    boolean foundLooking = false;
    boolean foundFollowing = false;
    try (LoggerTestTool loggerTestTool = new LoggerTestTool(QuorumPeer.class)) {
        ByteArrayOutputStream os = loggerTestTool.getOutputStream();
        // spin up a quorum, we use a small ticktime to make the test run faster
        servers = LaunchServers(numServers, 500);
        // find the leader
        int trueLeader = servers.findLeader();
        assertTrue(trueLeader >= 0, "There should be a leader");
        // find a follower
        int falseLeader = (trueLeader + 1) % numServers;
        assertTrue(servers.mt[falseLeader].main.quorumPeer.follower != null, "All servers should join the quorum");
        // to keep the quorum peer running and force it to go into the looking state, we kill leader election
        servers.mt[falseLeader].main.quorumPeer.electionAlg.shutdown();
        servers.mt[falseLeader].main.quorumPeer.follower.getSocket().close();
        // wait for the falseLeader to disconnect
        waitForOne(servers.zk[falseLeader], States.CONNECTING);
        // convince falseLeader that it is the leader
        servers.mt[falseLeader].main.quorumPeer.setPeerState(QuorumPeer.ServerState.LEADING);
        // provide time for the falseleader to realize no followers have connected
        // (this is twice the timeout used in Leader#getEpochToPropose)
        Thread.sleep(2 * servers.mt[falseLeader].main.quorumPeer.initLimit * servers.mt[falseLeader].main.quorumPeer.tickTime);
        // Restart leader election
        servers.mt[falseLeader].main.quorumPeer.startLeaderElection();
        // The previous client connection to falseLeader likely closed, create a new one
        servers.zk[falseLeader] = new ZooKeeper("127.0.0.1:" + servers.mt[falseLeader].getClientPort(), ClientBase.CONNECTION_TIMEOUT, this);
        // Wait for falseLeader to rejoin the quorum
        waitForOne(servers.zk[falseLeader], States.CONNECTED);
        // and ensure trueLeader is still the leader
        assertTrue(servers.mt[trueLeader].main.quorumPeer.leader != null);
        // Look through the logs for output that indicates the falseLeader is LEADING, then LOOKING, then FOLLOWING
        LineNumberReader r = new LineNumberReader(new StringReader(os.toString()));
        Pattern leading = Pattern.compile(".*myid=" + falseLeader + ".*LEADING.*");
        Pattern looking = Pattern.compile(".*myid=" + falseLeader + ".*LOOKING.*");
        Pattern following = Pattern.compile(".*myid=" + falseLeader + ".*FOLLOWING.*");
        String line;
        while ((line = r.readLine()) != null) {
            if (!foundLeading) {
                foundLeading = leading.matcher(line).matches();
            } else if (!foundLooking) {
                foundLooking = looking.matcher(line).matches();
            } else if (following.matcher(line).matches()) {
                foundFollowing = true;
                break;
            }
        }
    }
    assertTrue(foundLeading, "falseLeader never attempts to become leader");
    assertTrue(foundLooking, "falseLeader never gives up on leadership");
    assertTrue(foundFollowing, "falseLeader never rejoins the quorum");
}
Also used : Pattern(java.util.regex.Pattern) LoggerTestTool(org.apache.zookeeper.test.LoggerTestTool) ZooKeeper(org.apache.zookeeper.ZooKeeper) StringReader(java.io.StringReader) ByteArrayOutputStream(java.io.ByteArrayOutputStream) LineNumberReader(java.io.LineNumberReader) Test(org.junit.jupiter.api.Test)

Example 10 with LoggerTestTool

use of org.apache.zookeeper.test.LoggerTestTool in project zookeeper by apache.

the class QuorumPeerMainTest method testLeaderOutOfView.

/**
 * Verify that a node without the leader in its view will not attempt to connect to the leader.
 */
@Test
public void testLeaderOutOfView() throws Exception {
    ClientBase.setupTestEnv();
    int numServers = 3;
    // used for assertions later
    boolean foundLeading = false;
    boolean foundFollowing = false;
    try (LoggerTestTool loggerTestTool = new LoggerTestTool(QuorumPeerMainTest.class)) {
        ByteArrayOutputStream os = loggerTestTool.getOutputStream();
        Servers svrs = new Servers();
        svrs.clientPorts = new int[numServers];
        for (int i = 0; i < numServers; i++) {
            svrs.clientPorts[i] = PortAssignment.unique();
        }
        String quorumCfgIncomplete = getUniquePortCfgForId(1) + "\n" + getUniquePortCfgForId(2);
        String quorumCfgComplete = quorumCfgIncomplete + "\n" + getUniquePortCfgForId(3);
        svrs.mt = new MainThread[3];
        // Node 1 is started without the leader (3) in its config view
        svrs.mt[0] = new MainThread(1, svrs.clientPorts[0], quorumCfgIncomplete);
        for (int i = 1; i < numServers; i++) {
            svrs.mt[i] = new MainThread(i + 1, svrs.clientPorts[i], quorumCfgComplete);
        }
        // Node 1 must be started first, before quorum is formed, to trigger the attempted invalid connection to 3
        svrs.mt[0].start();
        QuorumPeer quorumPeer1 = waitForQuorumPeer(svrs.mt[0], CONNECTION_TIMEOUT);
        assertTrue(quorumPeer1.getPeerState() == QuorumPeer.ServerState.LOOKING);
        // Node 3 started second to avoid 1 and 2 forming a quorum before 3 starts up
        int highestServerIndex = numServers - 1;
        svrs.mt[highestServerIndex].start();
        QuorumPeer quorumPeer3 = waitForQuorumPeer(svrs.mt[highestServerIndex], CONNECTION_TIMEOUT);
        assertTrue(quorumPeer3.getPeerState() == QuorumPeer.ServerState.LOOKING);
        // Node 2 started last, kicks off leader election
        for (int i = 1; i < highestServerIndex; i++) {
            svrs.mt[i].start();
        }
        // Nodes 2 and 3 now form quorum and fully start. 1 attempts to vote for 3, fails, returns to LOOKING state
        for (int i = 1; i < numServers; i++) {
            assertTrue(ClientBase.waitForServerUp("127.0.0.1:" + svrs.clientPorts[i], CONNECTION_TIMEOUT), "waiting for server to start");
        }
        // Expecting that only 3 node will be leader is wrong, even 2 node can be leader, when cluster is formed with 1 node
        boolean firstAndSecondNodeFormedCluster = false;
        if (QuorumPeer.ServerState.LEADING == svrs.mt[1].getQuorumPeer().getPeerState()) {
            assertEquals(QuorumPeer.ServerState.FOLLOWING, svrs.mt[0].getQuorumPeer().getPeerState());
            assertEquals(QuorumPeer.ServerState.FOLLOWING, svrs.mt[highestServerIndex].getQuorumPeer().getPeerState());
            firstAndSecondNodeFormedCluster = true;
        } else {
            // Verify leader out of view scenario
            assertEquals(QuorumPeer.ServerState.LOOKING, svrs.mt[0].getQuorumPeer().getPeerState());
            assertEquals(QuorumPeer.ServerState.LEADING, svrs.mt[highestServerIndex].getQuorumPeer().getPeerState());
        }
        for (int i = 1; i < highestServerIndex; i++) {
            assertTrue(svrs.mt[i].getQuorumPeer().getPeerState() == QuorumPeer.ServerState.FOLLOWING || svrs.mt[i].getQuorumPeer().getPeerState() == QuorumPeer.ServerState.LEADING);
        }
        // Look through the logs for output that indicates Node 1 is LEADING or FOLLOWING
        LineNumberReader r = new LineNumberReader(new StringReader(os.toString()));
        Pattern leading = Pattern.compile(".*myid=1.*QuorumPeer.*LEADING.*");
        Pattern following = Pattern.compile(".*myid=1.*QuorumPeer.*FOLLOWING.*");
        String line;
        while ((line = r.readLine()) != null && !foundLeading && !foundFollowing) {
            foundLeading = leading.matcher(line).matches();
            foundFollowing = following.matcher(line).matches();
        }
        if (firstAndSecondNodeFormedCluster) {
            assertTrue(foundFollowing, "Corrupt peer should join quorum with servers having same server configuration");
        } else {
            assertFalse(foundLeading, "Corrupt peer should never become leader");
            assertFalse(foundFollowing, "Corrupt peer should not attempt connection to out of view leader");
        }
    }
}
Also used : Pattern(java.util.regex.Pattern) LoggerTestTool(org.apache.zookeeper.test.LoggerTestTool) StringReader(java.io.StringReader) ByteArrayOutputStream(java.io.ByteArrayOutputStream) LineNumberReader(java.io.LineNumberReader) Test(org.junit.jupiter.api.Test)

Aggregations

LoggerTestTool (org.apache.zookeeper.test.LoggerTestTool)11 ByteArrayOutputStream (java.io.ByteArrayOutputStream)9 LineNumberReader (java.io.LineNumberReader)9 StringReader (java.io.StringReader)9 Pattern (java.util.regex.Pattern)9 Test (org.junit.jupiter.api.Test)9 BaseTestMetricsProvider (org.apache.zookeeper.metrics.BaseTestMetricsProvider)3 BeforeAll (org.junit.jupiter.api.BeforeAll)2 ZooKeeper (org.apache.zookeeper.ZooKeeper)1