Source file
src/runtime/semasleep_test.go
1
2
3
4
5
6
7 package runtime_test
8
9 import (
10 "io"
11 "os/exec"
12 "syscall"
13 "testing"
14 "time"
15 )
16
17
18
19
20 func TestSpuriousWakeupsNeverHangSemasleep(t *testing.T) {
21 if *flagQuick {
22 t.Skip("-quick")
23 }
24 t.Parallel()
25
26 exe, err := buildTestProg(t, "testprog")
27 if err != nil {
28 t.Fatal(err)
29 }
30
31 cmd := exec.Command(exe, "After1")
32 stdout, err := cmd.StdoutPipe()
33 if err != nil {
34 t.Fatalf("StdoutPipe: %v", err)
35 }
36 beforeStart := time.Now()
37 if err := cmd.Start(); err != nil {
38 t.Fatalf("Failed to start command: %v", err)
39 }
40 doneCh := make(chan error, 1)
41 go func() {
42 doneCh <- cmd.Wait()
43 close(doneCh)
44 }()
45 t.Cleanup(func() {
46 cmd.Process.Kill()
47 <-doneCh
48 })
49
50
51
52 b, err := io.ReadAll(stdout)
53 if len(b) > 0 {
54 t.Logf("read from testprog stdout: %s", b)
55 }
56 if err != nil {
57 t.Fatalf("error reading from testprog: %v", err)
58 }
59
60
61
62
63
64
65
66 timeout := 10 * time.Second
67
68
69
70
71 ready := time.Now()
72
73
74
75
76
77 ticker := time.NewTicker(200 * time.Millisecond)
78 defer ticker.Stop()
79 for {
80 select {
81 case now := <-ticker.C:
82 if now.Sub(ready) > timeout {
83 t.Error("Program failed to return on time and has to be killed, issue #27520 still exists")
84
85
86 cmd.Process.Signal(syscall.SIGQUIT)
87 return
88 }
89
90
91
92 cmd.Process.Signal(syscall.SIGIO)
93
94 case err := <-doneCh:
95 if err != nil {
96 t.Fatalf("The program returned but unfortunately with an error: %v", err)
97 }
98 if time.Since(beforeStart) < 1*time.Second {
99
100
101 t.Fatalf("The program stopped too quickly.")
102 }
103 return
104 }
105 }
106 }
107
View as plain text