1 package report
2
3 import (
4 "fmt"
5 "reflect"
6 "testing"
7
8 "github.com/google/pprof/profile"
9 )
10
11
12 func makeTestStacks(samples ...*profile.Sample) StackSet {
13 prof := makeTestProfile(samples...)
14 rpt := NewDefault(prof, Options{OutputFormat: Tree, CallTree: true})
15 return rpt.Stacks()
16 }
17
18 func TestStacks(t *testing.T) {
19
20 main, foo, bar, tee := testL[0], testL[1], testL[2], testL[3]
21
22
23 type stack struct {
24 value int64
25 names []string
26 }
27 makeStack := func(value int64, names ...string) stack {
28 return stack{value, names}
29 }
30
31 for _, c := range []struct {
32 name string
33 stacks StackSet
34 expect []stack
35 }{
36 {
37 "simple",
38 makeTestStacks(
39 testSample(100, bar, foo, main),
40 testSample(200, tee, foo, main),
41 ),
42 []stack{
43 makeStack(100, "0:root", "1:main", "2:foo", "3:bar"),
44 makeStack(200, "0:root", "1:main", "2:foo", "4:tee"),
45 },
46 },
47 {
48 "recursion",
49 makeTestStacks(
50 testSample(100, bar, foo, foo, foo, main),
51 testSample(200, bar, foo, foo, main),
52 ),
53 []stack{
54
55 makeStack(100, "0:root", "1:main", "2:foo", "2:foo", "2:foo", "3:bar"),
56 makeStack(200, "0:root", "1:main", "2:foo", "2:foo", "3:bar"),
57 },
58 },
59 } {
60 t.Run(c.name, func(t *testing.T) {
61 var got []stack
62 for _, s := range c.stacks.Stacks {
63 stk := stack{
64 value: s.Value,
65 names: make([]string, len(s.Sources)),
66 }
67 for i, src := range s.Sources {
68 stk.names[i] = fmt.Sprint(src, ":", c.stacks.Sources[src].FullName)
69 }
70 got = append(got, stk)
71 }
72 if !reflect.DeepEqual(c.expect, got) {
73 t.Errorf("expecting source %+v, got %+v", c.expect, got)
74 }
75 })
76 }
77 }
78
79 func TestStackSources(t *testing.T) {
80
81 main, foo, bar, tee, inl := testL[0], testL[1], testL[2], testL[3], testL[5]
82
83 type srcInfo struct {
84 name string
85 self int64
86 inlined bool
87 }
88
89 source := func(stacks StackSet, name string) srcInfo {
90 src := findSource(stacks, name)
91 return srcInfo{src.FullName, src.Self, src.Inlined}
92 }
93
94 for _, c := range []struct {
95 name string
96 stacks StackSet
97 srcs []srcInfo
98 }{
99 {
100 "empty",
101 makeTestStacks(),
102 []srcInfo{},
103 },
104 {
105 "two-leaves",
106 makeTestStacks(
107 testSample(100, bar, foo, main),
108 testSample(200, tee, bar, foo, main),
109 testSample(1000, tee, main),
110 ),
111 []srcInfo{
112 {"main", 0, false},
113 {"bar", 100, false},
114 {"foo", 0, false},
115 {"tee", 1200, false},
116 },
117 },
118 {
119 "inlined",
120 makeTestStacks(
121 testSample(100, inl),
122 testSample(200, inl),
123 ),
124 []srcInfo{
125
126 {"tee", 300, true},
127 },
128 },
129 {
130 "recursion",
131 makeTestStacks(
132 testSample(100, foo, foo, foo, main),
133 testSample(100, foo, foo, main),
134 ),
135 []srcInfo{
136 {"main", 0, false},
137 {"foo", 200, false},
138 },
139 },
140 {
141 "flat",
142 makeTestStacks(
143 testSample(100, main),
144 testSample(100, foo),
145 testSample(100, bar),
146 testSample(100, tee),
147 ),
148 []srcInfo{
149 {"main", 100, false},
150 {"bar", 100, false},
151 {"foo", 100, false},
152 {"tee", 100, false},
153 },
154 },
155 } {
156 t.Run(c.name, func(t *testing.T) {
157 for _, expect := range c.srcs {
158 got := source(c.stacks, expect.name)
159 if !reflect.DeepEqual(expect, got) {
160 t.Errorf("expecting source %+v, got %+v", expect, got)
161 }
162 }
163 })
164 }
165 }
166
167 func findSource(stacks StackSet, name string) StackSource {
168 for _, src := range stacks.Sources {
169 if src.FullName == name {
170 return src
171 }
172 }
173 return StackSource{}
174 }
175
View as plain text