package org.multiverse.api.blocking; import org.junit.Before; import org.junit.Test; import org.multiverse.TestThread; import org.multiverse.api.exceptions.RetryInterruptedException; import java.util.concurrent.TimeUnit; import static org.junit.Assert.*; import static org.multiverse.TestUtils.*; public class DefaultRetryLatch_tryAwaitTest { @Before public void setUp(){ clearCurrentThreadInterruptedStatus(); } @Test public void whenAlreadyOpenAndSameEra(){ DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); latch.open(era); long result = latch.awaitNanos(era, 10,"sometransaction"); 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.awaitNanos(oldEra, 10,"sometransaction"); 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.awaitNanos(era, 10,"sometransaction"); 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); //assertTrue() } @Test public void testAlreadyOpenAndNulTimeout(){ DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); latch.open(era); long remaining = latch.awaitNanos(era, 0,"sometransaction"); assertEquals(0, remaining); assertOpen(latch); assertEra(latch, era); } @Test public void whenStillClosedAndNulTimeout(){ DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); long remaining = latch.awaitNanos(era, 0,"sometransaction"); 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.awaitNanos(era, -10,"sometransaction"); assertTrue(remaining <= 0); assertOpen(latch); assertEra(latch, era); } @Test public void whenStillClosedAndNegativeTimeout() { DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); long remaining = latch.awaitNanos(era, -10,"sometransaction"); assertTrue(remaining < 0); assertClosed(latch); assertEra(latch, era); } @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 whenStartingInterrupted_thenTransactionInterruptedExceptionAndInterruptedStatusRestored() { DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); Thread.currentThread().interrupt(); try { latch.awaitNanos(era, 10,"sometransaction"); fail(); } catch (RetryInterruptedException expected) { } assertTrue(Thread.currentThread().isInterrupted()); assertEra(latch, era); assertClosed(latch); } @Test public void whenInterruptedWhileWaiting_thenTransactionInterruptedExceptionAndInterruptedStatusRestored() throws InterruptedException { DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); AwaitThread t = new AwaitThread(latch, era, 10, TimeUnit.SECONDS); t.setPrintStackTrace(false); t.start(); sleepMs(500); assertAlive(t); t.interrupt(); t.join(); assertClosed(latch); assertEra(latch, era); t.assertFailedWithException(RetryInterruptedException.class); t.assertEndedWithInterruptStatus(true); } @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.awaitNanos(expectedEra, unit.toNanos(timeout),"sometransaction"); } } }