mirror of
https://github.com/andrewyng/openworker.git
synced 2026-11-04 05:17:09 +00:00
199 lines
8.0 KiB
JavaScript
199 lines
8.0 KiB
JavaScript
import { test } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { mkdtemp, writeFile, rm } from "node:fs/promises";
|
|
import { tmpdir } from "node:os";
|
|
import { join, resolve } from "node:path";
|
|
import { run } from "./stack.mjs";
|
|
const base = {
|
|
image: "example@sha256:" + "a".repeat(64),
|
|
config: {
|
|
service: {
|
|
id: "service-test",
|
|
namespace: "test",
|
|
agent: "installed-tools",
|
|
},
|
|
},
|
|
};
|
|
async function render(values) {
|
|
const dir = await mkdtemp(join(tmpdir(), "ows-chart-"));
|
|
try {
|
|
const p = join(dir, "values.json");
|
|
await writeFile(p, JSON.stringify({ ...base, ...values }));
|
|
return await run("helm", [
|
|
"template",
|
|
"test",
|
|
resolve("deploy/service/chart"),
|
|
"-f",
|
|
p,
|
|
]);
|
|
} finally {
|
|
await rm(dir, { recursive: true, force: true });
|
|
}
|
|
}
|
|
function deployment(out, role) {
|
|
return out
|
|
.split("\n---")
|
|
.find(
|
|
(s) => s.includes("kind: Deployment") && s.includes(`name: test-${role}`),
|
|
);
|
|
}
|
|
test("recordings stay opt-in and a separate connection uses an independently mounted secret",async()=>{
|
|
const off=await render({});assert.doesNotMatch(off,/mountPath: \/run\/observability|"database_env": "OW_OBSERVABILITY_URL"/);
|
|
const same=await render({config:{...base.config,schema:"ow_execution",observability:{}}});
|
|
assert.match(same,/ow_observability/);assert.doesNotMatch(same,/mountPath: \/run\/observability/);
|
|
const separate=await render({config:{...base.config,schema:"ow_execution",observability:{retention_days:14}},secrets:{observability:"recording-db"}});
|
|
assert.match(separate,/"database_env": "OW_OBSERVABILITY_URL"/);assert.match(separate,/"database_ca": "\/run\/observability\/ca.crt"/);
|
|
for(const role of ["api","worker","controller","platform"]){const d=deployment(separate,role);assert.match(d,/mountPath: \/run\/observability, readOnly: true/);assert.match(d,/secretName: recording-db/);}
|
|
const bootstrap=separate.split("\n---").find(s=>s.includes("kind: Job")&&s.includes("name: test-bootstrap"));assert.match(bootstrap,/mountPath: \/run\/observability/);
|
|
for(const values of [
|
|
{secrets:{observability:"recording-db"}},
|
|
{config:{...base.config,schema:"ow_same",observability:{schema:"ow_same"}}},
|
|
{config:{...base.config,observability:{database:{database_env:"UNMOUNTED"}}}},
|
|
{config:{...base.config,observability:{database:{database_loopback_plaintext:true}}},secrets:{observability:"db"}}
|
|
])await assert.rejects(()=>render(values));
|
|
});
|
|
test("service roles separate gateway, model, bootstrap and Kubernetes authority", async () => {
|
|
const out = await render({ secrets: { model: "model-key" } });
|
|
assert.equal((out.match(/kind: Deployment/g) || []).length, 4);
|
|
const api = deployment(out, "api"),
|
|
worker = deployment(out, "worker"),
|
|
platform = deployment(out, "platform");
|
|
assert.match(api, /automountServiceAccountToken: false/);
|
|
assert.doesNotMatch(
|
|
api,
|
|
/mountPath: \/openshell|mountPath: \/models|mountPath: \/bootstrap/,
|
|
);
|
|
assert.match(worker, /mountPath: \/openshell/);
|
|
assert.match(worker, /mountPath: \/models/);
|
|
assert.match(worker, /automountServiceAccountToken: false/);
|
|
assert.match(platform, /automountServiceAccountToken: true/);
|
|
assert.doesNotMatch(platform, /mountPath: \/openshell|mountPath: \/models/);
|
|
assert.match(out, /resources: \[deployments\/scale\]/);
|
|
assert.match(out, /resourceNames: \[test-worker\]/);
|
|
assert.doesNotMatch(out, /resources: \[secrets\]|verbs: \[.*create/);
|
|
assert.match(out, /subPath: config.json/);
|
|
assert.doesNotMatch(out, /mountPath: \/run\/service,/);
|
|
assert.match(out, /subPath: admin-token/);
|
|
assert.match(out, /labels: \{app: test-bootstrap\}/);
|
|
assert.match(out, /readOnlyRootFilesystem: true/);
|
|
});
|
|
test("Helm does not overwrite manual/HPA capacity; only GitOps owns replicas", async () => {
|
|
for (const ownership of ["manual", "autoscaled", "gitops"]) {
|
|
const worker = deployment(
|
|
await render({ worker: { ownership, replicas: 3 } }),
|
|
"worker",
|
|
);
|
|
const beforeTemplate = worker.split(" template:")[0];
|
|
if (ownership === "gitops") assert.match(beforeTemplate, /replicas: 3/);
|
|
else assert.doesNotMatch(beforeTemplate, /\n replicas:/);
|
|
}
|
|
});
|
|
test("S3 identity is assigned only to API/worker, with no Kubernetes API role", async () => {
|
|
const out = await render({
|
|
config: {
|
|
...base.config,
|
|
artifacts: {
|
|
kind: "s3",
|
|
deployment: "ows-test",
|
|
bucket: "test-bucket",
|
|
region: "us-west-2",
|
|
},
|
|
},
|
|
});
|
|
assert.match(out, /kind: ServiceAccount\nmetadata: \{name: test-artifacts\}/);
|
|
for (const role of ["api", "worker"])
|
|
assert.match(deployment(out, role), /serviceAccountName: test-artifacts/);
|
|
for (const role of ["controller", "platform"])
|
|
assert.doesNotMatch(
|
|
deployment(out, role),
|
|
/serviceAccountName: test-artifacts/,
|
|
);
|
|
assert.doesNotMatch(
|
|
out,
|
|
/subjects:.*test-artifacts|roleRef:.*test-artifacts/,
|
|
);
|
|
});
|
|
test("artifact content streams with its own bounded limit while JSON stays small", async () => {
|
|
const out = await render({});
|
|
assert.match(out, /client_max_body_size 160k/);
|
|
const content = out.match(/location ~ \^\/\(v1\/\)\?sessions\/[\s\S]*?\n\s*location \//)?.[0];
|
|
assert.ok(content, "Missing scoped artifact content location");
|
|
assert.match(content, /artifacts\/\[A-Za-z0-9_-\]\+\/content\$/);
|
|
assert.match(content, /client_max_body_size 64m/);
|
|
assert.match(content, /proxy_request_buffering off/);
|
|
assert.match(content, /client_body_timeout 120s/);
|
|
});
|
|
test("invalid ownership, mutable image and inadequate drain grace fail rendering", async () => {
|
|
await assert.rejects(render({ worker: { ownership: "mixed" } }));
|
|
await assert.rejects(render({ image: "example:latest" }));
|
|
await assert.rejects(
|
|
render({
|
|
config: {
|
|
service: { ...base.config.service, legacy_compatibility: true },
|
|
},
|
|
}),
|
|
);
|
|
await assert.rejects(
|
|
render({
|
|
worker: { drainSeconds: 90 },
|
|
terminationGracePeriodSeconds: 100,
|
|
}),
|
|
);
|
|
});
|
|
test("management UI has no execution, database, or cluster authority", async () => {
|
|
const uiValues = {
|
|
enabled: true,
|
|
image: "ui@sha256:" + "b".repeat(64),
|
|
publicOrigin: "https://manage.example.test",
|
|
serviceUrl: "https://test-api.default.svc",
|
|
caSecret: "api-public-ca",
|
|
};
|
|
const out = await render({ managementUI: uiValues });
|
|
const ui = deployment(out, "ui");
|
|
assert.match(ui, /automountServiceAccountToken: false/);
|
|
assert.match(ui, /replicas: 1/);
|
|
assert.match(ui, /type: Recreate/);
|
|
assert.match(ui, /NODE_EXTRA_CA_CERTS/);
|
|
assert.match(ui, /readOnlyRootFilesystem: true/);
|
|
assert.doesNotMatch(
|
|
ui,
|
|
/database-url|pg-ca|openshell|model-key|bootstrap|serviceAccountName/,
|
|
);
|
|
await assert.rejects(
|
|
render({ managementUI: { ...uiValues, image: "ui:latest" } }),
|
|
);
|
|
await assert.rejects(
|
|
render({
|
|
managementUI: { ...uiValues, publicOrigin: "http://manage.example.test" },
|
|
}),
|
|
);
|
|
await assert.rejects(
|
|
render({ managementUI: { ...uiValues, serviceUrl: "http://test-api" } }),
|
|
);
|
|
});
|
|
test("exporter authentication mounts only into harness roles and remains opt-in", async () => {
|
|
const off = await render({});
|
|
assert.doesNotMatch(off, /mountPath: \/run\/telemetry/);
|
|
const out = await render({
|
|
secrets: { telemetry: "export-auth" },
|
|
managementUI: {
|
|
enabled: true,
|
|
image: "ui@sha256:" + "b".repeat(64),
|
|
publicOrigin: "https://manage.example.test",
|
|
serviceUrl: "https://test-api.default.svc",
|
|
},
|
|
});
|
|
for (const role of ["api", "worker", "controller", "platform"]) {
|
|
const d = deployment(out, role);
|
|
assert.match(d, /mountPath: \/run\/telemetry, readOnly: true/);
|
|
assert.match(d, /secretName: export-auth/);
|
|
}
|
|
const ui = deployment(out, "ui");
|
|
assert.doesNotMatch(ui, /export-auth|\/run\/telemetry/);
|
|
const bootstrap = out
|
|
.split("\n---")
|
|
.find((s) => s.includes("kind: Job") && s.includes("name: test-bootstrap"));
|
|
assert.match(bootstrap, /OW_TELEMETRY_AUTH/);
|
|
assert.match(bootstrap, /secretName: export-auth/);
|
|
});
|