use of org.apache.zookeeper.test.ClientBase.CountdownWatcher in project zookeeper by apache.
the class FollowerResyncConcurrencyTest method testResyncByDiffAfterFollowerCrashes.
/**
* This test:
* Starts up 3 ZKs. The non-leader ZKs are writing to cluster
* Shut down one of the non-leader ZKs.
* Restart after sessions have expired but less than 500 txns have taken place (get a diff)
* Shut down immediately after restarting, start running separate thread with other transactions
* Restart to a diff while transactions are running in leader
*
* Before fixes for ZOOKEEPER-962, restarting off of diff could get an inconsistent view of data missing transactions that
* completed during diff syncing. Follower would also be considered "restarted" before all forwarded transactions
* were completely processed, so restarting would cause a snap file with a too-high zxid to be written, and transactions
* would be missed
*
* This test should pretty reliably catch the failure of restarting the server before all diff messages have been processed,
* however, due to the transient nature of the system it may not catch failures due to concurrent processing of transactions
* during the leader's diff forwarding.
*
* @throws IOException
* @throws InterruptedException
* @throws KeeperException
* @throws Throwable
*/
@Test
public void testResyncByDiffAfterFollowerCrashes() throws IOException, InterruptedException, KeeperException, Throwable {
final Semaphore sem = new Semaphore(0);
QuorumUtil qu = new QuorumUtil(1);
qu.startAll();
CountdownWatcher watcher1 = new CountdownWatcher();
CountdownWatcher watcher2 = new CountdownWatcher();
CountdownWatcher watcher3 = new CountdownWatcher();
int index = 1;
while (qu.getPeer(index).peer.leader == null) {
index++;
}
Leader leader = qu.getPeer(index).peer.leader;
assertNotNull(leader);
/* Reusing the index variable to select a follower to connect to */
index = (index == 1) ? 2 : 1;
LOG.info("Connecting to follower: {}", index);
final ZooKeeper zk1 = createClient(qu.getPeer(index).peer.getClientPort(), watcher1);
LOG.info("zk1 has session id 0x{}", Long.toHexString(zk1.getSessionId()));
final ZooKeeper zk2 = createClient(qu.getPeer(index).peer.getClientPort(), watcher2);
LOG.info("zk2 has session id 0x{}", Long.toHexString(zk2.getSessionId()));
final ZooKeeper zk3 = createClient(qu.getPeer(3).peer.getClientPort(), watcher3);
LOG.info("zk3 has session id 0x{}", Long.toHexString(zk3.getSessionId()));
zk1.create("/first", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zk2.create("/mybar", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
final AtomicBoolean runNow = new AtomicBoolean(false);
Thread mytestfooThread = new Thread(new Runnable() {
@Override
public void run() {
int inSyncCounter = 0;
while (inSyncCounter < 400) {
if (runNow.get()) {
zk3.create("/mytestfoo", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL, (rc, path, ctx, name) -> {
pending.decrementAndGet();
counter.incrementAndGet();
if (rc != 0) {
errors.incrementAndGet();
}
if (counter.get() > 7300) {
sem.release();
}
}, null);
pending.incrementAndGet();
try {
Thread.sleep(10);
} catch (Exception e) {
}
inSyncCounter++;
} else {
Thread.yield();
}
}
}
});
mytestfooThread.start();
for (int i = 0; i < 5000; i++) {
zk2.create("/mybar", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL, (rc, path, ctx, name) -> {
pending.decrementAndGet();
counter.incrementAndGet();
if (rc != 0) {
errors.incrementAndGet();
}
if (counter.get() > 7300) {
sem.release();
}
}, null);
pending.incrementAndGet();
if (i == 1000) {
qu.shutdown(index);
Thread.sleep(1100);
LOG.info("Shutting down s1");
}
if (i == 1100 || i == 1150 || i == 1200) {
Thread.sleep(1000);
}
if (i == 1200) {
qu.startThenShutdown(index);
runNow.set(true);
qu.restart(index);
LOG.info("Setting up server: {}", index);
}
if (i >= 1000 && i % 2 == 0) {
zk3.create("/newbaz", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL, (rc, path, ctx, name) -> {
pending.decrementAndGet();
counter.incrementAndGet();
if (rc != 0) {
errors.incrementAndGet();
}
if (counter.get() > 7300) {
sem.release();
}
}, null);
pending.incrementAndGet();
}
if (i == 1050 || i == 1100 || i == 1150) {
Thread.sleep(1000);
}
}
// Wait until all updates return
if (!sem.tryAcquire(ClientBase.CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS)) {
LOG.warn("Did not aquire semaphore fast enough");
}
mytestfooThread.join(ClientBase.CONNECTION_TIMEOUT);
if (mytestfooThread.isAlive()) {
LOG.error("mytestfooThread is still alive");
}
assertTrue(waitForPendingRequests(60));
assertTrue(waitForSync(qu, index, 10));
// Verify that server is following and has the same epoch as the leader
verifyState(qu, index, leader);
zk1.close();
zk2.close();
zk3.close();
qu.shutdownAll();
}
use of org.apache.zookeeper.test.ClientBase.CountdownWatcher in project zookeeper by apache.
the class LocalSessionsOnlyTest method testLocalSessions.
private void testLocalSessions(boolean testLeader) throws Exception {
String nodePrefix = "/testLocalSessions-" + (testLeader ? "leaderTest-" : "followerTest-");
int leaderIdx = qb.getLeaderIndex();
assertFalse(leaderIdx == -1, "No leader in quorum?");
int followerIdx = (leaderIdx + 1) % 5;
int testPeerIdx = testLeader ? leaderIdx : followerIdx;
String[] hostPorts = qb.hostPort.split(",");
CountdownWatcher watcher = new CountdownWatcher();
ZooKeeper zk = qb.createClient(watcher, hostPorts[testPeerIdx], CONNECTION_TIMEOUT);
watcher.waitForConnected(CONNECTION_TIMEOUT);
long localSessionId = zk.getSessionId();
// Try creating some data.
for (int i = 0; i < 5; i++) {
zk.create(nodePrefix + i, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
// cannot create ephemeral nodes on a local session.
try {
zk.create(nodePrefix + "ephemeral", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
fail("Ephemeral node creation should fail.");
} catch (KeeperException.EphemeralOnLocalSessionException e) {
}
// Close the session.
zk.close();
// Validate data on both follower and leader
Map<String, Integer> peers = new HashMap<String, Integer>();
peers.put("leader", leaderIdx);
peers.put("follower", followerIdx);
for (Entry<String, Integer> entry : peers.entrySet()) {
watcher.reset();
// Try reconnecting with a new session.
// The data should be persisted, even though the session was not.
zk = qb.createClient(watcher, hostPorts[entry.getValue()], CONNECTION_TIMEOUT);
watcher.waitForConnected(CONNECTION_TIMEOUT);
long newSessionId = zk.getSessionId();
assertFalse(newSessionId == localSessionId);
for (int i = 0; i < 5; i++) {
assertNotNull(zk.exists(nodePrefix + i, null), "Data not exists in " + entry.getKey());
}
// We may get the correct exception but the txn may go through
assertNull(zk.exists(nodePrefix + "ephemeral", null), "Data exists in " + entry.getKey());
zk.close();
}
qb.shutdownServers();
}
use of org.apache.zookeeper.test.ClientBase.CountdownWatcher in project zookeeper by apache.
the class LocalSessionRequestTest method testOpenCloseSession.
/**
* Test that a CloseSession request generated by both the server (client
* disconnect) or by the client (client explicitly issue close()) doesn't
* get committed by the ensemble
*/
public void testOpenCloseSession(boolean onLeader) throws Exception {
int leaderIdx = qb.getLeaderIndex();
assertFalse(leaderIdx == -1, "No leader in quorum?");
int followerIdx = (leaderIdx + 1) % 5;
int testPeerIdx = onLeader ? leaderIdx : followerIdx;
int verifyPeerIdx = onLeader ? followerIdx : leaderIdx;
String[] hostPorts = qb.hostPort.split(",");
CountdownWatcher watcher = new CountdownWatcher();
DisconnectableZooKeeper client = new DisconnectableZooKeeper(hostPorts[testPeerIdx], CONNECTION_TIMEOUT, watcher);
watcher.waitForConnected(CONNECTION_TIMEOUT);
long localSessionId1 = client.getSessionId();
// Cut the connection, so the server will create closeSession as part
// of expiring the session.
client.dontReconnect();
client.disconnect();
watcher.reset();
// We don't validate right away, will do another session create first
ZooKeeper zk = qb.createClient(watcher, hostPorts[testPeerIdx], CONNECTION_TIMEOUT);
watcher.waitForConnected(CONNECTION_TIMEOUT);
long localSessionId2 = zk.getSessionId();
// Send closeSession request.
zk.close();
watcher.reset();
// This should be enough time for the first session to expire and for
// the closeSession request to propagate to other machines (if there is a bug)
// Since it is time sensitive, we have false negative when test
// machine is under load
Thread.sleep(CONNECTION_TIMEOUT * 2);
// Validate that we don't see any txn from the first session
validateRequestLog(localSessionId1, verifyPeerIdx);
// Validate that we don't see any txn from the second session
validateRequestLog(localSessionId2, verifyPeerIdx);
qb.shutdownServers();
}
use of org.apache.zookeeper.test.ClientBase.CountdownWatcher in project zookeeper by apache.
the class Slf4JAuditLoggerTest method testEphemralZNodeAuditLogs.
@Test
public void testEphemralZNodeAuditLogs() throws Exception {
String ephemralPath = "/ephemral";
CountdownWatcher watcher2 = new CountdownWatcher();
ZooKeeper zk2 = new ZooKeeper("127.0.0.1:" + mt[0].getQuorumPeer().getClientPort(), ClientBase.CONNECTION_TIMEOUT, watcher2);
watcher2.waitForConnected(ClientBase.CONNECTION_TIMEOUT);
zk2.create(ephemralPath, "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
String session2 = "0x" + Long.toHexString(zk2.getSessionId());
verifyLog(getAuditLog(AuditConstants.OP_CREATE, ephemralPath, Result.SUCCESS, null, CreateMode.EPHEMERAL.toString().toLowerCase(), session2), readAuditLog(os));
zk2.close();
waitForDeletion(zk, ephemralPath);
// verify that ephemeral node deletion on session close are captured
// in audit log
// Because these operations are done by ZooKeeper server itself,
// there are no IP user is zkServer user, not any client user
verifyLogs(getAuditLog(AuditConstants.OP_DEL_EZNODE_EXP, ephemralPath, Result.SUCCESS, null, null, session2, ZKAuditProvider.getZKUser(), null), readAuditLog(os, SERVER_COUNT));
}
use of org.apache.zookeeper.test.ClientBase.CountdownWatcher in project zookeeper by apache.
the class QuorumDigestAuthTest method testSaslNotRequiredWithInvalidCredentials.
/**
* Test to verify that server is able to start with invalid credentials if
* the configuration is set to quorum.auth.serverRequireSasl=false.
* Quorum will talk each other even if the authentication is not succeeded
*/
@Test
@Timeout(value = 30)
public void testSaslNotRequiredWithInvalidCredentials() throws Exception {
Map<String, String> authConfigs = new HashMap<String, String>();
authConfigs.put(QuorumAuth.QUORUM_LEARNER_SASL_LOGIN_CONTEXT, "QuorumLearnerInvalid");
authConfigs.put(QuorumAuth.QUORUM_SASL_AUTH_ENABLED, "false");
authConfigs.put(QuorumAuth.QUORUM_SERVER_SASL_AUTH_REQUIRED, "false");
String connectStr = startQuorum(3, authConfigs, 3);
CountdownWatcher watcher = new CountdownWatcher();
ZooKeeper zk = new ZooKeeper(connectStr, ClientBase.CONNECTION_TIMEOUT, watcher);
watcher.waitForConnected(ClientBase.CONNECTION_TIMEOUT);
for (int i = 0; i < 10; i++) {
zk.create("/" + i, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
zk.close();
}
Aggregations