Move tests to main test suite (#1568)

Some merge-related fallout which needs to be cleaned up after we
consolidated all of the test suites into one location.
This commit is contained in:
Alex Crichton
2020-04-21 14:23:38 -05:00
committed by GitHub
parent c9a0ba81a0
commit 3862c1f3a8
3 changed files with 2 additions and 0 deletions

View File

@@ -1,135 +0,0 @@
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
use wasmtime::*;
fn interruptable_store() -> Store {
let engine = Engine::new(Config::new().interruptable(true));
Store::new(&engine)
}
fn hugely_recursive_module(store: &Store) -> anyhow::Result<Module> {
let mut wat = String::new();
wat.push_str(
r#"
(import "" "" (func))
(func (export "loop") call 2 call 2)
"#,
);
for i in 0..100 {
wat.push_str(&format!("(func call {0} call {0})\n", i + 3));
}
wat.push_str("(func call 0)\n");
Module::new(&store, &wat)
}
#[test]
fn loops_interruptable() -> anyhow::Result<()> {
let store = interruptable_store();
let module = Module::new(&store, r#"(func (export "loop") (loop br 0))"#)?;
let instance = Instance::new(&module, &[])?;
let iloop = instance.get_func("loop").unwrap().get0::<()>()?;
store.interrupt_handle()?.interrupt();
let trap = iloop().unwrap_err();
assert!(trap.message().contains("wasm trap: interrupt"));
Ok(())
}
#[test]
fn functions_interruptable() -> anyhow::Result<()> {
let store = interruptable_store();
let module = hugely_recursive_module(&store)?;
let func = Func::wrap(&store, || {});
let instance = Instance::new(&module, &[func.into()])?;
let iloop = instance.get_func("loop").unwrap().get0::<()>()?;
store.interrupt_handle()?.interrupt();
let trap = iloop().unwrap_err();
assert!(
trap.message().contains("wasm trap: interrupt"),
"{}",
trap.message()
);
Ok(())
}
#[test]
fn loop_interrupt_from_afar() -> anyhow::Result<()> {
// Create an instance which calls an imported function on each iteration of
// the loop so we can count the number of loop iterations we've executed so
// far.
static HITS: AtomicUsize = AtomicUsize::new(0);
let store = interruptable_store();
let module = Module::new(
&store,
r#"
(import "" "" (func))
(func (export "loop")
(loop
call 0
br 0)
)
"#,
)?;
let func = Func::wrap(&store, || {
HITS.fetch_add(1, SeqCst);
});
let instance = Instance::new(&module, &[func.into()])?;
// Use the instance's interrupt handle to wait for it to enter the loop long
// enough and then we signal an interrupt happens.
let handle = store.interrupt_handle()?;
let thread = std::thread::spawn(move || {
while HITS.load(SeqCst) <= 100_000 {
// continue ...
}
handle.interrupt();
});
// Enter the infinitely looping function and assert that our interrupt
// handle does indeed actually interrupt the function.
let iloop = instance.get_func("loop").unwrap().get0::<()>()?;
let trap = iloop().unwrap_err();
thread.join().unwrap();
assert!(
trap.message().contains("wasm trap: interrupt"),
"bad message: {}",
trap.message()
);
Ok(())
}
#[test]
fn function_interrupt_from_afar() -> anyhow::Result<()> {
// Create an instance which calls an imported function on each iteration of
// the loop so we can count the number of loop iterations we've executed so
// far.
static HITS: AtomicUsize = AtomicUsize::new(0);
let store = interruptable_store();
let module = hugely_recursive_module(&store)?;
let func = Func::wrap(&store, || {
HITS.fetch_add(1, SeqCst);
});
let instance = Instance::new(&module, &[func.into()])?;
// Use the instance's interrupt handle to wait for it to enter the loop long
// enough and then we signal an interrupt happens.
let handle = store.interrupt_handle()?;
let thread = std::thread::spawn(move || {
while HITS.load(SeqCst) <= 100_000 {
// continue ...
}
handle.interrupt();
});
// Enter the infinitely looping function and assert that our interrupt
// handle does indeed actually interrupt the function.
let iloop = instance.get_func("loop").unwrap().get0::<()>()?;
let trap = iloop().unwrap_err();
thread.join().unwrap();
assert!(
trap.message().contains("wasm trap: interrupt"),
"bad message: {}",
trap.message()
);
Ok(())
}

View File

@@ -1,60 +0,0 @@
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
use wasmtime::*;
#[test]
fn host_always_has_some_stack() -> anyhow::Result<()> {
static HITS: AtomicUsize = AtomicUsize::new(0);
// assume hosts always have at least 512k of stack
const HOST_STACK: usize = 512 * 1024;
let store = Store::default();
// Create a module that's infinitely recursive, but calls the host on each
// level of wasm stack to always test how much host stack we have left.
let module = Module::new(
&store,
r#"
(module
(import "" "" (func $host))
(func $recursive (export "foo")
call $host
call $recursive)
)
"#,
)?;
let func = Func::wrap(&store, test_host_stack);
let instance = Instance::new(&module, &[func.into()])?;
let foo = instance.get_func("foo").unwrap().get0::<()>()?;
// Make sure that our function traps and the trap says that the call stack
// has been exhausted.
let trap = foo().unwrap_err();
assert!(
trap.message().contains("call stack exhausted"),
"{}",
trap.message()
);
// Additionally, however, and this is the crucial test, make sure that the
// host function actually completed. If HITS is 1 then we entered but didn't
// exit meaning we segfaulted while executing the host, yet still tried to
// recover from it with longjmp.
assert_eq!(HITS.load(SeqCst), 0);
return Ok(());
fn test_host_stack() {
HITS.fetch_add(1, SeqCst);
assert!(consume_some_stack(0, HOST_STACK) > 0);
HITS.fetch_sub(1, SeqCst);
}
#[inline(never)]
fn consume_some_stack(ptr: usize, stack: usize) -> usize {
if stack == 0 {
return ptr;
}
let mut space = [0u8; 1024];
consume_some_stack(space.as_mut_ptr() as usize, stack.saturating_sub(1024))
}
}