diff --git a/README.md b/README.md index 44d5cfc13f..ea4dd2c33e 100644 --- a/README.md +++ b/README.md @@ -108,44 +108,22 @@ Note: Do not edit `relibc` inside `prefix` folder! Do your work on `relibc` fold ## Tests -This section explain how to build and run the tests. +Relibc has a test suite that also runs every time a new commit get pushed. You can see `.gitlab-ci.yml` to see how it's being executed. That being said, `./check.sh` is the recommended way to run tests. Here's few examples: -### Build ++ `./check.sh` - Run build, without running the test ++ `./check.sh --test` - Run all tests in x86_64 Redox using Redoxer ++ `./check.sh --test --host` - Run all tests in host (Linux) ++ `./check.sh --test --arch=aarch64` - Run all tests in specified arch + - Arch can be `x86_64`, `aarch64`, `i586`, or `riscv64gc` ++ `./check.sh --test=stdio/printf` - Run a single test + - Can be combined with `--host` or `--arch` + - Will run statically linked test in Linux, dynamically linked in Redox -To build the tests run `make all` on the `tests` folder, it will store the executables at `tests/bins_static` +Couple of notes: -If you did changes to your tests, run `make clean all` to rebuild the executables. - -### Redox OS Testing - -To test on Redox do the following steps: - -- Add the `relibc-tests` recipe on your filesystem configuration at `config/your-cpu/your-config.toml` (generally `desktop.toml`) -- Run the following commands to rebuild relibc with your changes, update the `relibc-tests` recipe and update your QEMU image: - -```sh -touch relibc -``` - -```sh -make prefix cr.relibc-tests image -``` - -- Run the tests - -```sh -/usr/share/relibc-tests/bins_static/test-name -``` - -### Linux Testing - -Run `make test` on the relibc directory. - -If you want to run one test, run the following command: - -```sh -tests/bins_static/test-name -``` +- Relibc and its tests will rebuild if files changed, however switching between arch or host requires you to run `make clean` +- Redoxer is needed to run tests for Redox. You can install it using `cargo install redoxer` +- Tests can hangs, the test runner can anticipate this, assuming the kernel doesn't hang too. ## Issues diff --git a/tests/src/main.rs b/tests/src/main.rs index 31b5444d53..5607e3ad90 100644 --- a/tests/src/main.rs +++ b/tests/src/main.rs @@ -1,3 +1,5 @@ +#![feature(exit_status_error)] + use std::{ env, fs, io::{self, Read, Write}, @@ -48,12 +50,28 @@ fn expected(bin: &str, kind: &str, generated: &[u8], status: ExitStatus) -> Resu const STATUS_ONLY: &str = "-s"; +fn print_tabbed(output: Vec, name: &str) { + if let Ok(stdout) = String::from_utf8(output) { + let stdout: Vec = stdout.trim().lines().map(|p| format!(" {}", p)).collect(); + let stdout = stdout.join("\n"); + if stdout.as_str() == "" { + println!("{name}: empty content"); + } else { + println!("{name}:\n{}", stdout); + } + } else { + println!("can't print out {name}: not utf8"); + } +} + fn main() { let mut failures = Vec::new(); let timeout = Duration::from_secs(10); let slowtime = Duration::from_secs(1); + let bins: Vec = env::args().skip(1).collect(); + let single_test = bins.len() == 1; - for bin in env::args().skip(1) { + for bin in bins { let status_only = bin.starts_with(STATUS_ONLY); let bin = if bin.starts_with(STATUS_ONLY) { bin.strip_prefix(STATUS_ONLY).unwrap().to_string() @@ -152,13 +170,30 @@ fn main() { } match (status, child) { - (Some(exit_status), Some(child)) => { - if !status_only { - let mut stdout = Vec::new(); - let mut stderr = Vec::new(); - child.stdout.unwrap().read_to_end(&mut stdout).unwrap(); - child.stderr.unwrap().read_to_end(&mut stderr).unwrap(); + (exit_status, Some(mut child)) => { + if exit_status.is_none() { + match child.kill() { + Ok(_) => {} + Err(e) => { + // if can't be killed then getting the output will hang + println!("Unable to kill, can't get output: {:?}", e); + continue; + } + } + } + let mut stdout = Vec::new(); + let mut stderr = Vec::new(); + child.stdout.unwrap().read_to_end(&mut stdout).unwrap(); + child.stderr.unwrap().read_to_end(&mut stderr).unwrap(); + let Some(exit_status) = exit_status else { + // hangs + print_tabbed(stdout, "stdout"); + print_tabbed(stderr, "stderr"); + continue; + }; + + if !status_only { if let Err(failure) = expected(&bin, "stdout", &stdout, exit_status) { println!("{}", failure); failures.push(failure); @@ -168,6 +203,17 @@ fn main() { failures.push(failure); } } + + if let Err(e) = exit_status.exit_ok() { + let failure = format!("test return error: {}", e); + println!("{}", failure); + failures.push(failure); + } + + if single_test { + print_tabbed(stdout, "stdout"); + print_tabbed(stderr, "stderr"); + } } (_, _) => { continue;