~ubuntu-branches/ubuntu/vivid/golang/vivid

« back to all changes in this revision

Viewing changes to src/pkg/os/signal/signal_test.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
package signal
8
8
 
9
9
import (
 
10
        "flag"
 
11
        "io/ioutil"
10
12
        "os"
 
13
        "os/exec"
 
14
        "runtime"
 
15
        "strconv"
11
16
        "syscall"
12
17
        "testing"
13
18
        "time"
14
19
)
15
20
 
16
 
const sighup = syscall.SIGHUP
17
 
 
18
21
func waitSig(t *testing.T, c <-chan os.Signal, sig os.Signal) {
19
22
        select {
20
23
        case s := <-c:
26
29
        }
27
30
}
28
31
 
 
32
// Test that basic signal handling works.
29
33
func TestSignal(t *testing.T) {
30
34
        // Ask for SIGHUP
31
35
        c := make(chan os.Signal, 1)
32
 
        Notify(c, sighup)
 
36
        Notify(c, syscall.SIGHUP)
 
37
        defer Stop(c)
33
38
 
34
39
        t.Logf("sighup...")
35
40
        // Send this process a SIGHUP
36
 
        syscall.Kill(syscall.Getpid(), sighup)
37
 
        waitSig(t, c, sighup)
 
41
        syscall.Kill(syscall.Getpid(), syscall.SIGHUP)
 
42
        waitSig(t, c, syscall.SIGHUP)
38
43
 
39
44
        // Ask for everything we can get.
40
45
        c1 := make(chan os.Signal, 1)
58
63
        // The first SIGHUP should be waiting for us on c.
59
64
        waitSig(t, c, syscall.SIGHUP)
60
65
}
 
66
 
 
67
func TestStress(t *testing.T) {
 
68
        dur := 3 * time.Second
 
69
        if testing.Short() {
 
70
                dur = 100 * time.Millisecond
 
71
        }
 
72
        defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
 
73
        done := make(chan bool)
 
74
        finished := make(chan bool)
 
75
        go func() {
 
76
                sig := make(chan os.Signal, 1)
 
77
                Notify(sig, syscall.SIGUSR1)
 
78
                defer Stop(sig)
 
79
        Loop:
 
80
                for {
 
81
                        select {
 
82
                        case <-sig:
 
83
                        case <-done:
 
84
                                break Loop
 
85
                        }
 
86
                }
 
87
                finished <- true
 
88
        }()
 
89
        go func() {
 
90
        Loop:
 
91
                for {
 
92
                        select {
 
93
                        case <-done:
 
94
                                break Loop
 
95
                        default:
 
96
                                syscall.Kill(syscall.Getpid(), syscall.SIGUSR1)
 
97
                                runtime.Gosched()
 
98
                        }
 
99
                }
 
100
                finished <- true
 
101
        }()
 
102
        time.Sleep(dur)
 
103
        close(done)
 
104
        <-finished
 
105
        <-finished
 
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)
 
110
}
 
111
 
 
112
var sendUncaughtSighup = flag.Int("send_uncaught_sighup", 0, "send uncaught SIGHUP during TestStop")
 
113
 
 
114
// Test that Stop cancels the channel's registrations.
 
115
func TestStop(t *testing.T) {
 
116
        sigs := []syscall.Signal{
 
117
                syscall.SIGWINCH,
 
118
                syscall.SIGHUP,
 
119
        }
 
120
 
 
121
        for _, sig := range sigs {
 
122
                // Send the signal.
 
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)
 
127
                }
 
128
                time.Sleep(10 * time.Millisecond)
 
129
 
 
130
                // Ask for signal
 
131
                c := make(chan os.Signal, 1)
 
132
                Notify(c, sig)
 
133
                defer Stop(c)
 
134
 
 
135
                // Send this process that signal
 
136
                syscall.Kill(syscall.Getpid(), sig)
 
137
                waitSig(t, c, sig)
 
138
 
 
139
                Stop(c)
 
140
                select {
 
141
                case s := <-c:
 
142
                        t.Fatalf("unexpected signal %v", s)
 
143
                case <-time.After(10 * time.Millisecond):
 
144
                        // nothing to read - good
 
145
                }
 
146
 
 
147
                // Send the signal.
 
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)
 
152
                }
 
153
 
 
154
                select {
 
155
                case s := <-c:
 
156
                        t.Fatalf("unexpected signal %v", s)
 
157
                case <-time.After(10 * time.Millisecond):
 
158
                        // nothing to read - good
 
159
                }
 
160
        }
 
161
}
 
162
 
 
163
// Test that when run under nohup, an uncaught SIGHUP does not kill the program,
 
164
// but a
 
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)
 
171
 
 
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.
 
177
        //
 
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.
 
180
        //
 
181
        // Both should fail without nohup and succeed with nohup.
 
182
 
 
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()
 
185
                if err == nil {
 
186
                        t.Fatalf("ran test with -send_uncaught_sighup=%d and it succeeded: expected failure.\nOutput:\n%s", i, out)
 
187
                }
 
188
        }
 
189
 
 
190
        Stop(c)
 
191
 
 
192
        // Again, this time with nohup, assuming we can find it.
 
193
        _, err := os.Stat("/usr/bin/nohup")
 
194
        if err != nil {
 
195
                t.Skip("cannot find nohup; skipping second half of test")
 
196
        }
 
197
 
 
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()
 
201
 
 
202
                data, _ := ioutil.ReadFile("nohup.out")
 
203
                os.Remove("nohup.out")
 
204
                if err != nil {
 
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)
 
206
                }
 
207
        }
 
208
}