test_programs_artifacts/
lib.rs

1include!(concat!(env!("OUT_DIR"), "/gen.rs"));
2
3use std::borrow::Cow;
4use std::collections::HashMap;
5use std::io::IsTerminal;
6use std::sync::{Arc, Mutex};
7use wasmtime::{CacheStore, Config, Engine};
8
9/// The wasi-tests binaries use these environment variables to determine their
10/// expected behavior.
11/// Used by all of the tests/ which execute the wasi-tests binaries.
12pub fn wasi_tests_environment() -> &'static [(&'static str, &'static str)] {
13    #[cfg(windows)]
14    {
15        &[
16            ("ERRNO_MODE_WINDOWS", "1"),
17            // Windows does not support dangling links or symlinks in the filesystem.
18            ("NO_DANGLING_FILESYSTEM", "1"),
19            // Windows does not support renaming a directory to an empty directory -
20            // empty directory must be deleted.
21            ("NO_RENAME_DIR_TO_EMPTY_DIR", "1"),
22        ]
23    }
24    #[cfg(all(unix, not(target_os = "macos")))]
25    {
26        &[("ERRNO_MODE_UNIX", "1")]
27    }
28    #[cfg(target_os = "macos")]
29    {
30        &[("ERRNO_MODE_MACOS", "1")]
31    }
32}
33
34pub fn stdio_is_terminal() -> bool {
35    std::io::stdin().is_terminal()
36        && std::io::stdout().is_terminal()
37        && std::io::stderr().is_terminal()
38}
39
40// Simple incremental cache used during tests to help improve test runtime.
41//
42// Many tests take a similar module (e.g. a component, a preview1 thing, sync,
43// async, etc) and run it in different contexts and this improve cache hit rates
44// across usages by sharing one incremental cache across tests.
45fn cache_store() -> Arc<dyn CacheStore> {
46    #[derive(Debug)]
47    struct MyCache;
48
49    static CACHE: Mutex<Option<HashMap<Vec<u8>, Vec<u8>>>> = Mutex::new(None);
50
51    impl CacheStore for MyCache {
52        fn get(&self, key: &[u8]) -> Option<Cow<[u8]>> {
53            let mut cache = CACHE.lock().unwrap();
54            let cache = cache.get_or_insert_with(HashMap::new);
55            cache.get(key).map(|s| s.to_vec().into())
56        }
57
58        fn insert(&self, key: &[u8], value: Vec<u8>) -> bool {
59            let mut cache = CACHE.lock().unwrap();
60            let cache = cache.get_or_insert_with(HashMap::new);
61            cache.insert(key.to_vec(), value);
62            true
63        }
64    }
65
66    Arc::new(MyCache)
67}
68
69/// Helper to create an `Engine` with a pre-configured `Config` that uses a
70/// cache for faster building of modules.
71pub fn engine(configure: impl FnOnce(&mut Config)) -> Engine {
72    let mut config = Config::new();
73    config.wasm_component_model(true);
74    config
75        .enable_incremental_compilation(cache_store())
76        .unwrap();
77    configure(&mut config);
78    Engine::new(&config).unwrap()
79}