Skip to content

Commit

Permalink
Fix intermittent BindException in BindException
Browse files Browse the repository at this point in the history
testCBWithReadOperation is repeated several times and the created HTTP server was not managed properly.

Also, simplified the test a little bit using a synchronized list to collect items.

Signed-off-by: Thomas Segismont <[email protected]>
  • Loading branch information
tsegismont committed Jan 10, 2025
1 parent 59aa690 commit 6706176
Showing 1 changed file with 27 additions and 39 deletions.
66 changes: 27 additions & 39 deletions src/test/java/io/vertx/circuitbreaker/tests/impl/UsageTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

import io.vertx.circuitbreaker.CircuitBreaker;
import io.vertx.circuitbreaker.CircuitBreakerOptions;
import io.vertx.core.*;
import io.vertx.core.Completable;
import io.vertx.core.Future;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.eventbus.Message;
import io.vertx.core.http.HttpClient;
import io.vertx.core.http.HttpHeaders;
import io.vertx.core.http.HttpMethod;
import io.vertx.core.http.HttpServer;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.unit.junit.Repeat;
import io.vertx.ext.unit.junit.RepeatRule;
Expand Down Expand Up @@ -40,15 +43,15 @@ public class UsageTest {
@Rule
public RepeatRule repeatRule = new RepeatRule();

// @Rule
// public WireMockRule wireMockRule = new WireMockRule(8089);
private Vertx vertx;
private List<String> items;
private CircuitBreaker cb;
private HttpServer server;

@Before
public void setUp() throws Exception {
vertx = Vertx.vertx();
items.clear();
items = Collections.synchronizedList(new ArrayList<>());
cb = CircuitBreaker.create("circuit-breaker", vertx, new CircuitBreakerOptions()
.setFallbackOnFailure(true)
.setTimeout(500)
Expand All @@ -67,14 +70,17 @@ public void setUp() throws Exception {

@After
public void tearDown() {
if (server != null) {
server.close().await();
}
cb.close();
vertx.close();
vertx.close().await();
}

@Test
@Repeat(10)
public void testCBWithReadOperation() throws Exception {
vertx.createHttpServer().requestHandler(req -> {
server = vertx.createHttpServer().requestHandler(req -> {
switch (req.path()) {
case "/resource":
req.response()
Expand Down Expand Up @@ -155,9 +161,7 @@ public void testCBWithReadOperation() throws Exception {
assertEquals("KO", json.get().getString("status"));
}

private List<String> items = new ArrayList<>();

public void asyncWrite(String content, Scenario scenario, Completable<Void> resultHandler) {
private void asyncWrite(Scenario scenario, Completable<Void> resultHandler) {
long random = (long) (Math.random() * 1000);
switch (scenario) {
case TIMEOUT:
Expand All @@ -170,14 +174,10 @@ public void asyncWrite(String content, Scenario scenario, Completable<Void> resu

vertx.setTimer(random, l -> {
if (scenario == Scenario.FAILURE) {
synchronized (UsageTest.this) {
items.add("Error");
}
items.add("Error");
resultHandler.fail("Bad Bad Bad");
} else {
synchronized (UsageTest.this) {
items.add(content);
}
items.add("Hello");
resultHandler.succeed();
}
});
Expand All @@ -194,63 +194,55 @@ enum Scenario {
public void testCBWithWriteOperation() {
cb.<Void>executeWithFallback(
future -> {
asyncWrite("Hello", Scenario.OK, future);
asyncWrite(Scenario.OK, future);
},
t -> null
);

await().until(() -> {
synchronized (UsageTest.this) {
return items.size() == 1;
}
});
await().until(() -> items.size() == 1);
items.clear();

AtomicBoolean fallbackCalled = new AtomicBoolean();
cb.<Void>executeWithFallback(
future -> {
asyncWrite("Hello", Scenario.FAILURE, future);
asyncWrite(Scenario.FAILURE, future);
},
t -> {
fallbackCalled.set(true);
return null;
}
);

await().until(() -> {
synchronized (UsageTest.this) {
return items.size() == 1;
}
});
await().until(() -> items.size() == 1);

assertTrue(fallbackCalled.get());

items.clear();
fallbackCalled.set(false);

cb.<Void>executeWithFallback(
future -> asyncWrite("Hello", Scenario.TIMEOUT, future),
future -> asyncWrite(Scenario.TIMEOUT, future),
t -> {
fallbackCalled.set(true);
return null;
}
);

await().untilAtomic(fallbackCalled, is(true));
assertEquals(Collections.emptyList(), items);
assertTrue(items.isEmpty());

items.clear();
fallbackCalled.set(false);
cb.<Void>executeWithFallback(
future -> asyncWrite("Hello", Scenario.RUNTIME_EXCEPTION, future),
future -> asyncWrite(Scenario.RUNTIME_EXCEPTION, future),
t -> {
fallbackCalled.set(true);
return null;
}
);

await().untilAtomic(fallbackCalled, is(true));
assertEquals(Collections.emptyList(), items);
assertTrue(items.isEmpty());
}


Expand All @@ -261,11 +253,7 @@ public void testCBWithEventBus() {
t -> null
).onComplete(ar -> items.add(ar.result().body()));

await().until(() -> {
synchronized (UsageTest.this) {
return items.size() == 1;
}
});
await().until(() -> items.size() == 1);
items.clear();

AtomicBoolean fallbackCalled = new AtomicBoolean();
Expand All @@ -278,7 +266,7 @@ public void testCBWithEventBus() {
);

await().untilAtomic(fallbackCalled, is(true));
assertEquals(Collections.emptyList(), items);
assertTrue(items.isEmpty());
fallbackCalled.set(false);

cb.<Message<String>>executeWithFallback(
Expand All @@ -290,7 +278,7 @@ public void testCBWithEventBus() {
);

await().untilAtomic(fallbackCalled, is(true));
assertEquals(Collections.emptyList(), items);
assertTrue(items.isEmpty());
fallbackCalled.set(false);

cb.<Message<String>>executeWithFallback(
Expand All @@ -302,7 +290,7 @@ public void testCBWithEventBus() {
);

await().untilAtomic(fallbackCalled, is(true));
assertEquals(Collections.emptyList(), items);
assertTrue(items.isEmpty());
fallbackCalled.set(false);
}
}

0 comments on commit 6706176

Please sign in to comment.