test: Cycle 6 — bounded mailbox backpressure + alloc fuzzing property test
Authored by Claude, lovingly guided by Zachery Aaron Shores-Chmielewski
This commit is contained in:
parent
4bc6f6077d
commit
a171faaad2
2 changed files with 74 additions and 0 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -2747,6 +2747,7 @@ dependencies = [
|
||||||
name = "swactor-wasm-actor"
|
name = "swactor-wasm-actor"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"proptest",
|
||||||
"swactor",
|
"swactor",
|
||||||
"wasmtime",
|
"wasmtime",
|
||||||
"wat",
|
"wat",
|
||||||
|
|
|
||||||
|
|
@ -1202,6 +1202,79 @@ fn native_handler_spawns_wasm_actor_and_forwards_message() {
|
||||||
assert_eq!(received.0, b"spawned-echo");
|
assert_eq!(received.0, b"spawned-echo");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Bounded mailbox: WASM actor with backpressure ────────────────────────────
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bounded_mailbox_applies_to_wasm_actor() {
|
||||||
|
// With a bounded mailbox of capacity 3, sending 10 messages should
|
||||||
|
// result in only 3 being processed (DropNewest policy).
|
||||||
|
use swactor::runtime::MailboxOverflow;
|
||||||
|
|
||||||
|
let engine = SharedEngine::new().unwrap();
|
||||||
|
let actor = WasmActorBuilder::new(engine, guest_wasm("echo"))
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let config = RuntimeConfig {
|
||||||
|
default_mailbox_capacity: 3,
|
||||||
|
mailbox_overflow: MailboxOverflow::DropNewest,
|
||||||
|
..RuntimeConfig::default()
|
||||||
|
};
|
||||||
|
let rt = Runtime::new(config);
|
||||||
|
let inbox = rt.new_inbox::<ByteMessage>().unwrap();
|
||||||
|
let addr = rt.spawn(actor).unwrap();
|
||||||
|
|
||||||
|
// Send 10 messages before any tick — only first 3 should be kept
|
||||||
|
for i in 0u8..10 {
|
||||||
|
rt.send_to(addr, framed_msg(inbox.addr(), &[i])).unwrap();
|
||||||
|
}
|
||||||
|
rt.tick();
|
||||||
|
|
||||||
|
let mut received = Vec::new();
|
||||||
|
while let Some(msg) = inbox.try_recv() {
|
||||||
|
received.push(msg.0[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(received.len(), 3, "bounded mailbox should limit to 3 messages");
|
||||||
|
// DropNewest keeps the first 3 sent
|
||||||
|
assert_eq!(received, vec![0, 1, 2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Property: alloc failures never kill the actor ────────────────────────────
|
||||||
|
|
||||||
|
proptest! {
|
||||||
|
#[test]
|
||||||
|
fn prop_any_alloc_return_value_never_kills_actor(alloc_val in -100i32..70000) {
|
||||||
|
// Regardless of what alloc returns (negative, zero, OOB, valid),
|
||||||
|
// sending a message should never kill the actor.
|
||||||
|
let alloc_const = format!("i32.const {alloc_val}");
|
||||||
|
let wat = format!(r#"
|
||||||
|
(module
|
||||||
|
(import "swactor" "send" (func $send (param i32 i32 i32)))
|
||||||
|
(memory (export "memory") 1)
|
||||||
|
(func (export "alloc") (param i32) (result i32)
|
||||||
|
{alloc_const}
|
||||||
|
)
|
||||||
|
(func (export "handle") (param i32 i32))
|
||||||
|
)
|
||||||
|
"#);
|
||||||
|
let wasm = wat::parse_str(&wat).unwrap();
|
||||||
|
let engine = SharedEngine::new().unwrap();
|
||||||
|
let actor = WasmActorBuilder::new(engine, wasm).build().unwrap();
|
||||||
|
|
||||||
|
let rt = Runtime::new(RuntimeConfig::default());
|
||||||
|
let addr = rt.spawn(actor).unwrap();
|
||||||
|
|
||||||
|
// Send a message — should never panic or poison
|
||||||
|
rt.send_to(addr, ByteMessage(vec![0u8; 100])).unwrap();
|
||||||
|
rt.tick();
|
||||||
|
|
||||||
|
// Actor should still accept messages (not poisoned)
|
||||||
|
let result = rt.send_to(addr, ByteMessage(vec![1]));
|
||||||
|
prop_assert!(result.is_ok(), "actor should survive any alloc return value: {alloc_val}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ── Multi-worker: WASM actors across threads ─────────────────────────────────
|
// ── Multi-worker: WASM actors across threads ─────────────────────────────────
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue