diff --git a/cmd/dlv/dlv_test.go b/cmd/dlv/dlv_test.go index 6d15794a..40fecf8d 100644 --- a/cmd/dlv/dlv_test.go +++ b/cmd/dlv/dlv_test.go @@ -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 { diff --git a/pkg/config/split_test.go b/pkg/config/split_test.go index 04a97dfb..d77d5608 100644 --- a/pkg/config/split_test.go +++ b/pkg/config/split_test.go @@ -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"` diff --git a/pkg/dwarf/frame/entries_test.go b/pkg/dwarf/frame/entries_test.go index 48b00886..2c735aa2 100644 --- a/pkg/dwarf/frame/entries_test.go +++ b/pkg/dwarf/frame/entries_test.go @@ -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 diff --git a/pkg/dwarf/frame/parser_test.go b/pkg/dwarf/frame/parser_test.go index efbfadd7..dcd2cf27 100644 --- a/pkg/dwarf/frame/parser_test.go +++ b/pkg/dwarf/frame/parser_test.go @@ -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}, diff --git a/pkg/dwarf/godwarf/tree_test.go b/pkg/dwarf/godwarf/tree_test.go index f27a4b1c..af189fff 100644 --- a/pkg/dwarf/godwarf/tree_test.go +++ b/pkg/dwarf/godwarf/tree_test.go @@ -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 { diff --git a/pkg/dwarf/leb128/decode_test.go b/pkg/dwarf/leb128/decode_test.go index f9049bc7..6dbf24e8 100644 --- a/pkg/dwarf/leb128/decode_test.go +++ b/pkg/dwarf/leb128/decode_test.go @@ -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) diff --git a/pkg/dwarf/leb128/encode_test.go b/pkg/dwarf/leb128/encode_test.go index f344b7c8..e0b18ef7 100644 --- a/pkg/dwarf/leb128/encode_test.go +++ b/pkg/dwarf/leb128/encode_test.go @@ -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 diff --git a/pkg/dwarf/line/line_parser_test.go b/pkg/dwarf/line/line_parser_test.go index 993420e4..f6e5f685 100644 --- a/pkg/dwarf/line/line_parser_test.go +++ b/pkg/dwarf/line/line_parser_test.go @@ -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) diff --git a/pkg/dwarf/line/state_machine_test.go b/pkg/dwarf/line/state_machine_test.go index 7240ec23..3337f76a 100644 --- a/pkg/dwarf/line/state_machine_test.go +++ b/pkg/dwarf/line/state_machine_test.go @@ -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. diff --git a/pkg/dwarf/loclist/loclist5_test.go b/pkg/dwarf/loclist/loclist5_test.go index 5bf692cb..efd82376 100644 --- a/pkg/dwarf/loclist/loclist5_test.go +++ b/pkg/dwarf/loclist/loclist5_test.go @@ -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) } diff --git a/pkg/dwarf/op/op_test.go b/pkg/dwarf/op/op_test.go index 92927e03..f848f867 100644 --- a/pkg/dwarf/op/op_test.go +++ b/pkg/dwarf/op/op_test.go @@ -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), diff --git a/pkg/dwarf/parseutil_test.go b/pkg/dwarf/parseutil_test.go index c8ea66ca..6929ac4f 100644 --- a/pkg/dwarf/parseutil_test.go +++ b/pkg/dwarf/parseutil_test.go @@ -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) diff --git a/pkg/gobuild/gobuild_test.go b/pkg/gobuild/gobuild_test.go index 4f249ee8..a5caa2c9 100644 --- a/pkg/gobuild/gobuild_test.go +++ b/pkg/gobuild/gobuild_test.go @@ -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) + } + }) } } diff --git a/pkg/goversion/version_test.go b/pkg/goversion/version_test.go index 48b0aa7f..64973c30 100644 --- a/pkg/goversion/version_test.go +++ b/pkg/goversion/version_test.go @@ -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") diff --git a/pkg/locspec/locations_test.go b/pkg/locspec/locations_test.go index 617126a1..58aa6d2d 100644 --- a/pkg/locspec/locations_test.go +++ b/pkg/locspec/locations_test.go @@ -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 { diff --git a/pkg/proc/core/core_test.go b/pkg/proc/core/core_test.go index 58b68741..30acea9b 100644 --- a/pkg/proc/core/core_test.go +++ b/pkg/proc/core/core_test.go @@ -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 } } diff --git a/pkg/proc/dwarf_expr_test.go b/pkg/proc/dwarf_expr_test.go index 0e3aa2a7..e5f14b0c 100644 --- a/pkg/proc/dwarf_expr_test.go +++ b/pkg/proc/dwarf_expr_test.go @@ -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) diff --git a/pkg/proc/test/support.go b/pkg/proc/test/support.go index 1de7a6f9..39e15f0c 100644 --- a/pkg/proc/test/support.go +++ b/pkg/proc/test/support.go @@ -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