@@ -15,7 +15,7 @@ import (
15
15
"golang.org/x/tools/gopls/internal/test/integration/fake"
16
16
)
17
17
18
- // TODO(rfindley): update these completion tests to run on multiple repos.
18
+ var completionGOPATH = flag . String ( "completion_gopath" , "" , "if set, use this GOPATH for BenchmarkCompletion" )
19
19
20
20
type completionBenchOptions struct {
21
21
file , locationRegexp string
@@ -25,6 +25,7 @@ type completionBenchOptions struct {
25
25
beforeCompletion func (* Env ) // run before each completion
26
26
}
27
27
28
+ // Deprecated: new tests should be expressed in BenchmarkCompletion.
28
29
func benchmarkCompletion (options completionBenchOptions , b * testing.B ) {
29
30
repo := getRepo (b , "tools" )
30
31
_ = repo .sharedEnv (b ) // ensure cache is warm
@@ -146,15 +147,15 @@ func (c *completer) _() {
146
147
}, b )
147
148
}
148
149
149
- type completionFollowingEditTest struct {
150
+ type completionTest struct {
150
151
repo string
151
152
name string
152
153
file string // repo-relative file to create
153
154
content string // file content
154
155
locationRegexp string // regexp for completion
155
156
}
156
157
157
- var completionFollowingEditTests = []completionFollowingEditTest {
158
+ var completionTests = []completionTest {
158
159
{
159
160
"tools" ,
160
161
"selector" ,
@@ -168,6 +169,32 @@ func (c *completer) _() {
168
169
` ,
169
170
`func \(c \*completer\) _\(\) {\n\tc\.inference\.kindMatches\((c)` ,
170
171
},
172
+ {
173
+ "tools" ,
174
+ "unimportedident" ,
175
+ "internal/lsp/source/completion/completion2.go" ,
176
+ `
177
+ package completion
178
+
179
+ func (c *completer) _() {
180
+ lo
181
+ }
182
+ ` ,
183
+ `lo()` ,
184
+ },
185
+ {
186
+ "tools" ,
187
+ "unimportedselector" ,
188
+ "internal/lsp/source/completion/completion2.go" ,
189
+ `
190
+ package completion
191
+
192
+ func (c *completer) _() {
193
+ log.
194
+ }
195
+ ` ,
196
+ `log\.()` ,
197
+ },
171
198
{
172
199
"kubernetes" ,
173
200
"selector" ,
@@ -213,14 +240,18 @@ func (p *Pivot) _() {
213
240
//
214
241
// Edits force type-checked packages to be invalidated, so we want to measure
215
242
// how long it takes before completion results are available.
216
- func BenchmarkCompletionFollowingEdit (b * testing.B ) {
217
- for _ , test := range completionFollowingEditTests {
243
+ func BenchmarkCompletion (b * testing.B ) {
244
+ for _ , test := range completionTests {
218
245
b .Run (fmt .Sprintf ("%s_%s" , test .repo , test .name ), func (b * testing.B ) {
219
- for _ , completeUnimported := range []bool {true , false } {
220
- b .Run (fmt .Sprintf ("completeUnimported=%v" , completeUnimported ), func (b * testing.B ) {
221
- for _ , budget := range []string {"0s" , "100ms" } {
222
- b .Run (fmt .Sprintf ("budget=%s" , budget ), func (b * testing.B ) {
223
- runCompletionFollowingEdit (b , test , completeUnimported , budget )
246
+ for _ , followingEdit := range []bool {true , false } {
247
+ b .Run (fmt .Sprintf ("edit=%v" , followingEdit ), func (b * testing.B ) {
248
+ for _ , completeUnimported := range []bool {true , false } {
249
+ b .Run (fmt .Sprintf ("unimported=%v" , completeUnimported ), func (b * testing.B ) {
250
+ for _ , budget := range []string {"0s" , "100ms" } {
251
+ b .Run (fmt .Sprintf ("budget=%s" , budget ), func (b * testing.B ) {
252
+ runCompletion (b , test , followingEdit , completeUnimported , budget )
253
+ })
254
+ }
224
255
})
225
256
}
226
257
})
@@ -229,13 +260,20 @@ func BenchmarkCompletionFollowingEdit(b *testing.B) {
229
260
}
230
261
}
231
262
263
+ // For optimizing unimported completion, it can be useful to benchmark with a
264
+ // huge GOMODCACHE.
232
265
var gomodcache = flag .String ("gomodcache" , "" , "optional GOMODCACHE for unimported completion benchmarks" )
233
266
234
- func runCompletionFollowingEdit (b * testing.B , test completionFollowingEditTest , completeUnimported bool , budget string ) {
267
+ func runCompletion (b * testing.B , test completionTest , followingEdit , completeUnimported bool , budget string ) {
235
268
repo := getRepo (b , test .repo )
236
- sharedEnv := repo .sharedEnv (b ) // ensure cache is warm
269
+ gopath := * completionGOPATH
270
+ if gopath == "" {
271
+ // use a warm GOPATH
272
+ sharedEnv := repo .sharedEnv (b )
273
+ gopath = sharedEnv .Sandbox .GOPATH ()
274
+ }
237
275
envvars := map [string ]string {
238
- "GOPATH" : sharedEnv . Sandbox . GOPATH (), // use the warm cache
276
+ "GOPATH" : gopath ,
239
277
}
240
278
241
279
if * gomodcache != "" {
@@ -248,7 +286,7 @@ func runCompletionFollowingEdit(b *testing.B, test completionFollowingEditTest,
248
286
"completeUnimported" : completeUnimported ,
249
287
"completionBudget" : budget ,
250
288
},
251
- }, "completionFollowingEdit " , false )
289
+ }, "completion " , false )
252
290
defer env .Close ()
253
291
254
292
env .CreateBuffer (test .file , "// __TEST_PLACEHOLDER_0__\n " + test .content )
@@ -278,12 +316,14 @@ func runCompletionFollowingEdit(b *testing.B, test completionFollowingEditTest,
278
316
279
317
b .ResetTimer ()
280
318
281
- if stopAndRecord := startProfileIfSupported (b , env , qualifiedName (test .repo , "completionFollowingEdit " )); stopAndRecord != nil {
319
+ if stopAndRecord := startProfileIfSupported (b , env , qualifiedName (test .repo , "completion " )); stopAndRecord != nil {
282
320
defer stopAndRecord ()
283
321
}
284
322
285
323
for i := 0 ; i < b .N ; i ++ {
286
- editPlaceholder ()
324
+ if followingEdit {
325
+ editPlaceholder ()
326
+ }
287
327
loc := env .RegexpSearch (test .file , test .locationRegexp )
288
328
env .Completion (loc )
289
329
}
0 commit comments