Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copy some of the WASI Rust tests from wasmtime #32

Merged
merged 7 commits into from
Jan 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion adapters/wasmtime.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ while [[ $# -gt 0 ]]; do
esac
done

wasmtime $TEST_FILE "${PROG_ARGS[@]}" "${ARGS[@]}"
wasmtime $TEST_FILE "${ARGS[@]}" "${PROG_ARGS[@]}"
1 change: 1 addition & 0 deletions tests/c/build.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/bin/bash
set -ueo pipefail

CC=${CC:=clang}

Expand Down
1 change: 1 addition & 0 deletions tests/rust/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target/
30 changes: 30 additions & 0 deletions tests/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions tests/rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "wasi_tests"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
libc = "0.2.65"
wasi = "0.10.2"
once_cell = "1.12"
6 changes: 6 additions & 0 deletions tests/rust/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash
set -ueo pipefail

cargo build --target=wasm32-wasi

cp target/wasm32-wasi/debug/*.wasm testsuite/
15 changes: 15 additions & 0 deletions tests/rust/src/bin/big_random_buf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
fn test_big_random_buf() {
let mut buf = Vec::new();
buf.resize(1024, 0);
unsafe {
wasi::random_get(buf.as_mut_ptr(), 1024).expect("failed to call random_get");
}
// Chances are pretty good that at least *one* byte will be non-zero in
// any meaningful random function producing 1024 u8 values.
assert!(buf.iter().any(|x| *x != 0), "random_get returned all zeros");
}

fn main() {
// Run the tests.
test_big_random_buf()
}
17 changes: 17 additions & 0 deletions tests/rust/src/bin/clock_time_get.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
unsafe fn test_clock_time_get() {
// Test that clock_time_get succeeds. Even in environments where it's not
// desirable to expose high-precision timers, it should still succeed.
// clock_res_get is where information about precision can be provided.
wasi::clock_time_get(wasi::CLOCKID_MONOTONIC, 1).expect("precision 1 should work");

let first_time =
wasi::clock_time_get(wasi::CLOCKID_MONOTONIC, 0).expect("precision 0 should work");

let time = wasi::clock_time_get(wasi::CLOCKID_MONOTONIC, 0).expect("re-fetch time should work");
assert!(first_time <= time, "CLOCK_MONOTONIC should be monotonic");
}

fn main() {
// Run the tests.
unsafe { test_clock_time_get() }
}
71 changes: 71 additions & 0 deletions tests/rust/src/bin/close_preopen.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use std::{env, process};
use wasi_tests::{assert_errno, open_scratch_directory};

unsafe fn test_close_preopen(dir_fd: wasi::Fd) {
let pre_fd: wasi::Fd = (libc::STDERR_FILENO + 1) as wasi::Fd;

assert!(dir_fd > pre_fd, "dir_fd number");

// Try to close a preopened directory handle.
assert_errno!(
wasi::fd_close(pre_fd)
.expect_err("closing a preopened file descriptor")
.raw_error(),
wasi::ERRNO_NOTSUP
);

// Try to renumber over a preopened directory handle.
assert_errno!(
wasi::fd_renumber(dir_fd, pre_fd)
.expect_err("renumbering over a preopened file descriptor")
.raw_error(),
wasi::ERRNO_NOTSUP
);

// Ensure that dir_fd is still open.
let dir_fdstat = wasi::fd_fdstat_get(dir_fd).expect("failed fd_fdstat_get");
assert_eq!(
dir_fdstat.fs_filetype,
wasi::FILETYPE_DIRECTORY,
"expected the scratch directory to be a directory",
);

// Try to renumber a preopened directory handle.
assert_errno!(
wasi::fd_renumber(pre_fd, dir_fd)
.expect_err("renumbering over a preopened file descriptor")
.raw_error(),
wasi::ERRNO_NOTSUP
);

// Ensure that dir_fd is still open.
let dir_fdstat = wasi::fd_fdstat_get(dir_fd).expect("failed fd_fdstat_get");
assert_eq!(
dir_fdstat.fs_filetype,
wasi::FILETYPE_DIRECTORY,
"expected the scratch directory to be a directory",
);
}

fn main() {
let mut args = env::args();
let prog = args.next().unwrap();
let arg = if let Some(arg) = args.next() {
arg
} else {
eprintln!("usage: {} <scratch directory>", prog);
process::exit(1);
};

// Open scratch directory
let dir_fd = match open_scratch_directory(&arg) {
Ok(dir_fd) => dir_fd,
Err(err) => {
eprintln!("{}", err);
process::exit(1)
}
};

// Run the tests.
unsafe { test_close_preopen(dir_fd) }
}
57 changes: 57 additions & 0 deletions tests/rust/src/bin/dangling_fd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use std::{env, process};
use wasi_tests::{open_scratch_directory, TESTCONFIG};

unsafe fn test_dangling_fd(dir_fd: wasi::Fd) {
if TESTCONFIG.support_dangling_filesystem() {
const FILE_NAME: &str = "dangling_fd_file.cleanup";
const DIR_NAME: &str = "dangling_fd_subdir.cleanup";
// Create a file, open it, delete it without closing the handle,
// and then try creating it again
let fd = wasi::path_open(dir_fd, 0, FILE_NAME, wasi::OFLAGS_CREAT, 0, 0, 0).unwrap();
wasi::fd_close(fd).unwrap();
let file_fd =
wasi::path_open(dir_fd, 0, FILE_NAME, 0, 0, 0, 0).expect("failed to open");
assert!(
file_fd > libc::STDERR_FILENO as wasi::Fd,
"file descriptor range check",
);
wasi::path_unlink_file(dir_fd, FILE_NAME).expect("failed to unlink");
let fd = wasi::path_open(dir_fd, 0, FILE_NAME, wasi::OFLAGS_CREAT, 0, 0, 0).unwrap();
wasi::fd_close(fd).unwrap();

// Now, repeat the same process but for a directory
wasi::path_create_directory(dir_fd, DIR_NAME).expect("failed to create dir");
let subdir_fd =
wasi::path_open(dir_fd, 0, DIR_NAME, wasi::OFLAGS_DIRECTORY, 0, 0, 0)
.expect("failed to open dir");
assert!(
subdir_fd > libc::STDERR_FILENO as wasi::Fd,
"file descriptor range check",
);
wasi::path_remove_directory(dir_fd, DIR_NAME).expect("failed to remove dir 2");
wasi::path_create_directory(dir_fd, DIR_NAME).expect("failed to create dir 2");
}
}

fn main() {
let mut args = env::args();
let prog = args.next().unwrap();
let arg = if let Some(arg) = args.next() {
arg
} else {
eprintln!("usage: {} <scratch directory>", prog);
process::exit(1);
};

// Open scratch directory
let dir_fd = match open_scratch_directory(&arg) {
Ok(dir_fd) => dir_fd,
Err(err) => {
eprintln!("{}", err);
process::exit(1)
}
};

// Run the tests.
unsafe { test_dangling_fd(dir_fd) }
}
53 changes: 53 additions & 0 deletions tests/rust/src/bin/dangling_symlink.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use std::{env, process};
use wasi_tests::{assert_errno, open_scratch_directory, TESTCONFIG};

unsafe fn test_dangling_symlink(dir_fd: wasi::Fd) {
if TESTCONFIG.support_dangling_filesystem() {
const SYMLINK_NAME: &str = "dangling_symlink_symlink.cleanup";
// First create a dangling symlink.
wasi::path_symlink("target", dir_fd, SYMLINK_NAME).expect("creating a symlink");

// Try to open it as a directory with O_NOFOLLOW.
assert_errno!(
wasi::path_open(dir_fd, 0, SYMLINK_NAME, wasi::OFLAGS_DIRECTORY, 0, 0, 0)
.expect_err("opening a dangling symlink as a directory")
.raw_error(),
wasi::ERRNO_NOTDIR,
wasi::ERRNO_LOOP
);

// Try to open it as a file with O_NOFOLLOW.
assert_errno!(
wasi::path_open(dir_fd, 0, SYMLINK_NAME, 0, 0, 0, 0)
.expect_err("opening a dangling symlink as a file")
.raw_error(),
wasi::ERRNO_LOOP
);

// Clean up.
wasi::path_unlink_file(dir_fd, SYMLINK_NAME).expect("failed to remove file");
}
}

fn main() {
let mut args = env::args();
let prog = args.next().unwrap();
let arg = if let Some(arg) = args.next() {
arg
} else {
eprintln!("usage: {} <scratch directory>", prog);
process::exit(1);
};

// Open scratch directory
let dir_fd = match open_scratch_directory(&arg) {
Ok(dir_fd) => dir_fd,
Err(err) => {
eprintln!("{}", err);
process::exit(1)
}
};

// Run the tests.
unsafe { test_dangling_symlink(dir_fd) }
}
74 changes: 74 additions & 0 deletions tests/rust/src/bin/directory_seek.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use std::{env, process};
use wasi_tests::{assert_errno, open_scratch_directory};

unsafe fn test_directory_seek(dir_fd: wasi::Fd) {
const DIR_NAME: &str = "directory_seek_dir.cleanup";
// Create a directory in the scratch directory.
wasi::path_create_directory(dir_fd, DIR_NAME).expect("failed to make directory");

// Open the directory and attempt to request rights for seeking.
let fd = wasi::path_open(
dir_fd,
0,
DIR_NAME,
wasi::OFLAGS_DIRECTORY,
wasi::RIGHTS_FD_SEEK,
0,
0,
)
.expect("failed to open file");
assert!(
fd > libc::STDERR_FILENO as wasi::Fd,
"file descriptor range check",
);

// Attempt to seek.
assert_errno!(
wasi::fd_seek(fd, 0, wasi::WHENCE_CUR)
.expect_err("seek on a directory")
.raw_error(),
wasi::ERRNO_ISDIR,
wasi::ERRNO_NOTCAPABLE,
wasi::ERRNO_BADF
);

// Check if we obtained the right to seek.
let fdstat = wasi::fd_fdstat_get(fd).expect("failed to fdstat");
assert_eq!(
fdstat.fs_filetype,
wasi::FILETYPE_DIRECTORY,
"expected the scratch directory to be a directory",
);
assert_eq!(
(fdstat.fs_rights_base & wasi::RIGHTS_FD_SEEK),
0,
"directory does NOT have the seek right",
);

// Clean up.
wasi::fd_close(fd).expect("failed to close fd");
wasi::path_remove_directory(dir_fd, DIR_NAME).expect("failed to remove dir");
}

fn main() {
let mut args = env::args();
let prog = args.next().unwrap();
let arg = if let Some(arg) = args.next() {
arg
} else {
eprintln!("usage: {} <scratch directory>", prog);
process::exit(1);
};

// Open scratch directory
let dir_fd = match open_scratch_directory(&arg) {
Ok(dir_fd) => dir_fd,
Err(err) => {
eprintln!("{}", err);
process::exit(1)
}
};

// Run the tests.
unsafe { test_directory_seek(dir_fd) }
}
Loading