github.com/grafana/pyroscope@v1.18.0/pkg/phlaredb/symdb/locations_test.go (about)

     1  package symdb
     2  
     3  import (
     4  	"bytes"
     5  	"math"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/require"
     9  
    10  	v1 "github.com/grafana/pyroscope/pkg/phlaredb/schemas/v1"
    11  )
    12  
    13  func Test_LocationsEncoding(t *testing.T) {
    14  	type testCase struct {
    15  		description string
    16  		locs        []v1.InMemoryLocation
    17  	}
    18  
    19  	testCases := []testCase{
    20  		{
    21  			description: "empty",
    22  			locs:        []v1.InMemoryLocation{},
    23  		},
    24  		{
    25  			description: "zero",
    26  			locs:        []v1.InMemoryLocation{{Line: []v1.InMemoryLine{}}},
    27  		},
    28  		{
    29  			description: "single location",
    30  			locs: []v1.InMemoryLocation{
    31  				{
    32  					Address:   math.MaxUint64,
    33  					MappingId: 1,
    34  					IsFolded:  false,
    35  					Line: []v1.InMemoryLine{
    36  						{FunctionId: 1, Line: 1},
    37  					},
    38  				},
    39  			},
    40  		},
    41  		{
    42  			description: "multiline locations",
    43  			locs: []v1.InMemoryLocation{
    44  				{
    45  					Line: []v1.InMemoryLine{
    46  						{FunctionId: 1, Line: 1},
    47  					},
    48  				},
    49  				{
    50  					Line: []v1.InMemoryLine{
    51  						{FunctionId: 1, Line: 1},
    52  						{FunctionId: 2, Line: 1},
    53  					},
    54  				},
    55  				{
    56  					Line: []v1.InMemoryLine{
    57  						{FunctionId: 1, Line: 1},
    58  						{FunctionId: 2, Line: 1},
    59  						{FunctionId: 3, Line: 1},
    60  					},
    61  				},
    62  			},
    63  		},
    64  		{
    65  			description: "optional fields mix",
    66  			locs: []v1.InMemoryLocation{
    67  				{Line: []v1.InMemoryLine{{FunctionId: 1, Line: 1}}},
    68  				{Line: []v1.InMemoryLine{{FunctionId: 1, Line: 1}}},
    69  				{
    70  					Address:   math.MaxUint64,
    71  					MappingId: 1,
    72  					IsFolded:  true,
    73  					Line:      []v1.InMemoryLine{{FunctionId: 1, Line: 1}},
    74  				},
    75  				{Line: []v1.InMemoryLine{{FunctionId: 1, Line: 1}}},
    76  			},
    77  		},
    78  		{
    79  			description: "optional fields mix split",
    80  			locs: []v1.InMemoryLocation{
    81  				{Line: []v1.InMemoryLine{{FunctionId: 1, Line: 1}}},
    82  				{Line: []v1.InMemoryLine{{FunctionId: 1, Line: 1}}},
    83  				{Line: []v1.InMemoryLine{{FunctionId: 1, Line: 1}}},
    84  				{
    85  					Address:   math.MaxUint64,
    86  					MappingId: 1,
    87  					IsFolded:  true,
    88  					Line:      []v1.InMemoryLine{{FunctionId: 1, Line: 1}},
    89  				},
    90  			},
    91  		},
    92  	}
    93  
    94  	for _, tc := range testCases {
    95  		tc := tc
    96  		t.Run(tc.description, func(t *testing.T) {
    97  			var buf bytes.Buffer
    98  			w := newTestFileWriter(&buf)
    99  			e := newLocationsEncoder()
   100  			e.blockSize = 3
   101  			h, err := writeSymbolsBlock(w, tc.locs, e)
   102  			require.NoError(t, err)
   103  
   104  			d, err := newLocationsDecoder(h)
   105  			require.NoError(t, err)
   106  			out := make([]v1.InMemoryLocation, h.Length)
   107  			require.NoError(t, d.decode(out, &buf))
   108  			require.Equal(t, tc.locs, out)
   109  		})
   110  	}
   111  }