1// Copyright 2020 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package regtest 6 7import ( 8 "context" 9 "flag" 10 "fmt" 11 "io/ioutil" 12 "os" 13 "testing" 14 "time" 15 16 "golang.org/x/tools/internal/lsp/cmd" 17 "golang.org/x/tools/internal/tool" 18) 19 20var ( 21 runSubprocessTests = flag.Bool("enable_gopls_subprocess_tests", false, "run regtests against a gopls subprocess") 22 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") 23 regtestTimeout = flag.Duration("regtest_timeout", 20*time.Second, "default timeout for each regtest") 24 skipCleanup = flag.Bool("regtest_skip_cleanup", false, "whether to skip cleaning up temp directories") 25 printGoroutinesOnFailure = flag.Bool("regtest_print_goroutines", false, "whether to print goroutines info on failure") 26) 27 28var runner *Runner 29 30func run(t *testing.T, files string, f TestFunc) { 31 runner.Run(t, files, f) 32} 33 34func withOptions(opts ...RunOption) configuredRunner { 35 return configuredRunner{opts: opts} 36} 37 38type configuredRunner struct { 39 opts []RunOption 40} 41 42func (r configuredRunner) run(t *testing.T, files string, f TestFunc) { 43 runner.Run(t, files, f, r.opts...) 44} 45 46func TestMain(m *testing.M) { 47 flag.Parse() 48 if os.Getenv("_GOPLS_TEST_BINARY_RUN_AS_GOPLS") == "true" { 49 tool.Main(context.Background(), cmd.New("gopls", "", nil, nil), os.Args[1:]) 50 os.Exit(0) 51 } 52 53 runner = &Runner{ 54 DefaultModes: NormalModes, 55 Timeout: *regtestTimeout, 56 PrintGoroutinesOnFailure: *printGoroutinesOnFailure, 57 SkipCleanup: *skipCleanup, 58 } 59 if *runSubprocessTests { 60 goplsPath := *goplsBinaryPath 61 if goplsPath == "" { 62 var err error 63 goplsPath, err = os.Executable() 64 if err != nil { 65 panic(fmt.Sprintf("finding test binary path: %v", err)) 66 } 67 } 68 runner.DefaultModes = NormalModes | SeparateProcess 69 runner.GoplsPath = goplsPath 70 } 71 dir, err := ioutil.TempDir("", "gopls-regtest-") 72 if err != nil { 73 panic(fmt.Errorf("creating regtest temp directory: %v", err)) 74 } 75 runner.TempDir = dir 76 77 code := m.Run() 78 if err := runner.Close(); err != nil { 79 fmt.Fprintf(os.Stderr, "closing test runner: %v\n", err) 80 os.Exit(1) 81 } 82 os.Exit(code) 83} 84