github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/runtime/trace/annotation_test.go (about) 1 // Copyright 2018 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 package trace_test 6 7 import ( 8 "bytes" 9 "context" 10 "fmt" 11 "internal/goexperiment" 12 "internal/trace" 13 "reflect" 14 . "runtime/trace" 15 "strings" 16 "sync" 17 "testing" 18 ) 19 20 func BenchmarkStartRegion(b *testing.B) { 21 b.ReportAllocs() 22 ctx, task := NewTask(context.Background(), "benchmark") 23 defer task.End() 24 25 b.RunParallel(func(pb *testing.PB) { 26 for pb.Next() { 27 StartRegion(ctx, "region").End() 28 } 29 }) 30 } 31 32 func BenchmarkNewTask(b *testing.B) { 33 b.ReportAllocs() 34 pctx, task := NewTask(context.Background(), "benchmark") 35 defer task.End() 36 37 b.RunParallel(func(pb *testing.PB) { 38 for pb.Next() { 39 _, task := NewTask(pctx, "task") 40 task.End() 41 } 42 }) 43 } 44 45 func TestUserTaskRegion(t *testing.T) { 46 if goexperiment.ExecTracer2 { 47 // An equivalent test exists in internal/trace/v2. 48 t.Skip("skipping because this test is incompatible with the new tracer") 49 } 50 if IsEnabled() { 51 t.Skip("skipping because -test.trace is set") 52 } 53 bgctx, cancel := context.WithCancel(context.Background()) 54 defer cancel() 55 56 preExistingRegion := StartRegion(bgctx, "pre-existing region") 57 58 buf := new(bytes.Buffer) 59 if err := Start(buf); err != nil { 60 t.Fatalf("failed to start tracing: %v", err) 61 } 62 63 // Beginning of traced execution 64 var wg sync.WaitGroup 65 ctx, task := NewTask(bgctx, "task0") // EvUserTaskCreate("task0") 66 wg.Add(1) 67 go func() { 68 defer wg.Done() 69 defer task.End() // EvUserTaskEnd("task0") 70 71 WithRegion(ctx, "region0", func() { 72 // EvUserRegionCreate("region0", start) 73 WithRegion(ctx, "region1", func() { 74 Log(ctx, "key0", "0123456789abcdef") // EvUserLog("task0", "key0", "0....f") 75 }) 76 // EvUserRegion("region0", end) 77 }) 78 }() 79 80 wg.Wait() 81 82 preExistingRegion.End() 83 postExistingRegion := StartRegion(bgctx, "post-existing region") 84 85 // End of traced execution 86 Stop() 87 88 postExistingRegion.End() 89 90 saveTrace(t, buf, "TestUserTaskRegion") 91 res, err := trace.Parse(buf, "") 92 if err == trace.ErrTimeOrder { 93 // golang.org/issues/16755 94 t.Skipf("skipping trace: %v", err) 95 } 96 if err != nil { 97 t.Fatalf("Parse failed: %v", err) 98 } 99 100 // Check whether we see all user annotation related records in order 101 type testData struct { 102 typ byte 103 strs []string 104 args []uint64 105 setLink bool 106 } 107 108 var got []testData 109 tasks := map[uint64]string{} 110 for _, e := range res.Events { 111 t.Logf("%s", e) 112 switch e.Type { 113 case trace.EvUserTaskCreate: 114 taskName := e.SArgs[0] 115 got = append(got, testData{trace.EvUserTaskCreate, []string{taskName}, nil, e.Link != nil}) 116 if e.Link != nil && e.Link.Type != trace.EvUserTaskEnd { 117 t.Errorf("Unexpected linked event %q->%q", e, e.Link) 118 } 119 tasks[e.Args[0]] = taskName 120 case trace.EvUserLog: 121 key, val := e.SArgs[0], e.SArgs[1] 122 taskName := tasks[e.Args[0]] 123 got = append(got, testData{trace.EvUserLog, []string{taskName, key, val}, nil, e.Link != nil}) 124 case trace.EvUserTaskEnd: 125 taskName := tasks[e.Args[0]] 126 got = append(got, testData{trace.EvUserTaskEnd, []string{taskName}, nil, e.Link != nil}) 127 if e.Link != nil && e.Link.Type != trace.EvUserTaskCreate { 128 t.Errorf("Unexpected linked event %q->%q", e, e.Link) 129 } 130 case trace.EvUserRegion: 131 taskName := tasks[e.Args[0]] 132 regionName := e.SArgs[0] 133 got = append(got, testData{trace.EvUserRegion, []string{taskName, regionName}, []uint64{e.Args[1]}, e.Link != nil}) 134 if e.Link != nil && (e.Link.Type != trace.EvUserRegion || e.Link.SArgs[0] != regionName) { 135 t.Errorf("Unexpected linked event %q->%q", e, e.Link) 136 } 137 } 138 } 139 want := []testData{ 140 {trace.EvUserTaskCreate, []string{"task0"}, nil, true}, 141 {trace.EvUserRegion, []string{"task0", "region0"}, []uint64{0}, true}, 142 {trace.EvUserRegion, []string{"task0", "region1"}, []uint64{0}, true}, 143 {trace.EvUserLog, []string{"task0", "key0", "0123456789abcdef"}, nil, false}, 144 {trace.EvUserRegion, []string{"task0", "region1"}, []uint64{1}, false}, 145 {trace.EvUserRegion, []string{"task0", "region0"}, []uint64{1}, false}, 146 {trace.EvUserTaskEnd, []string{"task0"}, nil, false}, 147 // Currently, pre-existing region is not recorded to avoid allocations. 148 // {trace.EvUserRegion, []string{"", "pre-existing region"}, []uint64{1}, false}, 149 {trace.EvUserRegion, []string{"", "post-existing region"}, []uint64{0}, false}, 150 } 151 if !reflect.DeepEqual(got, want) { 152 pretty := func(data []testData) string { 153 var s strings.Builder 154 for _, d := range data { 155 fmt.Fprintf(&s, "\t%+v\n", d) 156 } 157 return s.String() 158 } 159 t.Errorf("Got user region related events\n%+v\nwant:\n%+v", pretty(got), pretty(want)) 160 } 161 }