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