mirror of
				https://github.com/go-delve/delve.git
				synced 2025-10-31 02:36:18 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			187 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			187 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package terminal
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"io/ioutil"
 | |
| 	"net"
 | |
| 	"os"
 | |
| 	"path/filepath"
 | |
| 	"strings"
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/derekparker/delve/proc/test"
 | |
| 	"github.com/derekparker/delve/service"
 | |
| 	"github.com/derekparker/delve/service/api"
 | |
| 	"github.com/derekparker/delve/service/rpc"
 | |
| )
 | |
| 
 | |
| type FakeTerminal struct {
 | |
| 	*Term
 | |
| 	t testing.TB
 | |
| }
 | |
| 
 | |
| func (ft *FakeTerminal) Exec(cmdstr string) (outstr string, err error) {
 | |
| 	cmdstr, args := parseCommand(cmdstr)
 | |
| 	cmd := ft.cmds.Find(cmdstr)
 | |
| 
 | |
| 	outfh, err := ioutil.TempFile("", "cmdtestout")
 | |
| 	if err != nil {
 | |
| 		ft.t.Fatalf("could not create temporary file: %v", err)
 | |
| 	}
 | |
| 
 | |
| 	stdout, stderr := os.Stdout, os.Stderr
 | |
| 	os.Stdout, os.Stderr = outfh, outfh
 | |
| 	defer func() {
 | |
| 		os.Stdout, os.Stderr = stdout, stderr
 | |
| 		outfh.Close()
 | |
| 		outbs, err1 := ioutil.ReadFile(outfh.Name())
 | |
| 		if err1 != nil {
 | |
| 			ft.t.Fatalf("could not read temporary output file: %v", err)
 | |
| 		}
 | |
| 		outstr = string(outbs)
 | |
| 		os.Remove(outfh.Name())
 | |
| 	}()
 | |
| 	err = cmd(ft.Term, args)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (ft *FakeTerminal) MustExec(cmdstr string) string {
 | |
| 	outstr, err := ft.Exec(cmdstr)
 | |
| 	if err != nil {
 | |
| 		ft.t.Fatalf("Error executing <%s>: %v", cmdstr, err)
 | |
| 	}
 | |
| 	return outstr
 | |
| }
 | |
| 
 | |
| func withTestTerminal(name string, t testing.TB, fn func(*FakeTerminal)) {
 | |
| 	listener, err := net.Listen("tcp", "localhost:0")
 | |
| 	if err != nil {
 | |
| 		t.Fatalf("couldn't start listener: %s\n", err)
 | |
| 	}
 | |
| 	defer listener.Close()
 | |
| 	server := rpc.NewServer(&service.Config{
 | |
| 		Listener:    listener,
 | |
| 		ProcessArgs: []string{test.BuildFixture(name).Path},
 | |
| 	}, false)
 | |
| 	if err := server.Run(); err != nil {
 | |
| 		t.Fatal(err)
 | |
| 	}
 | |
| 	client := rpc.NewClient(listener.Addr().String())
 | |
| 	defer func() {
 | |
| 		client.Detach(true)
 | |
| 	}()
 | |
| 	ft := &FakeTerminal{
 | |
| 		t:    t,
 | |
| 		Term: New(client, nil),
 | |
| 	}
 | |
| 	fn(ft)
 | |
| }
 | |
| 
 | |
| func TestCommandDefault(t *testing.T) {
 | |
| 	var (
 | |
| 		cmds = Commands{}
 | |
| 		cmd  = cmds.Find("non-existant-command")
 | |
| 	)
 | |
| 
 | |
| 	err := cmd(nil, "")
 | |
| 	if err == nil {
 | |
| 		t.Fatal("cmd() did not default")
 | |
| 	}
 | |
| 
 | |
| 	if err.Error() != "command not available" {
 | |
| 		t.Fatal("wrong command output")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestCommandReplay(t *testing.T) {
 | |
| 	cmds := DebugCommands(nil)
 | |
| 	cmds.Register("foo", func(t *Term, args string) error { return fmt.Errorf("registered command") }, "foo command")
 | |
| 	cmd := cmds.Find("foo")
 | |
| 
 | |
| 	err := cmd(nil, "")
 | |
| 	if err.Error() != "registered command" {
 | |
| 		t.Fatal("wrong command output")
 | |
| 	}
 | |
| 
 | |
| 	cmd = cmds.Find("")
 | |
| 	err = cmd(nil, "")
 | |
| 	if err.Error() != "registered command" {
 | |
| 		t.Fatal("wrong command output")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestCommandReplayWithoutPreviousCommand(t *testing.T) {
 | |
| 	var (
 | |
| 		cmds = DebugCommands(nil)
 | |
| 		cmd  = cmds.Find("")
 | |
| 		err  = cmd(nil, "")
 | |
| 	)
 | |
| 
 | |
| 	if err != nil {
 | |
| 		t.Error("Null command not returned", err)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestCommandThread(t *testing.T) {
 | |
| 	var (
 | |
| 		cmds = DebugCommands(nil)
 | |
| 		cmd  = cmds.Find("thread")
 | |
| 	)
 | |
| 
 | |
| 	err := cmd(nil, "")
 | |
| 	if err == nil {
 | |
| 		t.Fatal("thread terminal command did not default")
 | |
| 	}
 | |
| 
 | |
| 	if err.Error() != "you must specify a thread" {
 | |
| 		t.Fatal("wrong command output: ", err.Error())
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestExecuteFile(t *testing.T) {
 | |
| 	breakCount := 0
 | |
| 	traceCount := 0
 | |
| 	c := &Commands{
 | |
| 		client: nil,
 | |
| 		cmds: []command{
 | |
| 			{aliases: []string{"trace"}, cmdFn: func(t *Term, args string) error {
 | |
| 				traceCount++
 | |
| 				return nil
 | |
| 			}},
 | |
| 			{aliases: []string{"break"}, cmdFn: func(t *Term, args string) error {
 | |
| 				breakCount++
 | |
| 				return nil
 | |
| 			}},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	fixturesDir := test.FindFixturesDir()
 | |
| 
 | |
| 	err := c.executeFile(nil, filepath.Join(fixturesDir, "bpfile"))
 | |
| 
 | |
| 	if err != nil {
 | |
| 		t.Fatalf("executeFile: %v", err)
 | |
| 	}
 | |
| 
 | |
| 	if breakCount != 1 || traceCount != 1 {
 | |
| 		t.Fatalf("Wrong counts break: %d trace: %d\n", breakCount, traceCount)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestIssue354(t *testing.T) {
 | |
| 	printStack([]api.Stackframe{}, "")
 | |
| 	printStack([]api.Stackframe{{api.Location{PC: 0, File: "irrelevant.go", Line: 10, Function: nil}, nil, nil}}, "")
 | |
| }
 | |
| 
 | |
| func TestIssue411(t *testing.T) {
 | |
| 	withTestTerminal("math", t, func(term *FakeTerminal) {
 | |
| 		term.MustExec("break math.go:8")
 | |
| 		term.MustExec("trace math.go:9")
 | |
| 		term.MustExec("continue")
 | |
| 		out := term.MustExec("next")
 | |
| 		if !strings.HasPrefix(out, "> main.main()") {
 | |
| 			t.Fatalf("Wrong output for next: <%s>", out)
 | |
| 		}
 | |
| 	})
 | |
| }
 | 
