32
32
import org .junit .jupiter .api .Test ;
33
33
import org .junit .jupiter .api .extension .RegisterExtension ;
34
34
import org .junit .jupiter .params .ParameterizedTest ;
35
- import org .junit .jupiter .params .provider .ValueSource ;
35
+ import org .junit .jupiter .params .provider .MethodSource ;
36
36
37
37
import java .io .File ;
38
38
import java .lang .reflect .Field ;
39
39
import java .net .SocketException ;
40
40
import java .net .SocketTimeoutException ;
41
41
import java .sql .Connection ;
42
42
import java .sql .SQLException ;
43
+ import java .util .concurrent .Callable ;
44
+ import java .util .concurrent .CancellationException ;
43
45
import java .util .concurrent .ExecutorService ;
44
46
import java .util .concurrent .Executors ;
47
+ import java .util .concurrent .Future ;
45
48
import java .util .concurrent .TimeUnit ;
49
+ import java .util .stream .Stream ;
46
50
51
+ import static org .awaitility .Awaitility .await ;
47
52
import static org .awaitility .Awaitility .with ;
48
53
import static org .firebirdsql .common .FBTestProperties .*;
49
54
import static org .firebirdsql .common .matchers .SQLExceptionMatchers .errorCodeEquals ;
@@ -129,36 +134,43 @@ void testWaitForEventNoEvent() throws Exception {
129
134
@ Test
130
135
void testWaitForEventIndefinitely () throws Exception {
131
136
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
+ }
138
146
}
139
147
140
148
@ Test
141
149
void testWaitForEventWithOccurrence () throws Exception {
142
150
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
+ }
150
160
}
151
161
152
162
@ Test
153
163
void testWaitForEventWithOccurrenceNoTimeout () throws Exception {
154
164
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
+ }
162
174
}
163
175
164
176
@ Test
@@ -219,9 +231,10 @@ void testLargeMultiLoad() throws Exception {
219
231
final int threadCount = 5 ;
220
232
final int repetitionCount = 100 ;
221
233
ExecutorService executorService = Executors .newFixedThreadPool (threadCount );
234
+ var eventProducer = new EventProducer (repetitionCount );
222
235
try {
223
236
for (int i = 0 ; i < threadCount ; i ++) {
224
- executorService .submit (new EventProducer ( repetitionCount ) );
237
+ executorService .submit (eventProducer );
225
238
}
226
239
} finally {
227
240
executorService .shutdown ();
@@ -240,9 +253,10 @@ void testLargeMultiLoad() throws Exception {
240
253
void testSlowCallback () throws Exception {
241
254
setupDefaultEventManager ();
242
255
var ael = new AccumulatingEventListener () {
256
+ @ SuppressWarnings ("java:S2925" )
243
257
public void eventOccurred (DatabaseEvent e ) {
244
258
try {
245
- Thread .sleep (300 );
259
+ Thread .sleep (250 );
246
260
} catch (InterruptedException ie ) {
247
261
// ignore
248
262
}
@@ -255,16 +269,15 @@ public void eventOccurred(DatabaseEvent e) {
255
269
for (int i = 0 ; i < repetitionCount ; i ++) {
256
270
executeSql ("INSERT INTO TEST VALUES (5)" );
257
271
}
258
- with ().pollDelay (1500 , TimeUnit .MILLISECONDS )
272
+ with ().pollDelay (1200 , TimeUnit .MILLISECONDS )
259
273
.await ().until (ael ::getTotalEvents , equalTo (repetitionCount ));
260
274
}
261
275
262
276
@ Test
263
277
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 )) {
268
281
eventManager1 .connect ();
269
282
eventManager2 .connect ();
270
283
@@ -303,9 +316,6 @@ void testMultipleManagersOnExistingConnectionOnOneEvent() throws Exception {
303
316
assertEquals (4 , ael5 .getTotalEvents (), "ael5 totalEvents" );
304
317
assertEquals (0 , ael6 .getTotalEvents (), "ael6 totalEvents" );
305
318
});
306
-
307
- eventManager1 .disconnect ();
308
- eventManager2 .disconnect ();
309
319
}
310
320
}
311
321
@@ -351,29 +361,29 @@ void testEventManagerOnExistingException_connectThrowsException_afterConnectionC
351
361
}
352
362
353
363
@ 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 {
356
366
setupDefaultEventManager ();
357
367
AbstractFbDatabase <?> db = (AbstractFbDatabase <?>) ((FBEventManager ) eventManager ).getFbDatabase ();
358
368
Field eldField = AbstractFbAttachment .class .getDeclaredField ("exceptionListenerDispatcher" );
359
369
eldField .setAccessible (true );
360
370
ExceptionListenerDispatcher eld = (ExceptionListenerDispatcher ) eldField .get (db );
361
371
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
-
370
372
assertTrue (eventManager .isConnected (), "expected connected event manager" );
371
373
372
374
eld .errorOccurred (exception );
373
375
374
376
assertFalse (eventManager .isConnected (), "expected disconnected event manager" );
375
377
}
376
378
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
+
377
387
/**
378
388
* Tests if a default event manager is reported as closed when the underlying {@link FbDatabase} detaches.
379
389
* <p>
@@ -392,30 +402,25 @@ void testDefaultEventManagerDisconnectionOnDbClose() throws Exception {
392
402
assertFalse (eventManager .isConnected (), "expected disconnected event manager" );
393
403
}
394
404
395
- private class EventWait implements Runnable {
405
+ private class EventWait implements Callable < Integer > {
396
406
397
407
private final String eventName ;
398
- private int eventCount ;
399
408
private final int timeout ;
400
409
401
410
EventWait (String eventName , int timeout ) {
402
411
this .eventName = eventName ;
403
412
this .timeout = timeout ;
404
413
}
405
414
406
- public void run () {
415
+ public Integer call () {
407
416
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 ;
411
420
} catch (Exception e ) {
412
- throw new RuntimeException (e . getMessage (), e );
421
+ throw new RuntimeException (e );
413
422
}
414
423
}
415
-
416
- int getEventCount () {
417
- return this .eventCount ;
418
- }
419
424
}
420
425
421
426
private static class AccumulatingEventListener implements EventListener {
@@ -435,15 +440,16 @@ public synchronized void eventOccurred(DatabaseEvent event) {
435
440
private record EventProducer (int count ) implements Runnable {
436
441
@ Override
437
442
public void run () {
438
- try (Connection conn = getConnectionViaDriverManager ();
443
+ try (var conn = getConnectionViaDriverManager ();
439
444
var stmt = conn .prepareStatement ("INSERT INTO TEST VALUES (?)" )) {
440
445
for (int i = 0 ; i < count ; i ++) {
441
446
stmt .setInt (1 , i );
442
447
stmt .execute ();
443
448
}
449
+ } catch (RuntimeException e ) {
450
+ throw e ;
444
451
} catch (Exception e ) {
445
- e .printStackTrace ();
446
- throw new RuntimeException (e .getMessage ());
452
+ throw new RuntimeException (e );
447
453
}
448
454
}
449
455
}
0 commit comments