1
2
3
4
5 package testtrace
6
7 import (
8 "bytes"
9 "fmt"
10 "internal/testenv"
11 "internal/trace/raw"
12 "internal/trace/version"
13 "io"
14 "os"
15 "strings"
16 "testing"
17 )
18
19
20
21 func Dump(t *testing.T, testName string, traceBytes []byte, forceToFile bool) {
22 onBuilder := testenv.Builder() != ""
23 onOldBuilder := !strings.Contains(testenv.Builder(), "gotip") && !strings.Contains(testenv.Builder(), "go1")
24
25 if onBuilder && !forceToFile {
26
27
28
29 s := dumpTraceToText(t, traceBytes)
30 if onOldBuilder && len(s) > 1<<20+512<<10 {
31
32
33
34
35
36
37 t.Logf("text trace too large to dump (%d bytes)", len(s))
38 } else {
39 t.Log(s)
40 }
41 } else {
42
43 t.Logf("wrote trace to file: %s", dumpTraceToFile(t, testName, traceBytes))
44 }
45 }
46
47 func dumpTraceToText(t *testing.T, b []byte) string {
48 t.Helper()
49
50 br, err := raw.NewReader(bytes.NewReader(b))
51 if err != nil {
52 t.Fatalf("dumping trace: %v", err)
53 }
54 var sb strings.Builder
55 tw, err := raw.NewTextWriter(&sb, version.Current)
56 if err != nil {
57 t.Fatalf("dumping trace: %v", err)
58 }
59 for {
60 ev, err := br.ReadEvent()
61 if err == io.EOF {
62 break
63 }
64 if err != nil {
65 t.Fatalf("dumping trace: %v", err)
66 }
67 if err := tw.WriteEvent(ev); err != nil {
68 t.Fatalf("dumping trace: %v", err)
69 }
70 }
71 return sb.String()
72 }
73
74 func dumpTraceToFile(t *testing.T, testName string, b []byte) string {
75 t.Helper()
76
77 name := fmt.Sprintf("%s.trace.", testName)
78 f, err := os.CreateTemp(t.ArtifactDir(), name)
79 if err != nil {
80 t.Fatalf("creating temp file: %v", err)
81 }
82 defer f.Close()
83 if _, err := io.Copy(f, bytes.NewReader(b)); err != nil {
84 t.Fatalf("writing trace dump to %q: %v", f.Name(), err)
85 }
86 return f.Name()
87 }
88
View as plain text