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  }