github.com/netdata/go.d.plugin@v0.58.1/pkg/stm/stm_test.go (about) 1 // SPDX-License-Identifier: GPL-3.0-or-later 2 3 package stm_test 4 5 import ( 6 "testing" 7 8 "github.com/netdata/go.d.plugin/pkg/stm" 9 10 "github.com/netdata/go.d.plugin/pkg/metrics" 11 12 "github.com/stretchr/testify/assert" 13 ) 14 15 func TestToMap_empty(t *testing.T) { 16 s := struct{}{} 17 18 expected := map[string]int64{} 19 20 assert.EqualValuesf(t, expected, stm.ToMap(s), "value test") 21 assert.EqualValuesf(t, expected, stm.ToMap(&s), "ptr test") 22 } 23 24 func TestToMap_metrics(t *testing.T) { 25 s := struct { 26 C metrics.Counter `stm:"c"` 27 G metrics.Gauge `stm:"g,100"` 28 H metrics.Histogram `stm:"h,100"` 29 S metrics.Summary `stm:"s,200,2"` 30 }{} 31 s.C.Inc() 32 s.G.Set(3.14) 33 s.H = metrics.NewHistogram([]float64{1, 5, 10}) 34 35 s.H.Observe(3.14) 36 s.H.Observe(6.28) 37 s.H.Observe(20) 38 39 s.S = metrics.NewSummary() 40 s.S.Observe(3.14) 41 s.S.Observe(6.28) 42 43 expected := map[string]int64{ 44 "c": 1, 45 "g": 314, 46 47 "h_count": 3, 48 "h_sum": 2942, 49 "h_bucket_1": 0, 50 "h_bucket_2": 1, 51 "h_bucket_3": 2, 52 53 "s_count": 2, 54 "s_sum": 942, 55 "s_min": 314, 56 "s_max": 628, 57 "s_avg": 471, 58 } 59 60 assert.Equal(t, expected, stm.ToMap(s), "value test") 61 assert.Equal(t, expected, stm.ToMap(&s), "ptr test") 62 } 63 64 func TestToMap_int(t *testing.T) { 65 s := struct { 66 I int `stm:"int"` 67 I8 int8 `stm:"int8"` 68 I16 int16 `stm:"int16"` 69 I32 int32 `stm:"int32"` 70 I64 int64 `stm:"int64"` 71 }{ 72 I: 1, I8: 2, I16: 3, I32: 4, I64: 5, 73 } 74 75 expected := map[string]int64{ 76 "int": 1, "int8": 2, "int16": 3, "int32": 4, "int64": 5, 77 } 78 79 assert.EqualValuesf(t, expected, stm.ToMap(s), "value test") 80 assert.EqualValuesf(t, expected, stm.ToMap(&s), "ptr test") 81 } 82 83 func TestToMap_float(t *testing.T) { 84 s := struct { 85 F32 float32 `stm:"f32,100"` 86 F64 float64 `stm:"f64"` 87 }{ 88 3.14, 628, 89 } 90 91 expected := map[string]int64{ 92 "f32": 314, "f64": 628, 93 } 94 95 assert.EqualValuesf(t, expected, stm.ToMap(s), "value test") 96 assert.EqualValuesf(t, expected, stm.ToMap(&s), "ptr test") 97 } 98 99 func TestToMap_struct(t *testing.T) { 100 type pair struct { 101 Left int `stm:"left"` 102 Right int `stm:"right"` 103 } 104 s := struct { 105 I int `stm:"int"` 106 Pempty pair `stm:""` 107 Ps pair `stm:"s"` 108 Notag int 109 }{ 110 I: 1, 111 Pempty: pair{2, 3}, 112 Ps: pair{4, 5}, 113 Notag: 6, 114 } 115 116 expected := map[string]int64{ 117 "int": 1, 118 "left": 2, "right": 3, 119 "s_left": 4, "s_right": 5, 120 } 121 122 assert.EqualValuesf(t, expected, stm.ToMap(s), "value test") 123 assert.EqualValuesf(t, expected, stm.ToMap(&s), "ptr test") 124 } 125 126 func TestToMap_tree(t *testing.T) { 127 type node struct { 128 Value int `stm:"v"` 129 Left *node `stm:"left"` 130 Right *node `stm:"right"` 131 } 132 s := node{1, 133 &node{2, nil, nil}, 134 &node{3, 135 &node{4, nil, nil}, 136 nil, 137 }, 138 } 139 expected := map[string]int64{ 140 "v": 1, 141 "left_v": 2, 142 "right_v": 3, 143 "right_left_v": 4, 144 } 145 146 assert.EqualValuesf(t, expected, stm.ToMap(s), "value test") 147 assert.EqualValuesf(t, expected, stm.ToMap(&s), "ptr test") 148 } 149 150 func TestToMap_map(t *testing.T) { 151 s := struct { 152 I int `stm:"int"` 153 M map[string]int64 `stm:""` 154 }{ 155 I: 1, 156 M: map[string]int64{ 157 "a": 2, 158 "b": 3, 159 }, 160 } 161 162 expected := map[string]int64{ 163 "int": 1, 164 "a": 2, 165 "b": 3, 166 } 167 168 assert.EqualValuesf(t, expected, stm.ToMap(s), "value test") 169 assert.EqualValuesf(t, expected, stm.ToMap(&s), "ptr test") 170 } 171 172 func TestToMap_nestMap(t *testing.T) { 173 s := struct { 174 I int `stm:"int"` 175 M map[string]interface{} `stm:""` 176 }{ 177 I: 1, 178 M: map[string]interface{}{ 179 "a": 2, 180 "b": 3, 181 "m": map[string]interface{}{ 182 "c": 4, 183 }, 184 }, 185 } 186 187 expected := map[string]int64{ 188 "int": 1, 189 "a": 2, 190 "b": 3, 191 "m_c": 4, 192 } 193 194 assert.EqualValuesf(t, expected, stm.ToMap(s), "value test") 195 assert.EqualValuesf(t, expected, stm.ToMap(&s), "ptr test") 196 } 197 198 func TestToMap_ptr(t *testing.T) { 199 two := 2 200 s := struct { 201 I int `stm:"int"` 202 Ptr *int `stm:"ptr"` 203 Nil *int `stm:"nil"` 204 }{ 205 I: 1, 206 Ptr: &two, 207 Nil: nil, 208 } 209 210 expected := map[string]int64{ 211 "int": 1, 212 "ptr": 2, 213 } 214 215 assert.EqualValuesf(t, expected, stm.ToMap(s), "value test") 216 assert.EqualValuesf(t, expected, stm.ToMap(&s), "ptr test") 217 } 218 219 func TestToMap_invalidType(t *testing.T) { 220 s := struct { 221 Str string `stm:"int"` 222 }{ 223 Str: "abc", 224 } 225 226 assert.Panics(t, func() { 227 stm.ToMap(s) 228 }, "value test") 229 assert.Panics(t, func() { 230 stm.ToMap(&s) 231 }, "ptr test") 232 } 233 234 func TestToMap_duplicateKey(t *testing.T) { 235 { 236 s := struct { 237 Key int `stm:"key"` 238 M map[string]int `stm:""` 239 }{ 240 Key: 1, 241 M: map[string]int{ 242 "key": 2, 243 }, 244 } 245 246 assert.Panics(t, func() { 247 stm.ToMap(s) 248 }, "value test") 249 assert.Panics(t, func() { 250 stm.ToMap(&s) 251 }, "ptr test") 252 } 253 { 254 s := struct { 255 Key float64 `stm:"key"` 256 M map[string]float64 `stm:""` 257 }{ 258 Key: 1, 259 M: map[string]float64{ 260 "key": 2, 261 }, 262 } 263 264 assert.Panics(t, func() { 265 stm.ToMap(s) 266 }, "value test") 267 assert.Panics(t, func() { 268 stm.ToMap(&s) 269 }, "ptr test") 270 } 271 } 272 273 func TestToMap_Variadic(t *testing.T) { 274 s1 := struct { 275 Key1 int `stm:"key1"` 276 }{ 277 Key1: 1, 278 } 279 s2 := struct { 280 Key2 int `stm:"key2"` 281 }{ 282 Key2: 2, 283 } 284 s3 := struct { 285 Key3 int `stm:"key3"` 286 }{ 287 Key3: 3, 288 } 289 290 assert.Equal( 291 t, 292 map[string]int64{ 293 "key1": 1, 294 "key2": 2, 295 "key3": 3, 296 }, 297 stm.ToMap(s1, s2, s3), 298 ) 299 } 300 301 func TestToMap_badTag(t *testing.T) { 302 assert.Panics(t, func() { 303 s := struct { 304 A int `stm:"a,not_int"` 305 }{1} 306 stm.ToMap(s) 307 }) 308 assert.Panics(t, func() { 309 s := struct { 310 A int `stm:"a,1,not_int"` 311 }{1} 312 stm.ToMap(s) 313 }) 314 assert.Panics(t, func() { 315 s := struct { 316 A int `stm:"a,not_int,1"` 317 }{1} 318 stm.ToMap(s) 319 }) 320 assert.Panics(t, func() { 321 s := struct { 322 A int `stm:"a,1,2,3"` 323 }{1} 324 stm.ToMap(s) 325 }) 326 } 327 328 func TestToMap_nilValue(t *testing.T) { 329 assert.Panics(t, func() { 330 s := struct { 331 a metrics.CounterVec `stm:"a"` 332 }{nil} 333 stm.ToMap(s) 334 }) 335 } 336 func TestToMap_bool(t *testing.T) { 337 s := struct { 338 A bool `stm:"a"` 339 B bool `stm:"b"` 340 }{ 341 A: true, 342 B: false, 343 } 344 assert.Equal( 345 t, 346 map[string]int64{ 347 "a": 1, 348 "b": 0, 349 }, 350 stm.ToMap(s), 351 ) 352 } 353 354 func TestToMap_ArraySlice(t *testing.T) { 355 s := [4]interface{}{ 356 map[string]int{ 357 "B": 1, 358 "C": 2, 359 }, 360 struct { 361 D int `stm:"D"` 362 E int `stm:"E"` 363 }{ 364 D: 3, 365 E: 4, 366 }, 367 struct { 368 STMKey string 369 F int `stm:"F"` 370 G int `stm:"G"` 371 }{ 372 F: 5, 373 G: 6, 374 }, 375 struct { 376 STMKey string 377 H int `stm:"H"` 378 I int `stm:"I"` 379 }{ 380 STMKey: "KEY", 381 H: 7, 382 I: 8, 383 }, 384 } 385 386 assert.Equal( 387 t, 388 map[string]int64{ 389 "B": 1, 390 "C": 2, 391 "D": 3, 392 "E": 4, 393 "F": 5, 394 "G": 6, 395 "KEY_H": 7, 396 "KEY_I": 8, 397 }, 398 stm.ToMap(s), 399 ) 400 401 assert.Equal( 402 t, 403 map[string]int64{ 404 "B": 1, 405 "C": 2, 406 "D": 3, 407 "E": 4, 408 "F": 5, 409 "G": 6, 410 "KEY_H": 7, 411 "KEY_I": 8, 412 }, 413 stm.ToMap(s[:]), 414 ) 415 }