mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
all: enable more tests on macOS/ARM64
On macOS, we can do "go build", can exec, and have the source tree available, so we can enable more tests. Skip ones that don't work. Most of them are due to that it requires external linking (for now) and some tests don't work with external linking (e.g. runtime deadlock detection). For them, helper functions CanInternalLink/MustInternalLink are introduced. I still want to have internal linking implemented, but it is still a good idea to identify which tests don't work with external linking. Updates #38485. Change-Id: I6b14697573cf3f371daf54b9ddd792acf232f2f2 Reviewed-on: https://go-review.googlesource.com/c/go/+/260719 Trust: Cherry Zhang <cherryyz@google.com> Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
parent
23e9e0c7f0
commit
f8df205e74
13 changed files with 123 additions and 20 deletions
|
|
@ -58,11 +58,10 @@ func init() {
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "android", "js":
|
case "android", "js":
|
||||||
canRun = false
|
canRun = false
|
||||||
case "darwin", "ios":
|
case "darwin":
|
||||||
switch runtime.GOARCH {
|
// nothing to do
|
||||||
case "arm64":
|
case "ios":
|
||||||
canRun = false
|
canRun = false
|
||||||
}
|
|
||||||
case "linux":
|
case "linux":
|
||||||
switch runtime.GOARCH {
|
switch runtime.GOARCH {
|
||||||
case "arm":
|
case "arm":
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ func MSanSupported(goos, goarch string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustLinkExternal reports whether goos/goarch requires external linking.
|
// MustLinkExternal reports whether goos/goarch requires external linking.
|
||||||
|
// (This is the opposite of internal/testenv.CanInternalLink. Keep them in sync.)
|
||||||
func MustLinkExternal(goos, goarch string) bool {
|
func MustLinkExternal(goos, goarch string) bool {
|
||||||
switch goos {
|
switch goos {
|
||||||
case "android":
|
case "android":
|
||||||
|
|
|
||||||
18
src/cmd/internal/sys/supported_test.go
Normal file
18
src/cmd/internal/sys/supported_test.go
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2020 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.
|
||||||
|
|
||||||
|
package sys
|
||||||
|
|
||||||
|
import (
|
||||||
|
"internal/testenv"
|
||||||
|
"runtime"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMustLinkExternalMatchesTestenv(t *testing.T) {
|
||||||
|
// MustLinkExternal and testenv.CanInternalLink are the exact opposite.
|
||||||
|
if b := MustLinkExternal(runtime.GOOS, runtime.GOARCH); b != !testenv.CanInternalLink() {
|
||||||
|
t.Fatalf("MustLinkExternal() == %v, testenv.CanInternalLink() == %v, don't match", b, testenv.CanInternalLink())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -238,6 +238,10 @@ func TestSizes(t *testing.T) {
|
||||||
if runtime.GOOS == "plan9" {
|
if runtime.GOOS == "plan9" {
|
||||||
t.Skip("skipping on plan9; no DWARF symbol table in executables")
|
t.Skip("skipping on plan9; no DWARF symbol table in executables")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// External linking may bring in C symbols with unknown size. Skip.
|
||||||
|
testenv.MustInternalLink(t)
|
||||||
|
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// DWARF sizes should never be -1.
|
// DWARF sizes should never be -1.
|
||||||
|
|
@ -919,6 +923,7 @@ func TestAbstractOriginSanityIssue26237(t *testing.T) {
|
||||||
|
|
||||||
func TestRuntimeTypeAttrInternal(t *testing.T) {
|
func TestRuntimeTypeAttrInternal(t *testing.T) {
|
||||||
testenv.MustHaveGoBuild(t)
|
testenv.MustHaveGoBuild(t)
|
||||||
|
testenv.MustInternalLink(t)
|
||||||
|
|
||||||
if runtime.GOOS == "plan9" {
|
if runtime.GOOS == "plan9" {
|
||||||
t.Skip("skipping on plan9; no DWARF symbol table in executables")
|
t.Skip("skipping on plan9; no DWARF symbol table in executables")
|
||||||
|
|
@ -1018,6 +1023,9 @@ func main() {
|
||||||
t.Fatalf("*main.X DIE had no runtime type attr. DIE: %v", dies[0])
|
t.Fatalf("*main.X DIE had no runtime type attr. DIE: %v", dies[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" {
|
||||||
|
return // everything is PIE on ARM64, addresses are relocated
|
||||||
|
}
|
||||||
if rtAttr.(uint64)+types.Addr != addr {
|
if rtAttr.(uint64)+types.Addr != addr {
|
||||||
t.Errorf("DWARF type offset was %#x+%#x, but test program said %#x", rtAttr.(uint64), types.Addr, addr)
|
t.Errorf("DWARF type offset was %#x+%#x, but test program said %#x", rtAttr.(uint64), types.Addr, addr)
|
||||||
}
|
}
|
||||||
|
|
@ -1203,6 +1211,15 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When external linking, we put all symbols in the symbol table (so the
|
||||||
|
// external linker can find them). Skip the symbol table check.
|
||||||
|
// TODO: maybe there is some way to tell the external linker not to put
|
||||||
|
// those symbols in the executable's symbol table? Prefix the symbol name
|
||||||
|
// with "." or "L" to pretend it is a label?
|
||||||
|
if !testenv.CanInternalLink() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
syms, err := f.Symbols()
|
syms, err := f.Symbols()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error reading symbols: %v", err)
|
t.Fatalf("error reading symbols: %v", err)
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUndefinedRelocErrors(t *testing.T) {
|
func TestUndefinedRelocErrors(t *testing.T) {
|
||||||
t.Parallel()
|
|
||||||
testenv.MustHaveGoBuild(t)
|
testenv.MustHaveGoBuild(t)
|
||||||
|
|
||||||
|
// When external linking, symbols may be defined externally, so we allow
|
||||||
|
// undefined symbols and let external linker resolve. Skip the test.
|
||||||
|
testenv.MustInternalLink(t)
|
||||||
|
|
||||||
|
t.Parallel()
|
||||||
dir, err := ioutil.TempDir("", "go-build")
|
dir, err := ioutil.TempDir("", "go-build")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|
|
||||||
|
|
@ -181,6 +181,7 @@ main.x: relocation target main.zero not defined
|
||||||
func TestIssue33979(t *testing.T) {
|
func TestIssue33979(t *testing.T) {
|
||||||
testenv.MustHaveGoBuild(t)
|
testenv.MustHaveGoBuild(t)
|
||||||
testenv.MustHaveCGO(t)
|
testenv.MustHaveCGO(t)
|
||||||
|
testenv.MustInternalLink(t)
|
||||||
|
|
||||||
// Skip test on platforms that do not support cgo internal linking.
|
// Skip test on platforms that do not support cgo internal linking.
|
||||||
switch runtime.GOARCH {
|
switch runtime.GOARCH {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,11 @@ func canInternalLink() bool {
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "aix":
|
case "aix":
|
||||||
return false
|
return false
|
||||||
|
case "darwin":
|
||||||
|
switch runtime.GOARCH {
|
||||||
|
case "arm64":
|
||||||
|
return false
|
||||||
|
}
|
||||||
case "dragonfly":
|
case "dragonfly":
|
||||||
return false
|
return false
|
||||||
case "freebsd":
|
case "freebsd":
|
||||||
|
|
|
||||||
|
|
@ -173,6 +173,9 @@ func testGoExec(t *testing.T, iscgo, isexternallinker bool) {
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" {
|
||||||
|
return true // On darwin/arm64 everything is PIE
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMinimalFeatures(t *testing.T) {
|
func TestMinimalFeatures(t *testing.T) {
|
||||||
|
// TODO: maybe do MustSupportFeatureDectection(t) ?
|
||||||
if runtime.GOARCH == "arm64" {
|
if runtime.GOARCH == "arm64" {
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "linux", "android":
|
case "linux", "android":
|
||||||
|
|
@ -36,6 +37,13 @@ func MustHaveDebugOptionsSupport(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MustSupportFeatureDectection(t *testing.T) {
|
||||||
|
if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" {
|
||||||
|
t.Skipf("CPU feature detection is not supported on %s/%s", runtime.GOOS, runtime.GOARCH)
|
||||||
|
}
|
||||||
|
// TODO: maybe there are other platforms?
|
||||||
|
}
|
||||||
|
|
||||||
func runDebugOptionsTest(t *testing.T, test string, options string) {
|
func runDebugOptionsTest(t *testing.T, test string, options string) {
|
||||||
MustHaveDebugOptionsSupport(t)
|
MustHaveDebugOptionsSupport(t)
|
||||||
|
|
||||||
|
|
@ -58,6 +66,7 @@ func runDebugOptionsTest(t *testing.T, test string, options string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDisableAllCapabilities(t *testing.T) {
|
func TestDisableAllCapabilities(t *testing.T) {
|
||||||
|
MustSupportFeatureDectection(t)
|
||||||
runDebugOptionsTest(t, "TestAllCapabilitiesDisabled", "cpu.all=off")
|
runDebugOptionsTest(t, "TestAllCapabilitiesDisabled", "cpu.all=off")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,12 +43,8 @@ func HasGoBuild() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "android", "js":
|
case "android", "js", "ios":
|
||||||
return false
|
return false
|
||||||
case "darwin", "ios":
|
|
||||||
if runtime.GOARCH == "arm64" {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -122,12 +118,8 @@ func GoTool() (string, error) {
|
||||||
// using os.StartProcess or (more commonly) exec.Command.
|
// using os.StartProcess or (more commonly) exec.Command.
|
||||||
func HasExec() bool {
|
func HasExec() bool {
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "js":
|
case "js", "ios":
|
||||||
return false
|
return false
|
||||||
case "darwin", "ios":
|
|
||||||
if runtime.GOARCH == "arm64" {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -135,10 +127,8 @@ func HasExec() bool {
|
||||||
// HasSrc reports whether the entire source tree is available under GOROOT.
|
// HasSrc reports whether the entire source tree is available under GOROOT.
|
||||||
func HasSrc() bool {
|
func HasSrc() bool {
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "darwin", "ios":
|
case "ios":
|
||||||
if runtime.GOARCH == "arm64" {
|
return false
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -202,6 +192,32 @@ func MustHaveCGO(t testing.TB) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CanInternalLink reports whether the current system can link programs with
|
||||||
|
// internal linking.
|
||||||
|
// (This is the opposite of cmd/internal/sys.MustLinkExternal. Keep them in sync.)
|
||||||
|
func CanInternalLink() bool {
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "android":
|
||||||
|
if runtime.GOARCH != "arm64" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case "darwin", "ios":
|
||||||
|
if runtime.GOARCH == "arm64" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustInternalLink checks that the current system can link programs with internal
|
||||||
|
// linking.
|
||||||
|
// If not, MustInternalLink calls t.Skip with an explanation.
|
||||||
|
func MustInternalLink(t testing.TB) {
|
||||||
|
if !CanInternalLink() {
|
||||||
|
t.Skipf("skipping test: internal linking on %s/%s is not supported", runtime.GOOS, runtime.GOARCH)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// HasSymlink reports whether the current system can use os.Symlink.
|
// HasSymlink reports whether the current system can use os.Symlink.
|
||||||
func HasSymlink() bool {
|
func HasSymlink() bool {
|
||||||
ok, _ := hasSymlink()
|
ok, _ := hasSymlink()
|
||||||
|
|
|
||||||
|
|
@ -605,6 +605,10 @@ func TestExtraFiles(t *testing.T) {
|
||||||
testenv.MustHaveExec(t)
|
testenv.MustHaveExec(t)
|
||||||
testenv.MustHaveGoBuild(t)
|
testenv.MustHaveGoBuild(t)
|
||||||
|
|
||||||
|
// This test runs with cgo disabled. External linking needs cgo, so
|
||||||
|
// it doesn't work if external linking is required.
|
||||||
|
testenv.MustInternalLink(t)
|
||||||
|
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
t.Skipf("skipping test on %q", runtime.GOOS)
|
t.Skipf("skipping test on %q", runtime.GOOS)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -181,6 +181,9 @@ func TestCrashHandler(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDeadlock(t *testing.T, name string) {
|
func testDeadlock(t *testing.T, name string) {
|
||||||
|
// External linking brings in cgo, causing deadlock detection not working.
|
||||||
|
testenv.MustInternalLink(t)
|
||||||
|
|
||||||
output := runTestProg(t, "testprog", name)
|
output := runTestProg(t, "testprog", name)
|
||||||
want := "fatal error: all goroutines are asleep - deadlock!\n"
|
want := "fatal error: all goroutines are asleep - deadlock!\n"
|
||||||
if !strings.HasPrefix(output, want) {
|
if !strings.HasPrefix(output, want) {
|
||||||
|
|
@ -205,6 +208,9 @@ func TestLockedDeadlock2(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGoexitDeadlock(t *testing.T) {
|
func TestGoexitDeadlock(t *testing.T) {
|
||||||
|
// External linking brings in cgo, causing deadlock detection not working.
|
||||||
|
testenv.MustInternalLink(t)
|
||||||
|
|
||||||
output := runTestProg(t, "testprog", "GoexitDeadlock")
|
output := runTestProg(t, "testprog", "GoexitDeadlock")
|
||||||
want := "no goroutines (main called runtime.Goexit) - deadlock!"
|
want := "no goroutines (main called runtime.Goexit) - deadlock!"
|
||||||
if !strings.Contains(output, want) {
|
if !strings.Contains(output, want) {
|
||||||
|
|
@ -290,6 +296,9 @@ func TestRecursivePanic4(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGoexitCrash(t *testing.T) {
|
func TestGoexitCrash(t *testing.T) {
|
||||||
|
// External linking brings in cgo, causing deadlock detection not working.
|
||||||
|
testenv.MustInternalLink(t)
|
||||||
|
|
||||||
output := runTestProg(t, "testprog", "GoexitExit")
|
output := runTestProg(t, "testprog", "GoexitExit")
|
||||||
want := "no goroutines (main called runtime.Goexit) - deadlock!"
|
want := "no goroutines (main called runtime.Goexit) - deadlock!"
|
||||||
if !strings.Contains(output, want) {
|
if !strings.Contains(output, want) {
|
||||||
|
|
@ -348,6 +357,9 @@ func TestBreakpoint(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGoexitInPanic(t *testing.T) {
|
func TestGoexitInPanic(t *testing.T) {
|
||||||
|
// External linking brings in cgo, causing deadlock detection not working.
|
||||||
|
testenv.MustInternalLink(t)
|
||||||
|
|
||||||
// see issue 8774: this code used to trigger an infinite recursion
|
// see issue 8774: this code used to trigger an infinite recursion
|
||||||
output := runTestProg(t, "testprog", "GoexitInPanic")
|
output := runTestProg(t, "testprog", "GoexitInPanic")
|
||||||
want := "fatal error: no goroutines (main called runtime.Goexit) - deadlock!"
|
want := "fatal error: no goroutines (main called runtime.Goexit) - deadlock!"
|
||||||
|
|
@ -412,6 +424,9 @@ func TestPanicAfterGoexit(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRecoveredPanicAfterGoexit(t *testing.T) {
|
func TestRecoveredPanicAfterGoexit(t *testing.T) {
|
||||||
|
// External linking brings in cgo, causing deadlock detection not working.
|
||||||
|
testenv.MustInternalLink(t)
|
||||||
|
|
||||||
output := runTestProg(t, "testprog", "RecoveredPanicAfterGoexit")
|
output := runTestProg(t, "testprog", "RecoveredPanicAfterGoexit")
|
||||||
want := "fatal error: no goroutines (main called runtime.Goexit) - deadlock!"
|
want := "fatal error: no goroutines (main called runtime.Goexit) - deadlock!"
|
||||||
if !strings.HasPrefix(output, want) {
|
if !strings.HasPrefix(output, want) {
|
||||||
|
|
@ -420,6 +435,9 @@ func TestRecoveredPanicAfterGoexit(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRecoverBeforePanicAfterGoexit(t *testing.T) {
|
func TestRecoverBeforePanicAfterGoexit(t *testing.T) {
|
||||||
|
// External linking brings in cgo, causing deadlock detection not working.
|
||||||
|
testenv.MustInternalLink(t)
|
||||||
|
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
output := runTestProg(t, "testprog", "RecoverBeforePanicAfterGoexit")
|
output := runTestProg(t, "testprog", "RecoverBeforePanicAfterGoexit")
|
||||||
want := "fatal error: no goroutines (main called runtime.Goexit) - deadlock!"
|
want := "fatal error: no goroutines (main called runtime.Goexit) - deadlock!"
|
||||||
|
|
@ -429,6 +447,9 @@ func TestRecoverBeforePanicAfterGoexit(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRecoverBeforePanicAfterGoexit2(t *testing.T) {
|
func TestRecoverBeforePanicAfterGoexit2(t *testing.T) {
|
||||||
|
// External linking brings in cgo, causing deadlock detection not working.
|
||||||
|
testenv.MustInternalLink(t)
|
||||||
|
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
output := runTestProg(t, "testprog", "RecoverBeforePanicAfterGoexit2")
|
output := runTestProg(t, "testprog", "RecoverBeforePanicAfterGoexit2")
|
||||||
want := "fatal error: no goroutines (main called runtime.Goexit) - deadlock!"
|
want := "fatal error: no goroutines (main called runtime.Goexit) - deadlock!"
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@ func TestFakeTime(t *testing.T) {
|
||||||
t.Skip("faketime not supported on windows")
|
t.Skip("faketime not supported on windows")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Faketime is advanced in checkdead. External linking brings in cgo,
|
||||||
|
// causing checkdead not working.
|
||||||
|
testenv.MustInternalLink(t)
|
||||||
|
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
exe, err := buildTestProg(t, "testfaketime", "-tags=faketime")
|
exe, err := buildTestProg(t, "testfaketime", "-tags=faketime")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue