github.com/muhammadn/cortex@v1.9.1-0.20220510110439-46bb7000d03d/pkg/ingester/mapper_test.go (about) 1 package ingester 2 3 import ( 4 "sort" 5 "testing" 6 7 "github.com/go-kit/log" 8 "github.com/prometheus/common/model" 9 "github.com/prometheus/prometheus/pkg/labels" 10 ) 11 12 var ( 13 // cm11, cm12, cm13 are colliding with fp1. 14 // cm21, cm22 are colliding with fp2. 15 // cm31, cm32 are colliding with fp3, which is below maxMappedFP. 16 // Note that fingerprints are set and not actually calculated. 17 // The collision detection is independent from the actually used 18 // fingerprinting algorithm. 19 fp1 = model.Fingerprint(maxMappedFP + 1) 20 fp2 = model.Fingerprint(maxMappedFP + 2) 21 fp3 = model.Fingerprint(1) 22 cm11 = labelPairs{ 23 {Name: "foo", Value: "bar"}, 24 {Name: "dings", Value: "bumms"}, 25 } 26 cm12 = labelPairs{ 27 {Name: "bar", Value: "foo"}, 28 } 29 cm13 = labelPairs{ 30 {Name: "foo", Value: "bar"}, 31 } 32 cm21 = labelPairs{ 33 {Name: "foo", Value: "bumms"}, 34 {Name: "dings", Value: "bar"}, 35 } 36 cm22 = labelPairs{ 37 {Name: "dings", Value: "foo"}, 38 {Name: "bar", Value: "bumms"}, 39 } 40 cm31 = labelPairs{ 41 {Name: "bumms", Value: "dings"}, 42 } 43 cm32 = labelPairs{ 44 {Name: "bumms", Value: "dings"}, 45 {Name: "bar", Value: "foo"}, 46 } 47 ) 48 49 func (a labelPairs) copyValuesAndSort() labels.Labels { 50 c := make(labels.Labels, len(a)) 51 for i, pair := range a { 52 c[i].Name = pair.Name 53 c[i].Value = pair.Value 54 } 55 sort.Sort(c) 56 return c 57 } 58 59 func TestFPMapper(t *testing.T) { 60 sm := newSeriesMap() 61 62 mapper := newFPMapper(sm, log.NewNopLogger()) 63 64 // Everything is empty, resolving a FP should do nothing. 65 assertFingerprintEqual(t, mapper.mapFP(fp1, cm11), fp1) 66 assertFingerprintEqual(t, mapper.mapFP(fp1, cm12), fp1) 67 68 // cm11 is in sm. Adding cm11 should do nothing. Mapping cm12 should resolve 69 // the collision. 70 sm.put(fp1, &memorySeries{metric: cm11.copyValuesAndSort()}) 71 assertFingerprintEqual(t, mapper.mapFP(fp1, cm11), fp1) 72 assertFingerprintEqual(t, mapper.mapFP(fp1, cm12), model.Fingerprint(1)) 73 74 // The mapped cm12 is added to sm, too. That should not change the outcome. 75 sm.put(model.Fingerprint(1), &memorySeries{metric: cm12.copyValuesAndSort()}) 76 assertFingerprintEqual(t, mapper.mapFP(fp1, cm11), fp1) 77 assertFingerprintEqual(t, mapper.mapFP(fp1, cm12), model.Fingerprint(1)) 78 79 // Now map cm13, should reproducibly result in the next mapped FP. 80 assertFingerprintEqual(t, mapper.mapFP(fp1, cm13), model.Fingerprint(2)) 81 assertFingerprintEqual(t, mapper.mapFP(fp1, cm13), model.Fingerprint(2)) 82 83 // Add cm13 to sm. Should not change anything. 84 sm.put(model.Fingerprint(2), &memorySeries{metric: cm13.copyValuesAndSort()}) 85 assertFingerprintEqual(t, mapper.mapFP(fp1, cm11), fp1) 86 assertFingerprintEqual(t, mapper.mapFP(fp1, cm12), model.Fingerprint(1)) 87 assertFingerprintEqual(t, mapper.mapFP(fp1, cm13), model.Fingerprint(2)) 88 89 // Now add cm21 and cm22 in the same way, checking the mapped FPs. 90 assertFingerprintEqual(t, mapper.mapFP(fp2, cm21), fp2) 91 sm.put(fp2, &memorySeries{metric: cm21.copyValuesAndSort()}) 92 assertFingerprintEqual(t, mapper.mapFP(fp2, cm21), fp2) 93 assertFingerprintEqual(t, mapper.mapFP(fp2, cm22), model.Fingerprint(3)) 94 sm.put(model.Fingerprint(3), &memorySeries{metric: cm22.copyValuesAndSort()}) 95 assertFingerprintEqual(t, mapper.mapFP(fp2, cm21), fp2) 96 assertFingerprintEqual(t, mapper.mapFP(fp2, cm22), model.Fingerprint(3)) 97 98 // Map cm31, resulting in a mapping straight away. 99 assertFingerprintEqual(t, mapper.mapFP(fp3, cm31), model.Fingerprint(4)) 100 sm.put(model.Fingerprint(4), &memorySeries{metric: cm31.copyValuesAndSort()}) 101 102 // Map cm32, which is now mapped for two reasons... 103 assertFingerprintEqual(t, mapper.mapFP(fp3, cm32), model.Fingerprint(5)) 104 sm.put(model.Fingerprint(5), &memorySeries{metric: cm32.copyValuesAndSort()}) 105 106 // Now check ALL the mappings, just to be sure. 107 assertFingerprintEqual(t, mapper.mapFP(fp1, cm11), fp1) 108 assertFingerprintEqual(t, mapper.mapFP(fp1, cm12), model.Fingerprint(1)) 109 assertFingerprintEqual(t, mapper.mapFP(fp1, cm13), model.Fingerprint(2)) 110 assertFingerprintEqual(t, mapper.mapFP(fp2, cm21), fp2) 111 assertFingerprintEqual(t, mapper.mapFP(fp2, cm22), model.Fingerprint(3)) 112 assertFingerprintEqual(t, mapper.mapFP(fp3, cm31), model.Fingerprint(4)) 113 assertFingerprintEqual(t, mapper.mapFP(fp3, cm32), model.Fingerprint(5)) 114 115 // Remove all the fingerprints from sm, which should change nothing, as 116 // the existing mappings stay and should be detected. 117 sm.del(fp1) 118 sm.del(fp2) 119 sm.del(fp3) 120 assertFingerprintEqual(t, mapper.mapFP(fp1, cm11), fp1) 121 assertFingerprintEqual(t, mapper.mapFP(fp1, cm12), model.Fingerprint(1)) 122 assertFingerprintEqual(t, mapper.mapFP(fp1, cm13), model.Fingerprint(2)) 123 assertFingerprintEqual(t, mapper.mapFP(fp2, cm21), fp2) 124 assertFingerprintEqual(t, mapper.mapFP(fp2, cm22), model.Fingerprint(3)) 125 assertFingerprintEqual(t, mapper.mapFP(fp3, cm31), model.Fingerprint(4)) 126 assertFingerprintEqual(t, mapper.mapFP(fp3, cm32), model.Fingerprint(5)) 127 } 128 129 // assertFingerprintEqual asserts that two fingerprints are equal. 130 func assertFingerprintEqual(t *testing.T, gotFP, wantFP model.Fingerprint) { 131 if gotFP != wantFP { 132 t.Errorf("got fingerprint %v, want fingerprint %v", gotFP, wantFP) 133 } 134 }