2020-02-06 17:50:37 -07:00
// 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 (
2020-02-10 09:34:13 -07:00
"context"
"flag"
2020-02-09 12:44:03 -07:00
"fmt"
2020-06-25 14:04:28 -06:00
"io/ioutil"
2020-02-06 17:50:37 -07:00
"os"
"testing"
"time"
2020-02-09 12:44:03 -07:00
2020-02-10 09:34:13 -07:00
"golang.org/x/tools/internal/lsp/cmd"
2020-08-26 15:41:45 -06:00
"golang.org/x/tools/internal/testenv"
2020-02-10 09:34:13 -07:00
"golang.org/x/tools/internal/tool"
)
var (
2020-04-15 15:14:53 -06:00
runSubprocessTests = flag . Bool ( "enable_gopls_subprocess_tests" , false , "run regtests against a gopls subprocess" )
2020-06-01 12:54:16 -06:00
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" )
2020-06-25 14:15:36 -06:00
regtestTimeout = flag . Duration ( "regtest_timeout" , 20 * time . Second , "default timeout for each regtest" )
2020-06-25 14:04:28 -06:00
skipCleanup = flag . Bool ( "regtest_skip_cleanup" , false , "whether to skip cleaning up temp directories" )
2020-06-01 12:54:16 -06:00
printGoroutinesOnFailure = flag . Bool ( "regtest_print_goroutines" , false , "whether to print goroutines info on failure" )
2020-02-06 17:50:37 -07:00
)
var runner * Runner
2020-07-16 08:34:33 -06:00
func run ( t * testing . T , files string , f TestFunc ) {
runner . Run ( t , files , f )
}
func withOptions ( opts ... RunOption ) configuredRunner {
return configuredRunner { opts : opts }
}
type configuredRunner struct {
opts [ ] RunOption
}
func ( r configuredRunner ) run ( t * testing . T , files string , f TestFunc ) {
runner . Run ( t , files , f , r . opts ... )
}
2020-02-06 17:50:37 -07:00
func TestMain ( m * testing . M ) {
2020-02-10 09:34:13 -07:00
flag . Parse ( )
if os . Getenv ( "_GOPLS_TEST_BINARY_RUN_AS_GOPLS" ) == "true" {
tool . Main ( context . Background ( ) , cmd . New ( "gopls" , "" , nil , nil ) , os . Args [ 1 : ] )
os . Exit ( 0 )
}
2020-04-15 15:14:53 -06:00
runner = & Runner {
DefaultModes : NormalModes ,
Timeout : * regtestTimeout ,
PrintGoroutinesOnFailure : * printGoroutinesOnFailure ,
2020-06-25 14:04:28 -06:00
SkipCleanup : * skipCleanup ,
2020-04-15 15:14:53 -06:00
}
2020-02-10 09:34:13 -07:00
if * runSubprocessTests {
goplsPath := * goplsBinaryPath
if goplsPath == "" {
var err error
2020-02-25 09:00:37 -07:00
goplsPath , err = os . Executable ( )
2020-02-10 09:34:13 -07:00
if err != nil {
panic ( fmt . Sprintf ( "finding test binary path: %v" , err ) )
}
}
2020-04-15 15:14:53 -06:00
runner . DefaultModes = NormalModes | SeparateProcess
runner . GoplsPath = goplsPath
2020-02-10 09:34:13 -07:00
}
2020-06-25 14:04:28 -06:00
dir , err := ioutil . TempDir ( "" , "gopls-regtest-" )
if err != nil {
panic ( fmt . Errorf ( "creating regtest temp directory: %v" , err ) )
}
runner . TempDir = dir
2020-04-15 15:14:53 -06:00
2020-02-10 09:34:13 -07:00
code := m . Run ( )
2020-06-25 14:04:28 -06:00
if err := runner . Close ( ) ; err != nil {
fmt . Fprintf ( os . Stderr , "closing test runner: %v\n" , err )
2020-08-26 15:41:45 -06:00
// Regtest cleanup is broken in go1.12 and earlier, but this is OK
// for our CI.
//
// But fail on go1.13+.
if testenv . Go1Point ( ) >= 13 {
os . Exit ( 1 )
}
2020-06-25 14:04:28 -06:00
}
2020-02-10 09:34:13 -07:00
os . Exit ( code )
}