Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Perform deeper compiletest path normalization for $TEST_BUILD_DIR to account for compare-mode/debugger cases, and normalize long type file filename hashes #136865

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions src/bootstrap/src/core/build_steps/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1762,15 +1762,21 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
cmd.arg("--coverage-dump-path").arg(coverage_dump);
}

cmd.arg("--src-base").arg(builder.src.join("tests").join(suite));
cmd.arg("--build-base").arg(testdir(builder, compiler.host).join(suite));
cmd.arg("--src-root").arg(&builder.src);
cmd.arg("--src-test-suite-root").arg(builder.src.join("tests").join(suite));

// N.B. it's important to distinguish between the *root* build directory, the *host* build
// directory immediately under the root build directory, and the test-suite-specific build
// directory.
cmd.arg("--build-root").arg(&builder.out);
cmd.arg("--build-test-suite-root").arg(testdir(builder, compiler.host).join(suite));

// When top stage is 0, that means that we're testing an externally provided compiler.
// In that case we need to use its specific sysroot for tests to pass.
let sysroot = if builder.top_stage == 0 {
builder.initial_sysroot.clone()
} else {
builder.sysroot(compiler).to_path_buf()
builder.sysroot(compiler)
};

cmd.arg("--sysroot-base").arg(sysroot);
Expand Down
26 changes: 17 additions & 9 deletions src/tools/compiletest/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,11 +215,15 @@ pub struct Config {
/// `None` then these tests will be ignored.
pub run_clang_based_tests_with: Option<String>,

/// The directory containing the tests to run
pub src_base: PathBuf,
/// The directory containing the sources.
pub src_root: PathBuf,
/// The directory containing the test suite sources. Must be a subdirectory of `src_root`.
pub src_test_suite_root: PathBuf,

/// The directory where programs should be built
pub build_base: PathBuf,
/// Root build directory (e.g. `build/`).
pub build_root: PathBuf,
/// Test suite specific build directory (e.g. `build/host/test/ui/`).
pub build_test_suite_root: PathBuf,

/// The directory containing the compiler sysroot
pub sysroot_base: PathBuf,
Expand Down Expand Up @@ -345,7 +349,7 @@ pub struct Config {

/// If true, this will generate a coverage file with UI test files that run `MachineApplicable`
/// diagnostics but are missing `run-rustfix` annotations. The generated coverage file is
/// created in `/<build_base>/rustfix_missing_coverage.txt`
/// created in `<test_suite_build_root>/rustfix_missing_coverage.txt`
pub rustfix_coverage: bool,

/// whether to run `tidy` (html-tidy) when a rustdoc test fails
Expand Down Expand Up @@ -799,12 +803,16 @@ pub const UI_STDERR_16: &str = "16bit.stderr";
pub const UI_COVERAGE: &str = "coverage";
pub const UI_COVERAGE_MAP: &str = "cov-map";

/// Absolute path to the directory where all output for all tests in the given
/// `relative_dir` group should reside. Example:
/// /path/to/build/host-tuple/test/ui/relative/
/// Absolute path to the directory where all output for all tests in the given `relative_dir` group
/// should reside. Example:
///
/// ```text
/// /path/to/build/host-tuple/test/ui/relative/
/// ```
///
/// This is created early when tests are collected to avoid race conditions.
pub fn output_relative_path(config: &Config, relative_dir: &Path) -> PathBuf {
config.build_base.join(relative_dir)
config.build_test_suite_root.join(relative_dir)
}

/// Generates a unique name for the test, such as `testname.revision.mode`.
Expand Down
25 changes: 7 additions & 18 deletions src/tools/compiletest/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1026,19 +1026,6 @@ impl Config {
}
}

pub fn find_rust_src_root(&self) -> Option<PathBuf> {
let mut path = self.src_base.clone();
let path_postfix = Path::new("src/etc/lldb_batchmode.py");

while path.pop() {
if path.join(&path_postfix).is_file() {
return Some(path);
}
}

None
}

fn parse_edition(&self, line: &str) -> Option<String> {
self.parse_name_value_directive(line, "edition")
}
Expand Down Expand Up @@ -1083,10 +1070,11 @@ impl Config {
}
}

// FIXME(jieyouxu): fix some of these variable names to more accurately reflect what they do.
fn expand_variables(mut value: String, config: &Config) -> String {
const CWD: &str = "{{cwd}}";
const SRC_BASE: &str = "{{src-base}}";
const BUILD_BASE: &str = "{{build-base}}";
const TEST_SUITE_BUILD_BASE: &str = "{{build-base}}";
const RUST_SRC_BASE: &str = "{{rust-src-base}}";
const SYSROOT_BASE: &str = "{{sysroot-base}}";
const TARGET_LINKER: &str = "{{target-linker}}";
Expand All @@ -1098,15 +1086,16 @@ fn expand_variables(mut value: String, config: &Config) -> String {
}

if value.contains(SRC_BASE) {
value = value.replace(SRC_BASE, &config.src_base.to_string_lossy());
value = value.replace(SRC_BASE, &config.src_test_suite_root.to_str().unwrap());
}

if value.contains(BUILD_BASE) {
value = value.replace(BUILD_BASE, &config.build_base.to_string_lossy());
if value.contains(TEST_SUITE_BUILD_BASE) {
value =
value.replace(TEST_SUITE_BUILD_BASE, &config.build_test_suite_root.to_str().unwrap());
}

if value.contains(SYSROOT_BASE) {
value = value.replace(SYSROOT_BASE, &config.sysroot_base.to_string_lossy());
value = value.replace(SYSROOT_BASE, &config.sysroot_base.to_str().unwrap());
}

if value.contains(TARGET_LINKER) {
Expand Down
6 changes: 4 additions & 2 deletions src/tools/compiletest/src/header/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,10 @@ impl ConfigBuilder {
"--run-lib-path=",
"--python=",
"--jsondocck-path=",
"--src-base=",
"--build-base=",
"--src-root=",
"--src-test-suite-root=",
"--build-root=",
"--build-test-suite-root=",
"--sysroot-base=",
"--cc=c",
"--cxx=c++",
Expand Down
85 changes: 55 additions & 30 deletions src/tools/compiletest/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,10 @@ pub fn parse_config(args: Vec<String>) -> Config {
.optopt("", "jsondoclint-path", "path to jsondoclint to use for doc tests", "PATH")
.optopt("", "run-clang-based-tests-with", "path to Clang executable", "PATH")
.optopt("", "llvm-filecheck", "path to LLVM's FileCheck binary", "DIR")
.reqopt("", "src-base", "directory to scan for test files", "PATH")
.reqopt("", "build-base", "directory to deposit test outputs", "PATH")
.reqopt("", "src-root", "directory containing sources", "PATH")
.reqopt("", "src-test-suite-root", "directory containing test suite sources", "PATH")
.reqopt("", "build-root", "path to root build directory", "PATH")
.reqopt("", "build-test-suite-root", "path to test suite specific build directory", "PATH")
.reqopt("", "sysroot-base", "directory containing the compiler sysroot", "PATH")
.reqopt("", "stage", "stage number under test", "N")
.reqopt("", "stage-id", "the target-stage identifier", "stageN-TARGET")
Expand Down Expand Up @@ -156,7 +158,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
"",
"rustfix-coverage",
"enable this to generate a Rustfix coverage file, which is saved in \
`./<build_base>/rustfix_missing_coverage.txt`",
`./<build_test_suite_root>/rustfix_missing_coverage.txt`",
)
.optflag("", "force-rerun", "rerun tests even if the inputs are unchanged")
.optflag("", "only-modified", "only run tests that result been modified")
Expand Down Expand Up @@ -243,7 +245,6 @@ pub fn parse_config(args: Vec<String>) -> Config {
|| header::extract_llvm_version_from_binary(&matches.opt_str("llvm-filecheck")?),
);

let src_base = opt_path(matches, "src-base");
let run_ignored = matches.opt_present("ignored");
let with_rustc_debug_assertions = matches.opt_present("with-rustc-debug-assertions");
let with_std_debug_assertions = matches.opt_present("with-std-debug-assertions");
Expand Down Expand Up @@ -300,6 +301,14 @@ pub fn parse_config(args: Vec<String>) -> Config {
None => panic!("`--stage` is required"),
};

let src_root = opt_path(matches, "src-root");
let src_test_suite_root = opt_path(matches, "src-test-suite-root");
assert!(src_test_suite_root.starts_with(&src_root));

let build_root = opt_path(matches, "build-root");
let build_test_suite_root = opt_path(matches, "build-test-suite-root");
assert!(build_test_suite_root.starts_with(&build_root));

Config {
bless: matches.opt_present("bless"),
compile_lib_path: make_absolute(opt_path(matches, "compile-lib-path")),
Expand All @@ -314,8 +323,13 @@ pub fn parse_config(args: Vec<String>) -> Config {
run_clang_based_tests_with: matches.opt_str("run-clang-based-tests-with"),
llvm_filecheck: matches.opt_str("llvm-filecheck").map(PathBuf::from),
llvm_bin_dir: matches.opt_str("llvm-bin-dir").map(PathBuf::from),
src_base,
build_base: opt_path(matches, "build-base"),

src_root,
src_test_suite_root,

build_root,
build_test_suite_root,

sysroot_base: opt_path(matches, "sysroot-base"),

stage,
Expand Down Expand Up @@ -422,8 +436,15 @@ pub fn log_config(config: &Config) {
logv(c, format!("rustc_path: {:?}", config.rustc_path.display()));
logv(c, format!("cargo_path: {:?}", config.cargo_path));
logv(c, format!("rustdoc_path: {:?}", config.rustdoc_path));
logv(c, format!("src_base: {:?}", config.src_base.display()));
logv(c, format!("build_base: {:?}", config.build_base.display()));

logv(c, format!("src_root: {}", config.src_root.display()));
logv(c, format!("src_test_suite_root: {}", config.src_test_suite_root.display()));

logv(c, format!("build_root: {}", config.build_root.display()));
logv(c, format!("build_test_suite_root: {}", config.build_test_suite_root.display()));

logv(c, format!("sysroot_base: {}", config.sysroot_base.display()));

logv(c, format!("stage: {}", config.stage));
logv(c, format!("stage_id: {}", config.stage_id));
logv(c, format!("mode: {}", config.mode));
Expand Down Expand Up @@ -473,7 +494,7 @@ pub fn run_tests(config: Arc<Config>) {
// we first make sure that the coverage file does not exist.
// It will be created later on.
if config.rustfix_coverage {
let mut coverage_file_path = config.build_base.clone();
let mut coverage_file_path = config.build_test_suite_root.clone();
coverage_file_path.push("rustfix_missing_coverage.txt");
if coverage_file_path.exists() {
if let Err(e) = fs::remove_file(&coverage_file_path) {
Expand Down Expand Up @@ -620,20 +641,29 @@ struct TestCollector {
/// regardless of whether any filters/tests were specified on the command-line,
/// because filtering is handled later by libtest.
pub fn collect_and_make_tests(config: Arc<Config>) -> Vec<test::TestDescAndFn> {
debug!("making tests from {:?}", config.src_base.display());
debug!("making tests from {}", config.src_test_suite_root.display());
let common_inputs_stamp = common_inputs_stamp(&config);
let modified_tests = modified_tests(&config, &config.src_base).unwrap_or_else(|err| {
panic!("modified_tests got error from dir: {}, error: {}", config.src_base.display(), err)
});
let modified_tests =
modified_tests(&config, &config.src_test_suite_root).unwrap_or_else(|err| {
panic!(
"modified_tests got error from dir: {}, error: {}",
config.src_test_suite_root.display(),
err
)
});
let cache = HeadersCache::load(&config);

let cx = TestCollectorCx { config, cache, common_inputs_stamp, modified_tests };
let mut collector =
TestCollector { tests: vec![], found_path_stems: HashSet::new(), poisoned: false };

collect_tests_from_dir(&cx, &mut collector, &cx.config.src_base, Path::new("")).unwrap_or_else(
|reason| panic!("Could not read tests from {}: {reason}", cx.config.src_base.display()),
);
collect_tests_from_dir(&cx, &mut collector, &cx.config.src_test_suite_root, Path::new(""))
.unwrap_or_else(|reason| {
panic!(
"Could not read tests from {}: {reason}",
cx.config.src_test_suite_root.display()
)
});

let TestCollector { tests, found_path_stems, poisoned } = collector;

Expand All @@ -655,7 +685,7 @@ pub fn collect_and_make_tests(config: Arc<Config>) -> Vec<test::TestDescAndFn> {
/// common to some subset of tests, and are hopefully unlikely to be modified
/// while working on other tests.)
fn common_inputs_stamp(config: &Config) -> Stamp {
let rust_src_dir = config.find_rust_src_root().expect("Could not find Rust source root");
let src_root = &config.src_root;

let mut stamp = Stamp::from_path(&config.rustc_path);

Expand All @@ -670,17 +700,17 @@ fn common_inputs_stamp(config: &Config) -> Stamp {
"src/etc/lldb_providers.py",
];
for file in &pretty_printer_files {
let path = rust_src_dir.join(file);
let path = src_root.join(file);
stamp.add_path(&path);
}

stamp.add_dir(&rust_src_dir.join("src/etc/natvis"));
stamp.add_dir(&src_root.join("src/etc/natvis"));

stamp.add_dir(&config.run_lib_path);

if let Some(ref rustdoc_path) = config.rustdoc_path {
stamp.add_path(&rustdoc_path);
stamp.add_path(&rust_src_dir.join("src/etc/htmldocck.py"));
stamp.add_path(&src_root.join("src/etc/htmldocck.py"));
}

// Re-run coverage tests if the `coverage-dump` tool was modified,
Expand All @@ -689,10 +719,10 @@ fn common_inputs_stamp(config: &Config) -> Stamp {
stamp.add_path(coverage_dump_path)
}

stamp.add_dir(&rust_src_dir.join("src/tools/run-make-support"));
stamp.add_dir(&src_root.join("src/tools/run-make-support"));

// Compiletest itself.
stamp.add_dir(&rust_src_dir.join("src/tools/compiletest/"));
stamp.add_dir(&src_root.join("src/tools/compiletest"));

stamp
}
Expand Down Expand Up @@ -933,10 +963,7 @@ fn files_related_to_test(
}

// `minicore.rs` test auxiliary: we need to make sure tests get rerun if this changes.
//
// FIXME(jieyouxu): untangle these paths, we should provide both a path to root `tests/` or
// `tests/auxiliary/` and the test suite in question. `src_base` is also a terrible name.
related.push(config.src_base.parent().unwrap().join("auxiliary").join("minicore.rs"));
related.push(config.src_root.join("tests").join("auxiliary").join("minicore.rs"));

related
}
Expand Down Expand Up @@ -1026,10 +1053,8 @@ fn make_test_name(
testpaths: &TestPaths,
revision: Option<&str>,
) -> test::TestName {
// Print the name of the file, relative to the repository root.
// `src_base` looks like `/path/to/rust/tests/ui`
let root_directory = config.src_base.parent().unwrap().parent().unwrap();
let path = testpaths.file.strip_prefix(root_directory).unwrap();
// Print the name of the file, relative to the sources root.
let path = testpaths.file.strip_prefix(&config.src_root).unwrap();
let debugger = match config.debugger {
Some(d) => format!("-{}", d),
None => String::new(),
Expand Down
Loading
Loading