docs(bf-59oct): map inline Mode A tests to bf-30m2j acceptance criteria
Coverage-map bead (step 2, parent bf-1zn8a, grandparent bf-30m2j). For each of bf-30m2j's five acceptance criteria, cites the covering inline test + specific assertion (file:line), or marks the genuine GAP: - C1 COVERED — current API (with_mode_a/ModeACoordinator::new), no with_mode_a_scaling - C2 COVERED — exactly-one-owner anti_entropy.rs:1622-1635 (owner_count==1, total_owned==64) - C3 COVERED core / GAP minimal-reshuffle — pod-reassignment anti_entropy.rs:1714-1755 - C4 GAP — module is #[cfg(feature=peer-discovery)]-gated, non-default; not in plain cargo test - C5 orthogonal action item — inline tests live in src/, not the p13_8 tests/ file Proves acceptance_4 is redundant; directs later siblings at the narrow gaps (survivor-stability, scale-up, hash-vector, default-feature discoverability) and the stale-comment edit rather than a redundant rewrite. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
47f2b1d5ec
commit
a05055b8ad
1 changed files with 151 additions and 0 deletions
151
notes/bf-59oct.md
Normal file
151
notes/bf-59oct.md
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
# bf-59oct — Map each inline Mode A test → grandparent bf-30m2j acceptance criteria
|
||||
|
||||
Coverage-map bead. Parent umbrella **bf-1zn8a**, grandparent **bf-30m2j**.
|
||||
Step 2 of the coverage investigation; builds on the empirical test-run evidence
|
||||
in sibling **bf-qvrmh** (which re-confirmed the three tests execute + pass).
|
||||
|
||||
This note is the crisp, decisive, per-test assertion-cited coverage map: for each
|
||||
of grandparent bf-30m2j's **five** acceptance criteria, which of the three inline
|
||||
tests covers it (with the specific assertion + `file:line`), and where the genuine
|
||||
gap is. The point is to prove the disabled `acceptance_4`'s criteria are already
|
||||
covered inline so later siblings attack the *narrow* gap instead of rewriting a
|
||||
redundant test.
|
||||
|
||||
## Test inventory (`crates/miroir-core/src/anti_entropy.rs`, mod `tests_mode_a_acceptance`)
|
||||
|
||||
Whole module is gated `#[cfg(all(test, feature = "peer-discovery"))]` @
|
||||
`anti_entropy.rs:1532`. All three are plain `#[tokio::test]` (no `#[ignore]`),
|
||||
run against the in-memory `crate::scatter::MockNodeClient` (no docker).
|
||||
|
||||
| Task shorthand | Actual fn | Location |
|
||||
|---|---|---|
|
||||
| exactly-one-owner | `test_mode_a_three_pods_each_shard_processed_once` | `anti_entropy.rs:1541` |
|
||||
| pod-reassignment | `test_mode_a_pod_reassignment` | `anti_entropy.rs:1665` |
|
||||
| partitioning-wiring | `test_mode_a_anti_entropy_partitioning` | `anti_entropy.rs:1761` |
|
||||
|
||||
All three exercise the **current** API, not the removed `with_mode_a_scaling`:
|
||||
`ModeACoordinator::new` + `PeerDiscovery::new` + `PeerSet::new` +
|
||||
`set_peer_set_for_test` (`mode_a_coordinator.rs:306`) + `with_mode_a`
|
||||
(`anti_entropy.rs:199`). Assertions query `ModeACoordinator::owns_shard`
|
||||
(`mode_a_coordinator.rs:151`) → `owner_for_shard` (`:123`, top-1 by score) →
|
||||
`rendezvous_score` (`:112`) = `XxHash64(shard_id || "||" || peer_id)` — i.e.
|
||||
exactly `top1_by_score(hash(s ‖ pid))` from plan §14.5 (`plan.md:3520`).
|
||||
|
||||
## Coverage map (grandparent bf-30m2j criteria 1-5)
|
||||
|
||||
### Criterion 1 — Rewrite/reinstate `acceptance_4` using current `ModeACoordinator`/`peer_discovery` API (not removed `with_mode_a_scaling`) — **[COVERED]**
|
||||
|
||||
The criterion's substance ("exercise the current API, not the deleted
|
||||
`with_mode_a_scaling`") is satisfied by all three tests. No `with_mode_a_scaling`
|
||||
symbol exists in the tree (only `with_mode_a` @ `anti_entropy.rs:199`):
|
||||
|
||||
- **partitioning-wiring** — `ModeACoordinator::new` @ `anti_entropy.rs:1768`;
|
||||
`with_mode_a(coordinator)` @ `anti_entropy.rs:1790`.
|
||||
- **exactly-one-owner** — `ModeACoordinator::new` @ `anti_entropy.rs:1548/1555/1562`;
|
||||
`with_mode_a(coordinator_{1,2,3})` @ `anti_entropy.rs:1581/1584/1587`.
|
||||
- **pod-reassignment** — `ModeACoordinator::new` @ `anti_entropy.rs:1672/1679/1686`.
|
||||
|
||||
The "API drift" the parent cites is already resolved in-tree; any rewrite of
|
||||
`acceptance_4` would duplicate this. (The *literal act* of deleting the dead
|
||||
`acceptance_4` is a cleanup, see criterion 5.)
|
||||
|
||||
### Criterion 2 — Each shard owned by EXACTLY ONE pod (no double-ownership, no orphan), matching `top1_by_score(hash(shard_id ‖ pod_id))` — **[COVERED by exactly-one-owner: anti_entropy.rs:1622-1635]**
|
||||
|
||||
- **No double-ownership:** per-shard `assert_eq!(owner_count, 1, …)` @
|
||||
`anti_entropy.rs:1622-1626` (counts how many of the 3 pods return
|
||||
`owns_shard == true` for each shard).
|
||||
- **No orphan:** `assert_eq!(total_owned, 64, …)` @ `anti_entropy.rs:1631-1635`
|
||||
(sum of pod1/pod2/pod3 shard counts == 64).
|
||||
- **Even distribution (supplementary):** `min_owned >= 15`, `max_owned <= 25` @
|
||||
`anti_entropy.rs:1649-1658`.
|
||||
- **Hash match:** `owns_shard` resolves through `owner_for_shard` (top-1) +
|
||||
`rendezvous_score` = `XxHash64(shard_id ‖ peer_id)` (`mode_a_coordinator.rs:112-145`),
|
||||
the exact `top1_by_score(hash(s ‖ pid))` of plan §14.5.
|
||||
|
||||
Reinforced by **pod-reassignment** @ `anti_entropy.rs:1733-1737`
|
||||
(`owner_count == 1` on pod-3's former shards) and `:1751-1755` (`total_owned == 64`).
|
||||
|
||||
### Criterion 3 — Ownership redistributes (minimal reshuffling) when peer set changes size — **[COVERED for the core; "minimal reshuffling" sub-clause is a narrow GAP]**
|
||||
|
||||
Core assertion covered by **pod-reassignment: anti_entropy.rs:1714-1755**:
|
||||
|
||||
- **Peer set shrinks 3→2:** `PeerSet::new(["pod-1","pod-2"])` +
|
||||
`set_peer_set_for_test` @ `anti_entropy.rs:1714-1721`.
|
||||
- **Redistribution asserted:** every shard pod-3 previously owned (captured @
|
||||
`:1705-1711`) is now owned by exactly one of pod-1/pod-2 — `assert_eq!(owner_count, 1)`
|
||||
@ `anti_entropy.rs:1733-1737`.
|
||||
- **Full coverage preserved:** `assert_eq!(total_owned, 64, …)` @
|
||||
`anti_entropy.rs:1751-1755`.
|
||||
|
||||
> **Narrow GAP (the "minimal reshuffling" sub-clause):** the test records only
|
||||
> pod-3's initial shards (`:1705-1711`) and re-checks only those. It never records
|
||||
> pod-1/pod-2's initial shards and asserts they are **unchanged** after the resize.
|
||||
> A buggy impl that reshuffled *all* shards on every peer-set change — while still
|
||||
> preserving exactly-one-owner + full coverage — would pass. This is parent
|
||||
> bf-1zn8a's gap (a): survivor-stability / minimal-reshuffling un-pinned for the
|
||||
> Mode A background-work ownership path. (Also no 3→4 scale-up case exists — gap (b).)
|
||||
|
||||
So: the literal criterion-3 head ("ownership redistributes when peer set changes
|
||||
size") = **COVERED**; the parenthetical "minimal reshuffling" qualifier = **GAP**.
|
||||
|
||||
### Criterion 4 — Test runs in default `cargo test` without `--ignored` or docker — **[GAP for "default cargo test"; sub-parts covered]**
|
||||
|
||||
- **No `#[ignore]`:** ✓ — plain `#[tokio::test]` @ `anti_entropy.rs:1540/1664/1760`.
|
||||
- **No docker:** ✓ — in-memory `MockNodeClient` @ `anti_entropy.rs:1577/1787`;
|
||||
synthetic peer set via `set_peer_set_for_test` (`mode_a_coordinator.rs:306`), no
|
||||
SRV/DNS.
|
||||
- **"Default `cargo test`":** **GAP.** The module is
|
||||
`#[cfg(all(test, feature = "peer-discovery"))]` @ `anti_entropy.rs:1532`, and
|
||||
`peer-discovery` is a **non-default** feature (`default = []` @
|
||||
`crates/miroir-core/Cargo.toml:67`; `peer-discovery = ["trust-dns-resolver"]` @
|
||||
`:71`). Plain `cargo test -p miroir-core mode_a` compiles **0** of these tests
|
||||
(confirmed empirically by sibling bf-qvrmh, RUN 1). They execute + pass only
|
||||
under `cargo test -p miroir-core --features peer-discovery` or `make test`
|
||||
(`--all-features`, `Makefile:8`).
|
||||
|
||||
⇒ **This is the genuine remaining gap** the later siblings should resolve. It is
|
||||
*not* "rewrite acceptance_4" — it is "make the Mode A partitioning tests
|
||||
discoverable/runnable in default `cargo test`" (e.g. move the module off the
|
||||
`peer-discovery` gate; the coordinator only needs `set_peer_set_for_test`, which
|
||||
already avoids SRV). This is the real narrow gap, per bf-1zn8a recommendation #5.
|
||||
|
||||
### Criterion 5 — Update/remove stale comment at `crates/miroir-core/tests/p13_8_anti_entropy.rs:240-244` — **[orthogonal action item, NOT a coverage item]**
|
||||
|
||||
The inline tests live in `src/anti_entropy.rs`, not in the `tests/p13_8_anti_entropy.rs`
|
||||
file. The stale comment @ `p13_8_anti_entropy.rs:241-244` still claims the disabled
|
||||
`acceptance_4_mode_a_shard_partitioning` "uses an old API (`with_mode_a_scaling`)"
|
||||
and "requires the peer-discovery feature and ModeACoordinator" — now misleading
|
||||
since the live replacement exists at `anti_entropy.rs:1532-1798`. It cannot be
|
||||
"covered" by the inline suite; it is a standalone ~4-line edit (point at the
|
||||
inline module, drop the dead `acceptance_4` reference). Track as its own action
|
||||
under bf-1zn8a recommendation #4 — **not** marked [GAP] against the inline tests.
|
||||
|
||||
## Verdict matrix
|
||||
|
||||
| # | Criterion | Verdict | Covering test : line | Key assertion |
|
||||
|---|---|---|---|---|
|
||||
| 1 | Current API (not `with_mode_a_scaling`) | **[COVERED]** | partitioning-wiring `:1790`; exactly-one-owner `:1581-1587`; pod-reassignment `:1672-1686` | `with_mode_a` / `ModeACoordinator::new` |
|
||||
| 2 | Exactly-one owner, no double/orphan, `top1_by_score(hash(s‖pid))` | **[COVERED]** | exactly-one-owner `:1622-1635` | `owner_count == 1`, `total_owned == 64` |
|
||||
| 3 | Redistribution on peer-set change (minimal reshuffling) | **[COVERED] core / [GAP] minimal-reshuffle** | pod-reassignment `:1714-1755` | `owner_count == 1` @ `:1733`, `total_owned == 64` @ `1751` |
|
||||
| 4 | Runs in default `cargo test`, no `--ignored`/docker | **[GAP] (default `cargo test`); sub-parts ✓** | — | gated `#[cfg(… feature = "peer-discovery")]` @ `anti_entropy.rs:1532`, `default = []` `Cargo.toml:67` |
|
||||
| 5 | Update stale comment `p13_8:240-244` | **orthogonal action item** | — | inline tests are in `src/`, not the `tests/` file |
|
||||
|
||||
## Bottom line
|
||||
|
||||
- **Criteria 1, 2:** fully covered inline.
|
||||
- **Criterion 3:** core covered inline; the *minimal-reshuffling / survivor-stability*
|
||||
sub-clause is the genuine narrow gap (a) — the thing a follow-on sibling should
|
||||
add (record pod-1/pod-2 initial shards, assert unchanged after resize).
|
||||
- **Criterion 4:** the *default-`cargo-test`* requirement is the other genuine gap —
|
||||
the suite is feature-gated behind non-default `peer-discovery`. Fixing
|
||||
discoverability (not rewriting a test) is the sibling work.
|
||||
- **Criterion 5:** orthogonal cleanup edit, not a coverage item.
|
||||
|
||||
The disabled `acceptance_4` is **redundant** — do not rewrite it. Direct later
|
||||
siblings at gaps (a) survivor-stability, (b) 3→4 scale-up, (c) pinned hash-vector,
|
||||
(4) default-feature discoverability, and the criterion-5 comment edit.
|
||||
|
||||
## Cross-refs
|
||||
|
||||
- `notes/bf-qvrmh.md` — empirical "do the three tests run?" foundation (RUN 1-4).
|
||||
- `notes/bf-1zn8a.md` — parent umbrella; full Step 2 map + gaps (a)/(b)/(c).
|
||||
Loading…
Add table
Reference in a new issue