From d2268902f7db32c03520f160f2d0e750d4d8d0b1 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Tue, 11 Jun 2024 11:37:51 -0400 Subject: [PATCH 1/4] rewrite and rename issue-10971-temps-dir to rmake format --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/issue-10971-temps-dir/Makefile | 10 --------- .../parallel-rustc-no-overwrite/rmake.rs | 22 +++++++++++++++++++ 3 files changed, 22 insertions(+), 11 deletions(-) delete mode 100644 tests/run-make/issue-10971-temps-dir/Makefile create mode 100644 tests/run-make/parallel-rustc-no-overwrite/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index ac89a30f35342..59c836862c5d4 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -79,7 +79,6 @@ run-make/invalid-library/Makefile run-make/invalid-so/Makefile run-make/invalid-staticlib/Makefile run-make/issue-107094/Makefile -run-make/issue-10971-temps-dir/Makefile run-make/issue-109934-lto-debuginfo/Makefile run-make/issue-14698/Makefile run-make/issue-15460/Makefile diff --git a/tests/run-make/issue-10971-temps-dir/Makefile b/tests/run-make/issue-10971-temps-dir/Makefile deleted file mode 100644 index 6e1649a58d231..0000000000000 --- a/tests/run-make/issue-10971-temps-dir/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -include ../tools.mk - -# Regression test for issue #10971 -# Running two invocations in parallel would overwrite each other's temp files. - -all: - touch $(TMPDIR)/lib.rs - - $(RUSTC) --crate-type=lib -Z temps-dir=$(TMPDIR)/temp1 $(TMPDIR)/lib.rs & \ - $(RUSTC) --crate-type=staticlib -Z temps-dir=$(TMPDIR)/temp2 $(TMPDIR)/lib.rs diff --git a/tests/run-make/parallel-rustc-no-overwrite/rmake.rs b/tests/run-make/parallel-rustc-no-overwrite/rmake.rs new file mode 100644 index 0000000000000..d45eb4f29116e --- /dev/null +++ b/tests/run-make/parallel-rustc-no-overwrite/rmake.rs @@ -0,0 +1,22 @@ +// When two instances of rustc are invoked in parallel, they +// can conflict on their temporary files and overwrite each others', +// leading to unsuccessful compilation. The -Z temps-dir flag adds +// separate designated directories for each rustc invocation, preventing +// conflicts. This test uses this flag and checks for successful compilation. +// See https://github.com/rust-lang/rust/pull/83846 + +use run_make_support::{fs_wrapper, rustc}; +use std::thread; + +fn main() { + fs_wrapper::create_file("lib.rs"); + let handle1 = thread::spawn(move || { + rustc().crate_type("lib").arg("-Ztemps-dir=temp1").input("lib.rs"); + }); + + let handle2 = thread::spawn(move || { + rustc().crate_type("staticlib").arg("-Ztemps-dir=temp2").input("lib.rs"); + }); + handle1.join().expect("lib thread panicked"); + handle2.join().expect("staticlib thread panicked"); +} From 03982dae0173f7358dd779aa2a92dd0a2ab0fe59 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Tue, 11 Jun 2024 11:57:07 -0400 Subject: [PATCH 2/4] rewrite inaccessible-temp-dir to rmake format --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/inaccessible-temp-dir/Makefile | 32 -------------- tests/run-make/inaccessible-temp-dir/rmake.rs | 44 +++++++++++++++++++ 3 files changed, 44 insertions(+), 33 deletions(-) delete mode 100644 tests/run-make/inaccessible-temp-dir/Makefile create mode 100644 tests/run-make/inaccessible-temp-dir/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 59c836862c5d4..dd6e64057b444 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -66,7 +66,6 @@ run-make/foreign-double-unwind/Makefile run-make/foreign-exceptions/Makefile run-make/foreign-rust-exceptions/Makefile run-make/glibc-staticlib-args/Makefile -run-make/inaccessible-temp-dir/Makefile run-make/include_bytes_deps/Makefile run-make/incr-add-rust-src-component/Makefile run-make/incr-foreign-head-span/Makefile diff --git a/tests/run-make/inaccessible-temp-dir/Makefile b/tests/run-make/inaccessible-temp-dir/Makefile deleted file mode 100644 index abdba4eb86145..0000000000000 --- a/tests/run-make/inaccessible-temp-dir/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -# only-linux -# ignore-arm - linker error on `armhf-gnu` - -include ../tools.mk - -# Issue #66530: We would ICE if someone compiled with `-o /dev/null`, -# because we would try to generate auxiliary files in `/dev/` (which -# at least the OS X file system rejects). -# -# An attempt to `-Ztemps-dir` into a directory we cannot write into should -# indeed be an error; but not an ICE. -# -# However, some folks run tests as root, which can write `/dev/` and end -# up clobbering `/dev/null`. Instead we'll use an inaccessible path, which -# also used to ICE, but even root can't magically write there. -# -# Note that `-Ztemps-dir` uses `create_dir_all` so it is not sufficient to -# use a directory with non-existing parent like `/does-not-exist/output`. - -all: - # Create an inaccessible directory - mkdir $(TMPDIR)/inaccessible - chmod 000 $(TMPDIR)/inaccessible - - # Run rustc with `-Ztemps-dir` set to a directory - # *inside* the inaccessible one, so that it can't create it - $(RUSTC) program.rs -Ztemps-dir=$(TMPDIR)/inaccessible/tmp 2>&1 \ - | $(CGREP) 'failed to find or create the directory specified by `--temps-dir`' - - # Make the inaccessible directory accessible, - # so that compiletest can delete the temp dir - chmod +rw $(TMPDIR)/inaccessible diff --git a/tests/run-make/inaccessible-temp-dir/rmake.rs b/tests/run-make/inaccessible-temp-dir/rmake.rs new file mode 100644 index 0000000000000..25c9d363820dc --- /dev/null +++ b/tests/run-make/inaccessible-temp-dir/rmake.rs @@ -0,0 +1,44 @@ +// Issue #66530: We would ICE if someone compiled with `-o /dev/null`, +// because we would try to generate auxiliary files in `/dev/` (which +// at least the OS X file system rejects). +// +// An attempt to `-Ztemps-dir` into a directory we cannot write into should +// indeed be an error; but not an ICE. +// +// However, some folks run tests as root, which can write `/dev/` and end +// up clobbering `/dev/null`. Instead we'll use an inaccessible path, which +// also used to ICE, but even root can't magically write there. +// +// Note that `-Ztemps-dir` uses `create_dir_all` so it is not sufficient to +// use a directory with non-existing parent like `/does-not-exist/output`. +// See https://github.com/rust-lang/rust/issues/66530 + +//@ only-linux +// Reason: set_mode is only available on Unix + +//@ ignore-arm +// Reason: linker error on `armhf-gnu` + +use run_make_support::{fs_wrapper, rustc}; + +fn main() { + // Create an inaccessible directory. + fs_wrapper::create_dir("inaccessible"); + let meta = fs_wrapper::metadata("inaccessible"); + let mut perms = meta.permissions(); + perms.set_mode(0o000); // Lock down the directory. + fs_wrapper::set_permissions("inaccessible", perms); + + // Run rustc with `-Z temps-dir` set to a directory *inside* the inaccessible one, + // so that it can't create `tmp`. + rustc() + .input("program.rs") + .arg("-Ztemps-dir=inaccessible/tmp") + .run_fail() + .assert_stderr_contains( + "failed to find or create the directory specified by `--temps-dir`", + ); + + perms.set_mode(0o666); // Unlock the directory, so that compiletest can delete it. + fs_wrapper::set_permissions("inaccessible", perms); +} From 7c2b3b5615cf5e8545c13f7635257cc3fb0eb7bf Mon Sep 17 00:00:00 2001 From: Oneirical Date: Tue, 11 Jun 2024 12:53:33 -0400 Subject: [PATCH 3/4] rewrite output-with-hyphens to rmake format --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/output-with-hyphens/Makefile | 8 ------- tests/run-make/output-with-hyphens/rmake.rs | 17 ++++++++++++++ .../parallel-rustc-no-overwrite/rmake.rs | 22 ++++++++++--------- 4 files changed, 29 insertions(+), 19 deletions(-) delete mode 100644 tests/run-make/output-with-hyphens/Makefile create mode 100644 tests/run-make/output-with-hyphens/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index dd6e64057b444..0d7951bcfffc0 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -156,7 +156,6 @@ run-make/optimization-remarks-dir/Makefile run-make/output-filename-conflicts-with-directory/Makefile run-make/output-filename-overwrites-input/Makefile run-make/output-type-permutations/Makefile -run-make/output-with-hyphens/Makefile run-make/override-aliased-flags/Makefile run-make/overwrite-input/Makefile run-make/panic-abort-eh_frame/Makefile diff --git a/tests/run-make/output-with-hyphens/Makefile b/tests/run-make/output-with-hyphens/Makefile deleted file mode 100644 index 846c9a66a89a0..0000000000000 --- a/tests/run-make/output-with-hyphens/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: - $(RUSTC) foo-bar.rs --crate-type bin - [ -f $(TMPDIR)/$(call BIN,foo-bar) ] - $(RUSTC) foo-bar.rs --crate-type lib - [ -f $(TMPDIR)/libfoo_bar.rlib ] diff --git a/tests/run-make/output-with-hyphens/rmake.rs b/tests/run-make/output-with-hyphens/rmake.rs new file mode 100644 index 0000000000000..21c003c628b9e --- /dev/null +++ b/tests/run-make/output-with-hyphens/rmake.rs @@ -0,0 +1,17 @@ +// Rust files with hyphens in their filename should +// not result in compiled libraries keeping that hyphen - +// it should become an underscore. Only bin executables +// should keep the hyphen. This test ensures that this rule +// remains enforced. +// See https://github.com/rust-lang/rust/pull/23786 + +//@ ignore-cross-compile + +use run_make_support::{path, rustc}; + +fn main() { + rustc().input("foo-bar.rs").crate_type("bin").run(); + assert!(path(bin_name("foo-bar")).exists()); + rustc().input("foo-bar.rs").crate_type("lib").run(); + assert!(path(bin_name("libfoo_bar.rlib")).exists()); +} diff --git a/tests/run-make/parallel-rustc-no-overwrite/rmake.rs b/tests/run-make/parallel-rustc-no-overwrite/rmake.rs index d45eb4f29116e..40c6ab7ed5ebf 100644 --- a/tests/run-make/parallel-rustc-no-overwrite/rmake.rs +++ b/tests/run-make/parallel-rustc-no-overwrite/rmake.rs @@ -6,17 +6,19 @@ // See https://github.com/rust-lang/rust/pull/83846 use run_make_support::{fs_wrapper, rustc}; +use std::sync::{Arc, Barrier}; use std::thread; fn main() { - fs_wrapper::create_file("lib.rs"); - let handle1 = thread::spawn(move || { - rustc().crate_type("lib").arg("-Ztemps-dir=temp1").input("lib.rs"); - }); - - let handle2 = thread::spawn(move || { - rustc().crate_type("staticlib").arg("-Ztemps-dir=temp2").input("lib.rs"); - }); - handle1.join().expect("lib thread panicked"); - handle2.join().expect("staticlib thread panicked"); + let barrier = Arc::new(Barrier::new(2)); + let handle = { + let barrier = Arc::clone(&barrier); + thread::spawn(move || { + barrier.wait(); + rustc().crate_type("lib").arg("-Ztemps-dir=temp1").input("lib.rs"); + }) + }; + barrier.wait(); + rustc().crate_type("staticlib").arg("-Ztemps-dir=temp2").input("lib.rs"); + handle.join().expect("lib thread panicked"); } From 03f19d632ad896be77a0dabfe1298f164c78067c Mon Sep 17 00:00:00 2001 From: Oneirical Date: Tue, 11 Jun 2024 16:12:36 -0400 Subject: [PATCH 4/4] Add new test_while_readonly helper function to run-make-support --- src/tools/run-make-support/src/lib.rs | 32 +++++++++++++++++ tests/run-make/inaccessible-temp-dir/rmake.rs | 36 ++++++++----------- tests/run-make/output-with-hyphens/rmake.rs | 4 +-- .../parallel-rustc-no-overwrite/rmake.rs | 5 +-- 4 files changed, 52 insertions(+), 25 deletions(-) diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index b920f9a07db87..6a89a75d71591 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -169,6 +169,38 @@ pub fn cwd() -> PathBuf { env::current_dir().unwrap() } +// FIXME(Oneirical): This will no longer be required after compiletest receives the ability +// to manipulate read-only files. See https://github.com/rust-lang/rust/issues/126334 +/// Ensure that the path P is read-only while the test runs, and restore original permissions +/// at the end so compiletest can clean up. +/// This will panic on Windows if the path is a directory (as it would otherwise do nothing) +#[track_caller] +pub fn test_while_readonly, F: FnOnce() + std::panic::UnwindSafe>( + path: P, + closure: F, +) { + let path = path.as_ref(); + if is_windows() && path.is_dir() { + eprintln!("This helper function cannot be used on Windows to make directories readonly."); + eprintln!( + "See the official documentation: + https://doc.rust-lang.org/std/fs/struct.Permissions.html#method.set_readonly" + ); + panic!("`test_while_readonly` on directory detected while on Windows."); + } + let metadata = fs_wrapper::metadata(&path); + let original_perms = metadata.permissions(); + + let mut new_perms = original_perms.clone(); + new_perms.set_readonly(true); + fs_wrapper::set_permissions(&path, new_perms); + + let success = std::panic::catch_unwind(closure); + + fs_wrapper::set_permissions(&path, original_perms); + success.unwrap(); +} + /// Use `cygpath -w` on a path to get a Windows path string back. This assumes that `cygpath` is /// available on the platform! #[track_caller] diff --git a/tests/run-make/inaccessible-temp-dir/rmake.rs b/tests/run-make/inaccessible-temp-dir/rmake.rs index 25c9d363820dc..be24e47b6decc 100644 --- a/tests/run-make/inaccessible-temp-dir/rmake.rs +++ b/tests/run-make/inaccessible-temp-dir/rmake.rs @@ -13,32 +13,26 @@ // use a directory with non-existing parent like `/does-not-exist/output`. // See https://github.com/rust-lang/rust/issues/66530 -//@ only-linux -// Reason: set_mode is only available on Unix - //@ ignore-arm // Reason: linker error on `armhf-gnu` +//@ ignore-windows +// Reason: `set_readonly` has no effect on directories +// and does not prevent modification. -use run_make_support::{fs_wrapper, rustc}; +use run_make_support::{fs_wrapper, rustc, test_while_readonly}; fn main() { // Create an inaccessible directory. fs_wrapper::create_dir("inaccessible"); - let meta = fs_wrapper::metadata("inaccessible"); - let mut perms = meta.permissions(); - perms.set_mode(0o000); // Lock down the directory. - fs_wrapper::set_permissions("inaccessible", perms); - - // Run rustc with `-Z temps-dir` set to a directory *inside* the inaccessible one, - // so that it can't create `tmp`. - rustc() - .input("program.rs") - .arg("-Ztemps-dir=inaccessible/tmp") - .run_fail() - .assert_stderr_contains( - "failed to find or create the directory specified by `--temps-dir`", - ); - - perms.set_mode(0o666); // Unlock the directory, so that compiletest can delete it. - fs_wrapper::set_permissions("inaccessible", perms); + test_while_readonly("inaccessible", || { + // Run rustc with `-Z temps-dir` set to a directory *inside* the inaccessible one, + // so that it can't create `tmp`. + rustc() + .input("program.rs") + .arg("-Ztemps-dir=inaccessible/tmp") + .run_fail() + .assert_stderr_contains( + "failed to find or create the directory specified by `--temps-dir`", + ); + }); } diff --git a/tests/run-make/output-with-hyphens/rmake.rs b/tests/run-make/output-with-hyphens/rmake.rs index 21c003c628b9e..79deb772bc5df 100644 --- a/tests/run-make/output-with-hyphens/rmake.rs +++ b/tests/run-make/output-with-hyphens/rmake.rs @@ -7,11 +7,11 @@ //@ ignore-cross-compile -use run_make_support::{path, rustc}; +use run_make_support::{bin_name, path, rust_lib_name, rustc}; fn main() { rustc().input("foo-bar.rs").crate_type("bin").run(); assert!(path(bin_name("foo-bar")).exists()); rustc().input("foo-bar.rs").crate_type("lib").run(); - assert!(path(bin_name("libfoo_bar.rlib")).exists()); + assert!(path(rust_lib_name("foo_bar")).exists()); } diff --git a/tests/run-make/parallel-rustc-no-overwrite/rmake.rs b/tests/run-make/parallel-rustc-no-overwrite/rmake.rs index 40c6ab7ed5ebf..3f032cf3762a9 100644 --- a/tests/run-make/parallel-rustc-no-overwrite/rmake.rs +++ b/tests/run-make/parallel-rustc-no-overwrite/rmake.rs @@ -10,15 +10,16 @@ use std::sync::{Arc, Barrier}; use std::thread; fn main() { + fs_wrapper::create_file("lib.rs"); let barrier = Arc::new(Barrier::new(2)); let handle = { let barrier = Arc::clone(&barrier); thread::spawn(move || { barrier.wait(); - rustc().crate_type("lib").arg("-Ztemps-dir=temp1").input("lib.rs"); + rustc().crate_type("lib").arg("-Ztemps-dir=temp1").input("lib.rs").run(); }) }; barrier.wait(); - rustc().crate_type("staticlib").arg("-Ztemps-dir=temp2").input("lib.rs"); + rustc().crate_type("staticlib").arg("-Ztemps-dir=temp2").input("lib.rs").run(); handle.join().expect("lib thread panicked"); }