90 lines
4.4 KiB
JavaScript
90 lines
4.4 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
import { describe, it } from "vitest";
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const rootDir = path.resolve(__dirname, "..");
|
|
|
|
const smokeScripts = [
|
|
"scripts/docker-web-runtime-smoke.sh",
|
|
"scripts/docker-api-runtime-smoke.sh",
|
|
"scripts/docker-worker-runtime-smoke.sh",
|
|
];
|
|
|
|
describe("Docker runtime smoke contract", () => {
|
|
it.each(smokeScripts)("reads the expected revision from the built image label: %s", (relativePath) => {
|
|
const source = fs.readFileSync(path.join(rootDir, relativePath), "utf8");
|
|
|
|
assert.match(source, /docker image inspect -f '\{\{ index \.Config\.Labels "org\.opencontainers\.image\.revision" \}\}' "\$IMAGE"/);
|
|
assert.match(source, /SMOKE_REVISION="\$\(resolve_smoke_revision\)"/);
|
|
});
|
|
|
|
it.each(smokeScripts)("rejects Dockerfile's default unknown revision: %s", (relativePath) => {
|
|
const source = fs.readFileSync(path.join(rootDir, relativePath), "utf8");
|
|
|
|
assert.match(source, /\$SMOKE_REVISION" == "unknown"/);
|
|
assert.match(source, /does not expose a concrete org\.opencontainers\.image\.revision/);
|
|
});
|
|
|
|
it.each(smokeScripts)("does not override APP_REVISION at container runtime: %s", (relativePath) => {
|
|
const source = fs.readFileSync(path.join(rootDir, relativePath), "utf8");
|
|
|
|
assert.doesNotMatch(source, /-e APP_REVISION=/);
|
|
});
|
|
|
|
it.each(["scripts/docker-web-runtime-smoke.sh", "scripts/docker-api-runtime-smoke.sh"])("validates the runtime OpenAPI JSON contract: %s", (relativePath) => {
|
|
const source = fs.readFileSync(path.join(rootDir, relativePath), "utf8");
|
|
|
|
assert.match(source, /expect_openapi_json/);
|
|
assert.match(source, /\/v1\/openapi\.json/);
|
|
assert.match(source, /payload\.paths\["\/v1\/entities\/\{entity\}\/rows"\]/);
|
|
assert.doesNotMatch(source, /payload\.paths\["\/v1\/workflows\/run\/\{id\}"\]/);
|
|
});
|
|
|
|
it("runs the Coolify web predeploy command inside the final web image", () => {
|
|
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-web-runtime-smoke.sh"), "utf8");
|
|
|
|
assert.match(source, /docker run --rm --network "\$NETWORK_NAME"/);
|
|
assert.match(source, /--entrypoint \/bin\/sh/);
|
|
assert.match(source, /pnpm exec prisma migrate deploy --config prisma\.config\.ts/);
|
|
assert.match(source, /NODE_ENV=production node packages\/db\/dist\/production-seed\.server\.js/);
|
|
assert.doesNotMatch(source, /DATABASE_URL="\$HOST_DATABASE_URL" pnpm exec prisma migrate deploy/);
|
|
});
|
|
|
|
it("runs the API smoke migration inside the final API image network", () => {
|
|
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-api-runtime-smoke.sh"), "utf8");
|
|
|
|
assert.match(source, /docker run --rm --network "\$NETWORK_NAME"/);
|
|
assert.match(source, /-e DATABASE_URL="\$CONTAINER_DATABASE_URL"/);
|
|
assert.match(source, /--entrypoint \/bin\/sh/);
|
|
assert.match(source, /pnpm exec prisma migrate deploy --config prisma\.config\.ts/);
|
|
assert.doesNotMatch(source, /HOST_DATABASE_URL/);
|
|
assert.doesNotMatch(source, /DATABASE_URL="\$HOST_DATABASE_URL" pnpm exec prisma migrate deploy/);
|
|
});
|
|
|
|
it("runs the worker smoke migration inside the final worker image network", () => {
|
|
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-worker-runtime-smoke.sh"), "utf8");
|
|
|
|
assert.match(source, /docker run --rm --network "\$NETWORK_NAME"/);
|
|
assert.match(source, /-e DATABASE_URL="\$CONTAINER_DATABASE_URL"/);
|
|
assert.match(source, /--entrypoint \/bin\/sh/);
|
|
assert.match(source, /pnpm exec prisma migrate deploy --config prisma\.config\.ts/);
|
|
assert.doesNotMatch(source, /HOST_DATABASE_URL/);
|
|
assert.doesNotMatch(source, /DATABASE_URL="\$HOST_DATABASE_URL" pnpm exec prisma migrate deploy/);
|
|
});
|
|
|
|
it("proves worker queue-group routing for general and mail workers", () => {
|
|
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-worker-runtime-smoke.sh"), "utf8");
|
|
|
|
assert.match(source, /-e WORKER_QUEUE_GROUP=general/);
|
|
assert.match(source, /-e WORKER_QUEUE_GROUP=mail/);
|
|
assert.match(source, /expect_worker_health "\$enabled_health_output" ready true general toolctrl\.notifications/);
|
|
assert.match(source, /expect_worker_health "\$mail_health_output" ready true mail toolctrl\.email/);
|
|
assert.match(source, /report\.workerGroup !== expectedGroup/);
|
|
assert.match(source, /report\.queues\.includes\(expectedQueue\)/);
|
|
});
|
|
});
|