123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- // Copyright 2014 Google Inc. All Rights Reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
-
- package report
-
- import (
- "bytes"
- "io/ioutil"
- "regexp"
- "testing"
-
- "github.com/google/pprof/internal/binutils"
- "github.com/google/pprof/internal/graph"
- "github.com/google/pprof/internal/proftest"
- "github.com/google/pprof/profile"
- )
-
- type testcase struct {
- rpt *Report
- want string
- }
-
- func TestSource(t *testing.T) {
- const path = "testdata/"
-
- sampleValue1 := func(v []int64) int64 {
- return v[1]
- }
-
- for _, tc := range []testcase{
- {
- rpt: New(
- testProfile.Copy(),
- &Options{
- OutputFormat: List,
- Symbol: regexp.MustCompile(`.`),
-
- SampleValue: sampleValue1,
- SampleUnit: testProfile.SampleType[1].Unit,
- },
- ),
- want: path + "source.rpt",
- },
- {
- rpt: New(
- testProfile.Copy(),
- &Options{
- OutputFormat: Dot,
- CallTree: true,
- Symbol: regexp.MustCompile(`.`),
-
- SampleValue: sampleValue1,
- SampleUnit: testProfile.SampleType[1].Unit,
- },
- ),
- want: path + "source.dot",
- },
- } {
- b := bytes.NewBuffer(nil)
- if err := Generate(b, tc.rpt, &binutils.Binutils{}); err != nil {
- t.Fatalf("%s: %v", tc.want, err)
- }
-
- gold, err := ioutil.ReadFile(tc.want)
- if err != nil {
- t.Fatalf("%s: %v", tc.want, err)
- }
- if string(b.String()) != string(gold) {
- d, err := proftest.Diff(gold, b.Bytes())
- if err != nil {
- t.Fatalf("%s: %v", "source", err)
- }
- t.Error("source" + "\n" + string(d) + "\n" + "gold:\n" + tc.want)
- }
- }
- }
-
- var testM = []*profile.Mapping{
- {
- ID: 1,
- HasFunctions: true,
- HasFilenames: true,
- HasLineNumbers: true,
- HasInlineFrames: true,
- },
- }
-
- var testF = []*profile.Function{
- {
- ID: 1,
- Name: "main",
- Filename: "testdata/source1",
- },
- {
- ID: 2,
- Name: "foo",
- Filename: "testdata/source1",
- },
- {
- ID: 3,
- Name: "bar",
- Filename: "testdata/source1",
- },
- {
- ID: 4,
- Name: "tee",
- Filename: "testdata/source2",
- },
- }
-
- var testL = []*profile.Location{
- {
- ID: 1,
- Mapping: testM[0],
- Line: []profile.Line{
- {
- Function: testF[0],
- Line: 2,
- },
- },
- },
- {
- ID: 2,
- Mapping: testM[0],
- Line: []profile.Line{
- {
- Function: testF[1],
- Line: 4,
- },
- },
- },
- {
- ID: 3,
- Mapping: testM[0],
- Line: []profile.Line{
- {
- Function: testF[2],
- Line: 10,
- },
- },
- },
- {
- ID: 4,
- Mapping: testM[0],
- Line: []profile.Line{
- {
- Function: testF[3],
- Line: 2,
- },
- },
- },
- {
- ID: 5,
- Mapping: testM[0],
- Line: []profile.Line{
- {
- Function: testF[3],
- Line: 8,
- },
- },
- },
- }
-
- var testProfile = &profile.Profile{
- PeriodType: &profile.ValueType{Type: "cpu", Unit: "millisecond"},
- Period: 10,
- DurationNanos: 10e9,
- SampleType: []*profile.ValueType{
- {Type: "samples", Unit: "count"},
- {Type: "cpu", Unit: "cycles"},
- },
- Sample: []*profile.Sample{
- {
- Location: []*profile.Location{testL[0]},
- Value: []int64{1, 1},
- },
- {
- Location: []*profile.Location{testL[2], testL[1], testL[0]},
- Value: []int64{1, 10},
- },
- {
- Location: []*profile.Location{testL[4], testL[2], testL[0]},
- Value: []int64{1, 100},
- },
- {
- Location: []*profile.Location{testL[3], testL[0]},
- Value: []int64{1, 1000},
- },
- {
- Location: []*profile.Location{testL[4], testL[3], testL[0]},
- Value: []int64{1, 10000},
- },
- },
- Location: testL,
- Function: testF,
- Mapping: testM,
- }
-
- func TestDisambiguation(t *testing.T) {
- parent1 := &graph.Node{Info: graph.NodeInfo{Name: "parent1"}}
- parent2 := &graph.Node{Info: graph.NodeInfo{Name: "parent2"}}
- child1 := &graph.Node{Info: graph.NodeInfo{Name: "child"}, Function: parent1}
- child2 := &graph.Node{Info: graph.NodeInfo{Name: "child"}, Function: parent2}
- child3 := &graph.Node{Info: graph.NodeInfo{Name: "child"}, Function: parent1}
- sibling := &graph.Node{Info: graph.NodeInfo{Name: "sibling"}, Function: parent1}
-
- n := []*graph.Node{parent1, parent2, child1, child2, child3, sibling}
-
- wanted := map[*graph.Node]string{
- parent1: "parent1",
- parent2: "parent2",
- child1: "child [1/2]",
- child2: "child [2/2]",
- child3: "child [1/2]",
- sibling: "sibling",
- }
-
- g := &graph.Graph{n}
-
- names := getDisambiguatedNames(g)
-
- for node, want := range wanted {
- if got := names[node]; got != want {
- t.Errorf("name %s, got %s, want %s", node.Info.Name, got, want)
- }
- }
- }
|