Skip to content

Instantly share code, notes, and snippets.

@elierotenberg
Created August 15, 2019 07:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elierotenberg/52bf8985dc7b34c6a7297c84f4b7a96a to your computer and use it in GitHub Desktop.
Save elierotenberg/52bf8985dc7b34c6a7297c84f4b7a96a to your computer and use it in GitHub Desktop.
Docker Compose TestUtils
interface IDockerComposeProps {
cwd?: string;
dockerComposeFile: string;
}
class DockerCompose {
private readonly props: IDockerComposeProps;
private state: "unknown" | "pending-up" | "up" | "pending-down" | "down";
public constructor(props: IDockerComposeProps) {
this.props = props;
this.state = "unknown";
}
public readonly down = async () => {
ok(
this.state === "unknown" || this.state === "up",
`Invalid state: ${this.state}`,
);
this.state = "pending-down";
const cwd = this.props.cwd || process.cwd();
const cmd = `docker-compose -f ${this.props.dockerComposeFile.replace(
/ /g,
"\\ ",
)} down`;
return await new Promise((resolve, reject) => {
const childProcess = exec(
cmd,
{
cwd,
},
(error, _stdout, _stderr) => {
if (error) {
this.state = "unknown";
return reject(error);
}
this.state = "down";
return resolve();
},
);
childProcess.on("error", error => {
reject(error);
});
});
};
public readonly up = async (): Promise<void> => {
ok(this.state === "down", `Invalid state: ${this.state}`);
this.state = "pending-up";
return await new Promise((resolve, reject) => {
const childProcess = spawn(
"docker-compose",
"-f docker-compose.test.yml up --build".split(" "),
{
cwd: this.props.cwd || process.cwd(),
},
);
let readyForStartup = false;
// Declare both in the same statement to avoid use-before-declare
const [onStdOutChunk, onError] = [
(chunk: Buffer): void => {
const data = chunk.toString("utf8");
if (data.includes("ready for start up")) {
readyForStartup = true;
}
if (readyForStartup && data.includes("ready to accept connections")) {
childProcess.off("error", onError);
childProcess.stdout.off("data", onStdOutChunk);
this.state = "up";
resolve();
}
},
(error: unknown): void => {
childProcess.off("error", onError);
childProcess.stdout.off("data", onStdOutChunk);
this.state = "unknown";
reject(error);
},
];
childProcess.on("error", onError);
childProcess.stdout.on("data", onStdOutChunk);
});
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment