From f4e13b2b81bc59fb564bf481ac708cf204d983e5 Mon Sep 17 00:00:00 2001 From: not-matthias Date: Mon, 10 Nov 2025 12:41:46 +0100 Subject: [PATCH 1/2] fix(walltime): ensure working directory is used when running the cmd --- src/run/runner/helpers/command.rs | 4 ++++ src/run/runner/tests.rs | 31 ++++++++++++++++++++++++++++ src/run/runner/wall_time/perf/mod.rs | 6 ++++++ 3 files changed, 41 insertions(+) diff --git a/src/run/runner/helpers/command.rs b/src/run/runner/helpers/command.rs index 4dbc5364..abd7dd8b 100644 --- a/src/run/runner/helpers/command.rs +++ b/src/run/runner/helpers/command.rs @@ -55,6 +55,10 @@ impl CommandBuilder { self.cwd = Some(dir.as_ref().to_owned()); } + pub fn get_current_dir(&self) -> Option<&OsStr> { + self.cwd.as_deref() + } + pub fn wrap(&mut self, wrapper: S, wrapper_args: I) -> &mut Self where S: AsRef, diff --git a/src/run/runner/tests.rs b/src/run/runner/tests.rs index 8b31a9e5..c9ffaa6e 100644 --- a/src/run/runner/tests.rs +++ b/src/run/runner/tests.rs @@ -254,4 +254,35 @@ mod walltime { }) .await; } + + // Ensure that the working directory is used correctly + #[rstest::rstest] + #[tokio::test] + async fn test_walltime_executor_in_working_dir(#[values(false, true)] enable_perf: bool) { + let (system_info, run_data, _temp_dir) = create_test_setup().await; + let (_permit, executor) = get_walltime_executor().await; + + let cmd = r#" +if [ "$(basename "$(pwd)")" != "within_sub_directory" ]; then + echo "FAIL: Working directory is not 'within_sub_directory'" + exit 1 +fi +"#; + + let mut config = walltime_config(cmd, enable_perf); + + let dir = TempDir::new().unwrap(); + config.working_directory = Some( + dir.path() + .join("within_sub_directory") + .to_string_lossy() + .to_string(), + ); + std::fs::create_dir_all(config.working_directory.as_ref().unwrap()).unwrap(); + + executor + .run(&config, &system_info, &run_data, &None) + .await + .unwrap(); + } } diff --git a/src/run/runner/wall_time/perf/mod.rs b/src/run/runner/wall_time/perf/mod.rs index 844688e8..ac6fd778 100644 --- a/src/run/runner/wall_time/perf/mod.rs +++ b/src/run/runner/wall_time/perf/mod.rs @@ -156,6 +156,12 @@ impl PerfRunner { ); let mut wrapped_builder = CommandBuilder::new("sh"); wrapped_builder.args(["-c", &raw_command]); + + // IMPORTANT: Preserve the working directory from the original command + if let Some(cwd) = cmd_builder.get_current_dir() { + wrapped_builder.current_dir(cwd); + } + let cmd = wrap_with_sudo(wrapped_builder)?.build(); debug!("cmd: {cmd:?}"); From 3bf0cff959c170e53ab538ae6e56380756b4d687 Mon Sep 17 00:00:00 2001 From: not-matthias Date: Mon, 10 Nov 2025 12:48:34 +0100 Subject: [PATCH 2/2] fix(walltime): ensure perf also fails when the command fails --- src/run/runner/tests.rs | 12 ++++++++++++ src/run/runner/wall_time/perf/mod.rs | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/run/runner/tests.rs b/src/run/runner/tests.rs index c9ffaa6e..5dd895bf 100644 --- a/src/run/runner/tests.rs +++ b/src/run/runner/tests.rs @@ -285,4 +285,16 @@ fi .await .unwrap(); } + + // Ensure that commands that fail actually fail + #[rstest::rstest] + #[tokio::test] + async fn test_walltime_executor_fails(#[values(false, true)] enable_perf: bool) { + let (system_info, run_data, _temp_dir) = create_test_setup().await; + let (_permit, executor) = get_walltime_executor().await; + + let config = walltime_config("exit 1", enable_perf); + let result = executor.run(&config, &system_info, &run_data, &None).await; + assert!(result.is_err(), "Command should fail"); + } } diff --git a/src/run/runner/wall_time/perf/mod.rs b/src/run/runner/wall_time/perf/mod.rs index ac6fd778..7e4c8220 100644 --- a/src/run/runner/wall_time/perf/mod.rs +++ b/src/run/runner/wall_time/perf/mod.rs @@ -150,11 +150,11 @@ impl PerfRunner { let perf_data_file_path = profile_folder.join(PERF_DATA_FILE_NAME); let raw_command = format!( - "{} | cat > {}", + "set -o pipefail && {} | cat > {}", &cmd_builder.as_command_line(), perf_data_file_path.to_string_lossy() ); - let mut wrapped_builder = CommandBuilder::new("sh"); + let mut wrapped_builder = CommandBuilder::new("bash"); wrapped_builder.args(["-c", &raw_command]); // IMPORTANT: Preserve the working directory from the original command