github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/metrics/metric/id/m3/id_test.go (about)

     1  // Copyright (c) 2017 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package m3
    22  
    23  import (
    24  	"testing"
    25  
    26  	"github.com/m3db/m3/src/metrics/metric/id"
    27  	"github.com/m3db/m3/src/x/pool"
    28  
    29  	"github.com/stretchr/testify/require"
    30  )
    31  
    32  func TestNewRollupID(t *testing.T) {
    33  	var (
    34  		name     = []byte("foo")
    35  		tagPairs = []id.TagPair{
    36  			{Name: []byte("tagName1"), Value: []byte("tagValue1")},
    37  			{Name: []byte("tagName2"), Value: []byte("tagValue2")},
    38  			{Name: []byte("tagName0"), Value: []byte("tagValue0")},
    39  		}
    40  	)
    41  	expected := []byte("m3+foo+m3_rollup=true,tagName0=tagValue0,tagName1=tagValue1,tagName2=tagValue2")
    42  	require.Equal(t, expected, NewRollupID(name, tagPairs))
    43  }
    44  
    45  func TestIsRollupIDNilIterator(t *testing.T) {
    46  	inputs := []struct {
    47  		name     []byte
    48  		tags     []byte
    49  		expected bool
    50  	}{
    51  		{name: []byte("foo"), tags: []byte("a1=b1,m3_rollup=true,a2=b2"), expected: true},
    52  		{name: []byte("foo.bar.baz"), expected: false},
    53  		{name: []byte("foo"), tags: []byte("a1=b1,a2=b2"), expected: false},
    54  	}
    55  	for _, input := range inputs {
    56  		require.Equal(t, input.expected, IsRollupID(input.name, input.tags, nil), string(input.tags))
    57  	}
    58  }
    59  
    60  func TestIsRollupIDExternalIterator(t *testing.T) {
    61  	inputs := []struct {
    62  		name     []byte
    63  		tags     []byte
    64  		expected bool
    65  	}{
    66  		{name: []byte("foo"), tags: []byte("a1=b1,m3_rollup=true,a2=b2"), expected: true},
    67  		{name: []byte("foo.bar.baz"), expected: false},
    68  		{name: []byte("foo"), tags: []byte("a1=b1,a2=b2"), expected: false},
    69  	}
    70  	p := id.NewSortedTagIteratorPool(pool.NewObjectPoolOptions())
    71  	p.Init(func() id.SortedTagIterator {
    72  		return NewPooledSortedTagIterator(nil, p)
    73  	})
    74  	for _, input := range inputs {
    75  		require.Equal(t, input.expected, IsRollupID(input.name, input.tags, p))
    76  	}
    77  }
    78  
    79  func TestMetricIDTagValue(t *testing.T) {
    80  	iterPool := id.NewSortedTagIteratorPool(nil)
    81  	iterPool.Init(func() id.SortedTagIterator {
    82  		return NewPooledSortedTagIterator(nil, iterPool)
    83  	})
    84  	inputs := []struct {
    85  		id            id.ID
    86  		tagName       []byte
    87  		expectedValue []byte
    88  		expectedFound bool
    89  	}{
    90  		{
    91  			id:            NewID([]byte("m3+foo+tagName1=tagValue1,tagName2=tagValue2"), iterPool),
    92  			tagName:       []byte("tagName1"),
    93  			expectedValue: []byte("tagValue1"),
    94  			expectedFound: true,
    95  		},
    96  		{
    97  			id:            NewID([]byte("m3+foo+tagName1=tagValue1,tagName2=tagValue2"), iterPool),
    98  			tagName:       []byte("tagName2"),
    99  			expectedValue: []byte("tagValue2"),
   100  			expectedFound: true,
   101  		},
   102  		{
   103  			id:            NewID([]byte("m3+foo+tagName1=tagValue1,tagName2=tagValue2"), iterPool),
   104  			tagName:       []byte("tagName3"),
   105  			expectedValue: nil,
   106  			expectedFound: false,
   107  		},
   108  		{
   109  			id:            NewID([]byte("illformed+tagName1=tagValue1,tagName2=tagValue2"), iterPool),
   110  			tagName:       []byte("tagName1"),
   111  			expectedValue: nil,
   112  			expectedFound: false,
   113  		},
   114  	}
   115  	for _, input := range inputs {
   116  		value, found := input.id.TagValue(input.tagName)
   117  		require.Equal(t, input.expectedValue, value)
   118  		require.Equal(t, input.expectedFound, found)
   119  	}
   120  }
   121  
   122  func TestNameAndTags(t *testing.T) {
   123  	inputs := []struct {
   124  		id           []byte
   125  		expectedName []byte
   126  		expectedTags []byte
   127  		expectedErr  error
   128  	}{
   129  		{
   130  			id:           []byte("stats.m3+foo+tagName1=tagValue1"),
   131  			expectedName: []byte("foo"),
   132  			expectedTags: []byte("tagName1=tagValue1"),
   133  			expectedErr:  nil,
   134  		},
   135  		{
   136  			id:           []byte("m3+foo+tagName1=tagValue1"),
   137  			expectedName: []byte("foo"),
   138  			expectedTags: []byte("tagName1=tagValue1"),
   139  			expectedErr:  nil,
   140  		},
   141  		{
   142  			id:           []byte("m3+foo+tagName1=tagValue1,tagName2=tagValue2"),
   143  			expectedName: []byte("foo"),
   144  			expectedTags: []byte("tagName1=tagValue1,tagName2=tagValue2"),
   145  			expectedErr:  nil,
   146  		},
   147  		{
   148  			id:           []byte("illformed"),
   149  			expectedName: nil,
   150  			expectedTags: nil,
   151  			expectedErr:  errInvalidM3Metric,
   152  		},
   153  		{
   154  			id:           []byte("m34+illformed+tagName1=tagValue1"),
   155  			expectedName: nil,
   156  			expectedTags: nil,
   157  			expectedErr:  errInvalidM3Metric,
   158  		},
   159  		{
   160  			id:           []byte("m3+illformed"),
   161  			expectedName: nil,
   162  			expectedTags: nil,
   163  			expectedErr:  errInvalidM3Metric,
   164  		},
   165  		{
   166  			id:           []byte("m3+illformed+tagName1,"),
   167  			expectedName: []byte("illformed"),
   168  			expectedTags: []byte("tagName1,"),
   169  			expectedErr:  nil,
   170  		},
   171  	}
   172  	for _, input := range inputs {
   173  		name, tags, err := NameAndTags(input.id)
   174  		require.Equal(t, input.expectedName, name)
   175  		require.Equal(t, input.expectedTags, tags)
   176  		require.Equal(t, input.expectedErr, err)
   177  	}
   178  }
   179  
   180  func TestSortedTagIterator(t *testing.T) {
   181  	inputs := []struct {
   182  		sortedTagPairs []byte
   183  		expectedPairs  []id.TagPair
   184  		expectedErr    error
   185  	}{
   186  		{
   187  			sortedTagPairs: []byte("tagName1=tagValue1"),
   188  			expectedPairs: []id.TagPair{
   189  				{Name: []byte("tagName1"), Value: []byte("tagValue1")},
   190  			},
   191  			expectedErr: nil,
   192  		},
   193  		{
   194  			sortedTagPairs: []byte("tagName1=tagValue1,tagName2=tagValue2,tagName3=tagValue3"),
   195  			expectedPairs: []id.TagPair{
   196  				{Name: []byte("tagName1"), Value: []byte("tagValue1")},
   197  				{Name: []byte("tagName2"), Value: []byte("tagValue2")},
   198  				{Name: []byte("tagName3"), Value: []byte("tagValue3")},
   199  			},
   200  			expectedErr: nil,
   201  		},
   202  		{
   203  			sortedTagPairs: []byte("tagName1"),
   204  			expectedPairs:  nil,
   205  			expectedErr:    errInvalidM3Metric,
   206  		},
   207  	}
   208  
   209  	for _, input := range inputs {
   210  		it := NewSortedTagIterator(input.sortedTagPairs)
   211  		var result []id.TagPair
   212  		for it.Next() {
   213  			name, value := it.Current()
   214  			result = append(result, id.TagPair{Name: name, Value: value})
   215  		}
   216  		require.Equal(t, input.expectedErr, it.Err())
   217  		require.Equal(t, input.expectedPairs, result)
   218  	}
   219  }