mirror of
https://git.proxmox.com/git/rustc
synced 2025-08-15 03:09:54 +00:00
155 lines
4.8 KiB
Rust
155 lines
4.8 KiB
Rust
//! You can run this test suite with:
|
|
//!
|
|
//! cargo test --test all
|
|
//!
|
|
//! An argument can be passed as well to filter, based on filename, which test
|
|
//! to run
|
|
//!
|
|
//! cargo test --test all foo.wit
|
|
|
|
use anyhow::{bail, Context, Result};
|
|
use libtest_mimic::{Arguments, Trial};
|
|
use pretty_assertions::StrComparison;
|
|
use std::env;
|
|
use std::ffi::OsStr;
|
|
use std::fs;
|
|
use std::io;
|
|
use std::path::{Path, PathBuf};
|
|
use std::str;
|
|
use wit_parser::*;
|
|
|
|
fn main() {
|
|
env_logger::init();
|
|
let tests = find_tests();
|
|
|
|
let mut trials = Vec::new();
|
|
for test in tests {
|
|
let trial = Trial::test(format!("{test:?}"), move || {
|
|
Runner {}
|
|
.run(&test)
|
|
.context(format!("test {:?} failed", test))
|
|
.map_err(|e| format!("{e:?}").into())
|
|
});
|
|
trials.push(trial);
|
|
}
|
|
|
|
let mut args = Arguments::from_args();
|
|
if cfg!(target_family = "wasm") && !cfg!(target_feature = "atomics") {
|
|
args.test_threads = Some(1);
|
|
}
|
|
libtest_mimic::run(&args, trials).exit();
|
|
}
|
|
|
|
/// Recursively finds all tests in a whitelisted set of directories which we
|
|
/// then load up and test in parallel.
|
|
fn find_tests() -> Vec<PathBuf> {
|
|
let mut tests = Vec::new();
|
|
find_tests("tests/ui".as_ref(), &mut tests);
|
|
find_tests("tests/ui/parse-fail".as_ref(), &mut tests);
|
|
tests.sort();
|
|
return tests;
|
|
|
|
fn find_tests(path: &Path, tests: &mut Vec<PathBuf>) {
|
|
for f in path.read_dir().unwrap() {
|
|
let f = f.unwrap();
|
|
let path = f.path();
|
|
if path.file_name().unwrap().to_str().unwrap() == "parse-fail" {
|
|
continue;
|
|
}
|
|
if f.file_type().unwrap().is_dir() {
|
|
tests.push(path);
|
|
continue;
|
|
}
|
|
|
|
match path.extension().and_then(|s| s.to_str()) {
|
|
Some("md") | Some("wit") | Some("wat") | Some("wasm") => {}
|
|
_ => continue,
|
|
}
|
|
tests.push(path);
|
|
}
|
|
}
|
|
}
|
|
|
|
struct Runner {}
|
|
|
|
impl Runner {
|
|
fn run(&mut self, test: &Path) -> Result<()> {
|
|
let mut resolve = Resolve::new();
|
|
resolve.features.insert("active".to_string());
|
|
let result = resolve.push_path(test);
|
|
let result = if test.iter().any(|s| s == "parse-fail") {
|
|
match result {
|
|
Ok(_) => bail!("expected test to not parse but it did"),
|
|
Err(mut e) => {
|
|
if let Some(err) = e.downcast_mut::<io::Error>() {
|
|
*err = io::Error::new(
|
|
io::ErrorKind::Other,
|
|
"some generic platform-agnostic error message",
|
|
);
|
|
}
|
|
format!("{:#}", e)
|
|
}
|
|
}
|
|
} else {
|
|
result?;
|
|
// format json string to human readable
|
|
let json_result = serde_json::to_string_pretty(&resolve)?;
|
|
// "foo.wit" => "foo.wit.json"
|
|
self.read_or_write_to_file(test, &json_result, "json")?;
|
|
return Ok(());
|
|
};
|
|
|
|
// "foo.wit" => "foo.wit.result"
|
|
// "foo.wit.md" => "foo.wit.md.result"
|
|
self.read_or_write_to_file(test, &result, "result")?;
|
|
return Ok(());
|
|
}
|
|
|
|
fn read_or_write_to_file(
|
|
&mut self,
|
|
test: &Path,
|
|
result: &str,
|
|
extension: &str,
|
|
) -> Result<(), anyhow::Error> {
|
|
let result_file = if test.extension() == Some(OsStr::new("md"))
|
|
&& test
|
|
.file_stem()
|
|
.and_then(|path| Path::new(path).extension())
|
|
== Some(OsStr::new("wit"))
|
|
{
|
|
test.with_extension(format!("md.{extension}"))
|
|
} else {
|
|
test.with_extension(format!("wit.{extension}"))
|
|
};
|
|
if env::var_os("BLESS").is_some() {
|
|
let normalized = normalize(&result, extension);
|
|
fs::write(&result_file, normalized)?;
|
|
} else {
|
|
let expected = fs::read_to_string(&result_file).context(format!(
|
|
"failed to read test expectation file {:?}\nthis can be fixed with BLESS=1",
|
|
result_file
|
|
))?;
|
|
let expected = normalize(&expected, extension);
|
|
let result = normalize(&result, extension);
|
|
if expected != result {
|
|
bail!(
|
|
"failed test: result is not as expected:{}",
|
|
StrComparison::new(&expected, &result),
|
|
);
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
fn normalize(s: &str, extension: &str) -> String {
|
|
let s = s.trim();
|
|
match extension {
|
|
// .result files have error messages with paths, so normalize Windows \ separators to /
|
|
"result" => s.replace("\\", "/").replace("\r\n", "\n"),
|
|
|
|
// .json files escape strings with \, so leave them alone
|
|
_ => s.replace("\r\n", "\n"),
|
|
}
|
|
}
|