github.com/grafana/pyroscope@v1.18.0/pkg/og/structs/flamebearer/flamebearer_test.go (about) 1 package flamebearer 2 3 import ( 4 . "github.com/onsi/ginkgo/v2" 5 . "github.com/onsi/gomega" 6 7 "github.com/grafana/pyroscope/pkg/og/storage/metadata" 8 "github.com/grafana/pyroscope/pkg/og/storage/segment" 9 "github.com/grafana/pyroscope/pkg/og/storage/tree" 10 ) 11 12 var ( 13 startTime = int64(1635508310) 14 durationDelta = int64(10) 15 samples = []uint64{1} 16 watermarks = map[int]int64{1: 1} 17 maxNodes = 1024 18 spyName = "spy-name" 19 sampleRate = uint32(10) 20 units = metadata.Units("units") 21 ) 22 23 var _ = Describe("FlamebearerProfile", func() { 24 Context("single", func() { 25 It("sets all attributes correctly", func() { 26 // taken from tree package tests 27 tree := tree.New() 28 tree.Insert([]byte("a;b"), uint64(1)) 29 tree.Insert([]byte("a;c"), uint64(2)) 30 31 timeline := &segment.Timeline{ 32 StartTime: startTime, 33 Samples: samples, 34 DurationDeltaNormalized: durationDelta, 35 Watermarks: watermarks, 36 } 37 38 p := NewProfile(ProfileConfig{ 39 Name: "name", 40 Tree: tree, 41 MaxNodes: maxNodes, 42 Timeline: timeline, 43 Metadata: metadata.Metadata{ 44 SpyName: spyName, 45 SampleRate: sampleRate, 46 Units: units, 47 }, 48 }) 49 50 // Flamebearer 51 Expect(p.Flamebearer.Names).To(Equal([]string{"total", "a", "c", "b"})) 52 Expect(p.Flamebearer.Levels).To(Equal([][]int{ 53 {0, 3, 0, 0}, 54 {0, 3, 0, 1}, 55 {0, 1, 1, 3, 0, 2, 2, 2}, 56 })) 57 Expect(p.Flamebearer.NumTicks).To(Equal(3)) 58 Expect(p.Flamebearer.MaxSelf).To(Equal(2)) 59 60 // Metadata 61 Expect(p.Metadata.Name).To(Equal("name")) 62 Expect(p.Metadata.Format).To(Equal("single")) 63 Expect(p.Metadata.SpyName).To(Equal(spyName)) 64 Expect(p.Metadata.SampleRate).To(Equal(sampleRate)) 65 Expect(p.Metadata.Units).To(Equal(units)) 66 67 // Timeline 68 Expect(p.Timeline.StartTime).To(Equal(startTime)) 69 Expect(p.Timeline.Samples).To(Equal(samples)) 70 Expect(p.Timeline.DurationDelta).To(Equal(durationDelta)) 71 Expect(p.Timeline.Watermarks).To(Equal(watermarks)) 72 73 // Ticks 74 Expect(p.LeftTicks).To(BeZero()) 75 Expect(p.RightTicks).To(BeZero()) 76 77 // Validate 78 Expect(p.Validate()).To(BeNil()) 79 }) 80 }) 81 }) 82 83 var _ = Describe("Checking profile validation", func() { 84 When("the version is invalid", func() { 85 var fb FlamebearerProfile 86 BeforeEach(func() { 87 fb.Version = 2 88 }) 89 90 Context("and we validate the profile", func() { 91 It("returns an error", func() { 92 Expect(fb.Validate()).To(MatchError("unsupported version 2")) 93 }) 94 }) 95 }) 96 97 When("the format is unsupported", func() { 98 var fb FlamebearerProfile 99 100 Context("and we validate the profile", func() { 101 It("returns an error", func() { 102 Expect(fb.Validate()).To(MatchError("unsupported format ")) 103 }) 104 }) 105 }) 106 107 When("there are no names", func() { 108 var fb FlamebearerProfile 109 BeforeEach(func() { 110 fb.Metadata.Format = "single" 111 }) 112 113 Context("and we validate the profile", func() { 114 It("returns an error", func() { 115 Expect(fb.Validate()).To(MatchError("a profile must have at least one symbol name")) 116 }) 117 }) 118 }) 119 120 When("there are no levels", func() { 121 var fb FlamebearerProfile 122 BeforeEach(func() { 123 fb.Metadata.Format = "single" 124 fb.Flamebearer.Names = []string{"name"} 125 }) 126 127 Context("and we validate the profile", func() { 128 It("returns an error", func() { 129 Expect(fb.Validate()).To(MatchError("a profile must have at least one profiling level")) 130 }) 131 }) 132 }) 133 134 When("the level size is invalid for the profile format", func() { 135 Context("and we validate a single profile", func() { 136 var fb FlamebearerProfile 137 BeforeEach(func() { 138 fb.Metadata.Format = "single" 139 fb.Flamebearer.Names = []string{"name"} 140 fb.Flamebearer.Levels = [][]int{{0, 0, 0, 0, 0, 0, 0}} 141 }) 142 143 It("returns an error", func() { 144 Expect(fb.Validate()).To(MatchError("a profile level should have a multiple of 4 values, but there's a level with 7 values")) 145 }) 146 }) 147 148 Context("and we validate a double profile", func() { 149 var fb FlamebearerProfile 150 BeforeEach(func() { 151 fb.Metadata.Format = "double" 152 fb.Flamebearer.Names = []string{"name"} 153 fb.Flamebearer.Levels = [][]int{{0, 0, 0, 0}} 154 }) 155 156 It("returns an error", func() { 157 Expect(fb.Validate()).To(MatchError("a profile level should have a multiple of 7 values, but there's a level with 4 values")) 158 }) 159 }) 160 }) 161 162 When("the name index is invalid", func() { 163 Context("and we validate a single profile", func() { 164 var fb FlamebearerProfile 165 BeforeEach(func() { 166 fb.Metadata.Format = "single" 167 fb.Flamebearer.Names = []string{"name"} 168 fb.Flamebearer.Levels = [][]int{{0, 0, 0, 1}} 169 }) 170 171 It("returns an error", func() { 172 Expect(fb.Validate()).To(MatchError("invalid name index 1, it should be smaller than 1")) 173 }) 174 }) 175 176 Context("and we validate a double profile", func() { 177 var fb FlamebearerProfile 178 BeforeEach(func() { 179 fb.Metadata.Format = "double" 180 fb.Flamebearer.Names = []string{"name"} 181 fb.Flamebearer.Levels = [][]int{{0, 0, 0, 0, 0, 0, 1}} 182 }) 183 184 It("returns an error", func() { 185 Expect(fb.Validate()).To(MatchError("invalid name index 1, it should be smaller than 1")) 186 }) 187 }) 188 }) 189 190 When("the name index is negative", func() { 191 Context("and we validate a single profile", func() { 192 var fb FlamebearerProfile 193 BeforeEach(func() { 194 fb.Metadata.Format = "single" 195 fb.Flamebearer.Names = []string{"name"} 196 fb.Flamebearer.Levels = [][]int{{0, 0, 0, -1}} 197 }) 198 199 It("returns an error", func() { 200 Expect(fb.Validate()).To(MatchError("invalid name index -1, it should be a non-negative value")) 201 }) 202 }) 203 }) 204 205 When("everything is valid", func() { 206 Context("and we validate a single profile", func() { 207 var fb FlamebearerProfile 208 BeforeEach(func() { 209 fb.Metadata.Format = "single" 210 fb.Flamebearer.Names = []string{"name"} 211 fb.Flamebearer.Levels = [][]int{{0, 0, 0, 0}} 212 }) 213 214 It("returns no error", func() { 215 Expect(fb.Validate()).To(BeNil()) 216 }) 217 }) 218 219 Context("and we validate a double profile", func() { 220 var fb FlamebearerProfile 221 BeforeEach(func() { 222 fb.Metadata.Format = "double" 223 fb.Flamebearer.Names = []string{"name"} 224 fb.Flamebearer.Levels = [][]int{{0, 0, 0, 0, 0, 0, 0}} 225 }) 226 227 It("returns an error", func() { 228 Expect(fb.Validate()).To(BeNil()) 229 }) 230 }) 231 }) 232 })