mirror of
https://github.com/go-delve/delve.git
synced 2025-10-30 10:17:03 +08:00
*: parallelize tests where possible (#4115)
This commit is contained in:
@ -57,6 +57,7 @@ func assertNoError(err error, t testing.TB, s string) {
|
||||
}
|
||||
|
||||
func TestBuild(t *testing.T) {
|
||||
t.Parallel()
|
||||
const listenAddr = "127.0.0.1:40573"
|
||||
|
||||
dlvbin := protest.GetDlvBinary(t)
|
||||
@ -171,6 +172,7 @@ func testOutput(t *testing.T, dlvbin, output string, delveCmds []string) (stdout
|
||||
// TestOutput verifies that the debug executable is created in the correct path
|
||||
// and removed after exit.
|
||||
func TestOutput(t *testing.T) {
|
||||
t.Parallel()
|
||||
dlvbin := protest.GetDlvBinary(t)
|
||||
|
||||
for _, output := range []string{"__debug_bin", "myownname", filepath.Join(t.TempDir(), "absolute.path")} {
|
||||
@ -187,7 +189,8 @@ func TestOutput(t *testing.T) {
|
||||
// TestUnattendedBreakpoint tests whether dlv will print a message to stderr when the client that sends continue is disconnected
|
||||
// or not.
|
||||
func TestUnattendedBreakpoint(t *testing.T) {
|
||||
const listenAddr = "127.0.0.1:40573"
|
||||
t.Parallel()
|
||||
const listenAddr = "127.0.0.1:40575"
|
||||
|
||||
fixturePath := filepath.Join(protest.FindFixturesDir(), "panic.go")
|
||||
cmd := exec.Command(protest.GetDlvBinary(t), "debug", "--continue", "--headless", "--accept-multiclient", "--listen", listenAddr, fixturePath)
|
||||
@ -215,7 +218,8 @@ func TestUnattendedBreakpoint(t *testing.T) {
|
||||
|
||||
// TestContinue verifies that the debugged executable starts immediately with --continue
|
||||
func TestContinue(t *testing.T) {
|
||||
const listenAddr = "127.0.0.1:40573"
|
||||
t.Parallel()
|
||||
const listenAddr = "127.0.0.1:40576"
|
||||
|
||||
dlvbin := protest.GetDlvBinary(t)
|
||||
|
||||
@ -247,7 +251,8 @@ func TestContinue(t *testing.T) {
|
||||
|
||||
// TestRedirect verifies that redirecting stdin works
|
||||
func TestRedirect(t *testing.T) {
|
||||
const listenAddr = "127.0.0.1:40573"
|
||||
t.Parallel()
|
||||
const listenAddr = "127.0.0.1:40574"
|
||||
|
||||
dlvbin := protest.GetDlvBinary(t)
|
||||
|
||||
@ -328,6 +333,7 @@ func diffMaybe(t *testing.T, filename string, generated []byte) {
|
||||
// TestGeneratedDoc tests that the autogenerated documentation has been
|
||||
// updated.
|
||||
func TestGeneratedDoc(t *testing.T) {
|
||||
t.Parallel()
|
||||
if runtime.GOOS == "windows" && runtime.GOARCH == "arm64" {
|
||||
//TODO(qmuntal): investigate further when the Windows ARM64 backend is more stable.
|
||||
t.Skip("skipping test on Windows in CI")
|
||||
@ -384,6 +390,8 @@ func TestGeneratedDoc(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExitInInit(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dlvbin := protest.GetDlvBinary(t)
|
||||
|
||||
buildtestdir := filepath.Join(protest.FindFixturesDir(), "buildtest")
|
||||
@ -469,6 +477,7 @@ func qf(*types.Package) string {
|
||||
}
|
||||
|
||||
func TestTypecheckRPC(t *testing.T) {
|
||||
t.Parallel()
|
||||
fset := &token.FileSet{}
|
||||
cfg := &packages.Config{
|
||||
Mode: packages.NeedSyntax | packages.NeedTypesInfo | packages.NeedName | packages.NeedCompiledGoFiles | packages.NeedTypes,
|
||||
@ -582,6 +591,7 @@ func TestTypecheckRPC(t *testing.T) {
|
||||
|
||||
// TestDAPCmd verifies that a dap server can be started and shut down.
|
||||
func TestDAPCmd(t *testing.T) {
|
||||
t.Parallel()
|
||||
const listenAddr = "127.0.0.1:40575"
|
||||
|
||||
dlvbin := protest.GetDlvBinary(t)
|
||||
@ -645,7 +655,8 @@ func newDAPRemoteClient(t *testing.T, addr string, isDlvAttach bool, isMulti boo
|
||||
}
|
||||
|
||||
func TestRemoteDAPClient(t *testing.T) {
|
||||
const listenAddr = "127.0.0.1:40576"
|
||||
t.Parallel()
|
||||
const listenAddr = "127.0.0.1:40577"
|
||||
|
||||
dlvbin := protest.GetDlvBinary(t)
|
||||
|
||||
@ -698,7 +709,8 @@ func closeDAPRemoteMultiClient(t *testing.T, c *daptest.Client, expectStatus str
|
||||
}
|
||||
|
||||
func TestRemoteDAPClientMulti(t *testing.T) {
|
||||
const listenAddr = "127.0.0.1:40577"
|
||||
t.Parallel()
|
||||
const listenAddr = "127.0.0.1:40578"
|
||||
|
||||
dlvbin := protest.GetDlvBinary(t)
|
||||
|
||||
@ -765,7 +777,8 @@ func TestRemoteDAPClientMulti(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRemoteDAPClientAfterContinue(t *testing.T) {
|
||||
const listenAddr = "127.0.0.1:40578"
|
||||
t.Parallel()
|
||||
const listenAddr = "127.0.0.1:40579"
|
||||
|
||||
dlvbin := protest.GetDlvBinary(t)
|
||||
|
||||
@ -822,6 +835,7 @@ func TestRemoteDAPClientAfterContinue(t *testing.T) {
|
||||
|
||||
// TestDAPCmdWithClient tests dlv dap --client-addr can be started and shut down.
|
||||
func TestDAPCmdWithClient(t *testing.T) {
|
||||
t.Parallel()
|
||||
listener, err := net.Listen("tcp", ":0")
|
||||
if err != nil {
|
||||
t.Fatalf("cannot setup listener required for testing: %v", err)
|
||||
@ -831,9 +845,6 @@ func TestDAPCmdWithClient(t *testing.T) {
|
||||
dlvbin := protest.GetDlvBinary(t)
|
||||
|
||||
cmd := exec.Command(dlvbin, "dap", "--log-output=dap", "--log", "--client-addr", listener.Addr().String())
|
||||
buf := &bytes.Buffer{}
|
||||
cmd.Stdin = buf
|
||||
cmd.Stdout = buf
|
||||
assertNoError(cmd.Start(), t, "start dlv dap process with --client-addr flag")
|
||||
|
||||
// Wait for the connection.
|
||||
@ -857,13 +868,14 @@ func TestDAPCmdWithClient(t *testing.T) {
|
||||
// Connection close should trigger dlv-reverse command's normal exit.
|
||||
if err := cmd.Wait(); err != nil {
|
||||
cmd.Process.Kill()
|
||||
t.Fatalf("command failed: %v\n%s\n%v", err, buf.Bytes(), cmd.Process.Pid)
|
||||
t.Fatalf("command failed: %v\n%v", err, cmd.Process.Pid)
|
||||
}
|
||||
}
|
||||
|
||||
// TestDAPCmdWithUnixClient tests dlv dap --client-addr can be started with unix domain socket and shut down.
|
||||
func TestDAPCmdWithUnixClient(t *testing.T) {
|
||||
tmpdir := os.TempDir()
|
||||
t.Parallel()
|
||||
tmpdir := t.TempDir()
|
||||
if tmpdir == "" {
|
||||
return
|
||||
}
|
||||
@ -878,9 +890,6 @@ func TestDAPCmdWithUnixClient(t *testing.T) {
|
||||
dlvbin := protest.GetDlvBinary(t)
|
||||
|
||||
cmd := exec.Command(dlvbin, "dap", "--log-output=dap", "--log", "--client-addr=unix:"+listener.Addr().String())
|
||||
buf := &bytes.Buffer{}
|
||||
cmd.Stdin = buf
|
||||
cmd.Stdout = buf
|
||||
assertNoError(cmd.Start(), t, "start dlv dap process with --client-addr flag")
|
||||
|
||||
// Wait for the connection.
|
||||
@ -904,11 +913,12 @@ func TestDAPCmdWithUnixClient(t *testing.T) {
|
||||
// Connection close should trigger dlv-reverse command's normal exit.
|
||||
if err := cmd.Wait(); err != nil {
|
||||
cmd.Process.Kill()
|
||||
t.Fatalf("command failed: %v\n%s\n%v", err, buf.Bytes(), cmd.Process.Pid)
|
||||
t.Fatalf("command failed: %v\n%v", err, cmd.Process.Pid)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTrace(t *testing.T) {
|
||||
t.Parallel()
|
||||
dlvbin := protest.GetDlvBinary(t)
|
||||
|
||||
expected := []byte("> goroutine(1): main.foo(99, 9801)\n>> goroutine(1): main.foo => (9900)\n")
|
||||
@ -933,6 +943,7 @@ func TestTrace(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTrace2(t *testing.T) {
|
||||
t.Parallel()
|
||||
dlvbin := protest.GetDlvBinary(t)
|
||||
|
||||
expected := []byte("> goroutine(1): main.callme(2)\n>> goroutine(1): main.callme => (4)\n")
|
||||
@ -957,6 +968,7 @@ func TestTrace2(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTraceDirRecursion(t *testing.T) {
|
||||
t.Parallel()
|
||||
dlvbin := protest.GetDlvBinary(t)
|
||||
|
||||
expected := []byte("> goroutine(1):frame(1) main.A(5, 5)\n > goroutine(1):frame(2) main.A(4, 4)\n > goroutine(1):frame(3) main.A(3, 3)\n > goroutine(1):frame(4) main.A(2, 2)\n > goroutine(1):frame(5) main.A(1, 1)\n >> goroutine(1):frame(5) main.A => (1)\n >> goroutine(1):frame(4) main.A => (2)\n >> goroutine(1):frame(3) main.A => (6)\n >> goroutine(1):frame(2) main.A => (24)\n>> goroutine(1):frame(1) main.A => (120)\n")
|
||||
@ -990,6 +1002,7 @@ func TestTraceDirRecursion(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTraceMultipleGoroutines(t *testing.T) {
|
||||
t.Parallel()
|
||||
dlvbin := protest.GetDlvBinary(t)
|
||||
|
||||
// TODO(derekparker) this test has to be a bit vague to avoid flakiness.
|
||||
@ -1021,6 +1034,7 @@ func TestTraceMultipleGoroutines(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTracePid(t *testing.T) {
|
||||
t.Parallel()
|
||||
if runtime.GOOS == "linux" {
|
||||
bs, _ := os.ReadFile("/proc/sys/kernel/yama/ptrace_scope")
|
||||
if bs == nil || strings.TrimSpace(string(bs)) != "0" {
|
||||
@ -1045,6 +1059,7 @@ func TestTracePid(t *testing.T) {
|
||||
|
||||
// dlv attach the process by pid
|
||||
cmd := exec.Command(dlvbin, "trace", "-p", strconv.Itoa(targetCmd.Process.Pid), "main.A")
|
||||
defer cmd.Wait()
|
||||
rdr, err := cmd.StderrPipe()
|
||||
assertNoError(err, t, "stderr pipe")
|
||||
defer rdr.Close()
|
||||
@ -1057,11 +1072,10 @@ func TestTracePid(t *testing.T) {
|
||||
if !bytes.Contains(output, expected) {
|
||||
t.Fatalf("expected:\n%s\ngot:\n%s", string(expected), string(output))
|
||||
}
|
||||
|
||||
cmd.Wait()
|
||||
}
|
||||
|
||||
func TestTraceBreakpointExists(t *testing.T) {
|
||||
t.Parallel()
|
||||
dlvbin := protest.GetDlvBinary(t)
|
||||
|
||||
fixtures := protest.FindFixturesDir()
|
||||
@ -1088,6 +1102,7 @@ func TestTraceBreakpointExists(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTracePrintStack(t *testing.T) {
|
||||
t.Parallel()
|
||||
dlvbin := protest.GetDlvBinary(t)
|
||||
|
||||
fixtures := protest.FindFixturesDir()
|
||||
@ -1110,6 +1125,7 @@ func TestTracePrintStack(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTraceEBPF(t *testing.T) {
|
||||
t.Parallel()
|
||||
if os.Getenv("CI") == "true" {
|
||||
t.Skip("cannot run test in CI, requires kernel compiled with btf support")
|
||||
}
|
||||
@ -1149,6 +1165,7 @@ func TestTraceEBPF(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTraceEBPF2(t *testing.T) {
|
||||
t.Parallel()
|
||||
if os.Getenv("CI") == "true" {
|
||||
t.Skip("cannot run test in CI, requires kernel compiled with btf support")
|
||||
}
|
||||
@ -1209,6 +1226,7 @@ func TestTraceEBPF2(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTraceEBPF3(t *testing.T) {
|
||||
t.Parallel()
|
||||
if os.Getenv("CI") == "true" {
|
||||
t.Skip("cannot run test in CI, requires kernel compiled with btf support")
|
||||
}
|
||||
@ -1257,6 +1275,7 @@ func TestTraceEBPF3(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTraceEBPF4(t *testing.T) {
|
||||
t.Parallel()
|
||||
if os.Getenv("CI") == "true" {
|
||||
t.Skip("cannot run test in CI, requires kernel compiled with btf support")
|
||||
}
|
||||
@ -1305,6 +1324,7 @@ func TestTraceEBPF4(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDlvTestChdir(t *testing.T) {
|
||||
t.Parallel()
|
||||
dlvbin := protest.GetDlvBinary(t)
|
||||
|
||||
fixtures := protest.FindFixturesDir()
|
||||
@ -1337,6 +1357,7 @@ func TestDlvTestChdir(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestVersion(t *testing.T) {
|
||||
t.Parallel()
|
||||
dlvbin := protest.GetDlvBinary(t)
|
||||
|
||||
got, err := exec.Command(dlvbin, "version", "-v").CombinedOutput()
|
||||
@ -1351,6 +1372,7 @@ func TestVersion(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStaticcheck(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := exec.LookPath("staticcheck")
|
||||
if err != nil {
|
||||
t.Skip("staticcheck not installed")
|
||||
@ -1373,43 +1395,50 @@ func TestStaticcheck(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDefaultBinary(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Check that when delve is run twice in the same directory simultaneously
|
||||
// it will pick different default output binary paths.
|
||||
dlvbin := protest.GetDlvBinary(t)
|
||||
fixture := filepath.Join(protest.FindFixturesDir(), "testargs.go")
|
||||
|
||||
startOne := func() (io.WriteCloser, func() error, *bytes.Buffer) {
|
||||
startOne := func() (io.WriteCloser, func() error, io.ReadCloser) {
|
||||
cmd := exec.Command(dlvbin, "debug", "--allow-non-terminal-interactive=true", fixture, "--", "test")
|
||||
stdin, _ := cmd.StdinPipe()
|
||||
stdoutBuf := new(bytes.Buffer)
|
||||
cmd.Stdout = stdoutBuf
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
assertNoError(err, t, "cmd.StdoutPipe")
|
||||
|
||||
assertNoError(cmd.Start(), t, "dlv debug")
|
||||
return stdin, cmd.Wait, stdoutBuf
|
||||
return stdin, cmd.Wait, stdout
|
||||
}
|
||||
|
||||
stdin1, wait1, stdoutBuf1 := startOne()
|
||||
stdin1, wait1, stdout1 := startOne()
|
||||
defer stdin1.Close()
|
||||
defer stdout1.Close()
|
||||
|
||||
stdin2, wait2, stdoutBuf2 := startOne()
|
||||
stdin2, wait2, stdout2 := startOne()
|
||||
defer stdin2.Close()
|
||||
defer stdout2.Close()
|
||||
|
||||
fmt.Fprintf(stdin1, "continue\nquit\n")
|
||||
fmt.Fprintf(stdin2, "continue\nquit\n")
|
||||
|
||||
wait1()
|
||||
wait2()
|
||||
|
||||
out1, out2 := stdoutBuf1.String(), stdoutBuf2.String()
|
||||
t.Logf("%q", out1)
|
||||
t.Logf("%q", out2)
|
||||
if out1 == out2 {
|
||||
out1, err := io.ReadAll(stdout1)
|
||||
assertNoError(err, t, "io.ReadAll")
|
||||
out2, err := io.ReadAll(stdout2)
|
||||
assertNoError(err, t, "io.ReadAll")
|
||||
t.Logf("%q", string(out1))
|
||||
t.Logf("%q", string(out2))
|
||||
if bytes.Equal(out1, out2) {
|
||||
t.Errorf("outputs match")
|
||||
}
|
||||
|
||||
wait1()
|
||||
wait2()
|
||||
}
|
||||
|
||||
func TestUnixDomainSocket(t *testing.T) {
|
||||
tmpdir := os.TempDir()
|
||||
t.Parallel()
|
||||
tmpdir := t.TempDir()
|
||||
if tmpdir == "" {
|
||||
return
|
||||
}
|
||||
@ -1461,6 +1490,7 @@ func TestUnixDomainSocket(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDeadcodeEliminated(t *testing.T) {
|
||||
t.Parallel()
|
||||
dlvbin := protest.GetDlvBinary(t)
|
||||
buf, err := exec.Command("go", "tool", "nm", dlvbin).CombinedOutput()
|
||||
if err != nil {
|
||||
|
||||
@ -5,6 +5,8 @@ import (
|
||||
)
|
||||
|
||||
func TestSplitQuotedFields(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
in := `field'A' 'fieldB' fie'l\'d'C fieldD 'another field' fieldE`
|
||||
tgt := []string{"fieldA", "fieldB", "fiel'dC", "fieldD", "another field", "fieldE"}
|
||||
out := SplitQuotedFields(in, '\'')
|
||||
@ -54,6 +56,8 @@ func TestSplitDoubleQuotedFields(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
in := tt.in
|
||||
tgt := tt.expected
|
||||
out := SplitQuotedFields(in, '"')
|
||||
@ -71,6 +75,8 @@ func TestSplitDoubleQuotedFields(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConfigureListByName(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type testConfig struct {
|
||||
boolArg bool `cfgName:"bool-arg"`
|
||||
listArg []string `cfgName:"list-arg"`
|
||||
|
||||
@ -13,6 +13,7 @@ func ptrSizeByRuntimeArch() int {
|
||||
}
|
||||
|
||||
func TestFDEForPC(t *testing.T) {
|
||||
t.Parallel()
|
||||
frames := newFrameIndex()
|
||||
frames = append(frames,
|
||||
&FrameDescriptionEntry{begin: 10, size: 40},
|
||||
@ -57,6 +58,7 @@ func TestFDEForPC(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAppend(t *testing.T) {
|
||||
t.Parallel()
|
||||
equal := func(x, y FrameDescriptionEntries) bool {
|
||||
if len(x) != len(y) {
|
||||
return false
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
)
|
||||
|
||||
func TestParseCIE(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := &parseContext{
|
||||
buf: bytes.NewBuffer([]byte{3, 0, 1, 124, 16, 12, 7, 8, 5, 16, 2, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 16, 64, 0, 0, 0, 0, 0}),
|
||||
common: &CommonInformationEntry{Length: 12},
|
||||
|
||||
@ -25,6 +25,7 @@ func assertRanges(t *testing.T, out, tgt [][2]uint64) {
|
||||
}
|
||||
|
||||
func TestNormalizeRanges(t *testing.T) {
|
||||
t.Parallel()
|
||||
mr := makeRanges
|
||||
//assertRanges(t, normalizeRanges(mr(105, 103, 90, 95, 25, 20, 20, 23)), mr(20, 23, 90, 95))
|
||||
assertRanges(t, normalizeRanges(mr(10, 12, 12, 15)), mr(10, 15))
|
||||
@ -33,6 +34,7 @@ func TestNormalizeRanges(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRangeContains(t *testing.T) {
|
||||
t.Parallel()
|
||||
mr := func(start, end uint64) [2]uint64 {
|
||||
return [2]uint64{start, end}
|
||||
}
|
||||
@ -59,6 +61,7 @@ func TestRangeContains(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRangesContains(t *testing.T) {
|
||||
t.Parallel()
|
||||
mr := makeRanges
|
||||
tcs := []struct {
|
||||
rngs1, rngs2 [][2]uint64
|
||||
@ -90,6 +93,7 @@ func TestRangesContains(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestContainsPC(t *testing.T) {
|
||||
t.Parallel()
|
||||
mr := makeRanges
|
||||
|
||||
tcs := []struct {
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
)
|
||||
|
||||
func TestDecodeUnsigned(t *testing.T) {
|
||||
t.Parallel()
|
||||
leb128 := bytes.NewBuffer([]byte{0xE5, 0x8E, 0x26})
|
||||
|
||||
n, c := DecodeUnsigned(leb128)
|
||||
@ -19,6 +20,7 @@ func TestDecodeUnsigned(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDecodeSigned(t *testing.T) {
|
||||
t.Parallel()
|
||||
sleb128 := bytes.NewBuffer([]byte{0x9b, 0xf1, 0x59})
|
||||
|
||||
n, c := DecodeSigned(sleb128)
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
)
|
||||
|
||||
func TestEncodeUnsigned(t *testing.T) {
|
||||
t.Parallel()
|
||||
tc := []uint64{0x00, 0x7f, 0x80, 0x8f, 0xffff, 0xfffffff7}
|
||||
for i := range tc {
|
||||
var buf bytes.Buffer
|
||||
@ -24,6 +25,7 @@ func TestEncodeUnsigned(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEncodeSigned(t *testing.T) {
|
||||
t.Parallel()
|
||||
tc := []int64{2, -2, 127, -127, 128, -128, 129, -129}
|
||||
for i := range tc {
|
||||
var buf bytes.Buffer
|
||||
|
||||
@ -145,6 +145,7 @@ func testDebugLinePrologueParser(p string, t *testing.T) {
|
||||
}
|
||||
|
||||
func TestUserFile(t *testing.T) {
|
||||
t.Parallel()
|
||||
if userTestFile == "" {
|
||||
return
|
||||
}
|
||||
@ -153,6 +154,7 @@ func TestUserFile(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebugLinePrologueParser(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Test against known good values, from readelf --debug-dump=rawline _fixtures/testnextprog
|
||||
p, err := filepath.Abs("../../../_fixtures/testnextprog")
|
||||
if err != nil {
|
||||
@ -288,6 +290,7 @@ func runTestPCToLine(t testing.TB, lineInfos DebugLines, entries []pctolineEntry
|
||||
}
|
||||
|
||||
func TestPCToLine(t *testing.T) {
|
||||
t.Parallel()
|
||||
lineInfos := loadBenchmarkData(t)
|
||||
|
||||
entries, basePCs := setupTestPCToLine(t, lineInfos)
|
||||
@ -307,6 +310,7 @@ func BenchmarkPCToLine(b *testing.B) {
|
||||
}
|
||||
|
||||
func TestDebugLineC(t *testing.T) {
|
||||
t.Parallel()
|
||||
p, err := filepath.Abs("../../../_fixtures/debug_line_c_data")
|
||||
if err != nil {
|
||||
t.Fatal("Could not find test data", p, err)
|
||||
@ -340,6 +344,7 @@ func TestDebugLineC(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebugLineDwarf4(t *testing.T) {
|
||||
t.Parallel()
|
||||
p, err := filepath.Abs("../../../_fixtures/zdebug_line_dwarf4")
|
||||
if err != nil {
|
||||
t.Fatal("Could not find test data", p, err)
|
||||
|
||||
@ -30,6 +30,7 @@ func slurpGzip(path string) ([]byte, error) {
|
||||
}
|
||||
|
||||
func TestGrafana(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Compares a full execution of our state machine on the debug_line section
|
||||
// of grafana to the output generated using debug/dwarf.LineReader on the
|
||||
// same section.
|
||||
@ -122,6 +123,7 @@ func checkCompileUnit(t *testing.T, cuname string, lnrdr *dwarf.LineReader, sm *
|
||||
}
|
||||
|
||||
func TestMultipleSequences(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Check that our state machine (specifically PCToLine and AllPCsBetween)
|
||||
// are correct when dealing with units containing more than one sequence.
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
)
|
||||
|
||||
func TestLoclist5(t *testing.T) {
|
||||
t.Parallel()
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
p32 := func(n uint32) { binary.Write(buf, binary.LittleEndian, n) }
|
||||
|
||||
@ -19,10 +19,12 @@ func assertExprResult(t *testing.T, expected int64, instructions []byte) {
|
||||
}
|
||||
|
||||
func TestExecuteStackProgram(t *testing.T) {
|
||||
t.Parallel()
|
||||
assertExprResult(t, 56, []byte{byte(DW_OP_consts), 0x1c, byte(DW_OP_consts), 0x1c, byte(DW_OP_plus)})
|
||||
}
|
||||
|
||||
func TestSignExtension(t *testing.T) {
|
||||
t.Parallel()
|
||||
var tgt uint64 = 0xffffffffffffff88
|
||||
assertExprResult(t, int64(tgt), []byte{byte(DW_OP_const1s), 0x88})
|
||||
tgt = 0xffffffffffff8888
|
||||
@ -30,12 +32,14 @@ func TestSignExtension(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStackOps(t *testing.T) {
|
||||
t.Parallel()
|
||||
assertExprResult(t, 1, []byte{byte(DW_OP_lit1), byte(DW_OP_lit2), byte(DW_OP_drop)})
|
||||
assertExprResult(t, 0, []byte{byte(DW_OP_lit1), byte(DW_OP_lit0), byte(DW_OP_pick), 0})
|
||||
assertExprResult(t, 1, []byte{byte(DW_OP_lit1), byte(DW_OP_lit0), byte(DW_OP_pick), 1})
|
||||
}
|
||||
|
||||
func TestBra(t *testing.T) {
|
||||
t.Parallel()
|
||||
assertExprResult(t, 32, []byte{
|
||||
byte(DW_OP_lit1),
|
||||
byte(DW_OP_lit5),
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
)
|
||||
|
||||
func TestReadString(t *testing.T) {
|
||||
t.Parallel()
|
||||
bstr := bytes.NewBuffer([]byte{'h', 'i', 0x0, 0xFF, 0xCC})
|
||||
str, _ := dwarf.ReadString(bstr)
|
||||
|
||||
|
||||
@ -17,11 +17,15 @@ func TestGoBuildArgsDashC(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
out := goBuildArgs("debug", []string{"pkg"}, tc.in, false)
|
||||
tgt := config.SplitQuotedFields(tc.tgt, '\'')
|
||||
t.Logf("%q -> %q", tc.in, out)
|
||||
if !reflect.DeepEqual(out, tgt) {
|
||||
t.Errorf("output mismatch input %q\noutput %q\ntarget %q", tc.in, out, tgt)
|
||||
}
|
||||
t.Run(tc.in, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
out := goBuildArgs("debug", []string{"pkg"}, tc.in, false)
|
||||
tgt := config.SplitQuotedFields(tc.tgt, '\'')
|
||||
t.Logf("%q -> %q", tc.in, out)
|
||||
if !reflect.DeepEqual(out, tgt) {
|
||||
t.Errorf("output mismatch input %q\noutput %q\ntarget %q", tc.in, out, tgt)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,6 +41,7 @@ func versionEqual(t *testing.T, verStr string, ver GoVersion) {
|
||||
}
|
||||
|
||||
func TestParseVersionStringAfterOrEqual(t *testing.T) {
|
||||
t.Parallel()
|
||||
versionAfterOrEqual(t, "go1.4", GoVersion{1, 4, 0, "", ""})
|
||||
versionAfterOrEqual(t, "go1.5.0", GoVersion{1, 5, 0, "", ""})
|
||||
versionAfterOrEqual(t, "go1.4.2", GoVersion{1, 4, 2, "", ""})
|
||||
@ -66,6 +67,7 @@ func TestParseVersionStringAfterOrEqual(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestParseVersionStringEqual(t *testing.T) {
|
||||
t.Parallel()
|
||||
versionEqual(t, "go1.4", GoVersion{1, 4, 0, "", ""})
|
||||
versionEqual(t, "go1.5.0", GoVersion{1, 5, 0, "", ""})
|
||||
versionEqual(t, "go1.4.2", GoVersion{1, 4, 2, "", ""})
|
||||
@ -82,6 +84,7 @@ func TestParseVersionStringEqual(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRoundtrip(t *testing.T) {
|
||||
t.Parallel()
|
||||
for _, verStr := range []string{
|
||||
"go1.4",
|
||||
"go1.4.2",
|
||||
@ -99,6 +102,7 @@ func TestRoundtrip(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInstalled(t *testing.T) {
|
||||
t.Parallel()
|
||||
installedVersion, ok := Installed()
|
||||
if !ok {
|
||||
t.Fatalf("could not parse output of go version")
|
||||
|
||||
@ -42,6 +42,7 @@ func assertNormalLocationSpec(t *testing.T, locstr string, tgt NormalLocationSpe
|
||||
}
|
||||
|
||||
func TestFunctionLocationParsing(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Function locations, simple package names, no line offset
|
||||
assertNormalLocationSpec(t, "proc.(*Process).Continue", NormalLocationSpec{"proc.(*Process).Continue", &FuncLocationSpec{PackageName: "proc", ReceiverName: "Process", BaseName: "Continue"}, -1})
|
||||
assertNormalLocationSpec(t, "proc.Process.Continue", NormalLocationSpec{"proc.Process.Continue", &FuncLocationSpec{PackageName: "proc", ReceiverName: "Process", BaseName: "Continue"}, -1})
|
||||
@ -75,6 +76,7 @@ func assertSubstitutePathEqual(t *testing.T, expected string, substituted string
|
||||
}
|
||||
|
||||
func TestSubstitutePathUnix(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Relative paths mapping
|
||||
assertSubstitutePathEqual(t, "/my/asb/folder/relative/path", SubstitutePath("relative/path", [][2]string{{"", "/my/asb/folder/"}}))
|
||||
assertSubstitutePathEqual(t, "/already/abs/path", SubstitutePath("/already/abs/path", [][2]string{{"", "/my/asb/folder/"}}))
|
||||
@ -95,6 +97,7 @@ func TestSubstitutePathUnix(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSubstitutePathWindows(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Relative paths mapping
|
||||
assertSubstitutePathEqual(t, "c:\\my\\asb\\folder\\relative\\path", SubstitutePath("relative\\path", [][2]string{{"", "c:\\my\\asb\\folder\\"}}))
|
||||
assertSubstitutePathEqual(t, "F:\\already\\abs\\path", SubstitutePath("F:\\already\\abs\\path", [][2]string{{"", "c:\\my\\asb\\folder\\"}}))
|
||||
@ -182,6 +185,7 @@ func platformCases() []tCase {
|
||||
}
|
||||
|
||||
func TestSubstitutePath(t *testing.T) {
|
||||
t.Parallel()
|
||||
for _, c := range platformCases() {
|
||||
subRules := [][2]string{}
|
||||
for _, r := range c.rules {
|
||||
|
||||
@ -133,6 +133,7 @@ func TestSplicedReader(t *testing.T) {
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
mem := &SplicedMemory{}
|
||||
for _, region := range test.regions {
|
||||
r := bytes.NewReader(region.data)
|
||||
@ -219,7 +220,7 @@ func withCoreFile(t *testing.T, name, args string) *proc.TargetGroup {
|
||||
t.Skipf("core file was not produced, could not run test, coredumpctl error: %v", err)
|
||||
return nil
|
||||
}
|
||||
test.PathsToRemove = append(test.PathsToRemove, cores[0])
|
||||
test.AddPathToRemove(cores[0])
|
||||
}
|
||||
corePath := cores[0]
|
||||
|
||||
@ -249,6 +250,8 @@ func logRegisters(t *testing.T, regs proc.Registers, arch *proc.Arch) {
|
||||
}
|
||||
|
||||
func TestCore(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mustSupportCore(t)
|
||||
|
||||
grp := withCoreFile(t, "panic", "")
|
||||
@ -315,6 +318,7 @@ func TestCore(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCoreFpRegisters(t *testing.T) {
|
||||
t.Parallel()
|
||||
if runtime.GOOS != "linux" || runtime.GOARCH == "386" {
|
||||
t.Skip("unsupported")
|
||||
}
|
||||
@ -405,6 +409,7 @@ func TestCoreFpRegisters(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCoreWithEmptyString(t *testing.T) {
|
||||
t.Parallel()
|
||||
mustSupportCore(t)
|
||||
|
||||
grp := withCoreFile(t, "coreemptystring", "")
|
||||
@ -443,6 +448,7 @@ mainSearch:
|
||||
}
|
||||
|
||||
func TestMinidump(t *testing.T) {
|
||||
t.Parallel()
|
||||
if runtime.GOOS != "windows" || runtime.GOARCH != "amd64" {
|
||||
t.Skip("minidumps can only be produced on windows/amd64")
|
||||
}
|
||||
@ -514,7 +520,7 @@ func procdump(t *testing.T, exePath string) string {
|
||||
t.Logf("\t%s", name)
|
||||
if strings.HasPrefix(name, exeName) && strings.HasSuffix(name, ".dmp") {
|
||||
mdmpPath := filepath.Join(exeDir, name)
|
||||
test.PathsToRemove = append(test.PathsToRemove, mdmpPath)
|
||||
test.AddPathToRemove(mdmpPath)
|
||||
return mdmpPath
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,6 +134,8 @@ func dwarfRegisters(bi *proc.BinaryInfo, regs *linutil.AMD64Registers) *op.Dwarf
|
||||
}
|
||||
|
||||
func TestDwarfExprRegisters(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := map[string]uint16{
|
||||
"a": 0x1234,
|
||||
"b": 0x4321,
|
||||
@ -163,6 +165,7 @@ func TestDwarfExprRegisters(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDwarfExprComposite(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCases := map[string]uint16{
|
||||
"pair.k": 0x8765,
|
||||
"pair.v": 0x5678,
|
||||
@ -273,6 +276,7 @@ func TestDwarfExprComposite(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDwarfExprLoclist(t *testing.T) {
|
||||
t.Parallel()
|
||||
const before = 0x1234
|
||||
const after = 0x4321
|
||||
|
||||
@ -304,6 +308,7 @@ func TestDwarfExprLoclist(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIssue1419(t *testing.T) {
|
||||
t.Parallel()
|
||||
// trying to read a slice variable with a location list that tries to read
|
||||
// from registers we don't have should not cause a panic.
|
||||
|
||||
@ -345,6 +350,7 @@ func TestIssue1419(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLocationCovers(t *testing.T) {
|
||||
t.Parallel()
|
||||
dwb := dwarfbuilder.New()
|
||||
|
||||
uint16off := dwb.AddBaseType("uint16", dwarfbuilder.DW_ATE_unsigned, 2)
|
||||
@ -373,6 +379,7 @@ func TestLocationCovers(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIssue1636_InlineWithoutOrigin(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Gcc (specifically GNU C++11 6.3.0) will emit DW_TAG_inlined_subroutine
|
||||
// without a DW_AT_abstract_origin or a name. What is an inlined subroutine
|
||||
// without a reference to an abstract origin or even a name? Regardless,
|
||||
@ -388,6 +395,7 @@ func TestIssue1636_InlineWithoutOrigin(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestUnsupportedType(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Tests that reading an unsupported type does not cause an error
|
||||
dwb := dwarfbuilder.New()
|
||||
dwb.AddCompileUnit("main", 0x0)
|
||||
@ -402,6 +410,7 @@ func TestUnsupportedType(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNestedCompileUnts(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Tests that a compile unit with a nested entry that we don't care about
|
||||
// (such as a DW_TAG_namespace) is read fully.
|
||||
dwb := dwarfbuilder.New()
|
||||
@ -418,6 +427,7 @@ func TestNestedCompileUnts(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAbstractOriginDefinedAfterUse(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Tests that an abstract origin entry can appear after its uses.
|
||||
dwb := dwarfbuilder.New()
|
||||
dwb.AddCompileUnit("main", 0x0)
|
||||
|
||||
@ -10,6 +10,7 @@ import (
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
@ -22,12 +23,6 @@ var EnableRace = flag.Bool("racetarget", false, "Enables race detector on inferi
|
||||
|
||||
var runningWithFixtures bool
|
||||
|
||||
var ldFlags string
|
||||
|
||||
func init() {
|
||||
ldFlags = os.Getenv("CGO_LDFLAGS")
|
||||
}
|
||||
|
||||
// Fixture is a test binary.
|
||||
type Fixture struct {
|
||||
// Name is the short name of the fixture.
|
||||
@ -48,9 +43,17 @@ type fixtureKey struct {
|
||||
|
||||
// Fixtures is a map of fixtureKey{ Fixture.Name, buildFlags } to Fixture.
|
||||
var fixtures = make(map[fixtureKey]Fixture)
|
||||
var fixturesmu sync.Mutex
|
||||
|
||||
// PathsToRemove is a list of files and directories to remove after running all the tests
|
||||
var PathsToRemove []string
|
||||
// pathsToRemove is a list of files and directories to remove after running all the tests
|
||||
var pathsToRemove []string
|
||||
var pathmu sync.Mutex
|
||||
|
||||
func AddPathToRemove(path string) {
|
||||
pathmu.Lock()
|
||||
defer pathmu.Unlock()
|
||||
pathsToRemove = append(pathsToRemove, path)
|
||||
}
|
||||
|
||||
// FindFixturesDir will search for the directory holding all test fixtures
|
||||
// beginning with the current directory and searching up 10 directories.
|
||||
@ -211,6 +214,8 @@ func BuildFixture(t testing.TB, name string, flags BuildFlags) Fixture {
|
||||
|
||||
fixture := Fixture{Name: name, Path: tmpfile, Source: source, BuildDir: absdir}
|
||||
|
||||
fixturesmu.Lock()
|
||||
defer fixturesmu.Unlock()
|
||||
fixtures[fk] = fixture
|
||||
return fixtures[fk]
|
||||
}
|
||||
@ -229,7 +234,7 @@ func RunTestsWithFixtures(m *testing.M) {
|
||||
os.Remove(f.Path)
|
||||
}
|
||||
|
||||
for _, p := range PathsToRemove {
|
||||
for _, p := range pathsToRemove {
|
||||
fi, err := os.Stat(p)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@ -431,11 +436,8 @@ func ProjectRoot() string {
|
||||
}
|
||||
|
||||
func GetDlvBinary(t *testing.T) string {
|
||||
// In case this was set in the environment
|
||||
// from getDlvBinEBPF lets clear it here, so
|
||||
// we can ensure we don't get build errors
|
||||
// depending on the test ordering.
|
||||
t.Setenv("CGO_LDFLAGS", ldFlags)
|
||||
t.Helper()
|
||||
|
||||
var tags []string
|
||||
if runtime.GOOS == "windows" && runtime.GOARCH == "arm64" {
|
||||
tags = []string{"-tags=exp.winarm64"}
|
||||
@ -453,20 +455,39 @@ func GetDlvBinary(t *testing.T) string {
|
||||
}
|
||||
|
||||
func GetDlvBinaryEBPF(t *testing.T) string {
|
||||
t.Helper()
|
||||
|
||||
return getDlvBinInternal(t, "-tags", "ebpf")
|
||||
}
|
||||
|
||||
// Fixtures is a map of fixtureKey{ Fixture.Name, buildFlags } to Fixture.
|
||||
var dlvbincache = make(map[string]string)
|
||||
var dlvbinmu sync.Mutex
|
||||
|
||||
func getDlvBinInternal(t *testing.T, goflags ...string) string {
|
||||
dlvbin := filepath.Join(t.TempDir(), "dlv.exe")
|
||||
dlvbinmu.Lock()
|
||||
defer dlvbinmu.Unlock()
|
||||
|
||||
// Parse GOFLAGS and filter out empty strings
|
||||
goenvflags := os.Getenv("GOFLAGS")
|
||||
if goenvflags != "" {
|
||||
goflags = slices.Concat(goflags, strings.Split(os.Getenv("GOFLAGS"), " "))
|
||||
}
|
||||
|
||||
strargs := strings.Join(goflags, "")
|
||||
if path, ok := dlvbincache[strargs]; ok {
|
||||
return path
|
||||
}
|
||||
|
||||
dlvbin := TempFile("dlv.exe")
|
||||
|
||||
dlvbincache[strargs] = dlvbin
|
||||
|
||||
args := append([]string{"build", "-o", dlvbin}, goflags...)
|
||||
args = append(args, "github.com/go-delve/delve/cmd/dlv")
|
||||
|
||||
wd, _ := os.Getwd()
|
||||
fmt.Printf("at %s %s\n", wd, goflags)
|
||||
|
||||
out, err := exec.Command("go", args...).CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("go build -o %v github.com/go-delve/delve/cmd/dlv: %v\n%s", dlvbin, err, string(out))
|
||||
t.Fatalf("go %s: %v\n%s", strings.Join(args, " "), err, string(out))
|
||||
}
|
||||
|
||||
return dlvbin
|
||||
|
||||
Reference in New Issue
Block a user