feat(tests): the conformance suite's sqlite column — the durable-schedule SQL-backed column green (wave 3)
- The first SQL-backed column: the default-build production shape (kv = sqlite + large = local, feature sqlite default-on) runs the form-independent reference rows verbatim (INV-1, INV-6, the NoLivenessSources/ProtectFailed abort shapes, the kv-only rejection row against kv-only(sqlite)) and grows the durable-schedule sweep rows — exact counts asserted relative to the staged schedule (ADR-012 §6.7): two-sweep counts over the full protection set, the race across the window delay (a re-put landing during the window survives the executing sweep), the holder-stages-only lease shape, INV-5 through durable-schedule outcomes, and the schedule-relative INV-2/INV-3 readings - Dispatch rows mirror the local column's family with the placement oracle adapted by medium: the sqlite file's pool/window rows vs the root's committed files; virgin-store reads as no-ops on a fresh file (the no-tables-yet tolerance engine-instrumented, this row its facade form) - Factories: dual-tier sqlite+local and kv-only(sqlite), instance- tracked temp sites (fresh sqlite file + private root per open; idempotent panicking-row-safe teardown), the column-tuned threshold and the test window-delay tuning (Duration::ZERO — execute-on-next- sweep); the module is cfg(feature = "sqlite"), default-on — the column runs in every default cargo test, server-less, never skips - Shared fixtures moved to rows.rs (committed_file_count, staging_file_count, slice_digest, LatchProtect pub(crate)) so the columns share them without the mem gate - README: the schedule-relative reading for SQL-backed columns recorded (citing ADR-012 §6.7), the sqlite rows table inventory, Current state (three columns) Verification: cargo test (default) green — 69 lib + 19 conformance + 3 git-interop; cargo test --features mem green (124 lib + 54 conformance); cargo check --all-features --tests green; cargo clippy --all-targets -- -D warnings green; cargo fmt --check green.
This commit is contained in:
1 parent
fb8326c4d5
commit
3f8e8158a7
6 files changed
+2049
-67
No files matched your search
@@ -46,13 +46,14 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::io::Cursor;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use sha2::{Digest as _, Sha256};
|
||||
|
||||
use crate::factory::StoreFactory;
|
||||
use crate::rows::{self, assert_exact_counts, patterned, Chunked, Failing, SetProtect, SetSource};
|
||||
use crate::rows::{
|
||||
self, assert_exact_counts, committed_file_count, patterned, slice_digest, staging_file_count,
|
||||
Chunked, Failing, SetProtect, SetSource,
|
||||
};
|
||||
use alkblobs::{Error, Key, Store, StoreMode, DEFAULT_DISPATCH_THRESHOLD};
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
@@ -159,55 +160,12 @@ impl StoreFactory for DualTierLocalFactory {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// On-disk observation helpers (the dispatch-coverage shape's medium
|
||||
// oracle; kv = mem never touches this disk, so these counts are
|
||||
// exactly the large tier's committed/staging residency).
|
||||
// On-disk observation helpers live in `rows` (the medium-backed
|
||||
// columns' shared oracle); kv = mem never touches this disk, so the
|
||||
// counts below are exactly the large tier's committed/staging
|
||||
// residency.
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
/// Every regular file under `root` outside any `staging` directory —
|
||||
/// with `kv = mem`, exactly one per committed large-tier entry.
|
||||
fn committed_file_count(root: &Path) -> usize {
|
||||
fn walk(dir: &Path, out: &mut Vec<PathBuf>) {
|
||||
let Ok(entries) = std::fs::read_dir(dir) else {
|
||||
return;
|
||||
};
|
||||
for entry in entries.flatten() {
|
||||
let Ok(kind) = entry.file_type() else {
|
||||
continue;
|
||||
};
|
||||
let path = entry.path();
|
||||
if kind.is_dir() {
|
||||
if path.file_name().and_then(|n| n.to_str()) == Some("staging") {
|
||||
continue;
|
||||
}
|
||||
walk(&path, out);
|
||||
} else if kind.is_file() {
|
||||
out.push(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut files = Vec::new();
|
||||
walk(root, &mut files);
|
||||
files.len()
|
||||
}
|
||||
|
||||
/// Files in the large tier's staging area — the residue counter of the
|
||||
/// exact-count hygiene row (zero after every failure form and every
|
||||
/// success form; a staged artifact lives there only mid-put).
|
||||
fn staging_file_count(root: &Path) -> usize {
|
||||
match std::fs::read_dir(root.join("staging")) {
|
||||
Ok(entries) => entries.count(),
|
||||
Err(_) => 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// The ADR-006 slice digest, computed independently of the crate —
|
||||
/// SHA-256 over exactly the returned bytes (the out-of-band
|
||||
/// verification the convention requires; callers verify the same way).
|
||||
fn slice_digest(bytes: &[u8]) -> [u8; 32] {
|
||||
Sha256::digest(bytes).into()
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// The column's own rows — dispatch coverage (the coverage shape's
|
||||
// reason to exist) and the local-specific properties. Every row takes
|
||||
|
||||
Reference in new issue
Block a user