tests: Improve test lookup on exact match

Regression tests were looked up using full directory walk
regardless of whether there was an exact match or not.
This patch looks up the test on exact match without
scanning for all tests. This improvement is important
due to how nextest executes tests: one by one using exact matches.
This commit is contained in:
Kamil Jarosz 2024-04-13 02:25:44 +02:00 committed by Nathan Adams
parent 7006b08095
commit e40374c403
1 changed files with 46 additions and 24 deletions

View File

@ -15,12 +15,13 @@ use ruffle_test_framework::vfs::{PhysicalFS, VfsPath};
use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe}; use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe};
use std::path::Path; use std::path::Path;
use std::thread::sleep; use std::thread::sleep;
use walkdir::DirEntry;
mod environment; mod environment;
mod external_interface; mod external_interface;
mod shared_object; mod shared_object;
const TEST_TOML_NAME: &str = "test.toml";
fn is_candidate(args: &Arguments, test_name: &str) -> bool { fn is_candidate(args: &Arguments, test_name: &str) -> bool {
if let Some(filter) = &args.filter { if let Some(filter) = &args.filter {
match args.exact { match args.exact {
@ -57,27 +58,48 @@ fn main() {
// Ignore error if it's already been set // Ignore error if it's already been set
let _ = tracing::subscriber::set_global_default(subscriber); let _ = tracing::subscriber::set_global_default(subscriber);
// When this is true, we are looking for one specific test.
// This is an important optimization for nextest,
// as it executes tests one by one.
let filter_exact = args.exact && args.filter.is_some();
let root = Path::new("tests/swfs"); let root = Path::new("tests/swfs");
let mut tests: Vec<Trial> = walkdir::WalkDir::new(root) let mut tests: Vec<Trial> = if filter_exact {
.into_iter() let name = args.filter.as_ref().unwrap();
.map(Result::unwrap) let absolute_root = std::fs::canonicalize(root).unwrap();
.filter(|entry| entry.file_type().is_file() && entry.file_name() == "test.toml") let path = absolute_root
.filter_map(|file| { .join(name)
let name = file .join(TEST_TOML_NAME)
.path() .canonicalize()
.parent()? .expect("test should exist");
.strip_prefix(root) path.strip_prefix(absolute_root).expect("path traversal");
.context("Couldn't strip root prefix from test dir") if path.is_file() {
.unwrap() vec![run_test(&args, &path, name)]
.to_string_lossy() } else {
.replace('\\', "/"); vec![]
if is_candidate(&args, &name) { }
Some(run_test(&args, file, name)) } else {
} else { walkdir::WalkDir::new(root)
None .into_iter()
} .map(Result::unwrap)
}) .filter(|entry| entry.file_type().is_file() && entry.file_name() == TEST_TOML_NAME)
.collect(); .filter_map(|file| {
let name = file
.path()
.parent()?
.strip_prefix(root)
.context("Couldn't strip root prefix from test dir")
.unwrap()
.to_string_lossy()
.replace('\\', "/");
if is_candidate(&args, &name) {
Some(run_test(&args, file.path(), &name))
} else {
None
}
})
.collect()
};
// Manual tests here, since #[test] doesn't work once we use our own test harness // Manual tests here, since #[test] doesn't work once we use our own test harness
tests.push(Trial::test("shared_object_avm1", || { tests.push(Trial::test("shared_object_avm1", || {
@ -101,14 +123,14 @@ fn main() {
libtest_mimic::run(&args, tests).exit() libtest_mimic::run(&args, tests).exit()
} }
fn run_test(args: &Arguments, file: DirEntry, name: String) -> Trial { fn run_test(args: &Arguments, file: &Path, name: &str) -> Trial {
let root = VfsPath::new(PhysicalFS::new(file.path().parent().unwrap())); let root = VfsPath::new(PhysicalFS::new(file.parent().unwrap()));
let test = Test::from_options( let test = Test::from_options(
TestOptions::read(&root.join("test.toml").unwrap()) TestOptions::read(&root.join("test.toml").unwrap())
.context("Couldn't load test options") .context("Couldn't load test options")
.unwrap(), .unwrap(),
root, root,
name.clone(), name.to_string(),
) )
.with_context(|| format!("Couldn't create test {name}")) .with_context(|| format!("Couldn't create test {name}"))
.unwrap(); .unwrap();