t.Run(tc.name, func(t *testing.T) {
t.Logf("Running with %d workers", tc.workers)
- var cpuTime time.Duration
+ var userTime, systemTime time.Duration
matches := matchAndAvoidStacks(stackContains, []string{"runtime/pprof.cpuHog1"}, avoidFunctions())
- p := testCPUProfile(t, matches, func(dur time.Duration) {
- cpuTime = diffCPUTime(t, func() {
+ acceptProfile := func(t *testing.T, p *profile.Profile) bool {
+ if !matches(t, p) {
+ return false
+ }
+
+ ok := true
+ for i, unit := range []string{"count", "nanoseconds"} {
+ if have, want := p.SampleType[i].Unit, unit; have != want {
+ t.Logf("pN SampleType[%d]; %q != %q", i, have, want)
+ ok = false
+ }
+ }
+
+ // cpuHog1 called below is the primary source of CPU
+ // load, but there may be some background work by the
+ // runtime. Since the OS rusage measurement will
+ // include all work done by the process, also compare
+ // against all samples in our profile.
+ var value time.Duration
+ for _, sample := range p.Sample {
+ value += time.Duration(sample.Value[1]) * time.Nanosecond
+ }
+
+ totalTime := userTime + systemTime
+ t.Logf("compare %s user + %s system = %s vs %s", userTime, systemTime, totalTime, value)
+ if err := compare(totalTime, value, maxDiff); err != nil {
+ t.Logf("compare got %v want nil", err)
+ ok = false
+ }
+
+ return ok
+ }
+
+ testCPUProfile(t, acceptProfile, func(dur time.Duration) {
+ userTime, systemTime = diffCPUTime(t, func() {
var wg sync.WaitGroup
var once sync.Once
for i := 0; i < tc.workers; i++ {
wg.Wait()
})
})
-
- for i, unit := range []string{"count", "nanoseconds"} {
- if have, want := p.SampleType[i].Unit, unit; have != want {
- t.Errorf("pN SampleType[%d]; %q != %q", i, have, want)
- }
- }
-
- // cpuHog1 called above is the primary source of CPU
- // load, but there may be some background work by the
- // runtime. Since the OS rusage measurement will
- // include all work done by the process, also compare
- // against all samples in our profile.
- var value time.Duration
- for _, sample := range p.Sample {
- value += time.Duration(sample.Value[1]) * time.Nanosecond
- }
-
- t.Logf("compare %s vs %s", cpuTime, value)
- if err := compare(cpuTime, value, maxDiff); err != nil {
- t.Errorf("compare got %v want nil", err)
- }
})
}
}
return nil
}
-var diffCPUTimeImpl func(f func()) time.Duration
+var diffCPUTimeImpl func(f func()) (user, system time.Duration)
-func diffCPUTime(t *testing.T, f func()) time.Duration {
+func diffCPUTime(t *testing.T, f func()) (user, system time.Duration) {
if fn := diffCPUTimeImpl; fn != nil {
return fn(f)
}
t.Fatalf("cannot measure CPU time on GOOS=%s GOARCH=%s", runtime.GOOS, runtime.GOARCH)
- return 0
+ return 0, 0
}
func contains(slice []string, s string) bool {