package io.vertx.ext.unit; import io.vertx.core.Vertx; import org.junit.Test; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import static org.junit.Assert.*; /** * @author <a href="mailto:julien@julienviet.com">Julien Viet</a> */ public class CompletionTest { @Test public void testAwaitSucceeded() { testSucceeded(completion -> completion.await()); testSucceeded(completion -> completion.await(2000)); } @Test public void testAwaitSuccessSucceeded() { testSucceeded(completion -> completion.awaitSuccess()); testSucceeded(completion -> completion.awaitSuccess(2000)); } private void testSucceeded(Consumer<Completion> consumer) { TestSuite suite = TestSuite.create("my_suite").test("my_test", context -> { }); Completion completion = suite.run(Vertx.vertx()); consumer.accept(completion); assertTrue(completion.isCompleted()); assertTrue(completion.isSucceeded()); assertFalse(completion.isFailed()); } @Test public void testAwaitFailed() { testAwaitFailed(completion -> completion.await()); testAwaitFailed(completion -> completion.await(2000)); } private void testAwaitFailed(Consumer<Completion> consumer) { TestSuite suite = TestSuite.create("my_suite").test("my_test", context -> { context.fail(); }); Completion completion = suite.run(Vertx.vertx()); consumer.accept(completion); assertTrue(completion.isCompleted()); assertFalse(completion.isSucceeded()); assertTrue(completion.isFailed()); } @Test public void testAwaitSuccessFailed() throws Exception { testAwaitSuccessFailed(completion -> completion.awaitSuccess()); testAwaitSuccessFailed(completion -> completion.awaitSuccess(2000)); } private void testAwaitSuccessFailed(Consumer<Completion> consumer) throws Exception { AtomicReference<AssertionError> expected = new AtomicReference<>(); TestSuite suite = TestSuite.create("my_suite").test("my_test", context -> { try { context.fail(); } catch (AssertionError ae) { expected.set(ae); throw ae; } }); Completion completion = suite.run(Vertx.vertx()); try { consumer.accept(completion); fail(); } catch (AssertionError ae) { assertSame(expected.get(), ae); } assertTrue(completion.isCompleted()); assertFalse(completion.isSucceeded()); assertTrue(completion.isFailed()); } @Test public void testAwaitTimeout() { testTimeout(completion -> completion.await(10)); } @Test public void testAwaitSuccessTimeout() { testTimeout(completion -> completion.awaitSuccess(10)); } private void testTimeout(Consumer<Completion> consumer) { TestSuite suite = TestSuite.create("my_suite").test("my_test", context -> { context.async(); }); Completion completion = suite.run(Vertx.vertx()); try { consumer.accept(completion); fail(); } catch (Exception e) { assertTrue(e instanceof TimeoutException); assertFalse(completion.isCompleted()); assertFalse(completion.isSucceeded()); assertFalse(completion.isFailed()); } } @Test public void testAwaitInterruption() { testAwaitSuccess(completion -> completion.await(), Thread.State.WAITING); testAwaitSuccess(completion -> completion.await(2000), Thread.State.TIMED_WAITING); } @Test public void testAwaitSuccessInterruption() { testAwaitSuccess(completion -> completion.awaitSuccess(), Thread.State.WAITING); testAwaitSuccess(completion -> completion.awaitSuccess(2000), Thread.State.TIMED_WAITING); } private void testAwaitSuccess(Consumer<Completion> consumer, Thread.State expectedState) { TestSuite suite = TestSuite.create("my_suite").test("my_test", context -> { context.async(); }); Thread thread = Thread.currentThread(); Completion completion = suite.run(Vertx.vertx()); new Thread(() -> { while (thread.getState() != expectedState) { try { Thread.sleep(1); } catch (InterruptedException ignore) { } } thread.interrupt(); }).start(); try { consumer.accept(completion); fail(); } catch (Exception e) { assertTrue(Thread.interrupted()); // Check and clear status assertTrue(e instanceof InterruptedException); assertFalse(completion.isCompleted()); assertFalse(completion.isSucceeded()); assertFalse(completion.isFailed()); } } }