mirror of
https://github.com/golang/go
synced 2024-11-18 08:44:43 -07:00
internal/lsp/regtest: add run options to support stress testing
A bunch of options are added to enable long-running performance-oriented tests in existing directories. They will be used in a later CL to implement a simple stress test, as an example of what is possible. Change-Id: I531b201b415362ea135978238b3d64b903226359 Reviewed-on: https://go-review.googlesource.com/c/tools/+/244440 Run-TryBot: Robert Findley <rfindley@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Heschi Kreinick <heschi@google.com>
This commit is contained in:
parent
a5e28d8dab
commit
84d0e3d1cc
@ -10,13 +10,9 @@ import (
|
||||
"golang.org/x/tools/internal/proxydir"
|
||||
)
|
||||
|
||||
// Proxy is a file-based module proxy.
|
||||
type Proxy struct {
|
||||
proxydir string
|
||||
}
|
||||
|
||||
// NewProxy creates a new proxy file tree using the txtar-encoded content.
|
||||
func NewProxy(tmpdir, txt string) (*Proxy, error) {
|
||||
// WriteProxy creates a new proxy file tree using the txtar-encoded content,
|
||||
// and returns its URL.
|
||||
func WriteProxy(tmpdir, txt string) (string, error) {
|
||||
files := unpackTxt(txt)
|
||||
type moduleVersion struct {
|
||||
modulePath, version string
|
||||
@ -33,14 +29,8 @@ func NewProxy(tmpdir, txt string) (*Proxy, error) {
|
||||
}
|
||||
for mv, files := range filesByModule {
|
||||
if err := proxydir.WriteModuleVersion(tmpdir, mv.modulePath, mv.version, files); err != nil {
|
||||
return nil, fmt.Errorf("error writing %s@%s: %v", mv.modulePath, mv.version, err)
|
||||
return "", fmt.Errorf("error writing %s@%s: %v", mv.modulePath, mv.version, err)
|
||||
}
|
||||
}
|
||||
return &Proxy{proxydir: tmpdir}, nil
|
||||
}
|
||||
|
||||
// GOPROXY returns the GOPROXY environment variable value for this proxy
|
||||
// directory.
|
||||
func (p *Proxy) GOPROXY() string {
|
||||
return proxydir.ToURL(p.proxydir)
|
||||
return proxydir.ToURL(tmpdir), nil
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import (
|
||||
type Sandbox struct {
|
||||
gopath string
|
||||
basedir string
|
||||
Proxy *Proxy
|
||||
goproxy string
|
||||
Workdir *Workdir
|
||||
}
|
||||
|
||||
@ -35,12 +35,23 @@ type SandboxConfig struct {
|
||||
// Files holds a txtar-encoded archive of files to populate the initial state
|
||||
// of the working directory.
|
||||
Files string
|
||||
// ProxyFiles holds a txtar-encoded archive of files to populate a file-based
|
||||
// Go proxy.
|
||||
ProxyFiles string
|
||||
// InGoPath specifies that the working directory should be within the
|
||||
// temporary GOPATH.
|
||||
InGoPath bool
|
||||
// Workdir configures the working directory of the Sandbox, for running in a
|
||||
// pre-existing directory. If unset, a new working directory will be created
|
||||
// under RootDir.
|
||||
//
|
||||
// This option is incompatible with InGoPath or Files.
|
||||
Workdir string
|
||||
|
||||
// ProxyFiles holds a txtar-encoded archive of files to populate a file-based
|
||||
// Go proxy.
|
||||
ProxyFiles string
|
||||
// GOPROXY is the explicit GOPROXY value that should be used for the sandbox.
|
||||
//
|
||||
// This option is incompatible with ProxyFiles.
|
||||
GOPROXY string
|
||||
}
|
||||
|
||||
// NewSandbox creates a collection of named temporary resources, with a
|
||||
@ -55,6 +66,15 @@ func NewSandbox(config *SandboxConfig) (_ *Sandbox, err error) {
|
||||
if config == nil {
|
||||
config = new(SandboxConfig)
|
||||
}
|
||||
|
||||
if config.Workdir != "" && (config.Files != "" || config.InGoPath) {
|
||||
return nil, fmt.Errorf("invalid SandboxConfig: Workdir cannot be used in conjunction with Files or InGoPath. Got %+v", config)
|
||||
}
|
||||
|
||||
if config.GOPROXY != "" && config.ProxyFiles != "" {
|
||||
return nil, fmt.Errorf("invalid SandboxConfig: GOPROXY cannot be set in conjunction with ProxyFiles. Got %+v", config)
|
||||
}
|
||||
|
||||
sb := &Sandbox{}
|
||||
defer func() {
|
||||
// Clean up if we fail at any point in this constructor.
|
||||
@ -68,22 +88,42 @@ func NewSandbox(config *SandboxConfig) (_ *Sandbox, err error) {
|
||||
return nil, fmt.Errorf("creating temporary workdir: %v", err)
|
||||
}
|
||||
sb.basedir = baseDir
|
||||
proxydir := filepath.Join(sb.basedir, "proxy")
|
||||
sb.gopath = filepath.Join(sb.basedir, "gopath")
|
||||
// Set the working directory as $GOPATH/src if inGopath is true.
|
||||
workdir := filepath.Join(sb.gopath, "src")
|
||||
dirs := []string{sb.gopath, proxydir}
|
||||
if !config.InGoPath {
|
||||
workdir = filepath.Join(sb.basedir, "work")
|
||||
dirs = append(dirs, workdir)
|
||||
if err := os.Mkdir(sb.gopath, 0755); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, subdir := range dirs {
|
||||
if err := os.Mkdir(subdir, 0755); err != nil {
|
||||
if config.GOPROXY != "" {
|
||||
sb.goproxy = config.GOPROXY
|
||||
} else {
|
||||
proxydir := filepath.Join(sb.basedir, "proxy")
|
||||
if err := os.Mkdir(proxydir, 0755); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sb.goproxy, err = WriteProxy(proxydir, config.ProxyFiles)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if config.Workdir != "" {
|
||||
sb.Workdir = NewWorkdir(config.Workdir)
|
||||
} else {
|
||||
workdir := config.Workdir
|
||||
// If we don't have a pre-existing work dir, we want to create either
|
||||
// $GOPATH/src or <RootDir/work>.
|
||||
if config.InGoPath {
|
||||
// Set the working directory as $GOPATH/src.
|
||||
workdir = filepath.Join(sb.gopath, "src")
|
||||
} else if workdir == "" {
|
||||
workdir = filepath.Join(sb.basedir, "work")
|
||||
}
|
||||
if err := os.Mkdir(workdir, 0755); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sb.Workdir = NewWorkdir(workdir)
|
||||
if err := sb.Workdir.WriteInitialFiles(config.Files); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
sb.Proxy, err = NewProxy(proxydir, config.ProxyFiles)
|
||||
sb.Workdir, err = NewWorkdir(workdir, config.Files)
|
||||
|
||||
return sb, nil
|
||||
}
|
||||
@ -126,7 +166,7 @@ func (sb *Sandbox) GOPATH() string {
|
||||
func (sb *Sandbox) GoEnv() map[string]string {
|
||||
vars := map[string]string{
|
||||
"GOPATH": sb.GOPATH(),
|
||||
"GOPROXY": sb.Proxy.GOPROXY(),
|
||||
"GOPROXY": sb.goproxy,
|
||||
"GO111MODULE": "",
|
||||
"GOSUMDB": "off",
|
||||
"GOPACKAGESDRIVER": "off",
|
||||
@ -144,10 +184,15 @@ func (sb *Sandbox) RunGoCommand(ctx context.Context, verb string, args ...string
|
||||
vars = append(vars, fmt.Sprintf("%s=%s", k, v))
|
||||
}
|
||||
inv := gocommand.Invocation{
|
||||
Verb: verb,
|
||||
Args: args,
|
||||
WorkingDir: sb.Workdir.workdir,
|
||||
Env: vars,
|
||||
Verb: verb,
|
||||
Args: args,
|
||||
Env: vars,
|
||||
}
|
||||
// sb.Workdir may be nil if we exited the constructor with errors (we call
|
||||
// Close to clean up any partial state from the constructor, which calls
|
||||
// RunGoCommand).
|
||||
if sb.Workdir != nil {
|
||||
inv.WorkingDir = sb.Workdir.workdir
|
||||
}
|
||||
gocmdRunner := &gocommand.Runner{}
|
||||
_, _, _, err := gocmdRunner.RunRaw(ctx, inv)
|
||||
@ -156,8 +201,10 @@ func (sb *Sandbox) RunGoCommand(ctx context.Context, verb string, args ...string
|
||||
}
|
||||
// Since running a go command may result in changes to workspace files,
|
||||
// check if we need to send any any "watched" file events.
|
||||
if err := sb.Workdir.CheckForFileChanges(ctx); err != nil {
|
||||
return fmt.Errorf("checking for file changes: %w", err)
|
||||
if sb.Workdir != nil {
|
||||
if err := sb.Workdir.CheckForFileChanges(ctx); err != nil {
|
||||
return fmt.Errorf("checking for file changes: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -40,19 +40,22 @@ type Workdir struct {
|
||||
|
||||
// NewWorkdir writes the txtar-encoded file data in txt to dir, and returns a
|
||||
// Workir for operating on these files using
|
||||
func NewWorkdir(dir, txt string) (*Workdir, error) {
|
||||
w := &Workdir{workdir: dir}
|
||||
func NewWorkdir(dir string) *Workdir {
|
||||
return &Workdir{workdir: dir}
|
||||
}
|
||||
|
||||
func (w *Workdir) WriteInitialFiles(txt string) error {
|
||||
files := unpackTxt(txt)
|
||||
for name, data := range files {
|
||||
if err := w.writeFileData(name, string(data)); err != nil {
|
||||
return nil, fmt.Errorf("writing to workdir: %w", err)
|
||||
return fmt.Errorf("writing to workdir: %w", err)
|
||||
}
|
||||
}
|
||||
// Poll to capture the current file state.
|
||||
if _, err := w.pollFiles(); err != nil {
|
||||
return nil, fmt.Errorf("polling files: %w", err)
|
||||
return fmt.Errorf("polling files: %w", err)
|
||||
}
|
||||
return w, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// RootURI returns the root URI for this working directory of this scratch
|
||||
|
@ -29,8 +29,8 @@ func newWorkdir(t *testing.T) (*Workdir, <-chan []FileEvent, func()) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
wd, err := NewWorkdir(tmpdir, data)
|
||||
if err != nil {
|
||||
wd := NewWorkdir(tmpdir)
|
||||
if err := wd.WriteInitialFiles(data); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cleanup := func() {
|
||||
|
@ -122,7 +122,7 @@ func main() {
|
||||
if before == after {
|
||||
t.Fatalf("go.mod file was unchanged by upgrade command")
|
||||
}
|
||||
}, WithProxy(proxyWithLatest))
|
||||
}, WithProxyFiles(proxyWithLatest))
|
||||
}
|
||||
|
||||
func TestRegenerateCgo(t *testing.T) {
|
||||
|
@ -402,7 +402,7 @@ func TestResolveDiagnosticWithDownload(t *testing.T) {
|
||||
// diagnostic for the wrong formatting type.
|
||||
// TODO: we should be able to easily also match the diagnostic message.
|
||||
env.Await(env.DiagnosticAtRegexp("print.go", "fmt.Printf"))
|
||||
}, WithProxy(testPackageWithRequireProxy))
|
||||
}, WithProxyFiles(testPackageWithRequireProxy))
|
||||
}
|
||||
|
||||
func TestMissingDependency(t *testing.T) {
|
||||
@ -664,7 +664,7 @@ func main() {
|
||||
env.Await(
|
||||
env.DiagnosticAtRegexp("main.go", `"github.com/ardanlabs/conf"`),
|
||||
)
|
||||
}, WithProxy(ardanLabsProxy))
|
||||
}, WithProxyFiles(ardanLabsProxy))
|
||||
}
|
||||
|
||||
// Test for golang/go#38207.
|
||||
@ -700,7 +700,7 @@ func main() {
|
||||
env.Await(
|
||||
EmptyDiagnostics("main.go"),
|
||||
)
|
||||
}, WithProxy(ardanLabsProxy))
|
||||
}, WithProxyFiles(ardanLabsProxy))
|
||||
}
|
||||
|
||||
// Test for golang/go#36960.
|
||||
|
@ -105,13 +105,13 @@ type condition struct {
|
||||
|
||||
// NewEnv creates a new test environment using the given scratch environment
|
||||
// and gopls server.
|
||||
func NewEnv(ctx context.Context, t *testing.T, scratch *fake.Sandbox, ts servertest.Connector, editorConfig fake.EditorConfig) *Env {
|
||||
func NewEnv(ctx context.Context, t *testing.T, sandbox *fake.Sandbox, ts servertest.Connector, editorConfig fake.EditorConfig, withHooks bool) *Env {
|
||||
t.Helper()
|
||||
conn := ts.Connect(ctx)
|
||||
env := &Env{
|
||||
T: t,
|
||||
Ctx: ctx,
|
||||
Sandbox: scratch,
|
||||
Sandbox: sandbox,
|
||||
Server: ts,
|
||||
state: State{
|
||||
diagnostics: make(map[string]*protocol.PublishDiagnosticsParams),
|
||||
@ -120,15 +120,18 @@ func NewEnv(ctx context.Context, t *testing.T, scratch *fake.Sandbox, ts servert
|
||||
},
|
||||
waiters: make(map[int]*condition),
|
||||
}
|
||||
hooks := fake.ClientHooks{
|
||||
OnDiagnostics: env.onDiagnostics,
|
||||
OnLogMessage: env.onLogMessage,
|
||||
OnWorkDoneProgressCreate: env.onWorkDoneProgressCreate,
|
||||
OnProgress: env.onProgress,
|
||||
OnShowMessage: env.onShowMessage,
|
||||
OnShowMessageRequest: env.onShowMessageRequest,
|
||||
var hooks fake.ClientHooks
|
||||
if withHooks {
|
||||
hooks = fake.ClientHooks{
|
||||
OnDiagnostics: env.onDiagnostics,
|
||||
OnLogMessage: env.onLogMessage,
|
||||
OnWorkDoneProgressCreate: env.onWorkDoneProgressCreate,
|
||||
OnProgress: env.onProgress,
|
||||
OnShowMessage: env.onShowMessage,
|
||||
OnShowMessageRequest: env.onShowMessageRequest,
|
||||
}
|
||||
}
|
||||
editor, err := fake.NewEditor(scratch, editorConfig).Connect(ctx, conn, hooks)
|
||||
editor, err := fake.NewEditor(sandbox, editorConfig).Connect(ctx, conn, hooks)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ var _, _ = x.X, y.Y
|
||||
editorConfig := fake.EditorConfig{Env: map[string]string{"GOMODCACHE": modcache}}
|
||||
withOptions(
|
||||
WithEditorConfig(editorConfig),
|
||||
WithProxy(proxy),
|
||||
WithProxyFiles(proxy),
|
||||
).run(t, files, func(t *testing.T, env *Env) {
|
||||
env.OpenFile("main.go")
|
||||
env.Await(env.DiagnosticAtRegexp("main.go", `y.Y`))
|
||||
|
@ -81,5 +81,5 @@ const Hello = "Hello"
|
||||
if len(links) != 0 {
|
||||
t.Errorf("documentLink: got %d document links for go.mod, want 0\nlinks: %v", len(links), links)
|
||||
}
|
||||
}, WithProxy(proxy))
|
||||
}, WithProxyFiles(proxy))
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ func main() {
|
||||
}
|
||||
`
|
||||
t.Run("basic", func(t *testing.T) {
|
||||
withOptions(WithProxy(proxy)).run(t, untidyModule, func(t *testing.T, env *Env) {
|
||||
withOptions(WithProxyFiles(proxy)).run(t, untidyModule, func(t *testing.T, env *Env) {
|
||||
// Open the file and make sure that the initial workspace load does not
|
||||
// modify the go.mod file.
|
||||
goModContent := env.ReadWorkspaceFile("go.mod")
|
||||
@ -76,7 +76,7 @@ func main() {
|
||||
t.Run("delete main.go", func(t *testing.T) {
|
||||
t.Skipf("This test will be flaky until golang/go#40269 is resolved.")
|
||||
|
||||
withOptions(WithProxy(proxy)).run(t, untidyModule, func(t *testing.T, env *Env) {
|
||||
withOptions(WithProxyFiles(proxy)).run(t, untidyModule, func(t *testing.T, env *Env) {
|
||||
goModContent := env.ReadWorkspaceFile("go.mod")
|
||||
mainContent := env.ReadWorkspaceFile("main.go")
|
||||
env.OpenFile("main.go")
|
||||
@ -140,7 +140,7 @@ require example.com v1.2.3
|
||||
if got := env.Editor.BufferText("go.mod"); got != want {
|
||||
t.Fatalf("unexpected go.mod content:\n%s", tests.Diff(want, got))
|
||||
}
|
||||
}, WithProxy(proxy))
|
||||
}, WithProxyFiles(proxy))
|
||||
}
|
||||
|
||||
// Test to reproduce golang/go#39041. It adds a new require to a go.mod file
|
||||
@ -207,7 +207,7 @@ require (
|
||||
if got := env.Editor.BufferText("go.mod"); got != want {
|
||||
t.Fatalf("TestNewDepWithUnusedDep failed:\n%s", tests.Diff(want, got))
|
||||
}
|
||||
}, WithProxy(proxy))
|
||||
}, WithProxyFiles(proxy))
|
||||
}
|
||||
|
||||
// TODO: For this test to be effective, the sandbox's file watcher must respect
|
||||
@ -242,7 +242,7 @@ go 1.12
|
||||
env.Await(
|
||||
EmptyDiagnostics("go.mod"),
|
||||
)
|
||||
}, WithProxy(proxy))
|
||||
}, WithProxyFiles(proxy))
|
||||
}
|
||||
|
||||
func TestBadlyVersionedModule(t *testing.T) {
|
||||
@ -328,7 +328,7 @@ require (
|
||||
if got := env.Editor.BufferText("go.mod"); got != want {
|
||||
t.Fatalf("suggested fixes failed:\n%s", tests.Diff(want, got))
|
||||
}
|
||||
}, WithProxy(badModule))
|
||||
}, WithProxyFiles(badModule))
|
||||
}
|
||||
|
||||
// Reproduces golang/go#38232.
|
||||
@ -367,7 +367,7 @@ func main() {
|
||||
env.Await(
|
||||
env.DiagnosticAtRegexp("main.go", "x = "),
|
||||
)
|
||||
}, WithProxy(proxy))
|
||||
}, WithProxyFiles(proxy))
|
||||
})
|
||||
|
||||
const known = `
|
||||
@ -404,7 +404,7 @@ func main() {
|
||||
env.Await(
|
||||
env.DiagnosticAtRegexp("main.go", "x = "),
|
||||
)
|
||||
}, WithProxy(proxy))
|
||||
}, WithProxyFiles(proxy))
|
||||
})
|
||||
}
|
||||
|
||||
@ -427,7 +427,7 @@ func main() {
|
||||
fmt.Println(blah.Name)
|
||||
}
|
||||
`
|
||||
withOptions(WithProxy(proxy)).run(t, untidyModule, func(t *testing.T, env *Env) {
|
||||
withOptions(WithProxyFiles(proxy)).run(t, untidyModule, func(t *testing.T, env *Env) {
|
||||
env.OpenFile("go.mod")
|
||||
env.Await(
|
||||
env.DiagnosticAtRegexp("main.go", `"example.com/blah"`),
|
||||
@ -487,7 +487,7 @@ func main() {
|
||||
println(blah.Name)
|
||||
}
|
||||
`
|
||||
withOptions(WithProxy(badProxy)).run(t, module, func(t *testing.T, env *Env) {
|
||||
withOptions(WithProxyFiles(badProxy)).run(t, module, func(t *testing.T, env *Env) {
|
||||
env.OpenFile("go.mod")
|
||||
env.Await(
|
||||
env.DiagnosticAtRegexp("go.mod", "require example.com v1.2.3"),
|
||||
|
@ -68,10 +68,13 @@ type Runner struct {
|
||||
}
|
||||
|
||||
type runConfig struct {
|
||||
editor fake.EditorConfig
|
||||
sandbox fake.SandboxConfig
|
||||
modes Mode
|
||||
timeout time.Duration
|
||||
editor fake.EditorConfig
|
||||
sandbox fake.SandboxConfig
|
||||
modes Mode
|
||||
timeout time.Duration
|
||||
debugAddr string
|
||||
skipLogs bool
|
||||
skipHooks bool
|
||||
}
|
||||
|
||||
func (r *Runner) defaultConfig() *runConfig {
|
||||
@ -99,8 +102,8 @@ func WithTimeout(d time.Duration) RunOption {
|
||||
})
|
||||
}
|
||||
|
||||
// WithProxy configures a file proxy using the given txtar-encoded string.
|
||||
func WithProxy(txt string) RunOption {
|
||||
// WithProxyFiles configures a file proxy using the given txtar-encoded string.
|
||||
func WithProxyFiles(txt string) RunOption {
|
||||
return optionSetter(func(opts *runConfig) {
|
||||
opts.sandbox.ProxyFiles = txt
|
||||
})
|
||||
@ -148,6 +151,50 @@ func InGOPATH() RunOption {
|
||||
})
|
||||
}
|
||||
|
||||
// WithDebugAddress configures a debug server bound to addr. This option is
|
||||
// currently only supported when executing in Singleton mode. It is intended to
|
||||
// be used for long-running stress tests.
|
||||
func WithDebugAddress(addr string) RunOption {
|
||||
return optionSetter(func(opts *runConfig) {
|
||||
opts.debugAddr = addr
|
||||
})
|
||||
}
|
||||
|
||||
// SkipLogs skips the buffering of logs during test execution. It is intended
|
||||
// for long-running stress tests.
|
||||
func SkipLogs() RunOption {
|
||||
return optionSetter(func(opts *runConfig) {
|
||||
opts.skipLogs = true
|
||||
})
|
||||
}
|
||||
|
||||
// InExistingDir runs the test in a pre-existing directory. If set, no initial
|
||||
// files may be passed to the runner. It is intended for long-running stress
|
||||
// tests.
|
||||
func InExistingDir(dir string) RunOption {
|
||||
return optionSetter(func(opts *runConfig) {
|
||||
opts.sandbox.Workdir = dir
|
||||
})
|
||||
}
|
||||
|
||||
// NoHooks disables the test runner's client hooks that are used for
|
||||
// instrumenting expectations (tracking diagnostics, logs, work done, etc.). It
|
||||
// is intended for performance-sensitive stress tests.
|
||||
func NoHooks() RunOption {
|
||||
return optionSetter(func(opts *runConfig) {
|
||||
opts.skipHooks = true
|
||||
})
|
||||
}
|
||||
|
||||
// WithGOPROXY configures the test environment to have an explicit proxy value.
|
||||
// This is intended for stress tests -- to ensure their isolation, regtests
|
||||
// should instead use WithProxyFiles.
|
||||
func WithGOPROXY(goproxy string) RunOption {
|
||||
return optionSetter(func(opts *runConfig) {
|
||||
opts.sandbox.GOPROXY = goproxy
|
||||
})
|
||||
}
|
||||
|
||||
type TestFunc func(t *testing.T, env *Env)
|
||||
|
||||
// Run executes the test function in the default configured gopls execution
|
||||
@ -175,10 +222,23 @@ func (r *Runner) Run(t *testing.T, files string, test TestFunc, opts ...RunOptio
|
||||
if config.modes&tc.mode == 0 {
|
||||
continue
|
||||
}
|
||||
if config.debugAddr != "" && tc.mode != Singleton {
|
||||
// Debugging is useful for running stress tests, but since the daemon has
|
||||
// likely already been started, it would be too late to debug.
|
||||
t.Fatalf("debugging regtest servers only works in Singleton mode, "+
|
||||
"got debug addr %q and mode %v", config.debugAddr, tc.mode)
|
||||
}
|
||||
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), config.timeout)
|
||||
defer cancel()
|
||||
ctx = debug.WithInstance(ctx, "", "")
|
||||
ctx = debug.WithInstance(ctx, "", "off")
|
||||
if config.debugAddr != "" {
|
||||
di := debug.GetInstance(ctx)
|
||||
di.DebugAddress = config.debugAddr
|
||||
di.Serve(ctx)
|
||||
di.MonitorMemory(ctx)
|
||||
}
|
||||
|
||||
tempDir := filepath.Join(r.TempDir, filepath.FromSlash(t.Name()))
|
||||
if err := os.MkdirAll(tempDir, 0755); err != nil {
|
||||
@ -198,10 +258,13 @@ func (r *Runner) Run(t *testing.T, files string, test TestFunc, opts ...RunOptio
|
||||
// exited before we clean up.
|
||||
r.AddCloser(sandbox)
|
||||
ss := tc.getServer(ctx, t)
|
||||
framer := jsonrpc2.NewRawStream
|
||||
ls := &loggingFramer{}
|
||||
framer := ls.framer(jsonrpc2.NewRawStream)
|
||||
if !config.skipLogs {
|
||||
framer = ls.framer(jsonrpc2.NewRawStream)
|
||||
}
|
||||
ts := servertest.NewPipeServer(ctx, ss, framer)
|
||||
env := NewEnv(ctx, t, sandbox, ts, config.editor)
|
||||
env := NewEnv(ctx, t, sandbox, ts, config.editor, !config.skipHooks)
|
||||
defer func() {
|
||||
if t.Failed() && r.PrintGoroutinesOnFailure {
|
||||
pprof.Lookup("goroutine").WriteTo(os.Stderr, 1)
|
||||
@ -261,7 +324,7 @@ func (r *Runner) getTestServer() *servertest.TCPServer {
|
||||
defer r.mu.Unlock()
|
||||
if r.ts == nil {
|
||||
ctx := context.Background()
|
||||
ctx = debug.WithInstance(ctx, "", "")
|
||||
ctx = debug.WithInstance(ctx, "", "off")
|
||||
ss := lsprpc.NewStreamServer(cache.New(ctx, nil), false)
|
||||
r.ts = servertest.NewTCPServer(ctx, ss, nil)
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ func runShared(t *testing.T, program string, testFunc func(env1 *Env, env2 *Env)
|
||||
runner.Run(t, sharedProgram, func(t *testing.T, env1 *Env) {
|
||||
// Create a second test session connected to the same workspace and server
|
||||
// as the first.
|
||||
env2 := NewEnv(env1.Ctx, t, env1.Sandbox, env1.Server, env1.Editor.Config)
|
||||
env2 := NewEnv(env1.Ctx, t, env1.Sandbox, env1.Server, env1.Editor.Config, true)
|
||||
testFunc(env1, env2)
|
||||
}, WithModes(modes))
|
||||
}
|
||||
|
@ -58,5 +58,5 @@ func _() {
|
||||
DiagnosticAt("a/a1.go", 6, 5),
|
||||
),
|
||||
)
|
||||
}, WithProxy(basicProxy))
|
||||
}, WithProxyFiles(basicProxy))
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ func TestReferences(t *testing.T) {
|
||||
},
|
||||
} {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
opts := []RunOption{WithProxy(workspaceProxy)}
|
||||
opts := []RunOption{WithProxyFiles(workspaceProxy)}
|
||||
if tt.rootPath != "" {
|
||||
opts = append(opts, WithRootPath(tt.rootPath))
|
||||
}
|
||||
@ -95,7 +95,7 @@ func TestReferences(t *testing.T) {
|
||||
// VS Code, where clicking on a reference result triggers a
|
||||
// textDocument/didOpen without a corresponding textDocument/didClose.
|
||||
func TestClearAnalysisDiagnostics(t *testing.T) {
|
||||
withOptions(WithProxy(workspaceProxy), WithRootPath("inner")).run(t, workspaceModule, func(t *testing.T, env *Env) {
|
||||
withOptions(WithProxyFiles(workspaceProxy), WithRootPath("inner")).run(t, workspaceModule, func(t *testing.T, env *Env) {
|
||||
env.OpenFile("main.go")
|
||||
env.Await(
|
||||
env.DiagnosticAtRegexp("main2.go", "fmt.Print"),
|
||||
|
Loading…
Reference in New Issue
Block a user