package pl.droidsonroids.gif;
import net.jodah.concurrentunit.Waiter;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.Timeout;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class ConditionVariableTest {
private static final int TEST_TIMEOUT = 500;
private static final int BLOCK_DURATION = 200;
@Rule
public Timeout timeout = new Timeout(TEST_TIMEOUT, TimeUnit.MILLISECONDS);
private ConditionVariable conditionVariable;
private Waiter waiter;
@Before
public void setUp() {
conditionVariable = new ConditionVariable();
waiter = new Waiter();
}
@Test
public void testBlock() throws Exception {
blockAndWait();
}
@Test
public void testOpen() throws Exception {
new Thread() {
@Override
public void run() {
conditionVariable.open();
waiter.resume();
}
}.start();
conditionVariable.block();
waiter.await();
}
@Test
public void testInitiallyOpened() throws Exception {
conditionVariable.set(true);
conditionVariable.block();
}
@Test
public void testInitiallyClosed() throws Exception {
conditionVariable.set(false);
blockAndWait();
}
@Test
public void testClose() throws Exception {
conditionVariable.close();
blockAndWait();
}
private void blockAndWait() throws InterruptedException, TimeoutException {
final Thread thread = new Thread() {
@Override
public void run() {
try {
waiter.resume();
conditionVariable.block();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
waiter.rethrow(e);
}
waiter.fail("ConditionVariable not blocked");
}
};
thread.start();
thread.join(BLOCK_DURATION);
waiter.await();
}
}