#[cfg(loom)]
use loom::sync::atomic::{AtomicUsize, Ordering};
#[cfg(not(loom))]
use std::sync::atomic::{AtomicUsize, Ordering};
use crate::pipeline::backend::{ConformDispatchConfig, ExecutionModel, VyreBackend};
#[cfg(test)]
mod tests {
use super::*;
struct MockBackend {
output: Vec<u8>,
}
impl VyreBackend for MockBackend {
fn name(&self) -> &str {
"mock"
}
fn dispatch(
&self,
_wgsl: &str,
_input: &[u8],
_output_size: usize,
_config: ConformDispatchConfig,
) -> Result<Vec<u8>, String> {
Ok(self.output.clone())
}
fn dispatch_program(
&self,
_program: &[u8],
_input: &[u8],
_output_size: usize,
_config: ConformDispatchConfig,
) -> Result<Vec<u8>, String> {
Ok(self.output.clone())
}
}
#[test]
fn fault_backend_succeeds_before_threshold() {
let inner = MockBackend {
output: vec![0xAB, 0xCD],
};
let fault = FaultInjectingBackend::new(&inner, 2);
assert!(fault
.dispatch("", &[], 2, ConformDispatchConfig::default())
.is_ok());
assert!(fault
.dispatch("", &[], 2, ConformDispatchConfig::default())
.is_ok());
}
#[test]
fn fault_backend_fails_at_threshold_without_panic() {
let inner = MockBackend {
output: vec![0xAB, 0xCD],
};
let fault = FaultInjectingBackend::new(&inner, 1);
assert!(fault
.dispatch("", &[], 2, ConformDispatchConfig::default())
.is_ok());
let result = fault.dispatch("", &[], 2, ConformDispatchConfig::default());
assert!(
result.is_err(),
"expected structured error at fail_after threshold, got: {:?}",
result
);
let msg = result.unwrap_err();
assert!(
msg.contains("Fault injection"),
"error must mention fault injection, got: {msg}"
);
}
#[test]
fn with_fault_at_dispatch_detects_failure() {
let inner = MockBackend {
output: vec![0x00; 4],
};
let program = vyre::ir::Program::new(vec![], [1, 1, 1], vec![vyre::ir::Node::Return]);
let result = with_fault_at_dispatch(&inner, &program, &[], 4, ConformDispatchConfig::default(), 0);
assert!(
result.is_err(),
"expected failure when fail_after=0, got: {:?}",
result
);
}
#[test]
fn with_fault_at_dispatch_allows_success() {
let inner = MockBackend {
output: vec![0x00; 4],
};
let program = vyre::ir::Program::new(vec![], [1, 1, 1], vec![vyre::ir::Node::Return]);
let result = with_fault_at_dispatch(&inner, &program, &[], 4, ConformDispatchConfig::default(), 5);
assert!(
result.is_ok(),
"expected success when fail_after is high, got: {:?}",
result
);
}
}