Skip to content

Commit 744c5b9

Browse files
Handle case where container port does not exist in inspect result (#1036)
1 parent b1da3c6 commit 744c5b9

File tree

2 files changed

+17
-36
lines changed

2 files changed

+17
-36
lines changed

packages/testcontainers/src/generic-container/inspect-container-util-ports-exposed.test.ts

Lines changed: 16 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import { ContainerInspectInfo } from "dockerode";
2-
import { InspectResult } from "../types";
32
import { mapInspectResult } from "../utils/map-inspect-result";
43
import { inspectContainerUntilPortsExposed } from "./inspect-container-util-ports-exposed";
54

6-
function mockExposed(): { inspectResult: ContainerInspectInfo; mappedInspectResult: InspectResult } {
5+
function mockInspectResult(ports: ContainerInspectInfo["NetworkSettings"]["Ports"]) {
76
const date = new Date();
87

98
const inspectResult: ContainerInspectInfo = {
@@ -22,34 +21,7 @@ function mockExposed(): { inspectResult: ContainerInspectInfo; mappedInspectResu
2221
FinishedAt: date.toISOString(),
2322
},
2423
NetworkSettings: {
25-
Ports: { "8080/tcp": [{ HostIp: "0.0.0.0", HostPort: "45000" }] },
26-
Networks: {},
27-
},
28-
} as unknown as ContainerInspectInfo;
29-
30-
return { inspectResult, mappedInspectResult: mapInspectResult(inspectResult) };
31-
}
32-
33-
function mockNotExposed(): { inspectResult: ContainerInspectInfo; mappedInspectResult: InspectResult } {
34-
const date = new Date();
35-
36-
const inspectResult: ContainerInspectInfo = {
37-
Name: "container-id",
38-
Config: {
39-
Hostname: "hostname",
40-
Labels: {},
41-
},
42-
State: {
43-
Health: {
44-
Status: "healthy",
45-
},
46-
Status: "running",
47-
Running: true,
48-
StartedAt: date.toISOString(),
49-
FinishedAt: date.toISOString(),
50-
},
51-
NetworkSettings: {
52-
Ports: { "8080/tcp": [] },
24+
Ports: ports,
5325
Networks: {},
5426
},
5527
} as unknown as ContainerInspectInfo;
@@ -58,7 +30,7 @@ function mockNotExposed(): { inspectResult: ContainerInspectInfo; mappedInspectR
5830
}
5931

6032
test("returns the inspect results when all ports are exposed", async () => {
61-
const data = mockExposed();
33+
const data = mockInspectResult({ "8080/tcp": [{ HostIp: "0.0.0.0", HostPort: "45000" }] });
6234
const inspectFn = vi.fn().mockResolvedValueOnce(data.inspectResult);
6335

6436
const result = await inspectContainerUntilPortsExposed(inspectFn, [8080], "container-id");
@@ -67,8 +39,8 @@ test("returns the inspect results when all ports are exposed", async () => {
6739
});
6840

6941
test("retries the inspect if ports are not yet exposed", async () => {
70-
const data1 = mockNotExposed();
71-
const data2 = mockExposed();
42+
const data1 = mockInspectResult({ "8080/tcp": [] });
43+
const data2 = mockInspectResult({ "8080/tcp": [{ HostIp: "0.0.0.0", HostPort: "45000" }] });
7244
const inspectFn = vi
7345
.fn()
7446
.mockResolvedValueOnce(data1.inspectResult)
@@ -81,8 +53,17 @@ test("retries the inspect if ports are not yet exposed", async () => {
8153
expect(inspectFn).toHaveBeenCalledTimes(3);
8254
});
8355

84-
test("throws an error when ports are not exposed within timeout", async () => {
85-
const data = mockNotExposed();
56+
test("throws an error when host ports are not exposed within timeout", async () => {
57+
const data = mockInspectResult({ "8080/tcp": [] });
58+
const inspectFn = vi.fn().mockResolvedValue(data.inspectResult);
59+
60+
await expect(inspectContainerUntilPortsExposed(inspectFn, [8080], "container-id", 0)).rejects.toThrow(
61+
"Container did not expose all ports after starting"
62+
);
63+
});
64+
65+
test("throws an error when container ports not exposed within timeout", async () => {
66+
const data = mockInspectResult({});
8667
const inspectFn = vi.fn().mockResolvedValue(data.inspectResult);
8768

8869
await expect(inspectContainerUntilPortsExposed(inspectFn, [8080], "container-id", 0)).rejects.toThrow(

packages/testcontainers/src/generic-container/inspect-container-util-ports-exposed.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export async function inspectContainerUntilPortsExposed(
2424
({ mappedInspectResult }) =>
2525
ports
2626
.map((exposedPort) => getContainerPort(exposedPort))
27-
.every((exposedPort) => mappedInspectResult.ports[exposedPort].length > 0),
27+
.every((exposedPort) => mappedInspectResult.ports[exposedPort]?.length > 0),
2828
() => {
2929
const message = `Container did not expose all ports after starting`;
3030
log.error(message, { containerId });

0 commit comments

Comments
 (0)