blob: b93b76f945dbea6a854ac80fe9962e67b21e7bf1 [file] [log] [blame]
// Copyright 2023 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 bench
import (
"fmt"
"path"
"regexp"
"testing"
. "golang.org/x/tools/gopls/internal/test/integration"
)
// BenchmarkReload benchmarks reloading a file metadata after a change to an import.
//
// This ensures we are able to diagnose a changed file without reloading all
// invalidated packages. See also golang/go#61344
func BenchmarkReload(b *testing.B) {
type replace map[string]string
tests := []struct {
repo string
file string
// replacements must be 'reversible', in the sense that the replacing
// string is unique.
replace replace
}{
// pkg/util/hash is transitively imported by a large number of packages. We
// should not need to reload those packages to get a diagnostic.
{"kubernetes", "pkg/util/hash/hash.go", replace{`"hash"`: `"hashx"`}},
{"kubernetes", "pkg/kubelet/kubelet.go", replace{
`"k8s.io/kubernetes/pkg/kubelet/config"`: `"k8s.io/kubernetes/pkg/kubelet/configx"`,
}},
}
for _, test := range tests {
b.Run(fmt.Sprintf("%s/%s", test.repo, path.Base(test.file)), func(b *testing.B) {
env := getRepo(b, test.repo).sharedEnv(b)
env.OpenFile(test.file)
defer closeBuffer(b, env, test.file)
env.AfterChange()
profileName := qualifiedName("reload", test.repo, path.Base(test.file))
if stopAndRecord := startProfileIfSupported(b, env, profileName); stopAndRecord != nil {
defer stopAndRecord()
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
// Mutate the file. This may result in cache hits, but that's OK: the
// goal is to ensure that we don't reload more than just the current
// package.
for k, v := range test.replace {
env.RegexpReplace(test.file, regexp.QuoteMeta(k), v)
}
// Note: don't use env.AfterChange() here: we only want to await the
// first diagnostic.
//
// Awaiting a full diagnosis would await diagnosing everything, which
// would require reloading everything.
env.Await(Diagnostics(ForFile(test.file)))
for k, v := range test.replace {
env.RegexpReplace(test.file, regexp.QuoteMeta(v), k)
}
env.Await(NoDiagnostics(ForFile(test.file)))
}
})
}
}