feat: add waitForLog to docker container

This commit is contained in:
2024-07-19 17:13:43 +02:00
parent 82635f71ff
commit 7ee495f879
10 changed files with 1618 additions and 33 deletions

24
.eslint/eslint.config.mjs Normal file
View File

@@ -0,0 +1,24 @@
import simpleImportSort from "eslint-plugin-simple-import-sort";
import tseslint from "typescript-eslint";
export default [
...tseslint.configs.recommended,
{
plugins: {
"simple-import-sort": simpleImportSort,
},
rules: {
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error",
},
},
{
files: ["**/*.ts"],
rules: {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unused-vars": ["error", {
argsIgnorePattern: "^_",
}],
},
},
];

1502
.eslint/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

11
.eslint/package.json Normal file
View File

@@ -0,0 +1,11 @@
{
"type": "module",
"devDependencies": {
"eslint": "9.7.0",
"eslint-plugin-simple-import-sort": "12.1.1",
"typescript-eslint": "7.16.0"
},
"overrides": {
"eslint": "9.7.0"
}
}

View File

@@ -15,13 +15,26 @@ jobs:
- uses: actions/checkout@v3
- name: Setup Deno
uses: maximousblk/setup-deno@v2 # Installs latest version
uses: maximousblk/setup-deno@v2
- run: deno task test
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.JS
uses: actions/setup-node@v4
with:
node-version: 20
- run: cd .eslint && npm ci
- run: deno task lint
publish:
runs-on: ubuntu-latest
needs: test
needs: [lint, test]
permissions:
contents: read

View File

@@ -1,10 +1,10 @@
name: Test
on:
push:
pull_request:
branches:
- main
pull_request:
push:
branches:
- main
@@ -15,6 +15,19 @@ jobs:
- uses: actions/checkout@v3
- name: Setup Deno
uses: maximousblk/setup-deno@v2 # Installs latest version
uses: maximousblk/setup-deno@v2
- run: deno task test
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.JS
uses: actions/setup-node@v4
with:
node-version: 20
- run: cd .eslint && npm ci
- run: deno task lint

12
.vscode/settings.json vendored
View File

@@ -1,5 +1,15 @@
{
"deno.enable": true,
"deno.lint": true,
"eslint.nodePath": "./.eslint/node_modules",
"eslint.options": {
"overrideConfigFile": "./.eslint/eslint.config.mjs"
},
"editor.formatOnSave": true,
"editor.defaultFormatter": "denoland.vscode-deno"
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"[typescript]": {
"editor.defaultFormatter": "denoland.vscode-deno"
}
}

View File

@@ -68,13 +68,9 @@ export class PostgresTestContainer {
});
await container.start();
await container.logs((line) => {
if (line.includes("init process complete")) {
return true;
}
});
await container.waitForLog("database system is ready");
await delay(1000);
await delay(250);
return new PostgresTestContainer(container, port, {
username: config.username ?? "postgres",

View File

@@ -1,6 +1,6 @@
{
"name": "@valkyr/testcontainers",
"version": "1.0.0",
"version": "1.0.1",
"exports": {
"./postgres": "./containers/postgres.ts"
},
@@ -25,6 +25,7 @@
"lineWidth": 120
},
"tasks": {
"lint": "npx eslint -c .eslint/eslint.config.mjs .",
"test": "export ENVIRONMENT=testing && deno test --allow-all --unstable-ffi"
}
}

View File

@@ -64,23 +64,18 @@ export class Container {
*
* @see https://docs.docker.com/engine/api/v1.45/#tag/Container/operation/ContainerLogs
*
* @param handler - Function to handle each line of the logs.
* @param query - Query parameters to send to the request
*/
async logs(handler: (line: string) => true | void) {
const res = await modem.request({
method: "GET",
path: `/containers/${this.id}/logs`,
query: {
stdout: true,
follow: true,
tail: "all",
},
});
for await (const chunk of res.stream) {
if (handler(chunk) === true) {
break;
}
}
async logs(query: {
follow?: boolean;
stdout?: boolean;
stderr?: boolean;
since?: number;
until?: number;
timestamps?: boolean;
tail?: number | "all";
} = {}) {
return modem.request({ method: "GET", path: `/containers/${this.id}/logs`, query });
}
/**
@@ -103,6 +98,26 @@ export class Container {
});
await new Exec(Id).start();
}
/**
* Waits for a specific log value to occur on the container within the given
* timeout limit.
*
* @param value - Value to look for.
* @param timeout - Time limit producing an error if exceeded.
*/
async waitForLog(value: string, timeout = 5_000): Promise<void> {
const response = await this.logs({ follow: true, stdout: true, stderr: true });
const timer = setTimeout(() => {
throw new Error("Timed out waiting for log result");
}, timeout);
for await (const chunk of response.stream) {
if (chunk.includes(value)) {
clearTimeout(timer);
break;
}
}
}
}
/*

View File

@@ -1,7 +1,7 @@
import type { ContainerConfig } from "../types/container.ts";
import { modem } from "./modem.ts";
import { Container } from "./container.ts";
import { Image } from "./image.ts";
import { modem } from "./modem.ts";
export class Docker {
/**