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