Skip to content

test(db-base): cover withRetry, corruption predicate, and cleanup helpers#292

Open
sebastianbreguel wants to merge 1 commit intomksglu:nextfrom
sebastianbreguel:test/session-extract-coverage
Open

test(db-base): cover withRetry, corruption predicate, and cleanup helpers#292
sebastianbreguel wants to merge 1 commit intomksglu:nextfrom
sebastianbreguel:test/session-extract-coverage

Conversation

@sebastianbreguel
Copy link
Copy Markdown
Contributor

Why

src/db-base.ts (493L) carries the SQLite primitives behind several recent incident fixes — withRetry (#263 wrapped indexPlainText/indexJSON/searchTrigram, #243 concurrent inserts), isSQLiteCorruptionError + renameCorruptDB (recovery path for #244 heavy-load death and #218 multi-session contention), and the WAL/cleanup helpers touched by #103 lifecycle guard and #249 marketplace-install fallout. Until now the module was only exercised indirectly via SessionDB integration tests.

This PR is pure regression-guard coverage for the pure, framework-free utilities. No changes to src/.

What's covered

withRetry (11 tests) — first-try success, retry-on-busy (Error), retry on "database is locked" string shape (bun:sqlite), rethrow of non-busy errors, rethrow of generic errors, non-Error throws (string, busy-shaped vs not), exhaustion with descriptive after N retries message, attempts = delays.length + 1 invariant, empty-delays short-circuit, and actual wall-clock delay verification (50ms lower bound).

isSQLiteCorruptionError (6 tests) — all four documented signatures (SQLITE_CORRUPT, SQLITE_NOTADB, database disk image is malformed, file is not a database), embedded in longer stack traces, and negative cases (SQLITE_BUSY, ENOENT, empty string).

renameCorruptDB (4 tests) — main-file quarantine with .corrupt-<ts> suffix, sidecar -wal/-shm rename when present, graceful no-op when sidecars or main file are missing.

cleanOrphanedWALFiles (3 tests) — sidecars removed only when the main DB is gone, sidecars preserved when DB still exists, tolerates empty dirs.

deleteDBFiles (3 tests) — unconditional removal of all three files, tolerant of partial/full absence.

defaultDBPath (4 tests) — pid embedding, custom prefix, default prefix, tmpdir scoping.

Test plan

  • npx vitest run tests/db-base.test.ts → 31/31 green, 66ms
  • Full suite on this branch vs clean next: same pre-existing 5 flakes in tests/hooks/integration.test.ts (SyntaxError: Unexpected end of JSON input from subprocess stdout) — not introduced here.
  • No imports or exports in src/ changed.

Single-concern PR; no runtime changes, no perf claims.

…p paths

Adds unit tests for pure utilities in src/db-base.ts that back the
SQLITE_BUSY retry wrapping (mksglu#263, mksglu#243) and corruption recovery path
behind mksglu#244/mksglu#218 incidents.

- withRetry: first-try success, retry-on-busy, rethrow non-busy, empty
  delays, exhaustion message, non-Error throws, delay honored.
- isSQLiteCorruptionError: all four documented signatures + negatives.
- renameCorruptDB: main-only, all sidecars, missing files.
- cleanOrphanedWALFiles: orphan removed, live DB preserved.
- deleteDBFiles: unconditional cleanup of main/-wal/-shm.
- defaultDBPath: pid embedding, prefix, tmpdir scoping.

31 tests, all green. No changes to src/.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant