1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // +build darwin freebsd linux netbsd openbsd
21 func waitSig(t
*testing
.T
, c
<-chan os
.Signal
, sig os
.Signal
) {
25 t
.Fatalf("signal was %v, want %v", s
, sig
)
27 case <-time
.After(1 * time
.Second
):
28 t
.Fatalf("timeout waiting for %v", sig
)
32 // Test that basic signal handling works.
33 func TestSignal(t
*testing
.T
) {
35 c
:= make(chan os
.Signal
, 1)
36 Notify(c
, syscall
.SIGHUP
)
40 // Send this process a SIGHUP
41 syscall
.Kill(syscall
.Getpid(), syscall
.SIGHUP
)
42 waitSig(t
, c
, syscall
.SIGHUP
)
44 // Ask for everything we can get.
45 c1
:= make(chan os
.Signal
, 1)
49 // Send this process a SIGWINCH
50 syscall
.Kill(syscall
.Getpid(), syscall
.SIGWINCH
)
51 waitSig(t
, c1
, syscall
.SIGWINCH
)
53 // Send two more SIGHUPs, to make sure that
54 // they get delivered on c1 and that not reading
55 // from c does not block everything.
57 syscall
.Kill(syscall
.Getpid(), syscall
.SIGHUP
)
58 waitSig(t
, c1
, syscall
.SIGHUP
)
60 syscall
.Kill(syscall
.Getpid(), syscall
.SIGHUP
)
61 waitSig(t
, c1
, syscall
.SIGHUP
)
63 // The first SIGHUP should be waiting for us on c.
64 waitSig(t
, c
, syscall
.SIGHUP
)
67 func TestStress(t
*testing
.T
) {
68 dur
:= 3 * time
.Second
70 dur
= 100 * time
.Millisecond
72 defer runtime
.GOMAXPROCS(runtime
.GOMAXPROCS(4))
73 done
:= make(chan bool)
74 finished
:= make(chan bool)
76 sig
:= make(chan os
.Signal
, 1)
77 Notify(sig
, syscall
.SIGUSR1
)
96 syscall
.Kill(syscall
.Getpid(), syscall
.SIGUSR1
)
106 // When run with 'go test -cpu=1,2,4' SIGUSR1 from this test can slip
107 // into subsequent TestSignal() causing failure.
108 // Sleep for a while to reduce the possibility of the failure.
109 time
.Sleep(10 * time
.Millisecond
)
112 var sendUncaughtSighup
= flag
.Int("send_uncaught_sighup", 0, "send uncaught SIGHUP during TestStop")
114 // Test that Stop cancels the channel's registrations.
115 func TestStop(t
*testing
.T
) {
116 sigs
:= []syscall
.Signal
{
121 for _
, sig
:= range sigs
{
123 // If it's SIGWINCH, we should not see it.
124 // If it's SIGHUP, maybe we'll die. Let the flag tell us what to do.
125 if sig
!= syscall
.SIGHUP ||
*sendUncaughtSighup
== 1 {
126 syscall
.Kill(syscall
.Getpid(), sig
)
128 time
.Sleep(10 * time
.Millisecond
)
131 c
:= make(chan os
.Signal
, 1)
135 // Send this process that signal
136 syscall
.Kill(syscall
.Getpid(), sig
)
142 t
.Fatalf("unexpected signal %v", s
)
143 case <-time
.After(10 * time
.Millisecond
):
144 // nothing to read - good
148 // If it's SIGWINCH, we should not see it.
149 // If it's SIGHUP, maybe we'll die. Let the flag tell us what to do.
150 if sig
!= syscall
.SIGHUP ||
*sendUncaughtSighup
== 2 {
151 syscall
.Kill(syscall
.Getpid(), sig
)
156 t
.Fatalf("unexpected signal %v", s
)
157 case <-time
.After(10 * time
.Millisecond
):
158 // nothing to read - good
163 // Test that when run under nohup, an uncaught SIGHUP does not kill the program,
165 func TestNohup(t
*testing
.T
) {
166 // Ugly: ask for SIGHUP so that child will not have no-hup set
167 // even if test is running under nohup environment.
168 // We have no intention of reading from c.
169 c
:= make(chan os
.Signal
, 1)
170 Notify(c
, syscall
.SIGHUP
)
172 // When run without nohup, the test should crash on an uncaught SIGHUP.
173 // When run under nohup, the test should ignore uncaught SIGHUPs,
174 // because the runtime is not supposed to be listening for them.
175 // Either way, TestStop should still be able to catch them when it wants them
176 // and then when it stops wanting them, the original behavior should resume.
178 // send_uncaught_sighup=1 sends the SIGHUP before starting to listen for SIGHUPs.
179 // send_uncaught_sighup=2 sends the SIGHUP after no longer listening for SIGHUPs.
181 // Both should fail without nohup and succeed with nohup.
183 for i
:= 1; i
<= 2; i
++ {
184 out
, err
:= exec
.Command(os
.Args
[0], "-test.run=TestStop", "-send_uncaught_sighup="+strconv
.Itoa(i
)).CombinedOutput()
186 t
.Fatalf("ran test with -send_uncaught_sighup=%d and it succeeded: expected failure.\nOutput:\n%s", i
, out
)
192 // Again, this time with nohup, assuming we can find it.
193 _
, err
:= os
.Stat("/usr/bin/nohup")
195 t
.Skip("cannot find nohup; skipping second half of test")
198 for i
:= 1; i
<= 2; i
++ {
199 os
.Remove("nohup.out")
200 out
, err
:= exec
.Command("/usr/bin/nohup", os
.Args
[0], "-test.run=TestStop", "-send_uncaught_sighup="+strconv
.Itoa(i
)).CombinedOutput()
202 data
, _
:= ioutil
.ReadFile("nohup.out")
203 os
.Remove("nohup.out")
205 t
.Fatalf("ran test with -send_uncaught_sighup=%d under nohup and it failed: expected success.\nError: %v\nOutput:\n%s%s", i
, err
, out
, data
)