test: Cycle 54 — grow+send, 20×20 stress, minimal module, data segment template
- grow_memory_and_use_new_page_for_send: memory.grow then send from new page - twenty_actors_twenty_messages_each: 400 total messages across 20 actors - module_with_only_send_import_needed: minimal sending module works - guest_data_segment_used_as_template: data segment content sent as payload All 232 tests pass. No new bugs found. Authored by Claude, lovingly guided by Zachery Aaron Shores-Chmielewski
This commit is contained in:
parent
246f957721
commit
95f1163251
1 changed files with 133 additions and 0 deletions
|
|
@ -8051,4 +8051,137 @@ fn three_level_nested_function_calls() {
|
||||||
|
|
||||||
let msg = inbox.try_recv().unwrap();
|
let msg = inbox.try_recv().unwrap();
|
||||||
assert_eq!(msg.0[0], 36, "(10+2)*3 = 36");
|
assert_eq!(msg.0[0], 36, "(10+2)*3 = 36");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Guest with grow + use new page for send ─────────────────────────────────
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn grow_memory_and_use_new_page_for_send() {
|
||||||
|
// Guest grows memory in handle, then uses the new page for the send dest.
|
||||||
|
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)
|
||||||
|
;; Grow memory by 1 page
|
||||||
|
(drop (memory.grow (i32.const 1)))
|
||||||
|
;; Copy dest address from message to new page (offset 65536)
|
||||||
|
(memory.copy (i32.const 65536) (local.get $ptr) (i32.const 32))
|
||||||
|
;; Write payload at offset 65600
|
||||||
|
(i32.store8 (i32.const 65600) (i32.const 99))
|
||||||
|
;; Send from new page
|
||||||
|
(call $send (i32.const 65536) (i32.const 65600) (i32.const 1))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
"#;
|
||||||
|
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"grow")).unwrap();
|
||||||
|
rt.tick();
|
||||||
|
|
||||||
|
let msg = inbox.try_recv().expect("send from grown page should work");
|
||||||
|
assert_eq!(msg.0, vec![99]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Stress: 20 actors each processing 20 messages ──────────────────────────
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn twenty_actors_twenty_messages_each() {
|
||||||
|
let engine = SharedEngine::new().unwrap();
|
||||||
|
let rt = Runtime::new(RuntimeConfig::default());
|
||||||
|
let inbox = rt.new_inbox::<ByteMessage>().unwrap();
|
||||||
|
|
||||||
|
let mut addrs = Vec::new();
|
||||||
|
for _ in 0..20 {
|
||||||
|
let actor = WasmActorBuilder::new(engine.clone(), guest_wasm("echo")).build().unwrap();
|
||||||
|
addrs.push(rt.spawn(actor).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (a, addr) in addrs.iter().enumerate() {
|
||||||
|
for m in 0u8..20 {
|
||||||
|
rt.send_to(*addr, framed_msg(inbox.addr(), &[a as u8, m])).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process across multiple ticks (budget=64 per actor)
|
||||||
|
for _ in 0..10 {
|
||||||
|
rt.tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut total = 0;
|
||||||
|
while let Some(_) = inbox.try_recv() {
|
||||||
|
total += 1;
|
||||||
|
}
|
||||||
|
assert_eq!(total, 400, "20 actors × 20 messages = 400 responses");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Module with multiple imports (only swactor.send matters) ────────────────
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn module_with_only_send_import_needed() {
|
||||||
|
// Module only imports swactor.send, no other imports.
|
||||||
|
// This is the minimal valid module that can send.
|
||||||
|
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)
|
||||||
|
(i32.store8 (i32.const 200) (i32.const 42))
|
||||||
|
(call $send (local.get $ptr) (i32.const 200) (i32.const 1))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
"#;
|
||||||
|
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"min")).unwrap();
|
||||||
|
rt.tick();
|
||||||
|
|
||||||
|
let msg = inbox.try_recv().unwrap();
|
||||||
|
assert_eq!(msg.0, vec![42]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Guest with memory.init-like pattern using data segments ─────────────────
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn guest_data_segment_used_as_template() {
|
||||||
|
// Guest has a data segment template and sends it as-is.
|
||||||
|
let wat = r#"
|
||||||
|
(module
|
||||||
|
(import "swactor" "send" (func $send (param i32 i32 i32)))
|
||||||
|
(memory (export "memory") 1)
|
||||||
|
(data (i32.const 300) "TEMPLATE")
|
||||||
|
(func (export "alloc") (param i32) (result i32) i32.const 4096)
|
||||||
|
(func (export "handle") (param $ptr i32) (param $len i32)
|
||||||
|
;; Send the data segment content as payload
|
||||||
|
(call $send (local.get $ptr) (i32.const 300) (i32.const 8))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
"#;
|
||||||
|
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"x")).unwrap();
|
||||||
|
rt.tick();
|
||||||
|
|
||||||
|
let msg = inbox.try_recv().unwrap();
|
||||||
|
assert_eq!(msg.0, b"TEMPLATE");
|
||||||
}
|
}
|
||||||
Loading…
Reference in a new issue