Skip to content

Commit

Permalink
Copy some of the rust WASI tests from wasmtime
Browse files Browse the repository at this point in the history
  • Loading branch information
loganek committed Jan 20, 2023
1 parent fcd20fa commit ac32f57
Show file tree
Hide file tree
Showing 16 changed files with 1,070 additions and 0 deletions.
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"
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) }
}
53 changes: 53 additions & 0 deletions tests/rust/src/bin/dangling_fd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
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() {
// 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", wasi::OFLAGS_CREAT, 0, 0, 0).unwrap();
wasi::fd_close(fd).unwrap();
let file_fd = wasi::path_open(dir_fd, 0, "file", 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").expect("failed to unlink");
let fd = wasi::path_open(dir_fd, 0, "file", 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, "subdir").expect("failed to create dir");
let subdir_fd = wasi::path_open(dir_fd, 0, "subdir", 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, "subdir").expect("failed to remove dir 2");
wasi::path_create_directory(dir_fd, "subdir").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) }
}
52 changes: 52 additions & 0 deletions tests/rust/src/bin/dangling_symlink.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
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() {
// First create a dangling symlink.
wasi::path_symlink("target", dir_fd, "symlink").expect("creating a symlink");

// Try to open it as a directory with O_NOFOLLOW.
assert_errno!(
wasi::path_open(dir_fd, 0, "symlink", 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", 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").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) }
}
71 changes: 71 additions & 0 deletions tests/rust/src/bin/directory_seek.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_directory_seek(dir_fd: wasi::Fd) {
// Create a directory in the scratch directory.
wasi::path_create_directory(dir_fd, "dir").expect("failed to make directory");

// Open the directory and attempt to request rights for seeking.
let fd = wasi::path_open(
dir_fd,
0,
"dir",
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_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").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

0 comments on commit ac32f57

Please sign in to comment.