2016-09-25 15:26:59 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
2017-07-26 18:51:44 +00:00
|
|
|
"bytes"
|
2017-02-10 14:11:40 +00:00
|
|
|
"flag"
|
2017-07-26 18:51:44 +00:00
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
2016-09-25 15:26:59 +00:00
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
"path/filepath"
|
|
|
|
"runtime"
|
2017-03-13 17:59:34 +00:00
|
|
|
"strings"
|
2016-09-25 15:26:59 +00:00
|
|
|
"testing"
|
|
|
|
|
2017-02-08 16:00:44 +00:00
|
|
|
protest "github.com/derekparker/delve/pkg/proc/test"
|
2016-09-25 15:26:59 +00:00
|
|
|
"github.com/derekparker/delve/service/rpc2"
|
|
|
|
)
|
|
|
|
|
2017-02-10 14:11:40 +00:00
|
|
|
var testBackend string
|
|
|
|
|
|
|
|
func TestMain(m *testing.M) {
|
|
|
|
flag.StringVar(&testBackend, "backend", "", "selects backend")
|
|
|
|
flag.Parse()
|
|
|
|
if testBackend == "" {
|
|
|
|
testBackend = os.Getenv("PROCTEST")
|
|
|
|
if testBackend == "" {
|
|
|
|
testBackend = "native"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
os.Exit(m.Run())
|
|
|
|
}
|
|
|
|
|
2016-09-25 15:26:59 +00:00
|
|
|
func assertNoError(err error, t testing.TB, s string) {
|
|
|
|
if err != nil {
|
|
|
|
_, file, line, _ := runtime.Caller(1)
|
|
|
|
fname := filepath.Base(file)
|
|
|
|
t.Fatalf("failed assertion at %s:%d: %s - %s\n", fname, line, s, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-13 17:59:34 +00:00
|
|
|
func goEnv(name string) string {
|
|
|
|
if val := os.Getenv(name); val != "" {
|
|
|
|
return val
|
|
|
|
}
|
|
|
|
val, err := exec.Command("go", "env", name).Output()
|
|
|
|
if err != nil {
|
|
|
|
panic(err) // the Go tool was tested to work earlier
|
|
|
|
}
|
|
|
|
return strings.TrimSpace(string(val))
|
|
|
|
}
|
|
|
|
|
2016-09-25 15:26:59 +00:00
|
|
|
func TestBuild(t *testing.T) {
|
|
|
|
const listenAddr = "localhost:40573"
|
2016-11-18 07:21:50 +00:00
|
|
|
var err error
|
2017-03-27 11:14:20 +00:00
|
|
|
makedir := filepath.Join(goEnv("GOPATH"), "src", "github.com", "derekparker", "delve")
|
|
|
|
for _, makeProgram := range []string{"make", "mingw32-make"} {
|
|
|
|
var out []byte
|
|
|
|
cmd := exec.Command(makeProgram, "build")
|
|
|
|
cmd.Dir = makedir
|
|
|
|
out, err = cmd.CombinedOutput()
|
2016-11-18 07:21:50 +00:00
|
|
|
if err == nil {
|
|
|
|
break
|
2017-03-27 11:14:20 +00:00
|
|
|
} else {
|
|
|
|
t.Logf("makefile error %s (%s): %v", makeProgram, makedir, err)
|
|
|
|
t.Logf("output %s", string(out))
|
2016-11-18 07:21:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
assertNoError(err, t, "make")
|
2017-03-27 11:14:20 +00:00
|
|
|
dlvbin := filepath.Join(makedir, "dlv")
|
2016-09-25 15:26:59 +00:00
|
|
|
defer os.Remove(dlvbin)
|
|
|
|
|
|
|
|
fixtures := protest.FindFixturesDir()
|
|
|
|
|
|
|
|
buildtestdir := filepath.Join(fixtures, "buildtest")
|
|
|
|
|
2017-02-10 14:11:40 +00:00
|
|
|
cmd := exec.Command(dlvbin, "debug", "--headless=true", "--listen="+listenAddr, "--api-version=2", "--backend="+testBackend)
|
2016-09-25 15:26:59 +00:00
|
|
|
cmd.Dir = buildtestdir
|
|
|
|
stdout, err := cmd.StdoutPipe()
|
|
|
|
assertNoError(err, t, "stdout pipe")
|
|
|
|
cmd.Start()
|
|
|
|
|
|
|
|
scan := bufio.NewScanner(stdout)
|
|
|
|
// wait for the debugger to start
|
|
|
|
scan.Scan()
|
|
|
|
go func() {
|
|
|
|
for scan.Scan() {
|
|
|
|
// keep pipe empty
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
client := rpc2.NewClient(listenAddr)
|
|
|
|
state := <-client.Continue()
|
|
|
|
|
|
|
|
if !state.Exited {
|
|
|
|
t.Fatal("Program did not exit")
|
|
|
|
}
|
2017-06-26 18:45:13 +00:00
|
|
|
|
|
|
|
client.Detach(true)
|
|
|
|
cmd.Wait()
|
2016-09-25 15:26:59 +00:00
|
|
|
}
|
2017-07-26 18:51:44 +00:00
|
|
|
|
|
|
|
func testIssue398(t *testing.T, dlvbin string, cmds []string) (stdout, stderr []byte) {
|
|
|
|
var stdoutBuf, stderrBuf bytes.Buffer
|
|
|
|
buildtestdir := filepath.Join(protest.FindFixturesDir(), "buildtest")
|
|
|
|
cmd := exec.Command(dlvbin, "debug")
|
|
|
|
cmd.Dir = buildtestdir
|
|
|
|
stdin, err := cmd.StdinPipe()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
cmd.Stdout = &stdoutBuf
|
|
|
|
cmd.Stderr = &stderrBuf
|
|
|
|
if err := cmd.Start(); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
for _, c := range cmds {
|
|
|
|
fmt.Fprintf(stdin, "%s\n", c)
|
|
|
|
}
|
|
|
|
// ignore "dlv debug" command error, it returns
|
|
|
|
// errors even after successful debug session.
|
|
|
|
cmd.Wait()
|
|
|
|
stdout, stderr = stdoutBuf.Bytes(), stderrBuf.Bytes()
|
|
|
|
|
|
|
|
debugbin := filepath.Join(buildtestdir, "debug")
|
|
|
|
_, err = os.Stat(debugbin)
|
|
|
|
if err == nil {
|
|
|
|
t.Errorf("running %q: file %v was not deleted\nstdout is %q, stderr is %q", cmds, debugbin, stdout, stderr)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if !os.IsNotExist(err) {
|
|
|
|
t.Errorf("running %q: %v\nstdout is %q, stderr is %q", cmds, err, stdout, stderr)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// TestIssue398 verifies that the debug executable is removed after exit.
|
|
|
|
func TestIssue398(t *testing.T) {
|
|
|
|
tmpdir, err := ioutil.TempDir("", "TestIssue398")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
|
|
|
|
dlvbin := filepath.Join(tmpdir, "dlv.exe")
|
|
|
|
out, err := exec.Command("go", "build", "-o", dlvbin, "github.com/derekparker/delve/cmd/dlv").CombinedOutput()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("go build -o %v github.com/derekparker/delve/cmd/dlv: %v\n%s", dlvbin, err, string(out))
|
|
|
|
}
|
|
|
|
|
|
|
|
testIssue398(t, dlvbin, []string{"exit"})
|
|
|
|
|
|
|
|
const hello = "hello world!"
|
|
|
|
stdout, _ := testIssue398(t, dlvbin, []string{"continue", "exit"})
|
|
|
|
if !strings.Contains(string(stdout), hello) {
|
|
|
|
t.Errorf("stdout %q should contain %q", stdout, hello)
|
|
|
|
}
|
|
|
|
}
|