github.com/grafana/pyroscope@v1.18.0/pkg/og/convert/speedscope/speedscope_test.go (about)

     1  package speedscope
     2  
     3  import (
     4  	"context"
     5  	"os"
     6  
     7  	. "github.com/onsi/ginkgo/v2"
     8  	. "github.com/onsi/gomega"
     9  
    10  	"github.com/grafana/pyroscope/api/model/labelset"
    11  	"github.com/grafana/pyroscope/pkg/og/ingestion"
    12  	"github.com/grafana/pyroscope/pkg/og/storage/metadata"
    13  
    14  	"github.com/grafana/pyroscope/pkg/og/storage"
    15  )
    16  
    17  type mockIngester struct{ actual []*storage.PutInput }
    18  
    19  func (m *mockIngester) Put(_ context.Context, p *storage.PutInput) error {
    20  	m.actual = append(m.actual, p)
    21  	return nil
    22  }
    23  
    24  func findInputByLabel(inputs []*storage.PutInput, normalizedLabel string) *storage.PutInput {
    25  	for _, in := range inputs {
    26  		if in.LabelSet.Normalized() == normalizedLabel {
    27  			return in
    28  		}
    29  	}
    30  	return nil
    31  }
    32  
    33  var _ = Describe("Speedscope", func() {
    34  	It("Can parse an event-format profile", func() {
    35  		data, err := os.ReadFile("testdata/simple.speedscope.json")
    36  		Expect(err).ToNot(HaveOccurred())
    37  
    38  		key, err := labelset.Parse("foo")
    39  		Expect(err).ToNot(HaveOccurred())
    40  
    41  		ingester := new(mockIngester)
    42  		profile := &RawProfile{RawData: data}
    43  
    44  		md := ingestion.Metadata{LabelSet: key, SampleRate: 100}
    45  		err = profile.Parse(context.Background(), ingester, nil, md)
    46  		Expect(err).ToNot(HaveOccurred())
    47  
    48  		Expect(ingester.actual).To(HaveLen(1))
    49  		input := ingester.actual[0]
    50  
    51  		Expect(input.Units).To(Equal(metadata.SamplesUnits))
    52  		Expect(input.LabelSet.Normalized()).To(Equal("foo{profile_name=simple.txt}"))
    53  		expectedResult := `a;b 500
    54  a;b;c 500
    55  a;b;d 400
    56  `
    57  		Expect(input.Val.String()).To(Equal(expectedResult))
    58  		Expect(input.SampleRate).To(Equal(uint32(10000)))
    59  	})
    60  
    61  	It("Can parse a sample-format profile", func() {
    62  		data, err := os.ReadFile("testdata/two-sampled.speedscope.json")
    63  		Expect(err).ToNot(HaveOccurred())
    64  
    65  		key, err := labelset.Parse("foo{x=y}")
    66  		Expect(err).ToNot(HaveOccurred())
    67  
    68  		ingester := new(mockIngester)
    69  		profile := &RawProfile{RawData: data}
    70  
    71  		md := ingestion.Metadata{LabelSet: key, SampleRate: 100}
    72  		err = profile.Parse(context.Background(), ingester, nil, md)
    73  		Expect(err).ToNot(HaveOccurred())
    74  
    75  		Expect(ingester.actual).To(HaveLen(2))
    76  
    77  		input := findInputByLabel(ingester.actual, "foo.seconds{profile_name=one,x=y}")
    78  		Expect(input).ToNot(BeNil())
    79  		Expect(input.Units).To(Equal(metadata.SamplesUnits))
    80  		Expect(input.LabelSet.Normalized()).To(Equal("foo.seconds{profile_name=one,x=y}"))
    81  		expectedResult := `a;b 500
    82  a;b;c 500
    83  a;b;d 400
    84  `
    85  		Expect(input.Val.String()).To(Equal(expectedResult))
    86  		Expect(input.SampleRate).To(Equal(uint32(100)))
    87  
    88  		input2 := findInputByLabel(ingester.actual, "foo.seconds{profile_name=two,x=y}")
    89  		Expect(input2).ToNot(BeNil())
    90  		Expect(input2.Units).To(Equal(metadata.SamplesUnits))
    91  		Expect(input2.LabelSet.Normalized()).To(Equal("foo.seconds{profile_name=two,x=y}"))
    92  		Expect(input2.Val.String()).To(Equal(expectedResult))
    93  		Expect(input2.SampleRate).To(Equal(uint32(100)))
    94  	})
    95  
    96  	It("Merges duplicate profiles", func() {
    97  		data, err := os.ReadFile("testdata/duplicates.speedscope.json")
    98  		Expect(err).ToNot(HaveOccurred())
    99  
   100  		key, err := labelset.Parse("foo{x=y}")
   101  		Expect(err).ToNot(HaveOccurred())
   102  
   103  		ingester := new(mockIngester)
   104  		profile := &RawProfile{RawData: data}
   105  
   106  		md := ingestion.Metadata{LabelSet: key, SampleRate: 100}
   107  		err = profile.Parse(context.Background(), ingester, nil, md)
   108  		Expect(err).ToNot(HaveOccurred())
   109  
   110  		// Three profiles merged in to one
   111  		Expect(ingester.actual).To(HaveLen(1))
   112  
   113  		input := ingester.actual[0]
   114  		Expect(input.Units).To(Equal(metadata.SamplesUnits))
   115  		// Note that profiles with different `endValue`s are merged
   116  		// since `endValue` not represented in pprof
   117  		Expect(input.LabelSet.Normalized()).To(Equal("foo{profile_name=one,x=y}"))
   118  		expectedResult := `a;b 1500
   119  a;b;c 1500
   120  a;b;d 1200
   121  `
   122  		Expect(input.Val.String()).To(Equal(expectedResult))
   123  		Expect(input.SampleRate).To(Equal(uint32(100)))
   124  	})
   125  })