func TestInstall(t *testing.T) {
testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveBuildMode(t, "c-archive")
if !testWork {
defer os.RemoveAll(filepath.Join(GOPATH, "pkg"))
t.Skip("skipping signal test on Windows")
}
testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveBuildMode(t, "c-archive")
if !testWork {
defer func() {
case "windows":
t.Skip("skipping signal test on Windows")
}
+ testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveBuildMode(t, "c-archive")
}
// buildSignalForwardingTest builds the executable used by the various
t.Skip("skipping signal test on Windows")
}
testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveBuildMode(t, "c-archive")
if !testWork {
defer func() {
t.Skip("skipping signal test on Windows")
}
testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveBuildMode(t, "c-archive")
if !testWork {
defer func() {
if runtime.Compiler == "gccgo" {
t.Skip("skipping -extar test when using gccgo")
}
- if runtime.GOOS == "ios" {
- t.Skip("shell scripts are not executable on iOS hosts")
- }
testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveBuildMode(t, "c-archive")
+ testenv.MustHaveExecPath(t, "bash") // This test uses a bash script
if !testWork {
defer func() {
t.Skipf("skipping PIE test on %s", GOOS)
}
testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveBuildMode(t, "c-archive")
libgoa := "libgo.a"
if runtime.Compiler == "gccgo" {
t.Skipf("skipping SIGPROF test on %s; see https://golang.org/issue/19320", GOOS)
}
testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveBuildMode(t, "c-archive")
t.Parallel()
// Test that installing a second time recreates the header file.
func TestCachedInstall(t *testing.T) {
testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveBuildMode(t, "c-archive")
+
if !testWork {
defer os.RemoveAll(filepath.Join(GOPATH, "pkg"))
}
// Issue 35294.
func TestManyCalls(t *testing.T) {
testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveBuildMode(t, "c-archive")
+
t.Parallel()
if !testWork {
t.Skip("skipping asynchronous preemption test with gccgo")
}
testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveBuildMode(t, "c-archive")
t.Parallel()
"encoding/binary"
"flag"
"fmt"
+ "internal/testenv"
"log"
"os"
"os/exec"
os.Exit(0)
}
}
+ if !testenv.HasGoBuild() {
+ // Checking for "go build" is a proxy for whether or not we can run "go env".
+ fmt.Printf("SKIP - no go build")
+ os.Exit(0)
+ }
GOOS = goEnv("GOOS")
GOARCH = goEnv("GOARCH")
)
func createHeadersOnce(t *testing.T) {
+ testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveBuildMode(t, "c-shared")
+
headersOnce.Do(func() {
headersErr = createHeaders()
})
// test0: exported symbols in shared lib are accessible.
func TestExportedSymbols(t *testing.T) {
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveExec(t)
+
t.Parallel()
cmd := "testp0"
if GOOS != "windows" {
t.Skip("skipping windows only test")
}
+ testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveBuildMode(t, "c-shared")
+
t.Parallel()
t.Run("OnlyExported", func(t *testing.T) {
// test1: shared library can be dynamically loaded and exported symbols are accessible.
func TestExportedSymbolsWithDynamicLoad(t *testing.T) {
- t.Parallel()
-
if GOOS == "windows" {
- t.Logf("Skipping on %s", GOOS)
- return
+ t.Skipf("Skipping on %s", GOOS)
}
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveExec(t)
+
+ t.Parallel()
cmd := "testp1"
bin := cmdToRun(cmd)
// test2: tests libgo2 which does not export any functions.
func TestUnexportedSymbols(t *testing.T) {
- t.Parallel()
-
if GOOS == "windows" {
- t.Logf("Skipping on %s", GOOS)
- return
+ t.Skipf("Skipping on %s", GOOS)
}
+ testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveBuildMode(t, "c-shared")
+
+ t.Parallel()
cmd := "testp2"
bin := cmdToRun(cmd)
// test3: tests main.main is exported on android.
func TestMainExportedOnAndroid(t *testing.T) {
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveExec(t)
+
t.Parallel()
switch GOOS {
}
func testSignalHandlers(t *testing.T, pkgname, cfile, cmd string) {
+ if GOOS == "windows" {
+ t.Skipf("Skipping on %s", GOOS)
+ }
+ testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveBuildMode(t, "c-shared")
+
libname := pkgname + ".a"
run(t,
nil,
// test4: test signal handlers
func TestSignalHandlers(t *testing.T) {
t.Parallel()
- if GOOS == "windows" {
- t.Logf("Skipping on %s", GOOS)
- return
- }
testSignalHandlers(t, "./libgo4", "main4.c", "testp4")
}
// test5: test signal handlers with os/signal.Notify
func TestSignalHandlersWithNotify(t *testing.T) {
t.Parallel()
- if GOOS == "windows" {
- t.Logf("Skipping on %s", GOOS)
- return
- }
testSignalHandlers(t, "./libgo5", "main5.c", "testp5")
}
func TestPIE(t *testing.T) {
- t.Parallel()
-
switch GOOS {
case "linux", "android":
break
default:
- t.Logf("Skipping on %s", GOOS)
- return
+ t.Skipf("Skipping on %s", GOOS)
}
+ t.Parallel()
+
createHeadersOnce(t)
f, err := elf.Open(libgoname)
// Test that installing a second time recreates the header file.
func TestCachedInstall(t *testing.T) {
+ testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveBuildMode(t, "c-shared")
+
tmpdir, err := os.MkdirTemp("", "cshared")
if err != nil {
t.Fatal(err)
case "android":
t.Skip("test fails on android; issue 29087")
}
+ testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveBuildMode(t, "c-shared")
t.Parallel()
}
func TestIssue36233(t *testing.T) {
+ testenv.MustHaveCGO(t)
+
t.Parallel()
// Test that the export header uses GoComplex64 and GoComplex128
"go/ast"
"go/parser"
"go/token"
+ "internal/testenv"
"os"
"os/exec"
"path/filepath"
}
func TestArgumentsPositions(t *testing.T) {
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveExec(t)
+
testdata, err := filepath.Abs("testdata")
if err != nil {
t.Fatal(err)
import (
"bytes"
+ "cmd/internal/quoted"
+ "internal/testenv"
"os"
"os/exec"
"path/filepath"
`
func TestBadSymbol(t *testing.T) {
+ testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
+
dir := t.TempDir()
mkdir := func(base string) string {
}
func cCompilerCmd(t *testing.T) []string {
- cc := []string{goEnv(t, "CC")}
+ cc, err := quoted.Split(goEnv(t, "CC"))
+ if err != nil {
+ t.Skipf("parsing go env CC: %s", err)
+ }
+ if len(cc) == 0 {
+ t.Skipf("no C compiler")
+ }
+ testenv.MustHaveExecPath(t, cc[0])
out := goEnv(t, "GOGCCFLAGS")
quote := '\000'
func check(t *testing.T, file string) {
t.Run(file, func(t *testing.T) {
testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
t.Parallel()
contents, err := os.ReadFile(path(file))
}
func sizeofLongDouble(t *testing.T) int {
+ testenv.MustHaveGoRun(t)
+ testenv.MustHaveCGO(t)
cmd := exec.Command("go", "run", path("long_double_size.go"))
out, err := cmd.CombinedOutput()
if err != nil {
cflags := cflags
t.Run(cflags, func(t *testing.T) {
testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
t.Parallel()
cmd := exec.Command("go", "build", path("issue14669.go"))
}
func TestMallocCrashesOnNil(t *testing.T) {
+ testenv.MustHaveCGO(t)
testenv.MustHaveGoRun(t)
t.Parallel()
"bytes"
"flag"
"fmt"
+ "internal/testenv"
"os"
"os/exec"
"path/filepath"
+ "runtime"
"strings"
"sync/atomic"
"testing"
}
func TestPointerChecks(t *testing.T) {
+ testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
+ if runtime.GOOS == "windows" {
+ // TODO: Skip just the cases that fail?
+ t.Skipf("some tests fail to build on %s", runtime.GOOS)
+ }
+
var gopath string
var dir string
if *tmp != "" {
func TestFortran(t *testing.T) {
testenv.MustHaveGoRun(t)
+ testenv.MustHaveCGO(t)
// Find the FORTRAN compiler.
fc := os.Getenv("FC")
func TestGoDefs(t *testing.T) {
testenv.MustHaveGoRun(t)
+ testenv.MustHaveCGO(t)
testdata, err := filepath.Abs("testdata")
if err != nil {
// TestTestRun runs a test case for cgo //export.
func TestTestRun(t *testing.T) {
- if os.Getenv("GOOS") == "android" {
- t.Skip("the go tool runs with CGO_ENABLED=0 on the android device")
- }
testenv.MustHaveGoRun(t)
+ testenv.MustHaveCGO(t)
cmd := exec.Command("go", "run", "main.go")
got, err := cmd.CombinedOutput()
"context"
"flag"
"fmt"
+ "internal/platform"
+ "internal/testenv"
"log"
"os"
"os/exec"
"path/filepath"
+ "runtime"
"strings"
"testing"
"time"
}
func testMain(m *testing.M) int {
+ // TODO: Move all of this initialization stuff into a sync.Once that each
+ // test can use, where we can properly t.Skip.
+ if !platform.BuildModeSupported(runtime.Compiler, "plugin", runtime.GOOS, runtime.GOARCH) {
+ fmt.Printf("SKIP - plugin build mode not supported\n")
+ os.Exit(0)
+ }
+ if !testenv.HasCGO() {
+ fmt.Printf("SKIP - cgo not supported\n")
+ os.Exit(0)
+ }
+
cwd, err := os.Getwd()
if err != nil {
log.Fatal(err)
import (
"fmt"
+ "internal/platform"
+ "internal/testenv"
"strings"
"testing"
)
func TestASAN(t *testing.T) {
+ testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
goos, err := goEnv("GOOS")
if err != nil {
t.Fatal(err)
t.Fatal(err)
}
// The asan tests require support for the -asan option.
- if !aSanSupported(goos, goarch) {
+ if !platform.ASanSupported(goos, goarch) {
t.Skipf("skipping on %s/%s; -asan option is not supported.", goos, goarch)
}
// The current implementation is only compatible with the ASan library from version
}
func TestASANLinkerX(t *testing.T) {
+ testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
// Test ASAN with linker's -X flag (see issue 56175).
goos, err := goEnv("GOOS")
if err != nil {
t.Fatal(err)
}
// The asan tests require support for the -asan option.
- if !aSanSupported(goos, goarch) {
+ if !platform.ASanSupported(goos, goarch) {
t.Skipf("skipping on %s/%s; -asan option is not supported.", goos, goarch)
}
if !compilerRequiredAsanVersion(goos, goarch) {
}
return cmd
}
-
-// mSanSupported is a copy of the function cmd/internal/sys.MSanSupported,
-// because the internal package can't be used here.
-func mSanSupported(goos, goarch string) bool {
- switch goos {
- case "linux":
- return goarch == "amd64" || goarch == "arm64"
- case "freebsd":
- return goarch == "amd64"
- default:
- return false
- }
-}
-
-// aSanSupported is a copy of the function cmd/internal/sys.ASanSupported,
-// because the internal package can't be used here.
-func aSanSupported(goos, goarch string) bool {
- switch goos {
- case "linux":
- return goarch == "amd64" || goarch == "arm64" || goarch == "riscv64" || goarch == "ppc64le"
- default:
- return false
- }
-}
import (
"fmt"
+ "internal/platform"
+ "internal/testenv"
"os"
"strings"
"testing"
)
func TestShared(t *testing.T) {
+ testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveBuildMode(t, "c-shared")
+
t.Parallel()
requireOvercommit(t)
tc := tc
name := strings.TrimSuffix(tc.src, ".go")
//The memory sanitizer tests require support for the -msan option.
- if tc.sanitizer == "memory" && !mSanSupported(GOOS, GOARCH) {
+ if tc.sanitizer == "memory" && !platform.MSanSupported(GOOS, GOARCH) {
t.Logf("skipping %s test on %s/%s; -msan option is not supported.", name, GOOS, GOARCH)
continue
}
package sanitizers_test
import (
+ "internal/platform"
"strings"
"testing"
)
t.Fatal(err)
}
// The msan tests require support for the -msan option.
- if !mSanSupported(goos, goarch) {
+ if !platform.MSanSupported(goos, goarch) {
t.Skipf("skipping on %s/%s; -msan option is not supported.", goos, goarch)
}
package sanitizers_test
import (
+ "internal/testenv"
"strings"
"testing"
)
func TestTSAN(t *testing.T) {
+ testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
+
goos, err := goEnv("GOOS")
if err != nil {
t.Fatal(err)
"flag"
"fmt"
"go/build"
+ "internal/platform"
+ "internal/testenv"
"io"
"log"
"os"
// TestMain calls testMain so that the latter can use defer (TestMain exits with os.Exit).
func testMain(m *testing.M) (int, error) {
+ // TODO: Move all of this initialization stuff into a sync.Once that each
+ // test can use, where we can properly t.Skip.
+ if !platform.BuildModeSupported(runtime.Compiler, "shared", runtime.GOOS, runtime.GOARCH) {
+ fmt.Printf("SKIP - shared build mode not supported\n")
+ os.Exit(0)
+ }
+ if !testenv.HasCGO() {
+ fmt.Printf("SKIP - cgo not supported\n")
+ os.Exit(0)
+ }
+
cwd, err := os.Getwd()
if err != nil {
log.Fatal(err)
if strings.HasSuffix(os.Getenv("GO_BUILDER_NAME"), "-alpine") {
t.Skip("skipping on alpine until issue #54354 resolved")
}
+ testenv.MustHaveBuildMode(t, "pie")
name := "trivial_pie"
goCmd(t, "build", "-buildmode=pie", "-o="+name, "./trivial")
defer os.Remove(name)
}
func TestCgoPIE(t *testing.T) {
+ testenv.MustHaveCGO(t)
+ testenv.MustHaveBuildMode(t, "pie")
name := "cgo_pie"
goCmd(t, "build", "-buildmode=pie", "-o="+name, "./execgo")
defer os.Remove(name)
+++ /dev/null
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !cgo
-
-package so_test
-
-// Nothing to test.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build cgo
-
package so_test
import (
+ "internal/testenv"
"log"
"os"
"os/exec"
"testing"
)
-func requireTestSOSupported(t *testing.T) {
- t.Helper()
- switch runtime.GOARCH {
- case "arm64":
- if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
- t.Skip("No exec facility on iOS.")
- }
- case "ppc64":
- if runtime.GOOS == "linux" {
- t.Skip("External linking not implemented on linux/ppc64 (issue #8912).")
- }
- }
- if runtime.GOOS == "android" {
- t.Skip("No exec facility on Android.")
- }
-}
-
func TestSO(t *testing.T) {
- requireTestSOSupported(t)
+ if runtime.GOOS == "ios" {
+ t.Skip("iOS disallows dynamic loading of user libraries")
+ }
+ testenv.MustHaveGoBuild(t)
+ testenv.MustHaveExec(t)
+ testenv.MustHaveCGO(t)
GOPATH, err := os.MkdirTemp("", "cgosotest")
if err != nil {
+++ /dev/null
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !cgo
-
-package so_test
-
-// Nothing to test.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build cgo
-
package so_test
import (
+ "internal/testenv"
"log"
"os"
"os/exec"
"testing"
)
-func requireTestSOSupported(t *testing.T) {
- t.Helper()
- switch runtime.GOARCH {
- case "arm64":
- if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
- t.Skip("No exec facility on iOS.")
- }
- case "ppc64":
- if runtime.GOOS == "linux" {
- t.Skip("External linking not implemented on linux/ppc64 (issue #8912).")
- }
- }
- if runtime.GOOS == "android" {
- t.Skip("No exec facility on Android.")
- }
-}
-
func TestSO(t *testing.T) {
- requireTestSOSupported(t)
+ if runtime.GOOS == "ios" {
+ t.Skip("iOS disallows dynamic loading of user libraries")
+ }
+ testenv.MustHaveGoBuild(t)
+ testenv.MustHaveExec(t)
+ testenv.MustHaveCGO(t)
GOPATH, err := os.MkdirTemp("", "cgosotest")
if err != nil {
// TestTestRun runs a cgo test that doesn't depend on non-standard libraries.
func TestTestRun(t *testing.T) {
testenv.MustHaveGoRun(t)
- if os.Getenv("GOOS") == "android" {
- t.Skip("subpackage stdio is not available on android")
- }
+ testenv.MustHaveCGO(t)
for _, file := range [...]string{
"chain.go",
}
const cgoHeading = "Testing cgo"
- if t.cgoEnabled && !t.iOS() {
- // Disabled on iOS. golang.org/issue/15919
- t.registerTest("cgo_teststdio", cgoHeading, &goTest{pkg: "cmd/cgo/internal/teststdio", timeout: 5 * time.Minute})
- t.registerTest("cgo_testlife", cgoHeading, &goTest{pkg: "cmd/cgo/internal/testlife", timeout: 5 * time.Minute})
- if goos != "android" {
- t.registerTest("cgo_testfortran", cgoHeading, &goTest{pkg: "cmd/cgo/internal/testfortran", timeout: 5 * time.Minute})
- }
- }
+ t.registerTest("cgo_teststdio", cgoHeading, &goTest{pkg: "cmd/cgo/internal/teststdio", timeout: 5 * time.Minute})
+ t.registerTest("cgo_testlife", cgoHeading, &goTest{pkg: "cmd/cgo/internal/testlife", timeout: 5 * time.Minute})
+ t.registerTest("cgo_testfortran", cgoHeading, &goTest{pkg: "cmd/cgo/internal/testfortran", timeout: 5 * time.Minute})
if t.cgoEnabled {
t.registerCgoTests(cgoHeading)
}
- if t.cgoEnabled {
- t.registerTest("cgo_testgodefs", cgoHeading, &goTest{pkg: "cmd/cgo/internal/testgodefs", timeout: 5 * time.Minute})
-
- t.registerTest("cgo_testso", cgoHeading, &goTest{pkg: "cmd/cgo/internal/testso", timeout: 600 * time.Second})
- t.registerTest("cgo_testsovar", cgoHeading, &goTest{pkg: "cmd/cgo/internal/testsovar", timeout: 600 * time.Second})
- if t.supportedBuildmode("c-archive") {
- t.registerTest("cgo_testcarchive", cgoHeading, &goTest{pkg: "cmd/cgo/internal/testcarchive", timeout: 5 * time.Minute})
- }
- if t.supportedBuildmode("c-shared") {
- t.registerTest("cgo_testcshared", cgoHeading, &goTest{pkg: "cmd/cgo/internal/testcshared", timeout: 5 * time.Minute})
- }
- if t.supportedBuildmode("shared") {
- t.registerTest("cgo_testshared", cgoHeading, &goTest{pkg: "cmd/cgo/internal/testshared", timeout: 600 * time.Second})
- }
- if t.supportedBuildmode("plugin") {
- t.registerTest("cgo_testplugin", cgoHeading, &goTest{pkg: "cmd/cgo/internal/testplugin", timeout: 600 * time.Second})
- }
- t.registerTest("cgo_testsanitizers", cgoHeading, &goTest{pkg: "cmd/cgo/internal/testsanitizers", timeout: 5 * time.Minute})
- if t.hasBash() && goos != "android" && !t.iOS() && gohostos != "windows" {
- t.registerTest("cgo_errors", cgoHeading, &goTest{pkg: "cmd/cgo/internal/testerrors", timeout: 5 * time.Minute})
- }
- }
+ t.registerTest("cgo_testgodefs", cgoHeading, &goTest{pkg: "cmd/cgo/internal/testgodefs", timeout: 5 * time.Minute})
+ t.registerTest("cgo_testso", cgoHeading, &goTest{pkg: "cmd/cgo/internal/testso", timeout: 600 * time.Second})
+ t.registerTest("cgo_testsovar", cgoHeading, &goTest{pkg: "cmd/cgo/internal/testsovar", timeout: 600 * time.Second})
+ t.registerTest("cgo_testcarchive", cgoHeading, &goTest{pkg: "cmd/cgo/internal/testcarchive", timeout: 5 * time.Minute})
+ t.registerTest("cgo_testcshared", cgoHeading, &goTest{pkg: "cmd/cgo/internal/testcshared", timeout: 5 * time.Minute})
+ t.registerTest("cgo_testshared", cgoHeading, &goTest{pkg: "cmd/cgo/internal/testshared", timeout: 600 * time.Second})
+ t.registerTest("cgo_testplugin", cgoHeading, &goTest{pkg: "cmd/cgo/internal/testplugin", timeout: 600 * time.Second})
+ t.registerTest("cgo_testsanitizers", cgoHeading, &goTest{pkg: "cmd/cgo/internal/testsanitizers", timeout: 5 * time.Minute})
+ t.registerTest("cgo_errors", cgoHeading, &goTest{pkg: "cmd/cgo/internal/testerrors", timeout: 5 * time.Minute})
if goos != "android" && !t.iOS() {
// Only start multiple test dir shards on builders,
// MSanSupported reports whether goos/goarch supports the memory
// sanitizer option.
-// There is a copy of this function in misc/cgo/testsanitizers/cc_test.go.
func MSanSupported(goos, goarch string) bool {
switch goos {
case "linux":
// ASanSupported reports whether goos/goarch supports the address
// sanitizer option.
-// There is a copy of this function in misc/cgo/testsanitizers/cc_test.go.
func ASanSupported(goos, goarch string) bool {
switch goos {
case "linux":
}
}
+// MustHaveBuildMode reports whether the current system can build programs in
+// the given build mode.
+// If not, MustHaveBuildMode calls t.Skip with an explanation.
+func MustHaveBuildMode(t testing.TB, buildmode string) {
+ if !platform.BuildModeSupported(runtime.Compiler, buildmode, runtime.GOOS, runtime.GOARCH) {
+ t.Skipf("skipping test: build mode %s on %s/%s is not supported by the %s compiler", buildmode, runtime.GOOS, runtime.GOARCH, runtime.Compiler)
+ }
+}
+
// HasSymlink reports whether the current system can use os.Symlink.
func HasSymlink() bool {
ok, _ := hasSymlink()