package org.jboss.as.controller;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
/**
* Unit tests of {@link ModelControllerLock}.
*
* @author Ken Wills <kwills@redhat.com> (c) 2016 Red Hat
*/
public class ModelControllerLockTestCase {
private static final int OP1 = 11111;
private static final int OP2 = 22222;
private static final int OP3 = 33333;
private static final long DEFAULT_TIMEOUT = 1;
private static final TimeUnit DEFAULT_TIMEUNIT = TimeUnit.MILLISECONDS;
@Test
public void testAcquireBasic() throws InterruptedException {
ModelControllerLock lock = new ModelControllerLock();
lock.lock(OP1);
assertTrue(lock.lockInterruptibly(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertTrue(lock.lock(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
}
@Test
public void testReacquireBasic() throws InterruptedException {
ModelControllerLock lock = new ModelControllerLock();
lock.lock(OP1);
assertFalse(lock.lockInterruptibly(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertTrue(lock.lockInterruptibly(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertTrue(lock.lock(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
lock.unlock(OP1);
assertFalse(lock.lockInterruptibly(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
lock.unlock(OP1);
assertFalse(lock.lockInterruptibly(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
lock.unlock(OP1);
lock.lock(OP2);
assertFalse(lock.lockInterruptibly(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertFalse(lock.lock(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertTrue(lock.lockInterruptibly(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
lock.unlock(OP2);
assertFalse(lock.lockInterruptibly(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
lock.unlock(OP2);
assertTrue(lock.lockInterruptibly(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
}
@Test(expected = IllegalMonitorStateException.class)
public void testUnlockNotLockedExclusive() throws IllegalStateException {
ModelControllerLock lock = new ModelControllerLock();
lock.unlock(OP1);
}
@Test(expected = IllegalMonitorStateException.class)
public void testTooManyExclusiveUnlocks() throws IllegalStateException {
ModelControllerLock lock = new ModelControllerLock();
for (int i = 0; i < 5; i++) {
lock.lock(OP1);
}
for (int i = 0; i < 6; i++) {
lock.unlock(OP1);
}
}
@Test(expected = IllegalMonitorStateException.class)
public void testUnlockNotLockedShared() throws IllegalStateException {
ModelControllerLock lock = new ModelControllerLock();
lock.unlockShared(OP1);
}
@Test(expected = IllegalMonitorStateException.class)
public void testTooManyUnlocksShared() throws IllegalStateException {
ModelControllerLock lock = new ModelControllerLock();
for (int i = 0; i < 5; i++) {
lock.lockShared(OP1);
}
for (int i = 0; i < 6; i++) {
lock.unlockShared(OP1);
}
}
@Test
public void testAcquire() throws InterruptedException {
ModelControllerLock lock = new ModelControllerLock();
lock.lock(OP1);
assertFalse(lock.lockInterruptibly(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertFalse(lock.lock(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
lock.unlock(OP1);
lock.lock(OP2);
assertFalse(lock.lockInterruptibly(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertFalse(lock.lock(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
}
@Test
public void testExclusiveBlocksShared() throws InterruptedException {
ModelControllerLock lock = new ModelControllerLock();
lock.lock(OP1);
assertFalse(lock.lockSharedInterruptibly(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertFalse(lock.lockSharedInterruptibly(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
lock.unlock(OP1);
lock.lockShared(OP2);
assertTrue(lock.lockSharedInterruptibly(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertFalse(lock.lockInterruptibly(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertTrue(lock.lockSharedInterruptibly(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertFalse(lock.lockInterruptibly(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
}
@Test
public void testAcquireSharedBasic() throws InterruptedException {
ModelControllerLock lock = new ModelControllerLock();
lock.lockShared(OP1);
assertTrue(lock.lockSharedInterruptibly(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertTrue(lock.lockShared(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
lock.unlockShared(OP1);
assertFalse(lock.lockInterruptibly(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
lock.unlockShared(OP1);
assertFalse(lock.lockInterruptibly(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
lock.unlockShared(OP1);
assertTrue(lock.lockInterruptibly(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
}
@Test
public void testAcquireShared() throws InterruptedException {
ModelControllerLock lock = new ModelControllerLock();
lock.lockShared(OP1);
lock.lockShared(OP2);
assertTrue(lock.lockSharedInterruptibly(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertTrue(lock.lockSharedInterruptibly(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertFalse(lock.lockInterruptibly(OP3, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertTrue(lock.lockShared(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertTrue(lock.lockShared(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
}
@Test
public void testSharedBlocksExclusive() throws InterruptedException {
ModelControllerLock lock = new ModelControllerLock();
lock.lockShared(OP1);
assertFalse(lock.lockInterruptibly(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertFalse(lock.lockInterruptibly(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
lock.unlockShared(OP1);
assertTrue(lock.lockInterruptibly(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertFalse(lock.lockInterruptibly(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertTrue(lock.lockInterruptibly(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
}
@Test
public void testExclusiveAllowsPermit0() throws InterruptedException {
ModelControllerLock lock = new ModelControllerLock();
lock.lock(0);
assertFalse(lock.lockSharedInterruptibly(0, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertTrue(lock.lockInterruptibly(0, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertFalse(lock.lockSharedInterruptibly(0, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
}
@Test
public void testSharedAllowsPermit0() throws InterruptedException {
ModelControllerLock lock = new ModelControllerLock();
lock.lockShared(0);
assertFalse(lock.lockInterruptibly(0, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertTrue(lock.lockSharedInterruptibly(0, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertFalse(lock.lockInterruptibly(0, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
}
@Test
public void testExclusiveAllowsMinMaxInt() throws InterruptedException {
ModelControllerLock lock = new ModelControllerLock();
lock.lock(Integer.MAX_VALUE);
assertFalse(lock.lockSharedInterruptibly(Integer.MAX_VALUE, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertTrue(lock.lockInterruptibly(Integer.MAX_VALUE, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertFalse(lock.lockSharedInterruptibly(Integer.MAX_VALUE, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
lock.unlock(Integer.MAX_VALUE);
lock.unlock(Integer.MAX_VALUE);
assertTrue(lock.lockSharedInterruptibly(Integer.MAX_VALUE, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
lock.unlockShared(Integer.MAX_VALUE);
lock.lock(Integer.MIN_VALUE);
assertFalse(lock.lockSharedInterruptibly(Integer.MIN_VALUE, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertTrue(lock.lockInterruptibly(Integer.MIN_VALUE, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertFalse(lock.lockSharedInterruptibly(Integer.MIN_VALUE, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
lock.unlock(Integer.MIN_VALUE);
lock.unlock(Integer.MIN_VALUE);
assertTrue(lock.lockSharedInterruptibly(Integer.MIN_VALUE, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
lock.unlockShared(Integer.MIN_VALUE);
}
@Test
public void testSharedAllowsMinMaxInt() throws InterruptedException {
ModelControllerLock lock = new ModelControllerLock();
lock.lockShared(Integer.MAX_VALUE);
assertFalse(lock.lockInterruptibly(Integer.MAX_VALUE, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertTrue(lock.lockSharedInterruptibly(Integer.MAX_VALUE, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertFalse(lock.lockInterruptibly(Integer.MAX_VALUE, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
lock.unlockShared(Integer.MAX_VALUE);
lock.unlockShared(Integer.MAX_VALUE);
assertTrue(lock.lockInterruptibly(Integer.MAX_VALUE, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
lock.unlock(Integer.MAX_VALUE);
lock.lockShared(Integer.MIN_VALUE);
assertFalse(lock.lockInterruptibly(Integer.MIN_VALUE, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertTrue(lock.lockSharedInterruptibly(Integer.MIN_VALUE, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertFalse(lock.lockInterruptibly(Integer.MIN_VALUE, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
lock.unlockShared(Integer.MIN_VALUE);
lock.unlockShared(Integer.MIN_VALUE);
assertTrue(lock.lockInterruptibly(Integer.MIN_VALUE, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
lock.unlock(Integer.MIN_VALUE);
}
@Test
public void testExclusiveWithThreads() throws InterruptedException {
final ModelControllerLock lock = new ModelControllerLock();
Runnable a = new Runnable() {
@Override
public void run() {
try {
lock.lock(OP1);
assertFalse(lock.lockInterruptibly(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
};
Runnable b = new Runnable() {
@Override
public void run() {
try {
assertFalse(lock.lockInterruptibly(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
lock.unlock(OP1);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
};
Thread t1 = new Thread(a);
Thread t2 = new Thread(b);
t1.start();
t1.join();
assertFalse(lock.lockInterruptibly(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
t2.start();
t2.join();
assertTrue(lock.lockInterruptibly(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
}
@Test
public void testSharedWithThreads() throws InterruptedException {
final ModelControllerLock lock = new ModelControllerLock();
Runnable a = new Runnable() {
@Override
public void run() {
try {
lock.lockShared(OP1);
assertFalse(lock.lockInterruptibly(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertTrue(lock.lockSharedInterruptibly(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
assertFalse(lock.lockInterruptibly(OP1, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
};
Runnable b = new Runnable() {
@Override
public void run() {
try {
assertFalse(lock.lockInterruptibly(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
lock.unlockShared(OP2);
lock.unlockShared(OP1);
assertTrue(lock.lockInterruptibly(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
lock.unlock(OP2);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
};
Thread t1 = new Thread(a);
Thread t2 = new Thread(b);
t1.start();
t1.join();
assertFalse(lock.lockInterruptibly(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
t2.start();
t2.join();
assertTrue(lock.lockInterruptibly(OP2, DEFAULT_TIMEOUT, DEFAULT_TIMEUNIT));
}
}