github.com/zebozhuang/go@v0.0.0-20200207033046-f8a98f6f5c5d/src/internal/testenv/testenv.go (about) 1 // Copyright 2015 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 testenv provides information about what functionality 6 // is available in different testing environments run by the Go team. 7 // 8 // It is an internal package because these details are specific 9 // to the Go team's test setup (on build.golang.org) and not 10 // fundamental to tests in general. 11 package testenv 12 13 import ( 14 "errors" 15 "flag" 16 "os" 17 "os/exec" 18 "path/filepath" 19 "runtime" 20 "strconv" 21 "strings" 22 "testing" 23 ) 24 25 // Builder reports the name of the builder running this test 26 // (for example, "linux-amd64" or "windows-386-gce"). 27 // If the test is not running on the build infrastructure, 28 // Builder returns the empty string. 29 func Builder() string { 30 return os.Getenv("GO_BUILDER_NAME") 31 } 32 33 // HasGoBuild reports whether the current system can build programs with ``go build'' 34 // and then run them with os.StartProcess or exec.Command. 35 func HasGoBuild() bool { 36 switch runtime.GOOS { 37 case "android", "nacl": 38 return false 39 case "darwin": 40 if strings.HasPrefix(runtime.GOARCH, "arm") { 41 return false 42 } 43 } 44 return true 45 } 46 47 // MustHaveGoBuild checks that the current system can build programs with ``go build'' 48 // and then run them with os.StartProcess or exec.Command. 49 // If not, MustHaveGoBuild calls t.Skip with an explanation. 50 func MustHaveGoBuild(t *testing.T) { 51 if !HasGoBuild() { 52 t.Skipf("skipping test: 'go build' not available on %s/%s", runtime.GOOS, runtime.GOARCH) 53 } 54 } 55 56 // HasGoRun reports whether the current system can run programs with ``go run.'' 57 func HasGoRun() bool { 58 // For now, having go run and having go build are the same. 59 return HasGoBuild() 60 } 61 62 // MustHaveGoRun checks that the current system can run programs with ``go run.'' 63 // If not, MustHaveGoRun calls t.Skip with an explanation. 64 func MustHaveGoRun(t *testing.T) { 65 if !HasGoRun() { 66 t.Skipf("skipping test: 'go run' not available on %s/%s", runtime.GOOS, runtime.GOARCH) 67 } 68 } 69 70 // GoToolPath reports the path to the Go tool. 71 // It is a convenience wrapper around GoTool. 72 // If the tool is unavailable GoToolPath calls t.Skip. 73 // If the tool should be available and isn't, GoToolPath calls t.Fatal. 74 func GoToolPath(t *testing.T) string { 75 MustHaveGoBuild(t) 76 path, err := GoTool() 77 if err != nil { 78 t.Fatal(err) 79 } 80 return path 81 } 82 83 // GoTool reports the path to the Go tool. 84 func GoTool() (string, error) { 85 if !HasGoBuild() { 86 return "", errors.New("platform cannot run go tool") 87 } 88 var exeSuffix string 89 if runtime.GOOS == "windows" { 90 exeSuffix = ".exe" 91 } 92 path := filepath.Join(runtime.GOROOT(), "bin", "go"+exeSuffix) 93 if _, err := os.Stat(path); err == nil { 94 return path, nil 95 } 96 goBin, err := exec.LookPath("go" + exeSuffix) 97 if err != nil { 98 return "", errors.New("cannot find go tool: " + err.Error()) 99 } 100 return goBin, nil 101 } 102 103 // HasExec reports whether the current system can start new processes 104 // using os.StartProcess or (more commonly) exec.Command. 105 func HasExec() bool { 106 switch runtime.GOOS { 107 case "nacl": 108 return false 109 case "darwin": 110 if strings.HasPrefix(runtime.GOARCH, "arm") { 111 return false 112 } 113 } 114 return true 115 } 116 117 // HasSrc reports whether the entire source tree is available under GOROOT. 118 func HasSrc() bool { 119 switch runtime.GOOS { 120 case "nacl": 121 return false 122 case "darwin": 123 if strings.HasPrefix(runtime.GOARCH, "arm") { 124 return false 125 } 126 } 127 return true 128 } 129 130 // MustHaveExec checks that the current system can start new processes 131 // using os.StartProcess or (more commonly) exec.Command. 132 // If not, MustHaveExec calls t.Skip with an explanation. 133 func MustHaveExec(t *testing.T) { 134 if !HasExec() { 135 t.Skipf("skipping test: cannot exec subprocess on %s/%s", runtime.GOOS, runtime.GOARCH) 136 } 137 } 138 139 // HasExternalNetwork reports whether the current system can use 140 // external (non-localhost) networks. 141 func HasExternalNetwork() bool { 142 return !testing.Short() 143 } 144 145 // MustHaveExternalNetwork checks that the current system can use 146 // external (non-localhost) networks. 147 // If not, MustHaveExternalNetwork calls t.Skip with an explanation. 148 func MustHaveExternalNetwork(t *testing.T) { 149 if testing.Short() { 150 t.Skipf("skipping test: no external network in -short mode") 151 } 152 } 153 154 var haveCGO bool 155 156 // MustHaveCGO calls t.Skip if cgo is not available. 157 func MustHaveCGO(t *testing.T) { 158 if !haveCGO { 159 t.Skipf("skipping test: no cgo") 160 } 161 } 162 163 // HasSymlink reports whether the current system can use os.Symlink. 164 func HasSymlink() bool { 165 ok, _ := hasSymlink() 166 return ok 167 } 168 169 // MustHaveSymlink reports whether the current system can use os.Symlink. 170 // If not, MustHaveSymlink calls t.Skip with an explanation. 171 func MustHaveSymlink(t *testing.T) { 172 ok, reason := hasSymlink() 173 if !ok { 174 t.Skipf("skipping test: cannot make symlinks on %s/%s%s", runtime.GOOS, runtime.GOARCH, reason) 175 } 176 } 177 178 // HasLink reports whether the current system can use os.Link. 179 func HasLink() bool { 180 // From Android release M (Marshmallow), hard linking files is blocked 181 // and an attempt to call link() on a file will return EACCES. 182 // - https://code.google.com/p/android-developer-preview/issues/detail?id=3150 183 return runtime.GOOS != "plan9" && runtime.GOOS != "android" 184 } 185 186 // MustHaveLink reports whether the current system can use os.Link. 187 // If not, MustHaveLink calls t.Skip with an explanation. 188 func MustHaveLink(t *testing.T) { 189 if !HasLink() { 190 t.Skipf("skipping test: hardlinks are not supported on %s/%s", runtime.GOOS, runtime.GOARCH) 191 } 192 } 193 194 var flaky = flag.Bool("flaky", false, "run known-flaky tests too") 195 196 func SkipFlaky(t *testing.T, issue int) { 197 if !*flaky { 198 t.Skipf("skipping known flaky test without the -flaky flag; see golang.org/issue/%d", issue) 199 } 200 } 201 202 func SkipFlakyNet(t *testing.T) { 203 if v, _ := strconv.ParseBool(os.Getenv("GO_BUILDER_FLAKY_NET")); v { 204 t.Skip("skipping test on builder known to have frequent network failures") 205 } 206 }