1 include!(concat!(env!("OUT_DIR"), "/gen.rs")); 2 3 use std::borrow::Cow; 4 use std::collections::HashMap; 5 use std::io::IsTerminal; 6 use std::sync::{Arc, Mutex}; 7 use 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. 12 pub 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 ("RENAME_DIR_ONTO_FILE", "1"), 23 ] 24 } 25 #[cfg(all(unix, not(target_os = "macos")))] 26 { 27 &[("ERRNO_MODE_UNIX", "1")] 28 } 29 #[cfg(target_os = "macos")] 30 { 31 &[("ERRNO_MODE_MACOS", "1")] 32 } 33 } 34 35 pub fn stdio_is_terminal() -> bool { 36 std::io::stdin().is_terminal() 37 && std::io::stdout().is_terminal() 38 && std::io::stderr().is_terminal() 39 } 40 41 // Simple incremental cache used during tests to help improve test runtime. 42 // 43 // Many tests take a similar module (e.g. a component, a preview1 thing, sync, 44 // async, etc) and run it in different contexts and this improve cache hit rates 45 // across usages by sharing one incremental cache across tests. 46 fn cache_store() -> Arc<dyn CacheStore> { 47 #[derive(Debug)] 48 struct MyCache; 49 50 static CACHE: Mutex<Option<HashMap<Vec<u8>, Vec<u8>>>> = Mutex::new(None); 51 52 impl CacheStore for MyCache { 53 fn get(&self, key: &[u8]) -> Option<Cow<'_, [u8]>> { 54 let mut cache = CACHE.lock().unwrap(); 55 let cache = cache.get_or_insert_with(HashMap::new); 56 cache.get(key).map(|s| s.to_vec().into()) 57 } 58 59 fn insert(&self, key: &[u8], value: Vec<u8>) -> bool { 60 let mut cache = CACHE.lock().unwrap(); 61 let cache = cache.get_or_insert_with(HashMap::new); 62 cache.insert(key.to_vec(), value); 63 true 64 } 65 } 66 67 Arc::new(MyCache) 68 } 69 70 /// Helper to create an `Engine` with a pre-configured `Config` that uses a 71 /// cache for faster building of modules. 72 pub fn engine(configure: impl FnOnce(&mut Config)) -> Engine { 73 let mut config = Config::new(); 74 config.wasm_component_model(true); 75 config 76 .enable_incremental_compilation(cache_store()) 77 .unwrap(); 78 configure(&mut config); 79 Engine::new(&config).unwrap() 80 } 81