fix: accept migration command arguments
This commit is contained in:
@@ -323,11 +323,11 @@ describe("migrated CLI 执行 guard 与提示清理", () => {
|
||||
});
|
||||
|
||||
test("migration Job 只从目标容器读取多行 CLI envelope,忽略合并日志尾随结果", () => {
|
||||
const verifyFailure = JSON.stringify({ ok: false, data: { ok: false, command: "web-probe sentinel migration verify", error: { code: "monitor-migration-pg-verify-mismatch", message: "verify saw {braces} and an escaped \"quote\"" } } }, null, 2);
|
||||
const verifyFailure = JSON.stringify({ ok: false, command: "web-probe sentinel migration verify --node NC01 --lane v03 --json", error: { code: "monitor-migration-pg-verify-mismatch", message: "verify saw {braces} and an escaped \"quote\"" } }, null, 2);
|
||||
const importSuccess = JSON.stringify({ ok: true, data: { ok: true, command: "web-probe sentinel migration import" } }, null, 2);
|
||||
const probe = { failed: true, podPhase: "Failed", containers: [{ name: "verify", phase: "terminated", exitCode: 1, reason: "Error", message: "-" }], containerLogs: { verify: `verify prefix\n${verifyFailure}`, import: importSuccess }, logsTail: `${verifyFailure}\n${importSuccess}` };
|
||||
const payload = migrationJobPayloadFromProbe(probe);
|
||||
expect(payload).toMatchObject({ ok: false, command: "web-probe sentinel migration verify", error: { code: "monitor-migration-pg-verify-mismatch", message: "verify saw {braces} and an escaped \"quote\"" } });
|
||||
expect(payload).toMatchObject({ ok: false, command: "web-probe sentinel migration verify --node NC01 --lane v03 --json", error: { code: "monitor-migration-pg-verify-mismatch", message: "verify saw {braces} and an escaped \"quote\"" } });
|
||||
const failure = migrationJobFailed("migration", { jobName: "job" }, "failed", payload, probe) as { projection?: Record<string, unknown> };
|
||||
expect(failure.projection?.failure).toMatchObject({ container: "verify", code: "monitor-migration-pg-verify-mismatch", message: "verify saw {braces} and an escaped \"quote\"" });
|
||||
expect(failure.projection?.result).toBeUndefined();
|
||||
@@ -339,6 +339,13 @@ describe("migrated CLI 执行 guard 与提示清理", () => {
|
||||
expect(migrationJobPayloadFromProbe({ succeeded: true, containers: [{ name: "verify", phase: "terminated", exitCode: 0 }], containerLogs: { verify: JSON.stringify({ ok: true, data: { ok: true, command: "web-probe sentinel migration verify" } }), import: importSuccess } })).toMatchObject({ ok: true, command: "web-probe sentinel migration verify" });
|
||||
});
|
||||
|
||||
test("migration Job 接受带参数的 direct export 包络并拒绝相似 command 前缀", () => {
|
||||
const direct = (command: string) => JSON.stringify({ ok: false, command, error: { code: "monitor-migration-artifact-path-invalid", message: "export artifact is unavailable" } }, null, 2);
|
||||
const failedExport = (command: string) => migrationJobPayloadFromProbe({ failed: true, containers: [{ name: "export", phase: "terminated", exitCode: 1 }], containerLogs: { export: direct(command) } });
|
||||
expect(failedExport("web-probe sentinel migration export --node NC01 --lane v03 --json")).toMatchObject({ ok: false, command: "web-probe sentinel migration export --node NC01 --lane v03 --json", error: { code: "monitor-migration-artifact-path-invalid" } });
|
||||
for (const command of ["web-probe sentinel migration export-other --json", "web-probe sentinel migration exportfoo --json", "web-probe sentinel migration import --json"]) expect(failedExport(command)).toMatchObject({ ok: false, error: { code: "monitor-migration-job-result-missing" } });
|
||||
});
|
||||
|
||||
test("migration Job 业务失败、创建失败和超时均只返回安全 failure 投影", () => {
|
||||
const business = migrationJobFailed("migration", { jobName: "job" }, "result-failed", { ok: false, error: { message: "https://user:PW123@host failed", stack: "secret stack" } }, { podPhase: "Succeeded", logsTail: "Bearer abc" }) as { projection?: Record<string, unknown> };
|
||||
const createFailed = migrationJobFailed("migration", { jobName: "job" }, "create-failed", {}, { podPhase: "CreateFailed", logsTail: "DATABASE_URL=https://user:PW123@host/db" }) as { projection?: Record<string, unknown> };
|
||||
|
||||
@@ -263,10 +263,14 @@ export function migrationJobPayloadFromProbe(probe: Record<string, unknown>): Re
|
||||
const expectedCommand = container === "export" ? "web-probe sentinel migration export" : container === "import" ? "web-probe sentinel migration import" : container === "verify" ? "web-probe sentinel migration verify" : null;
|
||||
const containerLogs = isRecord(probe.containerLogs) ? probe.containerLogs : {};
|
||||
const payload = container === null ? {} : sentinelPayloadFromLogs(String(containerLogs[container] ?? ""));
|
||||
if (expectedCommand !== null && payload.command === expectedCommand && (payload.ok === true || payload.ok === false)) return payload;
|
||||
if (expectedCommand !== null && migrationPayloadCommandMatches(payload.command, expectedCommand) && (payload.ok === true || payload.ok === false)) return payload;
|
||||
return { ok: false, error: { code: "monitor-migration-job-result-missing", message: expectedCommand === null ? "migration Job failed without an identifiable terminated container result" : `migration Job ${container} container did not emit the expected structured result` }, valuesRedacted: true };
|
||||
}
|
||||
|
||||
function migrationPayloadCommandMatches(value: unknown, expected: string): boolean {
|
||||
return typeof value === "string" && (value === expected || value.startsWith(`${expected} `));
|
||||
}
|
||||
|
||||
function migrationFailedContainerName(probe: Record<string, unknown>): string | null {
|
||||
const containers = Array.isArray(probe.containers) ? probe.containers.filter(isRecord) : [];
|
||||
return stringAtNullable(containers.find((container) => finiteNumberOrNull(container.exitCode) !== null && finiteNumberOrNull(container.exitCode) !== 0), "name");
|
||||
|
||||
Reference in New Issue
Block a user