feat(tests): the conformance suite's local column — the dual-tier dispatch-coverage shape green (wave 2)
- tests/conformance/local_column.rs: the first dual-tier column, run against the kv = mem + large = local factory (ADR-012 §6.3) — fresh temp-root store per open, per-instance tracked roots, idempotent teardown safe against abandoned/panicking rows (structural tests included); never skips (mem-gated — the dual-tier constructor rides feature mem until wave 3 provides an ungated kv engine) - the reference INV row set (rows.rs) mirrored against the dual-tier factory at a column-declared tuned threshold (1024), so the shared matrix and race fixtures exercise both tiers' bodies (INV-7) - dispatch rows grown: pure-function routing across put paths and re-puts with an on-disk placement oracle (tier residency is facade-invisible; with kv = mem the medium is the oracle), threshold boundary legs at the tuned and shipped-default thresholds with the constructor-tuned re-route leg, and fall-through per op with both-tier miss shapes (ADR-003/ADR-012 §6.1/§6.3/§6.5) - local-specific rows: on-disk stage-hygiene exact counts over both put paths (the real stage form, INV-3), pread windows over committed files with slice digests verified independently (ADR-006/ADR-010), virgin-store no-ops on a fresh root, and exact sweep counts over a both-tiers pool (INV-4/INV-5's both-tiers form) - rows.rs shared fixtures made pub(crate); README records the column's row inventory (§Columns beyond the reference set), the declared- threshold posture, and the new current state - stat-as-stat rides the mirrored INV-6 row's over-threshold legs; the Drop-cancellation hygiene form stays per-engine (recorded) Verification: cargo test (default) green; cargo test --features mem green (97 lib + 37 conformance + 4 git-interop); cargo test --all-features green; clippy --all-targets -D warnings green in both feature shapes (default + all-features); cargo fmt --check green; cargo doc --no-deps shows only the pre-existing warning class
This commit is contained in:
1 parent
f86e20a217
commit
45c456989f
5 files changed
+1560
-43
No files matched your search
+22
-17
@@ -52,24 +52,25 @@ use alkblobs::{
|
||||
///
|
||||
/// A set-backed liveness source — the live-shared seam's test shape:
|
||||
/// the store consults the same set the row mutates, so answers are
|
||||
/// live-shared, never registration snapshots.
|
||||
/// live-shared, never registration snapshots. `pub(crate)`: the
|
||||
/// suite's other columns reuse these fixtures.
|
||||
#[derive(Default)]
|
||||
struct SetSource {
|
||||
pub(crate) struct SetSource {
|
||||
live: Mutex<BTreeSet<Key>>,
|
||||
}
|
||||
|
||||
impl SetSource {
|
||||
fn register(store: &Store) -> Arc<SetSource> {
|
||||
pub(crate) fn register(store: &Store) -> Arc<SetSource> {
|
||||
let source = Arc::new(SetSource::default());
|
||||
store.register_liveness_source(source.clone());
|
||||
source
|
||||
}
|
||||
|
||||
fn add(&self, key: Key) {
|
||||
pub(crate) fn add(&self, key: Key) {
|
||||
self.live.lock().insert(key);
|
||||
}
|
||||
|
||||
fn remove(&self, key: &Key) {
|
||||
pub(crate) fn remove(&self, key: &Key) {
|
||||
self.live.lock().remove(key);
|
||||
}
|
||||
}
|
||||
@@ -87,16 +88,16 @@ impl LivenessSource for SetSource {
|
||||
/// A set-backed protect callback; `None` models the failed-to-answer
|
||||
/// case (abort-as-data on the safe side).
|
||||
#[derive(Default)]
|
||||
struct SetProtect {
|
||||
pub(crate) struct SetProtect {
|
||||
set: Mutex<Option<Vec<Key>>>,
|
||||
}
|
||||
|
||||
impl SetProtect {
|
||||
fn set_keys(&self, keys: Vec<Key>) {
|
||||
pub(crate) fn set_keys(&self, keys: Vec<Key>) {
|
||||
*self.set.lock() = Some(keys);
|
||||
}
|
||||
|
||||
fn fail(&self) {
|
||||
pub(crate) fn fail(&self) {
|
||||
*self.set.lock() = None;
|
||||
}
|
||||
}
|
||||
@@ -129,15 +130,15 @@ impl ProtectCallback for LatchProtect {
|
||||
/// A stream cut at controlled chunk boundaries (`sizes`, in order;
|
||||
/// tail data falls out whole) — makes multi-read loops, mid-stream
|
||||
/// overflow, and staged continuation observable past the put loop's
|
||||
/// own chunking.
|
||||
struct Chunked {
|
||||
/// own chunking. `pub(crate)`: the suite's other columns reuse it.
|
||||
pub(crate) struct Chunked {
|
||||
data: Vec<u8>,
|
||||
cursor: usize,
|
||||
sizes: std::collections::VecDeque<usize>,
|
||||
}
|
||||
|
||||
impl Chunked {
|
||||
fn new(data: &[u8], sizes: &[usize]) -> Chunked {
|
||||
pub(crate) fn new(data: &[u8], sizes: &[usize]) -> Chunked {
|
||||
Chunked {
|
||||
data: data.to_vec(),
|
||||
cursor: 0,
|
||||
@@ -177,15 +178,15 @@ impl AsyncRead for Chunked {
|
||||
|
||||
/// A stream that delivers `fail_after` bytes then errors mid-stream —
|
||||
/// the non-restartable source's failure (the failure-discard path's
|
||||
/// injectable shape).
|
||||
struct Failing {
|
||||
/// injectable shape). `pub(crate)`: the suite's other columns reuse it.
|
||||
pub(crate) struct Failing {
|
||||
data: Vec<u8>,
|
||||
cursor: usize,
|
||||
fail_after: usize,
|
||||
}
|
||||
|
||||
impl Failing {
|
||||
fn new(data: &[u8], fail_after: usize) -> Failing {
|
||||
pub(crate) fn new(data: &[u8], fail_after: usize) -> Failing {
|
||||
Failing {
|
||||
data: data.to_vec(),
|
||||
cursor: 0,
|
||||
@@ -247,14 +248,18 @@ fn matrix() -> Vec<Vec<u8>> {
|
||||
]
|
||||
}
|
||||
|
||||
fn patterned(len: usize, modulus: u32) -> Vec<u8> {
|
||||
/// A content-shape generator: `len` bytes cycling against `modulus` —
|
||||
/// deterministic, size-tunable content. `pub(crate)`: the suite's
|
||||
/// other columns reuse it.
|
||||
pub(crate) fn patterned(len: usize, modulus: u32) -> Vec<u8> {
|
||||
(0..len as u32).map(|i| (i % modulus) as u8).collect()
|
||||
}
|
||||
|
||||
/// One leg of the exact-count sweep assertions: a completed report's
|
||||
/// counts are exact over the staged set (`candidates_staged ==
|
||||
/// deleted + cancelled_by_arbitration`).
|
||||
fn assert_exact_counts(report: &alkblobs::SweepReport) {
|
||||
/// deleted + cancelled_by_arbitration`). `pub(crate)`: the suite's
|
||||
/// other columns reuse it.
|
||||
pub(crate) fn assert_exact_counts(report: &alkblobs::SweepReport) {
|
||||
assert_eq!(
|
||||
report.candidates_staged,
|
||||
report.deleted + report.cancelled_by_arbitration,
|
||||
|
||||
Reference in new issue
Block a user