github.com/grafana/pyroscope@v1.18.0/pkg/test/integration/ingest_speedscope_test.go (about) 1 package integration 2 3 import ( 4 "testing" 5 6 "connectrpc.com/connect" 7 "github.com/stretchr/testify/assert" 8 "github.com/stretchr/testify/require" 9 10 profilev1 "github.com/grafana/pyroscope/api/gen/proto/go/google/v1" 11 ) 12 13 type speedscopeTestDataStruct struct { 14 name string 15 speedscopeFile string 16 expectStatus int 17 expectedMetrics []expectedMetric 18 } 19 20 const ( 21 testdataDirSpeedscope = repoRoot + "pkg/og/convert/speedscope/testdata" 22 ) 23 24 var ( 25 speedscopeTestData = []speedscopeTestDataStruct{ 26 { 27 name: "single profile evented", 28 speedscopeFile: testdataDirSpeedscope + "/simple.speedscope.json", 29 expectStatus: 200, 30 expectedMetrics: []expectedMetric{ 31 // The difference between the metric name here and in the other test is a quirk in 32 // how the speedscope parsing logic. Only multi profile uploads will 33 // append the unit to the metric name which is parsed differently downstream. 34 {"process_cpu:cpu:nanoseconds:cpu:nanoseconds", nil, 0}, 35 }, 36 }, 37 { 38 name: "multi profile sampled", 39 speedscopeFile: testdataDirSpeedscope + "/two-sampled.speedscope.json", 40 expectStatus: 200, 41 expectedMetrics: []expectedMetric{ 42 {"wall:wall:nanoseconds:cpu:nanoseconds", nil, 0}, 43 }, 44 }, 45 { 46 name: "multi profile samples bytes units", 47 speedscopeFile: testdataDirSpeedscope + "/two-sampled-bytes.speedscope.json", 48 expectStatus: 200, 49 expectedMetrics: []expectedMetric{ 50 {"memory:samples:bytes::", nil, 0}, 51 }, 52 }, 53 } 54 ) 55 56 func TestIngestSpeedscope(t *testing.T) { 57 EachPyroscopeTest(t, func(p *PyroscopeTest, t *testing.T) { 58 for _, td := range speedscopeTestData { 59 t.Run(td.name, func(t *testing.T) { 60 rb := p.NewRequestBuilder(t) 61 req := rb.IngestSpeedscopeRequest(td.speedscopeFile) 62 p.Ingest(t, req, td.expectStatus) 63 64 if td.expectStatus == 200 { 65 for _, metric := range td.expectedMetrics { 66 rb.Render(metric.name) 67 profile := rb.SelectMergeProfile(metric.name, metric.query) 68 assertSpeedscopeProfile(t, profile) 69 } 70 } 71 }) 72 } 73 }) 74 } 75 76 func assertSpeedscopeProfile(t *testing.T, resp *connect.Response[profilev1.Profile]) { 77 assert.Equal(t, 1, len(resp.Msg.SampleType), "SampleType should be set") 78 require.Greater(t, len(resp.Msg.Sample), 0, "Profile should contain samples") 79 assert.Greater(t, resp.Msg.Sample[0].Value[0], int64(0), "Sample value should be positive") 80 }