#![allow(clippy::unwrap_used, clippy::expect_used, clippy::pedantic)]
use std::path::{Path, PathBuf};
use sqlite_core::{Database, Value};
use sqlite_forensic::{
audit, carve_all_deleted_records, carve_with_fragments, row_histories_with_residue,
};
fn corpus_root() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR"))
.join("..")
.join("tests")
.join("data")
.join("nemetz")
}
fn all_corpus_dbs() -> Vec<PathBuf> {
let mut out = Vec::new();
let root = corpus_root();
let mut stack = vec![root];
while let Some(dir) = stack.pop() {
let Ok(entries) = std::fs::read_dir(&dir) else {
continue;
};
for entry in entries.flatten() {
let path = entry.path();
if path.is_dir() {
stack.push(path);
} else if path.extension().and_then(|e| e.to_str()) == Some("db") {
out.push(path);
}
}
}
out.sort();
out
}
fn assert_record_sane(values: &[Value]) {
assert!(
values.len() <= 100_000,
"carved record has implausible column count {}",
values.len()
);
for v in values {
if let Value::Blob(b) = v {
let _ = b.len();
}
}
}
#[test]
fn full_corpus_is_panic_free_end_to_end() {
let dbs = all_corpus_dbs();
assert!(
dbs.len() >= 141,
"expected the full 141-database Nemetz corpus to be vendored, found only {} .db files under {}",
dbs.len(),
corpus_root().display()
);
let mut opened = 0usize;
for path in &dbs {
let bytes = std::fs::read(path).expect("corpus db readable");
let wal_path = path.with_extension("db-wal");
let db = if wal_path.exists() {
let wal = std::fs::read(&wal_path).expect("wal sidecar readable");
match Database::open_with_wal(bytes, &wal) {
Ok(db) => db,
Err(_) => continue,
}
} else {
match Database::open(bytes) {
Ok(db) => db,
Err(_) => continue,
}
};
opened += 1;
let tiers = carve_with_fragments(&db);
let full = carve_all_deleted_records(&db);
assert_eq!(
tiers.full,
full,
"{}: carve_with_fragments.full diverged from carve_all_deleted_records",
path.display()
);
for rec in &tiers.full {
assert_record_sane(&rec.values);
}
let anomalies = audit(&db);
assert!(
anomalies.len() <= 1_000_000,
"{}: audit returned an implausible anomaly count {}",
path.display(),
anomalies.len()
);
let _ = row_histories_with_residue(&db);
let rebuild_rows: Vec<sqlite_core::rebuild::RebuildRow> = tiers
.full
.iter()
.map(|r| sqlite_core::rebuild::RebuildRow {
page: r.page,
offset: r.offset,
rowid: Some(r.rowid),
source: format!("{:?}", r.source),
confidence: r.confidence,
cells: r.values.clone(),
})
.collect();
let image = sqlite_core::rebuild::build_recovered_db(&rebuild_rows);
let reopened = Database::open(image).expect("rebuilt image must re-open");
let _ = reopened.read_table(1, 5).expect("rebuilt schema readable");
}
assert!(
opened > 0,
"no corpus database opened — the pipeline never ran"
);
}