From 93b64502c3dced6b03ab7edece676baff35f76a0 Mon Sep 17 00:00:00 2001 From: Rob Findley Date: Wed, 22 Jul 2020 22:37:45 -0400 Subject: [PATCH] internal/lsp/regtest: add a simple stress test Using the new run options to configure a testing environment suitable for long-running tests, a trivial stress test is added to type arbitrarily in a known problematic repository (github.com/pilosa/pilosa). Change-Id: I2c8237843111f17ff5a096515cb4704c62513ed0 Reviewed-on: https://go-review.googlesource.com/c/tools/+/244441 Run-TryBot: Robert Findley TryBot-Result: Gobot Gobot Reviewed-by: Heschi Kreinick --- internal/lsp/regtest/stress_test.go | 81 +++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 internal/lsp/regtest/stress_test.go diff --git a/internal/lsp/regtest/stress_test.go b/internal/lsp/regtest/stress_test.go new file mode 100644 index 0000000000..55e81ae90a --- /dev/null +++ b/internal/lsp/regtest/stress_test.go @@ -0,0 +1,81 @@ +// Copyright 2020 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 regtest + +import ( + "context" + "flag" + "fmt" + "testing" + "time" +) + +// Pilosa is a repository that has historically caused significant memory +// problems for Gopls. We use it for a simple stress test that types +// arbitrarily in a file with lots of dependents. + +var pilosaPath = flag.String("pilosa_path", "", "Path to a directory containing "+ + "github.com/pilosa/pilosa, for stress testing. Do not set this unless you "+ + "know what you're doing!") + +func stressTestOptions(dir string) []RunOption { + return []RunOption{ + // Run in an existing directory, since we're trying to simulate known cases + // that cause gopls memory problems. + InExistingDir(dir), + + // Enable live debugging. + WithDebugAddress(":8087"), + + // Skip logs and hooks, as they buffer up memory unnaturally. + SkipLogs(), + NoHooks(), + // The Debug server only makes sense if running in singleton mode. + WithModes(Singleton), + // Set a generous timeout. Individual tests should control their own + // graceful termination. + WithTimeout(20 * time.Minute), + + // Use the actual proxy, since we want our builds to succeed. + WithGOPROXY("https://proxy.golang.org"), + } +} + +func TestPilosaStress(t *testing.T) { + if *pilosaPath == "" { + t.Skip("-pilosa_path not configured") + } + opts := stressTestOptions(*pilosaPath) + + withOptions(opts...).run(t, "", func(t *testing.T, env *Env) { + files := []string{ + "cmd.go", + "internal/private.pb.go", + "roaring/roaring.go", + "roaring/roaring_internal_test.go", + "server/handler_test.go", + } + for _, file := range files { + env.OpenFile(file) + } + ctx, cancel := context.WithTimeout(env.Ctx, 10*time.Minute) + defer cancel() + + i := 1 + // MagicNumber is an identifier that occurs in roaring.go. Just change it + // arbitrarily. + env.RegexpReplace("roaring/roaring.go", "MagicNumber", fmt.Sprintf("MagicNumber%d", 1)) + for { + select { + case <-ctx.Done(): + return + default: + } + env.RegexpReplace("roaring/roaring.go", fmt.Sprintf("MagicNumber%d", i), fmt.Sprintf("MagicNumber%d", i+1)) + time.Sleep(20 * time.Millisecond) + i++ + } + }) +}