use vyre_runtime::resident_work_queue::{
descriptor::{BatchDescriptor, BuiltinOpcode, SlotDescriptor, SlotOpcode},
protocol, ResidentIoQueue, ResidentWorkQueue, IO_SLOT_COUNT,
};
use vyre_runtime::PipelineError;
fn assert_no_cpu_wording(err: &PipelineError) {
let msg = err.to_string().to_lowercase();
assert!(!msg.contains("cpu"), "error must never mention CPU: {msg}");
assert!(
!msg.contains("fallback"),
"error must never mention fallback: {msg}"
);
assert!(
!msg.contains("software"),
"error must never imply software emulation: {msg}"
);
}
#[test]
fn encoder_errors_never_suggest_cpu_fallback() {
let too_many_slots = (u32::MAX / protocol::SLOT_WORDS) + 1;
assert_no_cpu_wording(
&ResidentWorkQueue::try_encode_empty_ring(too_many_slots).expect_err("must fail"),
);
assert_no_cpu_wording(
&ResidentWorkQueue::try_encode_control(false, 1, u32::MAX).expect_err("must fail"),
);
assert_no_cpu_wording(
&ResidentWorkQueue::try_encode_empty_debug_log(u32::MAX).expect_err("must fail"),
);
}
#[test]
fn queue_full_errors_never_suggest_cpu_fallback() {
let mut ring = ResidentWorkQueue::encode_empty_ring(1).unwrap();
let err = ResidentWorkQueue::publish_slot(
&mut ring,
0,
0,
protocol::opcode::NOP,
&[0u32; (protocol::ARGS_PER_SLOT + 1) as usize],
)
.expect_err("too many args must fail");
assert_no_cpu_wording(&err);
let err = ResidentIoQueue::new(0).expect_err("zero slots must fail");
assert_no_cpu_wording(&err);
let err = ResidentIoQueue::new(IO_SLOT_COUNT + 1).expect_err("oversized must fail");
assert_no_cpu_wording(&err);
}
#[test]
fn batch_descriptor_errors_never_suggest_cpu_fallback() {
let mut ring = ResidentWorkQueue::encode_empty_ring(1).unwrap();
let batch = BatchDescriptor::new(
0,
vec![
SlotDescriptor::single(0, SlotOpcode::Builtin(BuiltinOpcode::Nop), vec![]),
SlotDescriptor::single(0, SlotOpcode::Builtin(BuiltinOpcode::Nop), vec![]),
],
);
let err = batch
.publish_into(&mut ring)
.expect_err("overflow must fail");
assert_no_cpu_wording(&err);
}