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  }