use of com.twitter.distributedlog.lock.ZKSessionLock in project distributedlog by twitter.
the class TestZKSessionLock method testLockListenerOnExpired.
/**
* Test session expired after claimed the lock: lock state should be changed to expired and notify
* the lock listener about expiry.
*
* @throws Exception
*/
@Test(timeout = 60000)
public void testLockListenerOnExpired() throws Exception {
String lockPath = "/test-lock-listener-on-expired";
String clientId = "test-lock-listener-on-expired-" + System.currentTimeMillis();
createLockPath(zkc.get(), lockPath);
final CountDownLatch expiredLatch = new CountDownLatch(1);
LockListener listener = new LockListener() {
@Override
public void onExpired() {
expiredLatch.countDown();
}
};
final ZKSessionLock lock = new ZKSessionLock(zkc, lockPath, clientId, lockStateExecutor).setLockListener(listener);
lock.tryLock(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
// verification after lock
assertEquals(State.CLAIMED, lock.getLockState());
List<String> children = getLockWaiters(zkc, lockPath);
assertEquals(1, children.size());
assertEquals(lock.getLockId(), Await.result(asyncParseClientID(zkc.get(), lockPath, children.get(0))));
ZooKeeperClientUtils.expireSession(zkc, zkServers, sessionTimeoutMs);
expiredLatch.await();
assertEquals(State.EXPIRED, lock.getLockState());
children = getLockWaiters(zkc, lockPath);
assertEquals(0, children.size());
try {
lock.tryLock(0, TimeUnit.MILLISECONDS);
fail("Should fail on tryLock since lock state has changed.");
} catch (LockStateChangedException lsce) {
// expected
}
lock.unlock();
}
use of com.twitter.distributedlog.lock.ZKSessionLock in project distributedlog by twitter.
the class TestZKSessionLock method testLockOnNonExistedLock.
/**
* Test lock on non existed lock.
*
* - lock should fail on a non existed lock.
*
* @throws Exception
*/
@Test(timeout = 60000)
public void testLockOnNonExistedLock() throws Exception {
String lockPath = "/test-lock-on-non-existed-lock";
String clientId = "test-lock-on-non-existed-lock";
ZKSessionLock lock = new ZKSessionLock(zkc, lockPath, clientId, lockStateExecutor);
// lock
try {
lock.tryLock(0, TimeUnit.MILLISECONDS);
fail("Should fail on locking a non-existed lock.");
} catch (LockingException le) {
Throwable cause = le.getCause();
assertTrue(cause instanceof KeeperException);
assertEquals(KeeperException.Code.NONODE, ((KeeperException) cause).code());
}
assertEquals(State.CLOSED, lock.getLockState());
// lock should failed on a failure lock
try {
lock.tryLock(0, TimeUnit.MILLISECONDS);
fail("Should fail on locking a failure lock.");
} catch (LockStateChangedException lsce) {
// expected
}
assertEquals(State.CLOSED, lock.getLockState());
}
use of com.twitter.distributedlog.lock.ZKSessionLock in project distributedlog by twitter.
the class TestZKSessionLock method testUnlockTimeout.
/**
* Test unlock timeout.
*
* @throws Exception
*/
@Test(timeout = 60000)
public void testUnlockTimeout() throws Exception {
String name = testNames.getMethodName();
String lockPath = "/" + name;
String clientId = name;
createLockPath(zkc.get(), lockPath);
ZKSessionLock lock = new ZKSessionLock(zkc, lockPath, clientId, lockStateExecutor, 1 * 1000, /* op timeout */
NullStatsLogger.INSTANCE, new DistributedLockContext());
lock.tryLock(0, TimeUnit.MILLISECONDS);
assertEquals(State.CLAIMED, lock.getLockState());
try {
FailpointUtils.setFailpoint(FailpointUtils.FailPointName.FP_LockUnlockCleanup, new DelayFailpointAction(60 * 60 * 1000));
lock.unlock();
assertEquals(State.CLOSING, lock.getLockState());
} finally {
FailpointUtils.removeFailpoint(FailpointUtils.FailPointName.FP_LockUnlockCleanup);
}
}
use of com.twitter.distributedlog.lock.ZKSessionLock in project distributedlog by twitter.
the class TestZKSessionLock method testExecuteLockAction.
@Test(timeout = 60000)
public void testExecuteLockAction() throws Exception {
String lockPath = "/test-execute-lock-action";
String clientId = "test-execute-lock-action-" + System.currentTimeMillis();
ZKSessionLock lock = new ZKSessionLock(zkc, lockPath, clientId, lockStateExecutor);
final AtomicInteger counter = new AtomicInteger(0);
// lock action would be executed in same epoch
final CountDownLatch latch1 = new CountDownLatch(1);
lock.executeLockAction(lock.getEpoch().get(), new LockAction() {
@Override
public void execute() {
counter.incrementAndGet();
latch1.countDown();
}
@Override
public String getActionName() {
return "increment1";
}
});
latch1.await();
assertEquals("counter should be increased in same epoch", 1, counter.get());
// lock action would not be executed in same epoch
final CountDownLatch latch2 = new CountDownLatch(1);
lock.executeLockAction(lock.getEpoch().get() + 1, new LockAction() {
@Override
public void execute() {
counter.incrementAndGet();
}
@Override
public String getActionName() {
return "increment2";
}
});
lock.executeLockAction(lock.getEpoch().get(), new LockAction() {
@Override
public void execute() {
latch2.countDown();
}
@Override
public String getActionName() {
return "countdown";
}
});
latch2.await();
assertEquals("counter should not be increased in different epochs", 1, counter.get());
// lock action would not be executed in same epoch and promise would be satisfied with exception
Promise<BoxedUnit> promise = new Promise<BoxedUnit>();
lock.executeLockAction(lock.getEpoch().get() + 1, new LockAction() {
@Override
public void execute() {
counter.incrementAndGet();
}
@Override
public String getActionName() {
return "increment3";
}
}, promise);
try {
Await.result(promise);
fail("Should satisfy promise with epoch changed exception.");
} catch (EpochChangedException ece) {
// expected
}
assertEquals("counter should not be increased in different epochs", 1, counter.get());
lockStateExecutor.shutdown();
}
use of com.twitter.distributedlog.lock.ZKSessionLock in project distributedlog by twitter.
the class TestZKSessionLock method testTryCloseRaceCondition.
/**
* Test try-create after close race condition.
*
* @throws Exception
*/
@Test(timeout = 60000)
public void testTryCloseRaceCondition() throws Exception {
String name = testNames.getMethodName();
String lockPath = "/" + name;
String clientId = name;
createLockPath(zkc.get(), lockPath);
ZKSessionLock lock = new ZKSessionLock(zkc, lockPath, clientId, lockStateExecutor, 1 * 1000, /* op timeout */
NullStatsLogger.INSTANCE, new DistributedLockContext());
try {
FailpointUtils.setFailpoint(FailpointUtils.FailPointName.FP_LockTryCloseRaceCondition, FailpointUtils.DEFAULT_ACTION);
lock.tryLock(0, TimeUnit.MILLISECONDS);
} catch (LockClosedException ex) {
;
} finally {
FailpointUtils.removeFailpoint(FailpointUtils.FailPointName.FP_LockTryCloseRaceCondition);
}
assertEquals(State.CLOSED, lock.getLockState());
List<String> children = getLockWaiters(zkc, lockPath);
assertEquals(0, children.size());
}
Aggregations