From 521bdf2d55a7223028dac5e28903907b7de4af29 Mon Sep 17 00:00:00 2001 From: xxchan Date: Wed, 17 Apr 2024 17:13:21 +0800 Subject: [PATCH] fix the behavior of background `system` commands Signed-off-by: xxchan --- CHANGELOG.md | 5 +++++ sqllogictest/src/runner.rs | 30 +++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f21434..c959cae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * bin: When using `-j ` to run tests in parallel, add a random suffix to the temporary databases. This is useful if the test is manually canceled, but you want to rerun it freshly. Note that if the test failed, the database will be dropped. This is existing behavior and unchanged. * bin: replace `env_logger` with `tracing-subscriber`. You will be able to see the record being executed with `RUST_LOG=debug sqllogictest ...`. +* runner: fix the behavior of background `system` commands (end with `&`). In `0.20.0`, it will block until the process exits. Now we return immediately. + ``` + system ok + sleep 5 & + ``` ## [0.20.0] - 2024-04-08 diff --git a/sqllogictest/src/runner.rs b/sqllogictest/src/runner.rs index 6b02818..8942562 100644 --- a/sqllogictest/src/runner.rs +++ b/sqllogictest/src/runner.rs @@ -619,7 +619,11 @@ impl> Runner { loc: _, stdout: expected_stdout, } => { - let command = match self.may_substitute(command) { + if should_skip(&self.labels, "", &conditions) { + return RecordOutput::Nothing; + } + + let mut command = match self.may_substitute(command) { Ok(command) => command, Err(error) => { return RecordOutput::System { @@ -629,8 +633,14 @@ impl> Runner { } }; - if should_skip(&self.labels, "", &conditions) { - return RecordOutput::Nothing; + let is_background = command + .trim() + .chars() + .last() + .expect("system command is emptry") + == '&'; + if is_background { + command = command.trim_end_matches('&').trim().to_string(); } let mut cmd = if cfg!(target_os = "windows") { @@ -642,8 +652,22 @@ impl> Runner { cmd.arg("-c").arg(command); cmd }; + + if is_background { + // Spawn a new process, but don't wait for stdout, otherwise it will block until the process exits. + let error: Option = match cmd.spawn() { + Ok(_) => None, + Err(e) => Some(Arc::new(e)), + }; + return RecordOutput::System { + error, + stdout: None, + }; + } + cmd.stdout(std::process::Stdio::piped()); cmd.stderr(std::process::Stdio::piped()); + let result = D::run_command(cmd).await; #[derive(thiserror::Error, Debug)] #[error(