Dispose subprocess descendants after leader exit
This commit is contained in:
@@ -6,10 +6,12 @@ import (
|
||||
"errors"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -747,6 +749,41 @@ func TestSubprocessHelper(t *testing.T) {
|
||||
}
|
||||
time.Sleep(10 * time.Second)
|
||||
os.Exit(0)
|
||||
case "leader-exit-retained", "leader-exit-redirected", "leader-fail-redirected":
|
||||
descendant := exec.Command(os.Args[0], "-test.run=^TestSubprocessHelper$", "--", "descendant-after-release")
|
||||
descendant.Env = append(os.Environ(), "GO_WANT_SUBPROCESS_HELPER=1")
|
||||
if mode == "leader-exit-retained" {
|
||||
descendant.Stdout = os.Stdout
|
||||
descendant.Stderr = os.Stderr
|
||||
}
|
||||
if err := descendant.Start(); err != nil {
|
||||
os.Exit(3)
|
||||
}
|
||||
if !helperFileAppeared(os.Getenv("SUBPROCESS_HELPER_READY_PATH"), 2*time.Second) {
|
||||
os.Exit(4)
|
||||
}
|
||||
if mode == "leader-fail-redirected" {
|
||||
os.Exit(9)
|
||||
}
|
||||
os.Exit(0)
|
||||
case "descendant-after-release":
|
||||
if os.Getenv("SUBPROCESS_HELPER_IGNORE_TERM") == "1" {
|
||||
signal.Ignore(syscall.SIGTERM)
|
||||
}
|
||||
if err := os.WriteFile(os.Getenv("SUBPROCESS_HELPER_READY_PATH"), []byte("ready"), 0o600); err != nil {
|
||||
os.Exit(4)
|
||||
}
|
||||
deadline := time.Now().Add(10 * time.Second)
|
||||
for time.Now().Before(deadline) {
|
||||
if _, err := os.Stat(os.Getenv("SUBPROCESS_HELPER_RELEASE_PATH")); err == nil {
|
||||
_ = os.WriteFile(os.Getenv("SUBPROCESS_HELPER_SENTINEL_PATH"), []byte("survived"), 0o600)
|
||||
os.Exit(0)
|
||||
} else if !errors.Is(err, os.ErrNotExist) {
|
||||
os.Exit(5)
|
||||
}
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
os.Exit(0)
|
||||
case "descendant":
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
_ = os.WriteFile(os.Getenv("SUBPROCESS_HELPER_SENTINEL_PATH"), []byte("survived"), 0o600)
|
||||
@@ -770,3 +807,16 @@ func waitForHelperFile(t *testing.T, path string) {
|
||||
}
|
||||
t.Fatalf("helper file %q was not created", path)
|
||||
}
|
||||
|
||||
func helperFileAppeared(path string, timeout time.Duration) bool {
|
||||
deadline := time.Now().Add(timeout)
|
||||
for time.Now().Before(deadline) {
|
||||
if _, err := os.Stat(path); err == nil {
|
||||
return true
|
||||
} else if !errors.Is(err, os.ErrNotExist) {
|
||||
return false
|
||||
}
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user