From 4c56227bee9b3e918f6feaebc4769dbfc3dfe9b2 Mon Sep 17 00:00:00 2001 From: danggg Date: Sun, 23 Nov 2025 15:46:28 +0700 Subject: [PATCH] [nextest-runner] add verbose flag to display test command lines --- nextest-runner/src/list/test_list.rs | 30 ++++++++++++++++++++ nextest-runner/src/reporter/displayer/imp.rs | 15 ++++++++++ nextest-runner/src/reporter/events.rs | 3 ++ nextest-runner/src/reporter/imp.rs | 1 + nextest-runner/src/runner/dispatcher.rs | 2 ++ nextest-runner/src/runner/executor.rs | 14 +++++++++ nextest-runner/src/runner/internal_events.rs | 1 + 7 files changed, 66 insertions(+) diff --git a/nextest-runner/src/list/test_list.rs b/nextest-runner/src/list/test_list.rs index f250b08a896..195b4b01ffa 100644 --- a/nextest-runner/src/list/test_list.rs +++ b/nextest-runner/src/list/test_list.rs @@ -1182,6 +1182,36 @@ impl<'a> TestInstance<'a> { interceptor, ) } + + /// Returns the command line string for running this test. + pub(crate) fn command_line( + &self, + ctx: &TestExecuteContext<'_>, + test_list: &TestList<'_>, + wrapper_script: Option<&'a WrapperScriptConfig>, + extra_args: &[String], + ) -> String { + let platform_runner = ctx + .target_runner + .for_build_platform(self.suite_info.build_platform); + + let mut cli = TestCommandCli::default(); + cli.apply_wrappers( + wrapper_script, + platform_runner, + test_list.workspace_root(), + &test_list.rust_build_meta().target_directory, + ); + cli.push(self.suite_info.binary_path.as_str()); + + cli.extend(["--exact", self.name, "--nocapture"]); + if self.test_info.ignored { + cli.push("--ignored"); + } + cli.extend(extra_args.iter().map(String::as_str)); + + shell_words::join(cli.to_owned_cli()) + } } #[derive(Clone, Debug, Default)] diff --git a/nextest-runner/src/reporter/displayer/imp.rs b/nextest-runner/src/reporter/displayer/imp.rs index fc84ed316e1..a2519ccb4c5 100644 --- a/nextest-runner/src/reporter/displayer/imp.rs +++ b/nextest-runner/src/reporter/displayer/imp.rs @@ -54,6 +54,7 @@ pub(crate) struct DisplayReporterBuilder { pub(crate) failure_output: Option, pub(crate) should_colorize: bool, pub(crate) no_capture: bool, + pub(crate) verbose: bool, pub(crate) show_progress: ShowProgress, pub(crate) no_output_indent: bool, pub(crate) max_progress_running: MaxProgressRunning, @@ -141,6 +142,7 @@ impl DisplayReporterBuilder { final_status_level: self.status_levels.final_status_level, }, no_capture: self.no_capture, + verbose: self.verbose, no_output_indent: self.no_output_indent, counter_width, styles, @@ -377,6 +379,7 @@ struct DisplayReporterImpl<'a> { default_filter: CompiledDefaultFilter, status_levels: StatusLevels, no_capture: bool, + verbose: bool, no_output_indent: bool, // None if no counter is displayed. If a counter is displayed, this is the // width of the total number of tests to run. @@ -601,6 +604,7 @@ impl<'a> DisplayReporterImpl<'a> { stress_index, test_instance, current_stats, + command_line, .. } => { // In no-capture mode, print out a test start event. @@ -623,6 +627,15 @@ impl<'a> DisplayReporterImpl<'a> { ), )?; } + + if self.verbose { + writeln!( + writer, + "{:>12} {}", + "COMMAND".style(self.styles.count), + command_line, + )?; + } } TestEventKind::TestSlow { stress_index, @@ -2390,10 +2403,12 @@ mod tests { failure_output: Some(TestOutputDisplay::Immediate), should_colorize: false, no_capture: true, + verbose: false, show_progress: ShowProgress::Counter, no_output_indent: false, max_progress_running: MaxProgressRunning::default(), }; + let output = ReporterStderr::Buffer(out); let reporter = builder.build(&configs, output); f(reporter); diff --git a/nextest-runner/src/reporter/events.rs b/nextest-runner/src/reporter/events.rs index 50e2b285b4c..1d176e8221d 100644 --- a/nextest-runner/src/reporter/events.rs +++ b/nextest-runner/src/reporter/events.rs @@ -168,6 +168,9 @@ pub enum TestEventKind<'a> { /// The number of tests currently running, including this one. running: usize, + + /// The command line that will be used to run this test. + command_line: String, }, /// A test was slower than a configured soft timeout. diff --git a/nextest-runner/src/reporter/imp.rs b/nextest-runner/src/reporter/imp.rs index 8bf7e6cafbf..67c1c3a9790 100644 --- a/nextest-runner/src/reporter/imp.rs +++ b/nextest-runner/src/reporter/imp.rs @@ -148,6 +148,7 @@ impl ReporterBuilder { failure_output: self.failure_output, should_colorize: self.should_colorize, no_capture: self.no_capture, + verbose: self.verbose, show_progress: self.show_progress, no_output_indent: self.no_output_indent, max_progress_running: self.max_progress_running, diff --git a/nextest-runner/src/runner/dispatcher.rs b/nextest-runner/src/runner/dispatcher.rs index e6fd0b86ea9..d7827027a1f 100644 --- a/nextest-runner/src/runner/dispatcher.rs +++ b/nextest-runner/src/runner/dispatcher.rs @@ -656,6 +656,7 @@ where InternalEvent::Executor(ExecutorEvent::Started { stress_index, test_instance, + command_line, req_rx_tx, }) => { if self.run_stats.cancel_reason.is_some() { @@ -678,6 +679,7 @@ where test_instance, current_stats: self.run_stats, running: self.running_tests.len(), + command_line, }) } InternalEvent::Executor(ExecutorEvent::Slow { diff --git a/nextest-runner/src/runner/executor.rs b/nextest-runner/src/runner/executor.rs index 66e3bcf6aab..95021f686e3 100644 --- a/nextest-runner/src/runner/executor.rs +++ b/nextest-runner/src/runner/executor.rs @@ -210,11 +210,25 @@ impl<'a> ExecutorContext<'a> { let (req_rx_tx, req_rx_rx) = oneshot::channel(); + // Compute the command line for this test. + let ctx = TestExecuteContext { + profile_name: self.profile.name(), + double_spawn: &self.double_spawn, + target_runner: &self.target_runner, + }; + let command_line = test.instance.command_line( + &ctx, + self.test_list, + settings.run_wrapper(), + settings.run_extra_args(), + ); + // Wait for the Started event to be processed by the // execution future. _ = resp_tx.send(ExecutorEvent::Started { stress_index, test_instance: test.instance, + command_line, req_rx_tx, }); let mut req_rx = match req_rx_rx.await { diff --git a/nextest-runner/src/runner/internal_events.rs b/nextest-runner/src/runner/internal_events.rs index 18c18739894..73d04eb3dc7 100644 --- a/nextest-runner/src/runner/internal_events.rs +++ b/nextest-runner/src/runner/internal_events.rs @@ -69,6 +69,7 @@ pub(super) enum ExecutorEvent<'a> { Started { stress_index: Option, test_instance: TestInstance<'a>, + command_line: String, // The channel over which to return the unit request. // // The callback context is solely responsible for coordinating the