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");
}
}
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");
}
}
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");
}
}
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");
}
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");
}
}
}
Aggregations