0
# Wait Strategies
1
2
Flexible container readiness detection system providing multiple built-in strategies and extensibility for custom waiting logic. Wait strategies determine when containers are ready to accept connections or perform work.
3
4
## Capabilities
5
6
### Wait Factory
7
8
Factory class providing static methods for creating common wait strategies with sensible defaults.
9
10
```java { .api }
11
/**
12
* Factory class for creating wait strategies with convenient static methods
13
*/
14
public class Wait {
15
16
/** Default wait strategy - waits for first exposed port to be listening */
17
public static WaitStrategy defaultWaitStrategy();
18
19
/** Wait for default exposed port to be listening */
20
public static HostPortWaitStrategy forListeningPort();
21
22
/** Wait for specific ports to be listening */
23
public static HostPortWaitStrategy forListeningPorts(int... ports);
24
25
/** Wait for HTTP endpoint to return successful response */
26
public static HttpWaitStrategy forHttp(String path);
27
28
/** Wait for HTTPS endpoint to return successful response */
29
public static HttpWaitStrategy forHttps(String path);
30
31
/** Wait for specific log message to appear in container output */
32
public static LogMessageWaitStrategy forLogMessage(String regEx, int times);
33
34
/** Wait for Docker HEALTHCHECK to report healthy status */
35
public static DockerHealthcheckWaitStrategy forHealthcheck();
36
37
/** Wait for shell command to execute successfully */
38
public static ShellStrategy forSuccessfulCommand(String command);
39
40
/** Composite strategy waiting for all specified conditions */
41
public static WaitAllStrategy forAll(WaitStrategy... waitStrategies);
42
public static WaitAllStrategy forAll(Collection<WaitStrategy> waitStrategies);
43
}
44
```
45
46
**Usage Examples:**
47
48
```java
49
import org.testcontainers.containers.wait.strategy.Wait;
50
51
// Wait for HTTP endpoint
52
container.waitingFor(Wait.forHttp("/health").forStatusCode(200));
53
54
// Wait for multiple ports
55
container.waitingFor(Wait.forListeningPorts(8080, 8081));
56
57
// Wait for log message
58
container.waitingFor(Wait.forLogMessage(".*Server started.*", 1));
59
60
// Wait for Docker healthcheck
61
container.waitingFor(Wait.forHealthcheck());
62
63
// Composite waiting - all conditions must be met
64
container.waitingFor(Wait.forAll(
65
Wait.forListeningPort(),
66
Wait.forLogMessage(".*Ready.*", 1)
67
));
68
```
69
70
### WaitStrategy Interface
71
72
Base interface for all wait strategy implementations providing common configuration options.
73
74
```java { .api }
75
/**
76
* Base interface for container readiness detection strategies
77
*/
78
public interface WaitStrategy {
79
80
/**
81
* Wait until the container is ready according to this strategy
82
* @param waitStrategyTarget Container to wait for
83
*/
84
void waitUntilReady(WaitStrategyTarget waitStrategyTarget);
85
86
/**
87
* Configure maximum time to wait before timing out
88
* @param startupTimeout Maximum wait duration
89
* @return This strategy for method chaining
90
*/
91
WaitStrategy withStartupTimeout(Duration startupTimeout);
92
}
93
```
94
95
### Host Port Wait Strategy
96
97
Waits for container ports to be listening and accepting connections.
98
99
```java { .api }
100
/**
101
* Wait strategy that waits for ports to be listening
102
*/
103
public class HostPortWaitStrategy extends AbstractWaitStrategy {
104
105
public HostPortWaitStrategy();
106
107
/** Configure specific ports to wait for (overrides container exposed ports) */
108
public HostPortWaitStrategy forPorts(int... ports);
109
110
/** Configure custom port binding check interval */
111
public HostPortWaitStrategy withRateLimiter(RateLimiter rateLimiter);
112
113
@Override
114
public void waitUntilReady(WaitStrategyTarget waitStrategyTarget);
115
}
116
```
117
118
### HTTP Wait Strategy
119
120
Waits for HTTP/HTTPS endpoints to return expected responses with extensive configuration options.
121
122
```java { .api }
123
/**
124
* Wait strategy for HTTP/HTTPS endpoints with extensive configuration
125
*/
126
public class HttpWaitStrategy extends AbstractWaitStrategy {
127
128
public HttpWaitStrategy();
129
130
/** Configure the endpoint path to check */
131
public HttpWaitStrategy forPath(String path);
132
133
/** Configure expected HTTP status code (default: 200) */
134
public HttpWaitStrategy forStatusCode(int statusCode);
135
136
/** Configure expected status codes */
137
public HttpWaitStrategy forStatusCodeMatching(Predicate<Integer> statusCodePredicate);
138
139
/** Configure expected response body content */
140
public HttpWaitStrategy forResponsePredicate(Predicate<String> responsePredicate);
141
142
/** Configure specific port to check (overrides container exposed port) */
143
public HttpWaitStrategy forPort(int port);
144
145
/** Use HTTPS instead of HTTP */
146
public HttpWaitStrategy usingTls();
147
148
/** Allow self-signed certificates */
149
public HttpWaitStrategy allowInsecure();
150
151
/** Configure HTTP method (default: GET) */
152
public HttpWaitStrategy withMethod(String method);
153
154
/** Configure custom HTTP headers */
155
public HttpWaitStrategy withHeader(String name, String value);
156
157
/** Configure HTTP basic authentication */
158
public HttpWaitStrategy withBasicCredentials(String username, String password);
159
160
/** Configure custom read timeout */
161
public HttpWaitStrategy withReadTimeout(Duration readTimeout);
162
163
@Override
164
public void waitUntilReady(WaitStrategyTarget waitStrategyTarget);
165
}
166
```
167
168
**Usage Examples:**
169
170
```java
171
// Advanced HTTP wait configuration
172
HttpWaitStrategy httpWait = Wait.forHttp("/api/health")
173
.forStatusCode(200)
174
.forResponsePredicate(response -> response.contains("healthy"))
175
.withMethod("GET")
176
.withHeader("Accept", "application/json")
177
.withBasicCredentials("admin", "password")
178
.withReadTimeout(Duration.ofSeconds(10))
179
.withStartupTimeout(Duration.ofMinutes(2));
180
181
container.waitingFor(httpWait);
182
```
183
184
### Log Message Wait Strategy
185
186
Waits for specific log messages to appear in container output using regex patterns.
187
188
```java { .api }
189
/**
190
* Wait strategy that waits for specific log messages using regex patterns
191
*/
192
public class LogMessageWaitStrategy extends AbstractWaitStrategy {
193
194
public LogMessageWaitStrategy();
195
196
/** Configure regex pattern and occurrence count */
197
public static LogMessageWaitStrategy waitingFor(String regEx, int times);
198
199
/** Configure regex pattern (waits for single occurrence) */
200
public static LogMessageWaitStrategy waitingFor(String regEx);
201
202
/** Configure number of times the pattern should match */
203
public LogMessageWaitStrategy times(int times);
204
205
@Override
206
public void waitUntilReady(WaitStrategyTarget waitStrategyTarget);
207
}
208
```
209
210
### Docker Healthcheck Wait Strategy
211
212
Waits for Docker's built-in HEALTHCHECK to report healthy status.
213
214
```java { .api }
215
/**
216
* Wait strategy that uses Docker's HEALTHCHECK instruction
217
*/
218
public class DockerHealthcheckWaitStrategy extends AbstractWaitStrategy {
219
220
public DockerHealthcheckWaitStrategy();
221
222
@Override
223
public void waitUntilReady(WaitStrategyTarget waitStrategyTarget);
224
}
225
```
226
227
### Shell Command Wait Strategy
228
229
Waits for shell commands executed within the container to succeed.
230
231
```java { .api }
232
/**
233
* Wait strategy that executes shell commands within the container
234
*/
235
public class ShellStrategy extends AbstractWaitStrategy {
236
237
public ShellStrategy();
238
239
/** Configure the shell command to execute */
240
public static ShellStrategy waitingFor(String command);
241
242
@Override
243
public void waitUntilReady(WaitStrategyTarget waitStrategyTarget);
244
}
245
```
246
247
### Composite Wait Strategy
248
249
Combines multiple wait strategies, requiring all conditions to be satisfied.
250
251
```java { .api }
252
/**
253
* Composite wait strategy that waits for multiple conditions
254
*/
255
public class WaitAllStrategy extends AbstractWaitStrategy {
256
257
public WaitAllStrategy();
258
public WaitAllStrategy(Collection<WaitStrategy> waitStrategies);
259
260
/** Add wait strategies to the composite */
261
public WaitAllStrategy withStrategy(WaitStrategy waitStrategy);
262
263
@Override
264
public void waitUntilReady(WaitStrategyTarget waitStrategyTarget);
265
}
266
```
267
268
### Abstract Wait Strategy
269
270
Base implementation providing common functionality for wait strategies.
271
272
```java { .api }
273
/**
274
* Abstract base class for wait strategy implementations
275
*/
276
public abstract class AbstractWaitStrategy implements WaitStrategy {
277
278
protected Duration startupTimeout = Duration.ofSeconds(60);
279
280
@Override
281
public WaitStrategy withStartupTimeout(Duration startupTimeout);
282
283
/** Template method for subclass implementation */
284
public abstract void waitUntilReady(WaitStrategyTarget waitStrategyTarget);
285
286
/** Check if port is listening with rate limiting */
287
protected boolean isPortListening(WaitStrategyTarget waitStrategyTarget, int port);
288
289
/** Get rate limiter for polling operations */
290
protected RateLimiter getRateLimiter();
291
}
292
```
293
294
### Wait Strategy Target
295
296
Interface providing container information to wait strategies for readiness checking.
297
298
```java { .api }
299
/**
300
* Interface providing container information to wait strategies
301
*/
302
public interface WaitStrategyTarget {
303
304
/** Get host where container is running */
305
String getHost();
306
307
/** Get host port mapped to container port */
308
Integer getMappedPort(int originalPort);
309
310
/** Get list of exposed ports */
311
List<Integer> getExposedPorts();
312
313
/** Get container logs */
314
String getLogs();
315
316
/** Get logs of specific output types */
317
String getLogs(OutputFrame.OutputType... types);
318
319
/** Execute command within container */
320
Container.ExecResult execInContainer(String... command)
321
throws UnsupportedOperationException, IOException, InterruptedException;
322
323
/** Get container state information */
324
ContainerState getContainerInfo();
325
326
/** Get Docker container ID */
327
String getContainerId();
328
329
/** Get network aliases */
330
Set<String> getNetworkAliases();
331
332
/** Check if container is running */
333
boolean isRunning();
334
}
335
```
336
337
## Advanced Usage Patterns
338
339
### Custom Wait Strategies
340
341
Creating custom wait strategies by implementing the WaitStrategy interface:
342
343
```java
344
public class CustomWaitStrategy implements WaitStrategy {
345
private Duration timeout = Duration.ofMinutes(1);
346
347
@Override
348
public void waitUntilReady(WaitStrategyTarget target) {
349
// Custom readiness logic
350
Instant deadline = Instant.now().plus(timeout);
351
352
while (Instant.now().isBefore(deadline)) {
353
if (isReady(target)) {
354
return;
355
}
356
try {
357
Thread.sleep(1000);
358
} catch (InterruptedException e) {
359
Thread.currentThread().interrupt();
360
throw new RuntimeException(e);
361
}
362
}
363
throw new ContainerLaunchException("Container not ready within timeout");
364
}
365
366
@Override
367
public WaitStrategy withStartupTimeout(Duration timeout) {
368
this.timeout = timeout;
369
return this;
370
}
371
372
private boolean isReady(WaitStrategyTarget target) {
373
// Custom readiness check logic
374
return true;
375
}
376
}
377
```
378
379
### Combining Wait Strategies
380
381
```java
382
// Sequential waiting - each strategy must complete before the next
383
WaitStrategy combined = Wait.forAll(
384
Wait.forListeningPort(), // First wait for port
385
Wait.forLogMessage(".*Started.*", 1), // Then wait for log
386
Wait.forHttp("/health") // Finally check HTTP endpoint
387
);
388
389
container.waitingFor(combined);
390
```