0
# Advanced Configuration
1
2
Global defaults, fail-fast conditions, custom executors, and logging for complex testing scenarios and performance optimization.
3
4
## Capabilities
5
6
### Global Default Configuration
7
8
Set default behavior for all Awaitility await statements.
9
10
#### Timeout Defaults
11
12
```java { .api }
13
/**
14
* Set default timeout for all await statements
15
* @param defaultTimeout maximum wait time for conditions
16
*/
17
static void setDefaultTimeout(Duration defaultTimeout);
18
19
/**
20
* Set default timeout using value and time unit
21
* @param timeout timeout value
22
* @param unit time unit for timeout
23
*/
24
static void setDefaultTimeout(long timeout, TimeUnit unit);
25
```
26
27
#### Polling Defaults
28
29
```java { .api }
30
/**
31
* Set default poll interval for all await statements
32
* @param pollInterval time between condition evaluations
33
*/
34
static void setDefaultPollInterval(Duration pollInterval);
35
36
/**
37
* Set default poll interval using value and time unit
38
* @param pollInterval interval value
39
* @param unit time unit for interval
40
*/
41
static void setDefaultPollInterval(long pollInterval, TimeUnit unit);
42
43
/**
44
* Set default poll interval using custom strategy
45
* @param pollInterval polling strategy implementation
46
*/
47
static void setDefaultPollInterval(PollInterval pollInterval);
48
49
/**
50
* Set default poll delay for all await statements
51
* @param pollDelay initial delay before first condition check
52
*/
53
static void setDefaultPollDelay(Duration pollDelay);
54
55
/**
56
* Set default poll delay using value and time unit
57
* @param pollDelay delay value
58
* @param unit time unit for delay
59
*/
60
static void setDefaultPollDelay(long pollDelay, TimeUnit unit);
61
```
62
63
#### Reset Configuration
64
65
```java { .api }
66
/**
67
* Reset all configuration to default values:
68
* - timeout: 10 seconds
69
* - poll interval: 100 milliseconds
70
* - poll delay: 100 milliseconds
71
* - catch uncaught exceptions: true
72
* - ignore exceptions: false
73
* - no condition evaluation listener
74
* - no fail fast condition
75
*/
76
static void reset();
77
```
78
79
**Global Configuration Examples:**
80
```java
81
// Configure defaults in test setup
82
@BeforeClass
83
public static void setupAwaitility() {
84
setDefaultTimeout(Duration.ofMinutes(2));
85
setDefaultPollInterval(Duration.ofMillis(50));
86
setDefaultPollDelay(Duration.ofMillis(10));
87
}
88
89
@AfterClass
90
public static void cleanupAwaitility() {
91
reset(); // Clean slate for other tests
92
}
93
94
// Configure for specific test environments
95
public static void configureForIntegrationTests() {
96
setDefaultTimeout(5, MINUTES); // Longer timeouts
97
setDefaultPollInterval(500, MILLISECONDS); // Less frequent polling
98
setDefaultPollDelay(1, SECONDS); // Initial delay
99
}
100
101
public static void configureForUnitTests() {
102
setDefaultTimeout(10, SECONDS); // Shorter timeouts
103
setDefaultPollInterval(10, MILLISECONDS); // Frequent polling
104
setDefaultPollDelay(0, MILLISECONDS); // No initial delay
105
}
106
```
107
108
### Fail-Fast Conditions
109
110
Configure terminal failure conditions to avoid unnecessary waiting.
111
112
#### Boolean Fail-Fast Conditions
113
114
```java { .api }
115
/**
116
* Set default fail-fast condition for all await statements
117
* If condition ever returns true, terminate with TerminalFailureException
118
* @param defaultFailFastCondition callable that indicates terminal failure
119
*/
120
static void setDefaultFailFastCondition(Callable<Boolean> defaultFailFastCondition);
121
122
/**
123
* Set default fail-fast condition with descriptive reason
124
* @param failFastFailureReason description included in exception
125
* @param defaultFailFastCondition callable that indicates terminal failure
126
*/
127
static void setDefaultFailFastCondition(String failFastFailureReason,
128
Callable<Boolean> defaultFailFastCondition);
129
```
130
131
#### Assertion-Based Fail-Fast Conditions
132
133
```java { .api }
134
/**
135
* Set default fail-fast assertion for all await statements
136
* If assertion throws exception, terminate with TerminalFailureException
137
* @param defaultFailFastAssertion runnable that performs failure checks
138
*/
139
static void setDefaultFailFastCondition(ThrowingRunnable defaultFailFastAssertion);
140
141
/**
142
* Set default fail-fast assertion with descriptive reason
143
* @param failFastFailureReason description included in exception
144
* @param defaultFailFastAssertion runnable that performs failure checks
145
*/
146
static void setDefaultFailFastCondition(String failFastFailureReason,
147
ThrowingRunnable defaultFailFastAssertion);
148
```
149
150
#### Per-Await Fail-Fast Conditions
151
152
```java { .api }
153
/**
154
* Set fail-fast condition for this await statement
155
* @param failFastCondition callable that indicates terminal failure
156
* @return ConditionFactory for further configuration
157
*/
158
ConditionFactory failFast(Callable<Boolean> failFastCondition);
159
160
/**
161
* Set fail-fast condition with reason for this await statement
162
* @param failFastFailureReason description for failure
163
* @param failFastCondition callable that indicates terminal failure
164
* @return ConditionFactory for further configuration
165
*/
166
ConditionFactory failFast(String failFastFailureReason,
167
Callable<Boolean> failFastCondition);
168
169
/**
170
* Set fail-fast assertion for this await statement
171
* @param failFastAssertion runnable that performs failure checks
172
* @return ConditionFactory for further configuration
173
*/
174
ConditionFactory failFast(ThrowingRunnable failFastAssertion);
175
176
/**
177
* Set fail-fast assertion with reason for this await statement
178
* @param failFastFailureReason description for failure
179
* @param failFastAssertion runnable that performs failure checks
180
* @return ConditionFactory for further configuration
181
*/
182
ConditionFactory failFast(String failFastFailureReason,
183
ThrowingRunnable failFastAssertion);
184
```
185
186
**Fail-Fast Examples:**
187
```java
188
// Global fail-fast for system shutdown
189
setDefaultFailFastCondition("System is shutting down",
190
() -> systemStatus.equals("SHUTDOWN"));
191
192
// Per-await fail-fast for error conditions
193
await().failFast("Database connection lost",
194
() -> !databaseConnection.isValid(1))
195
.until(() -> dataProcessor.isComplete());
196
197
// Assertion-based fail-fast
198
await().failFast("Critical error occurred", () -> {
199
assertThat(errorCount.get()).isLessThan(10);
200
assertThat(systemHealth.getStatus()).isNotEqualTo(Status.CRITICAL);
201
})
202
.until(() -> operationCompletes());
203
204
// Complex fail-fast conditions
205
await().failFast("Service degradation detected", () -> {
206
double errorRate = errorCount.get() / (double) requestCount.get();
207
return errorRate > 0.1 || // More than 10% error rate
208
responseTime.get() > 5000 || // Response time > 5s
209
memoryUsage.get() > 0.9; // Memory usage > 90%
210
})
211
.until(() -> healthCheck.isHealthy());
212
```
213
214
### Thread and Executor Management
215
216
Configure custom execution strategies for condition evaluation.
217
218
#### Custom Executor Services
219
220
```java { .api }
221
/**
222
* Set default executor service for all await statements
223
* @param executorService custom executor for condition evaluation
224
*/
225
static void pollExecutorService(ExecutorService executorService);
226
227
/**
228
* Set executor service for this await statement
229
* @param executorService custom executor for condition evaluation
230
* @return ConditionFactory for further configuration
231
*/
232
ConditionFactory pollExecutorService(ExecutorService executorService);
233
```
234
235
#### Custom Thread Suppliers
236
237
```java { .api }
238
/**
239
* Set default thread supplier for all await statements
240
* @param threadSupplier function that creates threads for polling
241
*/
242
static void pollThread(Function<Runnable, Thread> threadSupplier);
243
244
/**
245
* Set thread supplier for this await statement
246
* @param threadSupplier function that creates threads for polling
247
* @return ConditionFactory for further configuration
248
*/
249
ConditionFactory pollThread(Function<Runnable, Thread> threadSupplier);
250
```
251
252
#### Same-Thread Execution
253
254
```java { .api }
255
/**
256
* Configure all await statements to poll in same thread as test
257
* Use with test framework timeouts for safety
258
*/
259
static void pollInSameThread();
260
261
/**
262
* Configure this await statement to poll in same thread as test
263
* @return ConditionFactory for further configuration
264
*/
265
ConditionFactory pollInSameThread();
266
```
267
268
**Thread Management Examples:**
269
```java
270
// Custom executor with specific thread pool size
271
ExecutorService customExecutor = Executors.newFixedThreadPool(2, r -> {
272
Thread t = new Thread(r);
273
t.setName("Awaitility-Custom-" + t.getId());
274
t.setDaemon(true);
275
return t;
276
});
277
278
// Set as default
279
pollExecutorService(customExecutor);
280
281
// Or use for specific await
282
await().pollExecutorService(customExecutor)
283
.until(() -> expensiveOperation.isComplete());
284
285
// Custom thread with priority
286
await().pollThread(runnable -> {
287
Thread thread = new Thread(runnable);
288
thread.setName("HighPriorityAwait");
289
thread.setPriority(Thread.MAX_PRIORITY);
290
thread.setDaemon(true);
291
return thread;
292
})
293
.until(() -> criticalOperation.isComplete());
294
295
// Same thread execution with JUnit timeout
296
@Test(timeout = 10000) // 10 second timeout
297
public void testWithSameThread() {
298
await().pollInSameThread()
299
.until(() -> quickOperation.isComplete());
300
}
301
```
302
303
### Logging and Condition Evaluation
304
305
Configure detailed logging and monitoring of condition evaluation.
306
307
#### Condition Evaluation Listeners
308
309
```java { .api }
310
/**
311
* Set default condition evaluation listener for all await statements
312
* @param defaultConditionEvaluationListener listener for evaluation events
313
*/
314
static void setDefaultConditionEvaluationListener(
315
ConditionEvaluationListener defaultConditionEvaluationListener);
316
317
/**
318
* Set condition evaluation listener for this await statement
319
* @param conditionEvaluationListener listener for evaluation events
320
* @return ConditionFactory for further configuration
321
*/
322
ConditionFactory conditionEvaluationListener(
323
ConditionEvaluationListener conditionEvaluationListener);
324
```
325
326
#### Built-in Logging
327
328
```java { .api }
329
/**
330
* Enable default logging to System.out for all await statements
331
*/
332
static void setDefaultLogging();
333
334
/**
335
* Enable custom logging for all await statements
336
* @param logPrinter consumer that handles log messages
337
*/
338
static void setLogging(Consumer<String> logPrinter);
339
340
/**
341
* Set custom logging listener for all await statements
342
* @param loggingListener listener that handles evaluation logging
343
*/
344
static void setLoggingListener(ConditionEvaluationListener loggingListener);
345
346
/**
347
* Enable default logging for this await statement
348
* @return ConditionFactory for further configuration
349
*/
350
ConditionFactory logging();
351
352
/**
353
* Enable custom logging for this await statement
354
* @param logPrinter consumer that handles log messages
355
* @return ConditionFactory for further configuration
356
*/
357
ConditionFactory logging(Consumer<String> logPrinter);
358
```
359
360
**Logging Examples:**
361
```java
362
// Enable default logging globally
363
setDefaultLogging();
364
365
// Custom logging to file
366
Logger logger = LoggerFactory.getLogger("AwaitilityTest");
367
setLogging(message -> logger.debug("Awaitility: {}", message));
368
369
// Custom evaluation listener
370
setDefaultConditionEvaluationListener(new ConditionEvaluationListener<Object>() {
371
@Override
372
public void conditionEvaluated(EvaluatedCondition<Object> condition) {
373
System.out.printf("Evaluation %d: %s = %s%n",
374
condition.getElapsedTimeInMS(),
375
condition.getDescription(),
376
condition.getValue());
377
}
378
379
@Override
380
public void beforeEvaluation(StartEvaluationEvent<Object> startEvaluationEvent) {
381
System.out.println("Starting evaluation of: " +
382
startEvaluationEvent.getDescription());
383
}
384
385
@Override
386
public void onTimeout(TimeoutEvent timeoutEvent) {
387
System.err.println("Timeout after: " + timeoutEvent.getElapsedTimeInMS() + "ms");
388
}
389
});
390
391
// Per-await custom logging
392
await().logging(msg -> System.out.println("Custom: " + msg))
393
.until(() -> operation.isComplete());
394
395
// Structured logging with additional context
396
await().conditionEvaluationListener(new ConditionEvaluationListener<Boolean>() {
397
@Override
398
public void conditionEvaluated(EvaluatedCondition<Boolean> condition) {
399
Map<String, Object> logData = Map.of(
400
"elapsed_ms", condition.getElapsedTimeInMS(),
401
"value", condition.getValue(),
402
"remaining_time_ms", condition.getRemainingTimeInMS(),
403
"description", condition.getDescription()
404
);
405
logger.info("Condition evaluation: {}", logData);
406
}
407
}).until(() -> complexOperation.isComplete());
408
```
409
410
### Advanced Configuration Patterns
411
412
Complex configuration scenarios combining multiple advanced features.
413
414
#### Environment-Specific Configuration
415
416
```java
417
public class AwaitilityConfig {
418
419
public static void configureForEnvironment(String environment) {
420
reset(); // Start clean
421
422
switch (environment.toLowerCase()) {
423
case "development":
424
configureDevelopment();
425
break;
426
case "integration":
427
configureIntegration();
428
break;
429
case "production":
430
configureProduction();
431
break;
432
default:
433
configureDefault();
434
}
435
}
436
437
private static void configureDevelopment() {
438
setDefaultTimeout(30, SECONDS);
439
setDefaultPollInterval(100, MILLISECONDS);
440
setDefaultLogging(); // Enable logging for debugging
441
442
// Fail fast on obvious errors
443
setDefaultFailFastCondition("Service crashed",
444
() -> serviceStatus.equals("CRASHED"));
445
}
446
447
private static void configureIntegration() {
448
setDefaultTimeout(5, MINUTES);
449
setDefaultPollInterval(500, MILLISECONDS);
450
setDefaultPollDelay(1, SECONDS);
451
452
// Custom executor for integration tests
453
ExecutorService integrationExecutor =
454
Executors.newFixedThreadPool(4);
455
pollExecutorService(integrationExecutor);
456
457
// Comprehensive fail-fast conditions
458
setDefaultFailFastCondition("Integration environment failure", () -> {
459
return !databaseHealthy() ||
460
!messageQueueHealthy() ||
461
!externalServiceHealthy();
462
});
463
}
464
465
private static void configureProduction() {
466
setDefaultTimeout(10, MINUTES);
467
setDefaultPollInterval(2, SECONDS);
468
setDefaultPollDelay(5, SECONDS);
469
470
// Minimal logging in production
471
setLogging(msg -> productionLogger.debug("Awaitility: {}", msg));
472
473
// Conservative fail-fast
474
setDefaultFailFastCondition("Critical system failure",
475
() -> systemHealth.getOverallStatus() == HealthStatus.CRITICAL);
476
}
477
}
478
```
479
480
#### Test Suite Configuration
481
482
```java
483
public class BaseIntegrationTest {
484
485
@BeforeEach
486
public void setupAwaitility() {
487
// Reset before each test
488
reset();
489
490
// Configure for integration testing
491
setDefaultTimeout(Duration.ofMinutes(2));
492
setDefaultPollInterval(Duration.ofMillis(200));
493
494
// Enable detailed logging for failed tests
495
setDefaultConditionEvaluationListener(new ConditionEvaluationListener<Object>() {
496
@Override
497
public void onTimeout(TimeoutEvent timeoutEvent) {
498
logger.error("Awaitility timeout in {}: {} after {}ms",
499
getCurrentTestMethod(),
500
timeoutEvent.getDescription(),
501
timeoutEvent.getElapsedTimeInMS());
502
}
503
});
504
505
// Global fail-fast for test environment issues
506
setDefaultFailFastCondition("Test environment unstable", () -> {
507
return testDatabase.getConnectionPool().getActiveCount() == 0 ||
508
testMessageBroker.getStatus() != BrokerStatus.RUNNING;
509
});
510
}
511
512
@AfterEach
513
public void cleanupAwaitility() {
514
reset();
515
}
516
517
// Utility methods for common patterns
518
protected ConditionFactory awaitSlowOperation() {
519
return await().atMost(Duration.ofMinutes(5))
520
.pollInterval(Duration.ofSeconds(2))
521
.logging(msg -> logger.trace("SlowOp: {}", msg));
522
}
523
524
protected ConditionFactory awaitQuickOperation() {
525
return await().atMost(Duration.ofSeconds(10))
526
.pollInterval(Duration.ofMillis(50))
527
.pollDelay(Duration.ofMillis(10));
528
}
529
}
530
```
531
532
#### Performance Monitoring Integration
533
534
```java
535
public class PerformanceAwareAwaitility {
536
537
private static final MeterRegistry meterRegistry = Metrics.globalRegistry;
538
private static final Timer awaitTimer = Timer.builder("awaitility.duration")
539
.description("Time spent waiting in Awaitility")
540
.register(meterRegistry);
541
542
public static void configureWithMetrics() {
543
setDefaultConditionEvaluationListener(new ConditionEvaluationListener<Object>() {
544
private final Map<String, Timer.Sample> samples = new ConcurrentHashMap<>();
545
546
@Override
547
public void beforeEvaluation(StartEvaluationEvent<Object> event) {
548
Timer.Sample sample = Timer.start(meterRegistry);
549
samples.put(event.getDescription(), sample);
550
}
551
552
@Override
553
public void conditionEvaluated(EvaluatedCondition<Object> condition) {
554
// Record individual evaluation metrics
555
meterRegistry.counter("awaitility.evaluations.total",
556
"condition", condition.getDescription(),
557
"result", String.valueOf(condition.isSatisfied()))
558
.increment();
559
}
560
561
@Override
562
public void onTimeout(TimeoutEvent timeoutEvent) {
563
Timer.Sample sample = samples.remove(timeoutEvent.getDescription());
564
if (sample != null) {
565
sample.stop(awaitTimer.tag("result", "timeout"));
566
}
567
568
meterRegistry.counter("awaitility.timeouts.total",
569
"condition", timeoutEvent.getDescription())
570
.increment();
571
}
572
});
573
}
574
}
575
```