golang.org/x/tools/gopls@v0.15.3/internal/test/integration/debug/debug_test.go (about) 1 // Copyright 2022 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 5 package debug 6 7 import ( 8 "context" 9 "encoding/json" 10 "io" 11 "net/http" 12 "strings" 13 "testing" 14 15 "golang.org/x/tools/gopls/internal/hooks" 16 "golang.org/x/tools/gopls/internal/protocol" 17 "golang.org/x/tools/gopls/internal/protocol/command" 18 . "golang.org/x/tools/gopls/internal/test/integration" 19 "golang.org/x/tools/gopls/internal/util/bug" 20 ) 21 22 func TestMain(m *testing.M) { 23 Main(m, hooks.Options) 24 } 25 26 func TestBugNotification(t *testing.T) { 27 // Verify that a properly configured session gets notified of a bug on the 28 // server. 29 WithOptions( 30 Modes(Default), // must be in-process to receive the bug report below 31 Settings{"showBugReports": true}, 32 ).Run(t, "", func(t *testing.T, env *Env) { 33 const desc = "got a bug" 34 bug.Report(desc) 35 env.Await(ShownMessage(desc)) 36 }) 37 } 38 39 // TestStartDebugging executes a gopls.start_debugging command to 40 // start the internal web server. 41 func TestStartDebugging(t *testing.T) { 42 WithOptions( 43 Modes(Default|Experimental), // doesn't work in Forwarded mode 44 ).Run(t, "", func(t *testing.T, env *Env) { 45 // Start a debugging server. 46 res, err := startDebugging(env.Ctx, env.Editor.Server, &command.DebuggingArgs{ 47 Addr: "", // any free port 48 }) 49 if err != nil { 50 t.Fatalf("startDebugging: %v", err) 51 } 52 53 // Assert that the server requested that the 54 // client show the debug page in a browser. 55 debugURL := res.URLs[0] 56 env.Await(ShownDocument(debugURL)) 57 58 // Send a request to the debug server and ensure it responds. 59 resp, err := http.Get(debugURL) 60 if err != nil { 61 t.Fatal(err) 62 } 63 defer resp.Body.Close() 64 data, err := io.ReadAll(resp.Body) 65 if err != nil { 66 t.Fatalf("reading HTTP response body: %v", err) 67 } 68 const want = "<title>Gopls" 69 if !strings.Contains(string(data), want) { 70 t.Errorf("GET %s response does not contain %q: <<%s>>", debugURL, want, data) 71 } 72 }) 73 } 74 75 // startDebugging starts a debugging server. 76 // TODO(adonovan): move into command package? 77 func startDebugging(ctx context.Context, server protocol.Server, args *command.DebuggingArgs) (*command.DebuggingResult, error) { 78 rawArgs, err := command.MarshalArgs(args) 79 if err != nil { 80 return nil, err 81 } 82 res0, err := server.ExecuteCommand(ctx, &protocol.ExecuteCommandParams{ 83 Command: command.StartDebugging.ID(), 84 Arguments: rawArgs, 85 }) 86 if err != nil { 87 return nil, err 88 } 89 // res0 is the result of a schemaless (map[string]any) JSON decoding. 90 // Re-encode and decode into the correct Go struct type. 91 // TODO(adonovan): fix (*serverDispatcher).ExecuteCommand. 92 data, err := json.Marshal(res0) 93 if err != nil { 94 return nil, err 95 } 96 var res *command.DebuggingResult 97 if err := json.Unmarshal(data, &res); err != nil { 98 return nil, err 99 } 100 return res, nil 101 }