@@ -4,8 +4,10 @@ import (
44 "testing"
55
66 "github.com/stretchr/testify/assert"
7+ "github.com/stretchr/testify/require"
78
89 profilev1 "github.com/grafana/pyroscope/api/gen/proto/go/google/v1"
10+ typesv1 "github.com/grafana/pyroscope/api/gen/proto/go/types/v1"
911)
1012
1113func Test_extractMappingFilename (t * testing.T ) {
@@ -97,3 +99,263 @@ func Test_symbolsPartitionKeyForProfile(t *testing.T) {
9799 })
98100 }
99101}
102+
103+ func Test_ParseProfileTypeSelector (t * testing.T ) {
104+ tests := []struct {
105+ Name string
106+ ID string
107+ Want * typesv1.ProfileType
108+ WantErr string
109+ }{
110+ {
111+ Name : "block_contentions_count" ,
112+ ID : "block:contentions:count:contentions:count" ,
113+ Want : & typesv1.ProfileType {
114+ Name : "block" ,
115+ ID : "block:contentions:count:contentions:count" ,
116+ SampleType : "contentions" ,
117+ SampleUnit : "count" ,
118+ PeriodType : "contentions" ,
119+ PeriodUnit : "count" ,
120+ },
121+ },
122+ {
123+ Name : "mutex_delay_nanoseconds" ,
124+ ID : "mutex:delay:nanoseconds:contentions:count" ,
125+ Want : & typesv1.ProfileType {
126+ Name : "mutex" ,
127+ ID : "mutex:delay:nanoseconds:contentions:count" ,
128+ SampleType : "delay" ,
129+ SampleUnit : "nanoseconds" ,
130+ PeriodType : "contentions" ,
131+ PeriodUnit : "count" ,
132+ },
133+ },
134+ {
135+ Name : "memory_alloc_space_bytes" ,
136+ ID : "memory:alloc_space:bytes:space:bytes" ,
137+ Want : & typesv1.ProfileType {
138+ Name : "memory" ,
139+ ID : "memory:alloc_space:bytes:space:bytes" ,
140+ SampleType : "alloc_space" ,
141+ SampleUnit : "bytes" ,
142+ PeriodType : "space" ,
143+ PeriodUnit : "bytes" ,
144+ },
145+ },
146+ {
147+ Name : "too_few_parts" ,
148+ ID : "memory:alloc_space:bytes:space" ,
149+ WantErr : `profile-type selection must be of the form <name>:<sample-type>:<sample-unit>:<period-type>:<period-unit>(:delta), got(4): "memory:alloc_space:bytes:space"` ,
150+ },
151+ {
152+ Name : "too_many_parts" ,
153+ ID : "memory:alloc_space:bytes:space:bytes:extra:part" ,
154+ WantErr : `profile-type selection must be of the form <name>:<sample-type>:<sample-unit>:<period-type>:<period-unit>(:delta), got(7): "memory:alloc_space:bytes:space:bytes:extra:part"` ,
155+ },
156+ {
157+ Name : "empty_string" ,
158+ ID : "" ,
159+ WantErr : `profile-type selection must be of the form <name>:<sample-type>:<sample-unit>:<period-type>:<period-unit>(:delta), got(1): ""` ,
160+ },
161+ {
162+ Name : "valid_with_delta" ,
163+ ID : "cpu:samples:count:cpu:nanoseconds:delta" ,
164+ Want : & typesv1.ProfileType {
165+ Name : "cpu" ,
166+ ID : "cpu:samples:count:cpu:nanoseconds:delta" ,
167+ SampleType : "samples" ,
168+ SampleUnit : "count" ,
169+ PeriodType : "cpu" ,
170+ PeriodUnit : "nanoseconds" ,
171+ },
172+ },
173+ }
174+
175+ for _ , tt := range tests {
176+ t .Run (tt .Name , func (t * testing.T ) {
177+ got , err := ParseProfileTypeSelector (tt .ID )
178+ if tt .WantErr != "" {
179+ require .Error (t , err )
180+ require .EqualError (t , err , tt .WantErr )
181+ } else {
182+ require .NoError (t , err )
183+ require .Equal (t , tt .Want , got )
184+ }
185+ })
186+ }
187+ }
188+
189+ func Test_ParseProfileTypeSelector_ValidProfileTypes (t * testing.T ) {
190+ // Shamelessly copied from: https://github.com/grafana/profiles-drilldown/blob/4e261a8744034bddefdec757d5d2e1d8dc0ec2bb/src/shared/infrastructure/profile-metrics/profile-metrics.json#L93
191+ var validProfileTypes = map [string ]* typesv1.ProfileType {
192+ "block:contentions:count:contentions:count" : {
193+ ID : "block:contentions:count:contentions:count" ,
194+ Name : "block" ,
195+ SampleType : "contentions" ,
196+ SampleUnit : "count" ,
197+ PeriodType : "contentions" ,
198+ PeriodUnit : "count" ,
199+ },
200+ "block:delay:nanoseconds:contentions:count" : {
201+ ID : "block:delay:nanoseconds:contentions:count" ,
202+ Name : "block" ,
203+ SampleType : "delay" ,
204+ SampleUnit : "nanoseconds" ,
205+ PeriodType : "contentions" ,
206+ PeriodUnit : "count" ,
207+ },
208+ "goroutine:goroutine:count:goroutine:count" : {
209+ ID : "goroutine:goroutine:count:goroutine:count" ,
210+ Name : "goroutine" ,
211+ SampleType : "goroutine" ,
212+ SampleUnit : "count" ,
213+ PeriodType : "goroutine" ,
214+ PeriodUnit : "count" ,
215+ },
216+ "goroutines:goroutine:count:goroutine:count" : {
217+ ID : "goroutines:goroutine:count:goroutine:count" ,
218+ Name : "goroutines" ,
219+ SampleType : "goroutine" ,
220+ SampleUnit : "count" ,
221+ PeriodType : "goroutine" ,
222+ PeriodUnit : "count" ,
223+ },
224+ "memory:alloc_in_new_tlab_bytes:bytes::" : {
225+ ID : "memory:alloc_in_new_tlab_bytes:bytes::" ,
226+ Name : "memory" ,
227+ SampleType : "alloc_in_new_tlab_bytes" ,
228+ SampleUnit : "bytes" ,
229+ PeriodType : "" ,
230+ PeriodUnit : "" ,
231+ },
232+ "memory:alloc_in_new_tlab_objects:count::" : {
233+ ID : "memory:alloc_in_new_tlab_objects:count::" ,
234+ Name : "memory" ,
235+ SampleType : "alloc_in_new_tlab_objects" ,
236+ SampleUnit : "count" ,
237+ PeriodType : "" ,
238+ PeriodUnit : "" ,
239+ },
240+ "memory:alloc_objects:count:space:bytes" : {
241+ ID : "memory:alloc_objects:count:space:bytes" ,
242+ Name : "memory" ,
243+ SampleType : "alloc_objects" ,
244+ SampleUnit : "count" ,
245+ PeriodType : "space" ,
246+ PeriodUnit : "bytes" ,
247+ },
248+ "memory:alloc_space:bytes:space:bytes" : {
249+ ID : "memory:alloc_space:bytes:space:bytes" ,
250+ Name : "memory" ,
251+ SampleType : "alloc_space" ,
252+ SampleUnit : "bytes" ,
253+ PeriodType : "space" ,
254+ PeriodUnit : "bytes" ,
255+ },
256+ "memory:inuse_objects:count:space:bytes" : {
257+ ID : "memory:inuse_objects:count:space:bytes" ,
258+ Name : "memory" ,
259+ SampleType : "inuse_objects" ,
260+ SampleUnit : "count" ,
261+ PeriodType : "space" ,
262+ PeriodUnit : "bytes" ,
263+ },
264+ "memory:inuse_space:bytes:space:bytes" : {
265+ ID : "memory:inuse_space:bytes:space:bytes" ,
266+ Name : "memory" ,
267+ SampleType : "inuse_space" ,
268+ SampleUnit : "bytes" ,
269+ PeriodType : "space" ,
270+ PeriodUnit : "bytes" ,
271+ },
272+ "mutex:contentions:count:contentions:count" : {
273+ ID : "mutex:contentions:count:contentions:count" ,
274+ Name : "mutex" ,
275+ SampleType : "contentions" ,
276+ SampleUnit : "count" ,
277+ PeriodType : "contentions" ,
278+ PeriodUnit : "count" ,
279+ },
280+ "mutex:delay:nanoseconds:contentions:count" : {
281+ ID : "mutex:delay:nanoseconds:contentions:count" ,
282+ Name : "mutex" ,
283+ SampleType : "delay" ,
284+ SampleUnit : "nanoseconds" ,
285+ PeriodType : "contentions" ,
286+ PeriodUnit : "count" ,
287+ },
288+ "process_cpu:alloc_samples:count:cpu:nanoseconds" : {
289+ ID : "process_cpu:alloc_samples:count:cpu:nanoseconds" ,
290+ Name : "process_cpu" ,
291+ SampleType : "alloc_samples" ,
292+ SampleUnit : "count" ,
293+ PeriodType : "cpu" ,
294+ PeriodUnit : "nanoseconds" ,
295+ },
296+ "process_cpu:alloc_size:bytes:cpu:nanoseconds" : {
297+ ID : "process_cpu:alloc_size:bytes:cpu:nanoseconds" ,
298+ Name : "process_cpu" ,
299+ SampleType : "alloc_size" ,
300+ SampleUnit : "bytes" ,
301+ PeriodType : "cpu" ,
302+ PeriodUnit : "nanoseconds" ,
303+ },
304+ "process_cpu:cpu:nanoseconds:cpu:nanoseconds" : {
305+ ID : "process_cpu:cpu:nanoseconds:cpu:nanoseconds" ,
306+ Name : "process_cpu" ,
307+ SampleType : "cpu" ,
308+ SampleUnit : "nanoseconds" ,
309+ PeriodType : "cpu" ,
310+ PeriodUnit : "nanoseconds" ,
311+ },
312+ "process_cpu:exception:count:cpu:nanoseconds" : {
313+ ID : "process_cpu:exception:count:cpu:nanoseconds" ,
314+ Name : "process_cpu" ,
315+ SampleType : "exception" ,
316+ SampleUnit : "count" ,
317+ PeriodType : "cpu" ,
318+ PeriodUnit : "nanoseconds" ,
319+ },
320+ "process_cpu:lock_count:count:cpu:nanoseconds" : {
321+ ID : "process_cpu:lock_count:count:cpu:nanoseconds" ,
322+ Name : "process_cpu" ,
323+ SampleType : "lock_count" ,
324+ SampleUnit : "count" ,
325+ PeriodType : "cpu" ,
326+ PeriodUnit : "nanoseconds" ,
327+ },
328+ "process_cpu:lock_time:nanoseconds:cpu:nanoseconds" : {
329+ ID : "process_cpu:lock_time:nanoseconds:cpu:nanoseconds" ,
330+ Name : "process_cpu" ,
331+ SampleType : "lock_time" ,
332+ SampleUnit : "nanoseconds" ,
333+ PeriodType : "cpu" ,
334+ PeriodUnit : "nanoseconds" ,
335+ },
336+ "process_cpu:samples:count::milliseconds" : {
337+ ID : "process_cpu:samples:count::milliseconds" ,
338+ Name : "process_cpu" ,
339+ SampleType : "samples" ,
340+ SampleUnit : "count" ,
341+ PeriodType : "" ,
342+ PeriodUnit : "milliseconds" ,
343+ },
344+ "process_cpu:samples:count:cpu:nanoseconds" : {
345+ ID : "process_cpu:samples:count:cpu:nanoseconds" ,
346+ Name : "process_cpu" ,
347+ SampleType : "samples" ,
348+ SampleUnit : "count" ,
349+ PeriodType : "cpu" ,
350+ PeriodUnit : "nanoseconds" ,
351+ },
352+ }
353+
354+ for id , want := range validProfileTypes {
355+ t .Run (id , func (t * testing.T ) {
356+ got , err := ParseProfileTypeSelector (id )
357+ require .NoError (t , err )
358+ require .Equal (t , want , got )
359+ })
360+ }
361+ }
0 commit comments