diff --git a/src/test/java/io/vertx/circuitbreaker/impl/UsageTest.java b/src/test/java/io/vertx/circuitbreaker/impl/UsageTest.java index 16ce4a5..135d704 100644 --- a/src/test/java/io/vertx/circuitbreaker/impl/UsageTest.java +++ b/src/test/java/io/vertx/circuitbreaker/impl/UsageTest.java @@ -21,18 +21,13 @@ import org.junit.Test; import org.junit.runner.RunWith; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import static com.jayway.awaitility.Awaitility.await; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; /** * @author Clement Escoffier @@ -44,14 +39,12 @@ public class UsageTest { public RepeatRule repeatRule = new RepeatRule(); private Vertx vertx; - private List items; private CircuitBreaker cb; private HttpServer server; @Before public void setUp() { vertx = Vertx.vertx(); - items = Collections.synchronizedList(new ArrayList<>()); cb = CircuitBreaker.create("circuit-breaker", vertx, new CircuitBreakerOptions() .setFallbackOnFailure(true) .setTimeout(500) @@ -163,29 +156,29 @@ public void testCBWithReadOperation() throws Exception { assertEquals("KO", json.get().getString("status")); } - private void asyncWrite(Scenario scenario, Promise resultHandler) { - long random = (long) (Math.random() * 1000); + private void asyncWrite(Scenario scenario, Promise promise) { + long delay; switch (scenario) { - case TIMEOUT: - random = 2000; - break; case RUNTIME_EXCEPTION: throw new RuntimeException("Bad bad bad"); + case TIMEOUT: + delay = 2000; + break; + default: + delay = ThreadLocalRandom.current().nextLong(1, 250); // Must be less than CB timeout + break; } - - vertx.setTimer(random, l -> { + vertx.setTimer(delay, l -> { if (scenario == Scenario.FAILURE) { - items.add("Error"); - resultHandler.fail("Bad Bad Bad"); + promise.fail("Bad Bad Bad"); } else { - items.add("Hello"); - resultHandler.complete(); + promise.complete("foo"); } }); } - enum Scenario { + private enum Scenario { OK, FAILURE, RUNTIME_EXCEPTION, @@ -193,105 +186,66 @@ enum Scenario { } @Test + @Repeat(10) public void testCBWithWriteOperation() { - cb.executeWithFallback( - future -> { - asyncWrite(Scenario.OK, future); - }, - t -> null - ); - - await().until(() -> items.size() == 1); - items.clear(); - - AtomicBoolean fallbackCalled = new AtomicBoolean(); - cb.executeWithFallback( - future -> { - asyncWrite(Scenario.FAILURE, future); - }, - t -> { - fallbackCalled.set(true); - return null; - } - ); - - await().until(() -> items.size() == 1); - - assertTrue(fallbackCalled.get()); - - items.clear(); - fallbackCalled.set(false); - - cb.executeWithFallback( - future -> asyncWrite(Scenario.TIMEOUT, future), - t -> { - fallbackCalled.set(true); - return null; - } - ); + AtomicReference str = new AtomicReference<>(); + cb.executeWithFallback( + promise -> asyncWrite(Scenario.OK, promise), + t -> "bar" + ).onComplete(ar -> str.set(ar.result())); + await().untilAtomic(str, is(equalTo("foo"))); - await().untilAtomic(fallbackCalled, is(true)); - assertTrue(items.isEmpty()); + str.set(null); + cb.executeWithFallback( + promise -> asyncWrite(Scenario.FAILURE, promise), + t -> "bar" + ).onComplete(ar -> str.set(ar.result())); + await().untilAtomic(str, is(equalTo("bar"))); - fallbackCalled.set(false); - cb.executeWithFallback( - future -> asyncWrite(Scenario.RUNTIME_EXCEPTION, future), - t -> { - fallbackCalled.set(true); - return null; - } - ); + str.set(null); + cb.executeWithFallback( + promise -> asyncWrite(Scenario.TIMEOUT, promise), + t -> "bar" + ).onComplete(ar -> str.set(ar.result())); + await().untilAtomic(str, is(equalTo("bar"))); - await().untilAtomic(fallbackCalled, is(true)); - assertTrue(items.isEmpty()); + str.set(null); + cb.executeWithFallback( + promise -> asyncWrite(Scenario.RUNTIME_EXCEPTION, promise), + t -> "bar" + ).onComplete(ar -> str.set(ar.result())); + await().untilAtomic(str, is(equalTo("bar"))); } @Test public void testCBWithEventBus() { - cb.>executeWithFallback( - future -> vertx.eventBus().request("ok", "").onComplete(future), - t -> null - ).onComplete(ar -> items.add(ar.result().body())); - - await().until(() -> items.size() == 1); - items.clear(); - - AtomicBoolean fallbackCalled = new AtomicBoolean(); - cb.>executeWithFallback( - future -> vertx.eventBus().request("timeout", "").onComplete(future), - t -> { - fallbackCalled.set(true); - return null; - } - ); - - await().untilAtomic(fallbackCalled, is(true)); - assertTrue(items.isEmpty()); - fallbackCalled.set(false); - - cb.>executeWithFallback( - future -> vertx.eventBus().request("fail", "").onComplete(future), - t -> { - fallbackCalled.set(true); - return null; - } - ); + AtomicReference str = new AtomicReference<>(); + cb.executeWithFallback( + promise -> vertx.eventBus().request("ok", "").map(Message::body).onComplete(promise), + t -> "KO" + ).onComplete(ar -> str.set(ar.result())); + await().untilAtomic(str, is(equalTo("OK"))); - await().untilAtomic(fallbackCalled, is(true)); - assertTrue(items.isEmpty()); - fallbackCalled.set(false); + str.set(null); + cb.executeWithFallback( + promise -> vertx.eventBus().request("timeout", "").map(Message::body).onComplete(promise), + t -> "KO" + ).onComplete(ar -> str.set(ar.result())); + await().untilAtomic(str, is(equalTo("KO"))); - cb.>executeWithFallback( - future -> vertx.eventBus().request("exception", "").onComplete(future), - t -> { - fallbackCalled.set(true); - return null; - } - ); + str.set(null); + cb.executeWithFallback( + promise -> vertx.eventBus().request("fail", "").map(Message::body).onComplete(promise), + t -> "KO" + ).onComplete(ar -> str.set(ar.result())); + await().untilAtomic(str, is(equalTo("KO"))); - await().untilAtomic(fallbackCalled, is(true)); - assertTrue(items.isEmpty()); - fallbackCalled.set(false); + str.set(null); + cb.executeWithFallback( + promise -> vertx.eventBus().request("exception", "").map(Message::body).onComplete(promise), + t -> "KO" + ).onComplete(ar -> str.set(ar.result())); + await().untilAtomic(str, is(equalTo("KO"))); } }