summaryrefslogtreecommitdiff
path: root/libgo/go/runtime/pprof/pprof_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/runtime/pprof/pprof_test.go')
-rw-r--r--libgo/go/runtime/pprof/pprof_test.go54
1 files changed, 42 insertions, 12 deletions
diff --git a/libgo/go/runtime/pprof/pprof_test.go b/libgo/go/runtime/pprof/pprof_test.go
index 10699637205..c32b84758a8 100644
--- a/libgo/go/runtime/pprof/pprof_test.go
+++ b/libgo/go/runtime/pprof/pprof_test.go
@@ -9,7 +9,9 @@ package pprof_test
import (
"bytes"
"fmt"
+ "internal/testenv"
"math/big"
+ "os"
"os/exec"
"regexp"
"runtime"
@@ -121,15 +123,19 @@ func parseProfile(t *testing.T, bytes []byte, f func(uintptr, []uintptr)) {
func testCPUProfile(t *testing.T, need []string, f func()) {
switch runtime.GOOS {
case "darwin":
- out, err := exec.Command("uname", "-a").CombinedOutput()
- if err != nil {
- t.Fatal(err)
+ switch runtime.GOARCH {
+ case "arm", "arm64":
+ // nothing
+ default:
+ out, err := exec.Command("uname", "-a").CombinedOutput()
+ if err != nil {
+ t.Fatal(err)
+ }
+ vers := string(out)
+ t.Logf("uname -a: %v", vers)
}
- vers := string(out)
- t.Logf("uname -a: %v", vers)
case "plan9":
- // unimplemented
- return
+ t.Skip("skipping on plan9")
}
var prof bytes.Buffer
@@ -141,7 +147,9 @@ func testCPUProfile(t *testing.T, need []string, f func()) {
// Check that profile is well formed and contains need.
have := make([]uintptr, len(need))
+ var samples uintptr
parseProfile(t, prof.Bytes(), func(count uintptr, stk []uintptr) {
+ samples += count
for _, pc := range stk {
f := runtime.FuncForPC(pc)
if f == nil {
@@ -155,6 +163,14 @@ func testCPUProfile(t *testing.T, need []string, f func()) {
}
}
})
+ t.Logf("total %d CPU profile samples collected", samples)
+
+ if samples < 10 && runtime.GOOS == "windows" {
+ // On some windows machines we end up with
+ // not enough samples due to coarse timer
+ // resolution. Let it go.
+ t.Skip("too few samples on Windows (golang.org/issue/10842)")
+ }
if len(need) == 0 {
return
@@ -187,14 +203,28 @@ func testCPUProfile(t *testing.T, need []string, f func()) {
t.Skipf("ignoring failure on %s; see golang.org/issue/6047", runtime.GOOS)
return
}
+ // Ignore the failure if the tests are running in a QEMU-based emulator,
+ // QEMU is not perfect at emulating everything.
+ // IN_QEMU environmental variable is set by some of the Go builders.
+ // IN_QEMU=1 indicates that the tests are running in QEMU. See issue 9605.
+ if os.Getenv("IN_QEMU") == "1" {
+ t.Skip("ignore the failure in QEMU; see golang.org/issue/9605")
+ return
+ }
t.FailNow()
}
}
+// Fork can hang if preempted with signals frequently enough (see issue 5517).
+// Ensure that we do not do this.
func TestCPUProfileWithFork(t *testing.T) {
- // Fork can hang if preempted with signals frequently enough (see issue 5517).
- // Ensure that we do not do this.
+ testenv.MustHaveExec(t)
+
heap := 1 << 30
+ if runtime.GOOS == "android" {
+ // Use smaller size for Android to avoid crash.
+ heap = 100 << 20
+ }
if testing.Short() {
heap = 100 << 20
}
@@ -217,7 +247,7 @@ func TestCPUProfileWithFork(t *testing.T) {
defer StopCPUProfile()
for i := 0; i < 10; i++ {
- exec.Command("go").CombinedOutput()
+ exec.Command(os.Args[0], "-h").CombinedOutput()
}
}
@@ -250,7 +280,7 @@ func TestGoroutineSwitch(t *testing.T) {
// exists to record a PC without a traceback. Those are okay.
if len(stk) == 2 {
f := runtime.FuncForPC(stk[1])
- if f != nil && (f.Name() == "System" || f.Name() == "ExternalCode" || f.Name() == "GC") {
+ if f != nil && (f.Name() == "runtime._System" || f.Name() == "runtime._ExternalCode" || f.Name() == "runtime._GC") {
return
}
}
@@ -368,7 +398,7 @@ func TestBlockProfile(t *testing.T) {
}
for _, test := range tests {
- if !regexp.MustCompile(test.re).MatchString(prof) {
+ if !regexp.MustCompile(strings.Replace(test.re, "\t", "\t+", -1)).MatchString(prof) {
t.Fatalf("Bad %v entry, expect:\n%v\ngot:\n%v", test.name, test.re, prof)
}
}