Every backup test exports and restores with the same code, so a change that moves both ends at once passes all of them and still breaks a file a self-hoster downloaded last month. Commit the disaster-recovery file the 1.46.1 exporter writes for the shared backup seed, with a manifest of its counts and SHA-256, and restore each committed file through the admin upload and restore routes into an empty account, comparing the re-exported counts section by section. The folder takes one file per release (GOLDEN_BACKUP_WRITE=1 writes the current one; the README says when). The seed's own illness-symptom catalogue key is swapped for a shipped one so every link resolves on a fresh instance. Ciphertext is sealed under the suite's fixed key. A measurement tombstone that ages past retention may only lower its count.
2.4 KiB
Golden backups
One disaster-recovery backup file per release, written by that release's own
exporter, and a manifest of what it held. tests/integration/golden-backups.test.ts
uploads every file here through the admin upload route, restores it into an
empty account through the restore route and job, exports the account again and
checks the counts section by section against the manifest. A backup a person
downloaded from an older release has to keep restoring after every later
change; this is where that is held still.
| File | What it is |
|---|---|
v<release>.json |
the file exactly as the exporter wrote it (compact JSON, never reformatted) |
v<release>.manifest.json |
release, schema version, owner id, exportedAt, SHA-256, byte size, counts |
The account is the shared backup seed (tests/integration/backup-fixture.ts:
one row of every two-ended model plus the column shapes), so every section the
backup writes holds at least one row. Ciphertext inside the file is sealed
under the integration suite's fixed key (ENCRYPTION_KEY in
vitest.integration.config.mts), so the file opens on every machine that runs
the suite and no real key is involved.
Adding the next release's file
Once per release, on the release branch after the version bump, with Docker running:
GOLDEN_BACKUP_WRITE=1 pnpm vitest run --config vitest.integration.config.mts tests/integration/golden-backups.test.ts
pnpm vitest run --config vitest.integration.config.mts tests/integration/golden-backups.test.ts
The first command writes v<version from package.json>.json and its manifest;
the second restores every file here, the new one included. Commit both files.
Never rewrite an existing release's file: the test checks each file against the SHA-256 in its manifest, because a file regenerated by today's exporter would prove only that today's exporter and today's restore agree. When a change means an old file can no longer restore as it was written, that is a breaking change to the backup format, and it is decided in the restore code, not by replacing the fixture.
A count the restore is documented to drop by age (a measurement tombstone past
its retention) is listed in AGES_OUT in the test and may only go down.