github.com/go-darwin/sys@v0.0.0-20220510002607-68fd01f054ca/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 "os" 16 "os/exec" 17 "path/filepath" 18 "runtime" 19 "strings" 20 "testing" 21 ) 22 23 // HasGoBuild reports whether the current system can build programs with “go build” 24 // and then run them with os.StartProcess or exec.Command. 25 func HasGoBuild() bool { 26 if os.Getenv("GO_GCFLAGS") != "" { 27 // It's too much work to require every caller of the go command 28 // to pass along "-gcflags="+os.Getenv("GO_GCFLAGS"). 29 // For now, if $GO_GCFLAGS is set, report that we simply can't 30 // run go build. 31 return false 32 } 33 switch runtime.GOOS { 34 case "android", "js", "ios": 35 return false 36 } 37 return true 38 } 39 40 // MustHaveGoBuild checks that the current system can build programs with “go build” 41 // and then run them with os.StartProcess or exec.Command. 42 // If not, MustHaveGoBuild calls t.Skip with an explanation. 43 func MustHaveGoBuild(t testing.TB) { 44 if os.Getenv("GO_GCFLAGS") != "" { 45 t.Skipf("skipping test: 'go build' not compatible with setting $GO_GCFLAGS") 46 } 47 if !HasGoBuild() { 48 t.Skipf("skipping test: 'go build' not available on %s/%s", runtime.GOOS, runtime.GOARCH) 49 } 50 } 51 52 // KnownEnv is a list of environment variables that affect the operation 53 // of the Go command. 54 const KnownEnv = ` 55 AR 56 CC 57 CGO_CFLAGS 58 CGO_CFLAGS_ALLOW 59 CGO_CFLAGS_DISALLOW 60 CGO_CPPFLAGS 61 CGO_CPPFLAGS_ALLOW 62 CGO_CPPFLAGS_DISALLOW 63 CGO_CXXFLAGS 64 CGO_CXXFLAGS_ALLOW 65 CGO_CXXFLAGS_DISALLOW 66 CGO_ENABLED 67 CGO_FFLAGS 68 CGO_FFLAGS_ALLOW 69 CGO_FFLAGS_DISALLOW 70 CGO_LDFLAGS 71 CGO_LDFLAGS_ALLOW 72 CGO_LDFLAGS_DISALLOW 73 CXX 74 FC 75 GCCGO 76 GO111MODULE 77 GO386 78 GOAMD64 79 GOARCH 80 GOARM 81 GOBIN 82 GOCACHE 83 GOENV 84 GOEXE 85 GOEXPERIMENT 86 GOFLAGS 87 GOGCCFLAGS 88 GOHOSTARCH 89 GOHOSTOS 90 GOINSECURE 91 GOMIPS 92 GOMIPS64 93 GOMODCACHE 94 GONOPROXY 95 GONOSUMDB 96 GOOS 97 GOPATH 98 GOPPC64 99 GOPRIVATE 100 GOPROXY 101 GOROOT 102 GOSUMDB 103 GOTMPDIR 104 GOTOOLDIR 105 GOVCS 106 GOWASM 107 GO_EXTLINK_ENABLED 108 PKG_CONFIG 109 ` 110 111 // GoToolPath reports the path to the Go tool. 112 // It is a convenience wrapper around GoTool. 113 // If the tool is unavailable GoToolPath calls t.Skip. 114 // If the tool should be available and isn't, GoToolPath calls t.Fatal. 115 func GoToolPath(t testing.TB) string { 116 MustHaveGoBuild(t) 117 path, err := GoTool() 118 if err != nil { 119 t.Fatal(err) 120 } 121 // Add all environment variables that affect the Go command to test metadata. 122 // Cached test results will be invalidate when these variables change. 123 // See golang.org/issue/32285. 124 for _, envVar := range strings.Fields(KnownEnv) { 125 os.Getenv(envVar) 126 } 127 return path 128 } 129 130 // GoTool reports the path to the Go tool. 131 func GoTool() (string, error) { 132 if !HasGoBuild() { 133 return "", errors.New("platform cannot run go tool") 134 } 135 var exeSuffix string 136 if runtime.GOOS == "windows" { 137 exeSuffix = ".exe" 138 } 139 path := filepath.Join(runtime.GOROOT(), "bin", "go"+exeSuffix) 140 if _, err := os.Stat(path); err == nil { 141 return path, nil 142 } 143 goBin, err := exec.LookPath("go" + exeSuffix) 144 if err != nil { 145 return "", errors.New("cannot find go tool: " + err.Error()) 146 } 147 return goBin, nil 148 } 149 150 // CleanCmdEnv will fill cmd.Env with the environment, excluding certain 151 // variables that could modify the behavior of the Go tools such as 152 // GODEBUG and GOTRACEBACK. 153 func CleanCmdEnv(cmd *exec.Cmd) *exec.Cmd { 154 if cmd.Env != nil { 155 panic("environment already set") 156 } 157 for _, env := range os.Environ() { 158 // Exclude GODEBUG from the environment to prevent its output 159 // from breaking tests that are trying to parse other command output. 160 if strings.HasPrefix(env, "GODEBUG=") { 161 continue 162 } 163 // Exclude GOTRACEBACK for the same reason. 164 if strings.HasPrefix(env, "GOTRACEBACK=") { 165 continue 166 } 167 cmd.Env = append(cmd.Env, env) 168 } 169 return cmd 170 }