@@ -22,36 +22,45 @@ use std::panic::AssertUnwindSafe;
2222use std:: sync:: Arc ;
2323
2424use futures:: FutureExt ;
25- use omnigraph:: db:: ReadTarget ;
25+ use omnigraph:: db:: { Omnigraph , ReadTarget } ;
2626use omnigraph:: loader:: { LoadMode , load_jsonl} ;
2727use omnigraph_compiler:: ir:: ParamMap ;
2828
29- #[ path = "dst/op.rs" ]
30- mod op;
31- #[ path = "dst/model.rs" ]
32- mod model;
33- #[ path = "dst/fault.rs" ]
34- mod fault;
35- #[ path = "dst/invariants.rs" ]
36- mod invariants;
29+ // The reusable harness primitives (op alphabet, reference model, white-box
30+ // battery, fault adapter, the `Backend` trait + `Embedded`/`Cli`) live in the
31+ // shared `omnigraph-dst` crate so the SAME walk can also run cross-backend (see
32+ // `omnigraph-cli/tests/cli_cross_backend_walk.rs`). This binary is the embedded
33+ // consumer: it adds the named regressions + the white-box generative walk.
34+ use omnigraph_dst:: backend:: Embedded ;
35+ use omnigraph_dst:: invariants:: { self , Finding , classify, classify_backend, run_battery} ;
36+ use omnigraph_dst:: model:: Model ;
37+ use omnigraph_dst:: op:: { self , Rng , doc, knows, person} ;
38+
39+ // Engine-local modules that stay in-tree (they drive the `Omnigraph` handle /
40+ // compiler / loader directly, with no Backend abstraction): the coverage ledger,
41+ // the D2×D3 read-shape battery, the proptest-state-machine shrinking campaign,
42+ // and the parser/loader fuzz.
43+ //
44+ // NOTE: the failpoint-gated recovery cells live in their OWN binary
45+ // (`tests/dst_recovery.rs`), not here — the process-global `fail` registry would
46+ // otherwise leak armed failpoints into these (non-serial, parallel) walks.
3747#[ path = "dst/coverage.rs" ]
3848mod coverage;
39- #[ path = "dst/backend.rs" ]
40- mod backend;
4149#[ path = "dst/readshape.rs" ]
4250mod readshape;
4351#[ path = "dst/statemachine.rs" ]
4452mod statemachine;
4553#[ path = "dst/fuzz.rs" ]
4654mod fuzz;
47- // NOTE: the failpoint-gated recovery cells live in their OWN binary
48- // (`tests/dst_recovery.rs`), not here — the process-global `fail` registry would
49- // otherwise leak armed failpoints into these (non-serial, parallel) walks.
5055
5156use coverage:: Coverage ;
52- use invariants:: { Finding , classify, run_battery} ;
53- use model:: Model ;
54- use op:: { Rng , doc, knows, person} ;
57+
58+ /// A raw embedded graph for the white-box regressions/scenarios — they drive the
59+ /// `Omnigraph` handle directly. The generative walk uses `Embedded` (the Backend
60+ /// impl) instead so the same code can run cross-backend.
61+ async fn open_clean ( uri : & str ) -> Omnigraph {
62+ Omnigraph :: init ( uri, op:: SCHEMA ) . await . expect ( "init" )
63+ }
5564
5665// ═══════════════════════════ named regressions ════════════════════════════
5766
@@ -61,7 +70,7 @@ use op::{Rng, doc, knows, person};
6170#[ tokio:: test]
6271async fn regression_rc1_stale_view_on_delete_combo ( ) {
6372 let dir = tempfile:: tempdir ( ) . unwrap ( ) ;
64- let db = backend :: open_clean ( dir. path ( ) . to_str ( ) . unwrap ( ) ) . await ;
73+ let db = open_clean ( dir. path ( ) . to_str ( ) . unwrap ( ) ) . await ;
6574 let mut seed = String :: new ( ) ;
6675 for i in 0 ..50 {
6776 seed. push_str ( & person ( & format ! ( "p{i}" ) ) ) ;
@@ -87,7 +96,7 @@ async fn regression_rc1_stale_view_on_delete_combo() {
8796#[ tokio:: test]
8897async fn regression_rc_x_btree_from_sorted_iter ( ) {
8998 let dir = tempfile:: tempdir ( ) . unwrap ( ) ;
90- let db = Arc :: new ( backend :: open_clean ( dir. path ( ) . to_str ( ) . unwrap ( ) ) . await ) ;
99+ let db = Arc :: new ( open_clean ( dir. path ( ) . to_str ( ) . unwrap ( ) ) . await ) ;
91100 const FRAGS : usize = 3 ;
92101 const PER : usize = 600 ;
93102 for frag in 0 ..FRAGS {
@@ -155,7 +164,7 @@ async fn regression_rc_x_btree_from_sorted_iter() {
155164#[ tokio:: test]
156165async fn regression_dup_key_under_concurrency ( ) {
157166 let dir = tempfile:: tempdir ( ) . unwrap ( ) ;
158- let db = Arc :: new ( backend :: open_clean ( dir. path ( ) . to_str ( ) . unwrap ( ) ) . await ) ;
167+ let db = Arc :: new ( open_clean ( dir. path ( ) . to_str ( ) . unwrap ( ) ) . await ) ;
159168 let workers = 4usize ;
160169 let keys = 500usize ;
161170 let mut handles = Vec :: new ( ) ;
@@ -203,7 +212,7 @@ async fn regression_dup_key_under_concurrency() {
203212#[ tokio:: test]
204213async fn regression_self_loop_not_traversable ( ) {
205214 let dir = tempfile:: tempdir ( ) . unwrap ( ) ;
206- let db = backend :: open_clean ( dir. path ( ) . to_str ( ) . unwrap ( ) ) . await ;
215+ let db = open_clean ( dir. path ( ) . to_str ( ) . unwrap ( ) ) . await ;
207216 load_jsonl ( & db, & person ( "s0" ) , LoadMode :: Merge ) . await . unwrap ( ) ;
208217 load_jsonl ( & db, & knows ( "s0" , "s0" ) , LoadMode :: Merge ) . await . unwrap ( ) ;
209218
@@ -255,7 +264,7 @@ async fn concurrent_walk_structural_invariants() {
255264 let mut reproduced: Vec < String > = Vec :: new ( ) ;
256265 for seed in 0 ..3u64 {
257266 let dir = tempfile:: tempdir ( ) . unwrap ( ) ;
258- let db = Arc :: new ( backend :: open_clean ( dir. path ( ) . to_str ( ) . unwrap ( ) ) . await ) ;
267+ let db = Arc :: new ( open_clean ( dir. path ( ) . to_str ( ) . unwrap ( ) ) . await ) ;
259268 let actors = 4usize ;
260269 let mut handles = Vec :: new ( ) ;
261270 for a in 0 ..actors {
@@ -347,7 +356,7 @@ async fn person_exists(db: &omnigraph::db::Omnigraph, branch: &str, slug: &str)
347356#[ tokio:: test]
348357async fn branch_isolation_and_merge ( ) {
349358 let dir = tempfile:: tempdir ( ) . unwrap ( ) ;
350- let db = backend :: open_clean ( dir. path ( ) . to_str ( ) . unwrap ( ) ) . await ;
359+ let db = open_clean ( dir. path ( ) . to_str ( ) . unwrap ( ) ) . await ;
351360 let mut seed = String :: new ( ) ;
352361 for i in 0 ..5 {
353362 seed. push_str ( & person ( & format ! ( "p{i}" ) ) ) ;
@@ -462,9 +471,9 @@ async fn run_walk(faults: bool) {
462471 let dir = tempfile:: tempdir ( ) . unwrap ( ) ;
463472 let uri = dir. path ( ) . to_str ( ) . unwrap ( ) ;
464473 let mut db = if faults {
465- backend :: open_faulted ( uri, seed, 8 ) . await
474+ Embedded :: open_faulted ( uri, seed, 8 ) . await
466475 } else {
467- backend :: open_clean ( uri) . await
476+ Embedded :: open_clean ( uri) . await
468477 } ;
469478 let mut rng = Rng :: new ( seed) ;
470479 let mut model = Model :: new ( ) ;
@@ -477,7 +486,7 @@ async fn run_walk(faults: bool) {
477486 // faulted walk continues fault-free after it — acceptable.)
478487 if step_i > 0 && rng. below ( 100 ) < 15 {
479488 drop ( db) ;
480- db = backend :: reopen ( uri) . await ;
489+ db = Embedded :: reopen ( uri) . await ;
481490 cov. op ( op:: OpKind :: Reopen ) ;
482491 }
483492 // A fault-injection / depth DST harness must treat a substrate PANIC
@@ -504,8 +513,7 @@ async fn run_walk(faults: bool) {
504513 } ;
505514 cov. op ( kind) ;
506515 if let Err ( e) = res {
507- let f = Finding :: Engine ( e) ;
508- match classify ( & f) {
516+ match classify_backend ( & e) {
509517 Some ( bug) => {
510518 cov. finding ( bug) ;
511519 reproduced. push ( format ! ( "seed={seed} step={step_i} op[{kind:?}] -> {bug}" ) ) ;
@@ -514,7 +522,7 @@ async fn run_walk(faults: bool) {
514522 // Fault injection legitimately fails writes in varied ways;
515523 // the INVARIANT checks below stay strict.
516524 None if faults => { }
517- None => panic ! ( "seed={seed} step={step_i}: NOVEL op error: {}" , f . message( ) ) ,
525+ None => panic ! ( "seed={seed} step={step_i}: NOVEL op error: {}" , e . message( ) ) ,
518526 }
519527 }
520528 let battery = match AssertUnwindSafe ( run_battery ( & db, & model) ) . catch_unwind ( ) . await {
@@ -556,7 +564,7 @@ async fn run_walk(faults: bool) {
556564 // prove the sweep left no residual drift. Reuses the same battery at
557565 // durability time, so no separate coverage cell.
558566 drop ( db) ;
559- let reopened = backend :: reopen ( uri) . await ;
567+ let reopened = Embedded :: reopen ( uri) . await ;
560568 for ( name, res) in run_battery ( & reopened, & model) . await {
561569 if let Err ( f) = res {
562570 match classify ( & f) {
@@ -616,7 +624,7 @@ async fn s3_battery_holds() {
616624 eprintln ! ( "skipping s3 dst battery: OMNIGRAPH_S3_TEST_BUCKET unset" ) ;
617625 return ;
618626 } ;
619- let db = backend :: open_clean ( & uri) . await ;
627+ let db = Embedded :: open_clean ( & uri) . await ;
620628 let mut rng = Rng :: new ( 1 ) ;
621629 let mut model = Model :: new ( ) ;
622630 for _ in 0 ..8 {
0 commit comments