github.com/tobiasdai/prometheus_common@v1.12.0/model/signature_test.go (about) 1 // Copyright 2014 The Prometheus Authors 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package model 15 16 import ( 17 "fmt" 18 "runtime" 19 "sync" 20 "testing" 21 ) 22 23 func TestLabelsToSignature(t *testing.T) { 24 var scenarios = []struct { 25 in map[string]string 26 out uint64 27 }{ 28 { 29 in: map[string]string{}, 30 out: 14695981039346656037, 31 }, 32 { 33 in: map[string]string{"name": "garland, briggs", "fear": "love is not enough"}, 34 out: 5799056148416392346, 35 }, 36 } 37 38 for i, scenario := range scenarios { 39 actual := LabelsToSignature(scenario.in) 40 41 if actual != scenario.out { 42 t.Errorf("%d. expected %d, got %d", i, scenario.out, actual) 43 } 44 } 45 } 46 47 func TestMetricToFingerprint(t *testing.T) { 48 var scenarios = []struct { 49 in LabelSet 50 out Fingerprint 51 }{ 52 { 53 in: LabelSet{}, 54 out: 14695981039346656037, 55 }, 56 { 57 in: LabelSet{"name": "garland, briggs", "fear": "love is not enough"}, 58 out: 5799056148416392346, 59 }, 60 } 61 62 for i, scenario := range scenarios { 63 actual := labelSetToFingerprint(scenario.in) 64 65 if actual != scenario.out { 66 t.Errorf("%d. expected %d, got %d", i, scenario.out, actual) 67 } 68 } 69 } 70 71 func TestMetricToFastFingerprint(t *testing.T) { 72 var scenarios = []struct { 73 in LabelSet 74 out Fingerprint 75 }{ 76 { 77 in: LabelSet{}, 78 out: 14695981039346656037, 79 }, 80 { 81 in: LabelSet{"name": "garland, briggs", "fear": "love is not enough"}, 82 out: 12952432476264840823, 83 }, 84 } 85 86 for i, scenario := range scenarios { 87 actual := labelSetToFastFingerprint(scenario.in) 88 89 if actual != scenario.out { 90 t.Errorf("%d. expected %d, got %d", i, scenario.out, actual) 91 } 92 } 93 } 94 95 func TestSignatureForLabels(t *testing.T) { 96 var scenarios = []struct { 97 in Metric 98 labels LabelNames 99 out uint64 100 }{ 101 { 102 in: Metric{}, 103 labels: nil, 104 out: 14695981039346656037, 105 }, 106 { 107 in: Metric{}, 108 labels: LabelNames{"empty"}, 109 out: 7187873163539638612, 110 }, 111 { 112 in: Metric{"name": "garland, briggs", "fear": "love is not enough"}, 113 labels: LabelNames{"empty"}, 114 out: 7187873163539638612, 115 }, 116 { 117 in: Metric{"name": "garland, briggs", "fear": "love is not enough"}, 118 labels: LabelNames{"fear", "name"}, 119 out: 5799056148416392346, 120 }, 121 { 122 in: Metric{"name": "garland, briggs", "fear": "love is not enough", "foo": "bar"}, 123 labels: LabelNames{"fear", "name"}, 124 out: 5799056148416392346, 125 }, 126 { 127 in: Metric{"name": "garland, briggs", "fear": "love is not enough"}, 128 labels: LabelNames{}, 129 out: 14695981039346656037, 130 }, 131 { 132 in: Metric{"name": "garland, briggs", "fear": "love is not enough"}, 133 labels: nil, 134 out: 14695981039346656037, 135 }, 136 } 137 138 for i, scenario := range scenarios { 139 actual := SignatureForLabels(scenario.in, scenario.labels...) 140 141 if actual != scenario.out { 142 t.Errorf("%d. expected %d, got %d", i, scenario.out, actual) 143 } 144 } 145 } 146 147 func TestSignatureWithoutLabels(t *testing.T) { 148 var scenarios = []struct { 149 in Metric 150 labels map[LabelName]struct{} 151 out uint64 152 }{ 153 { 154 in: Metric{}, 155 labels: nil, 156 out: 14695981039346656037, 157 }, 158 { 159 in: Metric{"name": "garland, briggs", "fear": "love is not enough"}, 160 labels: map[LabelName]struct{}{"fear": struct{}{}, "name": struct{}{}}, 161 out: 14695981039346656037, 162 }, 163 { 164 in: Metric{"name": "garland, briggs", "fear": "love is not enough", "foo": "bar"}, 165 labels: map[LabelName]struct{}{"foo": struct{}{}}, 166 out: 5799056148416392346, 167 }, 168 { 169 in: Metric{"name": "garland, briggs", "fear": "love is not enough"}, 170 labels: map[LabelName]struct{}{}, 171 out: 5799056148416392346, 172 }, 173 { 174 in: Metric{"name": "garland, briggs", "fear": "love is not enough"}, 175 labels: nil, 176 out: 5799056148416392346, 177 }, 178 } 179 180 for i, scenario := range scenarios { 181 actual := SignatureWithoutLabels(scenario.in, scenario.labels) 182 183 if actual != scenario.out { 184 t.Errorf("%d. expected %d, got %d", i, scenario.out, actual) 185 } 186 } 187 } 188 189 func benchmarkLabelToSignature(b *testing.B, l map[string]string, e uint64) { 190 for i := 0; i < b.N; i++ { 191 if a := LabelsToSignature(l); a != e { 192 b.Fatalf("expected signature of %d for %s, got %d", e, l, a) 193 } 194 } 195 } 196 197 func BenchmarkLabelToSignatureScalar(b *testing.B) { 198 benchmarkLabelToSignature(b, nil, 14695981039346656037) 199 } 200 201 func BenchmarkLabelToSignatureSingle(b *testing.B) { 202 benchmarkLabelToSignature(b, map[string]string{"first-label": "first-label-value"}, 5146282821936882169) 203 } 204 205 func BenchmarkLabelToSignatureDouble(b *testing.B) { 206 benchmarkLabelToSignature(b, map[string]string{"first-label": "first-label-value", "second-label": "second-label-value"}, 3195800080984914717) 207 } 208 209 func BenchmarkLabelToSignatureTriple(b *testing.B) { 210 benchmarkLabelToSignature(b, map[string]string{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 13843036195897128121) 211 } 212 213 func benchmarkMetricToFingerprint(b *testing.B, ls LabelSet, e Fingerprint) { 214 for i := 0; i < b.N; i++ { 215 if a := labelSetToFingerprint(ls); a != e { 216 b.Fatalf("expected signature of %d for %s, got %d", e, ls, a) 217 } 218 } 219 } 220 221 func BenchmarkMetricToFingerprintScalar(b *testing.B) { 222 benchmarkMetricToFingerprint(b, nil, 14695981039346656037) 223 } 224 225 func BenchmarkMetricToFingerprintSingle(b *testing.B) { 226 benchmarkMetricToFingerprint(b, LabelSet{"first-label": "first-label-value"}, 5146282821936882169) 227 } 228 229 func BenchmarkMetricToFingerprintDouble(b *testing.B) { 230 benchmarkMetricToFingerprint(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value"}, 3195800080984914717) 231 } 232 233 func BenchmarkMetricToFingerprintTriple(b *testing.B) { 234 benchmarkMetricToFingerprint(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 13843036195897128121) 235 } 236 237 func benchmarkMetricToFastFingerprint(b *testing.B, ls LabelSet, e Fingerprint) { 238 for i := 0; i < b.N; i++ { 239 if a := labelSetToFastFingerprint(ls); a != e { 240 b.Fatalf("expected signature of %d for %s, got %d", e, ls, a) 241 } 242 } 243 } 244 245 func BenchmarkMetricToFastFingerprintScalar(b *testing.B) { 246 benchmarkMetricToFastFingerprint(b, nil, 14695981039346656037) 247 } 248 249 func BenchmarkMetricToFastFingerprintSingle(b *testing.B) { 250 benchmarkMetricToFastFingerprint(b, LabelSet{"first-label": "first-label-value"}, 5147259542624943964) 251 } 252 253 func BenchmarkMetricToFastFingerprintDouble(b *testing.B) { 254 benchmarkMetricToFastFingerprint(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value"}, 18269973311206963528) 255 } 256 257 func BenchmarkMetricToFastFingerprintTriple(b *testing.B) { 258 benchmarkMetricToFastFingerprint(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676) 259 } 260 261 func BenchmarkEmptyLabelSignature(b *testing.B) { 262 input := []map[string]string{nil, {}} 263 264 var ms runtime.MemStats 265 runtime.ReadMemStats(&ms) 266 267 alloc := ms.Alloc 268 269 for _, labels := range input { 270 LabelsToSignature(labels) 271 } 272 273 runtime.ReadMemStats(&ms) 274 275 if got := ms.Alloc; alloc != got { 276 b.Fatal("expected LabelsToSignature with empty labels not to perform allocations") 277 } 278 } 279 280 func benchmarkMetricToFastFingerprintConc(b *testing.B, ls LabelSet, e Fingerprint, concLevel int) { 281 var start, end sync.WaitGroup 282 start.Add(1) 283 end.Add(concLevel) 284 errc := make(chan error, 1) 285 286 for i := 0; i < concLevel; i++ { 287 go func() { 288 start.Wait() 289 for j := b.N / concLevel; j >= 0; j-- { 290 if a := labelSetToFastFingerprint(ls); a != e { 291 select { 292 case errc <- fmt.Errorf("expected signature of %d for %s, got %d", e, ls, a): 293 default: 294 } 295 } 296 } 297 end.Done() 298 }() 299 } 300 b.ResetTimer() 301 start.Done() 302 end.Wait() 303 304 select { 305 case err := <-errc: 306 b.Fatal(err) 307 default: 308 } 309 } 310 311 func BenchmarkMetricToFastFingerprintTripleConc1(b *testing.B) { 312 benchmarkMetricToFastFingerprintConc(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 1) 313 } 314 315 func BenchmarkMetricToFastFingerprintTripleConc2(b *testing.B) { 316 benchmarkMetricToFastFingerprintConc(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 2) 317 } 318 319 func BenchmarkMetricToFastFingerprintTripleConc4(b *testing.B) { 320 benchmarkMetricToFastFingerprintConc(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 4) 321 } 322 323 func BenchmarkMetricToFastFingerprintTripleConc8(b *testing.B) { 324 benchmarkMetricToFastFingerprintConc(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 8) 325 }