From 4a7fbfe19cdc269b3b197c736ecce4395b39e1e3 Mon Sep 17 00:00:00 2001 From: Peter Somogyvari Date: Tue, 12 Jan 2021 14:12:22 -0800 Subject: [PATCH] feat(test-tooling): containers#getById and #waitForHealthCheck Adds two utility functions to the class called Containers: 1. public static async waitForHealthCheck(containerId: string, timeoutMs: number = 180000): Promise Awaits until a container identified by the containerId parameter becomes healthy. 2. public static async getById(containerId: string): Promise Utility method to obtain the ContainerInfo typed object from the dockerode library that contains the status information of the container among other things. Fixes #471 Signed-off-by: Peter Somogyvari (cherry picked from commit f52626e268e732ced7441dafc1e9c75024aa4798) Signed-off-by: Peter Somogyvari --- .../src/main/typescript/common/containers.ts | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/packages/cactus-test-tooling/src/main/typescript/common/containers.ts b/packages/cactus-test-tooling/src/main/typescript/common/containers.ts index 80bc8a01db..5ce51b3aa3 100644 --- a/packages/cactus-test-tooling/src/main/typescript/common/containers.ts +++ b/packages/cactus-test-tooling/src/main/typescript/common/containers.ts @@ -271,4 +271,50 @@ export class Containers { } }); } + + public static async getById(containerId: string): Promise { + const fnTag = `Containers#getById()`; + + Checks.nonBlankString(containerId, `${fnTag}:containerId`); + + const docker = new Dockerode(); + const containerInfos = await docker.listContainers({}); + const aContainerInfo = containerInfos.find((ci) => ci.Id === containerId); + + if (aContainerInfo) { + return aContainerInfo; + } else { + throw new Error(`${fnTag} no container by ID"${containerId}"`); + } + } + + /** + * Awaits until a container identified by the containerId + * parameter becomes healthy. + * @param containerId The ID of the container to wait for the healthy status. + * @param timeoutMs How much (in milliseconds) do we wait before giving up. + */ + public static async waitForHealthCheck( + containerId: string, + timeoutMs: number = 180000 + ): Promise { + const fnTag = "Containers#waitForHealthCheck()"; + + Checks.nonBlankString(containerId, `${fnTag}:containerId`); + + const startedAt = Date.now(); + let reachable: boolean = false; + do { + try { + const { Status } = await Containers.getById(containerId); + reachable = Status.endsWith(" (healthy)"); + } catch (ex) { + reachable = false; + if (Date.now() >= startedAt + timeoutMs) { + throw new Error(`${fnTag} timed out (${timeoutMs}ms) -> ${ex.stack}`); + } + } + await new Promise((resolve2) => setTimeout(resolve2, 1000)); + } while (!reachable); + } }