diff --git a/packages/testcontainers/src/wait-strategies/health-check-wait-strategy.ts b/packages/testcontainers/src/wait-strategies/health-check-wait-strategy.ts index ced92d562..bc2bad018 100644 --- a/packages/testcontainers/src/wait-strategies/health-check-wait-strategy.ts +++ b/packages/testcontainers/src/wait-strategies/health-check-wait-strategy.ts @@ -1,47 +1,31 @@ import Dockerode from "dockerode"; import { AbstractWaitStrategy } from "./wait-strategy"; -import { log } from "../common"; +import { IntervalRetry, log } from "../common"; import { getContainerRuntimeClient } from "../container-runtime"; export class HealthCheckWaitStrategy extends AbstractWaitStrategy { public async waitUntilReady(container: Dockerode.Container): Promise { log.debug(`Waiting for health check...`, { containerId: container.id }); - const client = await getContainerRuntimeClient(); - const containerEvents = await client.container.events(container, ["health_status"]); - return new Promise((resolve, reject) => { - const timeout = setTimeout(() => { - const message = `Health check not healthy after ${this.startupTimeout}ms`; + const status = await new IntervalRetry(100).retryUntil( + async () => (await client.container.inspect(container)).State.Health?.Status, + (healthCheckStatus) => healthCheckStatus === "healthy" || healthCheckStatus === "unhealthy", + () => { + const timeout = this.startupTimeout; + const message = `Health check not healthy after ${timeout}ms`; log.error(message, { containerId: container.id }); - containerEvents.destroy(); - reject(new Error(message)); - }, this.startupTimeout); - - const onTerminalState = () => { - clearTimeout(timeout); - containerEvents.destroy(); - log.debug(`Health check wait strategy complete`, { containerId: container.id }); - }; - - containerEvents.on("data", (data) => { - const parsedData = JSON.parse(data); + throw new Error(message); + }, + this.startupTimeout + ); - const status = - parsedData.status.split(":").length === 2 - ? parsedData.status.split(":")[1].trim() // Docker - : parsedData.HealthStatus; // Podman + if (status !== "healthy") { + const message = `Health check failed: ${status}`; + log.error(message, { containerId: container.id }); + throw new Error(message); + } - if (status === "healthy") { - resolve(); - onTerminalState(); - } else if (status === "unhealthy") { - const message = `Health check failed: ${status}`; - log.error(message, { containerId: container.id }); - reject(new Error(message)); - onTerminalState(); - } - }); - }); + log.debug(`Health check wait strategy complete`, { containerId: container.id }); } }