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  }