暂无描述

report_test.go 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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/proftest"
  22. "github.com/google/pprof/profile"
  23. )
  24. type testcase struct {
  25. rpt *Report
  26. want string
  27. }
  28. func TestSource(t *testing.T) {
  29. const path = "testdata/"
  30. sampleValue1 := func(v []int64) int64 {
  31. return v[1]
  32. }
  33. for _, tc := range []testcase{
  34. {
  35. rpt: New(
  36. testProfile.Copy(),
  37. &Options{
  38. OutputFormat: List,
  39. Symbol: regexp.MustCompile(`.`),
  40. SampleValue: sampleValue1,
  41. SampleUnit: testProfile.SampleType[1].Unit,
  42. },
  43. ),
  44. want: path + "source.rpt",
  45. },
  46. {
  47. rpt: New(
  48. testProfile.Copy(),
  49. &Options{
  50. OutputFormat: Dot,
  51. CallTree: true,
  52. Symbol: regexp.MustCompile(`.`),
  53. SampleValue: sampleValue1,
  54. SampleUnit: testProfile.SampleType[1].Unit,
  55. },
  56. ),
  57. want: path + "source.dot",
  58. },
  59. } {
  60. b := bytes.NewBuffer(nil)
  61. if err := Generate(b, tc.rpt, &binutils.Binutils{}); err != nil {
  62. t.Fatalf("%s: %v", tc.want, err)
  63. }
  64. gold, err := ioutil.ReadFile(tc.want)
  65. if err != nil {
  66. t.Fatalf("%s: %v", tc.want, err)
  67. }
  68. if string(b.String()) != string(gold) {
  69. d, err := proftest.Diff(gold, b.Bytes())
  70. if err != nil {
  71. t.Fatalf("%s: %v", "source", err)
  72. }
  73. t.Error("source" + "\n" + string(d) + "\n" + "gold:\n" + tc.want)
  74. }
  75. }
  76. }
  77. var testM = []*profile.Mapping{
  78. {
  79. ID: 1,
  80. HasFunctions: true,
  81. HasFilenames: true,
  82. HasLineNumbers: true,
  83. HasInlineFrames: true,
  84. },
  85. }
  86. var testF = []*profile.Function{
  87. {
  88. ID: 1,
  89. Name: "main",
  90. Filename: "testdata/source1",
  91. },
  92. {
  93. ID: 2,
  94. Name: "foo",
  95. Filename: "testdata/source1",
  96. },
  97. {
  98. ID: 3,
  99. Name: "bar",
  100. Filename: "testdata/source1",
  101. },
  102. {
  103. ID: 4,
  104. Name: "tee",
  105. Filename: "testdata/source2",
  106. },
  107. }
  108. var testL = []*profile.Location{
  109. {
  110. ID: 1,
  111. Mapping: testM[0],
  112. Line: []profile.Line{
  113. {
  114. Function: testF[0],
  115. Line: 2,
  116. },
  117. },
  118. },
  119. {
  120. ID: 2,
  121. Mapping: testM[0],
  122. Line: []profile.Line{
  123. {
  124. Function: testF[1],
  125. Line: 4,
  126. },
  127. },
  128. },
  129. {
  130. ID: 3,
  131. Mapping: testM[0],
  132. Line: []profile.Line{
  133. {
  134. Function: testF[2],
  135. Line: 10,
  136. },
  137. },
  138. },
  139. {
  140. ID: 4,
  141. Mapping: testM[0],
  142. Line: []profile.Line{
  143. {
  144. Function: testF[3],
  145. Line: 2,
  146. },
  147. },
  148. },
  149. {
  150. ID: 5,
  151. Mapping: testM[0],
  152. Line: []profile.Line{
  153. {
  154. Function: testF[3],
  155. Line: 8,
  156. },
  157. },
  158. },
  159. }
  160. var testProfile = &profile.Profile{
  161. PeriodType: &profile.ValueType{Type: "cpu", Unit: "millisecond"},
  162. Period: 10,
  163. DurationNanos: 10e9,
  164. SampleType: []*profile.ValueType{
  165. {Type: "samples", Unit: "count"},
  166. {Type: "cpu", Unit: "cycles"},
  167. },
  168. Sample: []*profile.Sample{
  169. {
  170. Location: []*profile.Location{testL[0]},
  171. Value: []int64{1, 1},
  172. },
  173. {
  174. Location: []*profile.Location{testL[2], testL[1], testL[0]},
  175. Value: []int64{1, 10},
  176. },
  177. {
  178. Location: []*profile.Location{testL[4], testL[2], testL[0]},
  179. Value: []int64{1, 100},
  180. },
  181. {
  182. Location: []*profile.Location{testL[3], testL[0]},
  183. Value: []int64{1, 1000},
  184. },
  185. {
  186. Location: []*profile.Location{testL[4], testL[3], testL[0]},
  187. Value: []int64{1, 10000},
  188. },
  189. },
  190. Location: testL,
  191. Function: testF,
  192. Mapping: testM,
  193. }