mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
os/signal: remove go t.Run from TestNohup
Since CL 226138, TestNohup has a bit of a strange construction: it wants to run the "uncaught" subtests in parallel with each other, and the "nohup" subtests in parallel with each other, but also needs join between "uncaught" and "nohop" so it can Stop notifying for SIGHUP. It achieves this by doing `go t.Run` with a WaitGroup rather than using `t.Parallel` in the subtest (which would make `t.Run` return immediately). However, this makes things more difficult to understand than necessary. As noted on https://pkg.go.dev/testing#hdr-Subtests_and_Sub_benchmarks, a second layer of subtest can be used to join parallel subtests. Switch to this form, which makes the test simpler to follow (particularly the cleanup that goes with "uncaught"). For #63799. Change-Id: Ibfce0f439508a7cfca848c7ccfd136c9c453ad8b Reviewed-on: https://go-review.googlesource.com/c/go/+/538899 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Bryan Mills <bcmills@google.com>
This commit is contained in:
parent
cfe36fd122
commit
5622a4b205
1 changed files with 77 additions and 79 deletions
|
|
@ -408,12 +408,6 @@ func TestStop(t *testing.T) {
|
|||
|
||||
// Test that when run under nohup, an uncaught SIGHUP does not kill the program.
|
||||
func TestNohup(t *testing.T) {
|
||||
// Ugly: ask for SIGHUP so that child will not have no-hup set
|
||||
// even if test is running under nohup environment.
|
||||
// We have no intention of reading from c.
|
||||
c := make(chan os.Signal, 1)
|
||||
Notify(c, syscall.SIGHUP)
|
||||
|
||||
// When run without nohup, the test should crash on an uncaught SIGHUP.
|
||||
// When run under nohup, the test should ignore uncaught SIGHUPs,
|
||||
// because the runtime is not supposed to be listening for them.
|
||||
|
|
@ -425,88 +419,92 @@ func TestNohup(t *testing.T) {
|
|||
//
|
||||
// Both should fail without nohup and succeed with nohup.
|
||||
|
||||
var subTimeout time.Duration
|
||||
t.Run("uncaught", func(t *testing.T) {
|
||||
// Ugly: ask for SIGHUP so that child will not have no-hup set
|
||||
// even if test is running under nohup environment.
|
||||
// We have no intention of reading from c.
|
||||
c := make(chan os.Signal, 1)
|
||||
Notify(c, syscall.SIGHUP)
|
||||
t.Cleanup(func() { Stop(c) })
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
if deadline, ok := t.Deadline(); ok {
|
||||
subTimeout = time.Until(deadline)
|
||||
subTimeout -= subTimeout / 10 // Leave 10% headroom for propagating output.
|
||||
}
|
||||
for i := 1; i <= 2; i++ {
|
||||
i := i
|
||||
go t.Run(fmt.Sprintf("uncaught-%d", i), func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
var subTimeout time.Duration
|
||||
if deadline, ok := t.Deadline(); ok {
|
||||
subTimeout = time.Until(deadline)
|
||||
subTimeout -= subTimeout / 10 // Leave 10% headroom for propagating output.
|
||||
}
|
||||
for i := 1; i <= 2; i++ {
|
||||
i := i
|
||||
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
args := []string{
|
||||
"-test.v",
|
||||
"-test.run=^TestStop$",
|
||||
"-send_uncaught_sighup=" + strconv.Itoa(i),
|
||||
"-die_from_sighup",
|
||||
}
|
||||
if subTimeout != 0 {
|
||||
args = append(args, fmt.Sprintf("-test.timeout=%v", subTimeout))
|
||||
}
|
||||
out, err := testenv.Command(t, os.Args[0], args...).CombinedOutput()
|
||||
args := []string{
|
||||
"-test.v",
|
||||
"-test.run=^TestStop$",
|
||||
"-send_uncaught_sighup=" + strconv.Itoa(i),
|
||||
"-die_from_sighup",
|
||||
}
|
||||
if subTimeout != 0 {
|
||||
args = append(args, fmt.Sprintf("-test.timeout=%v", subTimeout))
|
||||
}
|
||||
out, err := testenv.Command(t, os.Args[0], args...).CombinedOutput()
|
||||
|
||||
if err == nil {
|
||||
t.Errorf("ran test with -send_uncaught_sighup=%d and it succeeded: expected failure.\nOutput:\n%s", i, out)
|
||||
} else {
|
||||
t.Logf("test with -send_uncaught_sighup=%d failed as expected.\nError: %v\nOutput:\n%s", i, err, out)
|
||||
}
|
||||
})
|
||||
}
|
||||
wg.Wait()
|
||||
if err == nil {
|
||||
t.Errorf("ran test with -send_uncaught_sighup=%d and it succeeded: expected failure.\nOutput:\n%s", i, out)
|
||||
} else {
|
||||
t.Logf("test with -send_uncaught_sighup=%d failed as expected.\nError: %v\nOutput:\n%s", i, err, out)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
Stop(c)
|
||||
t.Run("nohup", func(t *testing.T) {
|
||||
// Skip the nohup test below when running in tmux on darwin, since nohup
|
||||
// doesn't work correctly there. See issue #5135.
|
||||
if runtime.GOOS == "darwin" && os.Getenv("TMUX") != "" {
|
||||
t.Skip("Skipping nohup test due to running in tmux on darwin")
|
||||
}
|
||||
|
||||
// Skip the nohup test below when running in tmux on darwin, since nohup
|
||||
// doesn't work correctly there. See issue #5135.
|
||||
if runtime.GOOS == "darwin" && os.Getenv("TMUX") != "" {
|
||||
t.Skip("Skipping nohup test due to running in tmux on darwin")
|
||||
}
|
||||
// Again, this time with nohup, assuming we can find it.
|
||||
_, err := exec.LookPath("nohup")
|
||||
if err != nil {
|
||||
t.Skip("cannot find nohup; skipping second half of test")
|
||||
}
|
||||
|
||||
// Again, this time with nohup, assuming we can find it.
|
||||
_, err := exec.LookPath("nohup")
|
||||
if err != nil {
|
||||
t.Skip("cannot find nohup; skipping second half of test")
|
||||
}
|
||||
var subTimeout time.Duration
|
||||
if deadline, ok := t.Deadline(); ok {
|
||||
subTimeout = time.Until(deadline)
|
||||
subTimeout -= subTimeout / 10 // Leave 10% headroom for propagating output.
|
||||
}
|
||||
for i := 1; i <= 2; i++ {
|
||||
i := i
|
||||
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
wg.Add(2)
|
||||
if deadline, ok := t.Deadline(); ok {
|
||||
subTimeout = time.Until(deadline)
|
||||
subTimeout -= subTimeout / 10 // Leave 10% headroom for propagating output.
|
||||
}
|
||||
for i := 1; i <= 2; i++ {
|
||||
i := i
|
||||
go t.Run(fmt.Sprintf("nohup-%d", i), func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
// POSIX specifies that nohup writes to a file named nohup.out if standard
|
||||
// output is a terminal. However, for an exec.Cmd, standard output is
|
||||
// not a terminal — so we don't need to read or remove that file (and,
|
||||
// indeed, cannot even create it if the current user is unable to write to
|
||||
// GOROOT/src, such as when GOROOT is installed and owned by root).
|
||||
|
||||
// POSIX specifies that nohup writes to a file named nohup.out if standard
|
||||
// output is a terminal. However, for an exec.Cmd, standard output is
|
||||
// not a terminal — so we don't need to read or remove that file (and,
|
||||
// indeed, cannot even create it if the current user is unable to write to
|
||||
// GOROOT/src, such as when GOROOT is installed and owned by root).
|
||||
args := []string{
|
||||
os.Args[0],
|
||||
"-test.v",
|
||||
"-test.run=^TestStop$",
|
||||
"-send_uncaught_sighup=" + strconv.Itoa(i),
|
||||
}
|
||||
if subTimeout != 0 {
|
||||
args = append(args, fmt.Sprintf("-test.timeout=%v", subTimeout))
|
||||
}
|
||||
out, err := testenv.Command(t, "nohup", args...).CombinedOutput()
|
||||
|
||||
args := []string{
|
||||
os.Args[0],
|
||||
"-test.v",
|
||||
"-test.run=^TestStop$",
|
||||
"-send_uncaught_sighup=" + strconv.Itoa(i),
|
||||
}
|
||||
if subTimeout != 0 {
|
||||
args = append(args, fmt.Sprintf("-test.timeout=%v", subTimeout))
|
||||
}
|
||||
out, err := testenv.Command(t, "nohup", args...).CombinedOutput()
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("ran test with -send_uncaught_sighup=%d under nohup and it failed: expected success.\nError: %v\nOutput:\n%s", i, err, out)
|
||||
} else {
|
||||
t.Logf("ran test with -send_uncaught_sighup=%d under nohup.\nOutput:\n%s", i, out)
|
||||
}
|
||||
})
|
||||
}
|
||||
wg.Wait()
|
||||
if err != nil {
|
||||
t.Errorf("ran test with -send_uncaught_sighup=%d under nohup and it failed: expected success.\nError: %v\nOutput:\n%s", i, err, out)
|
||||
} else {
|
||||
t.Logf("ran test with -send_uncaught_sighup=%d under nohup.\nOutput:\n%s", i, out)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Test that SIGCONT works (issue 8953).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue