Enhance single test run, document check.sh
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
+53
-7
@@ -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<u8>, name: &str) {
|
||||
if let Ok(stdout) = String::from_utf8(output) {
|
||||
let stdout: Vec<String> = 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<String> = 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;
|
||||
|
||||
Reference in New Issue
Block a user