github.com/AndrienkoAleksandr/go@v0.0.19/src/os/signal/signal_plan9_test.go (about) 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. 4 5 package signal 6 7 import ( 8 "internal/itoa" 9 "os" 10 "runtime" 11 "syscall" 12 "testing" 13 "time" 14 ) 15 16 func waitSig(t *testing.T, c <-chan os.Signal, sig os.Signal) { 17 select { 18 case s := <-c: 19 if s != sig { 20 t.Fatalf("signal was %v, want %v", s, sig) 21 } 22 case <-time.After(1 * time.Second): 23 t.Fatalf("timeout waiting for %v", sig) 24 } 25 } 26 27 // Test that basic signal handling works. 28 func TestSignal(t *testing.T) { 29 // Ask for hangup 30 c := make(chan os.Signal, 1) 31 Notify(c, syscall.Note("hangup")) 32 defer Stop(c) 33 34 // Send this process a hangup 35 t.Logf("hangup...") 36 postNote(syscall.Getpid(), "hangup") 37 waitSig(t, c, syscall.Note("hangup")) 38 39 // Ask for everything we can get. 40 c1 := make(chan os.Signal, 1) 41 Notify(c1) 42 43 // Send this process an alarm 44 t.Logf("alarm...") 45 postNote(syscall.Getpid(), "alarm") 46 waitSig(t, c1, syscall.Note("alarm")) 47 48 // Send two more hangups, to make sure that 49 // they get delivered on c1 and that not reading 50 // from c does not block everything. 51 t.Logf("hangup...") 52 postNote(syscall.Getpid(), "hangup") 53 waitSig(t, c1, syscall.Note("hangup")) 54 t.Logf("hangup...") 55 postNote(syscall.Getpid(), "hangup") 56 waitSig(t, c1, syscall.Note("hangup")) 57 58 // The first SIGHUP should be waiting for us on c. 59 waitSig(t, c, syscall.Note("hangup")) 60 } 61 62 func TestStress(t *testing.T) { 63 dur := 3 * time.Second 64 if testing.Short() { 65 dur = 100 * time.Millisecond 66 } 67 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) 68 done := make(chan bool) 69 finished := make(chan bool) 70 go func() { 71 sig := make(chan os.Signal, 1) 72 Notify(sig, syscall.Note("alarm")) 73 defer Stop(sig) 74 Loop: 75 for { 76 select { 77 case <-sig: 78 case <-done: 79 break Loop 80 } 81 } 82 finished <- true 83 }() 84 go func() { 85 Loop: 86 for { 87 select { 88 case <-done: 89 break Loop 90 default: 91 postNote(syscall.Getpid(), "alarm") 92 runtime.Gosched() 93 } 94 } 95 finished <- true 96 }() 97 time.Sleep(dur) 98 close(done) 99 <-finished 100 <-finished 101 // When run with 'go test -cpu=1,2,4' alarm from this test can slip 102 // into subsequent TestSignal() causing failure. 103 // Sleep for a while to reduce the possibility of the failure. 104 time.Sleep(10 * time.Millisecond) 105 } 106 107 // Test that Stop cancels the channel's registrations. 108 func TestStop(t *testing.T) { 109 if testing.Short() { 110 t.Skip("skipping in short mode") 111 } 112 sigs := []string{ 113 "alarm", 114 "hangup", 115 } 116 117 for _, sig := range sigs { 118 // Send the signal. 119 // If it's alarm, we should not see it. 120 // If it's hangup, maybe we'll die. Let the flag tell us what to do. 121 if sig != "hangup" { 122 postNote(syscall.Getpid(), sig) 123 } 124 time.Sleep(100 * time.Millisecond) 125 126 // Ask for signal 127 c := make(chan os.Signal, 1) 128 Notify(c, syscall.Note(sig)) 129 defer Stop(c) 130 131 // Send this process that signal 132 postNote(syscall.Getpid(), sig) 133 waitSig(t, c, syscall.Note(sig)) 134 135 Stop(c) 136 select { 137 case s := <-c: 138 t.Fatalf("unexpected signal %v", s) 139 case <-time.After(100 * time.Millisecond): 140 // nothing to read - good 141 } 142 143 // Send the signal. 144 // If it's alarm, we should not see it. 145 // If it's hangup, maybe we'll die. Let the flag tell us what to do. 146 if sig != "hangup" { 147 postNote(syscall.Getpid(), sig) 148 } 149 150 select { 151 case s := <-c: 152 t.Fatalf("unexpected signal %v", s) 153 case <-time.After(100 * time.Millisecond): 154 // nothing to read - good 155 } 156 } 157 } 158 159 func postNote(pid int, note string) error { 160 f, err := os.OpenFile("/proc/"+itoa.Itoa(pid)+"/note", os.O_WRONLY, 0) 161 if err != nil { 162 return err 163 } 164 defer f.Close() 165 _, err = f.Write([]byte(note)) 166 return err 167 }