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

153 lines 6.71 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DockerComposeEnvironment = void 0; const common_1 = require("../common"); const container_runtime_1 = require("../container-runtime"); const started_generic_container_1 = require("../generic-container/started-generic-container"); const reaper_1 = require("../reaper/reaper"); const bound_ports_1 = require("../utils/bound-ports"); const map_inspect_result_1 = require("../utils/map-inspect-result"); const pull_policy_1 = require("../utils/pull-policy"); const wait_1 = require("../wait-strategies/wait"); const wait_for_container_1 = require("../wait-strategies/wait-for-container"); const started_docker_compose_environment_1 = require("./started-docker-compose-environment"); class DockerComposeEnvironment { composeFilePath; composeFiles; projectName; build = false; recreate = true; environmentFile = ""; profiles = []; environment = {}; pullPolicy = pull_policy_1.PullPolicy.defaultPolicy(); defaultWaitStrategy = wait_1.Wait.forListeningPorts(); waitStrategy = {}; startupTimeout; constructor(composeFilePath, composeFiles, uuid = new common_1.RandomUuid()) { this.composeFilePath = composeFilePath; this.composeFiles = composeFiles; this.projectName = `testcontainers-${uuid.nextUuid()}`; } withBuild() { this.build = true; return this; } withEnvironment(environment) { this.environment = { ...this.environment, ...environment }; return this; } withEnvironmentFile(environmentFile) { this.environmentFile = environmentFile; return this; } withProfiles(...profiles) { this.profiles = [...this.profiles, ...profiles]; return this; } withNoRecreate() { this.recreate = false; this.projectName = "testcontainers-node"; return this; } withPullPolicy(pullPolicy) { this.pullPolicy = pullPolicy; return this; } withDefaultWaitStrategy(waitStrategy) { this.defaultWaitStrategy = waitStrategy; return this; } withWaitStrategy(containerName, waitStrategy) { this.waitStrategy[containerName] = waitStrategy; return this; } withStartupTimeout(startupTimeout) { this.startupTimeout = startupTimeout; return this; } withProjectName(projectName) { this.projectName = projectName; return this; } async up(services) { common_1.log.info(`Starting DockerCompose environment "${this.projectName}"...`); const client = await (0, container_runtime_1.getContainerRuntimeClient)(); const reaper = await (0, reaper_1.getReaper)(client); reaper.addComposeProject(this.projectName); const options = { filePath: this.composeFilePath, files: this.composeFiles, projectName: this.projectName, }; const commandOptions = []; if (this.build) { commandOptions.push("--build"); } if (!this.recreate) { commandOptions.push("--no-recreate"); } const composeOptions = []; if (this.environmentFile) { composeOptions.push("--env-file", this.environmentFile); } this.profiles.forEach((profile) => composeOptions.push("--profile", profile)); if (this.pullPolicy.shouldPull()) { await client.compose.pull(options, services); } await client.compose.up({ ...options, commandOptions, composeOptions, environment: { ...this.environment }, }, services); const startedContainers = (await client.container.list()).filter((container) => container.Labels["com.docker.compose.project"] === this.projectName); const startedContainerNames = startedContainers.reduce((containerNames, startedContainer) => [ ...containerNames, startedContainer.Names.join(", "), ], []); common_1.log.info(`Started containers "${startedContainerNames.join('", "')}"`); const startedGenericContainers = (await Promise.all(startedContainers.map(async (startedContainer) => { const container = client.container.getById(startedContainer.Id); const containerName = (0, container_runtime_1.parseComposeContainerName)(this.projectName, startedContainer.Names[0]); const inspectResult = await client.container.inspect(container); const mappedInspectResult = (0, map_inspect_result_1.mapInspectResult)(inspectResult); const boundPorts = bound_ports_1.BoundPorts.fromInspectResult(client.info.containerRuntime.hostIps, mappedInspectResult); const waitStrategy = this.waitStrategy[containerName] ? this.waitStrategy[containerName] : this.defaultWaitStrategy; if (this.startupTimeout !== undefined) { waitStrategy.withStartupTimeout(this.startupTimeout); } if (common_1.containerLog.enabled()) { (await client.container.logs(container)) .on("data", (data) => common_1.containerLog.trace(`${containerName}: ${data.trim()}`)) .on("err", (data) => common_1.containerLog.error(`${containerName}: ${data.trim()}`)); } try { await (0, wait_for_container_1.waitForContainer)(client, container, waitStrategy, boundPorts); } catch (err) { try { await client.compose.down(options, { removeVolumes: true, timeout: 0 }); } catch { common_1.log.warn(`Failed to stop DockerCompose environment after failed up`); } throw err; } return new started_generic_container_1.StartedGenericContainer(container, client.info.containerRuntime.host, inspectResult, boundPorts, containerName, waitStrategy, true); }))).reduce((map, startedGenericContainer) => { const containerName = startedGenericContainer.getName(); return { ...map, [containerName]: startedGenericContainer }; }, {}); common_1.log.info(`DockerCompose environment started`); return new started_docker_compose_environment_1.StartedDockerComposeEnvironment(startedGenericContainers, { ...options, composeOptions, environment: this.environment, }); } } exports.DockerComposeEnvironment = DockerComposeEnvironment; //# sourceMappingURL=docker-compose-environment.js.map