Skip to content

Commit ca2ea4e

Browse files
committed
Add support for reusing stopped containers
1 parent 08da47b commit ca2ea4e

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

packages/testcontainers/src/container-runtime/clients/container/docker-container-client.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ export class DockerContainerClient implements ContainerClient {
3535
const containers = await this.dockerode.listContainers({
3636
limit: 1,
3737
filters: {
38-
status: ["running"],
3938
label: [`${labelName}=${labelValue}`],
4039
},
4140
});

packages/testcontainers/src/generic-container/generic-container.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,11 @@ export class GenericContainer implements TestContainer {
130130
private async reuseContainer(client: ContainerRuntimeClient, container: Container) {
131131
const inspectResult = await client.container.inspect(container);
132132
const mappedInspectResult = mapInspectResult(inspectResult);
133+
if (!mappedInspectResult.state.running) {
134+
log.debug("Reused container is not running, attempting to start it");
135+
await client.container.start(container);
136+
}
137+
133138
const boundPorts = BoundPorts.fromInspectResult(client.info.containerRuntime.hostIps, mappedInspectResult).filter(
134139
this.exposedPorts
135140
);

packages/testcontainers/src/utils/map-inspect-result.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ export function mapInspectResult(inspectResult: ContainerInspectInfo): InspectRe
77
return {
88
name: inspectResult.Name,
99
hostname: inspectResult.Config.Hostname,
10-
ports: mapPorts(inspectResult),
10+
ports: {
11+
...mapHostConfigPortBindings(inspectResult),
12+
...mapPorts(inspectResult),
13+
},
1114
healthCheckStatus: mapHealthCheckStatus(inspectResult),
1215
networkSettings: mapNetworkSettings(inspectResult),
1316
state: {
@@ -20,6 +23,27 @@ export function mapInspectResult(inspectResult: ContainerInspectInfo): InspectRe
2023
};
2124
}
2225

26+
type HostConfigPortBindings = {
27+
[port: string]: Array<{
28+
HostIp: string;
29+
HostPort: string;
30+
}>;
31+
};
32+
33+
function mapHostConfigPortBindings(inspectInfo: ContainerInspectInfo): Ports {
34+
return Object.entries(inspectInfo.HostConfig.PortBindings as HostConfigPortBindings)
35+
.filter(([, hostPorts]) => hostPorts !== null)
36+
.map(([containerPort, hostPorts]) => {
37+
return {
38+
[parseInt(containerPort)]: hostPorts.map((hostPort) => ({
39+
hostIp: hostPort.HostIp,
40+
hostPort: parseInt(hostPort.HostPort),
41+
})),
42+
};
43+
})
44+
.reduce((acc, curr) => ({ ...acc, ...curr }), {});
45+
}
46+
2347
function mapPorts(inspectInfo: ContainerInspectInfo): Ports {
2448
return Object.entries(inspectInfo.NetworkSettings.Ports)
2549
.filter(([, hostPorts]) => hostPorts !== null)

0 commit comments

Comments
 (0)