Source file
misc/cgo/test/issue18146.go
1
2
3
4
5
6
7
8
9
10 package cgotest
11
12 import (
13 "bytes"
14 "crypto/md5"
15 "os"
16 "os/exec"
17 "runtime"
18 "syscall"
19 "testing"
20 "time"
21 )
22
23 func test18146(t *testing.T) {
24 if testing.Short() {
25 t.Skip("skipping in short mode")
26 }
27
28 if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
29 t.Skipf("skipping flaky test on %s; see golang.org/issue/18202", runtime.GOOS)
30 }
31
32 if runtime.GOARCH == "mips" || runtime.GOARCH == "mips64" {
33 t.Skipf("skipping on %s", runtime.GOARCH)
34 }
35
36 attempts := 1000
37 threads := 4
38
39
40
41
42
43 var nproc int
44 setNproc := true
45 switch runtime.GOOS {
46 default:
47 setNproc = false
48 case "aix":
49 nproc = 9
50 case "linux":
51 nproc = 6
52 case "darwin", "dragonfly", "freebsd", "netbsd", "openbsd":
53 nproc = 7
54 }
55 if setNproc {
56 var rlim syscall.Rlimit
57 if syscall.Getrlimit(nproc, &rlim) == nil {
58 max := int(rlim.Cur) / (threads + 5)
59 if attempts > max {
60 t.Logf("lowering attempts from %d to %d for RLIMIT_NPROC", attempts, max)
61 attempts = max
62 }
63 }
64 }
65
66 if os.Getenv("test18146") == "exec" {
67 runtime.GOMAXPROCS(1)
68 for n := threads; n > 0; n-- {
69 go func() {
70 for {
71 _ = md5.Sum([]byte("Hello, !"))
72 }
73 }()
74 }
75 runtime.GOMAXPROCS(threads)
76 argv := append(os.Args, "-test.run=NoSuchTestExists")
77 if err := syscall.Exec(os.Args[0], argv, os.Environ()); err != nil {
78 t.Fatal(err)
79 }
80 }
81
82 var cmds []*exec.Cmd
83 defer func() {
84 for _, cmd := range cmds {
85 cmd.Process.Kill()
86 }
87 }()
88
89 args := append(append([]string(nil), os.Args[1:]...), "-test.run=Test18146")
90 for n := attempts; n > 0; n-- {
91 cmd := exec.Command(os.Args[0], args...)
92 cmd.Env = append(os.Environ(), "test18146=exec")
93 buf := bytes.NewBuffer(nil)
94 cmd.Stdout = buf
95 cmd.Stderr = buf
96 if err := cmd.Start(); err != nil {
97
98
99
100
101 if pe, ok := err.(*os.PathError); ok {
102 err = pe.Err
103 }
104 if se, ok := err.(syscall.Errno); ok && (se == syscall.EAGAIN || se == syscall.EMFILE) {
105 time.Sleep(time.Millisecond)
106 continue
107 }
108
109 t.Error(err)
110 return
111 }
112 cmds = append(cmds, cmd)
113 }
114
115 failures := 0
116 for _, cmd := range cmds {
117 err := cmd.Wait()
118 if err == nil {
119 continue
120 }
121
122 t.Errorf("syscall.Exec failed: %v\n%s", err, cmd.Stdout)
123 failures++
124 }
125
126 if failures > 0 {
127 t.Logf("Failed %v of %v attempts.", failures, len(cmds))
128 }
129 }
130
View as plain text