mirror of
https://github.com/golang/go
synced 2024-11-18 08:54:45 -07:00
internal/lsp: move the debug.Instance onto the Context
This allows us to register a telemetry exporter that works with mulitple active debug instances. It also means we don't have to store the debug information in our other objects. Change-Id: I9a9d5b0407c3352b6eaff80fb2c434ca33f4e397 Reviewed-on: https://go-review.googlesource.com/c/tools/+/221558 Run-TryBot: Ian Cottrell <iancottrell@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
2b0b585e22
commit
4183ba16a9
@ -42,9 +42,9 @@ func testCommandLine(t *testing.T, exporter packagestest.Exporter) {
|
||||
}
|
||||
data := tests.Load(t, exporter, testdata)
|
||||
ctx := tests.Context(t)
|
||||
di := debug.NewInstance("", "")
|
||||
cache := cache.New(commandLineOptions, di.State)
|
||||
ss := lsprpc.NewStreamServer(cache, false, di)
|
||||
ctx = debug.WithInstance(ctx, "", "")
|
||||
cache := cache.New(ctx, commandLineOptions)
|
||||
ss := lsprpc.NewStreamServer(cache, false)
|
||||
ts := servertest.NewTCPServer(ctx, ss)
|
||||
for _, data := range data {
|
||||
defer data.Exported.Cleanup()
|
||||
|
17
internal/lsp/cache/cache.go
vendored
17
internal/lsp/cache/cache.go
vendored
@ -19,19 +19,17 @@ import (
|
||||
"golang.org/x/tools/internal/span"
|
||||
)
|
||||
|
||||
func New(options func(*source.Options), debugState *debug.State) *Cache {
|
||||
if debugState == nil {
|
||||
debugState = &debug.State{}
|
||||
}
|
||||
func New(ctx context.Context, options func(*source.Options)) *Cache {
|
||||
index := atomic.AddInt64(&cacheIndex, 1)
|
||||
c := &Cache{
|
||||
fs: &nativeFileSystem{},
|
||||
id: strconv.FormatInt(index, 10),
|
||||
fset: token.NewFileSet(),
|
||||
options: options,
|
||||
debug: debugState,
|
||||
}
|
||||
debugState.AddCache(debugCache{c})
|
||||
if di := debug.GetInstance(ctx); di != nil {
|
||||
di.State.AddCache(debugCache{c})
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
@ -40,7 +38,6 @@ type Cache struct {
|
||||
id string
|
||||
fset *token.FileSet
|
||||
options func(*source.Options)
|
||||
debug *debug.State
|
||||
|
||||
store memoize.Store
|
||||
}
|
||||
@ -79,7 +76,7 @@ func (c *Cache) GetFile(uri span.URI) source.FileHandle {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Cache) NewSession() *Session {
|
||||
func (c *Cache) NewSession(ctx context.Context) *Session {
|
||||
index := atomic.AddInt64(&sessionIndex, 1)
|
||||
s := &Session{
|
||||
cache: c,
|
||||
@ -87,7 +84,9 @@ func (c *Cache) NewSession() *Session {
|
||||
options: source.DefaultOptions(),
|
||||
overlays: make(map[span.URI]*overlay),
|
||||
}
|
||||
c.debug.AddSession(DebugSession{s})
|
||||
if di := debug.GetInstance(ctx); di != nil {
|
||||
di.State.AddSession(DebugSession{s})
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
|
9
internal/lsp/cache/session.go
vendored
9
internal/lsp/cache/session.go
vendored
@ -11,6 +11,7 @@ import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"golang.org/x/tools/internal/lsp/debug"
|
||||
"golang.org/x/tools/internal/lsp/source"
|
||||
"golang.org/x/tools/internal/span"
|
||||
"golang.org/x/tools/internal/telemetry/trace"
|
||||
@ -77,7 +78,9 @@ func (s *Session) Shutdown(ctx context.Context) {
|
||||
}
|
||||
s.views = nil
|
||||
s.viewMap = nil
|
||||
s.cache.debug.DropSession(DebugSession{s})
|
||||
if di := debug.GetInstance(ctx); di != nil {
|
||||
di.State.DropSession(DebugSession{s})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Session) Cache() source.Cache {
|
||||
@ -142,7 +145,9 @@ func (s *Session) createView(ctx context.Context, name string, folder span.URI,
|
||||
// Initialize the view without blocking.
|
||||
go v.initialize(xcontext.Detach(ctx), v.snapshot)
|
||||
|
||||
v.session.cache.debug.AddView(debugView{v})
|
||||
if di := debug.GetInstance(ctx); di != nil {
|
||||
di.State.AddView(debugView{v})
|
||||
}
|
||||
return v, v.snapshot, nil
|
||||
}
|
||||
|
||||
|
7
internal/lsp/cache/view.go
vendored
7
internal/lsp/cache/view.go
vendored
@ -23,6 +23,7 @@ import (
|
||||
"golang.org/x/tools/go/packages"
|
||||
"golang.org/x/tools/internal/gocommand"
|
||||
"golang.org/x/tools/internal/imports"
|
||||
"golang.org/x/tools/internal/lsp/debug"
|
||||
"golang.org/x/tools/internal/lsp/source"
|
||||
"golang.org/x/tools/internal/lsp/telemetry"
|
||||
"golang.org/x/tools/internal/memoize"
|
||||
@ -472,7 +473,7 @@ func (v *view) Shutdown(ctx context.Context) {
|
||||
v.session.removeView(ctx, v)
|
||||
}
|
||||
|
||||
func (v *view) shutdown(context.Context) {
|
||||
func (v *view) shutdown(ctx context.Context) {
|
||||
// TODO: Cancel the view's initialization.
|
||||
v.mu.Lock()
|
||||
defer v.mu.Unlock()
|
||||
@ -484,7 +485,9 @@ func (v *view) shutdown(context.Context) {
|
||||
os.Remove(v.tempMod.Filename())
|
||||
os.Remove(tempSumFile(v.tempMod.Filename()))
|
||||
}
|
||||
v.session.cache.debug.DropView(debugView{v})
|
||||
if di := debug.GetInstance(ctx); di != nil {
|
||||
di.State.DropView(debugView{v})
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore checks if the given URI is a URI we ignore.
|
||||
|
@ -39,7 +39,7 @@ func TestCapabilities(t *testing.T) {
|
||||
params.Capabilities.Workspace.Configuration = true
|
||||
|
||||
// Send an initialize request to the server.
|
||||
c.Server = lsp.NewServer(cache.New(app.options, nil).NewSession(), c.Client)
|
||||
c.Server = lsp.NewServer(cache.New(ctx, app.options).NewSession(ctx), c.Client)
|
||||
result, err := c.Server.Initialize(ctx, params)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -68,8 +68,6 @@ type Application struct {
|
||||
// PrepareOptions is called to update the options when a new view is built.
|
||||
// It is primarily to allow the behavior of gopls to be modified by hooks.
|
||||
PrepareOptions func(*source.Options)
|
||||
|
||||
debug *debug.Instance
|
||||
}
|
||||
|
||||
// New returns a new Application ready to run.
|
||||
@ -131,7 +129,7 @@ gopls flags are:
|
||||
// If no arguments are passed it will invoke the server sub command, as a
|
||||
// temporary measure for compatibility.
|
||||
func (app *Application) Run(ctx context.Context, args ...string) error {
|
||||
app.debug = debug.NewInstance(app.wd, app.OCAgent)
|
||||
ctx = debug.WithInstance(ctx, app.wd, app.OCAgent)
|
||||
app.Serve.app = app
|
||||
if len(args) == 0 {
|
||||
return tool.Run(ctx, &app.Serve, args)
|
||||
@ -191,7 +189,7 @@ func (app *Application) connect(ctx context.Context) (*connection, error) {
|
||||
switch {
|
||||
case app.Remote == "":
|
||||
connection := newConnection(app)
|
||||
connection.Server = lsp.NewServer(cache.New(app.options, nil).NewSession(), connection.Client)
|
||||
connection.Server = lsp.NewServer(cache.New(ctx, app.options).NewSession(ctx), connection.Client)
|
||||
ctx = protocol.WithClient(ctx, connection.Client)
|
||||
return connection, connection.initialize(ctx, app.options)
|
||||
case strings.HasPrefix(app.Remote, "internal@"):
|
||||
|
@ -47,9 +47,9 @@ func testCommandLine(t *testing.T, exporter packagestest.Exporter) {
|
||||
}
|
||||
|
||||
func testServer(ctx context.Context) *servertest.TCPServer {
|
||||
di := debug.NewInstance("", "")
|
||||
cache := cache.New(nil, di.State)
|
||||
ss := lsprpc.NewStreamServer(cache, false, di)
|
||||
ctx = debug.WithInstance(ctx, "", "")
|
||||
cache := cache.New(ctx, nil)
|
||||
ss := lsprpc.NewStreamServer(cache, false)
|
||||
return servertest.NewTCPServer(ctx, ss)
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
|
||||
"golang.org/x/tools/internal/jsonrpc2"
|
||||
"golang.org/x/tools/internal/lsp/cache"
|
||||
"golang.org/x/tools/internal/lsp/debug"
|
||||
"golang.org/x/tools/internal/lsp/lsprpc"
|
||||
"golang.org/x/tools/internal/lsp/protocol"
|
||||
"golang.org/x/tools/internal/tool"
|
||||
@ -55,22 +56,24 @@ func (s *Serve) Run(ctx context.Context, args ...string) error {
|
||||
return tool.CommandLineErrorf("server does not take arguments, got %v", args)
|
||||
}
|
||||
|
||||
closeLog, err := s.app.debug.SetLogFile(s.Logfile)
|
||||
if err != nil {
|
||||
return err
|
||||
di := debug.GetInstance(ctx)
|
||||
if di != nil {
|
||||
closeLog, err := di.SetLogFile(s.Logfile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closeLog()
|
||||
di.ServerAddress = s.Address
|
||||
di.DebugAddress = s.Debug
|
||||
di.Serve(ctx)
|
||||
di.MonitorMemory(ctx)
|
||||
}
|
||||
defer closeLog()
|
||||
s.app.debug.ServerAddress = s.Address
|
||||
s.app.debug.DebugAddress = s.Debug
|
||||
s.app.debug.Serve(ctx)
|
||||
s.app.debug.MonitorMemory(ctx)
|
||||
|
||||
var ss jsonrpc2.StreamServer
|
||||
if s.app.Remote != "" {
|
||||
network, addr := parseAddr(s.app.Remote)
|
||||
ss = lsprpc.NewForwarder(network, addr, true, s.app.debug)
|
||||
ss = lsprpc.NewForwarder(network, addr, true)
|
||||
} else {
|
||||
ss = lsprpc.NewStreamServer(cache.New(s.app.options, s.app.debug.State), true, s.app.debug)
|
||||
ss = lsprpc.NewStreamServer(cache.New(ctx, s.app.options), true)
|
||||
}
|
||||
|
||||
if s.Address != "" {
|
||||
@ -82,8 +85,8 @@ func (s *Serve) Run(ctx context.Context, args ...string) error {
|
||||
return jsonrpc2.ListenAndServe(ctx, "tcp", addr, ss, s.IdleTimeout)
|
||||
}
|
||||
stream := jsonrpc2.NewHeaderStream(os.Stdin, os.Stdout)
|
||||
if s.Trace {
|
||||
stream = protocol.LoggingStream(stream, s.app.debug.LogWriter)
|
||||
if s.Trace && di != nil {
|
||||
stream = protocol.LoggingStream(stream, di.LogWriter)
|
||||
}
|
||||
return ss.ServeStream(ctx, stream)
|
||||
}
|
||||
|
@ -37,6 +37,14 @@ import (
|
||||
"golang.org/x/tools/internal/telemetry/tag"
|
||||
)
|
||||
|
||||
type exporter struct {
|
||||
stderr io.Writer
|
||||
}
|
||||
|
||||
type instanceKeyType int
|
||||
|
||||
const instanceKey = instanceKeyType(0)
|
||||
|
||||
// An Instance holds all debug information associated with a gopls instance.
|
||||
type Instance struct {
|
||||
Logfile string
|
||||
@ -378,8 +386,26 @@ func getMemory(r *http.Request) interface{} {
|
||||
return m
|
||||
}
|
||||
|
||||
// NewInstance creates debug instance ready for use using the supplied configuration.
|
||||
func NewInstance(workdir, agent string) *Instance {
|
||||
func init() {
|
||||
export.SetExporter(&exporter{
|
||||
stderr: os.Stderr,
|
||||
})
|
||||
}
|
||||
|
||||
func GetInstance(ctx context.Context) *Instance {
|
||||
if ctx == nil {
|
||||
return nil
|
||||
}
|
||||
v := ctx.Value(instanceKey)
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
return v.(*Instance)
|
||||
}
|
||||
|
||||
// WithInstance creates debug instance ready for use using the supplied
|
||||
// configuration and stores it in the returned context.
|
||||
func WithInstance(ctx context.Context, workdir, agent string) context.Context {
|
||||
i := &Instance{
|
||||
StartTime: time.Now(),
|
||||
Workdir: workdir,
|
||||
@ -394,8 +420,7 @@ func NewInstance(workdir, agent string) *Instance {
|
||||
i.rpcs = &rpcs{}
|
||||
i.traces = &traces{}
|
||||
i.State = &State{}
|
||||
export.SetExporter(i)
|
||||
return i
|
||||
return context.WithValue(ctx, instanceKey, i)
|
||||
}
|
||||
|
||||
// SetLogFile sets the logfile for use with this instance.
|
||||
@ -519,7 +544,11 @@ func (i *Instance) writeMemoryDebug(threshold uint64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *Instance) StartSpan(ctx context.Context, spn *telemetry.Span) {
|
||||
func (e *exporter) StartSpan(ctx context.Context, spn *telemetry.Span) {
|
||||
i := GetInstance(ctx)
|
||||
if i == nil {
|
||||
return
|
||||
}
|
||||
if i.ocagent != nil {
|
||||
i.ocagent.StartSpan(ctx, spn)
|
||||
}
|
||||
@ -528,7 +557,11 @@ func (i *Instance) StartSpan(ctx context.Context, spn *telemetry.Span) {
|
||||
}
|
||||
}
|
||||
|
||||
func (i *Instance) FinishSpan(ctx context.Context, spn *telemetry.Span) {
|
||||
func (e *exporter) FinishSpan(ctx context.Context, spn *telemetry.Span) {
|
||||
i := GetInstance(ctx)
|
||||
if i == nil {
|
||||
return
|
||||
}
|
||||
if i.ocagent != nil {
|
||||
i.ocagent.FinishSpan(ctx, spn)
|
||||
}
|
||||
@ -537,14 +570,13 @@ func (i *Instance) FinishSpan(ctx context.Context, spn *telemetry.Span) {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: remove this hack
|
||||
// capture stderr at startup because it gets modified in a way that this
|
||||
// logger should not respect
|
||||
var stderr = os.Stderr
|
||||
|
||||
func (i *Instance) Log(ctx context.Context, event telemetry.Event) {
|
||||
if event.Error != nil {
|
||||
fmt.Fprintf(stderr, "%v\n", event)
|
||||
func (e *exporter) Log(ctx context.Context, event telemetry.Event) {
|
||||
i := GetInstance(ctx)
|
||||
if event.Error != nil || i == nil {
|
||||
fmt.Fprintf(e.stderr, "%v\n", event)
|
||||
}
|
||||
if i == nil {
|
||||
return
|
||||
}
|
||||
protocol.LogEvent(ctx, event)
|
||||
if i.ocagent != nil {
|
||||
@ -552,7 +584,11 @@ func (i *Instance) Log(ctx context.Context, event telemetry.Event) {
|
||||
}
|
||||
}
|
||||
|
||||
func (i *Instance) Metric(ctx context.Context, data telemetry.MetricData) {
|
||||
func (e *exporter) Metric(ctx context.Context, data telemetry.MetricData) {
|
||||
i := GetInstance(ctx)
|
||||
if i == nil {
|
||||
return
|
||||
}
|
||||
if i.ocagent != nil {
|
||||
i.ocagent.Metric(ctx, data)
|
||||
}
|
||||
|
@ -49,8 +49,8 @@ func testLSP(t *testing.T, exporter packagestest.Exporter) {
|
||||
for _, datum := range data {
|
||||
defer datum.Exported.Cleanup()
|
||||
|
||||
cache := cache.New(nil, nil)
|
||||
session := cache.NewSession()
|
||||
cache := cache.New(ctx, nil)
|
||||
session := cache.NewSession(ctx)
|
||||
options := tests.DefaultOptions()
|
||||
session.SetOptions(options)
|
||||
options.Env = datum.Config.Env
|
||||
|
@ -35,7 +35,6 @@ const AutoNetwork = "auto"
|
||||
// streams as a new LSP session, using a shared cache.
|
||||
type StreamServer struct {
|
||||
withTelemetry bool
|
||||
debug *debug.Instance
|
||||
cache *cache.Cache
|
||||
|
||||
// serverForTest may be set to a test fake for testing.
|
||||
@ -47,10 +46,9 @@ var clientIndex, serverIndex int64
|
||||
// NewStreamServer creates a StreamServer using the shared cache. If
|
||||
// withTelemetry is true, each session is instrumented with telemetry that
|
||||
// records RPC statistics.
|
||||
func NewStreamServer(cache *cache.Cache, withTelemetry bool, debugInstance *debug.Instance) *StreamServer {
|
||||
func NewStreamServer(cache *cache.Cache, withTelemetry bool) *StreamServer {
|
||||
s := &StreamServer{
|
||||
withTelemetry: withTelemetry,
|
||||
debug: debugInstance,
|
||||
cache: cache,
|
||||
}
|
||||
return s
|
||||
@ -118,16 +116,17 @@ func (s *StreamServer) ServeStream(ctx context.Context, stream jsonrpc2.Stream)
|
||||
|
||||
conn := jsonrpc2.NewConn(stream)
|
||||
client := protocol.ClientDispatcher(conn)
|
||||
session := s.cache.NewSession()
|
||||
session := s.cache.NewSession(ctx)
|
||||
dc := &debugClient{
|
||||
debugInstance: debugInstance{
|
||||
id: strconv.FormatInt(index, 10),
|
||||
},
|
||||
session: session,
|
||||
}
|
||||
s.debug.State.AddClient(dc)
|
||||
defer s.debug.State.DropClient(dc)
|
||||
|
||||
if di := debug.GetInstance(ctx); di != nil {
|
||||
di.State.AddClient(dc)
|
||||
defer di.State.DropClient(dc)
|
||||
}
|
||||
server := s.serverForTest
|
||||
if server == nil {
|
||||
server = lsp.NewServer(session, client)
|
||||
@ -148,7 +147,6 @@ func (s *StreamServer) ServeStream(ctx context.Context, stream jsonrpc2.Stream)
|
||||
}
|
||||
conn.AddHandler(&handshaker{
|
||||
client: dc,
|
||||
debug: s.debug,
|
||||
goplsPath: executable,
|
||||
})
|
||||
return conn.Run(protocol.WithClient(ctx, client))
|
||||
@ -168,13 +166,12 @@ type Forwarder struct {
|
||||
withTelemetry bool
|
||||
dialTimeout time.Duration
|
||||
retries int
|
||||
debug *debug.Instance
|
||||
goplsPath string
|
||||
}
|
||||
|
||||
// NewForwarder creates a new Forwarder, ready to forward connections to the
|
||||
// remote server specified by network and addr.
|
||||
func NewForwarder(network, addr string, withTelemetry bool, debugInstance *debug.Instance) *Forwarder {
|
||||
func NewForwarder(network, addr string, withTelemetry bool) *Forwarder {
|
||||
gp, err := os.Executable()
|
||||
if err != nil {
|
||||
stdlog.Printf("error getting gopls path for forwarder: %v", err)
|
||||
@ -187,7 +184,6 @@ func NewForwarder(network, addr string, withTelemetry bool, debugInstance *debug
|
||||
withTelemetry: withTelemetry,
|
||||
dialTimeout: 1 * time.Second,
|
||||
retries: 5,
|
||||
debug: debugInstance,
|
||||
goplsPath: gp,
|
||||
}
|
||||
}
|
||||
@ -224,30 +220,35 @@ func (f *Forwarder) ServeStream(ctx context.Context, stream jsonrpc2.Stream) err
|
||||
// Do a handshake with the server instance to exchange debug information.
|
||||
index := atomic.AddInt64(&serverIndex, 1)
|
||||
serverID := strconv.FormatInt(index, 10)
|
||||
di := debug.GetInstance(ctx)
|
||||
var (
|
||||
hreq = handshakeRequest{
|
||||
ServerID: serverID,
|
||||
Logfile: f.debug.Logfile,
|
||||
DebugAddr: f.debug.ListenedDebugAddress,
|
||||
GoplsPath: f.goplsPath,
|
||||
}
|
||||
hresp handshakeResponse
|
||||
)
|
||||
if di != nil {
|
||||
hreq.Logfile = di.Logfile
|
||||
hreq.DebugAddr = di.ListenedDebugAddress
|
||||
}
|
||||
if err := serverConn.Call(ctx, handshakeMethod, hreq, &hresp); err != nil {
|
||||
log.Error(ctx, "forwarder: gopls handshake failed", err)
|
||||
}
|
||||
if hresp.GoplsPath != f.goplsPath {
|
||||
log.Error(ctx, "", fmt.Errorf("forwarder: gopls path mismatch: forwarder is %q, remote is %q", f.goplsPath, hresp.GoplsPath))
|
||||
}
|
||||
f.debug.State.AddServer(debugServer{
|
||||
debugInstance: debugInstance{
|
||||
id: serverID,
|
||||
logfile: hresp.Logfile,
|
||||
debugAddress: hresp.DebugAddr,
|
||||
goplsPath: hresp.GoplsPath,
|
||||
},
|
||||
clientID: hresp.ClientID,
|
||||
})
|
||||
if di != nil {
|
||||
di.State.AddServer(debugServer{
|
||||
debugInstance: debugInstance{
|
||||
id: serverID,
|
||||
logfile: hresp.Logfile,
|
||||
debugAddress: hresp.DebugAddr,
|
||||
goplsPath: hresp.GoplsPath,
|
||||
},
|
||||
clientID: hresp.ClientID,
|
||||
})
|
||||
}
|
||||
g.Go(func() error {
|
||||
return clientConn.Run(ctx)
|
||||
})
|
||||
@ -375,7 +376,6 @@ func (forwarderHandler) Deliver(ctx context.Context, r *jsonrpc2.Request, delive
|
||||
type handshaker struct {
|
||||
jsonrpc2.EmptyHandler
|
||||
client *debugClient
|
||||
debug *debug.Instance
|
||||
goplsPath string
|
||||
}
|
||||
|
||||
@ -410,10 +410,13 @@ func (h *handshaker) Deliver(ctx context.Context, r *jsonrpc2.Request, delivered
|
||||
resp := handshakeResponse{
|
||||
ClientID: h.client.id,
|
||||
SessionID: cache.DebugSession{Session: h.client.session}.ID(),
|
||||
Logfile: h.debug.Logfile,
|
||||
DebugAddr: h.debug.ListenedDebugAddress,
|
||||
GoplsPath: h.goplsPath,
|
||||
}
|
||||
if di := debug.GetInstance(ctx); di != nil {
|
||||
resp.Logfile = di.Logfile
|
||||
resp.DebugAddr = di.ListenedDebugAddress
|
||||
}
|
||||
|
||||
if err := r.Reply(ctx, resp, nil); err != nil {
|
||||
log.Error(ctx, "replying to handshake", err)
|
||||
}
|
||||
|
@ -48,8 +48,8 @@ func TestClientLogging(t *testing.T) {
|
||||
server := pingServer{}
|
||||
client := fakeClient{logs: make(chan string, 10)}
|
||||
|
||||
di := debug.NewInstance("", "")
|
||||
ss := NewStreamServer(cache.New(nil, di.State), false, di)
|
||||
ctx = debug.WithInstance(ctx, "", "")
|
||||
ss := NewStreamServer(cache.New(ctx, nil), false)
|
||||
ss.serverForTest = server
|
||||
ts := servertest.NewPipeServer(ctx, ss)
|
||||
defer ts.Close()
|
||||
@ -104,15 +104,16 @@ func TestRequestCancellation(t *testing.T) {
|
||||
server := waitableServer{
|
||||
started: make(chan struct{}),
|
||||
}
|
||||
diserve := debug.NewInstance("", "")
|
||||
ss := NewStreamServer(cache.New(nil, diserve.State), false, diserve)
|
||||
baseCtx := context.Background()
|
||||
serveCtx := debug.WithInstance(baseCtx, "", "")
|
||||
ss := NewStreamServer(cache.New(serveCtx, nil), false)
|
||||
ss.serverForTest = server
|
||||
ctx := context.Background()
|
||||
tsDirect := servertest.NewTCPServer(ctx, ss)
|
||||
tsDirect := servertest.NewTCPServer(serveCtx, ss)
|
||||
defer tsDirect.Close()
|
||||
|
||||
forwarder := NewForwarder("tcp", tsDirect.Addr, false, debug.NewInstance("", ""))
|
||||
tsForwarded := servertest.NewPipeServer(ctx, forwarder)
|
||||
forwarderCtx := debug.WithInstance(baseCtx, "", "")
|
||||
forwarder := NewForwarder("tcp", tsDirect.Addr, false)
|
||||
tsForwarded := servertest.NewPipeServer(forwarderCtx, forwarder)
|
||||
defer tsForwarded.Close()
|
||||
|
||||
tests := []struct {
|
||||
@ -125,7 +126,7 @@ func TestRequestCancellation(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.serverType, func(t *testing.T) {
|
||||
cc := test.ts.Connect(ctx)
|
||||
cc := test.ts.Connect(baseCtx)
|
||||
cc.AddHandler(protocol.Canceller{})
|
||||
ctx := context.Background()
|
||||
ctx1, cancel1 := context.WithCancel(ctx)
|
||||
@ -177,16 +178,16 @@ func TestDebugInfoLifecycle(t *testing.T) {
|
||||
resetExitFuncs := OverrideExitFuncsForTest()
|
||||
defer resetExitFuncs()
|
||||
|
||||
clientDebug := debug.NewInstance("", "")
|
||||
serverDebug := debug.NewInstance("", "")
|
||||
baseCtx := context.Background()
|
||||
clientCtx := debug.WithInstance(baseCtx, "", "")
|
||||
serverCtx := debug.WithInstance(baseCtx, "", "")
|
||||
|
||||
cache := cache.New(nil, serverDebug.State)
|
||||
ss := NewStreamServer(cache, false, serverDebug)
|
||||
ctx := context.Background()
|
||||
tsBackend := servertest.NewTCPServer(ctx, ss)
|
||||
cache := cache.New(serverCtx, nil)
|
||||
ss := NewStreamServer(cache, false)
|
||||
tsBackend := servertest.NewTCPServer(serverCtx, ss)
|
||||
|
||||
forwarder := NewForwarder("tcp", tsBackend.Addr, false, clientDebug)
|
||||
tsForwarder := servertest.NewPipeServer(ctx, forwarder)
|
||||
forwarder := NewForwarder("tcp", tsBackend.Addr, false)
|
||||
tsForwarder := servertest.NewPipeServer(clientCtx, forwarder)
|
||||
|
||||
ws, err := fake.NewWorkspace("gopls-lsprpc-test", []byte(exampleProgram))
|
||||
if err != nil {
|
||||
@ -194,31 +195,33 @@ func TestDebugInfoLifecycle(t *testing.T) {
|
||||
}
|
||||
defer ws.Close()
|
||||
|
||||
conn1 := tsForwarder.Connect(ctx)
|
||||
ed1, err := fake.NewConnectedEditor(ctx, ws, conn1)
|
||||
conn1 := tsForwarder.Connect(clientCtx)
|
||||
ed1, err := fake.NewConnectedEditor(clientCtx, ws, conn1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer ed1.Shutdown(ctx)
|
||||
conn2 := tsBackend.Connect(ctx)
|
||||
ed2, err := fake.NewConnectedEditor(ctx, ws, conn2)
|
||||
defer ed1.Shutdown(clientCtx)
|
||||
conn2 := tsBackend.Connect(baseCtx)
|
||||
ed2, err := fake.NewConnectedEditor(baseCtx, ws, conn2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer ed2.Shutdown(ctx)
|
||||
defer ed2.Shutdown(baseCtx)
|
||||
|
||||
serverDebug := debug.GetInstance(serverCtx)
|
||||
if got, want := len(serverDebug.State.Clients()), 2; got != want {
|
||||
t.Errorf("len(server:Clients) = %d, want %d", got, want)
|
||||
}
|
||||
if got, want := len(serverDebug.State.Sessions()), 2; got != want {
|
||||
t.Errorf("len(server:Sessions) = %d, want %d", got, want)
|
||||
}
|
||||
clientDebug := debug.GetInstance(clientCtx)
|
||||
if got, want := len(clientDebug.State.Servers()), 1; got != want {
|
||||
t.Errorf("len(client:Servers) = %d, want %d", got, want)
|
||||
}
|
||||
// Close one of the connections to verify that the client and session were
|
||||
// dropped.
|
||||
if err := ed1.Shutdown(ctx); err != nil {
|
||||
if err := ed1.Shutdown(clientCtx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got, want := len(serverDebug.State.Sessions()), 1; got != want {
|
||||
|
@ -24,7 +24,7 @@ func TestMain(m *testing.M) {
|
||||
func TestModfileRemainsUnchanged(t *testing.T) {
|
||||
ctx := tests.Context(t)
|
||||
cache := cache.New(nil, nil)
|
||||
session := cache.NewSession()
|
||||
session := cache.NewSession(ctx)
|
||||
options := tests.DefaultOptions()
|
||||
options.TempModfile = true
|
||||
options.Env = append(os.Environ(), "GOPACKAGESDRIVER=off", "GOROOT=")
|
||||
|
@ -80,8 +80,9 @@ func (r *Runner) getTestServer() *servertest.TCPServer {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
if r.ts == nil {
|
||||
di := debug.NewInstance("", "")
|
||||
ss := lsprpc.NewStreamServer(cache.New(nil, di.State), false, di)
|
||||
ctx := context.Background()
|
||||
ctx = debug.WithInstance(ctx, "", "")
|
||||
ss := lsprpc.NewStreamServer(cache.New(ctx, nil), false)
|
||||
r.ts = servertest.NewTCPServer(context.Background(), ss)
|
||||
}
|
||||
return r.ts
|
||||
@ -186,8 +187,8 @@ func (r *Runner) RunInMode(modes EnvMode, t *testing.T, filedata string, test fu
|
||||
}
|
||||
|
||||
func (r *Runner) singletonEnv(ctx context.Context, t *testing.T) (servertest.Connector, func()) {
|
||||
di := debug.NewInstance("", "")
|
||||
ss := lsprpc.NewStreamServer(cache.New(nil, di.State), false, di)
|
||||
ctx = debug.WithInstance(ctx, "", "")
|
||||
ss := lsprpc.NewStreamServer(cache.New(ctx, nil), false)
|
||||
ts := servertest.NewPipeServer(ctx, ss)
|
||||
cleanup := func() {
|
||||
ts.Close()
|
||||
@ -200,8 +201,9 @@ func (r *Runner) sharedEnv(ctx context.Context, t *testing.T) (servertest.Connec
|
||||
}
|
||||
|
||||
func (r *Runner) forwardedEnv(ctx context.Context, t *testing.T) (servertest.Connector, func()) {
|
||||
ctx = debug.WithInstance(ctx, "", "")
|
||||
ts := r.getTestServer()
|
||||
forwarder := lsprpc.NewForwarder("tcp", ts.Addr, false, debug.NewInstance("", ""))
|
||||
forwarder := lsprpc.NewForwarder("tcp", ts.Addr, false)
|
||||
ts2 := servertest.NewPipeServer(ctx, forwarder)
|
||||
cleanup := func() {
|
||||
ts2.Close()
|
||||
@ -210,10 +212,11 @@ func (r *Runner) forwardedEnv(ctx context.Context, t *testing.T) (servertest.Con
|
||||
}
|
||||
|
||||
func (r *Runner) separateProcessEnv(ctx context.Context, t *testing.T) (servertest.Connector, func()) {
|
||||
ctx = debug.WithInstance(ctx, "", "")
|
||||
socket := r.getRemoteSocket(t)
|
||||
// TODO(rfindley): can we use the autostart behavior here, instead of
|
||||
// pre-starting the remote?
|
||||
forwarder := lsprpc.NewForwarder("unix", socket, false, debug.NewInstance("", ""))
|
||||
forwarder := lsprpc.NewForwarder("unix", socket, false)
|
||||
ts2 := servertest.NewPipeServer(ctx, forwarder)
|
||||
cleanup := func() {
|
||||
ts2.Close()
|
||||
|
@ -47,8 +47,8 @@ func testSource(t *testing.T, exporter packagestest.Exporter) {
|
||||
for _, datum := range data {
|
||||
defer datum.Exported.Cleanup()
|
||||
|
||||
cache := cache.New(nil, nil)
|
||||
session := cache.NewSession()
|
||||
cache := cache.New(ctx, nil)
|
||||
session := cache.NewSession(ctx)
|
||||
options := tests.DefaultOptions()
|
||||
options.Env = datum.Config.Env
|
||||
view, _, err := session.NewView(ctx, "source_test", span.URIFromPath(datum.Config.Dir), options)
|
||||
|
Loading…
Reference in New Issue
Block a user