Skip to content

Commit e404ca2

Browse files
committed
internal/lsp/regtest: use a common directory for regtest sandboxes
For easier debugging (and less cruft if regtests are ctrl-c'ed), root all regtest sandboxes in a common directory. This also tries one last time to clean up the directory, and fails on an error. This might be flaky on windows, but hasn't been so far... Also give regtest sandboxes names derived from their test name. Updates golang/go#39384 Updates golang/go#38490 Change-Id: Iae53c29e75f5eb2b8d938d205fbeb463ffc82eb2 Reviewed-on: https://go-review.googlesource.com/c/tools/+/240059 Run-TryBot: Robert Findley <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Rebecca Stambler <[email protected]>
1 parent df98bc6 commit e404ca2

File tree

5 files changed

+40
-31
lines changed

5 files changed

+40
-31
lines changed

internal/lsp/fake/editor_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func main() {
4848
`
4949

5050
func TestClientEditing(t *testing.T) {
51-
ws, err := NewSandbox("TestClientEditing", exampleProgram, "", false, false)
51+
ws, err := NewSandbox("", exampleProgram, "", false, false)
5252
if err != nil {
5353
t.Fatal(err)
5454
}

internal/lsp/fake/sandbox.go

+9-7
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
// Sandbox holds a collection of temporary resources to use for working with Go
2121
// code in tests.
2222
type Sandbox struct {
23-
name string
2423
gopath string
2524
basedir string
2625
Proxy *Proxy
@@ -36,21 +35,24 @@ type Sandbox struct {
3635
// working directory populated by the txtar-encoded content in srctxt, and a
3736
// file-based module proxy populated with the txtar-encoded content in
3837
// proxytxt.
39-
func NewSandbox(name, srctxt, proxytxt string, inGopath bool, withoutWorkspaceFolders bool) (_ *Sandbox, err error) {
40-
sb := &Sandbox{
41-
name: name,
42-
}
38+
//
39+
// If rootDir is non-empty, it will be used as the root of temporary
40+
// directories created for the sandbox. Otherwise, a new temporary directory
41+
// will be used as root.
42+
func NewSandbox(rootDir, srctxt, proxytxt string, inGopath bool, withoutWorkspaceFolders bool) (_ *Sandbox, err error) {
43+
sb := &Sandbox{}
4344
defer func() {
4445
// Clean up if we fail at any point in this constructor.
4546
if err != nil {
4647
sb.Close()
4748
}
4849
}()
49-
basedir, err := ioutil.TempDir("", fmt.Sprintf("goplstest-sandbox-%s-", name))
50+
51+
baseDir, err := ioutil.TempDir(rootDir, "gopls-sandbox-")
5052
if err != nil {
5153
return nil, fmt.Errorf("creating temporary workdir: %v", err)
5254
}
53-
sb.basedir = basedir
55+
sb.basedir = baseDir
5456
proxydir := filepath.Join(sb.basedir, "proxy")
5557
sb.gopath = filepath.Join(sb.basedir, "gopath")
5658
// Set the working directory as $GOPATH/src if inGopath is true.

internal/lsp/lsprpc/lsprpc_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ func main() {
196196
}`
197197

198198
func TestDebugInfoLifecycle(t *testing.T) {
199-
sb, err := fake.NewSandbox("gopls-lsprpc-test", exampleProgram, "", false, false)
199+
sb, err := fake.NewSandbox("", exampleProgram, "", false, false)
200200
if err != nil {
201201
t.Fatal(err)
202202
}

internal/lsp/regtest/reg_test.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"context"
99
"flag"
1010
"fmt"
11+
"io/ioutil"
1112
"os"
1213
"testing"
1314
"time"
@@ -20,6 +21,7 @@ var (
2021
runSubprocessTests = flag.Bool("enable_gopls_subprocess_tests", false, "run regtests against a gopls subprocess")
2122
goplsBinaryPath = flag.String("gopls_test_binary", "", "path to the gopls binary for use as a remote, for use with the -enable_gopls_subprocess_tests flag")
2223
regtestTimeout = flag.Duration("regtest_timeout", 60*time.Second, "default timeout for each regtest")
24+
skipCleanup = flag.Bool("regtest_skip_cleanup", false, "whether to skip cleaning up temp directories")
2325
printGoroutinesOnFailure = flag.Bool("regtest_print_goroutines", false, "whether to print goroutines info on failure")
2426
)
2527

@@ -36,6 +38,7 @@ func TestMain(m *testing.M) {
3638
DefaultModes: NormalModes,
3739
Timeout: *regtestTimeout,
3840
PrintGoroutinesOnFailure: *printGoroutinesOnFailure,
41+
SkipCleanup: *skipCleanup,
3942
}
4043
if *runSubprocessTests {
4144
goplsPath := *goplsBinaryPath
@@ -49,8 +52,16 @@ func TestMain(m *testing.M) {
4952
runner.DefaultModes = NormalModes | SeparateProcess
5053
runner.GoplsPath = goplsPath
5154
}
55+
dir, err := ioutil.TempDir("", "gopls-regtest-")
56+
if err != nil {
57+
panic(fmt.Errorf("creating regtest temp directory: %v", err))
58+
}
59+
runner.TempDir = dir
5260

5361
code := m.Run()
54-
runner.Close()
62+
if err := runner.Close(); err != nil {
63+
fmt.Fprintf(os.Stderr, "closing test runner: %v\n", err)
64+
os.Exit(1)
65+
}
5566
os.Exit(code)
5667
}

internal/lsp/regtest/runner.go

+17-21
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ type Runner struct {
5656
Timeout time.Duration
5757
GoplsPath string
5858
PrintGoroutinesOnFailure bool
59+
TempDir string
60+
SkipCleanup bool
5961

6062
mu sync.Mutex
6163
ts *servertest.TCPServer
@@ -70,7 +72,6 @@ type runConfig struct {
7072
modes Mode
7173
proxyTxt string
7274
timeout time.Duration
73-
skipCleanup bool
7475
gopath bool
7576
withoutWorkspaceFolders bool
7677
}
@@ -139,14 +140,6 @@ func InGOPATH() RunOption {
139140
})
140141
}
141142

142-
// SkipCleanup is used only for debugging: is skips cleaning up the tests state
143-
// after completion.
144-
func SkipCleanup() RunOption {
145-
return optionSetter(func(opts *runConfig) {
146-
opts.skipCleanup = true
147-
})
148-
}
149-
150143
// Run executes the test function in the default configured gopls execution
151144
// modes. For each a test run, a new workspace is created containing the
152145
// un-txtared files specified by filedata.
@@ -173,12 +166,16 @@ func (r *Runner) Run(t *testing.T, filedata string, test func(t *testing.T, e *E
173166
continue
174167
}
175168
t.Run(tc.name, func(t *testing.T) {
176-
t.Helper()
177169
ctx, cancel := context.WithTimeout(context.Background(), config.timeout)
178170
defer cancel()
179171
ctx = debug.WithInstance(ctx, "", "")
180172

181-
sandbox, err := fake.NewSandbox("regtest", filedata, config.proxyTxt, config.gopath, config.withoutWorkspaceFolders)
173+
tempDir := filepath.Join(r.TempDir, filepath.FromSlash(t.Name()))
174+
if err := os.MkdirAll(tempDir, 0755); err != nil {
175+
t.Fatal(err)
176+
}
177+
178+
sandbox, err := fake.NewSandbox(tempDir, filedata, config.proxyTxt, config.gopath, config.withoutWorkspaceFolders)
182179
if err != nil {
183180
t.Fatal(err)
184181
}
@@ -188,13 +185,7 @@ func (r *Runner) Run(t *testing.T, filedata string, test func(t *testing.T, e *E
188185
// Windows. This may still be flaky however, and in the future we need a
189186
// better solution to ensure that all Go processes started by gopls have
190187
// exited before we clean up.
191-
if config.skipCleanup {
192-
defer func() {
193-
t.Logf("Skipping workspace cleanup: running in %s", sandbox.Workdir.RootURI())
194-
}()
195-
} else {
196-
r.AddCloser(sandbox)
197-
}
188+
r.AddCloser(sandbox)
198189
ss := tc.getServer(ctx, t)
199190
ls := &loggingFramer{}
200191
framer := ls.framer(jsonrpc2.NewRawStream)
@@ -291,7 +282,7 @@ func (r *Runner) getRemoteSocket(t *testing.T) string {
291282
t.Fatal("cannot run tests with a separate process unless a path to a gopls binary is configured")
292283
}
293284
var err error
294-
r.socketDir, err = ioutil.TempDir("", "gopls-regtests")
285+
r.socketDir, err = ioutil.TempDir(r.TempDir, "gopls-regtest-socket")
295286
if err != nil {
296287
t.Fatalf("creating tempdir: %v", err)
297288
}
@@ -333,8 +324,13 @@ func (r *Runner) Close() error {
333324
errmsgs = append(errmsgs, err.Error())
334325
}
335326
}
336-
for _, closer := range r.closers {
337-
if err := closer.Close(); err != nil {
327+
if !r.SkipCleanup {
328+
for _, closer := range r.closers {
329+
if err := closer.Close(); err != nil {
330+
errmsgs = append(errmsgs, err.Error())
331+
}
332+
}
333+
if err := os.RemoveAll(r.TempDir); err != nil {
338334
errmsgs = append(errmsgs, err.Error())
339335
}
340336
}

0 commit comments

Comments
 (0)