Nessuna descrizione

report_test.go 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. // Copyright 2014 Google Inc. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package report
  15. import (
  16. "bytes"
  17. "io/ioutil"
  18. "regexp"
  19. "testing"
  20. "github.com/google/pprof/internal/binutils"
  21. "github.com/google/pprof/internal/graph"
  22. "github.com/google/pprof/internal/proftest"
  23. "github.com/google/pprof/profile"
  24. )
  25. type testcase struct {
  26. rpt *Report
  27. want string
  28. }
  29. func TestSource(t *testing.T) {
  30. const path = "testdata/"
  31. sampleValue1 := func(v []int64) int64 {
  32. return v[1]
  33. }
  34. for _, tc := range []testcase{
  35. {
  36. rpt: New(
  37. testProfile.Copy(),
  38. &Options{
  39. OutputFormat: List,
  40. Symbol: regexp.MustCompile(`.`),
  41. SampleValue: sampleValue1,
  42. SampleUnit: testProfile.SampleType[1].Unit,
  43. },
  44. ),
  45. want: path + "source.rpt",
  46. },
  47. {
  48. rpt: New(
  49. testProfile.Copy(),
  50. &Options{
  51. OutputFormat: Dot,
  52. CallTree: true,
  53. Symbol: regexp.MustCompile(`.`),
  54. SampleValue: sampleValue1,
  55. SampleUnit: testProfile.SampleType[1].Unit,
  56. },
  57. ),
  58. want: path + "source.dot",
  59. },
  60. } {
  61. b := bytes.NewBuffer(nil)
  62. if err := Generate(b, tc.rpt, &binutils.Binutils{}); err != nil {
  63. t.Fatalf("%s: %v", tc.want, err)
  64. }
  65. gold, err := ioutil.ReadFile(tc.want)
  66. if err != nil {
  67. t.Fatalf("%s: %v", tc.want, err)
  68. }
  69. if string(b.String()) != string(gold) {
  70. d, err := proftest.Diff(gold, b.Bytes())
  71. if err != nil {
  72. t.Fatalf("%s: %v", "source", err)
  73. }
  74. t.Error("source" + "\n" + string(d) + "\n" + "gold:\n" + tc.want)
  75. }
  76. }
  77. }
  78. var testM = []*profile.Mapping{
  79. {
  80. ID: 1,
  81. HasFunctions: true,
  82. HasFilenames: true,
  83. HasLineNumbers: true,
  84. HasInlineFrames: true,
  85. },
  86. }
  87. var testF = []*profile.Function{
  88. {
  89. ID: 1,
  90. Name: "main",
  91. Filename: "testdata/source1",
  92. },
  93. {
  94. ID: 2,
  95. Name: "foo",
  96. Filename: "testdata/source1",
  97. },
  98. {
  99. ID: 3,
  100. Name: "bar",
  101. Filename: "testdata/source1",
  102. },
  103. {
  104. ID: 4,
  105. Name: "tee",
  106. Filename: "testdata/source2",
  107. },
  108. }
  109. var testL = []*profile.Location{
  110. {
  111. ID: 1,
  112. Mapping: testM[0],
  113. Line: []profile.Line{
  114. {
  115. Function: testF[0],
  116. Line: 2,
  117. },
  118. },
  119. },
  120. {
  121. ID: 2,
  122. Mapping: testM[0],
  123. Line: []profile.Line{
  124. {
  125. Function: testF[1],
  126. Line: 4,
  127. },
  128. },
  129. },
  130. {
  131. ID: 3,
  132. Mapping: testM[0],
  133. Line: []profile.Line{
  134. {
  135. Function: testF[2],
  136. Line: 10,
  137. },
  138. },
  139. },
  140. {
  141. ID: 4,
  142. Mapping: testM[0],
  143. Line: []profile.Line{
  144. {
  145. Function: testF[3],
  146. Line: 2,
  147. },
  148. },
  149. },
  150. {
  151. ID: 5,
  152. Mapping: testM[0],
  153. Line: []profile.Line{
  154. {
  155. Function: testF[3],
  156. Line: 8,
  157. },
  158. },
  159. },
  160. }
  161. var testProfile = &profile.Profile{
  162. PeriodType: &profile.ValueType{Type: "cpu", Unit: "millisecond"},
  163. Period: 10,
  164. DurationNanos: 10e9,
  165. SampleType: []*profile.ValueType{
  166. {Type: "samples", Unit: "count"},
  167. {Type: "cpu", Unit: "cycles"},
  168. },
  169. Sample: []*profile.Sample{
  170. {
  171. Location: []*profile.Location{testL[0]},
  172. Value: []int64{1, 1},
  173. },
  174. {
  175. Location: []*profile.Location{testL[2], testL[1], testL[0]},
  176. Value: []int64{1, 10},
  177. },
  178. {
  179. Location: []*profile.Location{testL[4], testL[2], testL[0]},
  180. Value: []int64{1, 100},
  181. },
  182. {
  183. Location: []*profile.Location{testL[3], testL[0]},
  184. Value: []int64{1, 1000},
  185. },
  186. {
  187. Location: []*profile.Location{testL[4], testL[3], testL[0]},
  188. Value: []int64{1, 10000},
  189. },
  190. },
  191. Location: testL,
  192. Function: testF,
  193. Mapping: testM,
  194. }
  195. func TestDisambiguation(t *testing.T) {
  196. parent1 := &graph.Node{Info: graph.NodeInfo{Name: "parent1"}}
  197. parent2 := &graph.Node{Info: graph.NodeInfo{Name: "parent2"}}
  198. child1 := &graph.Node{Info: graph.NodeInfo{Name: "child"}, Function: parent1}
  199. child2 := &graph.Node{Info: graph.NodeInfo{Name: "child"}, Function: parent2}
  200. child3 := &graph.Node{Info: graph.NodeInfo{Name: "child"}, Function: parent1}
  201. sibling := &graph.Node{Info: graph.NodeInfo{Name: "sibling"}, Function: parent1}
  202. n := []*graph.Node{parent1, parent2, child1, child2, child3, sibling}
  203. wanted := map[*graph.Node]string{
  204. parent1: "parent1",
  205. parent2: "parent2",
  206. child1: "child [1/2]",
  207. child2: "child [2/2]",
  208. child3: "child [1/2]",
  209. sibling: "sibling",
  210. }
  211. g := &graph.Graph{n}
  212. names := getDisambiguatedNames(g)
  213. for node, want := range wanted {
  214. if got := names[node]; got != want {
  215. t.Errorf("name %s, got %s, want %s", node.Info.Name, got, want)
  216. }
  217. }
  218. }