diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:14:23 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:14:23 +0000 |
commit | 73df946d56c74384511a194dd01dbe099584fd1a (patch) | |
tree | fd0bcea490dd81327ddfbb31e215439672c9a068 /src/os/signal/signal_plan9_test.go | |
parent | Initial commit. (diff) | |
download | golang-1.16-upstream.tar.xz golang-1.16-upstream.zip |
Adding upstream version 1.16.10.upstream/1.16.10upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/os/signal/signal_plan9_test.go')
-rw-r--r-- | src/os/signal/signal_plan9_test.go | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/src/os/signal/signal_plan9_test.go b/src/os/signal/signal_plan9_test.go new file mode 100644 index 0000000..10bfdc3 --- /dev/null +++ b/src/os/signal/signal_plan9_test.go @@ -0,0 +1,181 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package signal + +import ( + "os" + "runtime" + "syscall" + "testing" + "time" +) + +func waitSig(t *testing.T, c <-chan os.Signal, sig os.Signal) { + select { + case s := <-c: + if s != sig { + t.Fatalf("signal was %v, want %v", s, sig) + } + case <-time.After(1 * time.Second): + t.Fatalf("timeout waiting for %v", sig) + } +} + +// Test that basic signal handling works. +func TestSignal(t *testing.T) { + // Ask for hangup + c := make(chan os.Signal, 1) + Notify(c, syscall.Note("hangup")) + defer Stop(c) + + // Send this process a hangup + t.Logf("hangup...") + postNote(syscall.Getpid(), "hangup") + waitSig(t, c, syscall.Note("hangup")) + + // Ask for everything we can get. + c1 := make(chan os.Signal, 1) + Notify(c1) + + // Send this process an alarm + t.Logf("alarm...") + postNote(syscall.Getpid(), "alarm") + waitSig(t, c1, syscall.Note("alarm")) + + // Send two more hangups, to make sure that + // they get delivered on c1 and that not reading + // from c does not block everything. + t.Logf("hangup...") + postNote(syscall.Getpid(), "hangup") + waitSig(t, c1, syscall.Note("hangup")) + t.Logf("hangup...") + postNote(syscall.Getpid(), "hangup") + waitSig(t, c1, syscall.Note("hangup")) + + // The first SIGHUP should be waiting for us on c. + waitSig(t, c, syscall.Note("hangup")) +} + +func TestStress(t *testing.T) { + dur := 3 * time.Second + if testing.Short() { + dur = 100 * time.Millisecond + } + defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) + done := make(chan bool) + finished := make(chan bool) + go func() { + sig := make(chan os.Signal, 1) + Notify(sig, syscall.Note("alarm")) + defer Stop(sig) + Loop: + for { + select { + case <-sig: + case <-done: + break Loop + } + } + finished <- true + }() + go func() { + Loop: + for { + select { + case <-done: + break Loop + default: + postNote(syscall.Getpid(), "alarm") + runtime.Gosched() + } + } + finished <- true + }() + time.Sleep(dur) + close(done) + <-finished + <-finished + // When run with 'go test -cpu=1,2,4' alarm from this test can slip + // into subsequent TestSignal() causing failure. + // Sleep for a while to reduce the possibility of the failure. + time.Sleep(10 * time.Millisecond) +} + +// Test that Stop cancels the channel's registrations. +func TestStop(t *testing.T) { + if testing.Short() { + t.Skip("skipping in short mode") + } + sigs := []string{ + "alarm", + "hangup", + } + + for _, sig := range sigs { + // Send the signal. + // If it's alarm, we should not see it. + // If it's hangup, maybe we'll die. Let the flag tell us what to do. + if sig != "hangup" { + postNote(syscall.Getpid(), sig) + } + time.Sleep(100 * time.Millisecond) + + // Ask for signal + c := make(chan os.Signal, 1) + Notify(c, syscall.Note(sig)) + defer Stop(c) + + // Send this process that signal + postNote(syscall.Getpid(), sig) + waitSig(t, c, syscall.Note(sig)) + + Stop(c) + select { + case s := <-c: + t.Fatalf("unexpected signal %v", s) + case <-time.After(100 * time.Millisecond): + // nothing to read - good + } + + // Send the signal. + // If it's alarm, we should not see it. + // If it's hangup, maybe we'll die. Let the flag tell us what to do. + if sig != "hangup" { + postNote(syscall.Getpid(), sig) + } + + select { + case s := <-c: + t.Fatalf("unexpected signal %v", s) + case <-time.After(100 * time.Millisecond): + // nothing to read - good + } + } +} + +func itoa(val int) string { + if val < 0 { + return "-" + itoa(-val) + } + var buf [32]byte // big enough for int64 + i := len(buf) - 1 + for val >= 10 { + buf[i] = byte(val%10 + '0') + i-- + val /= 10 + } + buf[i] = byte(val + '0') + return string(buf[i:]) +} + +func postNote(pid int, note string) error { + f, err := os.OpenFile("/proc/"+itoa(pid)+"/note", os.O_WRONLY, 0) + if err != nil { + return err + } + defer f.Close() + _, err = f.Write([]byte(note)) + return err +} |