feat(tests): the conformance suite's postgres column — the first SKIP-posture column green (wave 4)
- The column (tests/conformance/postgres_column.rs, feature `postgres`, default-off): the factories are the alkstore pg-factory pattern reused — `dual-tier postgres+local` (kv = postgres + large = local at the column-declared threshold 1024, window delay `Duration::ZERO`) and `kv-only(postgres)` at 1024 (the rejection row's host); a fresh engine-owned schema per `open()` (unique per call, seeded per tag/pid/time — racing opens included), registry-tracked per instance, teardown `DROP SCHEMA IF EXISTS … CASCADE` over exactly the minted schemas + the vended temp roots (idempotent, owned, panicking-row-safe) - The SKIP posture: connection settings ride the environment (ALKBLOBS_PG_HOST/PORT/USER/PASSWORD/DB), every runner gates behind a reachability probe, server-less runs skip cleanly (a skip is not a failure); the acceptance run is green against the harness server (dockerized `pglo-poc`, :15432 — the alkstore harness's same server) - Rows: the form-independent reference rows mirror verbatim (INV-1, INV-6, the NoLivenessSources/ProtectFailed abort shapes, the kv-only rejection row); the sqlite column's durable-schedule sweep family mirrors (schedule-relative INV-2/INV-3 readings, the two-sweep exact counts over the full protection set, the race across the window delay, the holder-stages-only lease shape, INV-5 list correctness); the dispatch rows adapt the placement oracle by medium (independent- connection counts of the schema's rows vs the root's committed files) plus the virgin-store row; every row ADR-stamped, traced to the backlog - Structural factory tests: fresh isolated opens (two opens mint distinct schemas and share nothing) and teardown against a panicking row (schemas really dropped, pg_namespace-verified) - README amended: the postgres rows table in §Columns beyond the reference set; the column plan's SKIP-posture note names the landed column; current state (four columns, waves 2–4) Verification: cargo test (default) 69/19/3 ok — the column compiles out; cargo test --features postgres 102/36/3 ok against the harness server (and green skipping server-less); cargo clippy --all-targets -- -D warnings green (default, postgres, all-features); cargo fmt --check green; pg_namespace verified schema-clean after live runs.
This commit is contained in:
1 parent
67b927b13c
commit
0fb05fce3a
4 files changed
+2229
-8
No files matched your search
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: suite-column-postgres
|
||||
name: Conformance suite — the postgres column (the SKIP-posture column)
|
||||
status: pending
|
||||
status: completed
|
||||
depends_on: [store-postgres-construction]
|
||||
scope: moderate
|
||||
risk: medium
|
||||
@@ -121,8 +121,78 @@ server**). The column runs under `--features postgres` (feature
|
||||
|
||||
## Notes
|
||||
|
||||
> To be filled by implementation agent
|
||||
> Implemented in `tests/conformance/postgres_column.rs` + `main.rs` +
|
||||
> `README.md` (wave 4, following `suite-column-sqlite` — the
|
||||
> SQL-backed structural twin — and the alkstore pg-factory pattern).
|
||||
> Recorded design points, as resolved:
|
||||
>
|
||||
> - **Factories as specced** — `DualTierPostgresFactory` (kv = postgres
|
||||
> + large = local at the column-declared `TUNED_THRESHOLD` = 1024,
|
||||
> window delay `WINDOW_DELAY` = `Duration::ZERO`, the test tuning)
|
||||
> and `KvOnlyPostgresFactory` (`KV_ONLY_THRESHOLD` = 1024, the
|
||||
> rejection row's host). Both hold the DSN, a schema sequence
|
||||
> counter, and the per-instance schema registry (`Mutex<Vec<String>>,
|
||||
> poisoned-lock via `unwrap_or_else(|e| e.into_inner())` per
|
||||
> convention); `open()` mints `alkblobs_suite_{tag}_{pid}_{nanos}_{seq}`
|
||||
> — unique per call, racing opens included — plus a fresh private
|
||||
> temp root for the large tier (dual-tier; kv-only needs none),
|
||||
> tracked per-instance. Teardown `DROP SCHEMA IF EXISTS "…" CASCADE`
|
||||
> over exactly the minted schemas (one admin connection, then the
|
||||
> drops) plus `remove_dir_all` over the vended roots (NotFound
|
||||
> tolerated) — idempotent, owned, panicking-row-safe.
|
||||
> - **SKIP posture as specced** — `harness_dsn()` rides
|
||||
> `ALKBLOBS_PG_HOST/PORT/USER/PASSWORD/DB` (host required, non-empty;
|
||||
> port/user/password/db defaulting to the harness server's values —
|
||||
> :15432, `postgres`/`poc`, db `blobs` — the src/postgres.rs engine
|
||||
> tests' exact convention, the alkblobs adaptation of the alkstore
|
||||
> harness convention), `harness_ready()` probes with a 3 s-timed
|
||||
> admin connection, every runner gates on it first, and the skip
|
||||
> note prints once per skipped test. The acceptance run below is
|
||||
> against the harness server — a skip never substituted.
|
||||
> - **The medium oracle, adapted by medium** — an independent admin
|
||||
> connection per count (`SELECT COUNT(*) FROM "schema".blobs` /
|
||||
> `gc_window`) vs the root's committed files; `schema_exists` (the
|
||||
> `pg_namespace` probe) instruments the structural teardown
|
||||
> assertions.
|
||||
> - **Rows** — the sqlite column's inventory mirrored point for point
|
||||
> (the schedule-relative rows, the dispatch rows with the oracle's
|
||||
> medium swapped, the virgin-store row read against a fresh schema,
|
||||
> the structural factory tests adapted to schemas: two opens mint
|
||||
> distinct schemas and share nothing, teardown-against-a-panicking
|
||||
> row really drops the schemas); stamps cite the postgres rows of
|
||||
> ADR-007/012 (ADR-007 §5 replacing the sqlite arm's citations).
|
||||
> - **One cleanup caught in review-of-diff**: the `dual_tier` open
|
||||
> tracks the temp *base* dir and constructs the store against
|
||||
> `base.join("local-root")` — teardown removes the base directory
|
||||
> wholesale (the root's parent), so the site removal is one
|
||||
> operation like the sqlite column's.
|
||||
> - The `pglo-poc` container was already running in the dev
|
||||
> environment (verified with `docker ps` before implementation); no
|
||||
> environment changes were needed.
|
||||
|
||||
## Summary
|
||||
|
||||
> To be filled on completion
|
||||
> Completed 2026-10-12 (wave 4). The postgres column — the suite's
|
||||
> first SKIP-posture column — landed green against the harness server
|
||||
> (`pglo-poc`, :15432): 17 conformance tests (the mirrored
|
||||
> form-independent reference rows — INV-1 round-trips, INV-6 stat
|
||||
> discipline, the `NoLivenessSources`/`ProtectFailed` abort shapes,
|
||||
> the kv-only rejection row — the durable-schedule sweep rows (INV-2
|
||||
> and INV-3 schedule-relative readings, the two-sweep exact-count row
|
||||
> over the full protection set, the sweep-vs-put race across the
|
||||
> window delay, the holder-stages-only lease shape, INV-5 list
|
||||
> correctness), the dispatch rows with the placement oracle adapted to
|
||||
> the pg medium, and the virgin-store row), every row ADR-stamped and
|
||||
> traced to the backlog. Factory isolation (fresh schema per open,
|
||||
> registry-tracked) and idempotent `DROP SCHEMA … CASCADE` teardown
|
||||
> are structurally exercised (panicking-row-safe; `pg_namespace`
|
||||
> verified empty after runs — the shared server carries no residue).
|
||||
> README amended: the postgres rows table in §Columns beyond the
|
||||
> reference set, the column plan's SKIP-posture note naming the
|
||||
> landed column, and current state (four columns). Verification:
|
||||
> `cargo test` (default) 69/19/3 ok — the column compiles out;
|
||||
> `cargo test --features postgres` 102/36/3 ok green against the
|
||||
> server, and green skipping server-less (17 skip-noted columns rows;
|
||||
> default-build gates unaffected); `cargo clippy --all-targets -- -D
|
||||
> warnings` green (default, `--features postgres`, `--all-features`);
|
||||
> `cargo fmt --check` green.
|
||||
@@ -295,19 +295,62 @@ legal degenerate tuning, `Duration::ZERO` — execute-on-next-sweep):
|
||||
the schedule the durable rows assert against is exactly the
|
||||
next-sweep executor form.
|
||||
|
||||
**The postgres column's own rows** (tests/conformance/postgres_column.rs,
|
||||
the first SKIP-posture column — the fleet-capable-kv shape, `kv =
|
||||
postgres` + `large = local`, feature `postgres` default-off,
|
||||
ADR-007/012 §5): the **durable-schedule sweep rows** mirror the sqlite
|
||||
column's family (§The schedule-relative reading for SQL-backed
|
||||
columns; ADR-012 §6.7 — the same window delay tuning, `0` —
|
||||
execute-on-next-sweep) and the dispatch rows with the placement
|
||||
oracle adapted by medium again — kv entries live as rows in the pg
|
||||
schema's `blobs` table, large entries under the local root (an
|
||||
independent connection counting the schema's rows vs the root's
|
||||
committed files; the column's own rows also watch the schedule
|
||||
itself, the schema's `gc_window` rows). The form-independent
|
||||
reference rows mirror verbatim: the INV-1 round-trip family and the
|
||||
INV-6 stat-discipline row against the dual-tier factory, the
|
||||
`NoLivenessSources`/`ProtectFailed` abort shapes (form-independent —
|
||||
abort before staging), and the kv-only rejection row against a
|
||||
`kv-only(postgres)` factory (threshold-agnostic by discovery,
|
||||
unchanged; the threshold materializable per the configuration
|
||||
contract). Connection settings ride the environment
|
||||
(`ALKBLOBS_PG_HOST/PORT/USER/PASSWORD/DB`) and the runners gate
|
||||
behind a reachability probe; the factories follow the alkstore
|
||||
pg-factory pattern (alkstore-postgres `contract_suite.rs`): a fresh
|
||||
engine-owned schema per `open()`, tracked per-instance, teardown
|
||||
`DROP SCHEMA IF EXISTS … CASCADE` over exactly the minted schemas
|
||||
(idempotent, owned, panicking-row-safe — `CASCADE` removes
|
||||
dependents server-side while the abandoned store's pooled
|
||||
connections fail closed on next use).
|
||||
|
||||
| Row (`postgres_column.rs`) | Traces to |
|
||||
|---|---|
|
||||
| `dedup_identical_content_is_one_pool_entry` | INV-2 (same-path and cross-path legs; counts read against the durable schedule) |
|
||||
| `stage_hygiene_zero_residue_on_failure_exactly_one_entry_on_success` | INV-3 (both put paths, both failure modes; schedule-relative counts) |
|
||||
| `two_sweep_exact_counts_over_the_full_protection_set` | INV-4/INV-5 (the full protection set across two sweeps — staged this sweep, executed by the next; the both-tiers form) |
|
||||
| `a_put_landing_during_the_window_survives_the_executing_sweep` | INV-4 (the sweep-vs-put race across the window delay; execution-time re-arbitration) |
|
||||
| `the_contended_second_sweeper_aborts_as_data_and_the_holder_stages_only` | INV-4 (the `SweeperLock` abort shape — abort before staging; the holder's durable-form completion: stages only) |
|
||||
| `list_correctness_is_observable_through_durable_schedule_outcomes` | INV-5 (exact counts, never list comparison) |
|
||||
| `routing_is_a_pure_function_of_length_across_put_paths_and_re_puts` | ADR-003 §Dispatch policy (purity/no-migration); ADR-012 §6.3; ADR-012 §6.7 (schedule-relative dedup legs); ADR-007 §5; INV-7 facade-contract row |
|
||||
| `threshold_boundary_lengths_route_deterministically` | ADR-003 §Dispatch policy (at/below/above, tuned + shipped-default thresholds); ADR-012 §6.3; ADR-007 §5 |
|
||||
| `kv_tier_misses_fall_through_to_the_large_tier_per_op` | ADR-012 §6.1 (fall-through per op); ADR-012 §6.5 ruling 5 (miss shapes); ADR-006; ADR-012 §6.3; ADR-007 §5 |
|
||||
| `virgin_store_reads_are_no_ops_on_a_fresh_schema` | store-api.md §Error model (virgin-store semantics); ADR-012 §6.5; ADR-007 §5 (the constructor always ensures the schema — the facade's fresh-schema form of the tolerance) |
|
||||
|
||||
## Column plan
|
||||
|
||||
**mem is the contract-reference engine** (ADR-011 §2): wave 2 lands
|
||||
its column first (the first column binds the `Store` facade type), and
|
||||
every other engine's rows mirror mem's column — an addition to mem's
|
||||
column propagates as a requirement to all other columns (INV-7). The
|
||||
pg columns (postgres, pg-lo) additionally run the SKIP posture above;
|
||||
the fleet-form rows of INV-4 are engine-gated to the postgres column
|
||||
and first run in wave 6.
|
||||
pg columns (postgres, pg-lo) additionally run the SKIP posture above —
|
||||
the **postgres column is the posture's first landed host** (server-less
|
||||
runs skip cleanly; its wave-4 acceptance is the green run against the
|
||||
harness server); the fleet-form rows of INV-4 are engine-gated to the
|
||||
postgres column and first run in wave 6.
|
||||
|
||||
## Current state
|
||||
|
||||
The harness is green on **three columns** (waves 2–3). The **mem
|
||||
The harness is green on **four columns** (waves 2–4). The **mem
|
||||
column** is the contract-reference column: the factory binding is the
|
||||
concrete `alkblobs::Store` facade (see §The factory contract — the
|
||||
binding demonstrator remains in `binding.rs`), the reference row set
|
||||
@@ -361,3 +404,30 @@ default build: every `cargo test` run exercises it. The sqlite
|
||||
engine's no-tables-yet read tolerance is engine-instrumented
|
||||
(src/sqlite.rs's tests; the constructor-vs-lazy timing design point
|
||||
there), the column's virgin-store row being its facade form.
|
||||
|
||||
The **postgres column** (the suite's **first SKIP-posture column** —
|
||||
the fleet-capable-kv shape, `kv = postgres` + `large = local`, feature
|
||||
`postgres` **default-off**, ADR-007/013 §4, landed wave 4) mirrors the
|
||||
form-independent reference rows (INV-1, INV-6, the
|
||||
`NoLivenessSources`/`ProtectFailed` abort shapes, and the kv-only
|
||||
rejection row against `kv-only(postgres)`) and grows the sqlite
|
||||
column's durable-schedule sweep rows plus the dispatch rows with the
|
||||
placement oracle adapted by medium (an independent connection counts
|
||||
the pg schema's `blobs` rows vs the root's committed files; the
|
||||
column's own rows watch the schedule's `gc_window` rows) and the
|
||||
virgin-store row — the recorded inventory is in §Columns beyond the
|
||||
reference set. Its factories declare the column-tuned threshold and
|
||||
the test tuning of the window delay (`Duration::ZERO` —
|
||||
execute-on-next-sweep) and follow the alkstore pg-factory pattern: a
|
||||
fresh engine-owned schema per `open()` (unique per call, seeded per
|
||||
tag/pid/time — racing opens included), tracked per-instance in the
|
||||
schema registry, teardown `DROP SCHEMA IF EXISTS … CASCADE` over
|
||||
exactly the minted schemas plus removal of every vended temp root
|
||||
(idempotent, owned, panicking-row-safe; each runner owns its
|
||||
instance). The column **skips cleanly server-less** under the
|
||||
reachability probe (`ALKBLOBS_PG_HOST` gating; the remaining
|
||||
settings default to the harness server's values) — a skip is not a
|
||||
failure — and its acceptance is the green run **against the harness
|
||||
server** (dockerized `pglo-poc`, `postgres:16-alpine`, :15432, db
|
||||
`blobs`, verified live 2026-10-12; the alkstore harness's same
|
||||
server).
|
||||
@@ -30,7 +30,10 @@
|
||||
//! shape, `kv = sqlite` + `large = local`), which mirrors the
|
||||
//! form-independent reference rows and grows the durable-schedule
|
||||
//! sweep rows (README §The schedule-relative reading for SQL-backed
|
||||
//! columns).
|
||||
//! columns); [`postgres_column`] — the suite's first SKIP-posture
|
||||
//! column (the fleet-capable-kv shape, `kv = postgres` + `large =
|
||||
//! `local`, feature `postgres` default-off), which mirrors the same
|
||||
//! sets against the harness server and skips cleanly server-less.
|
||||
//!
|
||||
//! Items beyond the tests below are the later columns' surface, hence
|
||||
//! the scoped `#![allow(dead_code)]` — it shrinks as columns land.
|
||||
@@ -45,6 +48,8 @@ mod factory;
|
||||
mod local_column;
|
||||
#[cfg(feature = "mem")]
|
||||
mod mem_column;
|
||||
#[cfg(feature = "postgres")]
|
||||
mod postgres_column;
|
||||
mod rows;
|
||||
#[cfg(feature = "sqlite")]
|
||||
mod sqlite_column;
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user