package gov.nasa.jpf.test.java.concurrent; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Exchanger; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.junit.Test; import gov.nasa.jpf.util.test.TestJPF; import gov.nasa.jpf.vm.Verify; public class CountDownLatchTest extends TestJPF { private static final int N = 2; // Too many states to test if set higher than 2. jpf-concurrent's gov.nasa.jpf.test.java.concurrent.CountDownLatchTest can handle more threads. private static final int COUNTER_SUCCESS = 0; private static final int COUNTER_EXCHANGED = 1; //@Ignore("detects deadlock with exposure CG??") @Test public void testCountDown() throws InterruptedException { if (verifyNoPropertyViolation("+vm.time.model=ConstantZero", "+vm.por.break_on_exposure=true")) { final CountDownLatch latch = new CountDownLatch(N); final Exchanger<Object> exchanger = new Exchanger<Object>(); final ExecutorService service = Executors.newFixedThreadPool(N); Runnable task = new Runnable() { public void run() { try { Object source = new Object(); Object result = exchanger.exchange(source); //Object result = exchanger.exchange(source, 1L, TimeUnit.SECONDS); // If N==2 and without jpf-concurrent, the timeout causes 149,808 states to be explored. assert source != result : "source != result"; assert result != null : "result != null"; latch.countDown(); Verify.incrementCounter(COUNTER_EXCHANGED); } catch (InterruptedException e) { throw new Error(e); } } }; for (int i = 0; i < N; i++) { service.execute(task); } latch.await(); service.shutdown(); Verify.incrementCounter(COUNTER_SUCCESS); } else { // outside JPF assert Verify.getCounter(COUNTER_SUCCESS) > 0 : "never succeeded"; assert Verify.getCounter(COUNTER_EXCHANGED) > 0 : "never exchanged"; } } }