Skip to content

Commit 79b7183

Browse files
committed
Replace reliance on sleep with awaitility
1 parent 9d7bb0f commit 79b7183

File tree

1 file changed

+61
-55
lines changed

1 file changed

+61
-55
lines changed

src/test/org/firebirdsql/event/FBEventManagerTest.java

Lines changed: 61 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,23 @@
3232
import org.junit.jupiter.api.Test;
3333
import org.junit.jupiter.api.extension.RegisterExtension;
3434
import org.junit.jupiter.params.ParameterizedTest;
35-
import org.junit.jupiter.params.provider.ValueSource;
35+
import org.junit.jupiter.params.provider.MethodSource;
3636

3737
import java.io.File;
3838
import java.lang.reflect.Field;
3939
import java.net.SocketException;
4040
import java.net.SocketTimeoutException;
4141
import java.sql.Connection;
4242
import java.sql.SQLException;
43+
import java.util.concurrent.Callable;
44+
import java.util.concurrent.CancellationException;
4345
import java.util.concurrent.ExecutorService;
4446
import java.util.concurrent.Executors;
47+
import java.util.concurrent.Future;
4548
import java.util.concurrent.TimeUnit;
49+
import java.util.stream.Stream;
4650

51+
import static org.awaitility.Awaitility.await;
4752
import static org.awaitility.Awaitility.with;
4853
import static org.firebirdsql.common.FBTestProperties.*;
4954
import static org.firebirdsql.common.matchers.SQLExceptionMatchers.errorCodeEquals;
@@ -129,36 +134,43 @@ void testWaitForEventNoEvent() throws Exception {
129134
@Test
130135
void testWaitForEventIndefinitely() throws Exception {
131136
setupDefaultEventManager();
132-
var eventWait = new EventWait("TEST_EVENT_B", 0);
133-
var waitThread = new Thread(eventWait);
134-
waitThread.start();
135-
waitThread.join(1000);
136-
if (waitThread.isAlive()) waitThread.interrupt();
137-
assertEquals(0, eventWait.getEventCount());
137+
ExecutorService executorService = Executors.newSingleThreadExecutor();
138+
try {
139+
Future<Integer> eventResult = executorService.submit(new EventWait("TEST_EVENT_B", 0));
140+
await().during(1, TimeUnit.SECONDS).until(() -> !eventResult.isDone());
141+
eventResult.cancel(true);
142+
assertThrows(CancellationException.class, eventResult::get);
143+
} finally {
144+
executorService.shutdownNow();
145+
}
138146
}
139147

140148
@Test
141149
void testWaitForEventWithOccurrence() throws Exception {
142150
setupDefaultEventManager();
143-
var eventWait = new EventWait("TEST_EVENT_B", 10000);
144-
var waitThread = new Thread(eventWait);
145-
waitThread.start();
146-
Thread.sleep(SHORT_DELAY);
147-
executeSql("INSERT INTO TEST VALUES (1)");
148-
waitThread.join();
149-
assertEquals(1, eventWait.getEventCount());
151+
ExecutorService executorService = Executors.newSingleThreadExecutor();
152+
try {
153+
Future<Integer> eventResult = executorService.submit(new EventWait("TEST_EVENT_B", 10000));
154+
executeSql("INSERT INTO TEST VALUES (1)");
155+
await().atMost(1, TimeUnit.SECONDS).until(eventResult::isDone);
156+
assertEquals(1, eventResult.get());
157+
} finally {
158+
executorService.shutdownNow();
159+
}
150160
}
151161

152162
@Test
153163
void testWaitForEventWithOccurrenceNoTimeout() throws Exception {
154164
setupDefaultEventManager();
155-
var eventWait = new EventWait("TEST_EVENT_A", 0);
156-
var waitThread = new Thread(eventWait);
157-
waitThread.start();
158-
Thread.sleep(SHORT_DELAY);
159-
executeSql("INSERT INTO TEST VALUES (2)");
160-
waitThread.join();
161-
assertEquals(2, eventWait.getEventCount());
165+
ExecutorService executorService = Executors.newSingleThreadExecutor();
166+
try {
167+
Future<Integer> eventResult = executorService.submit(new EventWait("TEST_EVENT_A", 0));
168+
executeSql("INSERT INTO TEST VALUES (2)");
169+
await().atMost(1, TimeUnit.SECONDS).until(eventResult::isDone);
170+
assertEquals(2, eventResult.get());
171+
} finally {
172+
executorService.shutdownNow();
173+
}
162174
}
163175

164176
@Test
@@ -219,9 +231,10 @@ void testLargeMultiLoad() throws Exception {
219231
final int threadCount = 5;
220232
final int repetitionCount = 100;
221233
ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
234+
var eventProducer = new EventProducer(repetitionCount);
222235
try {
223236
for (int i = 0; i < threadCount; i++) {
224-
executorService.submit(new EventProducer(repetitionCount));
237+
executorService.submit(eventProducer);
225238
}
226239
} finally {
227240
executorService.shutdown();
@@ -240,9 +253,10 @@ void testLargeMultiLoad() throws Exception {
240253
void testSlowCallback() throws Exception {
241254
setupDefaultEventManager();
242255
var ael = new AccumulatingEventListener() {
256+
@SuppressWarnings("java:S2925")
243257
public void eventOccurred(DatabaseEvent e) {
244258
try {
245-
Thread.sleep(300);
259+
Thread.sleep(250);
246260
} catch (InterruptedException ie) {
247261
// ignore
248262
}
@@ -255,16 +269,15 @@ public void eventOccurred(DatabaseEvent e) {
255269
for (int i = 0; i < repetitionCount; i++) {
256270
executeSql("INSERT INTO TEST VALUES (5)");
257271
}
258-
with().pollDelay(1500, TimeUnit.MILLISECONDS)
272+
with().pollDelay(1200, TimeUnit.MILLISECONDS)
259273
.await().until(ael::getTotalEvents, equalTo(repetitionCount));
260274
}
261275

262276
@Test
263277
void testMultipleManagersOnExistingConnectionOnOneEvent() throws Exception {
264-
try (Connection connection = getConnectionViaDriverManager()) {
265-
var eventManager1 = FBEventManager.createFor(connection);
266-
var eventManager2 = FBEventManager.createFor(connection);
267-
278+
try (Connection connection = getConnectionViaDriverManager();
279+
var eventManager1 = FBEventManager.createFor(connection);
280+
var eventManager2 = FBEventManager.createFor(connection)) {
268281
eventManager1.connect();
269282
eventManager2.connect();
270283

@@ -303,9 +316,6 @@ void testMultipleManagersOnExistingConnectionOnOneEvent() throws Exception {
303316
assertEquals(4, ael5.getTotalEvents(), "ael5 totalEvents");
304317
assertEquals(0, ael6.getTotalEvents(), "ael6 totalEvents");
305318
});
306-
307-
eventManager1.disconnect();
308-
eventManager2.disconnect();
309319
}
310320
}
311321

@@ -351,29 +361,29 @@ void testEventManagerOnExistingException_connectThrowsException_afterConnectionC
351361
}
352362

353363
@ParameterizedTest
354-
@ValueSource(strings = { "BrokenSQLException", "FatalSQLException", "SocketException", "SocketTimeoutException" })
355-
void testDefaultEventManagerDisconnectOnFatalException(String exceptionType) throws Exception {
364+
@MethodSource("fatalExceptions")
365+
void testDefaultEventManagerDisconnectOnFatalException(SQLException exception) throws Exception {
356366
setupDefaultEventManager();
357367
AbstractFbDatabase<?> db = (AbstractFbDatabase<?>) ((FBEventManager) eventManager).getFbDatabase();
358368
Field eldField = AbstractFbAttachment.class.getDeclaredField("exceptionListenerDispatcher");
359369
eldField.setAccessible(true);
360370
ExceptionListenerDispatcher eld = (ExceptionListenerDispatcher) eldField.get(db);
361371

362-
SQLException exception = switch (exceptionType) {
363-
case "BrokenSQLException" -> new SQLException("broken", "00000", ISCConstants.isc_net_write_err);
364-
case "FatalSQLException" -> new SQLException("fatal not broken", "00000", ISCConstants.isc_req_sync);
365-
case "SocketException" -> new SQLException(new SocketException());
366-
case "SocketTimeoutException" -> new SQLException(new SocketTimeoutException());
367-
default -> throw new IllegalArgumentException("Unexpected exceptionType: " + exceptionType);
368-
};
369-
370372
assertTrue(eventManager.isConnected(), "expected connected event manager");
371373

372374
eld.errorOccurred(exception);
373375

374376
assertFalse(eventManager.isConnected(), "expected disconnected event manager");
375377
}
376378

379+
static Stream<SQLException> fatalExceptions() {
380+
return Stream.of(
381+
new SQLException("broken", "00000", ISCConstants.isc_net_write_err),
382+
new SQLException("fatal not broken", "00000", ISCConstants.isc_req_sync),
383+
new SQLException(new SocketException()),
384+
new SQLException(new SocketTimeoutException()));
385+
}
386+
377387
/**
378388
* Tests if a default event manager is reported as closed when the underlying {@link FbDatabase} detaches.
379389
* <p>
@@ -392,30 +402,25 @@ void testDefaultEventManagerDisconnectionOnDbClose() throws Exception {
392402
assertFalse(eventManager.isConnected(), "expected disconnected event manager");
393403
}
394404

395-
private class EventWait implements Runnable {
405+
private class EventWait implements Callable<Integer> {
396406

397407
private final String eventName;
398-
private int eventCount;
399408
private final int timeout;
400409

401410
EventWait(String eventName, int timeout) {
402411
this.eventName = eventName;
403412
this.timeout = timeout;
404413
}
405414

406-
public void run() {
415+
public Integer call() {
407416
try {
408-
eventCount = eventManager.waitForEvent(eventName, timeout);
409-
} catch (InterruptedException ie) {
410-
eventCount = 0;
417+
return eventManager.waitForEvent(eventName, timeout);
418+
} catch (RuntimeException e) {
419+
throw e;
411420
} catch (Exception e) {
412-
throw new RuntimeException(e.getMessage(), e);
421+
throw new RuntimeException(e);
413422
}
414423
}
415-
416-
int getEventCount() {
417-
return this.eventCount;
418-
}
419424
}
420425

421426
private static class AccumulatingEventListener implements EventListener {
@@ -435,15 +440,16 @@ public synchronized void eventOccurred(DatabaseEvent event) {
435440
private record EventProducer(int count) implements Runnable {
436441
@Override
437442
public void run() {
438-
try (Connection conn = getConnectionViaDriverManager();
443+
try (var conn = getConnectionViaDriverManager();
439444
var stmt = conn.prepareStatement("INSERT INTO TEST VALUES (?)")) {
440445
for (int i = 0; i < count; i++) {
441446
stmt.setInt(1, i);
442447
stmt.execute();
443448
}
449+
} catch (RuntimeException e) {
450+
throw e;
444451
} catch (Exception e) {
445-
e.printStackTrace();
446-
throw new RuntimeException(e.getMessage());
452+
throw new RuntimeException(e);
447453
}
448454
}
449455
}

0 commit comments

Comments
 (0)