import { describe, expect, test } from "bun:test"; import { readFileSync } from "node:fs"; import { projectLogicalDumps } from "./platform-db-postgres-backups"; import { readPostgresLogicalDumps, renderPostgresRemoteRunnerForTest } from "./platform-db"; describe("PostgreSQL logical dumps", () => { test("keeps Sub2API on PK01 and declares PikaOA on NC01", () => { const pk01LogicalDumps = readPostgresLogicalDumps("config/platform-db/postgres-pk01.yaml"); const nc01LogicalDumps = readPostgresLogicalDumps("config/platform-db/postgres-nc01.yaml"); expect(pk01LogicalDumps).toHaveLength(1); expect(pk01LogicalDumps[0]).toMatchObject({ database: "sub2api", scriptPath: "/usr/local/sbin/unidesk-pk01-sub2api-pgdump.sh", serviceName: "unidesk-pk01-sub2api-pgdump.service", timerName: "unidesk-pk01-sub2api-pgdump.timer", schedule: "*-*-* 03:17:00", retentionDays: 14, }); expect(nc01LogicalDumps.map((item) => item.database)).toEqual(["agentrun_v02", "pikaoa"]); expect(nc01LogicalDumps[1]).toMatchObject({ destination: { path: "/var/backups/unidesk/platform-db/nc01/pikaoa" }, schedule: "*-*-* 03:47:00", retentionDays: 14, }); }); test("renders YAML-driven backup resources without Sub2API constants", () => { const runner = renderPostgresRemoteRunnerForTest(); expect(runner).toContain('data["backup"]["logicalDumps"][index]'); expect(runner).toContain("backup.logicalDumps.$backup_index.serviceName"); expect(runner).toContain("backup.logicalDumps.$backup_index.timerName"); expect(runner).not.toContain("unidesk-pk01-sub2api-pgdump.service"); expect(runner).not.toContain("OnCalendar=*-*-* 03:17:00"); }); test("PK01 backup YAML has no duplicate future encryption key", () => { const source = readFileSync("config/platform-db/postgres-pk01.yaml", "utf8"); expect(source.match(/^\s+futureKeyRef:/gmu)).toHaveLength(1); expect(() => readPostgresLogicalDumps("config/platform-db/postgres-pk01.yaml")).not.toThrow(); }); test("reports stale or missing evidence as warnings", () => { const [declaration] = readPostgresLogicalDumps("config/platform-db/postgres-pk01.yaml"); const [projection] = projectLogicalDumps([declaration], [{ database: declaration.database, databaseExists: true, scriptPath: declaration.scriptPath, scriptExists: true, serviceName: declaration.serviceName, serviceResult: "success", serviceExitStatus: 0, lastSuccessAt: null, timerName: declaration.timerName, timerActive: true, timerEnabled: true, nextRunAt: null, latestNonEmptyDump: null, }]); expect(projection.recoverability.recoverable).toBeFalse(); expect(projection.warnings).toContain("backup-recent-success-missing"); expect(projection.warnings).toContain("backup-latest-non-empty-dump-missing"); }); });