Skip to content

Commit 5634542

Browse files
committed
tests: also collect run-only mutex profile in sysbench
This extends `Benchmark{,Parallel}Sysbench`'s functionality to create a delta profile for allocations to the mutex profiler. Epic: CRDB-42584 Release note: none
1 parent 540a042 commit 5634542

File tree

1 file changed

+54
-24
lines changed

1 file changed

+54
-24
lines changed

pkg/sql/tests/sysbench_test.go

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -984,57 +984,87 @@ func (f doneFn) Stop(b testing.TB) {
984984
}
985985

986986
func startAllocsProfile(b testing.TB) doneFn {
987-
out := benchmemFile(b)
988-
if out == "" {
989-
return func(tb testing.TB) {}
987+
outAllocs := testProfileFile(b, "memprofile")
988+
diffAllocs := diffProfile(b, func() []byte {
989+
if outAllocs == "" {
990+
return nil
991+
}
992+
p := runtimepprof.Lookup("allocs")
993+
var buf bytes.Buffer
994+
995+
runtime.GC()
996+
require.NoError(b, p.WriteTo(&buf, 0))
997+
998+
return buf.Bytes()
999+
})
1000+
1001+
outMutex := testProfileFile(b, "mutexprofile")
1002+
diffMutex := diffProfile(b, func() []byte {
1003+
if outMutex == "" {
1004+
return nil
1005+
}
1006+
p := runtimepprof.Lookup("mutex")
1007+
var buf bytes.Buffer
1008+
require.NoError(b, p.WriteTo(&buf, 0))
1009+
return buf.Bytes()
1010+
})
1011+
1012+
return func(b testing.TB) {
1013+
if sl := diffAllocs(b); len(sl) > 0 {
1014+
require.NoError(b, os.WriteFile(outAllocs, sl, 0644))
1015+
}
1016+
if sl := diffMutex(b); len(sl) > 0 {
1017+
require.NoError(b, os.WriteFile(outMutex, sl, 0644))
1018+
}
9901019
}
1020+
}
9911021

1022+
func diffProfile(b testing.TB, take func() []byte) func(testing.TB) []byte {
9921023
// The below is essentially cribbed from pprof.go in net/http/pprof.
993-
p := runtimepprof.Lookup("allocs")
994-
var buf bytes.Buffer
995-
runtime.GC()
996-
require.NoError(b, p.WriteTo(&buf, 0))
997-
pBase, err := profile.ParseData(buf.Bytes())
1024+
1025+
baseBytes := take()
1026+
if baseBytes == nil {
1027+
return func(tb testing.TB) []byte { return nil }
1028+
}
1029+
pBase, err := profile.ParseData(baseBytes)
9981030
require.NoError(b, err)
9991031

1000-
return func(b testing.TB) {
1001-
runtime.GC()
1002-
var buf bytes.Buffer
1003-
require.NoError(b, p.WriteTo(&buf, 0))
1004-
pNew, err := profile.ParseData(buf.Bytes())
1032+
return func(b testing.TB) []byte {
1033+
pNew, err := profile.ParseData(take())
10051034
require.NoError(b, err)
10061035
pBase.Scale(-1)
10071036
pMerged, err := profile.Merge([]*profile.Profile{pBase, pNew})
10081037
require.NoError(b, err)
10091038
pMerged.TimeNanos = pNew.TimeNanos
10101039
pMerged.DurationNanos = pNew.TimeNanos - pBase.TimeNanos
10111040

1012-
buf = bytes.Buffer{}
1041+
buf := bytes.Buffer{}
10131042
require.NoError(b, pMerged.Write(&buf))
1014-
require.NoError(b, os.WriteFile(out, buf.Bytes(), 0644))
1043+
return buf.Bytes()
10151044
}
10161045
}
10171046

1018-
// If -test.benchmem is passed, also write a base alloc profile when the
1019-
// setup is done. This can be used via `pprof -base` to show only the
1020-
// allocs during run (excluding the setup).
1047+
// If -test.<something> is passed for the flag corresponding to the given
1048+
// profile, also write a base profile when the setup is done. This can be used
1049+
// via `pprof -base` to show only the samples from during run (excluding the
1050+
// setup).
10211051
//
1022-
// The file name for the base profile will be derived from -test.memprofile, and
1052+
// The file name for the base profile will be derived from -test.<flag>, and
10231053
// will contain it as a prefix (mod the file extension).
1024-
func benchmemFile(b testing.TB) string {
1054+
func testProfileFile(b testing.TB, flagWithoutTestPrefix string) string {
10251055
b.Helper()
1026-
var benchMemFile string
1056+
var flagFile string
10271057
var outputDir string
1028-
require.NoError(b, sniffarg.DoEnv("test.memprofile", &benchMemFile))
1058+
require.NoError(b, sniffarg.DoEnv("test."+flagWithoutTestPrefix, &flagFile))
10291059
require.NoError(b, sniffarg.DoEnv("test.outputdir", &outputDir))
10301060

1031-
if benchMemFile == "" {
1061+
if flagFile == "" {
10321062
return ""
10331063
}
10341064

10351065
saniRE := regexp.MustCompile(`\W+`)
10361066
saniName := saniRE.ReplaceAllString(strings.TrimPrefix(b.Name(), "Benchmark"), "_")
1037-
dest := strings.Replace(benchMemFile, ".", "_"+saniName+".", 1)
1067+
dest := strings.Replace(flagFile, ".", "_"+saniName+".", 1)
10381068
if outputDir != "" {
10391069
dest = filepath.Join(outputDir, dest)
10401070
}

0 commit comments

Comments
 (0)