fix(pikaoa): render test database search path
This commit is contained in:
@@ -239,6 +239,44 @@ test("validation-only fixture never invokes remote capture", async () => {
|
||||
assert.equal(payload.remoteQueried, false);
|
||||
assert.equal((payload.status as Record<string, unknown>).remoteQueried, false);
|
||||
|
||||
const planResult = await runPikaoaCommand({} as UniDeskConfig, [
|
||||
"test-target", "plan", "--config", "config/fixtures/pikaoa-test-target.yaml", "--target", "TEST01", "--instance", "validation-only", "--commit", "0123456789abcdef", "--output", "json",
|
||||
], forbiddenCapture);
|
||||
const planPayload = JSON.parse(planResult.renderedText) as Record<string, unknown>;
|
||||
const plan = planPayload.plan as Record<string, unknown>;
|
||||
assert.deepEqual(plan.database, {
|
||||
schema: "pikaoa",
|
||||
dsnParameterPresence: { sslmode: true, search_path: true },
|
||||
valuesPrinted: false,
|
||||
});
|
||||
assert.deepEqual(plan.runtimeConfig, {
|
||||
secretName: "pikaoa-test-runtime",
|
||||
key: "pikaoa.yaml",
|
||||
mountPath: "/etc/pikaoa/pikaoa.yaml",
|
||||
consumers: ["migration", "api", "worker"],
|
||||
valuesPrinted: false,
|
||||
});
|
||||
assert.equal(planPayload.valuesPrinted, false);
|
||||
assert.equal(JSON.stringify(planPayload).includes("fixture-db-password"), false);
|
||||
assert.equal(JSON.stringify(planPayload).includes("postgres://"), false);
|
||||
|
||||
const missingSchemaRoot = mkdtempSync(join(tmpdir(), "pikaoa-test-target-missing-schema-"));
|
||||
const missingSchemaPath = join(missingSchemaRoot, "pikaoa.yaml");
|
||||
const missingSchemaFixture = readFileSync(rootPath("config", "fixtures", "pikaoa-test-target.yaml"), "utf8")
|
||||
.replace(" schema: pikaoa\n", "");
|
||||
writeFileSync(missingSchemaPath, missingSchemaFixture);
|
||||
try {
|
||||
await assert.rejects(
|
||||
runPikaoaCommand({} as UniDeskConfig, [
|
||||
"test-target", "status", "--config", missingSchemaPath, "--target", "TEST01", "--instance", "missing-schema", "--output", "json",
|
||||
], forbiddenCapture),
|
||||
/testRuntime\.targets\.TEST01\.database\.schema 必须是非空字符串/u,
|
||||
);
|
||||
assert.equal(calls, 0);
|
||||
} finally {
|
||||
rmSync(missingSchemaRoot, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
const unconfigured = await runPikaoaCommand({} as UniDeskConfig, ["test-target", "status", "--output", "json"], forbiddenCapture);
|
||||
const unconfiguredPayload = JSON.parse(unconfigured.renderedText) as Record<string, unknown>;
|
||||
assert.equal(calls, 0);
|
||||
|
||||
@@ -61,6 +61,7 @@ interface TestTargetSpec {
|
||||
image: string;
|
||||
name: string;
|
||||
username: string;
|
||||
schema: string;
|
||||
port: number;
|
||||
password: SecretSourceSpec;
|
||||
};
|
||||
@@ -319,6 +320,7 @@ function parseTarget(id: string, root: Record<string, unknown>, configLabel: str
|
||||
image: imageReference(database.image, `${path}.database.image`),
|
||||
name: postgresIdentifier(database.name, `${path}.database.name`),
|
||||
username: postgresIdentifier(database.username, `${path}.database.username`),
|
||||
schema: postgresIdentifier(database.schema, `${path}.database.schema`),
|
||||
port: positiveInteger(database.port, `${path}.database.port`, 65_535),
|
||||
password: secretSource(database.password, "database.password", `${path}.database.password`),
|
||||
},
|
||||
@@ -447,6 +449,14 @@ function renderedPlan(selection: Selection, context: RenderContext): Record<stri
|
||||
valuesPrinted: false,
|
||||
sources: secretSources(target).map((source) => ({ ...source, presence: "unchecked", fingerprint: null, valuesPrinted: false })),
|
||||
},
|
||||
database: databasePlanSummary(target),
|
||||
runtimeConfig: {
|
||||
secretName: target.runtime.secretName,
|
||||
key: "pikaoa.yaml",
|
||||
mountPath: "/etc/pikaoa/pikaoa.yaml",
|
||||
consumers: ["migration", "api", "worker"],
|
||||
valuesPrinted: false,
|
||||
},
|
||||
probes: {
|
||||
api: { liveness: target.probes.apiLivenessPath, readiness: target.probes.apiReadinessPath, metrics: target.observability.apiMetricsPath },
|
||||
worker: { liveness: target.probes.workerLivenessPath, readiness: target.probes.workerReadinessPath, metrics: target.observability.workerMetricsPath },
|
||||
@@ -741,7 +751,7 @@ function deployment(
|
||||
}
|
||||
|
||||
function runtimeSecretData(target: TestTargetSpec, context: RenderContext, secrets: SecretMaterial): Record<string, string> {
|
||||
const databaseURL = `postgres://${encodeURIComponent(target.database.username)}:${encodeURIComponent(secrets.databasePassword)}@pikaoa-postgres:${target.database.port}/${encodeURIComponent(target.database.name)}?sslmode=disable`;
|
||||
const databaseURL = renderDatabaseURL(target, secrets.databasePassword);
|
||||
return {
|
||||
[target.database.password.targetKey]: secrets.databasePassword,
|
||||
[target.runtime.sessionSecret.targetKey]: secrets.sessionSecret,
|
||||
@@ -773,6 +783,29 @@ function runtimeSecretData(target: TestTargetSpec, context: RenderContext, secre
|
||||
};
|
||||
}
|
||||
|
||||
function renderDatabaseURL(target: TestTargetSpec, password: string): string {
|
||||
const databaseURL = new URL("postgres://pikaoa-postgres");
|
||||
databaseURL.username = target.database.username;
|
||||
databaseURL.password = password;
|
||||
databaseURL.port = String(target.database.port);
|
||||
databaseURL.pathname = `/${target.database.name}`;
|
||||
databaseURL.searchParams.set("sslmode", "disable");
|
||||
databaseURL.searchParams.set("search_path", target.database.schema);
|
||||
return databaseURL.toString();
|
||||
}
|
||||
|
||||
function databasePlanSummary(target: TestTargetSpec): Record<string, unknown> {
|
||||
const databaseURL = new URL(renderDatabaseURL(target, "<redacted>"));
|
||||
return {
|
||||
schema: target.database.schema,
|
||||
dsnParameterPresence: {
|
||||
sslmode: databaseURL.searchParams.has("sslmode"),
|
||||
search_path: databaseURL.searchParams.has("search_path"),
|
||||
},
|
||||
valuesPrinted: false,
|
||||
};
|
||||
}
|
||||
|
||||
function readSecretMaterial(selection: Selection, target: TestTargetSpec): {
|
||||
ok: boolean;
|
||||
values: SecretMaterial;
|
||||
|
||||
Reference in New Issue
Block a user