|
| 1 | +import assert from "node:assert/strict"; |
| 2 | +import fs from "node:fs"; |
| 3 | +import os from "node:os"; |
| 4 | +import path from "node:path"; |
| 5 | +import { spawnSync } from "node:child_process"; |
| 6 | +import test from "node:test"; |
| 7 | +import { fileURLToPath } from "node:url"; |
| 8 | + |
| 9 | +import { daemonArguments, parsePort } from "../docker/open-design/entrypoint.mjs"; |
| 10 | + |
| 11 | +const ROOT = path.dirname(path.dirname(fileURLToPath(import.meta.url))); |
| 12 | +const ENTRYPOINT = path.join(ROOT, "docker/open-design/entrypoint.mjs"); |
| 13 | +const DOCKERFILE = path.join(ROOT, "docker/open-design/Dockerfile"); |
| 14 | + |
| 15 | +test("[OD001] parsePort accepts decimal ports in the valid range", () => { |
| 16 | + for (const [raw, expected] of [["1", 1], ["7456", 7456], ["65535", 65535], ["07456", 7456]]) { |
| 17 | + assert.equal(parsePort(raw), expected, raw); |
| 18 | + } |
| 19 | +}); |
| 20 | + |
| 21 | +for (const raw of ["", "0", "65536", "7456 ", " 7456", "+7456", "7456; touch marker", "7456\n--help"]) { |
| 22 | + test(`[OD002] parsePort rejects unsafe value ${JSON.stringify(raw)}`, () => { |
| 23 | + assert.throws(() => parsePort(raw), /OD_PORT.*1 and 65535/); |
| 24 | + }); |
| 25 | +} |
| 26 | + |
| 27 | +test("[OD003] daemon arguments keep the port as one argument", () => { |
| 28 | + assert.deepEqual(daemonArguments(parsePort("7456")), [ |
| 29 | + "apps/daemon/dist/cli.js", |
| 30 | + "--port", |
| 31 | + "7456", |
| 32 | + "--no-open", |
| 33 | + ]); |
| 34 | +}); |
| 35 | + |
| 36 | +test("[OD004] a shell metacharacter fails before any daemon can start", () => { |
| 37 | + const marker = path.join(os.tmpdir(), `open-design-entrypoint-${process.pid}-marker`); |
| 38 | + const result = spawnSync(process.execPath, [ENTRYPOINT], { |
| 39 | + cwd: ROOT, |
| 40 | + encoding: "utf8", |
| 41 | + env: { ...process.env, OD_PORT: `7456; touch ${marker}` }, |
| 42 | + }); |
| 43 | + |
| 44 | + assert.equal(result.status, 1, result.stderr); |
| 45 | + assert.match(result.stderr, /OD_PORT/); |
| 46 | + assert.equal(fs.existsSync(marker), false); |
| 47 | +}); |
| 48 | + |
| 49 | +test("[OD005] Docker uses an exec-form Node entrypoint without shell interpolation", () => { |
| 50 | + const dockerfile = fs.readFileSync(DOCKERFILE, "utf8"); |
| 51 | + assert.match(dockerfile, /COPY entrypoint\.mjs \/usr\/local\/bin\/open-design-entrypoint\.mjs/); |
| 52 | + assert.match(dockerfile, /ENTRYPOINT \["node", "\/usr\/local\/bin\/open-design-entrypoint\.mjs"\]/); |
| 53 | + assert.doesNotMatch(dockerfile, /sh\s+-lc|\$\{OD_PORT/); |
| 54 | +}); |
0 commit comments