]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/dist: refine test conditions and enable more cgo tests on Android, iOS
authorAustin Clements <austin@google.com>
Wed, 26 Apr 2023 16:16:26 +0000 (12:16 -0400)
committerAustin Clements <austin@google.com>
Fri, 19 May 2023 01:37:31 +0000 (01:37 +0000)
This CL moves many cgo test conditions out of dist and into the tests
themselves, now that they can use the testenv.Must* helpers.

This refines a lot of the conditions, which happens to have the effect
of enabling many tests on Android and iOS that are disabled by
too-coarse GOOS checks in dist today.

Fixes #15919.

Change-Id: I2947526b08928d2f7f89f107b5b2403b32092ed8
Reviewed-on: https://go-review.googlesource.com/c/go/+/495918
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Austin Clements <austin@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
24 files changed:
src/cmd/cgo/internal/testcarchive/carchive_test.go
src/cmd/cgo/internal/testcshared/cshared_test.go
src/cmd/cgo/internal/testerrors/argposition_test.go
src/cmd/cgo/internal/testerrors/badsym_test.go
src/cmd/cgo/internal/testerrors/errors_test.go
src/cmd/cgo/internal/testerrors/ptr_test.go
src/cmd/cgo/internal/testfortran/fortran_test.go
src/cmd/cgo/internal/testgodefs/testgodefs_test.go
src/cmd/cgo/internal/testlife/life_test.go
src/cmd/cgo/internal/testplugin/plugin_test.go
src/cmd/cgo/internal/testsanitizers/asan_test.go
src/cmd/cgo/internal/testsanitizers/cc_test.go
src/cmd/cgo/internal/testsanitizers/cshared_test.go
src/cmd/cgo/internal/testsanitizers/msan_test.go
src/cmd/cgo/internal/testsanitizers/tsan_test.go
src/cmd/cgo/internal/testshared/shared_test.go
src/cmd/cgo/internal/testso/noso_test.go [deleted file]
src/cmd/cgo/internal/testso/so_test.go
src/cmd/cgo/internal/testsovar/noso_test.go [deleted file]
src/cmd/cgo/internal/testsovar/so_test.go
src/cmd/cgo/internal/teststdio/stdio_test.go
src/cmd/dist/test.go
src/internal/platform/supported.go
src/internal/testenv/testenv.go

index a92ec46c1a389ea4faeec93039fd9f2b244695b6..a367bca2f19af722a813d3a71bbd14f79b7d9942 100644 (file)
@@ -461,6 +461,8 @@ func checkELFArchiveObject(t *testing.T, arname string, off int64, obj io.Reader
 
 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"))
@@ -504,6 +506,8 @@ func TestEarlySignalHandler(t *testing.T) {
                t.Skip("skipping signal test on Windows")
        }
        testenv.MustHaveGoBuild(t)
+       testenv.MustHaveCGO(t)
+       testenv.MustHaveBuildMode(t, "c-archive")
 
        if !testWork {
                defer func() {
@@ -643,6 +647,9 @@ func checkSignalForwardingTest(t *testing.T) {
        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
@@ -772,6 +779,8 @@ func TestOsSignal(t *testing.T) {
                t.Skip("skipping signal test on Windows")
        }
        testenv.MustHaveGoBuild(t)
+       testenv.MustHaveCGO(t)
+       testenv.MustHaveBuildMode(t, "c-archive")
 
        if !testWork {
                defer func() {
@@ -811,6 +820,8 @@ func TestSigaltstack(t *testing.T) {
                t.Skip("skipping signal test on Windows")
        }
        testenv.MustHaveGoBuild(t)
+       testenv.MustHaveCGO(t)
+       testenv.MustHaveBuildMode(t, "c-archive")
 
        if !testWork {
                defer func() {
@@ -860,10 +871,10 @@ func TestExtar(t *testing.T) {
        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() {
@@ -907,6 +918,8 @@ func TestPIE(t *testing.T) {
                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" {
@@ -1002,6 +1015,8 @@ func TestSIGPROF(t *testing.T) {
                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()
 
@@ -1116,6 +1131,9 @@ func TestCompileWithoutShared(t *testing.T) {
 // 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"))
        }
@@ -1156,6 +1174,9 @@ func TestCachedInstall(t *testing.T) {
 // Issue 35294.
 func TestManyCalls(t *testing.T) {
        testenv.MustHaveGoBuild(t)
+       testenv.MustHaveCGO(t)
+       testenv.MustHaveBuildMode(t, "c-archive")
+
        t.Parallel()
 
        if !testWork {
@@ -1215,6 +1236,8 @@ func TestPreemption(t *testing.T) {
                t.Skip("skipping asynchronous preemption test with gccgo")
        }
        testenv.MustHaveGoBuild(t)
+       testenv.MustHaveCGO(t)
+       testenv.MustHaveBuildMode(t, "c-archive")
 
        t.Parallel()
 
index 2b572498170f1180884549045e879b4944b3dbcf..fbbe66662f9752e2cf3c4abd8c58986cfd107862 100644 (file)
@@ -12,6 +12,7 @@ import (
        "encoding/binary"
        "flag"
        "fmt"
+       "internal/testenv"
        "log"
        "os"
        "os/exec"
@@ -50,6 +51,11 @@ func testMain(m *testing.M) int {
                        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")
@@ -390,6 +396,10 @@ var (
 )
 
 func createHeadersOnce(t *testing.T) {
+       testenv.MustHaveGoBuild(t)
+       testenv.MustHaveCGO(t)
+       testenv.MustHaveBuildMode(t, "c-shared")
+
        headersOnce.Do(func() {
                headersErr = createHeaders()
        })
@@ -413,6 +423,9 @@ func cleanupAndroid() {
 
 // test0: exported symbols in shared lib are accessible.
 func TestExportedSymbols(t *testing.T) {
+       testenv.MustHaveCGO(t)
+       testenv.MustHaveExec(t)
+
        t.Parallel()
 
        cmd := "testp0"
@@ -516,6 +529,10 @@ func TestNumberOfExportedFunctions(t *testing.T) {
        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) {
@@ -528,12 +545,13 @@ func TestNumberOfExportedFunctions(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)
@@ -557,12 +575,14 @@ func TestExportedSymbolsWithDynamicLoad(t *testing.T) {
 
 // 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)
@@ -597,6 +617,9 @@ func TestUnexportedSymbols(t *testing.T) {
 
 // test3: tests main.main is exported on android.
 func TestMainExportedOnAndroid(t *testing.T) {
+       testenv.MustHaveCGO(t)
+       testenv.MustHaveExec(t)
+
        t.Parallel()
 
        switch GOOS {
@@ -624,6 +647,13 @@ func TestMainExportedOnAndroid(t *testing.T) {
 }
 
 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,
@@ -655,34 +685,25 @@ func testSignalHandlers(t *testing.T, pkgname, cfile, cmd string) {
 // 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)
@@ -717,6 +738,10 @@ func TestPIE(t *testing.T) {
 
 // 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)
@@ -817,6 +842,9 @@ func TestGo2C2Go(t *testing.T) {
        case "android":
                t.Skip("test fails on android; issue 29087")
        }
+       testenv.MustHaveGoBuild(t)
+       testenv.MustHaveCGO(t)
+       testenv.MustHaveBuildMode(t, "c-shared")
 
        t.Parallel()
 
@@ -866,6 +894,8 @@ func TestGo2C2Go(t *testing.T) {
 }
 
 func TestIssue36233(t *testing.T) {
+       testenv.MustHaveCGO(t)
+
        t.Parallel()
 
        // Test that the export header uses GoComplex64 and GoComplex128
index dd26663df2e889237358aebf23a29dc8e5714e02..0876dc4caf35aac9704502be9540c8ca8617813b 100644 (file)
@@ -12,6 +12,7 @@ import (
        "go/ast"
        "go/parser"
        "go/token"
+       "internal/testenv"
        "os"
        "os/exec"
        "path/filepath"
@@ -65,6 +66,9 @@ func (v *Visitor) Visit(node ast.Node) ast.Visitor {
 }
 
 func TestArgumentsPositions(t *testing.T) {
+       testenv.MustHaveCGO(t)
+       testenv.MustHaveExec(t)
+
        testdata, err := filepath.Abs("testdata")
        if err != nil {
                t.Fatal(err)
index bc3ba2b489f2d120f831f656e74e1b373a0a65a5..6c87977bd1dcc1061704b107cfbdaa6bee5078b7 100644 (file)
@@ -6,6 +6,8 @@ package errorstest
 
 import (
        "bytes"
+       "cmd/internal/quoted"
+       "internal/testenv"
        "os"
        "os/exec"
        "path/filepath"
@@ -39,6 +41,9 @@ func main() {
 `
 
 func TestBadSymbol(t *testing.T) {
+       testenv.MustHaveGoBuild(t)
+       testenv.MustHaveCGO(t)
+
        dir := t.TempDir()
 
        mkdir := func(base string) string {
@@ -167,7 +172,14 @@ func TestBadSymbol(t *testing.T) {
 }
 
 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'
index 5147e51aa17b8252c8ae02c61ea177eb80171276..486530e186c610fc96d26cfc058e6ac4305593d5 100644 (file)
@@ -24,6 +24,7 @@ func path(file string) string {
 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))
@@ -91,6 +92,8 @@ func expect(t *testing.T, file string, errors []*regexp.Regexp) {
 }
 
 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 {
@@ -137,6 +140,7 @@ func TestToleratesOptimizationFlag(t *testing.T) {
                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"))
@@ -150,6 +154,7 @@ func TestToleratesOptimizationFlag(t *testing.T) {
 }
 
 func TestMallocCrashesOnNil(t *testing.T) {
+       testenv.MustHaveCGO(t)
        testenv.MustHaveGoRun(t)
        t.Parallel()
 
index 24851cbf35810f6f1272c216e8468c2e63679c6f..149445899fee0b0e2496812e01153283b5f9fb12 100644 (file)
@@ -10,9 +10,11 @@ import (
        "bytes"
        "flag"
        "fmt"
+       "internal/testenv"
        "os"
        "os/exec"
        "path/filepath"
+       "runtime"
        "strings"
        "sync/atomic"
        "testing"
@@ -434,6 +436,13 @@ var ptrTests = []ptrTest{
 }
 
 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 != "" {
index fa4f0e604940a9c08fe928e013255166bfeb742f..eaa36ac7f9b0e8e4071f7e7063c51b2057288881 100644 (file)
@@ -17,6 +17,7 @@ import (
 
 func TestFortran(t *testing.T) {
        testenv.MustHaveGoRun(t)
+       testenv.MustHaveCGO(t)
 
        // Find the FORTRAN compiler.
        fc := os.Getenv("FC")
index 7b149ffe20e4d7948a7eacc7ca2cc6fd18037eb9..8138b7fa3d5a5fe611fbe19f27e5d02a2baab594 100644 (file)
@@ -32,6 +32,7 @@ var filePrefixes = []string{
 
 func TestGoDefs(t *testing.T) {
        testenv.MustHaveGoRun(t)
+       testenv.MustHaveCGO(t)
 
        testdata, err := filepath.Abs("testdata")
        if err != nil {
index e6b371fe7c0b2ca2e8306c5ee3561d0da7e262a8..7beeaa98238f9ed44e04852d85c53168aff6bf2d 100644 (file)
@@ -46,10 +46,8 @@ func testMain(m *testing.M) int {
 
 // 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()
index 84ea839a2f423f70124ba1f7ee026164b9da576c..e211a96304a938b2348805ca3e649a325c618381 100644 (file)
@@ -9,10 +9,13 @@ import (
        "context"
        "flag"
        "fmt"
+       "internal/platform"
+       "internal/testenv"
        "log"
        "os"
        "os/exec"
        "path/filepath"
+       "runtime"
        "strings"
        "testing"
        "time"
@@ -44,6 +47,17 @@ func prettyPrintf(format string, args ...interface{}) {
 }
 
 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)
index 9bf48915e24c19c19a6cf7e505713c45ccf78039..7db356244a85a8bd164468acca74dcd9f736e0ec 100644 (file)
@@ -8,11 +8,15 @@ package sanitizers_test
 
 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)
@@ -22,7 +26,7 @@ func TestASAN(t *testing.T) {
                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
@@ -102,6 +106,8 @@ func TestASAN(t *testing.T) {
 }
 
 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 {
@@ -112,7 +118,7 @@ func TestASANLinkerX(t *testing.T) {
                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) {
index 5facb37e68a516247c2cf32795dfa9dd081db716..6eb5a64f9b237a1d167677b29c76869b5f77c902 100644 (file)
@@ -562,27 +562,3 @@ func hangProneCmd(name string, arg ...string) *exec.Cmd {
        }
        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
-       }
-}
index 5a8e93d101ca872b21d2d28bc722ac5c0cfde257..f26c50a6219a5128183f014f04465da9acc459cf 100644 (file)
@@ -8,12 +8,18 @@ package sanitizers_test
 
 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)
 
@@ -50,7 +56,7 @@ func TestShared(t *testing.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
                }
index a05c545d2afdad5c1e1abc9ed9e69541d0cd0330..1a22b5246c0a33c477a2f6291ca6c8aad9af0051 100644 (file)
@@ -7,6 +7,7 @@
 package sanitizers_test
 
 import (
+       "internal/platform"
        "strings"
        "testing"
 )
@@ -21,7 +22,7 @@ func TestMSAN(t *testing.T) {
                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)
        }
 
index 6f70ebfef5f6ec8e78e2c63bb889d445a7ccb154..8e758e6ea7c85819131ebb99aa3309a35e08c0df 100644 (file)
@@ -7,11 +7,15 @@
 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)
index 34cf3f3141b0176a202f5252e22f5d9c0842abe5..05e87b9d50c76c51c26b37f1d0d6833ca51ec84f 100644 (file)
@@ -12,6 +12,8 @@ import (
        "flag"
        "fmt"
        "go/build"
+       "internal/platform"
+       "internal/testenv"
        "io"
        "log"
        "os"
@@ -91,6 +93,17 @@ func goCmd(t *testing.T, args ...string) string {
 
 // 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)
@@ -531,6 +544,7 @@ func TestTrivialPIE(t *testing.T) {
        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)
@@ -539,6 +553,8 @@ func TestTrivialPIE(t *testing.T) {
 }
 
 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)
diff --git a/src/cmd/cgo/internal/testso/noso_test.go b/src/cmd/cgo/internal/testso/noso_test.go
deleted file mode 100644 (file)
index 45b13e1..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-// 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.
index 5c460d21b60cea140175e5d5212b28199fead2e9..a2cd056c45ae630ff281faed7d2037a0112f7854 100644 (file)
@@ -2,11 +2,10 @@
 // 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"
@@ -16,25 +15,13 @@ import (
        "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 {
diff --git a/src/cmd/cgo/internal/testsovar/noso_test.go b/src/cmd/cgo/internal/testsovar/noso_test.go
deleted file mode 100644 (file)
index 45b13e1..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-// 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.
index 5c460d21b60cea140175e5d5212b28199fead2e9..a2cd056c45ae630ff281faed7d2037a0112f7854 100644 (file)
@@ -2,11 +2,10 @@
 // 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"
@@ -16,25 +15,13 @@ import (
        "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 {
index fad367e30cab31c64f07d58e22d458e199beded0..f191c50a42744ae3c9f4a3b49bfc02407735c7af 100644 (file)
@@ -48,9 +48,7 @@ func testMain(m *testing.M) int {
 // 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",
index b6775cacbb0180e518e12f579a0c3fa74ecf1382..9fed4b9e20cee2178ef30f7c2ed1b82acdf53530 100644 (file)
@@ -847,40 +847,22 @@ func (t *tester) registerTests() {
        }
 
        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,
index 1287838edb81cce433ea13e9e38542eeafbe457a..e762bb304e8070dadcc910548b58bdb5c235ec89 100644 (file)
@@ -24,7 +24,6 @@ func RaceDetectorSupported(goos, goarch string) bool {
 
 // 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":
@@ -38,7 +37,6 @@ func MSanSupported(goos, goarch string) bool {
 
 // 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":
index 70606242d66b725eeaa6824fe8d39df1d250ba1c..31b58ddba7ef7adf10a959cb7ffe0cf2637f1608 100644 (file)
@@ -371,6 +371,15 @@ func MustInternalLink(t testing.TB, withCgo bool) {
        }
 }
 
+// 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()