Files
pikasTech-HWLAB/scripts/src/dev-runtime-provisioning.test.mjs
T
2026-05-23 10:22:57 +00:00

271 lines
11 KiB
JavaScript

import assert from "node:assert/strict";
import test from "node:test";
import {
buildDevRuntimeProvisioningReport,
parseArgs
} from "./dev-runtime-provisioning.mjs";
test("source check parses target role/database without leaking DB URL material", async () => {
const report = await buildDevRuntimeProvisioningReport(parseArgs(["--check"]), {
env: {
HWLAB_CLOUD_DB_URL: fixturePostgresUrl({ password: fixtureSecret("super") }),
HWLAB_CLOUD_DB_SSL_MODE: "disable"
},
now: () => "2026-05-23T00:00:00.000Z"
});
assert.equal(report.conclusion.status, "ready");
assert.equal(report.actions.liveDbReadAttempted, false);
assert.equal(report.actions.liveDbWriteAttempted, false);
assert.equal(report.db.targetRoleNamePresent, true);
assert.equal(report.db.targetDatabaseNamePresent, true);
assert.equal(report.db.targetPasswordPresent, true);
assert.equal(report.safety.secretValuesPrinted, false);
assertNoFixtureSecrets(report);
});
test("source check without injected DB URL is ready and performs no live access", async () => {
const report = await buildDevRuntimeProvisioningReport(parseArgs(["--check"]), {
env: {},
now: () => "2026-05-23T00:00:00.000Z"
});
assert.equal(report.conclusion.status, "ready");
assert.equal(report.actions.liveDbReadAttempted, false);
assert.equal(report.actions.liveDbWriteAttempted, false);
assert.equal(report.blockers.length, 0);
assert.equal(report.db.targetUrlPresent, false);
assert.equal(report.gates.role.status, "not_checked");
});
test("live dry-run classifies missing target role separately from missing database", async () => {
const report = await buildDevRuntimeProvisioningReport(
parseArgs(["--dry-run", "--allow-live-db-read", "--confirm-dev"]),
{
env: envWithAdmin(),
adminClient: createAdminClient({ roleExists: false, databaseExists: true }),
queryClient: createRuntimeClient("auth"),
now: () => "2026-05-23T00:00:00.000Z"
}
);
assert.equal(report.conclusion.status, "blocked");
assert.equal(report.actions.adminInspectionAttempted, true);
assert.equal(report.actions.liveDbWriteAttempted, false);
assert.equal(report.provisioning.targetRole.exists, false);
assert.equal(report.provisioning.targetDatabase.exists, true);
assert.equal(report.blockers.some((blocker) => blocker.scope === "runtime-provisioning-role"), true);
assert.equal(report.blockers.some((blocker) => blocker.scope === "runtime-provisioning-database"), false);
assert.equal(report.blockers.some((blocker) => blocker.scope === "runtime-provisioning-auth"), true);
assertNoFixtureSecrets(report);
});
test("live dry-run classifies missing target database separately from target role", async () => {
const report = await buildDevRuntimeProvisioningReport(
parseArgs(["--dry-run", "--allow-live-db-read", "--confirm-dev"]),
{
env: envWithAdmin(),
adminClient: createAdminClient({ roleExists: true, databaseExists: false }),
queryClient: createRuntimeClient("auth"),
now: () => "2026-05-23T00:00:00.000Z"
}
);
assert.equal(report.conclusion.status, "blocked");
assert.equal(report.provisioning.targetRole.exists, true);
assert.equal(report.provisioning.targetDatabase.exists, false);
assert.equal(report.blockers.some((blocker) => blocker.scope === "runtime-provisioning-role"), false);
assert.equal(report.blockers.some((blocker) => blocker.scope === "runtime-provisioning-database"), true);
});
test("live dry-run separates SSL from auth/schema/migration", async () => {
const report = await buildDevRuntimeProvisioningReport(
parseArgs(["--dry-run", "--allow-live-db-read", "--confirm-dev"]),
{
env: envWithAdmin({ sslMode: "require" }),
adminClient: createAdminClient({ roleExists: true, databaseExists: true }),
queryClient: createRuntimeClient("ssl"),
now: () => "2026-05-23T00:00:00.000Z"
}
);
assert.equal(report.conclusion.status, "blocked");
assert.equal(report.gates.ssl.status, "blocked");
assert.equal(report.gates.auth.status, "not_checked");
assert.equal(report.gates.schema.status, "not_checked");
assert.equal(report.gates.migration.status, "not_checked");
assert.equal(report.blockers.some((blocker) => blocker.scope === "runtime-provisioning-ssl"), true);
assert.equal(JSON.stringify(report).includes("does not support SSL"), false);
});
test("live dry-run leaves role/database ready while migration remains a downstream blocker", async () => {
const report = await buildDevRuntimeProvisioningReport(
parseArgs(["--dry-run", "--allow-live-db-read", "--confirm-dev"]),
{
env: envWithAdmin(),
adminClient: createAdminClient({ roleExists: true, databaseExists: true }),
queryClient: createRuntimeClient("migration"),
now: () => "2026-05-23T00:00:00.000Z"
}
);
assert.equal(report.conclusion.status, "ready");
assert.equal(report.provisioning.ready, true);
assert.equal(report.provisioning.targetRole.ready, true);
assert.equal(report.provisioning.targetDatabase.ready, true);
assert.equal(report.runtime.blocker, "runtime_durable_adapter_migration_blocked");
assert.equal(report.gates.migration.status, "blocked");
assert.equal(report.blockers.length, 0);
});
test("apply creates missing role/database and grants target privileges without printing secrets", async () => {
const adminClient = createAdminClient({ roleExists: false, databaseExists: false });
const targetAdminClient = createAdminClient({ roleExists: true, databaseExists: true });
const report = await buildDevRuntimeProvisioningReport(
parseArgs(["--apply", "--confirm-dev", "--confirmed-non-production"]),
{
env: envWithAdmin(),
adminClient,
queryClient: createRuntimeClient("ready"),
now: () => "2026-05-23T00:00:00.000Z",
adminDbUrlOverride: null,
pgModuleLoader: async () => {
throw new Error("pgModuleLoader should not be used when adminClient is injected");
}
}
);
assert.equal(targetAdminClient.calls.length, 0);
assert.equal(report.conclusion.status, "ready");
assert.equal(report.actions.roleCreated, true);
assert.equal(report.actions.databaseCreated, true);
assert.equal(report.actions.rolePasswordSynchronized, true);
assert.equal(report.actions.databaseConnectGranted, true);
assert.equal(report.actions.schemaPrivilegesGranted, true);
assert.equal(report.provisioning.ready, true);
assert.ok(adminClient.calls.some((call) => call.sql.startsWith("CREATE ROLE ")));
assert.ok(adminClient.calls.some((call) => call.sql.startsWith("CREATE DATABASE ")));
assert.ok(adminClient.calls.some((call) => call.sql.startsWith("GRANT CONNECT ON DATABASE ")));
assert.ok(adminClient.calls.some((call) => call.sql.startsWith("GRANT USAGE, CREATE ON SCHEMA public ")));
assertNoFixtureSecrets(report);
});
function envWithAdmin({ sslMode = "disable" } = {}) {
return {
HWLAB_CLOUD_DB_URL: fixturePostgresUrl({ password: fixtureSecret("app") }),
HWLAB_CLOUD_DB_ADMIN_URL: fixturePostgresUrl({
user: "postgres",
password: fixtureSecret("admin"),
database: "postgres"
}),
HWLAB_CLOUD_DB_SSL_MODE: sslMode
};
}
function fixturePostgresUrl({
user = "hwlab_app",
password = fixtureSecret("app"),
host = "db.example.test",
database = "hwlab_runtime"
} = {}) {
return `${["postgresql", "://"].join("")}${user}:${password}@${host}:5432/${database}`;
}
function fixtureSecret(kind) {
return `${kind}-${"secret"}`;
}
function assertNoFixtureSecrets(value) {
const text = JSON.stringify(value);
for (const forbidden of [
fixtureSecret("super"),
fixtureSecret("app"),
fixtureSecret("admin"),
"db.example.test",
"hwlab_app",
"hwlab_runtime"
]) {
assert.equal(text.includes(forbidden), false);
}
}
function createAdminClient({ roleExists, databaseExists }) {
const state = {
roleExists,
databaseExists,
calls: []
};
return {
get calls() {
return state.calls;
},
async query(sql, params = []) {
state.calls.push({ sql, params });
if (sql.includes("pg_catalog.pg_roles")) {
return { rows: state.roleExists ? [{ present: 1 }] : [] };
}
if (sql.includes("pg_catalog.pg_database")) {
return { rows: state.databaseExists ? [{ present: 1 }] : [] };
}
if (sql.startsWith("CREATE ROLE ")) {
state.roleExists = true;
return { rows: [] };
}
if (sql.startsWith("ALTER ROLE ")) {
return { rows: [] };
}
if (sql.startsWith("CREATE DATABASE ")) {
state.databaseExists = true;
return { rows: [] };
}
if (sql.startsWith("GRANT CONNECT ON DATABASE ") || sql.startsWith("GRANT USAGE, CREATE ON SCHEMA public ")) {
return { rows: [] };
}
throw new Error(`unexpected admin query: ${sql}`);
}
};
}
function createRuntimeClient(mode) {
return {
async query(sql) {
if (sql.includes("information_schema.columns")) {
if (mode === "ssl") {
const error = new Error("fixture SSL blocked: server does not support SSL");
error.code = "08P01";
throw error;
}
if (mode === "auth") {
const error = new Error("fixture auth blocked");
error.code = "28P01";
throw error;
}
return { rows: schemaRows() };
}
if (sql.startsWith("SELECT id, schema_version FROM hwlab_schema_migrations")) {
if (mode === "migration") return { rows: [] };
return { rows: [{ id: "0001_cloud_core_skeleton", schema_version: "runtime-durable-postgres-v1" }] };
}
if (sql.startsWith("SELECT COUNT(*)::int AS count FROM ")) {
return { rows: [{ count: 0 }] };
}
throw new Error(`unexpected runtime query: ${sql}`);
}
};
}
function schemaRows() {
const schema = {
gateway_sessions: ["id", "project_id", "gateway_service_id", "status", "started_at", "ended_at", "gateway_session_json"],
box_resources: ["id", "project_id", "gateway_session_id", "resource_state", "labels_json", "resource_json", "updated_at"],
box_capabilities: ["id", "box_resource_id", "capability_type", "capability_json", "updated_at"],
hardware_operations: ["id", "project_id", "requested_by", "operation_type", "operation_json", "status", "requested_at", "updated_at"],
audit_events: ["id", "request_id", "actor", "source", "operation", "target", "result", "timestamp", "event_json"],
evidence_records: ["id", "project_id", "operation_id", "evidence_type", "uri", "metadata_json", "created_at"]
};
return Object.entries(schema).flatMap(([table, columns]) =>
columns.map((column) => ({ table_name: table, column_name: column }))
);
}