golang.org/x/exp@v0.0.0-20240506185415-9bf2ced13842/trace/reader_test.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Code generated by "gen.bash" from internal/trace/v2; DO NOT EDIT. 6 7 //go:build go1.21 8 9 package trace_test 10 11 import ( 12 "bytes" 13 "flag" 14 "fmt" 15 "io" 16 "os" 17 "path/filepath" 18 "strings" 19 "testing" 20 21 "golang.org/x/exp/trace" 22 "golang.org/x/exp/trace/internal/raw" 23 "golang.org/x/exp/trace/internal/testtrace" 24 "golang.org/x/exp/trace/internal/version" 25 ) 26 27 var ( 28 logEvents = flag.Bool("log-events", false, "whether to log high-level events; significantly slows down tests") 29 dumpTraces = flag.Bool("dump-traces", false, "dump traces even on success") 30 ) 31 32 func TestReaderGolden(t *testing.T) { 33 matches, err := filepath.Glob("./testdata/tests/*.test") 34 if err != nil { 35 t.Fatalf("failed to glob for tests: %v", err) 36 } 37 for _, testPath := range matches { 38 testPath := testPath 39 testName, err := filepath.Rel("./testdata", testPath) 40 if err != nil { 41 t.Fatalf("failed to relativize testdata path: %v", err) 42 } 43 t.Run(testName, func(t *testing.T) { 44 tr, exp, err := testtrace.ParseFile(testPath) 45 if err != nil { 46 t.Fatalf("failed to parse test file at %s: %v", testPath, err) 47 } 48 testReader(t, tr, exp) 49 }) 50 } 51 } 52 53 func FuzzReader(f *testing.F) { 54 // Currently disabled because the parser doesn't do much validation and most 55 // getters can be made to panic. Turn this on once the parser is meant to 56 // reject invalid traces. 57 const testGetters = false 58 59 f.Fuzz(func(t *testing.T, b []byte) { 60 r, err := trace.NewReader(bytes.NewReader(b)) 61 if err != nil { 62 return 63 } 64 for { 65 ev, err := r.ReadEvent() 66 if err != nil { 67 break 68 } 69 70 if !testGetters { 71 continue 72 } 73 // Make sure getters don't do anything that panics 74 switch ev.Kind() { 75 case trace.EventLabel: 76 ev.Label() 77 case trace.EventLog: 78 ev.Log() 79 case trace.EventMetric: 80 ev.Metric() 81 case trace.EventRangeActive, trace.EventRangeBegin: 82 ev.Range() 83 case trace.EventRangeEnd: 84 ev.Range() 85 ev.RangeAttributes() 86 case trace.EventStateTransition: 87 ev.StateTransition() 88 case trace.EventRegionBegin, trace.EventRegionEnd: 89 ev.Region() 90 case trace.EventTaskBegin, trace.EventTaskEnd: 91 ev.Task() 92 case trace.EventSync: 93 case trace.EventStackSample: 94 case trace.EventBad: 95 } 96 } 97 }) 98 } 99 100 func testReader(t *testing.T, tr io.Reader, exp *testtrace.Expectation) { 101 r, err := trace.NewReader(tr) 102 if err != nil { 103 if err := exp.Check(err); err != nil { 104 t.Error(err) 105 } 106 return 107 } 108 v := testtrace.NewValidator() 109 for { 110 ev, err := r.ReadEvent() 111 if err == io.EOF { 112 break 113 } 114 if err != nil { 115 if err := exp.Check(err); err != nil { 116 t.Error(err) 117 } 118 return 119 } 120 if *logEvents { 121 t.Log(ev.String()) 122 } 123 if err := v.Event(ev); err != nil { 124 t.Error(err) 125 } 126 } 127 if err := exp.Check(nil); err != nil { 128 t.Error(err) 129 } 130 } 131 132 func dumpTraceToText(t *testing.T, b []byte) string { 133 t.Helper() 134 135 br, err := raw.NewReader(bytes.NewReader(b)) 136 if err != nil { 137 t.Fatalf("dumping trace: %v", err) 138 } 139 var sb strings.Builder 140 tw, err := raw.NewTextWriter(&sb, version.Current) 141 if err != nil { 142 t.Fatalf("dumping trace: %v", err) 143 } 144 for { 145 ev, err := br.ReadEvent() 146 if err == io.EOF { 147 break 148 } 149 if err != nil { 150 t.Fatalf("dumping trace: %v", err) 151 } 152 if err := tw.WriteEvent(ev); err != nil { 153 t.Fatalf("dumping trace: %v", err) 154 } 155 } 156 return sb.String() 157 } 158 159 func dumpTraceToFile(t *testing.T, testName string, stress bool, b []byte) string { 160 t.Helper() 161 162 desc := "default" 163 if stress { 164 desc = "stress" 165 } 166 name := fmt.Sprintf("%s.%s.trace.", testName, desc) 167 f, err := os.CreateTemp("", name) 168 if err != nil { 169 t.Fatalf("creating temp file: %v", err) 170 } 171 defer f.Close() 172 if _, err := io.Copy(f, bytes.NewReader(b)); err != nil { 173 t.Fatalf("writing trace dump to %q: %v", f.Name(), err) 174 } 175 return f.Name() 176 }