github.com/alibaba/ilogtail/pkg@v0.0.0-20250526110833-c53b480d046c/protocol/converter/converter_sls_metric_test.go (about) 1 // Copyright 2022 iLogtail Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package protocol 16 17 import ( 18 "strconv" 19 "testing" 20 "time" 21 22 "github.com/stretchr/testify/assert" 23 24 "github.com/alibaba/ilogtail/pkg/protocol" 25 ) 26 27 func Test_newMetricReader(t *testing.T) { 28 tests := []struct { 29 log *protocol.Log 30 wantReader *metricReader 31 wantErr bool 32 }{ 33 { 34 log: &protocol.Log{ 35 Contents: []*protocol.Log_Content{ 36 {Key: metricNameKey, Value: "name"}, 37 {Key: metricLabelsKey, Value: "aaa#$#bbb"}, 38 {Key: metricValueKey, Value: "1"}, 39 {Key: metricTimeNanoKey, Value: "12344"}, 40 }, 41 }, 42 wantReader: &metricReader{ 43 name: "name", 44 labels: "aaa#$#bbb", 45 value: "1", 46 timestamp: "12344", 47 }, 48 }, 49 { 50 log: &protocol.Log{ 51 Contents: []*protocol.Log_Content{ 52 {Key: metricNameKey, Value: ""}, 53 {Key: metricLabelsKey, Value: "aaa#$#bbb"}, 54 {Key: metricValueKey, Value: "1"}, 55 {Key: metricTimeNanoKey, Value: "12344"}, 56 }, 57 }, 58 wantErr: true, 59 }, 60 { 61 log: &protocol.Log{ 62 Contents: []*protocol.Log_Content{ 63 {Key: metricNameKey, Value: "name"}, 64 {Key: metricLabelsKey, Value: "aaa#$#bbb"}, 65 {Key: metricValueKey, Value: ""}, 66 {Key: metricTimeNanoKey, Value: "12344"}, 67 }, 68 }, 69 wantErr: true, 70 }, 71 } 72 73 for _, test := range tests { 74 reader := newMetricReader() 75 err := reader.set(test.log) 76 if test.wantErr { 77 assert.NotNil(t, err) 78 continue 79 } 80 assert.Nil(t, err) 81 assert.Equal(t, test.wantReader, reader) 82 } 83 } 84 85 func Test_metricReader_readNames(t *testing.T) { 86 tests := []struct { 87 reader *metricReader 88 wantMetricName string 89 wantFieldName string 90 }{ 91 { 92 reader: &metricReader{ 93 name: "aa", 94 }, 95 wantMetricName: "aa", 96 wantFieldName: "value", 97 }, 98 { 99 reader: &metricReader{ 100 name: "aa:bb", 101 }, 102 wantMetricName: "aa:bb", 103 wantFieldName: "value", 104 }, 105 { 106 reader: &metricReader{ 107 name: "aa:bb", 108 fieldName: "bb", 109 }, 110 wantMetricName: "aa", 111 wantFieldName: "bb", 112 }, 113 { 114 reader: &metricReader{ 115 name: ":", 116 }, 117 wantMetricName: ":", 118 wantFieldName: "value", 119 }, 120 { 121 reader: &metricReader{ 122 name: "aa:value", 123 fieldName: "value", 124 }, 125 wantMetricName: "aa:value", 126 wantFieldName: "value", 127 }, 128 } 129 130 for _, test := range tests { 131 metricName, fieldName := test.reader.readNames() 132 assert.Equal(t, test.wantMetricName, metricName) 133 assert.Equal(t, test.wantFieldName, fieldName) 134 } 135 } 136 137 func Test_metricReader_readSortedLabels(t *testing.T) { 138 tests := []struct { 139 reader *metricReader 140 wantLabels []MetricLabel 141 wantErr bool 142 }{ 143 { 144 reader: &metricReader{ 145 labels: "bb#$#aa|aa#$#bb", 146 }, 147 wantLabels: []MetricLabel{ 148 {Key: "aa", Value: "bb"}, 149 {Key: "bb", Value: "aa"}, 150 }, 151 }, 152 { 153 reader: &metricReader{ 154 labels: "bb#$#aa", 155 }, 156 wantLabels: []MetricLabel{ 157 {Key: "bb", Value: "aa"}, 158 }, 159 }, 160 { 161 reader: &metricReader{ 162 labels: "bb#$#aa|aa#$#", 163 }, 164 wantLabels: []MetricLabel{ 165 {Key: "aa", Value: ""}, 166 {Key: "bb", Value: "aa"}, 167 }, 168 }, 169 { 170 reader: &metricReader{ 171 labels: "", 172 }, 173 wantLabels: nil, 174 }, 175 { 176 reader: &metricReader{ 177 labels: "bb#$#aa|aa#$#bb|", 178 }, 179 wantLabels: []MetricLabel{ 180 {Key: "aa", Value: "bb"}, 181 {Key: "bb", Value: "aa"}, 182 }, 183 }, 184 { 185 reader: &metricReader{ 186 labels: "bb", 187 }, 188 wantErr: true, 189 }, 190 { 191 reader: &metricReader{ 192 labels: "bb#$#aa|eee", 193 }, 194 wantLabels: []MetricLabel{ 195 {Key: "bb", Value: "aa|eee"}, 196 }, 197 }, 198 { 199 reader: &metricReader{ 200 labels: "bb#$#aa|eee|aa#$#bb", 201 }, 202 wantLabels: []MetricLabel{ 203 {Key: "aa", Value: "bb"}, 204 {Key: "bb", Value: "aa|eee"}, 205 }, 206 }, 207 { 208 reader: &metricReader{ 209 labels: "bb#$#aa||eee||aa#$#bb", 210 }, 211 wantLabels: []MetricLabel{ 212 {Key: "aa", Value: "bb"}, 213 {Key: "bb", Value: "aa||eee|"}, 214 }, 215 }, 216 { 217 reader: &metricReader{ 218 labels: "cc||bb#$#aa||eee||aa#$#bb", 219 }, 220 wantLabels: []MetricLabel{ 221 {Key: "aa", Value: "bb"}, 222 {Key: "cc||bb", Value: "aa||eee|"}, 223 }, 224 }, 225 } 226 227 for _, test := range tests { 228 labels, err := test.reader.readSortedLabels() 229 if test.wantErr { 230 assert.NotNilf(t, err, "reader", *test.reader) 231 continue 232 } 233 assert.Nil(t, err) 234 assert.Equal(t, test.wantLabels, labels) 235 } 236 } 237 238 func Test_metricReader_countLabels(t *testing.T) { 239 tests := []struct { 240 reader *metricReader 241 wantCount int 242 }{ 243 { 244 reader: &metricReader{ 245 labels: "aa#$#bb", 246 }, 247 wantCount: 1, 248 }, 249 { 250 reader: &metricReader{ 251 labels: "", 252 }, 253 wantCount: 0, 254 }, 255 { 256 reader: &metricReader{ 257 labels: "aa#$#bb|bb#$#cc", 258 }, 259 wantCount: 2, 260 }, 261 } 262 263 for _, test := range tests { 264 n := test.reader.countLabels() 265 assert.Equal(t, test.wantCount, n) 266 } 267 } 268 269 func Test_metricReader_readValue(t *testing.T) { 270 tests := []struct { 271 reader *metricReader 272 wantValue interface{} 273 wantErr bool 274 }{ 275 { 276 reader: &metricReader{ 277 value: "1", 278 valueType: valueTypeBool, 279 }, 280 wantValue: true, 281 }, 282 { 283 reader: &metricReader{ 284 value: "1", 285 valueType: valueTypeInt, 286 }, 287 wantValue: int64(1), 288 }, 289 { 290 reader: &metricReader{ 291 value: "1.1", 292 valueType: valueTypeFloat, 293 }, 294 wantValue: float64(1.1), 295 }, 296 { 297 reader: &metricReader{ 298 value: "", 299 }, 300 wantErr: true, 301 }, 302 { 303 reader: &metricReader{ 304 value: "aaa", 305 valueType: valueTypeString, 306 }, 307 wantValue: "aaa", 308 }, 309 } 310 311 for _, test := range tests { 312 value, err := test.reader.readValue() 313 if test.wantErr { 314 assert.NotNil(t, err) 315 continue 316 } 317 assert.Equal(t, test.wantValue, value) 318 } 319 } 320 321 func Test_metricReader_readTimestamp(t *testing.T) { 322 tests := []struct { 323 reader *metricReader 324 wantTime time.Time 325 wantErr bool 326 }{ 327 { 328 reader: &metricReader{ 329 timestamp: strconv.FormatInt(time.Date(2022, 01, 01, 01, 01, 01, 01, time.UTC).UnixNano(), 10), 330 }, 331 wantTime: time.Date(2022, 01, 01, 01, 01, 01, 01, time.UTC), 332 }, 333 { 334 reader: &metricReader{ 335 timestamp: "", 336 }, 337 wantTime: time.Time{}, 338 }, 339 { 340 reader: &metricReader{ 341 timestamp: "abc", 342 }, 343 wantErr: true, 344 }, 345 } 346 347 for _, test := range tests { 348 timestamp, err := test.reader.readTimestamp() 349 if test.wantErr { 350 assert.NotNil(t, err) 351 continue 352 } 353 assert.Nil(t, err) 354 assert.Equal(t, test.wantTime, timestamp) 355 } 356 } 357 358 func Test_metricReader_set(t *testing.T) { 359 tests := []struct { 360 log *protocol.Log 361 wantErr bool 362 wantReader metricReader 363 }{ 364 { 365 log: &protocol.Log{Contents: []*protocol.Log_Content{ 366 {Key: metricNameKey, Value: "_metric"}, 367 {Key: metricFieldKey, Value: "value"}, 368 {Key: metricValueTypeKey, Value: "float"}, 369 {Key: metricValueKey, Value: "1"}, 370 }}, 371 wantErr: false, 372 wantReader: metricReader{ 373 name: "_metric", 374 value: "1", 375 valueType: "float", 376 fieldName: "value", 377 }, 378 }, 379 { 380 log: &protocol.Log{Contents: []*protocol.Log_Content{ 381 {Key: metricNameKey, Value: "_metric"}, 382 {Key: metricFieldKey, Value: "value"}, 383 {Key: metricValueTypeKey, Value: "string"}, 384 {Key: metricValueKey, Value: ""}, 385 }}, 386 wantErr: false, 387 wantReader: metricReader{ 388 name: "_metric", 389 value: "", 390 valueType: "string", 391 fieldName: "value", 392 }, 393 }, 394 { 395 log: &protocol.Log{Contents: []*protocol.Log_Content{ 396 {Key: metricNameKey, Value: "_metric"}, 397 {Key: metricFieldKey, Value: "value"}, 398 {Key: metricValueTypeKey, Value: "float"}, 399 {Key: metricValueKey, Value: ""}, 400 }}, 401 wantErr: true, 402 }, 403 } 404 405 for _, test := range tests { 406 reader := metricReader{} 407 err := reader.set(test.log) 408 if test.wantErr { 409 assert.NotNil(t, err) 410 continue 411 } 412 assert.Nil(t, err) 413 assert.Equal(t, test.wantReader, reader) 414 } 415 }