Source file src/pkg/internal/testenv/testenv.go
1
2
3
4
5
6
7
8
9
10
11 package testenv
12
13 import (
14 "errors"
15 "flag"
16 "internal/cfg"
17 "os"
18 "os/exec"
19 "path/filepath"
20 "runtime"
21 "strconv"
22 "strings"
23 "sync"
24 "testing"
25 )
26
27
28
29
30
31 func Builder() string {
32 return os.Getenv("GO_BUILDER_NAME")
33 }
34
35
36
37 func HasGoBuild() bool {
38 if os.Getenv("GO_GCFLAGS") != "" {
39
40
41
42
43 return false
44 }
45 switch runtime.GOOS {
46 case "android", "nacl", "js":
47 return false
48 case "darwin":
49 if strings.HasPrefix(runtime.GOARCH, "arm") {
50 return false
51 }
52 }
53 return true
54 }
55
56
57
58
59 func MustHaveGoBuild(t testing.TB) {
60 if os.Getenv("GO_GCFLAGS") != "" {
61 t.Skipf("skipping test: 'go build' not compatible with setting $GO_GCFLAGS")
62 }
63 if !HasGoBuild() {
64 t.Skipf("skipping test: 'go build' not available on %s/%s", runtime.GOOS, runtime.GOARCH)
65 }
66 }
67
68
69 func HasGoRun() bool {
70
71 return HasGoBuild()
72 }
73
74
75
76 func MustHaveGoRun(t testing.TB) {
77 if !HasGoRun() {
78 t.Skipf("skipping test: 'go run' not available on %s/%s", runtime.GOOS, runtime.GOARCH)
79 }
80 }
81
82
83
84
85
86 func GoToolPath(t testing.TB) string {
87 MustHaveGoBuild(t)
88 path, err := GoTool()
89 if err != nil {
90 t.Fatal(err)
91 }
92
93
94
95 for _, envVar := range strings.Fields(cfg.KnownEnv) {
96 os.Getenv(envVar)
97 }
98 return path
99 }
100
101
102 func GoTool() (string, error) {
103 if !HasGoBuild() {
104 return "", errors.New("platform cannot run go tool")
105 }
106 var exeSuffix string
107 if runtime.GOOS == "windows" {
108 exeSuffix = ".exe"
109 }
110 path := filepath.Join(runtime.GOROOT(), "bin", "go"+exeSuffix)
111 if _, err := os.Stat(path); err == nil {
112 return path, nil
113 }
114 goBin, err := exec.LookPath("go" + exeSuffix)
115 if err != nil {
116 return "", errors.New("cannot find go tool: " + err.Error())
117 }
118 return goBin, nil
119 }
120
121
122
123 func HasExec() bool {
124 switch runtime.GOOS {
125 case "nacl", "js":
126 return false
127 case "darwin":
128 if strings.HasPrefix(runtime.GOARCH, "arm") {
129 return false
130 }
131 }
132 return true
133 }
134
135
136 func HasSrc() bool {
137 switch runtime.GOOS {
138 case "nacl":
139 return false
140 case "darwin":
141 if strings.HasPrefix(runtime.GOARCH, "arm") {
142 return false
143 }
144 }
145 return true
146 }
147
148
149
150
151 func MustHaveExec(t testing.TB) {
152 if !HasExec() {
153 t.Skipf("skipping test: cannot exec subprocess on %s/%s", runtime.GOOS, runtime.GOARCH)
154 }
155 }
156
157 var execPaths sync.Map
158
159
160
161
162 func MustHaveExecPath(t testing.TB, path string) {
163 MustHaveExec(t)
164
165 err, found := execPaths.Load(path)
166 if !found {
167 _, err = exec.LookPath(path)
168 err, _ = execPaths.LoadOrStore(path, err)
169 }
170 if err != nil {
171 t.Skipf("skipping test: %s: %s", path, err)
172 }
173 }
174
175
176
177 func HasExternalNetwork() bool {
178 return !testing.Short() && runtime.GOOS != "nacl" && runtime.GOOS != "js"
179 }
180
181
182
183
184 func MustHaveExternalNetwork(t testing.TB) {
185 if runtime.GOOS == "nacl" || runtime.GOOS == "js" {
186 t.Skipf("skipping test: no external network on %s", runtime.GOOS)
187 }
188 if testing.Short() {
189 t.Skipf("skipping test: no external network in -short mode")
190 }
191 }
192
193 var haveCGO bool
194
195
196 func HasCGO() bool {
197 return haveCGO
198 }
199
200
201 func MustHaveCGO(t testing.TB) {
202 if !haveCGO {
203 t.Skipf("skipping test: no cgo")
204 }
205 }
206
207
208 func HasSymlink() bool {
209 ok, _ := hasSymlink()
210 return ok
211 }
212
213
214
215 func MustHaveSymlink(t testing.TB) {
216 ok, reason := hasSymlink()
217 if !ok {
218 t.Skipf("skipping test: cannot make symlinks on %s/%s%s", runtime.GOOS, runtime.GOARCH, reason)
219 }
220 }
221
222
223 func HasLink() bool {
224
225
226
227 return runtime.GOOS != "plan9" && runtime.GOOS != "android"
228 }
229
230
231
232 func MustHaveLink(t testing.TB) {
233 if !HasLink() {
234 t.Skipf("skipping test: hardlinks are not supported on %s/%s", runtime.GOOS, runtime.GOARCH)
235 }
236 }
237
238 var flaky = flag.Bool("flaky", false, "run known-flaky tests too")
239
240 func SkipFlaky(t testing.TB, issue int) {
241 t.Helper()
242 if !*flaky {
243 t.Skipf("skipping known flaky test without the -flaky flag; see golang.org/issue/%d", issue)
244 }
245 }
246
247 func SkipFlakyNet(t testing.TB) {
248 t.Helper()
249 if v, _ := strconv.ParseBool(os.Getenv("GO_BUILDER_FLAKY_NET")); v {
250 t.Skip("skipping test on builder known to have frequent network failures")
251 }
252 }
253
254
255
256
257 func CleanCmdEnv(cmd *exec.Cmd) *exec.Cmd {
258 if cmd.Env != nil {
259 panic("environment already set")
260 }
261 for _, env := range os.Environ() {
262
263
264 if strings.HasPrefix(env, "GODEBUG=") {
265 continue
266 }
267
268 if strings.HasPrefix(env, "GOTRACEBACK=") {
269 continue
270 }
271 cmd.Env = append(cmd.Env, env)
272 }
273 return cmd
274 }
275
View as plain text