//! The **sqlite column** — the suite's first SQL-backed column: the //! reference row set run against the default-build production shape //! (`kv = sqlite` + `large = local`; feature `sqlite` is default-on, //! ADR-007, ADR-013 §4), extended with the **durable-schedule sweep //! rows** and the dispatch rows (README §Columns beyond the reference //! set; INV-7: every engine's rows mirror the reference column). //! //! The sweep rows are **schedule-relative on this column** (the //! README §The schedule-relative reading for SQL-backed columns is //! the recorded amendment, citing ADR-012 §6.7): the reference set's //! single-sweep exact-count rows are the inline-form host's — the //! durable form stages its candidates this sweep and executes them by //! the next, so the exact counts here are asserted against the staged //! schedule. The form-independent rows mirror verbatim //! ([`crate::rows`]: the round-trip family, the stat-discipline row, //! the no-sources and failed-protect abort shapes, and the kv-only //! rejection row against the kv-only factory); the schedule-relative //! properties grew their own rows below (dedup and stage hygiene //! observe their invariants through sweep outcomes, so they read //! against the schedule too). Mem-only never mirrors here: the mode //! is not constructible without mem. //! //! The factories (README §The factory contract): `open()` vends the //! concrete [`alkblobs::Store`] facade over a fresh temp site per //! call — a private temporary directory holding the sqlite pool file //! and the large engine's private root — so two opens never share //! state. Teardown removes every site this factory instance vended //! (idempotent: a repeated teardown is a no-op and an already-removed //! directory is tolerated; safe against abandoned instances — each //! site is private to its open). The local column's instance-tracks- //! its-own-root pattern: every runner constructs its own factory, so //! concurrent rows never touch each other's sites. The column never //! skips (README §SKIP posture — server-less engines' columns must //! always be green in every environment). //! //! The dual-tier dispatch rows mirror the local column's family with //! the placement oracle adapted: both tiers are on disk now — kv //! entries live in the sqlite file (the oracle counts its pool rows), //! large entries under the local root — so the oracle distinguishes //! by medium. #![allow(dead_code)] use std::io::Cursor; use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex}; use std::time::Duration; use rusqlite::Connection; use crate::factory::StoreFactory; use crate::rows::{ self, committed_file_count, patterned, slice_digest, staging_file_count, Failing, LatchProtect, SetProtect, SetSource, }; use alkblobs::{Error, Key, Store, StoreMode, DEFAULT_DISPATCH_THRESHOLD}; // ------------------------------------------------------------------ // The factories // ------------------------------------------------------------------ /// The column's declared dual-tier threshold — small, so the shared /// content matrix and the race fixtures cross it and both tiers' /// bodies are exercised (sub-threshold rows land in the sqlite file; /// over-threshold rows stage-commit into the local root). pub(crate) const TUNED_THRESHOLD: u64 = 1024; /// The column's declared kv-only rejection threshold — small, so every /// leg of the rejection row stays trivially materializable. pub(crate) const KV_ONLY_THRESHOLD: u64 = 1024; /// The **test tuning of the window delay** (ADR-008 §2's legal /// degenerate tuning): `0` — execute-on-next-sweep. The durable /// schedule's staging sweep stages the dead set; the *next* sweep is /// its executor, which is exactly the schedule the sweep rows assert /// against. pub(crate) const WINDOW_DELAY: Duration = Duration::ZERO; /// One vended backing site: a fresh private temporary directory /// holding the sqlite pool file and the large engine's root. #[derive(Clone)] pub(crate) struct Site { /// The whole private directory — what teardown removes. base: PathBuf, /// The sqlite pool file — the kv tier's medium (the dispatch /// oracle's kv-side counter and the durable window's rows table). database: PathBuf, /// The local root — the large tier's medium (the dispatch /// oracle's file-side counter rides [`committed_file_count`]). root: PathBuf, } fn fresh_site(tag: &str) -> Site { use std::sync::atomic::{AtomicU64, Ordering}; use std::time::{SystemTime, UNIX_EPOCH}; static SEQ: AtomicU64 = AtomicU64::new(0); let seq = SEQ.fetch_add(1, Ordering::Relaxed); let nanos = SystemTime::now() .duration_since(UNIX_EPOCH) .map(|d| d.as_nanos()) .unwrap_or(0); let base = std::env::temp_dir().join(format!( "alkblobs-sqlite-column-{tag}-{}-{:x}-{seq}", std::process::id(), nanos )); std::fs::create_dir_all(&base).expect("temp site created"); Site { base, database: PathBuf::new(), root: PathBuf::new(), } } impl Site { fn with_pool(mut self) -> Site { self.database = self.base.join("pool.db"); self.root = self.base.join("local-root"); self } /// The sqlite pool file path — captured before teardown so a /// structural test can assert the removal. pub(crate) fn database(&self) -> &Path { &self.database } /// The local root path — for the file oracle's callers. pub(crate) fn root(&self) -> &Path { &self.root } fn remove(self) -> Result<(), Error> { match std::fs::remove_dir_all(&self.base) { Ok(()) => Ok(()), Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(()), Err(e) => Err(Error::Io(e.to_string())), } } } /// The dispatch-coverage factory: `kv = sqlite` + `large = local` at /// the threshold this column declares and the test tuning of the /// window delay (see [`TUNED_THRESHOLD`], [`WINDOW_DELAY`], and the /// default-threshold sibling `DualTierSqliteFactory::new( /// DEFAULT_DISPATCH_THRESHOLD)` the boundary row runs against). /// /// **Why a fresh instance per runner (not a shared static):** teardown /// removes the sites *this instance* vended; a shared instance's /// teardown would race concurrently running rows' sites. Every runner /// constructs its own and owns its lifecycle. pub(crate) struct DualTierSqliteFactory { /// The declared dispatch threshold — the routing boundary this /// column's rows run at (constructor-tunable; ADR-003). Declared /// configuration, like the local column's (the dual-tier store /// never rejects, so there is nothing to probe). threshold: u64, /// The declared window delay — the durable schedule's cadence knob /// the sweep rows run at (the test tuning: execute-on-next-sweep). window_delay: Duration, /// Every temp site this instance vended, for its own teardown. sites: Mutex>, } impl DualTierSqliteFactory { pub(crate) fn new(threshold: u64) -> DualTierSqliteFactory { DualTierSqliteFactory { threshold, window_delay: WINDOW_DELAY, sites: Mutex::new(Vec::new()), } } /// Open + track the vended site: the shape the column's own rows /// use (they observe the backing medium, so they need the site /// alongside the store). pub(crate) async fn open_tracked(&self) -> Result<(Store, Site), Error> { let site = fresh_site("dual-tier").with_pool(); let store = Store::dual_tier_sqlite_local( &site.database, &site.root, self.threshold, self.window_delay, ) .await?; self.sites .lock() .unwrap_or_else(|e| e.into_inner()) .push(site.clone()); Ok((store, site)) } /// The database files this instance vended, for the structural /// tests' teardown assertions. pub(crate) fn tracked_databases(&self) -> Vec { self.sites .lock() .unwrap_or_else(|e| e.into_inner()) .iter() .map(|site| site.database.clone()) .collect() } } impl StoreFactory for DualTierSqliteFactory { fn name(&self) -> &'static str { "dual-tier sqlite+local" } async fn open(&self) -> Result { self.open_tracked().await.map(|(store, _)| store) } async fn teardown(&self) -> Result<(), Error> { for site in self .sites .lock() .unwrap_or_else(|e| e.into_inner()) .drain(..) { site.remove()?; } Ok(()) } } /// The kv-only(sqlite) factory (ADR-011 §4; ADR-012 §6.2): no large /// tier; the threshold is the put-time rejection point the kv-only /// row discovers by probing. The durable single-node medium. pub(crate) struct KvOnlySqliteFactory { /// The rejection point this column's configuration declares. The /// kv-only row discovers it behaviorally and requires it /// materializable for its boundary legs. pub(crate) threshold: u64, /// The declared window delay — the durable schedule's cadence knob. window_delay: Duration, /// Every temp site this instance vended, for its own teardown. sites: Mutex>, } impl KvOnlySqliteFactory { pub(crate) fn new(threshold: u64) -> KvOnlySqliteFactory { KvOnlySqliteFactory { threshold, window_delay: WINDOW_DELAY, sites: Mutex::new(Vec::new()), } } } impl StoreFactory for KvOnlySqliteFactory { fn name(&self) -> &'static str { "kv-only(sqlite)" } async fn open(&self) -> Result { let site = fresh_site("kv-only").with_pool(); let store = Store::kv_only_sqlite(&site.database, self.threshold, self.window_delay).await?; self.sites .lock() .unwrap_or_else(|e| e.into_inner()) .push(site); Ok(store) } async fn teardown(&self) -> Result<(), Error> { for site in self .sites .lock() .unwrap_or_else(|e| e.into_inner()) .drain(..) { site.remove()?; } Ok(()) } } // ------------------------------------------------------------------ // The medium oracle (the dispatch rows' instrument, adapted from the // local column's): both tiers are on disk now, so the oracle // distinguishes by medium — the sqlite file's pool and window tables // vs the root's committed files. // ------------------------------------------------------------------ /// Rows in one of the sqlite pool file's tables — the kv tier's pool /// (`blobs`) or the durable window's staged candidates (`gc_window`), /// counted from the test's own independent connection to the file. fn sqlite_table_rows(database: &Path, table: &str) -> usize { let conn = Connection::open(database).expect("the oracle connection opens"); let count: i64 = conn .query_row(&format!("SELECT COUNT(*) FROM {table}"), [], |row| { row.get(0) }) .expect("the oracle query succeeds"); count.max(0) as usize } /// The sqlite kv tier's pool residency — exactly one row per committed /// kv-tier entry (the CAS table's rows). fn sqlite_pool_rows(site: &Site) -> usize { sqlite_table_rows(site.database(), "blobs") } /// The durable window's staged-candidate residency — the schedule /// observer the durable rows assert against (staged rows land here; /// the executing sweep's take empties them). fn sqlite_window_rows(site: &Site) -> usize { sqlite_table_rows(site.database(), "gc_window") } // ------------------------------------------------------------------ // The column's own rows — the durable-schedule sweep family, the // schedule-relative readings of the sweep-counting INV rows, and the // local-specific forms. Every row takes this column's concrete // factory (it observes the backing medium), is ADR-stamped per the // convention, and traces its family. // ------------------------------------------------------------------ /// INV-2 on the durable schedule: identical content put twice — /// through the same put path and across the two paths — is one pool /// entry (one row in the sqlite file), and the re-put's `Pin` /// protects exactly as a fresh put's does. One-pool-entry is asserted /// through durable-schedule outcomes (the INV-5 posture): the pins /// held stage nothing; once unpinned, sweep 1 stages exactly the one /// entry and removes nothing, and its executor sweep deletes exactly /// that staged set — never a list comparison, and never a single-sweep /// count (README §The schedule-relative reading for SQL-backed /// columns). /// /// Contract stamp: store-api.md §Invariants 2; ADR-003 (whole-value /// put is CAS first-writer-wins); ADR-005 (a re-put refcounts the /// existing entry under the same arbitration lock); ADR-008 §2 (the /// staged re-arbitrated delete); ADR-012 §6.7 (the executor is the /// next sweep — the schedule these counts read against). pub async fn dedup_identical_content_is_one_pool_entry(factory: &DualTierSqliteFactory) { let (store, site) = factory .open_tracked() .await .expect("open vends a fresh, isolated store"); SetSource::register(&store); let content = b"deduplicated content".to_vec(); let canonical = Key::derive(&content, content.len() as u64); let (key, first) = store .put(Some(content.len() as u64), Cursor::new(content.as_slice())) .await .expect("the fresh put publishes"); let (reput, second) = store .put(Some(content.len() as u64), Cursor::new(content.as_slice())) .await .expect("the same-path re-put publishes"); assert_eq!(key, canonical); assert_eq!(reput, canonical, "one derivation, one address"); let report = store.sweep().await.expect("sweeps are never errors"); assert_eq!(report.aborted, None); assert_eq!( report.candidates_staged, 0, "one pool entry, both refcounts composing under the same lock" ); assert_eq!( sqlite_pool_rows(&site), 1, "one pool entry, both refcounts — one row in the sqlite file" ); drop(first); let report = store.sweep().await.expect("sweeps are never errors"); assert_eq!( report.candidates_staged, 0, "the re-put's pin protects exactly as a fresh put's" ); drop(second); let report = store.sweep().await.expect("sweeps are never errors"); assert_eq!( (report.candidates_staged, report.deleted), (1, 0), "exactly one pool entry all along — staged this sweep, not executed" ); let report = store.sweep().await.expect("sweeps are never errors"); assert_eq!( (report.deleted, report.cancelled_by_arbitration), (1, 0), "the executing sweep deleted exactly the staged entry" ); assert!(!store.has(&canonical.as_bytes()).await.unwrap()); assert_eq!(sqlite_pool_rows(&site), 0, "the executed delete landed"); let cross = b"deduplicated across the put paths".to_vec(); let cross_canonical = Key::derive(&cross, cross.len() as u64); let (key, first) = store .put(Some(cross.len() as u64), Cursor::new(cross.as_slice())) .await .expect("the known-length put publishes"); let (reput, second) = store .put(None, Cursor::new(cross.as_slice())) .await .expect("the unknown-length re-put publishes"); assert_eq!(key, cross_canonical); assert_eq!(reput, cross_canonical, "one pool entry across the paths"); let report = store.sweep().await.expect("sweeps are never errors"); assert_eq!(report.candidates_staged, 0, "both refcounts compose"); drop(second); let report = store.sweep().await.expect("sweeps are never errors"); assert_eq!( report.candidates_staged, 0, "the re-put's pin protects exactly as a fresh put's (other drop order)" ); drop(first); let report = store.sweep().await.expect("sweeps are never errors"); assert_eq!( (report.candidates_staged, report.deleted), (1, 0), "exactly one pool entry all along" ); let report = store.sweep().await.expect("sweeps are never errors"); assert_eq!(report.deleted, 1, "executed exactly the staged set"); assert!(!store.has(&cross_canonical.as_bytes()).await.unwrap()); drop(store); factory.teardown().await.expect("teardown is idempotent"); } /// INV-3 on the durable schedule: stage hygiene — every put-path /// failure leaves zero residue and every success leaves exactly one /// committed entry, over both put paths and both injectable failure /// modes (a mid-stream stream failure and a declared-length /// mismatch). The kv tier's stage form is degenerate (nothing stages /// outside a flush), so residue is the pool itself — the sqlite file's /// rows, which the failures never touch — observed through /// durable-schedule sweep outcomes: zero staged after every failure, /// and a success staged exactly once, then executed exactly once. /// /// Contract stamp: store-api.md §Invariants 3; ADR-010 §1 (the /// staged-put contract: commit publishes, every failure path /// discards); ADR-003 (stage-then-commit, the kv form degenerate); /// ADR-012 §6.7 (the schedule-relative reading the success counts /// follow). pub async fn stage_hygiene_zero_residue_on_failure_exactly_one_entry_on_success( factory: &DualTierSqliteFactory, ) { let (store, site) = factory .open_tracked() .await .expect("open vends a fresh, isolated store"); SetSource::register(&store); let content = patterned(200, 167); let canonical = Key::derive(&content, content.len() as u64); let err = store .put(Some(content.len() as u64), Failing::new(&content, 40)) .await .expect_err("the failed mid-stream put rejects"); assert!( matches!(err, Error::Io(_)), "the stream failure surfaces as Io: {err}" ); let err = store .put(None, Failing::new(&content, 40)) .await .expect_err("the failed unknown-length put rejects"); assert!( matches!(err, Error::Io(_)), "the stream failure surfaces as Io: {err}" ); let err = store .put(Some(100), Cursor::new(content.as_slice())) .await .expect_err("the over-fed mismatch rejects"); assert_eq!(err, Error::Verification, "declared-len mismatch rejects"); let err = store .put(Some(400), Cursor::new(content.as_slice())) .await .expect_err("the under-fed mismatch rejects"); assert_eq!(err, Error::Verification, "declared-len mismatch rejects"); let report = store.sweep().await.expect("sweeps are never errors"); assert_eq!(report.aborted, None); assert_eq!( ( report.candidates_staged, report.deleted, report.cancelled_by_arbitration ), (0, 0, 0), "zero residue after every failure, both put paths, both failure modes" ); assert_eq!( sqlite_pool_rows(&site), 0, "the pool table holds zero entries after every failure" ); let (key, pin) = store .put(Some(content.len() as u64), Cursor::new(content.as_slice())) .await .expect("the known-length put publishes"); assert_eq!(key, canonical); drop(pin); let report = store.sweep().await.expect("sweeps are never errors"); assert_eq!( (report.candidates_staged, report.deleted), (1, 0), "exactly one committed entry staged on success" ); let report = store.sweep().await.expect("sweeps are never errors"); assert_eq!( report.deleted, 1, "the executing sweep removed exactly that one entry" ); assert!(!store.has(&canonical.as_bytes()).await.unwrap()); let (key, pin) = store .put(None, Cursor::new(content.as_slice())) .await .expect("the unknown-length put publishes"); assert_eq!(key, canonical); drop(pin); let report = store.sweep().await.expect("sweeps are never errors"); assert_eq!( (report.candidates_staged, report.deleted), (1, 0), "exactly one committed entry staged on the other put path too" ); let report = store.sweep().await.expect("sweeps are never errors"); assert_eq!(report.deleted, 1, "and executed exactly that staged set"); assert!(!store.has(&canonical.as_bytes()).await.unwrap()); drop(store); factory.teardown().await.expect("teardown is idempotent"); } /// INV-4, the durable-schedule happy shape: the full protection set /// spanning both tiers (a source-live kv entry, a pinned large-tier /// entry, a protect-named large-tier entry) plus one dead entry per /// tier — sweep 1 stages exactly the two dead candidates and deletes /// nothing (staging is not executing: the pool and the medium hold /// everything and the window holds the staged rows); sweep 2 executes /// exactly that staged set (`deleted + cancelled == N` against the /// staged set), and the protected entries stay byte-identical. The /// exact staged candidates also make this the INV-5 posture's /// both-tiers form: list correctness (complete and well-formed across /// both tiers' enumerations) is observable only through these /// outcomes. The medium oracle distinguishes the tiers (the sqlite /// file's pool rows vs the root's committed files) and watches the /// schedule itself (the window's rows). /// /// Contract stamp: store-api.md §Invariants 4 (exact counts with /// correct liveness) and §Invariants 5 (list correctness through /// sweep outcomes); ADR-005 (three liveness marks; delete windows /// with arbitrate-at-delete-time); ADR-008 §2 (the staged /// re-arbitrated delete; the constructor-tunable delay); ADR-012 §1 /// (sweeps are never errors — the report is the outcome record); /// ADR-012 §6.7 (the executor is the next sweep — the schedule these /// counts read against); ADR-007 (sqlite, the default-build kv /// engine). pub async fn two_sweep_exact_counts_over_the_full_protection_set(factory: &DualTierSqliteFactory) { let threshold = factory.threshold; let (store, site) = factory .open_tracked() .await .expect("open vends a fresh, isolated store"); let source = SetSource::register(&store); let protect = Arc::new(SetProtect::default()); store.register_protect_callback(protect.clone()); let source_live = patterned((threshold - 1) as usize, 191); let (key_live, _) = store .put( Some(source_live.len() as u64), Cursor::new(source_live.as_slice()), ) .await .expect("the source-live entry publishes"); source.add(key_live.clone()); let pinned = patterned(2 * threshold as usize + 7, 173); let (key_pinned, pin_pinned) = store .put(None, Cursor::new(pinned.as_slice())) .await .expect("the pinned entry publishes"); let protected = patterned(2 * threshold as usize + 11, 167); let (key_protected, _) = store .put( Some(protected.len() as u64), Cursor::new(protected.as_slice()), ) .await .expect("the protect-named entry publishes"); protect.set_keys(vec![key_protected.clone()]); let dead_kv = patterned((threshold - 3) as usize, 149); let (key_dead_kv, pin) = store .put(Some(dead_kv.len() as u64), Cursor::new(dead_kv.as_slice())) .await .expect("the kv-tier dead entry publishes"); drop(pin); let dead_large = patterned(2 * threshold as usize + 13, 151); let (key_dead_large, pin) = store .put(None, Cursor::new(dead_large.as_slice())) .await .expect("the large-tier dead entry publishes"); drop(pin); assert_eq!( (sqlite_pool_rows(&site), committed_file_count(site.root())), (2, 3), "before the sweep, both tiers hold their entries exactly \ (two pool rows in the sqlite file, three committed files \ under the root)" ); let first = store.sweep().await.expect("sweeps are never errors"); assert_eq!(first.aborted, None); assert_eq!( ( first.candidates_staged, first.deleted, first.cancelled_by_arbitration ), (2, 0, 0), "sweep 1 staged exactly the two dead entries and deleted \ nothing — staging is not executing" ); assert_eq!( sqlite_window_rows(&site), 2, "the staged set waits in the durable window" ); for (key, content) in [ (&key_live, &source_live), (&key_pinned, &pinned), (&key_protected, &protected), ] { let (len, blob) = store .get(&key.as_bytes()) .await .expect("get succeeds") .expect("the protected entry is present"); assert_eq!( blob.read_at(0, len).await.expect("the window reads"), content.as_slice(), "the protected entry is byte-identical after the staging sweep" ); } assert!( store.has(&key_live.as_bytes()).await.unwrap() && store.has(&key_pinned.as_bytes()).await.unwrap() && store.has(&key_protected.as_bytes()).await.unwrap(), "the staged sweep deleted nothing: every entry intact" ); let second = store.sweep().await.expect("sweeps are never errors"); assert_eq!(second.aborted, None); assert_eq!( second.candidates_staged, 0, "nothing newly dead since the staging sweep" ); assert_eq!( second.deleted + second.cancelled_by_arbitration, 2, "sweep 2 executed exactly the staged set" ); assert_eq!( (second.deleted, second.cancelled_by_arbitration), (2, 0), "with correct liveness, every executed candidate deleted" ); assert!(!store.has(&key_dead_kv.as_bytes()).await.unwrap()); assert!(!store.has(&key_dead_large.as_bytes()).await.unwrap()); assert_eq!( (sqlite_pool_rows(&site), committed_file_count(site.root())), (1, 2), "the executed deletes landed on both media exactly" ); assert_eq!( sqlite_window_rows(&site), 0, "the executed rows left the durable window" ); drop(pin_pinned); let third = store.sweep().await.expect("sweeps are never errors"); assert_eq!( (third.candidates_staged, third.deleted), (1, 0), "with the pin dropped, the formerly pinned entry stages" ); let fourth = store.sweep().await.expect("sweeps are never errors"); assert_eq!( fourth.deleted, 1, "and the next sweep executes it — exactly one deletion" ); assert!(!store.has(&key_pinned.as_bytes()).await.unwrap()); assert!(store.has(&key_live.as_bytes()).await.unwrap()); assert!(store.has(&key_protected.as_bytes()).await.unwrap()); assert_eq!( committed_file_count(site.root()), 1, "exactly the protect-named entry's file remains" ); drop(store); factory.teardown().await.expect("teardown is idempotent"); } /// INV-4, the race, in its durable-schedule form: a put landing /// *during the window* survives the executing sweep — the re-put's /// pin is minted (pin-before-publish) between the staging sweep and /// the executing sweep, so the execution-time re-arbitration cancels /// the pinned candidate while the unpinned twin deletes; once the pin /// drops, the twin re-stages and executes exactly once. Both put /// paths race in-body over both tiers (a kv twin and a large twin). /// /// Contract stamp: store-api.md §Invariants 4; ADR-005 (pin-before- /// publish ordering; the delete window closes the sweep-vs-put race); /// ADR-008 §2 (the staged re-arbitrated delete — the race holds /// across the window delay); ADR-012 §6.7 (execution-time /// re-arbitration is the executor sweep's posture). pub async fn a_put_landing_during_the_window_survives_the_executing_sweep( factory: &DualTierSqliteFactory, ) { let threshold = factory.threshold; let (store, site) = factory .open_tracked() .await .expect("open vends a fresh, isolated store"); SetSource::register(&store); let rounds: [(String, Vec, bool, bool); 2] = [ ( "the kv twin (known-path re-put)".to_owned(), patterned((threshold - 1) as usize, 191), true, true, ), ( "the large twin (unknown-path re-put)".to_owned(), patterned(2 * threshold as usize + 5, 173), false, false, ), ]; for (index, (tag, content, original_known, reput_known)) in rounds.iter().enumerate() { let len = content.len() as u64; let twin = Key::derive(content, len); let witness = format!("the dead witness of round {index}").into_bytes(); let witness_key = Key::derive(&witness, witness.len() as u64); let original = if *original_known { Some(len) } else { None }; let (_, pin) = store .put(original, Cursor::new(content.as_slice())) .await .expect("the twin publishes"); drop(pin); let (_, pin) = store .put(None, Cursor::new(witness.as_slice())) .await .expect("the witness publishes"); drop(pin); let staged = store.sweep().await.expect("sweeps are never errors"); assert_eq!( ( staged.aborted, staged.candidates_staged, staged.deleted, staged.cancelled_by_arbitration ), (None, 2, 0, 0), "{tag}: the staging sweep stages exactly the two dead \ twins and deletes nothing" ); // The put lands during the window (the re-put dedups into the // existing twin and refcounts its pin): protected across the // delay, pin-before-publish. let reput = if *reput_known { Some(len) } else { None }; let (_, pin) = store .put(reput, Cursor::new(content.as_slice())) .await .expect("the re-put publishes"); let executed = store.sweep().await.expect("sweeps are never errors"); assert_eq!(executed.aborted, None, "{tag}"); assert_eq!( executed.candidates_staged, 0, "{tag}: nothing newly dead since the staging sweep" ); assert_eq!( executed.deleted + executed.cancelled_by_arbitration, 2, "{tag}: the executing sweep ran exactly the staged set" ); assert_eq!(executed.deleted, 1, "{tag}: the unpinned witness deleted"); assert_eq!( executed.cancelled_by_arbitration, 1, "{tag}: the pinned twin's candidate cancelled at execution time" ); assert!( !store.has(&witness_key.as_bytes()).await.unwrap(), "{tag}: the unpinned twin is gone" ); let (got_len, blob) = store .get(&twin.as_bytes()) .await .expect("get succeeds") .expect("{tag}: the put landing during the window survived"); assert_eq!(got_len, len, "{tag}"); assert_eq!( blob.read_at(0, len).await.expect("the window reads"), content.as_slice(), "{tag}: the surviving twin is byte-identical" ); drop(pin); let restaged = store.sweep().await.expect("sweeps are never errors"); assert_eq!( (restaged.candidates_staged, restaged.deleted), (1, 0), "{tag}: the pin dropped — the twin re-stages" ); let executed = store.sweep().await.expect("sweeps are never errors"); assert_eq!( executed.deleted, 1, "{tag}: the re-staged candidate executes exactly once" ); assert!(!store.has(&twin.as_bytes()).await.unwrap()); assert_eq!( sqlite_window_rows(&site), 0, "{tag}: the window holds nothing after the executed round" ); } drop(store); factory.teardown().await.expect("teardown is idempotent"); } /// INV-4, abort shape: the sweep is single-flight on the durable form /// too — the in-process sweep lease (ADR-013 §2's single-node analog). /// The contended second sweeper aborts with `SweeperLock` in a /// completed `Ok(SweepReport)` — nothing executed, nothing staged, /// nothing deleted (abort before staging: form-independent) — while /// the lease holder's sweep completes by **staging only**: its staged /// set waits in the window for the next sweep to execute (the /// durable form's schedule-relative replacement for the reference /// row's inline holder-completion leg). /// /// Contract stamp: store-api.md §Invariants 4; ADR-012 §1 (abort is /// report data, never an error); ADR-013 §2 (the named exclusive /// sweep lease — one sweeper per pool, holdership ends at release); /// ADR-012 §6.7 (the executor is the next sweep — the holder stages, /// it does not execute). pub async fn the_contended_second_sweeper_aborts_as_data_and_the_holder_stages_only( factory: &DualTierSqliteFactory, ) { let threshold = factory.threshold; let (store, site) = factory .open_tracked() .await .expect("open vends a fresh, isolated store"); SetSource::register(&store); let (entered_tx, entered_rx) = std::sync::mpsc::channel::<()>(); let (release_tx, release_rx) = std::sync::mpsc::channel::<()>(); store.register_protect_callback(Arc::new(LatchProtect { entered: entered_tx, release: parking_lot::Mutex::new(Some(release_rx)), })); let content = patterned((threshold - 1) as usize, 167); let (key, pin) = store .put(Some(content.len() as u64), Cursor::new(content.as_slice())) .await .expect("the dead witness publishes"); drop(pin); // The lease holder sweeps on its own task (its protect consult // blocks that task's thread mid-callback); this task contends and // then releases the holder. let store = Arc::new(store); let holder = tokio::spawn({ let store = Arc::clone(&store); async move { store.sweep().await } }); while entered_rx.recv_timeout(Duration::from_millis(50)).is_err() { tokio::task::yield_now().await; } let second = store.sweep().await.expect("sweeps are never errors"); assert_eq!( second.aborted, Some(alkblobs::GcAbortCause::SweeperLock), "the contended sweeper aborts as report data" ); assert_eq!( ( second.candidates_staged, second.deleted, second.cancelled_by_arbitration ), (0, 0, 0), "the contended sweep executes, stages, and deletes nothing" ); assert!( store.has(&key.as_bytes()).await.unwrap(), "the contended sweep deleted nothing" ); assert_eq!( sqlite_window_rows(&site), 0, "the aborted sweep staged nothing into the window" ); release_tx.send(()).ok(); let report = holder .await .expect("the holder task joined") .expect("sweeps are never errors"); assert_eq!(report.aborted, None, "the lease holder completes"); assert_eq!( (report.candidates_staged, report.deleted), (1, 0), "the holder stages exactly the dead set — it does not execute \ (the durable form's schedule)" ); assert_eq!( sqlite_window_rows(&site), 1, "the holder's staged set waits in the durable window" ); assert!( store.has(&key.as_bytes()).await.unwrap(), "the holder staged, did not execute: the entry is intact" ); let executed = store.sweep().await.expect("sweeps are never errors"); assert_eq!( executed.deleted, 1, "the next sweep is the executor of the staged set" ); assert!(!store.has(&key.as_bytes()).await.unwrap()); drop(store); factory.teardown().await.expect("teardown is idempotent"); } /// INV-5 on the durable schedule: `list()` correctness is observable /// only through GC — the enumeration is complete and well-formed in /// both directions, proven by exact durable-schedule outcomes: the /// staging sweep stages exactly the dead set (neither more nor fewer /// candidates), the executing sweep deletes exactly that staged set, /// and a liveness flip re-stages exactly the newly dead entry. Never /// a direct list comparison. /// /// Contract stamp: store-api.md §Invariants 5; ADR-003 (`list()` is /// complete and well-formed by contract — load-bearing for GC); /// ADR-005 (the sweep's live-set diff rides `list()`); ADR-012 §6.7 /// (the executor is the next sweep — the schedule these counts read /// against). pub async fn list_correctness_is_observable_through_durable_schedule_outcomes( factory: &DualTierSqliteFactory, ) { let (store, site) = factory .open_tracked() .await .expect("open vends a fresh, isolated store"); let source = SetSource::register(&store); let mut keys = Vec::new(); for (index, content) in [ b"kept live by the source, entry one".to_vec(), b"kept live by the source, entry two".to_vec(), b"dead at the first staging, entry three".to_vec(), b"dead at the first staging, entry four".to_vec(), b"dead at the first staging, entry five".to_vec(), ] .into_iter() .enumerate() { let declared = if index % 2 == 0 { Some(content.len() as u64) } else { None }; let (key, pin) = store .put(declared, Cursor::new(content.as_slice())) .await .expect("the entry publishes"); drop(pin); keys.push(key); } source.add(keys[0].clone()); source.add(keys[1].clone()); let first = store.sweep().await.expect("sweeps are never errors"); assert_eq!(first.aborted, None); assert_eq!( (first.candidates_staged, first.deleted), (3, 0), "the enumeration staged exactly the three dead entries — \ complete and well-formed in both directions" ); for key in &keys { assert!( store.has(&key.as_bytes()).await.unwrap(), "staging deleted nothing: every enumerated entry is intact" ); } assert_eq!( sqlite_window_rows(&site), 3, "the staged schedule holds the three candidates" ); let second = store.sweep().await.expect("sweeps are never errors"); assert_eq!( (second.candidates_staged, second.deleted), (0, 3), "the executing sweep removed exactly the staged set" ); assert!(store.has(&keys[0].as_bytes()).await.unwrap()); assert!(store.has(&keys[1].as_bytes()).await.unwrap()); for key in &keys[2..] { assert!(!store.has(&key.as_bytes()).await.unwrap()); } source.remove(&keys[1]); let third = store.sweep().await.expect("sweeps are never errors"); assert_eq!( (third.candidates_staged, third.deleted), (1, 0), "the newly dead entry is staged exactly" ); let fourth = store.sweep().await.expect("sweeps are never errors"); assert_eq!(fourth.deleted, 1, "and executed exactly by the next sweep"); assert!(!store.has(&keys[1].as_bytes()).await.unwrap()); assert!(store.has(&keys[0].as_bytes()).await.unwrap()); source.remove(&keys[0]); let fifth = store.sweep().await.expect("sweeps are never errors"); assert_eq!(fifth.candidates_staged, 1, "the last entry stages exactly"); let sixth = store.sweep().await.expect("sweeps are never errors"); assert_eq!(sixth.deleted, 1, "and executes exactly"); drop(store); factory.teardown().await.expect("teardown is idempotent"); } /// Dispatch row: **routing is a pure function of length** — at, below, /// and over the declared threshold, the same content lands on exactly /// the same tier through both put paths (same placement every time; /// nothing moves, nothing duplicates), identical content through both /// paths is one pool entry, and every read is byte-identical from /// wherever that tier holds it. /// /// Tier placement is observed through the backing medium (the module /// doc's oracle, adapted): kv entries hold a row in the sqlite file /// and none under the root; large entries hold a committed file under /// the root and no pool row — the facade cannot and must not expose /// tier residency (it is engine-blind). /// /// Contract stamp: store-api.md §Invariants 7 (facade-contract row); /// ADR-003 §Dispatch policy (routing is a pure function of length; /// no migration; CAS first-writer-wins makes re-puts one entry); /// ADR-005 (re-put refcounts); ADR-007 (sqlite, the default-build /// kv engine); ADR-012 §6.3 (the dual-tier dispatch-coverage shape); /// ADR-012 §6.7 (the schedule-relative cleanup the dedup legs read /// against). pub async fn routing_is_a_pure_function_of_length_across_put_paths_and_re_puts( factory: &DualTierSqliteFactory, ) { let threshold = factory.threshold; let (store, site) = factory .open_tracked() .await .expect("open vends a fresh, isolated store"); SetSource::register(&store); for content in [ patterned((threshold - 1) as usize, 191), patterned(threshold as usize, 173), patterned((threshold + 1) as usize, 167), patterned(4 * threshold as usize + 9, 151), ] { let len = content.len() as u64; let canonical = Key::derive(&content, len); let expected_rows = if len > threshold { 0 } else { 1 }; let expected_files = if len > threshold { 1 } else { 0 }; for (path_tag, declared) in [("the known path", Some(len)), ("the unknown path", None)] { let (key, pin) = store .put(declared, Cursor::new(content.as_slice())) .await .expect("put publishes"); assert_eq!( key, canonical, "the canonical derivation addresses the put on {path_tag}" ); assert_eq!( sqlite_pool_rows(&site), expected_rows, "length {len} on {path_tag}: the placement is exactly the \ routing function's answer and never moves or duplicates \ (the sqlite medium holds {expected_rows} kv rows)" ); assert_eq!( committed_file_count(site.root()), expected_files, "length {len} on {path_tag}: the large-tier medium holds \ {expected_files} committed files" ); assert_eq!( staging_file_count(site.root()), 0, "a published put leaves no stage file on {path_tag}" ); let (got_len, blob) = store .get(&key.as_bytes()) .await .expect("get succeeds") .expect("the entry is present"); assert_eq!( got_len, len, "the read serves the entry from its placed tier" ); assert_eq!( blob.read_at(0, len).await.expect("the whole window reads"), content, "the entry is byte-identical from its placed tier across paths" ); drop(pin); } let staged = store.sweep().await.expect("sweeps are never errors"); assert_eq!( staged.candidates_staged, 1, "identical content through both put paths is one pool entry" ); let executed = store.sweep().await.expect("sweeps are never errors"); assert_eq!( executed.deleted, 1, "the executing sweep removed exactly the one entry (durable \ schedule: staged this sweep, executed by the next)" ); assert_eq!( (sqlite_pool_rows(&site), committed_file_count(site.root())), (0, 0), "both media are back to zero" ); } drop(store); factory.teardown().await.expect("teardown is idempotent"); } /// Dispatch row: **threshold boundary lengths route deterministically** /// — at/below/above the factory's declared threshold, on both put /// paths, the placement is the routing function's answer every time /// (the medium oracle distinguishes the sqlite file's rows from the /// root's committed files); and the default-threshold boundary /// re-routes with the tuning (the constructor-tuned threshold /// deterministically places the default boundary's length on the tier /// its own threshold names). Run against two factories by the runner /// — the column's tuned threshold and the shipped default — the same /// row shape at two declared thresholds being the tunable re-route /// demonstration. The durable cleanup: the staged sweep stages exactly /// the six entries' dead set and the next sweep executes it. /// /// Contract stamp: store-api.md §Invariants 7 (facade-contract row); /// ADR-003 §Dispatch policy (default 128 KiB at-or-below routes kv; /// constructor-tunable without API change); ADR-007 (sqlite, the /// default-build kv engine); ADR-012 §6.3 (the dual-tier /// dispatch-coverage shape); ADR-012 §6.7 (schedule-relative cleanup). pub async fn threshold_boundary_lengths_route_deterministically(factory: &DualTierSqliteFactory) { let threshold = factory.threshold; let (store, site) = factory .open_tracked() .await .expect("open vends a fresh, isolated store"); SetSource::register(&store); let boundary = [ (threshold - 1, 191u32, false), (threshold, 173, false), (threshold, 167, false), (threshold + 1, 151, true), (threshold + 1, 139, true), ]; let mut expected_rows = 0u64; let mut expected_files = 0u64; for (len, modulus, lands_large) in boundary { let content = patterned(len as usize, modulus); for declared in [Some(content.len() as u64), None] { let (key, pin) = store .put(declared, Cursor::new(content.as_slice())) .await .expect("put publishes"); assert_eq!( key, Key::derive(&content, len), "the canonical derivation addresses the put" ); assert_eq!( sqlite_pool_rows(&site) as u64, expected_rows + if lands_large { 0 } else { 1 }, "boundary length {len}: at/below the threshold lands kv \ (one row in the sqlite file), over it lands large (a \ committed file instead), both put paths" ); assert_eq!( committed_file_count(site.root()) as u64, expected_files + if lands_large { 1 } else { 0 }, "boundary length {len}: the large-tier medium matches the \ routing answer" ); drop(pin); } if lands_large { expected_files += 1; } else { expected_rows += 1; } } // The default boundary re-routes with the constructor's tuning: // the shipped default's length belongs to the tier this // configuration's own threshold puts it on. let at_default = patterned(DEFAULT_DISPATCH_THRESHOLD as usize, 199); let default_lands_large = DEFAULT_DISPATCH_THRESHOLD > threshold; let (key, pin) = store .put( Some(DEFAULT_DISPATCH_THRESHOLD), Cursor::new(at_default.as_slice()), ) .await .expect("the default-boundary put publishes"); assert_eq!( key, Key::derive(&at_default, DEFAULT_DISPATCH_THRESHOLD), "the canonical derivation addresses the put" ); assert_eq!( sqlite_pool_rows(&site) as u64, expected_rows + if default_lands_large { 0 } else { 1 }, "the default boundary's length routes to the tier this \ configuration's tuning names (the sqlite medium's answer)" ); assert_eq!( committed_file_count(site.root()) as u64, expected_files + if default_lands_large { 1 } else { 0 }, "the default boundary's length routes to the tier this \ configuration's tuning names (the large medium's answer)" ); drop(pin); let staged = store.sweep().await.expect("sweeps are never errors"); assert_eq!( staged.candidates_staged, 6, "each leg's content was exactly one pool entry" ); let executed = store.sweep().await.expect("sweeps are never errors"); assert_eq!( executed.deleted, 6, "the executing sweep removed every entry, tier notwithstanding" ); assert_eq!( (sqlite_pool_rows(&site), committed_file_count(site.root())), (0, 0), "both media are back to zero" ); drop(store); factory.teardown().await.expect("teardown is idempotent"); } /// Dispatch row: **a kv-tier miss falls through to the large tier on /// every key-addressed op** — content the routing function placed on /// the large tier (one committed file under the root; the sqlite /// medium holds no pool row — the kv tier misses) serves `get`, /// `stat`, `has`, and `read_range` whole, exact, and digest-correct; /// the mirror-position leg proves the kv tier is the *first* consult /// (sub-threshold content, one sqlite row and no committed file, /// reads still served); and both-tier misses resolve per the error /// model's per-op shapes (reached here by the durable schedule's /// staged-then-executed deletion of the subject entry). /// /// Contract stamp: store-api.md §Read path (fall-through consult /// order); ADR-012 §6.1 (every key-addressed op consults kv first, /// then large; the general rule); ADR-012 §6.5 ruling 5 (both-tier /// miss shapes: `None` on get/stat, `Err(Missing)` on read_range); /// ADR-006 (the slice digest); ADR-007 (sqlite, the default-build /// kv engine); ADR-012 §6.3 (the dispatch-coverage shape). pub async fn kv_tier_misses_fall_through_to_the_large_tier_per_op(factory: &DualTierSqliteFactory) { let threshold = factory.threshold; let (store, site) = factory .open_tracked() .await .expect("open vends a fresh, isolated store"); SetSource::register(&store); // Over-threshold content — the kv tier misses, the large tier // serves every op. Both put paths hold the shape. for (content, declared) in [ ( patterned(3 * threshold as usize + 41, 181), Some(3 * threshold + 41), ), (patterned(3 * threshold as usize + 43, 197), None), ] { let len = content.len() as u64; let (key, pin) = store .put(declared, Cursor::new(content.as_slice())) .await .expect("put publishes"); assert_eq!( (sqlite_pool_rows(&site), committed_file_count(site.root())), (0, 1), "the content lives on exactly the large tier — the kv tier \ misses" ); let (got_len, blob) = store .get(&key.as_bytes()) .await .expect("get succeeds") .expect("the large tier served the kv miss"); assert_eq!(got_len, len); assert_eq!( blob.read_at(0, len).await.expect("the whole window reads"), content, "the fall-through read is byte-identical" ); assert_eq!( store.stat(&key.as_bytes()).await.expect("stat succeeds"), Some(alkblobs::EntryMeta { len, algorithm: key.algorithm(), }), "stat falls through and carries the length plus algorithm" ); assert!( store.has(&key.as_bytes()).await.unwrap(), "has falls through" ); let mid = len / 2; let (slice, digest) = store .read_range(&key.as_bytes(), mid, 17) .await .expect("read_range falls through"); assert_eq!( slice, content[(mid as usize)..(mid as usize + 17)], "the range slice is exact" ); assert_eq!( digest, slice_digest(&slice), "the slice digest is SHA-256 over exactly the returned bytes" ); // Sweep the entry away (the pin dropped): the miss shapes now // resolve per op — the large tier misses too. The durable // schedule: staged this sweep, executed by the next. drop(pin); let staged = store.sweep().await.expect("sweeps are never errors"); assert_eq!((staged.candidates_staged, staged.deleted), (1, 0)); let executed = store.sweep().await.expect("sweeps are never errors"); assert_eq!( executed.deleted, 1, "exactly the one entry died across the two sweeps" ); assert!( store .get(&key.as_bytes()) .await .expect("get succeeds") .is_none(), "a both-tier miss on get is Ok(None)" ); assert_eq!( store.stat(&key.as_bytes()).await.expect("stat succeeds"), None, "a both-tier miss on stat is Ok(None)" ); assert!( !store.has(&key.as_bytes()).await.unwrap(), "a both-tier miss on has is false" ); assert_eq!( store .read_range(&key.as_bytes(), 0, 4) .await .expect_err("the both-tier miss errs"), Error::Missing, "a both-tier miss on read_range is Err(Missing)" ); } // The mirror-position leg: sub-threshold content — the kv tier is // the first consult and serves before the large tier is reached // (one row in the sqlite file; no committed file ever lands). let small = patterned((threshold - 1) as usize, 149); let (key, pin) = store .put(Some(small.len() as u64), Cursor::new(small.as_slice())) .await .expect("the sub-threshold put publishes"); assert_eq!( (sqlite_pool_rows(&site), committed_file_count(site.root())), (1, 0), "the kv tier holds the sub-threshold entry — the large tier was \ never consulted on the write, never reached on the read" ); let (len, blob) = store .get(&key.as_bytes()) .await .expect("get succeeds") .expect("the kv tier served"); assert_eq!(len, small.len() as u64); assert_eq!( blob.read_at(0, len).await.expect("the whole window reads"), small ); drop(pin); // Both-tier miss shapes for a key that never existed at all, per // op, over the fresh both-tier store. let absent = b"never put here".to_vec(); let absent = Key::derive(&absent, absent.len() as u64); assert!( store .get(&absent.as_bytes()) .await .expect("get succeeds") .is_none(), "never-put: get is Ok(None)" ); assert_eq!( store.stat(&absent.as_bytes()).await.expect("stat succeeds"), None, "never-put: stat is Ok(None)" ); assert!( !store.has(&absent.as_bytes()).await.unwrap(), "never-put: has is false" ); assert_eq!( store .read_range(&absent.as_bytes(), 0, 4) .await .expect_err("never-put read_range errs"), Error::Missing, "never-put: read_range is Err(Missing)" ); drop(store); factory.teardown().await.expect("teardown is idempotent"); } /// Virgin-store row: **reads are no-ops on a fresh file** — an empty /// `list`, absent reads per op (`None` on get/stat, `false` on has, /// `Err(Missing)` on read_range), and nothing on the fresh medium /// itself (zero pool rows, zero window rows, zero committed files). /// The sqlite engine's no-tables-yet read tolerance (every read /// against a genuinely tableless database file is a no-op, never a /// "table does not exist" error) is instrumented engine-side — a /// store constructor always ensures the schema — so the facade's /// fresh-file form of the tolerance is this row's assertions. /// /// Contract stamp: store-api.md §Error model (virgin-store semantics: /// reads on a fresh store see absent/empty, never errors); ADR-012 /// §6.5 ruling 5 (the per-op miss shapes); ADR-007 (the sqlite /// engine — the read tolerance's engine-level posture and the /// schema-creation timing design point). pub async fn virgin_store_reads_are_no_ops_on_a_fresh_file(factory: &DualTierSqliteFactory) { let (store, site) = factory .open_tracked() .await .expect("open vends a fresh, isolated store"); assert_eq!( store.mode(), StoreMode::DualTier, "the column's factory is the dispatch-coverage shape" ); let absent = b"nothing was ever put".to_vec(); let absent = Key::derive(&absent, absent.len() as u64); assert_eq!( store.list().await.expect("list succeeds"), Vec::::new(), "the virgin pool lists empty" ); assert!( store .get(&absent.as_bytes()) .await .expect("get succeeds") .is_none(), "absent get is Ok(None)" ); assert_eq!( store.stat(&absent.as_bytes()).await.expect("stat succeeds"), None, "absent stat is Ok(None)" ); assert!( !store.has(&absent.as_bytes()).await.unwrap(), "absent has is false" ); assert_eq!( store .read_range(&absent.as_bytes(), 0, 4) .await .expect_err("absent read_range errs"), Error::Missing, "absent read_range is Err(Missing)" ); assert_eq!( ( sqlite_pool_rows(&site), sqlite_window_rows(&site), committed_file_count(site.root()) ), (0, 0, 0), "the fresh medium holds nothing (pool, durable window, and \ committed tree all empty)" ); drop(store); factory.teardown().await.expect("teardown is idempotent"); } // ------------------------------------------------------------------ // The runners — the column's tests: the form-independent reference // rows mirrored verbatim against the dual-tier factory (INV-1, INV-6, // and the two no-op abort shapes), the durable-schedule rows above, // the kv-only rejection row against the kv-only factory (unchanged — // threshold-agnostic by discovery), and the factory contract's // structural shapes. // ------------------------------------------------------------------ #[tokio::test] async fn sqlite_inv1_round_trip_puts_and_gets_are_byte_identical() { let factory = DualTierSqliteFactory::new(TUNED_THRESHOLD); rows::round_trip_puts_and_gets_are_byte_identical(&factory).await; } #[tokio::test] async fn sqlite_inv2_dedup_identical_content_is_one_pool_entry() { let factory = DualTierSqliteFactory::new(TUNED_THRESHOLD); dedup_identical_content_is_one_pool_entry(&factory).await; } #[tokio::test] async fn sqlite_inv3_stage_hygiene_zero_residue_one_entry_on_success() { let factory = DualTierSqliteFactory::new(TUNED_THRESHOLD); stage_hygiene_zero_residue_on_failure_exactly_one_entry_on_success(&factory).await; } #[tokio::test] async fn sqlite_inv4_two_sweep_exact_counts_over_the_full_protection_set() { let factory = DualTierSqliteFactory::new(TUNED_THRESHOLD); two_sweep_exact_counts_over_the_full_protection_set(&factory).await; } #[tokio::test] async fn sqlite_inv4_a_put_landing_during_the_window_survives_the_executing_sweep() { let factory = DualTierSqliteFactory::new(TUNED_THRESHOLD); a_put_landing_during_the_window_survives_the_executing_sweep(&factory).await; } #[tokio::test] async fn sqlite_inv4_sweep_without_liveness_sources_aborts_and_deletes_nothing() { let factory = DualTierSqliteFactory::new(TUNED_THRESHOLD); rows::sweep_without_liveness_sources_aborts_and_deletes_nothing(&factory).await; } #[tokio::test] async fn sqlite_inv4_sweep_with_a_failed_protect_callback_aborts_and_deletes_nothing() { let factory = DualTierSqliteFactory::new(TUNED_THRESHOLD); rows::sweep_with_a_failed_protect_callback_aborts_and_deletes_nothing(&factory).await; } #[tokio::test(flavor = "multi_thread", worker_threads = 4)] async fn sqlite_inv4_the_contended_second_sweeper_aborts_as_data_and_the_holder_stages_only() { let factory = DualTierSqliteFactory::new(TUNED_THRESHOLD); the_contended_second_sweeper_aborts_as_data_and_the_holder_stages_only(&factory).await; } #[tokio::test] async fn sqlite_inv5_list_correctness_through_durable_schedule_outcomes() { let factory = DualTierSqliteFactory::new(TUNED_THRESHOLD); list_correctness_is_observable_through_durable_schedule_outcomes(&factory).await; } #[tokio::test] async fn sqlite_inv6_stat_reports_len_and_algorithm_without_fetching_content() { let factory = DualTierSqliteFactory::new(TUNED_THRESHOLD); rows::stat_reports_len_and_algorithm_without_fetching_content(&factory).await; } #[tokio::test] async fn sqlite_virgin_store_reads_are_no_ops_on_a_fresh_file() { let factory = DualTierSqliteFactory::new(TUNED_THRESHOLD); virgin_store_reads_are_no_ops_on_a_fresh_file(&factory).await; } #[tokio::test] async fn sqlite_kv_only_mode_rejects_over_threshold_puts_at_put_time() { let factory = KvOnlySqliteFactory::new(KV_ONLY_THRESHOLD); rows::kv_only_mode_rejects_over_threshold_puts_at_put_time(&factory).await; } #[tokio::test] async fn dispatch_routing_is_a_pure_function_of_length_across_put_paths_and_re_puts() { let factory = DualTierSqliteFactory::new(TUNED_THRESHOLD); routing_is_a_pure_function_of_length_across_put_paths_and_re_puts(&factory).await; } #[tokio::test] async fn dispatch_threshold_boundary_lengths_route_deterministically() { let tuned = DualTierSqliteFactory::new(TUNED_THRESHOLD); threshold_boundary_lengths_route_deterministically(&tuned).await; let default = DualTierSqliteFactory::new(DEFAULT_DISPATCH_THRESHOLD); threshold_boundary_lengths_route_deterministically(&default).await; } #[tokio::test] async fn dispatch_kv_tier_misses_fall_through_to_the_large_tier_per_op() { let factory = DualTierSqliteFactory::new(TUNED_THRESHOLD); kv_tier_misses_fall_through_to_the_large_tier_per_op(&factory).await; } // ------------------------------------------------------------------ // The factory contract's structural shapes (the mem and local // columns' pattern, carried to the SQL-backed medium-backed factory): // fresh isolated opens (fresh site per open, nothing shared) and // idempotent teardown safe against a panicking row. Not conformance // rows — no backlog entry — the factory contract's own wiring-level // assertions. // ------------------------------------------------------------------ /// Every `open()` vends a fresh, isolated store: no shared state /// between islands, observable on the facade *and* on the fresh media /// (each open's sqlite file and root are private and start empty). #[tokio::test] async fn factory_open_vends_fresh_isolated_sqlite_stores() { let factory = DualTierSqliteFactory::new(TUNED_THRESHOLD); let (a, site_a) = factory.open_tracked().await.expect("open vends a store"); let (b, site_b) = factory.open_tracked().await.expect("open vends another"); assert_ne!( site_a.database(), site_b.database(), "two opens never share a sqlite file" ); assert_ne!( site_a.root(), site_b.root(), "two opens never share a local root" ); let content_a = patterned(2 * TUNED_THRESHOLD as usize + 5, 167); let content_b = patterned(TUNED_THRESHOLD as usize - 5, 191); let (key_a, _) = a .put( Some(content_a.len() as u64), Cursor::new(content_a.as_slice()), ) .await .expect("island a's put publishes"); let (key_b, _) = b .put(None, Cursor::new(content_b.as_slice())) .await .expect("island b's put publishes"); assert!(a.has(&key_a.as_bytes()).await.unwrap()); assert!( !a.has(&key_b.as_bytes()).await.unwrap(), "island a sees nothing of island b" ); assert!(b.has(&key_b.as_bytes()).await.unwrap()); assert!( !b.has(&key_a.as_bytes()).await.unwrap(), "island b sees nothing of island a" ); assert_eq!( ( sqlite_pool_rows(&site_a), committed_file_count(site_a.root()) ), (0, 1), "island a's media hold exactly its own entry (a's content routes large)" ); assert_eq!( ( sqlite_pool_rows(&site_b), committed_file_count(site_b.root()) ), (1, 0), "island b's media hold exactly its own entry (b's content routes kv)" ); let (c, site_c) = factory.open_tracked().await.expect("a third vends fresh"); assert_eq!( ( sqlite_pool_rows(&site_c), committed_file_count(site_c.root()) ), (0, 0), "a third open's media are virgin" ); assert!( !c.has(&key_a.as_bytes()).await.unwrap(), "a third open shares nothing with the first" ); assert!( !c.has(&key_b.as_bytes()).await.unwrap(), "a third open shares nothing with the second" ); factory .teardown() .await .expect("teardown removes the sites"); factory.teardown().await.expect("teardown repeats cleanly"); } /// A failing assertion panics the row before teardown runs — and /// teardown must make sense over the abandoned instance anyway: it is /// idempotent against the panicked row's path, the vended files are /// really gone, and the next open vends a fresh store on a fresh /// (empty) medium (README §The factory contract). #[tokio::test] async fn factory_teardown_is_safe_against_a_panicking_row() { let content = patterned(TUNED_THRESHOLD as usize - 7, 173); let abandoned = Key::derive(&content, content.len() as u64); let factory = Arc::new(DualTierSqliteFactory::new(TUNED_THRESHOLD)); let task = { let factory = Arc::clone(&factory); tokio::spawn(async move { let (store, _) = factory.open_tracked().await.expect("open vends the store"); let (_, pin) = store .put(Some(content.len() as u64), Cursor::new(content.as_slice())) .await .expect("the put publishes"); drop(pin); panic!("a failing assertion panics the row (the factory contract's early exit)"); }) }; assert!( task.await.is_err(), "the row's panic surfaced as its failure" ); let databases = factory.tracked_databases(); assert!(!databases.is_empty(), "the panicked row vended a site"); factory .teardown() .await .expect("teardown makes sense over the abandoned instance"); factory.teardown().await.expect("teardown is idempotent"); for database in databases { assert!( !database.exists(), "teardown removed the panicked row's sqlite file: {database:?}" ); } let (store, site) = factory .open_tracked() .await .expect("the next open still vends a store"); assert!( !store.has(&abandoned.as_bytes()).await.unwrap(), "no residue from the panicked row — isolation is factory-owned" ); assert_eq!( (sqlite_pool_rows(&site), committed_file_count(site.root())), (0, 0), "and its media carry nothing of the abandoned run" ); factory .teardown() .await .expect("teardown removes the last site"); }