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 }