package org.multiverse.api.blocking; import org.junit.Before; import org.junit.Test; import org.multiverse.TestThread; import java.util.concurrent.TimeUnit; import static org.junit.Assert.*; import static org.multiverse.TestUtils.*; public class DefaultRetryLatch_tryAwaitUninterruptibleTest { @Before public void setUp() { clearCurrentThreadInterruptedStatus(); } @Test public void whenAlreadyOpenAndSameEra() { DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); latch.open(era); long result = latch.awaitNanosUninterruptible(era, 10); assertEquals(10, result); assertOpen(latch); assertEquals(era, latch.getEra()); } @Test public void whenAlreadyOpenAndDifferentEra() { DefaultRetryLatch latch = new DefaultRetryLatch(); long oldEra = latch.getEra(); latch.reset(); long era = latch.getEra(); latch.open(era); long result = latch.awaitNanosUninterruptible(oldEra, 10); assertEquals(10, result); assertOpen(latch); assertEquals(era, latch.getEra()); } @Test public void whenClosedButDifferentEra() { DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); latch.reset(); long expectedEra = latch.getEra(); long result = latch.awaitNanosUninterruptible(era, 10); assertEquals(10, result); assertEquals(expectedEra, latch.getEra()); assertClosed(latch); } @Test public void whenSomeWaitingIsNeeded() { DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); AwaitThread t = new AwaitThread(latch, era, 10, TimeUnit.SECONDS); t.start(); sleepMs(500); assertAlive(t); latch.open(era); joinAll(t); assertOpen(latch); } @Test public void whenTimeout() { DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); AwaitThread t = new AwaitThread(latch, era, 1, TimeUnit.SECONDS); t.start(); joinAll(t); assertClosed(latch); assertEra(latch, era); assertTrue(t.result < 0); } @Test public void testAlreadyOpenAndNulTimeout() { DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); latch.open(era); long remaining = latch.awaitNanosUninterruptible(era, 0); assertEquals(0, remaining); assertOpen(latch); assertEra(latch, era); } @Test public void whenStillClosedAndNulTimeout() { DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); long remaining = latch.awaitNanosUninterruptible(era, 0); assertTrue(remaining < 0); assertClosed(latch); assertEra(latch, era); } @Test public void whenAlreadyOpenAndNegativeTimeout() { DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); latch.open(era); long remaining = latch.awaitNanosUninterruptible(era, -10); assertTrue(remaining < 0); assertOpen(latch); assertEra(latch, era); } @Test public void whenStillClosedAndNegativeTimeout() { DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); long remaining = latch.awaitNanosUninterruptible(era, -10); assertTrue(remaining < 0); assertClosed(latch); assertEra(latch, era); } @Test public void whenStartingInterrupted() { DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); AwaitThread t = new AwaitThread(latch, era, 10, TimeUnit.SECONDS); t.setStartInterrupted(true); t.start(); sleepMs(500); assertAlive(t); //do some waiting and see if it still is waiting sleepMs(500); assertAlive(t); //now lets open the latch latch.open(era); joinAll(t); assertOpen(latch); assertEra(latch, era); t.assertEndedWithInterruptStatus(true); assertTrue(t.result > 0); assertTrue(t.result < TimeUnit.SECONDS.toNanos(10)); } @Test public void whenInterruptedWhileWaiting() { DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); AwaitThread t = new AwaitThread(latch, era, 10, TimeUnit.SECONDS); t.start(); sleepMs(500); assertAlive(t); t.interrupt(); //do some waiting and see if it still is waiting sleepMs(500); assertAlive(t); //now lets open the latch latch.open(era); joinAll(t); assertOpen(latch); assertEra(latch, era); t.assertEndedWithInterruptStatus(true); assertTrue(t.result > 0); assertTrue(t.result < TimeUnit.SECONDS.toNanos(10)); } @Test public void whenResetWhileWaiting_thenSleepingThreadsNotified() { DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); AwaitThread t = new AwaitThread(latch, era, 10, TimeUnit.SECONDS); t.start(); sleepMs(500); assertAlive(t); latch.reset(); joinAll(t); assertClosed(latch); assertEra(latch, era + 1); assertTrue(t.result > 0); assertTrue(t.result < TimeUnit.SECONDS.toNanos(10)); } class AwaitThread extends TestThread { private final RetryLatch latch; private final long expectedEra; private long timeout; private TimeUnit unit; private long result; AwaitThread(RetryLatch latch, long expectedEra, long timeout, TimeUnit unit) { this.latch = latch; this.expectedEra = expectedEra; this.timeout = timeout; this.unit = unit; } @Override public void doRun() throws Exception { result = latch.awaitNanosUninterruptible(expectedEra, unit.toNanos(timeout)); } } }