From 8075c98745767467bbc63b6b9068fecd647bad76 Mon Sep 17 00:00:00 2001 From: Osama Abdelkader Date: Thu, 6 Nov 2025 23:59:21 +0200 Subject: [PATCH 1/2] Add test for success path Adds missing test coverage for rustdoc's `--test-builder` option. The existing test only covered the error case (non-executable builder). This PR adds: - A custom test builder that logs arguments and forwards to rustc - A test verifying that `--test-builder` successfully invokes the custom builder with rustc-style arguments - Improved comments explaining both the error and success test scenarios The test validates that custom builders can properly intercept and handle doctest compilation. Signed-off-by: Osama Abdelkader --- .../run-make/rustdoc-test-builder/builder.rs | 23 ++++++++++++ .../run-make/rustdoc-test-builder/doctest.rs | 3 ++ tests/run-make/rustdoc-test-builder/rmake.rs | 35 +++++++++++++++++-- 3 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 tests/run-make/rustdoc-test-builder/builder.rs create mode 100644 tests/run-make/rustdoc-test-builder/doctest.rs diff --git a/tests/run-make/rustdoc-test-builder/builder.rs b/tests/run-make/rustdoc-test-builder/builder.rs new file mode 100644 index 0000000000000..b5a2c8ae346ea --- /dev/null +++ b/tests/run-make/rustdoc-test-builder/builder.rs @@ -0,0 +1,23 @@ +use std::ffi::OsString; +use std::path::PathBuf; +use std::process::{self, Command}; +use std::{env, fs}; + +fn main() { + let args: Vec = env::args_os().collect(); + let log_path = env::var_os("BUILDER_LOG").map(PathBuf::from).expect("BUILDER_LOG must be set"); + let real_rustc = env::var_os("REAL_RUSTC").expect("REAL_RUSTC must be set"); + + let log_contents = + args.iter().skip(1).map(|arg| arg.to_string_lossy()).collect::>().join("\n"); + fs::write(&log_path, log_contents).expect("failed to write builder log"); + + let status = Command::new(real_rustc) + .args(args.iter().skip(1)) + .status() + .expect("failed to invoke real rustc"); + + if !status.success() { + process::exit(status.code().unwrap_or(1)); + } +} diff --git a/tests/run-make/rustdoc-test-builder/doctest.rs b/tests/run-make/rustdoc-test-builder/doctest.rs new file mode 100644 index 0000000000000..1a4ff6a2fdd76 --- /dev/null +++ b/tests/run-make/rustdoc-test-builder/doctest.rs @@ -0,0 +1,3 @@ +//! ```rust +//! assert_eq!(2 + 2, 4); +//! ``` diff --git a/tests/run-make/rustdoc-test-builder/rmake.rs b/tests/run-make/rustdoc-test-builder/rmake.rs index 9aa8143dc1dc4..75f1c16de0c3f 100644 --- a/tests/run-make/rustdoc-test-builder/rmake.rs +++ b/tests/run-make/rustdoc-test-builder/rmake.rs @@ -1,11 +1,14 @@ -// This test ensures that if the rustdoc test binary is not executable, it will -// gracefully fail and not panic. +// This test validates the `--test-builder` rustdoc option. +// It ensures that: +// 1. When the test-builder path points to a non-executable file, rustdoc gracefully fails +// 2. When the test-builder path points to a valid executable, it receives rustc arguments //@ needs-target-std -use run_make_support::{path, rfs, rustdoc}; +use run_make_support::{path, rfs, rustc, rustc_path, rustdoc}; fn main() { + // Test 1: Verify that a non-executable test-builder fails gracefully let absolute_path = path("foo.rs").canonicalize().expect("failed to get absolute path"); let output = rustdoc() .input("foo.rs") @@ -19,4 +22,30 @@ fn main() { output.assert_stdout_contains("Failed to spawn "); // ... and that we didn't panic. output.assert_not_ice(); + + // Test 2: Verify that a valid test-builder is invoked with correct arguments + // Build a custom test-builder that logs its arguments and forwards to rustc + let builder_bin = path("builder-bin"); + rustc().input("builder.rs").output(&builder_bin).run(); + + let log_path = path("builder.log"); + let _ = std::fs::remove_file(&log_path); + + // Run rustdoc with our custom test-builder + rustdoc() + .input("doctest.rs") + .arg("--test") + .arg("-Zunstable-options") + .arg("--test-builder") + .arg(&builder_bin) + .env("REAL_RUSTC", rustc_path()) + .env("BUILDER_LOG", &log_path) + .run(); + + // Verify the custom builder was invoked with rustc-style arguments + let log_contents = rfs::read_to_string(&log_path); + assert!( + log_contents.contains("--crate-type"), + "expected builder to receive rustc arguments, got:\n{log_contents}" + ); } From 09385f9201ed5bf93cdfe034f44cf1444cd41d45 Mon Sep 17 00:00:00 2001 From: Osama Abdelkader Date: Fri, 7 Nov 2025 16:30:25 +0200 Subject: [PATCH 2/2] use bare_rustc to keep host toolchain Signed-off-by: Osama Abdelkader --- tests/run-make/rustdoc-test-builder/rmake.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/run-make/rustdoc-test-builder/rmake.rs b/tests/run-make/rustdoc-test-builder/rmake.rs index 75f1c16de0c3f..cd537571cbd96 100644 --- a/tests/run-make/rustdoc-test-builder/rmake.rs +++ b/tests/run-make/rustdoc-test-builder/rmake.rs @@ -5,7 +5,7 @@ //@ needs-target-std -use run_make_support::{path, rfs, rustc, rustc_path, rustdoc}; +use run_make_support::{bare_rustc, path, rfs, rustc_path, rustdoc}; fn main() { // Test 1: Verify that a non-executable test-builder fails gracefully @@ -24,9 +24,10 @@ fn main() { output.assert_not_ice(); // Test 2: Verify that a valid test-builder is invoked with correct arguments - // Build a custom test-builder that logs its arguments and forwards to rustc + // Build a custom test-builder that logs its arguments and forwards to rustc. + // Use `bare_rustc` so we compile for the host architecture even in cross builds. let builder_bin = path("builder-bin"); - rustc().input("builder.rs").output(&builder_bin).run(); + bare_rustc().input("builder.rs").output(&builder_bin).run(); let log_path = path("builder.log"); let _ = std::fs::remove_file(&log_path);