...

Source file src/runtime/trace/annotation_test.go

Documentation: runtime/trace

		 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  }
	 157  

View as plain text