github.com/stealthrocket/wzprof@v0.2.1-0.20230830205924-5fa86be5e5b3/cpu_test.go (about)

     1  package wzprof
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/tetratelabs/wazero/api"
     8  	"github.com/tetratelabs/wazero/experimental"
     9  	"github.com/tetratelabs/wazero/experimental/wazerotest"
    10  )
    11  
    12  func BenchmarkCPUProfilerOn(b *testing.B) {
    13  	p := ProfilingFor(nil).CPUProfiler()
    14  	p.StartProfile()
    15  	benchmarkFunctionListener(b, p)
    16  }
    17  
    18  func BenchmarkCPUProfilerOff(b *testing.B) {
    19  	p := ProfilingFor(nil).CPUProfiler()
    20  	benchmarkFunctionListener(b, p)
    21  }
    22  
    23  func TestCPUProfilerTime(t *testing.T) {
    24  	currentTime := int64(0)
    25  
    26  	p := ProfilingFor(nil).CPUProfiler(
    27  		TimeFunc(func() int64 { return currentTime }),
    28  	)
    29  
    30  	module := wazerotest.NewModule(nil,
    31  		wazerotest.NewFunction(func(context.Context, api.Module) {}),
    32  		wazerotest.NewFunction(func(context.Context, api.Module) {}),
    33  		wazerotest.NewFunction(func(context.Context, api.Module) {}),
    34  	)
    35  
    36  	f0 := p.NewFunctionListener(module.Function(0).Definition())
    37  	f1 := p.NewFunctionListener(module.Function(1).Definition())
    38  	f2 := p.NewFunctionListener(module.Function(2).Definition())
    39  
    40  	stack0 := []experimental.StackFrame{
    41  		{Function: module.Function(0)},
    42  	}
    43  
    44  	stack1 := []experimental.StackFrame{
    45  		{Function: module.Function(0)},
    46  		{Function: module.Function(1)},
    47  	}
    48  
    49  	stack2 := []experimental.StackFrame{
    50  		{Function: module.Function(0)},
    51  		{Function: module.Function(1)},
    52  		{Function: module.Function(2)},
    53  	}
    54  
    55  	def0 := stack0[0].Function.Definition()
    56  	def1 := stack1[1].Function.Definition()
    57  	def2 := stack2[2].Function.Definition()
    58  
    59  	ctx := context.Background()
    60  
    61  	const (
    62  		t0 int64 = 1
    63  		t1 int64 = 10
    64  		t2 int64 = 42
    65  		t3 int64 = 100
    66  		t4 int64 = 101
    67  		t5 int64 = 102
    68  	)
    69  
    70  	p.StartProfile()
    71  
    72  	currentTime = t0
    73  	f0.Before(ctx, module, def0, nil, experimental.NewStackIterator(stack0...))
    74  
    75  	currentTime = t1
    76  	f1.Before(ctx, module, def1, nil, experimental.NewStackIterator(stack1...))
    77  
    78  	currentTime = t2
    79  	f2.Before(ctx, module, def2, nil, experimental.NewStackIterator(stack2...))
    80  
    81  	currentTime = t3
    82  	f2.After(ctx, module, def2, nil)
    83  
    84  	currentTime = t4
    85  	f1.After(ctx, module, def1, nil)
    86  
    87  	currentTime = t5
    88  	f0.After(ctx, module, def0, nil)
    89  
    90  	trace0 := makeStackTraceFromFrames(stack0)
    91  	trace1 := makeStackTraceFromFrames(stack1)
    92  	trace2 := makeStackTraceFromFrames(stack2)
    93  
    94  	d2 := t3 - t2
    95  	d1 := t4 - (t1 + d2)
    96  	d0 := t5 - (t0 + d1 + d2)
    97  
    98  	assertStackCount(t, p.counts, trace0, 1, d0)
    99  	assertStackCount(t, p.counts, trace1, 1, d1)
   100  	assertStackCount(t, p.counts, trace2, 1, d2)
   101  }
   102  
   103  func assertStackCount(t *testing.T, counts stackCounterMap, trace stackTrace, count, total int64) {
   104  	t.Helper()
   105  	c := counts.lookup(trace)
   106  
   107  	if c.count() != count {
   108  		t.Errorf("%sstack count mismatch: want=%d got=%d", trace, count, c.count())
   109  	}
   110  
   111  	if c.total() != total {
   112  		t.Errorf("%sstack total mismatch: want=%d got=%d", trace, total, c.total())
   113  	}
   114  }
   115  
   116  func makeStackTraceFromFrames(stackFrames []experimental.StackFrame) stackTrace {
   117  	return makeStackTrace(stackTrace{}, experimental.NewStackIterator(stackFrames...))
   118  }