Skip to content

Commit 6069d7b

Browse files
committed
add section in docs describing timeouts
1 parent 5ed1ceb commit 6069d7b

File tree

6 files changed

+61
-23
lines changed

6 files changed

+61
-23
lines changed

docs/features/advanced.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,35 @@
11
# Advanced
22

3+
## Timeout parameter of APIs
4+
5+
Testcontainers library provides a set of classes and functions, and some of them expect a parameter named `timeout`, `ms`, or similar to be passed from the caller. This parameters are of type `number`, and the unit of measurement for this parameters across all public APIs is the same: millisecond. For example:
6+
7+
```js
8+
export interface TestContainer {
9+
...
10+
withStartupTimeout(ms: number): this; // timeout expected to be passed as milliseconds
11+
}
12+
```
13+
14+
The underlying docker APIs may expect different units for timeouts and intervals, and testcontainers library will do the needed conversion under the hood automatically. For example, consider the `stop` method of a container:
15+
16+
```javascript
17+
const container = await new GenericContainer("alpine").start();
18+
await container.stop({ timeout: 10_000 }); // testcontainers library expects the timeout to be passed as milliseconds
19+
```
20+
21+
The Docker API [expects seconds](https://docs.docker.com/reference/api/engine/version/v1.48/#tag/Container/operation/ContainerStop) to be passed to this API call. The 10_000 ms value will be converted to seconds by testontainers library.
22+
23+
Keep in mind that conversion from ms to seconds uses truncation to integer, for example:
24+
25+
```
26+
5000ms = 5s
27+
3800ms = 3s
28+
500ms = 0s
29+
```
30+
31+
You may also pass a *negative* value to function parameters, but this may lead to unexpedted results.
32+
333
## Container Runtime Client
434

535
Testcontainers configures an underlying container runtime to perform its tasks. This runtime works automatically with several providers like Docker, Podman, Colima, Rancher Desktop and Testcontainers Desktop. There are too many usage examples to list here, but here are some common examples:

docs/features/compose.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,11 @@ const environment = await new DockerComposeEnvironment(composeFilePath, composeF
140140
await environment.down();
141141
```
142142

143-
If you need to wait for the environment to be downed, you can provide a timeout. The unit of timeout here is **second**:
143+
If you need to wait for the environment to be downed, you can provide a timeout:
144144

145145
```javascript
146146
const environment = await new DockerComposeEnvironment(composeFilePath, composeFile).up();
147-
await environment.down({ timeout: 10 }); // timeout after 10 seconds
147+
await environment.down({ timeout: 10_000 }); // 10 seconds
148148
```
149149

150150
Volumes created by the environment are removed when stopped. This is configurable:

docs/features/containers.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,11 +334,11 @@ const container = await new GenericContainer("alpine").start();
334334
await container.stop();
335335
```
336336

337-
If you need to wait for the container to be stopped, you can provide a timeout. The unit of timeout option here is **second**:
337+
If you need to wait for the container to be stopped, you can provide a timeout:
338338

339339
```javascript
340340
const container = await new GenericContainer("alpine").start();
341-
await container.stop({ timeout: 10 }); // 10 seconds
341+
await container.stop({ timeout: 10_000 }); // 10 seconds
342342
```
343343

344344
You can disable automatic removal of the container, which is useful for debugging, or if for example you want to copy content from the container once it has stopped:

docs/features/wait-strategies.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# Wait Strategies
22

3-
Note that the startup timeout of all wait strategies is configurable. The unit of timeout of wait strategies is **millisecond**:
3+
Note that the startup timeout of all wait strategies is configurable:
44

55
```javascript
66
const { GenericContainer } = require("testcontainers");
77

88
const container = await new GenericContainer("alpine")
9-
.withStartupTimeout(120000) // wait 120 seconds
9+
.withStartupTimeout(120_000) // 120 seconds
1010
.start();
1111
```
1212

@@ -73,18 +73,18 @@ const { GenericContainer, Wait } = require("testcontainers");
7373
const container = await new GenericContainer("alpine").withWaitStrategy(Wait.forHealthCheck()).start();
7474
```
7575

76-
Define your own health check. The unit of timeouts and intervals here is **millisecond**:
76+
Define your own health check:
7777

7878
```javascript
7979
const { GenericContainer, Wait } = require("testcontainers");
8080

8181
const container = await new GenericContainer("alpine")
8282
.withHealthCheck({
8383
test: ["CMD-SHELL", "curl -f http://localhost || exit 1"],
84-
interval: 1000,
85-
timeout: 3000,
84+
interval: 1000, // 1 second
85+
timeout: 3000, // 3 seconds
8686
retries: 5,
87-
startPeriod: 1000,
87+
startPeriod: 1000, // 1 second
8888
})
8989
.withWaitStrategy(Wait.forHealthCheck())
9090
.start();
@@ -148,7 +148,7 @@ const container = await new GenericContainer("redis")
148148
.withMethod("POST")
149149
.withHeaders({ X_CUSTOM_VALUE: "custom" })
150150
.withBasicCredentials("username", "password")
151-
.withReadTimeout(10000)) // timeout after 10 seconds
151+
.withReadTimeout(10_000)) // 10 seconds
152152
```
153153

154154
### Use TLS
@@ -186,7 +186,7 @@ This strategy is intended for use with containers that only run briefly and exit
186186
const { GenericContainer, Wait } = require("testcontainers");
187187

188188
const container = await new GenericContainer("alpine")
189-
.withWaitStrategy(Wait.forOneShotStartup()))
189+
.withWaitStrategy(Wait.forOneShotStartup())
190190
.start();
191191
```
192192

@@ -202,11 +202,11 @@ const container = await new GenericContainer("alpine")
202202
.start();
203203
```
204204

205-
The composite wait strategy by default will respect each individual wait strategy's startup timeout. The unit of timeouts here is **millisecond**. For example:
205+
The composite wait strategy by default will respect each individual wait strategy's startup timeout. For example:
206206

207207
```javascript
208-
const w1 = Wait.forListeningPorts().withStartupTimeout(1000); // wait 1 second
209-
const w2 = Wait.forLogMessage("READY").withStartupTimeout(2000); // wait 2 seconds
208+
const w1 = Wait.forListeningPorts().withStartupTimeout(1000); // 1 second
209+
const w2 = Wait.forLogMessage("READY").withStartupTimeout(2000); // 2 seconds
210210

211211
const composite = Wait.forAll([w1, w2]);
212212

@@ -217,21 +217,21 @@ expect(w2.getStartupTimeout()).toBe(2000);
217217
The startup timeout of inner wait strategies that have not defined their own startup timeout can be set by setting the startup timeout on the composite:
218218

219219
```javascript
220-
const w1 = Wait.forListeningPorts().withStartupTimeout(1000); // wait 1 second
220+
const w1 = Wait.forListeningPorts().withStartupTimeout(1000); // 1 second
221221
const w2 = Wait.forLogMessage("READY");
222222

223-
const composite = Wait.forAll([w1, w2]).withStartupTimeout(2000); // wait 2 seconds
223+
const composite = Wait.forAll([w1, w2]).withStartupTimeout(2000); // 2 seconds
224224

225225
expect(w1.getStartupTimeout()).toBe(1000);
226226
expect(w2.getStartupTimeout()).toBe(2000);
227227
```
228228

229-
The startup timeout of all wait strategies can be controlled by setting a deadline on the composite. In this case, the composite will throw unless all inner wait strategies have resolved before the deadline. The unit of deadline timeout is **millisecond**.
229+
The startup timeout of all wait strategies can be controlled by setting a deadline on the composite. In this case, the composite will throw unless all inner wait strategies have resolved before the deadline.
230230

231231
```javascript
232232
const w1 = Wait.forListeningPorts();
233233
const w2 = Wait.forLogMessage("READY");
234-
const composite = Wait.forAll([w1, w2]).withDeadline(2000); // wait 2 seconds
234+
const composite = Wait.forAll([w1, w2]).withDeadline(2000); // 2 seconds
235235
```
236236

237237
## Other startup strategies

packages/testcontainers/src/common/ms.test.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { Ms } from "./ms";
22

33
describe("Ms", () => {
4-
it.for([[10_000, 10_000]])("should return %i ms from %i ms", ([ms1, ms2]) => {
4+
it.for([
5+
[10_000, 10_000],
6+
[-1000, -1000],
7+
[0, 0],
8+
])("should return %i ms from %i ms", ([ms1, ms2]) => {
59
const t = new Ms(ms1);
610
expect(t.value()).toEqual(ms2);
711
});
@@ -12,13 +16,19 @@ describe("Ms", () => {
1216
[1010, 1],
1317
[1999, 1],
1418
[10_000, 10],
19+
[-10, -0],
20+
[-999, -0],
21+
[-1010, -1],
22+
[-1999, -1],
23+
[-10_000, -10],
1524
])("should convert %i ms to %i seconds", ([ms, s]) => {
1625
const t = new Ms(ms);
1726
expect(t.seconds()).toEqual(s);
1827
});
1928
it.for([
2029
[0, 0],
2130
[1, 1_000_000],
31+
[-1, -1_000_000],
2232
])("should convert %i ms to %i ns", ([ms, ns]) => {
2333
const t = new Ms(ms);
2434
expect(t.nanos()).toEqual(ns);

packages/testcontainers/src/common/ms.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
* Represents time interval in milliseconds.
33
*/
44
export class Ms {
5-
constructor(private readonly milliseconds: number) {
6-
if (milliseconds < 0) throw new Error("Negative interval is not supported in this context.");
7-
}
5+
constructor(private readonly milliseconds: number) {}
86
public seconds(): number {
97
return Math.trunc(this.milliseconds * 1e-3);
108
}

0 commit comments

Comments
 (0)