...

Source file src/github.com/google/pprof/profile/prune_test.go

Documentation: github.com/google/pprof/profile

     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  
    15  package profile
    16  
    17  import (
    18  	"strings"
    19  	"testing"
    20  )
    21  
    22  func TestPrune(t *testing.T) {
    23  	for _, test := range []struct {
    24  		in   *Profile
    25  		want string
    26  	}{
    27  		{in1, out1},
    28  		{in2, out2},
    29  	} {
    30  		in := test.in.Copy()
    31  		in.RemoveUninteresting()
    32  		if err := in.CheckValid(); err != nil {
    33  			t.Error(err)
    34  		}
    35  		w := strings.Split(test.want, "\n")
    36  		for i, g := range strings.Split(in.String(), "\n") {
    37  			if i >= len(w) {
    38  				t.Fatalf("got trailing %s", g)
    39  			}
    40  			if strings.TrimSpace(g) != strings.TrimSpace(w[i]) {
    41  				t.Fatalf(`%d: got: "%s"  want:"%s"`, i, g, w[i])
    42  			}
    43  		}
    44  	}
    45  }
    46  
    47  var funs = []*Function{
    48  	{ID: 1, Name: "main", SystemName: "main", Filename: "main.c"},
    49  	{ID: 2, Name: "fun1", SystemName: "fun1", Filename: "fun.c"},
    50  	{ID: 3, Name: "fun2", SystemName: "fun2", Filename: "fun.c"},
    51  	{ID: 4, Name: "fun3", SystemName: "fun3", Filename: "fun.c"},
    52  	{ID: 5, Name: "fun4", SystemName: "fun4", Filename: "fun.c"},
    53  	{ID: 6, Name: "fun5", SystemName: "fun5", Filename: "fun.c"},
    54  	{ID: 7, Name: "unsimplified_fun(int)", SystemName: "unsimplified_fun(int)", Filename: "fun.c"},
    55  	{ID: 8, Name: "Foo::(anonymous namespace)::Test::Bar", SystemName: "Foo::(anonymous namespace)::Test::Bar", Filename: "fun.c"},
    56  	{ID: 9, Name: "Hello::(anonymous namespace)::World(const Foo::(anonymous namespace)::Test::Bar)", SystemName: "Hello::(anonymous namespace)::World(const Foo::(anonymous namespace)::Test::Bar)", Filename: "fun.c"},
    57  	{ID: 10, Name: "Foo::operator()(::Bar)", SystemName: "Foo::operator()(::Bar)", Filename: "fun.c"},
    58  }
    59  
    60  var locs1 = []*Location{
    61  	{
    62  		ID: 1,
    63  		Line: []Line{
    64  			{Function: funs[0], Line: 1, Column: 7},
    65  		},
    66  	},
    67  	{
    68  		ID: 2,
    69  		Line: []Line{
    70  			{Function: funs[1], Line: 2},
    71  			{Function: funs[2], Line: 1},
    72  		},
    73  	},
    74  	{
    75  		ID: 3,
    76  		Line: []Line{
    77  			{Function: funs[3], Line: 2},
    78  			{Function: funs[1], Line: 1, Column: 7},
    79  		},
    80  	},
    81  	{
    82  		ID: 4,
    83  		Line: []Line{
    84  			{Function: funs[3], Line: 2},
    85  			{Function: funs[1], Line: 2},
    86  			{Function: funs[5], Line: 2},
    87  		},
    88  	},
    89  }
    90  
    91  var in1 = &Profile{
    92  	PeriodType:    &ValueType{Type: "cpu", Unit: "milliseconds"},
    93  	Period:        1,
    94  	DurationNanos: 10e9,
    95  	SampleType: []*ValueType{
    96  		{Type: "samples", Unit: "count"},
    97  		{Type: "cpu", Unit: "milliseconds"},
    98  	},
    99  	Sample: []*Sample{
   100  		{
   101  			Location: []*Location{locs1[0]},
   102  			Value:    []int64{1, 1},
   103  		},
   104  		{
   105  			Location: []*Location{locs1[1], locs1[0]},
   106  			Value:    []int64{1, 1},
   107  		},
   108  		{
   109  			Location: []*Location{locs1[2], locs1[0]},
   110  			Value:    []int64{1, 1},
   111  		},
   112  		{
   113  			Location: []*Location{locs1[3], locs1[0]},
   114  			Value:    []int64{1, 1},
   115  		},
   116  		{
   117  			Location: []*Location{locs1[3], locs1[2], locs1[1], locs1[0]},
   118  			Value:    []int64{1, 1},
   119  		},
   120  	},
   121  	Location:   locs1,
   122  	Function:   funs,
   123  	DropFrames: "fu.*[12]|banana",
   124  	KeepFrames: ".*[n2][n2]",
   125  }
   126  
   127  const out1 = `PeriodType: cpu milliseconds
   128  Period: 1
   129  Duration: 10s
   130  Samples:
   131  samples/count cpu/milliseconds
   132            1          1: 1
   133            1          1: 2 1
   134            1          1: 1
   135            1          1: 4 1
   136            1          1: 2 1
   137  Locations
   138       1: 0x0 main main.c:1:7 s=0
   139       2: 0x0 fun2 fun.c:1:0 s=0
   140       3: 0x0 fun3 fun.c:2:0 s=0
   141               fun1 fun.c:1:7 s=0
   142       4: 0x0 fun5 fun.c:2:0 s=0
   143  Mappings
   144  `
   145  
   146  var locs2 = []*Location{
   147  	{
   148  		ID: 1,
   149  		Line: []Line{
   150  			{Function: funs[0], Line: 1},
   151  		},
   152  	},
   153  	{
   154  		ID: 2,
   155  		Line: []Line{
   156  			{Function: funs[6], Line: 1},
   157  		},
   158  	},
   159  	{
   160  		ID: 3,
   161  		Line: []Line{
   162  			{Function: funs[7], Line: 1},
   163  		},
   164  	},
   165  	{
   166  		ID: 4,
   167  		Line: []Line{
   168  			{Function: funs[8], Line: 1},
   169  		},
   170  	},
   171  	{
   172  		ID: 5,
   173  		Line: []Line{
   174  			{Function: funs[9], Line: 1},
   175  		},
   176  	},
   177  }
   178  
   179  var in2 = &Profile{
   180  	PeriodType:    &ValueType{Type: "cpu", Unit: "milliseconds"},
   181  	Period:        1,
   182  	DurationNanos: 10e9,
   183  	SampleType: []*ValueType{
   184  		{Type: "samples", Unit: "count"},
   185  		{Type: "cpu", Unit: "milliseconds"},
   186  	},
   187  	Sample: []*Sample{
   188  		// Unsimplified name with parameters shouldn't match.
   189  		{
   190  			Location: []*Location{locs2[1], locs2[0]},
   191  			Value:    []int64{1, 1},
   192  		},
   193  		// .*Foo::.*::Bar.* should (and will be dropped) regardless of the anonymous namespace.
   194  		{
   195  			Location: []*Location{locs2[2], locs2[0]},
   196  			Value:    []int64{1, 1},
   197  		},
   198  		// .*Foo::.*::Bar.* shouldn't match inside the parameter list.
   199  		{
   200  			Location: []*Location{locs2[3], locs2[0]},
   201  			Value:    []int64{1, 1},
   202  		},
   203  		// .*operator\(\) should match, regardless of parameters.
   204  		{
   205  			Location: []*Location{locs2[4], locs2[0]},
   206  			Value:    []int64{1, 1},
   207  		},
   208  	},
   209  	Location:   locs2,
   210  	Function:   funs,
   211  	DropFrames: `unsimplified_fun\(int\)|.*Foo::.*::Bar.*|.*operator\(\)`,
   212  }
   213  
   214  const out2 = `PeriodType: cpu milliseconds
   215  Period: 1
   216  Duration: 10s
   217  Samples:
   218  samples/count cpu/milliseconds
   219            1          1: 2 1
   220            1          1: 1
   221            1          1: 4 1
   222            1          1: 1
   223  Locations
   224       1: 0x0 main main.c:1:0 s=0
   225       2: 0x0 unsimplified_fun(int) fun.c:1:0 s=0
   226       3: 0x0 Foo::(anonymous namespace)::Test::Bar fun.c:1:0 s=0
   227       4: 0x0 Hello::(anonymous namespace)::World(const Foo::(anonymous namespace)::Test::Bar) fun.c:1:0 s=0
   228       5: 0x0 Foo::operator()(::Bar) fun.c:1:0 s=0
   229  Mappings
   230  `
   231  

View as plain text