diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 8cc2f06f2e4..03f404c62cc 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -27,9 +27,9 @@ env: MSRV: "1.74" NEXTEST_PROFILE: "ci" RUSTUP_WINDOWS_PATH_ADD_BIN: 1 + WASI_SDK_VERSION: "22" jobs: - setup: name: Set up runs-on: ubuntu-22.04 @@ -144,6 +144,40 @@ jobs: # run: | # make test-js-core + test_wasix: + name: Test WASIX + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + toolchain: ${{ env.MSRV }} + - name: Install Tools + run: | + sudo apt-get update + sudo apt-get install -y git llvm clang make lld curl + - name: Build wasix sysroot + run: | + cd ~ + git clone --recurse-submodules https://github.com/wasix-org/wasix-libc + cd wasix-libc + ./build32.sh + rm -rf /opt/wasix-sysroot + cp -r sysroot32 ~/wasix-sysroot + - name: Install wasi-sdk Tools + run: | + cd ~ + curl -L "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${{ env.WASI_SDK_VERSION }}/wasi-sdk-${{ env.WASI_SDK_VERSION }}.0-linux.tar.gz" -o wasi-sdk.tar.gz + tar -xzf wasi-sdk.tar.gz + cp -r wasi-sdk-${{ env.WASI_SDK_VERSION }}.0 ~/wasi-sdk + - name: Install wasm-opt + run: | + sudo apt-get install -y binaryen + - name: make test-wasix + run: | + WASI_SDK=~/wasi-sdk WASIX_SYSROOT=~/wasix-sysroot make test-wasix + test_wasm_build: name: Test wasm build runs-on: ubuntu-22.04 diff --git a/Makefile b/Makefile index 726632d0e05..9b705e2bab1 100644 --- a/Makefile +++ b/Makefile @@ -632,6 +632,10 @@ test-wasi-fyi: build-wasmer cd tests/wasi-fyi; \ ./test.sh +test-wasix: build-wasmer + cd tests/wasix; \ + ./test.sh + test-integration-cli: build-wasmer build-capi package-capi-headless package distribution cp ./dist/wasmer.tar.gz ./link.tar.gz rustup target add wasm32-wasi diff --git a/lib/cli/src/commands/run/mod.rs b/lib/cli/src/commands/run/mod.rs index eac19537da7..dc4bf97b8bb 100644 --- a/lib/cli/src/commands/run/mod.rs +++ b/lib/cli/src/commands/run/mod.rs @@ -395,12 +395,15 @@ impl Run { let mut runner = WasiRunner::new(); + let (is_home_mapped, mapped_diretories) = self.wasi.build_mapped_directories()?; + runner .with_args(&self.args) .with_injected_packages(packages) .with_envs(self.wasi.env_vars.clone()) .with_mapped_host_commands(self.wasi.build_mapped_commands()?) - .with_mapped_directories(self.wasi.build_mapped_directories()?) + .with_mapped_directories(mapped_diretories) + .with_home_mapped(is_home_mapped) .with_forward_host_env(self.wasi.forward_host_env) .with_capabilities(self.wasi.capabilities()); diff --git a/lib/cli/src/commands/run/wasi.rs b/lib/cli/src/commands/run/wasi.rs index f452f46777d..9e9d135dc01 100644 --- a/lib/cli/src/commands/run/wasi.rs +++ b/lib/cli/src/commands/run/wasi.rs @@ -26,6 +26,7 @@ use wasmer_wasix::{ journal::{CompactingLogFileJournal, DynJournal}, os::{tty_sys::SysTty, TtyBridge}, rewind_ext, + runners::MAPPED_CURRENT_DIR_DEFAULT_PATH, runners::{MappedCommand, MappedDirectory}, runtime::{ module_cache::{FileSystemCache, ModuleCache}, @@ -180,8 +181,6 @@ pub struct RunProperties { #[allow(dead_code)] impl Wasi { - const MAPPED_CURRENT_DIR_DEFAULT_PATH: &'static str = "/mnt/host"; - pub fn map_dir(&mut self, alias: &str, target_on_disk: PathBuf) { self.mapped_dirs.push(MappedDirectory { guest: alias.to_string(), @@ -269,7 +268,7 @@ impl Wasi { MappedDirectory { host: current_dir, - guest: Self::MAPPED_CURRENT_DIR_DEFAULT_PATH.to_string(), + guest: MAPPED_CURRENT_DIR_DEFAULT_PATH.to_string(), } } else { let resolved = dir.canonicalize().with_context(|| { @@ -322,7 +321,7 @@ impl Wasi { MappedDirectory { host: resolved_host, - guest: Self::MAPPED_CURRENT_DIR_DEFAULT_PATH.to_string(), + guest: MAPPED_CURRENT_DIR_DEFAULT_PATH.to_string(), } } else { MappedDirectory { @@ -353,7 +352,7 @@ impl Wasi { .unwrap(); if have_current_dir { - b.map_dir(".", Self::MAPPED_CURRENT_DIR_DEFAULT_PATH)? + b.map_dir(".", MAPPED_CURRENT_DIR_DEFAULT_PATH)? } else { b.map_dir(".", "/")? } @@ -402,7 +401,7 @@ impl Wasi { Ok(Vec::new()) } - pub fn build_mapped_directories(&self) -> Result, anyhow::Error> { + pub fn build_mapped_directories(&self) -> Result<(bool, Vec), anyhow::Error> { let mut mapped_dirs = Vec::new(); // Process the --dirs flag and merge it with --mapdir. @@ -419,7 +418,7 @@ impl Wasi { MappedDirectory { host: current_dir, - guest: Self::MAPPED_CURRENT_DIR_DEFAULT_PATH.to_string(), + guest: MAPPED_CURRENT_DIR_DEFAULT_PATH.to_string(), } } else { let resolved = dir.canonicalize().with_context(|| { @@ -472,7 +471,7 @@ impl Wasi { MappedDirectory { host: resolved_host, - guest: Self::MAPPED_CURRENT_DIR_DEFAULT_PATH.to_string(), + guest: MAPPED_CURRENT_DIR_DEFAULT_PATH.to_string(), } } else { MappedDirectory { @@ -483,7 +482,7 @@ impl Wasi { mapped_dirs.push(mapping); } - Ok(mapped_dirs) + Ok((have_current_dir, mapped_dirs)) } pub fn build_mapped_commands(&self) -> Result, anyhow::Error> { diff --git a/lib/wasix/src/runners/mod.rs b/lib/wasix/src/runners/mod.rs index a2bf9eb4128..949ac65b397 100644 --- a/lib/wasix/src/runners/mod.rs +++ b/lib/wasix/src/runners/mod.rs @@ -13,5 +13,7 @@ pub mod wcgi; pub use self::{ runner::Runner, - wasi_common::{MappedCommand, MappedDirectory, MountedDirectory}, + wasi_common::{ + MappedCommand, MappedDirectory, MountedDirectory, MAPPED_CURRENT_DIR_DEFAULT_PATH, + }, }; diff --git a/lib/wasix/src/runners/wasi.rs b/lib/wasix/src/runners/wasi.rs index 42c65826886..11905849df5 100644 --- a/lib/wasix/src/runners/wasi.rs +++ b/lib/wasix/src/runners/wasi.rs @@ -18,7 +18,7 @@ use crate::{ }; use wasmer_types::ModuleHash; -use super::wasi_common::MappedCommand; +use super::wasi_common::{MappedCommand, MAPPED_CURRENT_DIR_DEFAULT_PATH}; #[derive(Debug, Default, Clone)] pub struct WasiRunner { @@ -80,6 +80,11 @@ impl WasiRunner { self.with_mounted_directories(dirs.into_iter().map(Into::into).map(MountedDirectory::from)) } + pub fn with_home_mapped(&mut self, is_home_mapped: bool) -> &mut Self { + self.wasi.is_home_mapped = is_home_mapped; + self + } + pub fn with_mounted_directories(&mut self, dirs: I) -> &mut Self where I: IntoIterator, @@ -250,6 +255,10 @@ impl WasiRunner { builder.set_stderr(Box::new(stderr.clone())); } + if self.wasi.is_home_mapped { + builder.set_current_dir(MAPPED_CURRENT_DIR_DEFAULT_PATH); + } + Ok(builder) } diff --git a/lib/wasix/src/runners/wasi_common.rs b/lib/wasix/src/runners/wasi_common.rs index 1a48482c1fc..87956d2c7e8 100644 --- a/lib/wasix/src/runners/wasi_common.rs +++ b/lib/wasix/src/runners/wasi_common.rs @@ -18,6 +18,8 @@ use crate::{ WasiEnvBuilder, }; +pub const MAPPED_CURRENT_DIR_DEFAULT_PATH: &str = "/home"; + #[derive(Debug, Clone)] pub struct MappedCommand { /// The new alias. @@ -34,6 +36,7 @@ pub(crate) struct CommonWasiOptions { pub(crate) forward_host_env: bool, pub(crate) mapped_host_commands: Vec, pub(crate) mounts: Vec, + pub(crate) is_home_mapped: bool, pub(crate) injected_packages: Vec, pub(crate) capabilities: Capabilities, #[derivative(Debug = "ignore")] diff --git a/tests/wasix/.gitignore b/tests/wasix/.gitignore new file mode 100644 index 00000000000..61b5cdac584 --- /dev/null +++ b/tests/wasix/.gitignore @@ -0,0 +1,3 @@ +output* +*.webc +*.wasm \ No newline at end of file diff --git a/tests/wasix/cwd-to-home/expected b/tests/wasix/cwd-to-home/expected new file mode 100644 index 00000000000..c227083464f --- /dev/null +++ b/tests/wasix/cwd-to-home/expected @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/tests/wasix/cwd-to-home/hello.txt b/tests/wasix/cwd-to-home/hello.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/wasix/cwd-to-home/main.c b/tests/wasix/cwd-to-home/main.c new file mode 100644 index 00000000000..7009ef98a97 --- /dev/null +++ b/tests/wasix/cwd-to-home/main.c @@ -0,0 +1,10 @@ +#include +#include + +int main() +{ + int fd = open("hello.txt", O_RDWR); + printf("%d", (fd == -1)); + + return 0; +} \ No newline at end of file diff --git a/tests/wasix/cwd-to-home/run.sh b/tests/wasix/cwd-to-home/run.sh new file mode 100755 index 00000000000..474bd170e0d --- /dev/null +++ b/tests/wasix/cwd-to-home/run.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +$WASMER -q run main.wasm --dir=. > output + +diff -u output expected 1>/dev/null \ No newline at end of file diff --git a/tests/wasix/test.sh b/tests/wasix/test.sh new file mode 100755 index 00000000000..f3349e46c4a --- /dev/null +++ b/tests/wasix/test.sh @@ -0,0 +1,90 @@ +#!/bin/bash + +if [[ -z "${WASI_SDK}" ]]; then + echo "WASI_SDK is not found" + exit 1 +fi + +if [[ -z "${WASIX_SYSROOT}" ]]; then + echo "WASIX_SYSROOT is not found" + exit 1 +fi + +export RANLIB="$WASI_SDK/bin/ranlib" +export AR="$WASI_SDK/bin/ar" +export NM="$WASI_SDK/bin/nm" +export CC="$WASI_SDK/bin/clang" +export CXX="$WASI_SDK/bin/clang" +export CFLAGS="\ +--sysroot=$WASIX_SYSROOT \ +-matomics \ +-mbulk-memory \ +-mmutable-globals \ +-pthread \ +-mthread-model posix \ +-ftls-model=local-exec \ +-fno-trapping-math \ +-D_WASI_EMULATED_MMAN \ +-D_WASI_EMULATED_SIGNAL \ +-D_WASI_EMULATED_PROCESS_CLOCKS \ +-O3 \ +-g \ +-flto" +export LD="$WASI_SDK/bin/wasm-ld" +export LDFLAGS="\ +-Wl,--shared-memory \ +-Wl,--max-memory=4294967296 \ +-Wl,--import-memory \ +-Wl,--export-dynamic \ +-Wl,--export=__heap_base \ +-Wl,--export=__stack_pointer \ +-Wl,--export=__data_end \ +-Wl,--export=__wasm_init_tls \ +-Wl,--export=__wasm_signal \ +-Wl,--export=__tls_size \ +-Wl,--export=__tls_align \ +-Wl,--export=__tls_base \ +-lwasi-emulated-mman \ +-O3 \ +-g \ +-flto" +export LIBS="\ +-Wl,--shared-memory \ +-Wl,--max-memory=4294967296 \ +-Wl,--import-memory \ +-Wl,--export-dynamic \ +-Wl,--export=__heap_base \ +-Wl,--export=__stack_pointer \ +-Wl,--export=__data_end \ +-Wl,--export=__wasm_init_tls \ +-Wl,--export=__wasm_signal \ +-Wl,--export=__tls_size \ +-Wl,--export=__tls_align \ +-Wl,--export=__tls_base \ +-lwasi-emulated-mman \ +-O3 \ +-g \ +-flto" + +export WASMER=$(realpath "../../target/release/wasmer") + +printf "\n\nStarting WASIX Test Suite:\n" + +status=0 +while read dir; do + dir=$(basename "$dir") + printf "Testing $dir..." + + cmd="cd $dir; \ + $CC $CFLAGS $LDFLAGS -o main.wasm main.c; \ + ./run.sh" + + if bash -c "$cmd"; then + printf "\rTesting $dir ✅\n" + else + printf "\rTesting $dir ❌\n" + status=1 + fi +done < <(find . -mindepth 1 -maxdepth 1 -type d) + +exit $status \ No newline at end of file