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