From 3ade0b80d08884185b306325dedf29adf5cf525b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Wed, 19 Jun 2024 12:00:27 +0200 Subject: [PATCH] testscript: ignore result when interrupting background processes When an entire script runs and the end is reached, any background processes begun with a '&' command get interrupted or killed, depending on the platform and timeout, and we wait for them to finish. We also checked their resulting status code and failed if they didn't exit with a status code of 0. However, as explained in the comment, this would always fail on Windows, given that it doesn't have interrupt signals so we would kill directly, causing a "signal: killed" error. Worse, any failures here caused a `panic: fail now!` as that is how we bubble up errors when a script command is being run, but such panics were not being recovered once we reached the end of a script. Now that we don't check the result anymore here, the panics are gone. Fixes #228. Fixes #260. --- testscript/testdata/interrupt_implicit.txt | 4 ++++ testscript/testscript.go | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 testscript/testdata/interrupt_implicit.txt diff --git a/testscript/testdata/interrupt_implicit.txt b/testscript/testdata/interrupt_implicit.txt new file mode 100644 index 0000000..6ea1c39 --- /dev/null +++ b/testscript/testdata/interrupt_implicit.txt @@ -0,0 +1,4 @@ +# Let testscript stop signalcatcher at the end of the testscript. + +signalcatcher & +waitfile catchsignal diff --git a/testscript/testscript.go b/testscript/testscript.go index 360398f..1146050 100644 --- a/testscript/testscript.go +++ b/testscript/testscript.go @@ -651,7 +651,11 @@ func (ts *TestScript) run() { for _, bg := range ts.background { interruptProcess(bg.cmd.Process) } - ts.cmdWait(false, nil) + // On some platforms like Windows, we kill background commands directly + // as we can't send them an interrupt signal, so they always fail. + // Moreover, it's relatively common for a process to fail when interrupted. + // Once we've reached the end of the script, ignore the status of background commands. + ts.waitBackground(false) // If we reached here but we've failed (probably because ContinueOnError // was set), don't wipe the log and print "PASS".