UNPKG

testcontainers

Version:

Testcontainers is a NodeJS library that supports tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container

145 lines 5.25 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.HttpWaitStrategy = void 0; const undici_1 = require("undici"); const common_1 = require("../common"); const container_runtime_1 = require("../container-runtime"); const wait_strategy_1 = require("./wait-strategy"); class HttpWaitStrategy extends wait_strategy_1.AbstractWaitStrategy { path; port; options; protocol = "http"; method = "GET"; headers = {}; predicates = []; _allowInsecure = false; readTimeout = 1000; constructor(path, port, options) { super(); this.path = path; this.port = port; this.options = options; } forStatusCode(statusCode) { this.predicates.push(async (response) => response.status === statusCode); return this; } forStatusCodeMatching(predicate) { this.predicates.push(async (response) => predicate(response.status)); return this; } forResponsePredicate(predicate) { this.predicates.push(async (response) => predicate(await response.text())); return this; } withMethod(method) { this.method = method; return this; } withHeaders(headers) { this.headers = { ...this.headers, ...headers }; return this; } withBasicCredentials(username, password) { const base64Encoded = Buffer.from(`${username}:${password}`).toString("base64"); this.headers = { ...this.headers, Authorization: `Basic ${base64Encoded}` }; return this; } withReadTimeout(readTimeout) { this.readTimeout = readTimeout; return this; } usingTls() { this.protocol = "https"; return this; } allowInsecure() { this._allowInsecure = true; return this; } async waitUntilReady(container, boundPorts) { common_1.log.debug(`Waiting for HTTP...`, { containerId: container.id }); const exitStatus = "exited"; let containerExited = false; const client = await (0, container_runtime_1.getContainerRuntimeClient)(); const { abortOnContainerExit } = this.options; await new common_1.IntervalRetry(this.readTimeout).retryUntil(async () => { try { const url = `${this.protocol}://${client.info.containerRuntime.host}:${boundPorts.getBinding(this.port)}${this.path}`; if (abortOnContainerExit) { const containerStatus = (await client.container.inspect(container)).State.Status; if (containerStatus === exitStatus) { containerExited = true; return; } } return await fetch(url, { method: this.method, signal: AbortSignal.timeout(this.readTimeout), headers: this.headers, dispatcher: this.getAgent(), }); } catch { return undefined; } }, async (response) => { if (abortOnContainerExit && containerExited) { return true; } if (response === undefined) { return false; } else if (!this.predicates.length) { return response.ok; } else { for (const predicate of this.predicates) { const result = await predicate(response); if (!result) { return false; } } return true; } }, () => { const message = `URL ${this.path} not accessible after ${this.startupTimeout}ms`; common_1.log.error(message, { containerId: container.id }); throw new Error(message); }, this.startupTimeout); if (abortOnContainerExit && containerExited) { return this.handleContainerExit(container); } common_1.log.debug(`HTTP wait strategy complete`, { containerId: container.id }); } async handleContainerExit(container) { const tail = 50; const lastLogs = []; const client = await (0, container_runtime_1.getContainerRuntimeClient)(); let message; try { const stream = await client.container.logs(container, { tail }); await new Promise((res) => { stream.on("data", (d) => lastLogs.push(d.trim())).on("end", res); }); message = `Container exited during HTTP healthCheck, last ${tail} logs: ${lastLogs.join("\n")}`; } catch (err) { message = "Container exited during HTTP healthCheck, failed to get last logs"; } common_1.log.error(message, { containerId: container.id }); throw new Error(message); } getAgent() { if (this._allowInsecure) { return new undici_1.Agent({ connect: { rejectUnauthorized: false, }, }); } } } exports.HttpWaitStrategy = HttpWaitStrategy; //# sourceMappingURL=http-wait-strategy.js.map