Source file
src/runtime/trace/subscribe_test.go
1
2
3
4
5 package trace_test
6
7 import (
8 "bytes"
9 inttrace "internal/trace"
10 "internal/trace/testtrace"
11 "io"
12 "runtime"
13 "runtime/trace"
14 "slices"
15 "testing"
16 )
17
18 func TestSubscribers(t *testing.T) {
19 validate := func(t *testing.T, source string, tr []byte) {
20 t.Log("validating", source)
21 defer func() {
22 if t.Failed() {
23 testtrace.Dump(t, "TestSubscribers."+source, tr, *dumpTraces)
24 }
25 }()
26
27
28 r, err := inttrace.NewReader(bytes.NewReader(tr))
29 if err != nil {
30 t.Errorf("unexpected error creating trace reader for %s: %v", source, err)
31 return
32 }
33
34 v := testtrace.NewValidator()
35
36 if runtime.GOOS == "windows" || runtime.GOARCH == "wasm" {
37 v.SkipClockSnapshotChecks()
38 }
39
40 var syncs []int
41 evs := 0
42 for {
43 ev, err := r.ReadEvent()
44 if err == io.EOF {
45 break
46 }
47 if err != nil {
48 t.Errorf("unexpected error reading trace for %s: %v", source, err)
49 break
50 }
51 if err := v.Event(ev); err != nil {
52 t.Errorf("event validation failed: %s", err)
53 break
54 }
55 if ev.Kind() == inttrace.EventSync {
56 syncs = append(syncs, evs)
57 }
58 evs++
59 }
60 if !t.Failed() {
61 ends := []int{syncs[0], syncs[len(syncs)-1]}
62 if wantEnds := []int{0, evs - 1}; !slices.Equal(wantEnds, ends) {
63 t.Errorf("expected a sync event at each end of the trace, found sync events at %d instead of %d for %s",
64 ends, wantEnds, source)
65 }
66 }
67 }
68
69 validateTraces := func(t *testing.T, trace, frTrace *bytes.Buffer) {
70 validate(t, "tracer", trace.Bytes())
71 validate(t, "flightRecorder", frTrace.Bytes())
72 }
73 startFlightRecorder := func(t *testing.T) *trace.FlightRecorder {
74 fr := trace.NewFlightRecorder(trace.FlightRecorderConfig{})
75 if err := fr.Start(); err != nil {
76 t.Fatalf("unexpected error creating flight recorder: %v", err)
77 }
78 return fr
79 }
80 startTrace := func(t *testing.T, w io.Writer) {
81 if err := trace.Start(w); err != nil {
82 t.Fatalf("unexpected error starting flight recorder: %v", err)
83 }
84 }
85 stopFlightRecorder := func(t *testing.T, fr *trace.FlightRecorder, w io.Writer) {
86 if _, err := fr.WriteTo(w); err != nil {
87 t.Fatalf("unexpected error writing trace from flight recorder: %v", err)
88 }
89 fr.Stop()
90 }
91 stopTrace := func() {
92 trace.Stop()
93 }
94 t.Run("start(flight)_start(trace)_stop(trace)_stop(flight)", func(t *testing.T) {
95 if trace.IsEnabled() {
96 t.Skip("skipping because trace is already enabled")
97 }
98 frBuf := new(bytes.Buffer)
99 tBuf := new(bytes.Buffer)
100 fr := startFlightRecorder(t)
101 defer fr.Stop()
102 startTrace(t, tBuf)
103 defer trace.Stop()
104 stopTrace()
105 stopFlightRecorder(t, fr, frBuf)
106 validateTraces(t, tBuf, frBuf)
107 })
108 t.Run("start(trace)_start(flight)_stop(trace)_stop(flight)", func(t *testing.T) {
109 if trace.IsEnabled() {
110 t.Skip("skipping because trace is already enabled")
111 }
112 frBuf := new(bytes.Buffer)
113 tBuf := new(bytes.Buffer)
114 startTrace(t, tBuf)
115 defer trace.Stop()
116 fr := startFlightRecorder(t)
117 defer fr.Stop()
118 stopTrace()
119 stopFlightRecorder(t, fr, frBuf)
120 validateTraces(t, tBuf, frBuf)
121 })
122 t.Run("start(flight)_stop(flight)_start(trace)_stop(trace)", func(t *testing.T) {
123 if trace.IsEnabled() {
124 t.Skip("skipping because trace is already enabled")
125 }
126 frBuf := new(bytes.Buffer)
127 tBuf := new(bytes.Buffer)
128 fr := startFlightRecorder(t)
129 defer fr.Stop()
130 stopFlightRecorder(t, fr, frBuf)
131 startTrace(t, tBuf)
132 defer trace.Stop()
133 stopTrace()
134 validateTraces(t, tBuf, frBuf)
135 })
136 t.Run("start(flight)_stop(flight)_start(trace)_stop(trace)", func(t *testing.T) {
137 if trace.IsEnabled() {
138 t.Skip("skipping because trace is already enabled")
139 }
140 frBuf := new(bytes.Buffer)
141 tBuf := new(bytes.Buffer)
142 fr := startFlightRecorder(t)
143 defer fr.Stop()
144 stopFlightRecorder(t, fr, frBuf)
145 startTrace(t, tBuf)
146 defer trace.Stop()
147 stopTrace()
148 validateTraces(t, tBuf, frBuf)
149 })
150 t.Run("start(flight)_start(trace)_stop(flight)_stop(trace)", func(t *testing.T) {
151 if trace.IsEnabled() {
152 t.Skip("skipping because trace is already enabled")
153 }
154 frBuf := new(bytes.Buffer)
155 tBuf := new(bytes.Buffer)
156 fr := startFlightRecorder(t)
157 defer fr.Stop()
158 startTrace(t, tBuf)
159 defer trace.Stop()
160 stopFlightRecorder(t, fr, frBuf)
161 stopTrace()
162 validateTraces(t, tBuf, frBuf)
163 })
164 }
165
View as plain text