test: Cycle 45 — 4KB round-trip, payload length report, odd alignment, idle ticks
- large_4kb_message_round_trips: 4096-byte payload echoes with pattern verification - guest_reports_payload_length: guest computes and sends back payload length as LE i32 - alloc_returns_odd_alignment: alloc returns 1 (unaligned), host writes correctly - shared_engine_clone_and_debug: cloned engine Debug output matches - idle_ticks_dont_affect_wasm_actor: 500 empty ticks, then message still works All 193 tests pass. No new bugs found. Authored by Claude, lovingly guided by Zachery Aaron Shores-Chmielewski
This commit is contained in:
parent
82ca6869aa
commit
2d24737026
1 changed files with 124 additions and 0 deletions
|
|
@ -6806,3 +6806,127 @@ fn double_guest_with_max_byte_value() {
|
||||||
assert_eq!(msg2.0, vec![0xFF]);
|
assert_eq!(msg2.0, vec![0xFF]);
|
||||||
assert!(inbox.try_recv().is_none(), "exactly two copies");
|
assert!(inbox.try_recv().is_none(), "exactly two copies");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── ByteMessage supports large messages (4KB) ───────────────────────────────
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn large_4kb_message_round_trips() {
|
||||||
|
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();
|
||||||
|
|
||||||
|
// 4KB payload (each byte = position mod 256)
|
||||||
|
let payload: Vec<u8> = (0..4096).map(|i| (i & 0xFF) as u8).collect();
|
||||||
|
rt.send_to(addr, framed_msg(inbox.addr(), &payload)).unwrap();
|
||||||
|
rt.tick();
|
||||||
|
|
||||||
|
let msg = inbox.try_recv().unwrap();
|
||||||
|
assert_eq!(msg.0.len(), 4096);
|
||||||
|
assert_eq!(msg.0, payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Guest that sends back payload length as response ────────────────────────
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn guest_reports_payload_length() {
|
||||||
|
// Guest reads the payload length (len-32) and sends it back as a 4-byte LE integer.
|
||||||
|
let wat = r#"
|
||||||
|
(module
|
||||||
|
(import "swactor" "send" (func $send (param i32 i32 i32)))
|
||||||
|
(memory (export "memory") 1)
|
||||||
|
(func (export "alloc") (param i32) (result i32) i32.const 4096)
|
||||||
|
(func (export "handle") (param $ptr i32) (param $len i32)
|
||||||
|
;; Store payload_len = len - 32 as i32 at offset 200
|
||||||
|
(i32.store (i32.const 200) (i32.sub (local.get $len) (i32.const 32)))
|
||||||
|
(call $send (local.get $ptr) (i32.const 200) (i32.const 4))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
"#;
|
||||||
|
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 inbox = rt.new_inbox::<ByteMessage>().unwrap();
|
||||||
|
let addr = rt.spawn(actor).unwrap();
|
||||||
|
|
||||||
|
rt.send_to(addr, framed_msg(inbox.addr(), &[0u8; 100])).unwrap();
|
||||||
|
rt.tick();
|
||||||
|
|
||||||
|
let msg = inbox.try_recv().unwrap();
|
||||||
|
let len = i32::from_le_bytes([msg.0[0], msg.0[1], msg.0[2], msg.0[3]]);
|
||||||
|
assert_eq!(len, 100, "guest should report payload length of 100");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Alloc returns 1 (odd alignment) — still works ──────────────────────────
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn alloc_returns_odd_alignment() {
|
||||||
|
// Guest alloc returns 1 (not aligned). Host should still write correctly.
|
||||||
|
let wat = r#"
|
||||||
|
(module
|
||||||
|
(import "swactor" "send" (func $send (param i32 i32 i32)))
|
||||||
|
(memory (export "memory") 1)
|
||||||
|
(func (export "alloc") (param i32) (result i32) i32.const 1)
|
||||||
|
(func (export "handle") (param $ptr i32) (param $len i32)
|
||||||
|
;; Echo from offset 1
|
||||||
|
(call $send
|
||||||
|
(local.get $ptr)
|
||||||
|
(i32.add (local.get $ptr) (i32.const 32))
|
||||||
|
(i32.sub (local.get $len) (i32.const 32))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
"#;
|
||||||
|
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 inbox = rt.new_inbox::<ByteMessage>().unwrap();
|
||||||
|
let addr = rt.spawn(actor).unwrap();
|
||||||
|
|
||||||
|
rt.send_to(addr, framed_msg(inbox.addr(), b"odd-align")).unwrap();
|
||||||
|
rt.tick();
|
||||||
|
|
||||||
|
let msg = inbox.try_recv().unwrap();
|
||||||
|
assert_eq!(msg.0, b"odd-align");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── SharedEngine clone + Debug ──────────────────────────────────────────────
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn shared_engine_clone_and_debug() {
|
||||||
|
let engine = SharedEngine::new().unwrap();
|
||||||
|
let cloned = engine.clone();
|
||||||
|
let debug1 = format!("{:?}", engine);
|
||||||
|
let debug2 = format!("{:?}", cloned);
|
||||||
|
assert_eq!(debug1, debug2, "cloned engine should have same debug repr");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Multiple sequential ticks without messages don't affect WASM actor ──────
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn idle_ticks_dont_affect_wasm_actor() {
|
||||||
|
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();
|
||||||
|
|
||||||
|
// 500 idle ticks
|
||||||
|
for _ in 0..500 {
|
||||||
|
rt.tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should still work
|
||||||
|
rt.send_to(addr, framed_msg(inbox.addr(), b"after-idle")).unwrap();
|
||||||
|
rt.tick();
|
||||||
|
|
||||||
|
let msg = inbox.try_recv().unwrap();
|
||||||
|
assert_eq!(msg.0, b"after-idle");
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue