Skip to content

test(db): raise interloper-db coverage from 87% to 98% - #317

Merged
aaaaahaaaaa merged 1 commit into
mainfrom
test/interloper-db-coverage
Sep 4, 2026
Merged

test(db): raise interloper-db coverage from 87% to 98%#317
aaaaahaaaaa merged 1 commit into
mainfrom
test/interloper-db-coverage

Conversation

@aaaaahaaaaa

Copy link
Copy Markdown
Contributor

Fills the untested surface of interloper-db, closing 223 of its 256 uncovered statements (87% → 98%). Tests only: no source file changes.

Coverage

Module Before After
provision.py 18% 100%
engine.py 65% 100%
store/auth.py 76% 100%
store/base.py 79% 100%
store/organisations.py 79% 99%
store/components.py 86% 98%
store/runs.py 86% 100%
store/events.py 88% 91%
store/hydration.py 89% 95%
store/relations.py, quotas/base.py, store/tokens.py, store/status.py 92–94% 94–100%

Reviewer notes

provision.py is faked, deliberately. Its routines are Postgres-specific — a pg_advisory_lock, a maintenance connection to postgres, pg_terminate_backend — and the package unit-tests against in-memory SQLite with no integration marker used anywhere in the repo. So the engine is faked and the statements it is handed are asserted: the lock brackets the work and is released even when the migration raises, view-backed models are left to Alembic (with a guard test so that filter can't silently become a no-op), the maintenance DSN swap happens under AUTOCOMMIT, and the drop evicts other sessions while sparing its own.

Drift is produced the way it arises, not by hand. create rejects an unknown catalog key, so a drifted row can't be written directly. Instead the row is written by a store whose catalog lists the key and read by one whose catalog does not — which reports disabled (the class is still importable) rather than missing. That distinction is the status resolver's, and my first draft got it wrong.

Two guards need a row the schema forbids. A session or token whose profile is gone is unreachable through the store's API — the foreign key blocks it. Those two tests fabricate the orphan with PRAGMA foreign_keys=OFF and a comment saying why: the guard exists for a row that should not be there, so the test proves what it does rather than asserting the guard is dead code.

Store.from_settings — the canonical constructor every long-lived process uses — is covered both ways round: a configured key attaches a cipher that round-trips, and no key logs the warning and leaves the store failing closed rather than writing plaintext.

On the test layout

The package already mirrors correctly, and the mechanical check passes in both directions with no orphans. Three modules gained a file at their mirror path because they carry behaviour beyond declarations:

  • session.py → the dialect dispatch that keeps every upsert portable
  • models/columns.py → the JSONB-on-Postgres / JSON-elsewhere variance the whole schema rests on
  • models/components.pyparent_key and stamp_state

models/auth.py, models/quotas.py and models/tokens.py stay without one. They are field declarations only, already exercised through the stores that write them, and this follows the precedent of models/test_runs.py — which exists for real behaviour (event_metadata), not to restate field definitions. Say the word if you'd rather every module carry a file regardless and I'll add them.

Deliberately left uncovered

The 33 remaining statements are:

  • EventStore.save (7) — compiles Postgres ON CONFLICT DO NOTHING, so SQLite can't reach it. Needs a live Postgres.
  • guards the source itself marks unreachable (# defensive: FKs make this unreachable in hydration.py and components.py)
  • TypeError arms for a quota registered as the wrong type
  • a handful of slot-validation branches in relations.py

Verification

uv run ruff check, uv run ty check, uv run pytest packages/interloper-db (429 passed) and the full workspace suite (2532 passed, 2 skipped) all green; the db suite is stable across three runs. Pre-commit ran the same three hooks on the commit.

By Digitl

Fills the untested surface of interloper-db, closing 223 of its 256
uncovered statements.

Two modules had no tests at all. `engine.py` is straightforward. For
`provision.py` — 18% before — the routines are Postgres-specific (an
advisory lock, a maintenance connection to `postgres`,
`pg_terminate_backend`), and the package unit-tests against in-memory
SQLite with no integration marker anywhere, so the engine is faked and the
statements it is handed are asserted: the lock brackets the work and is
released even when the migration fails, view-backed models are left to
Alembic, the maintenance DSN swap happens, and the drop evicts other
sessions while sparing its own.

The store facets make up the rest. `Store.from_settings` (the canonical
constructor every long-lived process uses) is covered both ways round: a
configured key attaches a working cipher, and no key logs the warning and
leaves the store failing closed. Sessions, membership, invitations, the
backfill progression arms, and the component-drift paths follow.

Drift is exercised the way it arises rather than by hand: `create` rejects
an unknown catalog key, so the row is written by a store whose catalog
lists it and read by one whose catalog does not. That reports `disabled`
(the class is still importable) rather than `missing`, which is the
distinction the status resolver draws.

Two guards are reachable only with an orphaned row — a session or token
whose profile is gone — which the foreign keys prevent. Those are
fabricated with `PRAGMA foreign_keys=OFF` and a comment saying so: the
guard exists for a row that should not be there, and the test proves what
it does rather than asserting the guard is dead.

Three modules gained a test file at their mirror path because they carry
behaviour beyond their declarations: `session.py` (the dialect dispatch
that keeps every upsert portable), `models/columns.py` (the JSONB/JSON
variance the whole schema rests on) and `models/components.py`
(`parent_key`, `stamp_state`). `models/auth.py`, `models/quotas.py` and
`models/tokens.py` stay without one — they are declarations only, already
covered through the stores that write them, following the precedent of
`models/test_runs.py`, which exists for real behaviour rather than for
field definitions.

The 33 statements left are the paths SQLite cannot reach — `EventStore.save`
compiles Postgres `ON CONFLICT` — plus guards marked unreachable in the
source and `TypeError` arms for a misregistered quota.

By Digitl
@aaaaahaaaaa
aaaaahaaaaa merged commit dd529e0 into main Sep 4, 2026
10 checks passed
@aaaaahaaaaa
aaaaahaaaaa deleted the test/interloper-db-coverage branch September 4, 2026 15:51
@codecov

codecov Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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