test(wasm-actor): cycle 86 — conditional double, 200 tick longevity, AND mask (383 tests)

Added 4 tests: conditional double or echo, 200 messages across 200 ticks,
three inboxes from same runtime, AND mask low nibble. No new bugs found.

Authored by Claude, lovingly guided by Zachery Aaron Shores-Chmielewski
This commit is contained in:
Claude 2026-02-13 10:56:32 +00:00
parent dda7b1f1e9
commit 265a0ba7a7

View file

@ -12221,3 +12221,132 @@ fn budget_leaves_remaining_for_next_tick() {
assert_eq!(t1 + t2 + t3, 12, "all 12 processed across ticks");
assert!(t1 <= 5, "budget limits first tick");
}
// ── Cycle 86 ─────────────────────────────────────────────────────────────────
// Guest doubles only specific payloads, echoes others
#[test]
fn guest_conditional_double_or_echo() {
let wat = r#"(module
(import "swactor" "send" (func $send (param i32 i32 i32)))
(memory (export "memory") 1)
(func (export "alloc") (param $len i32) (result i32) i32.const 1024)
(func (export "handle") (param $ptr i32) (param $len i32)
(local $payload_len i32)
(if (i32.lt_u (local.get $len) (i32.const 33)) (then return))
(local.set $payload_len (i32.sub (local.get $len) (i32.const 32)))
;; If first payload byte is 0xDD, double it
(if (i32.eq (i32.load8_u (i32.add (local.get $ptr) (i32.const 32))) (i32.const 0xDD))
(then
;; Send twice
(call $send (local.get $ptr) (i32.add (local.get $ptr) (i32.const 32)) (local.get $payload_len))
(call $send (local.get $ptr) (i32.add (local.get $ptr) (i32.const 32)) (local.get $payload_len))
)
(else
;; Echo once
(call $send (local.get $ptr) (i32.add (local.get $ptr) (i32.const 32)) (local.get $payload_len))
)
)
)
)"#;
let engine = SharedEngine::new().unwrap();
let actor = WasmActorBuilder::new(engine, wat::parse_str(wat).unwrap())
.build().unwrap();
let rt = Runtime::new(RuntimeConfig::default());
let inbox = rt.new_inbox::<ByteMessage>().unwrap();
let addr = rt.spawn(actor).unwrap();
// Regular message — echo
rt.send_to(addr, framed_msg(inbox.addr(), &[0xAA, 0xBB])).unwrap();
// Trigger double
rt.send_to(addr, framed_msg(inbox.addr(), &[0xDD, 0xEE])).unwrap();
rt.tick();
let msgs: Vec<Vec<u8>> = std::iter::from_fn(|| inbox.try_recv().map(|m| m.0)).collect();
assert_eq!(msgs.len(), 3, "1 echo + 2 double = 3");
}
// Long-running WASM actor: 200 messages across 200 ticks
#[test]
fn two_hundred_messages_across_two_hundred_ticks() {
let engine = SharedEngine::new().unwrap();
let actor = WasmActorBuilder::new(engine, guest_wasm("echo")).build().unwrap();
let rt = Runtime::new(RuntimeConfig::default());
let inbox = rt.new_inbox::<ByteMessage>().unwrap();
let addr = rt.spawn(actor).unwrap();
for i in 0u8..200 {
rt.send_to(addr, framed_msg(inbox.addr(), &[i])).unwrap();
rt.tick();
let resp = inbox.try_recv().expect("each tick echoes");
assert_eq!(resp.0, vec![i]);
}
}
// Multiple inboxes from same runtime
#[test]
fn three_inboxes_from_same_runtime() {
let engine = SharedEngine::new().unwrap();
let rt = Runtime::new(RuntimeConfig::default());
let inbox1 = rt.new_inbox::<ByteMessage>().unwrap();
let inbox2 = rt.new_inbox::<ByteMessage>().unwrap();
let inbox3 = rt.new_inbox::<ByteMessage>().unwrap();
let actor = WasmActorBuilder::new(engine, guest_wasm("echo")).build().unwrap();
let addr = rt.spawn(actor).unwrap();
// Send to echo targeting different inboxes
rt.send_to(addr, framed_msg(inbox1.addr(), b"one")).unwrap();
rt.tick();
rt.send_to(addr, framed_msg(inbox2.addr(), b"two")).unwrap();
rt.tick();
rt.send_to(addr, framed_msg(inbox3.addr(), b"three")).unwrap();
rt.tick();
assert_eq!(inbox1.try_recv().unwrap().0, b"one");
assert_eq!(inbox2.try_recv().unwrap().0, b"two");
assert_eq!(inbox3.try_recv().unwrap().0, b"three");
}
// Guest that uses i32.and to mask bytes
#[test]
fn guest_and_mask_low_nibble() {
let wat = r#"(module
(import "swactor" "send" (func $send (param i32 i32 i32)))
(memory (export "memory") 1)
(func (export "alloc") (param $len i32) (result i32) i32.const 1024)
(func (export "handle") (param $ptr i32) (param $len i32)
(local $i i32)
(if (i32.lt_u (local.get $len) (i32.const 33)) (then return))
;; Mask each payload byte to low nibble
(local.set $i (i32.const 32))
(block $exit
(loop $loop
(br_if $exit (i32.ge_u (local.get $i) (local.get $len)))
(i32.store8
(i32.add (local.get $ptr) (local.get $i))
(i32.and
(i32.load8_u (i32.add (local.get $ptr) (local.get $i)))
(i32.const 0x0F)))
(local.set $i (i32.add (local.get $i) (i32.const 1)))
(br $loop)
)
)
(call $send (local.get $ptr)
(i32.add (local.get $ptr) (i32.const 32))
(i32.sub (local.get $len) (i32.const 32)))
)
)"#;
let engine = SharedEngine::new().unwrap();
let actor = WasmActorBuilder::new(engine, wat::parse_str(wat).unwrap())
.build().unwrap();
let rt = Runtime::new(RuntimeConfig::default());
let inbox = rt.new_inbox::<ByteMessage>().unwrap();
let addr = rt.spawn(actor).unwrap();
rt.send_to(addr, framed_msg(inbox.addr(), &[0xAB, 0xCD, 0xEF])).unwrap();
rt.tick();
let resp = inbox.try_recv().expect("masked response");
assert_eq!(resp.0, vec![0x0B, 0x0D, 0x0F]);
}