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