mod builder;
use builder::E01Builder;
use ewf_forensic::{AnalysisProgress, EwfIntegrity, EwfIntegrityAnomaly};
use std::path::PathBuf;
fn ewf1_fixture() -> Vec<u8> {
E01Builder::new(65536).build()
}
fn ewf2_fixture_path() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/data/zeros_128s.Ex01")
}
#[test]
fn ewf1_progress_called_at_least_once() {
let data = ewf1_fixture();
let mut call_count = 0usize;
EwfIntegrity::new(&data).analyse_with_progress(|_p| {
call_count += 1;
});
assert!(call_count > 0, "progress callback must be called at least once");
}
#[test]
fn ewf1_progress_chunks_done_monotone() {
let data = ewf1_fixture();
let mut last = 0usize;
EwfIntegrity::new(&data).analyse_with_progress(|p: AnalysisProgress| {
assert!(
p.chunks_done >= last,
"chunks_done must not decrease: was {last}, now {}",
p.chunks_done
);
last = p.chunks_done;
});
}
#[test]
fn ewf1_progress_final_chunks_done_nonzero() {
let data = ewf1_fixture();
let mut final_progress: Option<AnalysisProgress> = None;
EwfIntegrity::new(&data).analyse_with_progress(|p: AnalysisProgress| {
final_progress = Some(p);
});
let p = final_progress.expect("at least one progress callback must fire");
assert!(p.chunks_done > 0, "final chunks_done must be > 0; got {}", p.chunks_done);
}
#[test]
fn ewf1_progress_same_anomalies_as_analyse() {
let data = ewf1_fixture();
let baseline = EwfIntegrity::new(&data).analyse();
let with_progress = EwfIntegrity::new(&data).analyse_with_progress(|_| {});
assert_eq!(
baseline, with_progress,
"analyse_with_progress must return same anomalies as analyse()"
);
}
#[test]
fn ewf1_progress_bytes_done_monotone() {
let data = ewf1_fixture();
let mut last_bytes = 0u64;
EwfIntegrity::new(&data).analyse_with_progress(|p: AnalysisProgress| {
assert!(
p.bytes_done >= last_bytes,
"bytes_done must not decrease: was {last_bytes}, now {}",
p.bytes_done
);
last_bytes = p.bytes_done;
});
}
#[test]
fn ewf2_progress_chunks_total_matches_chunk_table() {
let path = ewf2_fixture_path();
if !path.exists() {
eprintln!("skipping: fixture not found");
return;
}
let data = std::fs::read(&path).expect("read fixture");
let mut last: Option<AnalysisProgress> = None;
EwfIntegrity::new(&data).analyse_with_progress(|p: AnalysisProgress| {
last = Some(p);
});
let p = last.expect("at least one callback");
assert_eq!(
p.chunks_total,
Some(2),
"zeros_128s.Ex01 has 2 chunks; chunks_total must be Some(2), got {:?}",
p.chunks_total
);
assert_eq!(
p.chunks_done, 2,
"final chunks_done must equal chunks_total=2, got {}",
p.chunks_done
);
}
#[test]
fn ewf2_progress_same_anomalies_as_analyse() {
let path = ewf2_fixture_path();
if !path.exists() {
eprintln!("skipping: fixture not found");
return;
}
let data = std::fs::read(&path).expect("read fixture");
let baseline = EwfIntegrity::new(&data).analyse();
let with_progress = EwfIntegrity::new(&data).analyse_with_progress(|_| {});
assert_eq!(baseline, with_progress);
}