package org.multiverse.api.blocking; import org.junit.Before; import org.junit.Test; import org.multiverse.TestThread; import org.multiverse.api.exceptions.RetryInterruptedException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import static org.multiverse.TestUtils.*; public class DefaultRetryLatch_awaitTest { @Before public void setUp(){ clearCurrentThreadInterruptedStatus(); } @Test public void whenAlreadyOpenAndSameEra(){ DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); latch.open(era); latch.await(era,"sometransaction"); 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); latch.await(oldEra,"sometransaction"); assertOpen(latch); assertEquals(era, latch.getEra()); } @Test public void whenClosedButDifferentEra(){ DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); latch.reset(); long expectedEra = latch.getEra(); latch.await(era,"sometransaction"); assertEquals(expectedEra, latch.getEra()); assertClosed(latch); } @Test public void whenSomeWaitingIsNeeded() { DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); AwaitThread t = new AwaitThread(latch, era); t.start(); sleepMs(500); assertAlive(t); latch.open(era); joinAll(t); assertOpen(latch); } @Test public void whenStartingInterrupted() { DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); Thread.currentThread().interrupt(); try { latch.await(era,"sometransaction"); fail(); } catch (RetryInterruptedException expected) { } assertEra(latch, era); assertClosed(latch); } @Test public void whenInterruptedWhileWaiting() throws InterruptedException { DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); AwaitThread t = new AwaitThread(latch, era); t.setPrintStackTrace(false); t.start(); sleepMs(500); assertAlive(t); t.interrupt(); t.join(); assertClosed(latch); assertEra(latch, era); t.assertEndedWithInterruptStatus(true); t.assertFailedWithException(RetryInterruptedException.class); } @Test public void whenResetWhileWaiting_thenSleepingThreadsNotified() { DefaultRetryLatch latch = new DefaultRetryLatch(); long era = latch.getEra(); AwaitThread t = new AwaitThread(latch, era); t.start(); sleepMs(500); assertAlive(t); latch.reset(); joinAll(t); assertClosed(latch); assertEra(latch, era + 1); } class AwaitThread extends TestThread { private final RetryLatch latch; private final long expectedEra; AwaitThread(RetryLatch latch, long expectedEra) { this.latch = latch; this.expectedEra = expectedEra; } @Override public void doRun() throws Exception { latch.await(expectedEra,"sometransaction"); } } }