mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
compiletest: Encapsulate all of the code that touches libtest
This commit is contained in:
parent
3e762b1897
commit
ecf9e204c9
@ -9,9 +9,9 @@ use std::{fmt, iter};
|
|||||||
use build_helper::git::GitConfig;
|
use build_helper::git::GitConfig;
|
||||||
use semver::Version;
|
use semver::Version;
|
||||||
use serde::de::{Deserialize, Deserializer, Error as _};
|
use serde::de::{Deserialize, Deserializer, Error as _};
|
||||||
use test::{ColorConfig, OutputFormat};
|
|
||||||
|
|
||||||
pub use self::Mode::*;
|
pub use self::Mode::*;
|
||||||
|
use crate::executor::{ColorConfig, OutputFormat};
|
||||||
use crate::util::{PathBufExt, add_dylib_path};
|
use crate::util::{PathBufExt, add_dylib_path};
|
||||||
|
|
||||||
macro_rules! string_enum {
|
macro_rules! string_enum {
|
||||||
|
156
src/tools/compiletest/src/executor.rs
Normal file
156
src/tools/compiletest/src/executor.rs
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
//! This module encapsulates all of the code that interacts directly with
|
||||||
|
//! libtest, to execute the collected tests.
|
||||||
|
//!
|
||||||
|
//! This will hopefully make it easier to migrate away from libtest someday.
|
||||||
|
|
||||||
|
use std::borrow::Cow;
|
||||||
|
use std::io;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::common::{Config, TestPaths};
|
||||||
|
|
||||||
|
/// Delegates to libtest to run the list of collected tests.
|
||||||
|
///
|
||||||
|
/// Returns `Ok(true)` if all tests passed, or `Ok(false)` if one or more tests failed.
|
||||||
|
pub(crate) fn execute_tests(config: &Config, tests: Vec<CollectedTest>) -> io::Result<bool> {
|
||||||
|
let opts = test_opts(config);
|
||||||
|
let tests = tests.into_iter().map(|t| t.into_libtest()).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
test::run_tests_console(&opts, tests)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Information needed to create a `test::TestDescAndFn`.
|
||||||
|
pub(crate) struct CollectedTest {
|
||||||
|
pub(crate) desc: CollectedTestDesc,
|
||||||
|
pub(crate) config: Arc<Config>,
|
||||||
|
pub(crate) testpaths: TestPaths,
|
||||||
|
pub(crate) revision: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Information needed to create a `test::TestDesc`.
|
||||||
|
pub(crate) struct CollectedTestDesc {
|
||||||
|
pub(crate) name: String,
|
||||||
|
pub(crate) ignore: bool,
|
||||||
|
pub(crate) ignore_message: Option<Cow<'static, str>>,
|
||||||
|
pub(crate) should_panic: ShouldPanic,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CollectedTest {
|
||||||
|
fn into_libtest(self) -> test::TestDescAndFn {
|
||||||
|
let Self { desc, config, testpaths, revision } = self;
|
||||||
|
let CollectedTestDesc { name, ignore, ignore_message, should_panic } = desc;
|
||||||
|
|
||||||
|
// Libtest requires the ignore message to be a &'static str, so we might
|
||||||
|
// have to leak memory to create it. This is fine, as we only do so once
|
||||||
|
// per test, so the leak won't grow indefinitely.
|
||||||
|
let ignore_message = ignore_message.map(|msg| match msg {
|
||||||
|
Cow::Borrowed(s) => s,
|
||||||
|
Cow::Owned(s) => &*String::leak(s),
|
||||||
|
});
|
||||||
|
|
||||||
|
let desc = test::TestDesc {
|
||||||
|
name: test::DynTestName(name),
|
||||||
|
ignore,
|
||||||
|
ignore_message,
|
||||||
|
source_file: "",
|
||||||
|
start_line: 0,
|
||||||
|
start_col: 0,
|
||||||
|
end_line: 0,
|
||||||
|
end_col: 0,
|
||||||
|
should_panic: should_panic.to_libtest(),
|
||||||
|
compile_fail: false,
|
||||||
|
no_run: false,
|
||||||
|
test_type: test::TestType::Unknown,
|
||||||
|
};
|
||||||
|
|
||||||
|
// This closure is invoked when libtest returns control to compiletest
|
||||||
|
// to execute the test.
|
||||||
|
let testfn = test::DynTestFn(Box::new(move || {
|
||||||
|
crate::runtest::run(config, &testpaths, revision.as_deref());
|
||||||
|
Ok(())
|
||||||
|
}));
|
||||||
|
|
||||||
|
test::TestDescAndFn { desc, testfn }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether console output should be colored or not.
|
||||||
|
#[derive(Copy, Clone, Default, Debug)]
|
||||||
|
pub enum ColorConfig {
|
||||||
|
#[default]
|
||||||
|
AutoColor,
|
||||||
|
AlwaysColor,
|
||||||
|
NeverColor,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ColorConfig {
|
||||||
|
fn to_libtest(self) -> test::ColorConfig {
|
||||||
|
match self {
|
||||||
|
Self::AutoColor => test::ColorConfig::AutoColor,
|
||||||
|
Self::AlwaysColor => test::ColorConfig::AlwaysColor,
|
||||||
|
Self::NeverColor => test::ColorConfig::NeverColor,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Format of the test results output.
|
||||||
|
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
|
||||||
|
pub enum OutputFormat {
|
||||||
|
/// Verbose output
|
||||||
|
Pretty,
|
||||||
|
/// Quiet output
|
||||||
|
#[default]
|
||||||
|
Terse,
|
||||||
|
/// JSON output
|
||||||
|
Json,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OutputFormat {
|
||||||
|
fn to_libtest(self) -> test::OutputFormat {
|
||||||
|
match self {
|
||||||
|
Self::Pretty => test::OutputFormat::Pretty,
|
||||||
|
Self::Terse => test::OutputFormat::Terse,
|
||||||
|
Self::Json => test::OutputFormat::Json,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether test is expected to panic or not.
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
|
pub(crate) enum ShouldPanic {
|
||||||
|
No,
|
||||||
|
Yes,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ShouldPanic {
|
||||||
|
fn to_libtest(self) -> test::ShouldPanic {
|
||||||
|
match self {
|
||||||
|
Self::No => test::ShouldPanic::No,
|
||||||
|
Self::Yes => test::ShouldPanic::Yes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_opts(config: &Config) -> test::TestOpts {
|
||||||
|
test::TestOpts {
|
||||||
|
exclude_should_panic: false,
|
||||||
|
filters: config.filters.clone(),
|
||||||
|
filter_exact: config.filter_exact,
|
||||||
|
run_ignored: if config.run_ignored { test::RunIgnored::Yes } else { test::RunIgnored::No },
|
||||||
|
format: config.format.to_libtest(),
|
||||||
|
logfile: config.logfile.clone(),
|
||||||
|
run_tests: true,
|
||||||
|
bench_benchmarks: true,
|
||||||
|
nocapture: config.nocapture,
|
||||||
|
color: config.color.to_libtest(),
|
||||||
|
shuffle: false,
|
||||||
|
shuffle_seed: None,
|
||||||
|
test_threads: None,
|
||||||
|
skip: config.skip.clone(),
|
||||||
|
list: false,
|
||||||
|
options: test::Options::new(),
|
||||||
|
time_options: None,
|
||||||
|
force_run_in_process: false,
|
||||||
|
fail_fast: config.fail_fast,
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,7 @@ use tracing::*;
|
|||||||
|
|
||||||
use crate::common::{Config, Debugger, FailMode, Mode, PassMode};
|
use crate::common::{Config, Debugger, FailMode, Mode, PassMode};
|
||||||
use crate::debuggers::{extract_cdb_version, extract_gdb_version};
|
use crate::debuggers::{extract_cdb_version, extract_gdb_version};
|
||||||
|
use crate::executor::{CollectedTestDesc, ShouldPanic};
|
||||||
use crate::header::auxiliary::{AuxProps, parse_and_update_aux};
|
use crate::header::auxiliary::{AuxProps, parse_and_update_aux};
|
||||||
use crate::header::needs::CachedNeedsConditions;
|
use crate::header::needs::CachedNeedsConditions;
|
||||||
use crate::util::static_regex;
|
use crate::util::static_regex;
|
||||||
@ -1355,15 +1356,15 @@ where
|
|||||||
Some((min, max))
|
Some((min, max))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_test_description<R: Read>(
|
pub(crate) fn make_test_description<R: Read>(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
cache: &HeadersCache,
|
cache: &HeadersCache,
|
||||||
name: test::TestName,
|
name: String,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
src: R,
|
src: R,
|
||||||
test_revision: Option<&str>,
|
test_revision: Option<&str>,
|
||||||
poisoned: &mut bool,
|
poisoned: &mut bool,
|
||||||
) -> test::TestDesc {
|
) -> CollectedTestDesc {
|
||||||
let mut ignore = false;
|
let mut ignore = false;
|
||||||
let mut ignore_message = None;
|
let mut ignore_message = None;
|
||||||
let mut should_fail = false;
|
let mut should_fail = false;
|
||||||
@ -1387,10 +1388,7 @@ pub fn make_test_description<R: Read>(
|
|||||||
match $e {
|
match $e {
|
||||||
IgnoreDecision::Ignore { reason } => {
|
IgnoreDecision::Ignore { reason } => {
|
||||||
ignore = true;
|
ignore = true;
|
||||||
// The ignore reason must be a &'static str, so we have to leak memory to
|
ignore_message = Some(reason.into());
|
||||||
// create it. This is fine, as the header is parsed only at the start of
|
|
||||||
// compiletest so it won't grow indefinitely.
|
|
||||||
ignore_message = Some(&*Box::leak(Box::<str>::from(reason)));
|
|
||||||
}
|
}
|
||||||
IgnoreDecision::Error { message } => {
|
IgnoreDecision::Error { message } => {
|
||||||
eprintln!("error: {}:{line_number}: {message}", path.display());
|
eprintln!("error: {}:{line_number}: {message}", path.display());
|
||||||
@ -1431,25 +1429,12 @@ pub fn make_test_description<R: Read>(
|
|||||||
// since we run the pretty printer across all tests by default.
|
// since we run the pretty printer across all tests by default.
|
||||||
// If desired, we could add a `should-fail-pretty` annotation.
|
// If desired, we could add a `should-fail-pretty` annotation.
|
||||||
let should_panic = match config.mode {
|
let should_panic = match config.mode {
|
||||||
crate::common::Pretty => test::ShouldPanic::No,
|
crate::common::Pretty => ShouldPanic::No,
|
||||||
_ if should_fail => test::ShouldPanic::Yes,
|
_ if should_fail => ShouldPanic::Yes,
|
||||||
_ => test::ShouldPanic::No,
|
_ => ShouldPanic::No,
|
||||||
};
|
};
|
||||||
|
|
||||||
test::TestDesc {
|
CollectedTestDesc { name, ignore, ignore_message, should_panic }
|
||||||
name,
|
|
||||||
ignore,
|
|
||||||
ignore_message,
|
|
||||||
source_file: "",
|
|
||||||
start_line: 0,
|
|
||||||
start_col: 0,
|
|
||||||
end_line: 0,
|
|
||||||
end_col: 0,
|
|
||||||
should_panic,
|
|
||||||
compile_fail: false,
|
|
||||||
no_run: false,
|
|
||||||
test_type: test::TestType::Unknown,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ignore_cdb(config: &Config, line: &str) -> IgnoreDecision {
|
fn ignore_cdb(config: &Config, line: &str) -> IgnoreDecision {
|
||||||
|
@ -8,14 +8,15 @@ use super::{
|
|||||||
parse_normalize_rule,
|
parse_normalize_rule,
|
||||||
};
|
};
|
||||||
use crate::common::{Config, Debugger, Mode};
|
use crate::common::{Config, Debugger, Mode};
|
||||||
|
use crate::executor::{CollectedTestDesc, ShouldPanic};
|
||||||
|
|
||||||
fn make_test_description<R: Read>(
|
fn make_test_description<R: Read>(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
name: test::TestName,
|
name: String,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
src: R,
|
src: R,
|
||||||
revision: Option<&str>,
|
revision: Option<&str>,
|
||||||
) -> test::TestDesc {
|
) -> CollectedTestDesc {
|
||||||
let cache = HeadersCache::load(config);
|
let cache = HeadersCache::load(config);
|
||||||
let mut poisoned = false;
|
let mut poisoned = false;
|
||||||
let test = crate::header::make_test_description(
|
let test = crate::header::make_test_description(
|
||||||
@ -233,7 +234,7 @@ fn parse_rs(config: &Config, contents: &str) -> EarlyProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn check_ignore(config: &Config, contents: &str) -> bool {
|
fn check_ignore(config: &Config, contents: &str) -> bool {
|
||||||
let tn = test::DynTestName(String::new());
|
let tn = String::new();
|
||||||
let p = Path::new("a.rs");
|
let p = Path::new("a.rs");
|
||||||
let d = make_test_description(&config, tn, p, std::io::Cursor::new(contents), None);
|
let d = make_test_description(&config, tn, p, std::io::Cursor::new(contents), None);
|
||||||
d.ignore
|
d.ignore
|
||||||
@ -242,13 +243,13 @@ fn check_ignore(config: &Config, contents: &str) -> bool {
|
|||||||
#[test]
|
#[test]
|
||||||
fn should_fail() {
|
fn should_fail() {
|
||||||
let config: Config = cfg().build();
|
let config: Config = cfg().build();
|
||||||
let tn = test::DynTestName(String::new());
|
let tn = String::new();
|
||||||
let p = Path::new("a.rs");
|
let p = Path::new("a.rs");
|
||||||
|
|
||||||
let d = make_test_description(&config, tn.clone(), p, std::io::Cursor::new(""), None);
|
let d = make_test_description(&config, tn.clone(), p, std::io::Cursor::new(""), None);
|
||||||
assert_eq!(d.should_panic, test::ShouldPanic::No);
|
assert_eq!(d.should_panic, ShouldPanic::No);
|
||||||
let d = make_test_description(&config, tn, p, std::io::Cursor::new("//@ should-fail"), None);
|
let d = make_test_description(&config, tn, p, std::io::Cursor::new("//@ should-fail"), None);
|
||||||
assert_eq!(d.should_panic, test::ShouldPanic::Yes);
|
assert_eq!(d.should_panic, ShouldPanic::Yes);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -12,6 +12,7 @@ pub mod common;
|
|||||||
pub mod compute_diff;
|
pub mod compute_diff;
|
||||||
mod debuggers;
|
mod debuggers;
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
|
mod executor;
|
||||||
pub mod header;
|
pub mod header;
|
||||||
mod json;
|
mod json;
|
||||||
mod raise_fd_limit;
|
mod raise_fd_limit;
|
||||||
@ -32,7 +33,6 @@ use std::{env, fs, vec};
|
|||||||
|
|
||||||
use build_helper::git::{get_git_modified_files, get_git_untracked_files};
|
use build_helper::git::{get_git_modified_files, get_git_untracked_files};
|
||||||
use getopts::Options;
|
use getopts::Options;
|
||||||
use test::ColorConfig;
|
|
||||||
use tracing::*;
|
use tracing::*;
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
@ -41,6 +41,7 @@ use crate::common::{
|
|||||||
CompareMode, Config, Debugger, Mode, PassMode, TestPaths, UI_EXTENSIONS, expected_output_path,
|
CompareMode, Config, Debugger, Mode, PassMode, TestPaths, UI_EXTENSIONS, expected_output_path,
|
||||||
output_base_dir, output_relative_path,
|
output_base_dir, output_relative_path,
|
||||||
};
|
};
|
||||||
|
use crate::executor::{CollectedTest, ColorConfig, OutputFormat};
|
||||||
use crate::header::HeadersCache;
|
use crate::header::HeadersCache;
|
||||||
use crate::util::logv;
|
use crate::util::logv;
|
||||||
|
|
||||||
@ -402,9 +403,9 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
|||||||
verbose: matches.opt_present("verbose"),
|
verbose: matches.opt_present("verbose"),
|
||||||
format: match (matches.opt_present("quiet"), matches.opt_present("json")) {
|
format: match (matches.opt_present("quiet"), matches.opt_present("json")) {
|
||||||
(true, true) => panic!("--quiet and --json are incompatible"),
|
(true, true) => panic!("--quiet and --json are incompatible"),
|
||||||
(true, false) => test::OutputFormat::Terse,
|
(true, false) => OutputFormat::Terse,
|
||||||
(false, true) => test::OutputFormat::Json,
|
(false, true) => OutputFormat::Json,
|
||||||
(false, false) => test::OutputFormat::Pretty,
|
(false, false) => OutputFormat::Pretty,
|
||||||
},
|
},
|
||||||
only_modified: matches.opt_present("only-modified"),
|
only_modified: matches.opt_present("only-modified"),
|
||||||
color,
|
color,
|
||||||
@ -535,8 +536,6 @@ pub fn run_tests(config: Arc<Config>) {
|
|||||||
// Let tests know which target they're running as
|
// Let tests know which target they're running as
|
||||||
env::set_var("TARGET", &config.target);
|
env::set_var("TARGET", &config.target);
|
||||||
|
|
||||||
let opts = test_opts(&config);
|
|
||||||
|
|
||||||
let mut configs = Vec::new();
|
let mut configs = Vec::new();
|
||||||
if let Mode::DebugInfo = config.mode {
|
if let Mode::DebugInfo = config.mode {
|
||||||
// Debugging emscripten code doesn't make sense today
|
// Debugging emscripten code doesn't make sense today
|
||||||
@ -563,12 +562,12 @@ pub fn run_tests(config: Arc<Config>) {
|
|||||||
tests.extend(collect_and_make_tests(c));
|
tests.extend(collect_and_make_tests(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
tests.sort_by(|a, b| a.desc.name.as_slice().cmp(&b.desc.name.as_slice()));
|
tests.sort_by(|a, b| Ord::cmp(&a.desc.name, &b.desc.name));
|
||||||
|
|
||||||
// Delegate to libtest to filter and run the big list of structures created
|
// Delegate to libtest to filter and run the big list of structures created
|
||||||
// during test discovery. When libtest decides to run a test, it will invoke
|
// during test discovery. When libtest decides to run a test, it will
|
||||||
// the corresponding closure created by `make_test_closure`.
|
// return control to compiletest by invoking a closure.
|
||||||
let res = test::run_tests_console(&opts, tests);
|
let res = crate::executor::execute_tests(&config, tests);
|
||||||
|
|
||||||
// Check the outcome reported by libtest.
|
// Check the outcome reported by libtest.
|
||||||
match res {
|
match res {
|
||||||
@ -612,30 +611,6 @@ pub fn run_tests(config: Arc<Config>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn test_opts(config: &Config) -> test::TestOpts {
|
|
||||||
test::TestOpts {
|
|
||||||
exclude_should_panic: false,
|
|
||||||
filters: config.filters.clone(),
|
|
||||||
filter_exact: config.filter_exact,
|
|
||||||
run_ignored: if config.run_ignored { test::RunIgnored::Yes } else { test::RunIgnored::No },
|
|
||||||
format: config.format,
|
|
||||||
logfile: config.logfile.clone(),
|
|
||||||
run_tests: true,
|
|
||||||
bench_benchmarks: true,
|
|
||||||
nocapture: config.nocapture,
|
|
||||||
color: config.color,
|
|
||||||
shuffle: false,
|
|
||||||
shuffle_seed: None,
|
|
||||||
test_threads: None,
|
|
||||||
skip: config.skip.clone(),
|
|
||||||
list: false,
|
|
||||||
options: test::Options::new(),
|
|
||||||
time_options: None,
|
|
||||||
force_run_in_process: false,
|
|
||||||
fail_fast: config.fail_fast,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Read-only context data used during test collection.
|
/// Read-only context data used during test collection.
|
||||||
struct TestCollectorCx {
|
struct TestCollectorCx {
|
||||||
config: Arc<Config>,
|
config: Arc<Config>,
|
||||||
@ -646,17 +621,17 @@ struct TestCollectorCx {
|
|||||||
|
|
||||||
/// Mutable state used during test collection.
|
/// Mutable state used during test collection.
|
||||||
struct TestCollector {
|
struct TestCollector {
|
||||||
tests: Vec<test::TestDescAndFn>,
|
tests: Vec<CollectedTest>,
|
||||||
found_path_stems: HashSet<PathBuf>,
|
found_path_stems: HashSet<PathBuf>,
|
||||||
poisoned: bool,
|
poisoned: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates libtest structures for every test/revision in the test suite directory.
|
/// Creates test structures for every test/revision in the test suite directory.
|
||||||
///
|
///
|
||||||
/// This always inspects _all_ test files in the suite (e.g. all 17k+ ui tests),
|
/// This always inspects _all_ test files in the suite (e.g. all 17k+ ui tests),
|
||||||
/// regardless of whether any filters/tests were specified on the command-line,
|
/// regardless of whether any filters/tests were specified on the command-line,
|
||||||
/// because filtering is handled later by libtest.
|
/// because filtering is handled later by libtest.
|
||||||
pub fn collect_and_make_tests(config: Arc<Config>) -> Vec<test::TestDescAndFn> {
|
pub(crate) fn collect_and_make_tests(config: Arc<Config>) -> Vec<CollectedTest> {
|
||||||
debug!("making tests from {}", config.src_test_suite_root.display());
|
debug!("making tests from {}", config.src_test_suite_root.display());
|
||||||
let common_inputs_stamp = common_inputs_stamp(&config);
|
let common_inputs_stamp = common_inputs_stamp(&config);
|
||||||
let modified_tests =
|
let modified_tests =
|
||||||
@ -885,7 +860,7 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te
|
|||||||
};
|
};
|
||||||
|
|
||||||
// For each revision (or the sole dummy revision), create and append a
|
// For each revision (or the sole dummy revision), create and append a
|
||||||
// `test::TestDescAndFn` that can be handed over to libtest.
|
// `CollectedTest` that can be handed over to the test executor.
|
||||||
collector.tests.extend(revisions.into_iter().map(|revision| {
|
collector.tests.extend(revisions.into_iter().map(|revision| {
|
||||||
// Create a test name and description to hand over to libtest.
|
// Create a test name and description to hand over to libtest.
|
||||||
let src_file = fs::File::open(&test_path).expect("open test file to parse ignores");
|
let src_file = fs::File::open(&test_path).expect("open test file to parse ignores");
|
||||||
@ -908,13 +883,14 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te
|
|||||||
if !cx.config.force_rerun && is_up_to_date(cx, testpaths, &early_props, revision) {
|
if !cx.config.force_rerun && is_up_to_date(cx, testpaths, &early_props, revision) {
|
||||||
desc.ignore = true;
|
desc.ignore = true;
|
||||||
// Keep this in sync with the "up-to-date" message detected by bootstrap.
|
// Keep this in sync with the "up-to-date" message detected by bootstrap.
|
||||||
desc.ignore_message = Some("up-to-date");
|
desc.ignore_message = Some("up-to-date".into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the callback that will run this test/revision when libtest calls it.
|
let config = Arc::clone(&cx.config);
|
||||||
let testfn = make_test_closure(Arc::clone(&cx.config), testpaths, revision);
|
let testpaths = testpaths.clone();
|
||||||
|
let revision = revision.map(str::to_owned);
|
||||||
|
|
||||||
test::TestDescAndFn { desc, testfn }
|
CollectedTest { desc, config, testpaths, revision }
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1046,11 +1022,7 @@ impl Stamp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a name for this test/revision that can be handed over to libtest.
|
/// Creates a name for this test/revision that can be handed over to libtest.
|
||||||
fn make_test_name(
|
fn make_test_name(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> String {
|
||||||
config: &Config,
|
|
||||||
testpaths: &TestPaths,
|
|
||||||
revision: Option<&str>,
|
|
||||||
) -> test::TestName {
|
|
||||||
// Print the name of the file, relative to the sources root.
|
// Print the name of the file, relative to the sources root.
|
||||||
let path = testpaths.file.strip_prefix(&config.src_root).unwrap();
|
let path = testpaths.file.strip_prefix(&config.src_root).unwrap();
|
||||||
let debugger = match config.debugger {
|
let debugger = match config.debugger {
|
||||||
@ -1062,32 +1034,14 @@ fn make_test_name(
|
|||||||
None => String::new(),
|
None => String::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
test::DynTestName(format!(
|
format!(
|
||||||
"[{}{}{}] {}{}",
|
"[{}{}{}] {}{}",
|
||||||
config.mode,
|
config.mode,
|
||||||
debugger,
|
debugger,
|
||||||
mode_suffix,
|
mode_suffix,
|
||||||
path.display(),
|
path.display(),
|
||||||
revision.map_or("".to_string(), |rev| format!("#{}", rev))
|
revision.map_or("".to_string(), |rev| format!("#{}", rev))
|
||||||
))
|
)
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a callback for this test/revision that libtest will call when it
|
|
||||||
/// decides to actually run the underlying test.
|
|
||||||
fn make_test_closure(
|
|
||||||
config: Arc<Config>,
|
|
||||||
testpaths: &TestPaths,
|
|
||||||
revision: Option<&str>,
|
|
||||||
) -> test::TestFn {
|
|
||||||
let testpaths = testpaths.clone();
|
|
||||||
let revision = revision.map(str::to_owned);
|
|
||||||
|
|
||||||
// This callback is the link between compiletest's test discovery code,
|
|
||||||
// and the parts of compiletest that know how to run an individual test.
|
|
||||||
test::DynTestFn(Box::new(move || {
|
|
||||||
runtest::run(config, &testpaths, revision.as_deref());
|
|
||||||
Ok(())
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks that test discovery didn't find any tests whose name stem is a prefix
|
/// Checks that test discovery didn't find any tests whose name stem is a prefix
|
||||||
|
Loading…
Reference in New Issue
Block a user