github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/pkg/storage/tree/pprof_test.go (about)

     1  package tree
     2  
     3  import (
     4  	"time"
     5  
     6  	. "github.com/onsi/ginkgo/v2/dsl/core"
     7  	. "github.com/onsi/gomega"
     8  	"google.golang.org/protobuf/proto"
     9  )
    10  
    11  var _ = Describe("tree", func() {
    12  	var tree *Tree
    13  	var profile *Profile
    14  	var fnNames []string
    15  
    16  	Describe("pprof", func() {
    17  		BeforeEach(func() {
    18  			tree = New()
    19  			tree.Insert([]byte("main;foo;1;2;3;4;5"), uint64(15))
    20  			tree.Insert([]byte("main;baz;1;2;3;4;5;6"), uint64(55))
    21  			tree.Insert([]byte("main;baz;1;2;3;4;5;6;8"), uint64(25))
    22  			tree.Insert([]byte("main;bar;1;2;3;4;5;6;8"), uint64(35))
    23  			tree.Insert([]byte("main;foo;1;2;3;4;5;6"), uint64(20))
    24  			tree.Insert([]byte("main;bar;1;2;3;4;5;6;9"), uint64(35))
    25  			tree.Insert([]byte("main;baz;1;2;3;4;5;6;7"), uint64(30))
    26  			tree.Insert([]byte("main;qux;1;2;3;4;5;6;7;8;9"), uint64(65))
    27  
    28  			profile = tree.Pprof(&PprofMetadata{
    29  				Type:      "cpu",
    30  				Unit:      "samples",
    31  				StartTime: time.Date(2021, 1, 1, 10, 0, 1, 0, time.UTC),
    32  				Duration:  time.Minute,
    33  			})
    34  			fnNames = []string{
    35  				"main",
    36  				"foo",
    37  				"bar",
    38  				"baz",
    39  				"qux",
    40  				"1",
    41  				"2",
    42  				"3",
    43  				"4",
    44  				"5",
    45  				"6",
    46  				"7",
    47  				"8",
    48  				"9",
    49  			}
    50  		})
    51  		It("Should serialize correctly", func() {
    52  			_, err := proto.Marshal(profile)
    53  			Expect(err).ToNot(HaveOccurred())
    54  		})
    55  		Describe("StringTable", func() {
    56  			It("Should build correctly", func() {
    57  				Expect(len(profile.StringTable)).To(Equal(17))
    58  				Expect(profile.StringTable).To(ConsistOf(
    59  					append(
    60  						fnNames,
    61  						"",
    62  						"cpu",
    63  						"samples",
    64  					),
    65  				))
    66  			})
    67  			It("Should have empty first element", func() {
    68  				profile = tree.Pprof(&PprofMetadata{})
    69  				Expect(profile.StringTable[0]).To(Equal(""))
    70  			})
    71  		})
    72  		Describe("Metadata", func() {
    73  			It("Should build correctly", func() {
    74  				Expect(profile.TimeNanos).To(Equal(int64(1609495201000000000)))
    75  				Expect(profile.DurationNanos).To(Equal(int64(60000000000)))
    76  				Expect(len(profile.SampleType)).To(Equal(1))
    77  				_type := profile.StringTable[profile.SampleType[0].Type]
    78  				unit := profile.StringTable[profile.SampleType[0].Unit]
    79  
    80  				Expect(_type).To(Equal("cpu"))
    81  				Expect(unit).To(Equal("samples"))
    82  			})
    83  		})
    84  		Describe("Function", func() {
    85  			It("Should build correctly", func() {
    86  				Expect(len(profile.Function)).To(Equal(14))
    87  				for _, fn := range profile.Function {
    88  					Expect(fn.Id).NotTo(BeZero())
    89  					Expect(fn.Name).NotTo(BeZero())
    90  					Expect(fn.SystemName).NotTo(BeZero())
    91  				}
    92  			})
    93  			Context("Name", func() {
    94  				It("Should have corresponding StringTable entries", func() {
    95  					var names []string
    96  					for _, fn := range profile.Function {
    97  						fnName := profile.StringTable[fn.Name]
    98  						names = append(names, fnName)
    99  					}
   100  					Expect(names).To(ConsistOf(fnNames))
   101  				})
   102  			})
   103  			Context("SystemName", func() {
   104  				It("Should have corresponding StringTable entries", func() {
   105  					var names []string
   106  					for _, fn := range profile.Function {
   107  						fnName := profile.StringTable[fn.SystemName]
   108  						names = append(names, fnName)
   109  					}
   110  					Expect(names).To(ConsistOf(fnNames))
   111  				})
   112  			})
   113  		})
   114  		Describe("Location", func() {
   115  			It("Should build correctly", func() {
   116  				Expect(len(profile.Location)).To(Equal(14))
   117  				for _, l := range profile.Location {
   118  					Expect(l.Id).NotTo(BeZero())
   119  					Expect(l.Line).NotTo(BeZero())
   120  					Expect(l.Line[0].FunctionId).NotTo(BeZero())
   121  				}
   122  			})
   123  			It("Should have corresponding functions", func() {
   124  				fnMap := make(map[uint64]*Function)
   125  				for _, fn := range profile.Function {
   126  					fnMap[fn.Id] = fn
   127  				}
   128  				for _, l := range profile.Location {
   129  					fnID := l.Line[0].FunctionId
   130  					_, ok := fnMap[fnID]
   131  					Expect(ok).To(BeTrue())
   132  				}
   133  			})
   134  		})
   135  		Describe("Sample", func() {
   136  			It("Should build correctly", func() {
   137  				Expect(len(profile.Sample)).To(Equal(8))
   138  				for _, s := range profile.Sample {
   139  					Expect(s.LocationId).NotTo(BeZero())
   140  					Expect(s.Value).NotTo(BeZero())
   141  				}
   142  			})
   143  			It("Should have corresponding locations", func() {
   144  				lMap := make(map[uint64]*Location)
   145  				for _, l := range profile.Location {
   146  					lMap[l.Id] = l
   147  				}
   148  				for _, s := range profile.Sample {
   149  					for _, l := range s.LocationId {
   150  						_, ok := lMap[l]
   151  						Expect(ok).To(BeTrue())
   152  					}
   153  				}
   154  			})
   155  		})
   156  	})
   157  })