use std::fs;
use std::path::PathBuf;
fn backend_triggered_src() -> String {
fs::read_to_string(
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("src/engine/backend_triggered.rs"),
)
.expect("backend_triggered.rs readable")
}
#[test]
fn per_chunk_gpu_failure_is_hard_and_reason_carrying() {
let src = backend_triggered_src();
assert!(
src.contains("self.record_gpu_runtime_fault(reason.clone())")
&& src.contains("Err(crate::error::ScanError::Gpu(reason))"),
"collect_triggered_patterns_gpu must return every off-GPU path as a recorded structured GPU error"
);
assert!(
src.contains("gpu literal matcher not built for this scanner")
&& src.contains("self.gpu_backend_unavailable_reason(route)")
&& src.contains("gpu presence scan failed:"),
"each off-GPU cause (no matcher / no backend / failed dispatch) must carry a concrete reason"
);
}
#[test]
fn per_chunk_gpu_has_no_silent_simd_swap() {
let src = backend_triggered_src();
let start = src
.find("fn collect_triggered_patterns_gpu(")
.expect("collect_triggered_patterns_gpu present");
let body = &src[start..];
let end = body
.find("\n fn ")
.or_else(|| body.find("\n pub(crate) fn "))
.map(|off| start + off)
.unwrap_or(src.len());
let func = &src[start..end];
assert!(
func.contains("self.record_gpu_runtime_fault(reason.clone())")
&& func.contains("Err(crate::error::ScanError::Gpu(reason))")
&& func.matches("return dispatch_failure(").count() >= 2
&& func.contains("Err(error) => dispatch_failure(")
&& !func.contains("degraded_backend_after_gpu_failure")
&& !func.contains("process_exit"),
"the per-chunk GPU path must return dispatch failures without a CPU/SIMD substitution or process-exit ownership"
);
assert!(
!func.contains("tracing::debug!(\"gpu presence scan failed"),
"a failed presence dispatch must terminate visibly, not continue after tracing::debug!"
);
}