// Copyright 2022 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 debug import ( "context" "encoding/json" "io" "net/http" "os" "strings" "testing" "golang.org/x/tools/gopls/internal/protocol" "golang.org/x/tools/gopls/internal/protocol/command" . "golang.org/x/tools/gopls/internal/test/integration" "golang.org/x/tools/gopls/internal/util/bug" ) func TestMain(m *testing.M) { os.Exit(Main(m)) } func TestBugNotification(t *testing.T) { // Verify that a properly configured session gets notified of a bug on the // server. WithOptions( Modes(Default), // must be in-process to receive the bug report below Settings{"showBugReports": true}, ).Run(t, "", func(t *testing.T, env *Env) { const desc = "got a bug" bug.Report(desc) env.Await(ShownMessage(desc)) }) } // TestStartDebugging executes a gopls.start_debugging command to // start the internal web server. func TestStartDebugging(t *testing.T) { WithOptions( Modes(Default), // doesn't work in Forwarded mode ).Run(t, "", func(t *testing.T, env *Env) { // Start a debugging server. res, err := startDebugging(env.Ctx, env.Editor.Server, &command.DebuggingArgs{ Addr: "", // any free port }) if err != nil { t.Fatalf("startDebugging: %v", err) } // Assert that the server requested that the // client show the debug page in a browser. debugURL := res.URLs[0] env.Await(ShownDocument(debugURL)) // Send a request to the debug server and ensure it responds. resp, err := http.Get(debugURL) if err != nil { t.Fatal(err) } defer resp.Body.Close() data, err := io.ReadAll(resp.Body) if err != nil { t.Fatalf("reading HTTP response body: %v", err) } const want = "Gopls" if !strings.Contains(string(data), want) { t.Errorf("GET %s response does not contain %q: <<%s>>", debugURL, want, data) } }) } // startDebugging starts a debugging server. // TODO(adonovan): move into command package? func startDebugging(ctx context.Context, server protocol.Server, args *command.DebuggingArgs) (*command.DebuggingResult, error) { rawArgs, err := command.MarshalArgs(args) if err != nil { return nil, err } res0, err := server.ExecuteCommand(ctx, &protocol.ExecuteCommandParams{ Command: command.StartDebugging.String(), Arguments: rawArgs, }) if err != nil { return nil, err } // res0 is the result of a schemaless (map[string]any) JSON decoding. // Re-encode and decode into the correct Go struct type. // TODO(adonovan): fix (*serverDispatcher).ExecuteCommand. data, err := json.Marshal(res0) if err != nil { return nil, err } var res *command.DebuggingResult if err := json.Unmarshal(data, &res); err != nil { return nil, err } return res, nil }