Skip to content

Commit f8df205

Browse files
committed
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 <[email protected]> Run-TryBot: Cherry Zhang <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]> Reviewed-by: Than McIntosh <[email protected]>
1 parent 23e9e0c commit f8df205

File tree

13 files changed

+123
-20
lines changed

13 files changed

+123
-20
lines changed

src/cmd/go/go_test.go

+4-5
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,10 @@ func init() {
5858
switch runtime.GOOS {
5959
case "android", "js":
6060
canRun = false
61-
case "darwin", "ios":
62-
switch runtime.GOARCH {
63-
case "arm64":
64-
canRun = false
65-
}
61+
case "darwin":
62+
// nothing to do
63+
case "ios":
64+
canRun = false
6665
case "linux":
6766
switch runtime.GOARCH {
6867
case "arm":

src/cmd/internal/sys/supported.go

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ func MSanSupported(goos, goarch string) bool {
3232
}
3333

3434
// MustLinkExternal reports whether goos/goarch requires external linking.
35+
// (This is the opposite of internal/testenv.CanInternalLink. Keep them in sync.)
3536
func MustLinkExternal(goos, goarch string) bool {
3637
switch goos {
3738
case "android":
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2020 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 sys
6+
7+
import (
8+
"internal/testenv"
9+
"runtime"
10+
"testing"
11+
)
12+
13+
func TestMustLinkExternalMatchesTestenv(t *testing.T) {
14+
// MustLinkExternal and testenv.CanInternalLink are the exact opposite.
15+
if b := MustLinkExternal(runtime.GOOS, runtime.GOARCH); b != !testenv.CanInternalLink() {
16+
t.Fatalf("MustLinkExternal() == %v, testenv.CanInternalLink() == %v, don't match", b, testenv.CanInternalLink())
17+
}
18+
}

src/cmd/link/internal/ld/dwarf_test.go

+17
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,10 @@ func TestSizes(t *testing.T) {
238238
if runtime.GOOS == "plan9" {
239239
t.Skip("skipping on plan9; no DWARF symbol table in executables")
240240
}
241+
242+
// External linking may bring in C symbols with unknown size. Skip.
243+
testenv.MustInternalLink(t)
244+
241245
t.Parallel()
242246

243247
// DWARF sizes should never be -1.
@@ -919,6 +923,7 @@ func TestAbstractOriginSanityIssue26237(t *testing.T) {
919923

920924
func TestRuntimeTypeAttrInternal(t *testing.T) {
921925
testenv.MustHaveGoBuild(t)
926+
testenv.MustInternalLink(t)
922927

923928
if runtime.GOOS == "plan9" {
924929
t.Skip("skipping on plan9; no DWARF symbol table in executables")
@@ -1018,6 +1023,9 @@ func main() {
10181023
t.Fatalf("*main.X DIE had no runtime type attr. DIE: %v", dies[0])
10191024
}
10201025

1026+
if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" {
1027+
return // everything is PIE on ARM64, addresses are relocated
1028+
}
10211029
if rtAttr.(uint64)+types.Addr != addr {
10221030
t.Errorf("DWARF type offset was %#x+%#x, but test program said %#x", rtAttr.(uint64), types.Addr, addr)
10231031
}
@@ -1203,6 +1211,15 @@ func main() {
12031211
}
12041212
}
12051213

1214+
// When external linking, we put all symbols in the symbol table (so the
1215+
// external linker can find them). Skip the symbol table check.
1216+
// TODO: maybe there is some way to tell the external linker not to put
1217+
// those symbols in the executable's symbol table? Prefix the symbol name
1218+
// with "." or "L" to pretend it is a label?
1219+
if !testenv.CanInternalLink() {
1220+
return
1221+
}
1222+
12061223
syms, err := f.Symbols()
12071224
if err != nil {
12081225
t.Fatalf("error reading symbols: %v", err)

src/cmd/link/internal/ld/ld_test.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,13 @@ import (
1818
)
1919

2020
func TestUndefinedRelocErrors(t *testing.T) {
21-
t.Parallel()
2221
testenv.MustHaveGoBuild(t)
22+
23+
// When external linking, symbols may be defined externally, so we allow
24+
// undefined symbols and let external linker resolve. Skip the test.
25+
testenv.MustInternalLink(t)
26+
27+
t.Parallel()
2328
dir, err := ioutil.TempDir("", "go-build")
2429
if err != nil {
2530
t.Fatal(err)

src/cmd/link/link_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ main.x: relocation target main.zero not defined
181181
func TestIssue33979(t *testing.T) {
182182
testenv.MustHaveGoBuild(t)
183183
testenv.MustHaveCGO(t)
184+
testenv.MustInternalLink(t)
184185

185186
// Skip test on platforms that do not support cgo internal linking.
186187
switch runtime.GOARCH {

src/cmd/nm/nm_cgo_test.go

+5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ func canInternalLink() bool {
1515
switch runtime.GOOS {
1616
case "aix":
1717
return false
18+
case "darwin":
19+
switch runtime.GOARCH {
20+
case "arm64":
21+
return false
22+
}
1823
case "dragonfly":
1924
return false
2025
case "freebsd":

src/cmd/nm/nm_test.go

+3
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ func testGoExec(t *testing.T, iscgo, isexternallinker bool) {
173173
if runtime.GOOS == "windows" {
174174
return true
175175
}
176+
if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" {
177+
return true // On darwin/arm64 everything is PIE
178+
}
176179
return false
177180
}
178181

src/internal/cpu/cpu_test.go

+9
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
)
1616

1717
func TestMinimalFeatures(t *testing.T) {
18+
// TODO: maybe do MustSupportFeatureDectection(t) ?
1819
if runtime.GOARCH == "arm64" {
1920
switch runtime.GOOS {
2021
case "linux", "android":
@@ -36,6 +37,13 @@ func MustHaveDebugOptionsSupport(t *testing.T) {
3637
}
3738
}
3839

40+
func MustSupportFeatureDectection(t *testing.T) {
41+
if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" {
42+
t.Skipf("CPU feature detection is not supported on %s/%s", runtime.GOOS, runtime.GOARCH)
43+
}
44+
// TODO: maybe there are other platforms?
45+
}
46+
3947
func runDebugOptionsTest(t *testing.T, test string, options string) {
4048
MustHaveDebugOptionsSupport(t)
4149

@@ -58,6 +66,7 @@ func runDebugOptionsTest(t *testing.T, test string, options string) {
5866
}
5967

6068
func TestDisableAllCapabilities(t *testing.T) {
69+
MustSupportFeatureDectection(t)
6170
runDebugOptionsTest(t, "TestAllCapabilitiesDisabled", "cpu.all=off")
6271
}
6372

src/internal/testenv/testenv.go

+30-14
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,8 @@ func HasGoBuild() bool {
4343
return false
4444
}
4545
switch runtime.GOOS {
46-
case "android", "js":
46+
case "android", "js", "ios":
4747
return false
48-
case "darwin", "ios":
49-
if runtime.GOARCH == "arm64" {
50-
return false
51-
}
5248
}
5349
return true
5450
}
@@ -122,23 +118,17 @@ func GoTool() (string, error) {
122118
// using os.StartProcess or (more commonly) exec.Command.
123119
func HasExec() bool {
124120
switch runtime.GOOS {
125-
case "js":
121+
case "js", "ios":
126122
return false
127-
case "darwin", "ios":
128-
if runtime.GOARCH == "arm64" {
129-
return false
130-
}
131123
}
132124
return true
133125
}
134126

135127
// HasSrc reports whether the entire source tree is available under GOROOT.
136128
func HasSrc() bool {
137129
switch runtime.GOOS {
138-
case "darwin", "ios":
139-
if runtime.GOARCH == "arm64" {
140-
return false
141-
}
130+
case "ios":
131+
return false
142132
}
143133
return true
144134
}
@@ -202,6 +192,32 @@ func MustHaveCGO(t testing.TB) {
202192
}
203193
}
204194

195+
// CanInternalLink reports whether the current system can link programs with
196+
// internal linking.
197+
// (This is the opposite of cmd/internal/sys.MustLinkExternal. Keep them in sync.)
198+
func CanInternalLink() bool {
199+
switch runtime.GOOS {
200+
case "android":
201+
if runtime.GOARCH != "arm64" {
202+
return false
203+
}
204+
case "darwin", "ios":
205+
if runtime.GOARCH == "arm64" {
206+
return false
207+
}
208+
}
209+
return true
210+
}
211+
212+
// MustInternalLink checks that the current system can link programs with internal
213+
// linking.
214+
// If not, MustInternalLink calls t.Skip with an explanation.
215+
func MustInternalLink(t testing.TB) {
216+
if !CanInternalLink() {
217+
t.Skipf("skipping test: internal linking on %s/%s is not supported", runtime.GOOS, runtime.GOARCH)
218+
}
219+
}
220+
205221
// HasSymlink reports whether the current system can use os.Symlink.
206222
func HasSymlink() bool {
207223
ok, _ := hasSymlink()

src/os/exec/exec_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,10 @@ func TestExtraFiles(t *testing.T) {
605605
testenv.MustHaveExec(t)
606606
testenv.MustHaveGoBuild(t)
607607

608+
// This test runs with cgo disabled. External linking needs cgo, so
609+
// it doesn't work if external linking is required.
610+
testenv.MustInternalLink(t)
611+
608612
if runtime.GOOS == "windows" {
609613
t.Skipf("skipping test on %q", runtime.GOOS)
610614
}

src/runtime/crash_test.go

+21
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,9 @@ func TestCrashHandler(t *testing.T) {
181181
}
182182

183183
func testDeadlock(t *testing.T, name string) {
184+
// External linking brings in cgo, causing deadlock detection not working.
185+
testenv.MustInternalLink(t)
186+
184187
output := runTestProg(t, "testprog", name)
185188
want := "fatal error: all goroutines are asleep - deadlock!\n"
186189
if !strings.HasPrefix(output, want) {
@@ -205,6 +208,9 @@ func TestLockedDeadlock2(t *testing.T) {
205208
}
206209

207210
func TestGoexitDeadlock(t *testing.T) {
211+
// External linking brings in cgo, causing deadlock detection not working.
212+
testenv.MustInternalLink(t)
213+
208214
output := runTestProg(t, "testprog", "GoexitDeadlock")
209215
want := "no goroutines (main called runtime.Goexit) - deadlock!"
210216
if !strings.Contains(output, want) {
@@ -290,6 +296,9 @@ func TestRecursivePanic4(t *testing.T) {
290296
}
291297

292298
func TestGoexitCrash(t *testing.T) {
299+
// External linking brings in cgo, causing deadlock detection not working.
300+
testenv.MustInternalLink(t)
301+
293302
output := runTestProg(t, "testprog", "GoexitExit")
294303
want := "no goroutines (main called runtime.Goexit) - deadlock!"
295304
if !strings.Contains(output, want) {
@@ -348,6 +357,9 @@ func TestBreakpoint(t *testing.T) {
348357
}
349358

350359
func TestGoexitInPanic(t *testing.T) {
360+
// External linking brings in cgo, causing deadlock detection not working.
361+
testenv.MustInternalLink(t)
362+
351363
// see issue 8774: this code used to trigger an infinite recursion
352364
output := runTestProg(t, "testprog", "GoexitInPanic")
353365
want := "fatal error: no goroutines (main called runtime.Goexit) - deadlock!"
@@ -412,6 +424,9 @@ func TestPanicAfterGoexit(t *testing.T) {
412424
}
413425

414426
func TestRecoveredPanicAfterGoexit(t *testing.T) {
427+
// External linking brings in cgo, causing deadlock detection not working.
428+
testenv.MustInternalLink(t)
429+
415430
output := runTestProg(t, "testprog", "RecoveredPanicAfterGoexit")
416431
want := "fatal error: no goroutines (main called runtime.Goexit) - deadlock!"
417432
if !strings.HasPrefix(output, want) {
@@ -420,6 +435,9 @@ func TestRecoveredPanicAfterGoexit(t *testing.T) {
420435
}
421436

422437
func TestRecoverBeforePanicAfterGoexit(t *testing.T) {
438+
// External linking brings in cgo, causing deadlock detection not working.
439+
testenv.MustInternalLink(t)
440+
423441
t.Parallel()
424442
output := runTestProg(t, "testprog", "RecoverBeforePanicAfterGoexit")
425443
want := "fatal error: no goroutines (main called runtime.Goexit) - deadlock!"
@@ -429,6 +447,9 @@ func TestRecoverBeforePanicAfterGoexit(t *testing.T) {
429447
}
430448

431449
func TestRecoverBeforePanicAfterGoexit2(t *testing.T) {
450+
// External linking brings in cgo, causing deadlock detection not working.
451+
testenv.MustInternalLink(t)
452+
432453
t.Parallel()
433454
output := runTestProg(t, "testprog", "RecoverBeforePanicAfterGoexit2")
434455
want := "fatal error: no goroutines (main called runtime.Goexit) - deadlock!"

src/runtime/time_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ func TestFakeTime(t *testing.T) {
2020
t.Skip("faketime not supported on windows")
2121
}
2222

23+
// Faketime is advanced in checkdead. External linking brings in cgo,
24+
// causing checkdead not working.
25+
testenv.MustInternalLink(t)
26+
2327
t.Parallel()
2428

2529
exe, err := buildTestProg(t, "testfaketime", "-tags=faketime")

0 commit comments

Comments
 (0)