Merge pull request #192 from arihant2math/usertest-updates

This commit is contained in:
Ashwin Naren
2026-02-09 13:59:18 -08:00
committed by GitHub
6 changed files with 91 additions and 55 deletions

10
Cargo.lock generated
View File

@@ -58,6 +58,15 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "colored"
version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34"
dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "crc"
version = "3.4.0"
@@ -581,6 +590,7 @@ checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
name = "usertest"
version = "0.1.0"
dependencies = [
"colored",
"inventory",
"libc",
"parking_lot",

View File

@@ -4,6 +4,7 @@ version = "0.1.0"
edition = "2024"
[dependencies]
colored = "3"
inventory = "0.3"
libc = "0.2"
parking_lot = "0.12"

View File

@@ -14,7 +14,7 @@ fn test_opendir() {
}
}
register_test!(test_opendir, "Testing opendir syscall");
register_test!(test_opendir);
fn test_readdir() {
let path = CString::new("/").unwrap();
@@ -38,7 +38,7 @@ fn test_readdir() {
}
}
register_test!(test_readdir, "Testing readdir syscall");
register_test!(test_readdir);
fn test_chdir() {
let path = CString::new("/dev").unwrap();
@@ -61,7 +61,7 @@ fn test_chdir() {
}
}
register_test!(test_chdir, "Testing chdir syscall");
register_test!(test_chdir);
fn test_fchdir() {
let path = CString::new("/dev").unwrap();
@@ -89,7 +89,7 @@ fn test_fchdir() {
}
}
register_test!(test_fchdir, "Testing fchdir syscall");
register_test!(test_fchdir);
fn test_chroot() {
let file = "/bin/busybox";
@@ -107,7 +107,7 @@ fn test_chroot() {
}
}
register_test!(test_chroot, "Testing chroot syscall");
register_test!(test_chroot);
fn test_chmod() {
let dir_path = "/tmp/chmod_test";
@@ -131,7 +131,7 @@ fn test_chmod() {
fs::remove_dir(dir_path).expect("Failed to delete directory");
}
register_test!(test_chmod, "Testing chmod syscall");
register_test!(test_chmod);
fn test_fchmod() {
let dir_path = "/tmp/fchmod_test";
@@ -160,7 +160,7 @@ fn test_fchmod() {
fs::remove_dir(dir_path).expect("Failed to delete directory");
}
register_test!(test_fchmod, "Testing fchmod syscall");
register_test!(test_fchmod);
fn test_chown() {
let dir_path = "/tmp/chown_test";
@@ -184,7 +184,7 @@ fn test_chown() {
fs::remove_dir(dir_path).expect("Failed to delete directory");
}
register_test!(test_chown, "Testing chown syscall");
register_test!(test_chown);
fn test_fchown() {
let dir_path = "/tmp/fchown_test";
@@ -213,7 +213,7 @@ fn test_fchown() {
fs::remove_dir(dir_path).expect("Failed to delete directory");
}
register_test!(test_fchown, "Testing fchown syscall");
register_test!(test_fchown);
fn test_read() {
let file = "/dev/zero";
@@ -233,7 +233,7 @@ fn test_read() {
}
}
register_test!(test_read, "Testing read syscall");
register_test!(test_read);
fn test_write() {
let file = "/dev/null";
@@ -252,7 +252,7 @@ fn test_write() {
}
}
register_test!(test_write, "Testing write syscall");
register_test!(test_write);
fn test_link() {
let path = "/tmp/link_test";
@@ -289,7 +289,7 @@ fn test_link() {
fs::remove_file(link).expect("Failed to delete link");
}
register_test!(test_link, "Testing link syscall");
register_test!(test_link);
fn test_symlink() {
use std::fs::{self, File};
@@ -330,7 +330,7 @@ fn test_symlink() {
fs::remove_file(link).expect("Failed to delete link");
}
register_test!(test_symlink, "Testing symlink syscall");
register_test!(test_symlink);
fn test_rename() {
use std::fs::{self, File};
@@ -366,7 +366,7 @@ fn test_rename() {
fs::remove_file(new_path).expect("Failed to delete file");
}
register_test!(test_rename, "Testing rename syscall");
register_test!(test_rename);
fn test_truncate() {
use std::fs::{self, File};
@@ -392,7 +392,7 @@ fn test_truncate() {
fs::remove_file(path).expect("Failed to delete file");
}
register_test!(test_truncate, "Testing truncate syscall");
register_test!(test_truncate);
fn test_ftruncate() {
let file = "/tmp/ftruncate_test.txt";
@@ -423,7 +423,7 @@ fn test_ftruncate() {
fs::remove_file(file).expect("Failed to delete file");
}
register_test!(test_ftruncate, "Testing ftruncate syscall");
register_test!(test_ftruncate);
fn test_utimens() {
let file = "/tmp/utimens_test";
@@ -481,7 +481,7 @@ fn test_utimens() {
fs::remove_file(file).expect("Failed to delete file");
}
register_test!(test_utimens, "Testing utimens syscall");
register_test!(test_utimens);
fn test_statx() {
#[repr(C)]
@@ -568,7 +568,7 @@ fn test_statx() {
fs::remove_file(file).expect("Failed to delete file");
}
register_test!(test_statx, "Testing statx syscall");
register_test!(test_statx);
fn test_rust_file() {
use std::fs::{self, File};
@@ -587,10 +587,19 @@ fn test_rust_file() {
.expect("Failed to read from file");
assert_eq!(contents, "Hello, Rust!");
}
fs::hard_link(path, "/tmp/rust_fs_test_link.txt").expect("Failed to create hard link");
let metadata = fs::metadata(path).expect("Failed to get metadata");
assert_eq!(metadata.len(), 12);
fs::rename(
"/tmp/rust_fs_test_link.txt",
"/tmp/rust_fs_test_renamed.txt",
)
.expect("Failed to rename file");
fs::remove_file("/tmp/rust_fs_test_renamed.txt").expect("Failed to delete renamed file");
fs::remove_file(path).expect("Failed to delete file");
}
register_test!(test_rust_file, "Testing rust file operations");
register_test!(test_rust_file);
fn test_rust_dir() {
use std::fs;
@@ -602,4 +611,4 @@ fn test_rust_dir() {
fs::remove_dir(dir_path).expect("Failed to delete directory");
}
register_test!(test_rust_dir, "Testing rust directory operations");
register_test!(test_rust_dir);

View File

@@ -42,7 +42,7 @@ fn test_futex() {
}
}
register_test!(test_futex, "Testing futex");
register_test!(test_futex);
fn test_futex_bitset() {
// Wait on bit 1, Wake on bit 1
@@ -214,4 +214,4 @@ fn test_futex_bitset() {
}
}
register_test!(test_futex_bitset, "Testing futex bitset");
register_test!(test_futex_bitset);

View File

@@ -1,3 +1,4 @@
use colored::Colorize;
use std::{
io::{Write, stdout},
sync::{Arc, Barrier, Mutex},
@@ -20,8 +21,8 @@ macro_rules! register_test {
($name:ident) => {
// Add to inventory
inventory::submit! {
crate::Test {
test_text: stringify!($name),
$crate::Test {
test_text: concat!(module_path!(), "::", stringify!($name)),
test_fn: $name,
}
}
@@ -29,7 +30,7 @@ macro_rules! register_test {
($name:ident, $text:expr) => {
// Add to inventory
inventory::submit! {
crate::Test {
$crate::Test {
test_text: $text,
test_fn: $name,
}
@@ -43,7 +44,7 @@ fn test_sync() {
}
}
register_test!(test_sync, "Testing sync syscall");
register_test!(test_sync);
fn test_clock_sleep() {
use std::thread::sleep;
@@ -56,7 +57,7 @@ fn test_clock_sleep() {
assert!(now.elapsed() >= SLEEP_LEN);
}
register_test!(test_clock_sleep, "Testing clock sleep");
register_test!(test_clock_sleep);
fn test_fork() {
unsafe {
@@ -74,7 +75,7 @@ fn test_fork() {
}
}
register_test!(test_fork, "Testing fork syscall");
register_test!(test_fork);
fn test_rust_thread() {
let handle = thread::spawn(|| 24);
@@ -82,7 +83,7 @@ fn test_rust_thread() {
assert_eq!(handle.join().unwrap(), 24);
}
register_test!(test_rust_thread, "Testing rust threads");
register_test!(test_rust_thread);
fn test_rust_mutex() {
const THREADS: usize = 32;
@@ -116,7 +117,7 @@ fn test_rust_mutex() {
assert_eq!(final_val, THREADS * ITERS);
}
register_test!(test_rust_mutex, "Testing rust mutex");
register_test!(test_rust_mutex);
fn test_parking_lot_mutex_timeout() {
use parking_lot::Mutex;
@@ -134,10 +135,7 @@ fn test_parking_lot_mutex_timeout() {
drop(guard);
}
register_test!(
test_parking_lot_mutex_timeout,
"Testing parking_lot mutex with timeout"
);
register_test!(test_parking_lot_mutex_timeout);
fn test_thread_with_name() {
let handle = thread::Builder::new()
@@ -150,7 +148,7 @@ fn test_thread_with_name() {
handle.join().unwrap();
}
register_test!(test_thread_with_name, "Testing thread with name");
register_test!(test_thread_with_name);
fn test_mincore() {
use std::ptr;
@@ -194,9 +192,9 @@ fn test_mincore() {
}
}
register_test!(test_mincore, "Testing mincore syscall");
register_test!(test_mincore);
fn run_test(test_fn: fn()) {
fn run_test(test_fn: fn()) -> Result<(), i32> {
// Fork a new process to run the test
unsafe {
let pid = libc::fork();
@@ -204,17 +202,27 @@ fn run_test(test_fn: fn()) {
panic!("fork failed");
} else if pid == 0 {
// Child process
test_fn();
libc::_exit(0);
let result = std::panic::catch_unwind(|| {
test_fn();
});
let exit_code = if let Err(e) = result {
// Get the panic info
eprintln!("Test panicked: {:?}", e);
let error = std::io::Error::last_os_error();
eprintln!("Last OS error: {}", error);
1
} else {
0
};
libc::_exit(exit_code);
} else {
// Parent process
let mut status = 0;
libc::waitpid(pid, &mut status, 0);
if !libc::WIFEXITED(status) || libc::WEXITSTATUS(status) != 0 {
panic!(
"Test failed in child process: {} (this might be incorrect)",
std::io::Error::last_os_error()
);
Err(status)
} else {
Ok(())
}
}
}
@@ -223,12 +231,26 @@ fn run_test(test_fn: fn()) {
fn main() {
println!("Running userspace tests ...");
let start = std::time::Instant::now();
let mut failures = 0;
for test in inventory::iter::<Test> {
print!("{} ...", test.test_text);
stdout().flush();
run_test(test.test_fn);
println!(" OK");
let _ = stdout().flush();
match run_test(test.test_fn) {
Ok(()) => println!("{}", " OK".green()),
Err(code) => {
println!(" {}", "FAILED".red());
eprintln!("Test '{}' failed with exit code {}", test.test_text, code);
failures += 1;
}
}
}
let end = std::time::Instant::now();
if failures > 0 {
eprintln!(
"{failures} tests failed in {} ms",
(end - start).as_millis()
);
std::process::exit(1);
}
println!("All tests passed in {} ms", (end - start).as_millis());
}

View File

@@ -72,10 +72,7 @@ fn test_interruptible_nanosleep() {
}
}
register_test!(
test_interruptible_nanosleep,
"Testing interruptible nanosleep"
);
register_test!(test_interruptible_nanosleep);
fn test_interruptible_read_pipe() {
register_handler(libc::SIGALRM, false);
@@ -114,10 +111,7 @@ fn test_interruptible_read_pipe() {
}
}
register_test!(
test_interruptible_read_pipe,
"Testing interruptible read (pipe)"
);
register_test!(test_interruptible_read_pipe);
fn test_interruptible_waitpid() {
register_handler(libc::SIGALRM, false);
@@ -162,4 +156,4 @@ fn test_interruptible_waitpid() {
}
}
register_test!(test_interruptible_waitpid, "Testing interruptible waitpid");
register_test!(test_interruptible_waitpid);