github.com/google/cloudprober@v0.11.3/metrics/map_test.go (about) 1 // Copyright 2017 The Cloudprober 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 metrics 16 17 import ( 18 "reflect" 19 "testing" 20 ) 21 22 func verify(t *testing.T, m *Map, expectedKeys []string, expectedMap map[string]int64) { 23 t.Helper() 24 25 if !reflect.DeepEqual(m.Keys(), expectedKeys) { 26 t.Errorf("Map doesn't have expected keys. Got: %q, Expected: %q", m.Keys(), expectedKeys) 27 } 28 for k, v := range expectedMap { 29 if m.GetKey(k).Int64() != v { 30 t.Errorf("Key values not as expected. Key: %s, Got: %d, Expected: %d", k, m.GetKey(k).Int64(), v) 31 } 32 } 33 } 34 35 func TestMap(t *testing.T) { 36 m := NewMap("code", NewInt(0)) 37 m.IncKeyBy("200", NewInt(4000)) 38 39 verify(t, m, []string{"200"}, map[string]int64{"200": 4000}) 40 41 m.IncKey("500") 42 verify(t, m, []string{"200", "500"}, map[string]int64{ 43 "200": 4000, 44 "500": 1, 45 }) 46 47 // Verify that keys are ordered 48 m.IncKey("404") 49 verify(t, m, []string{"200", "404", "500"}, map[string]int64{ 50 "200": 4000, 51 "404": 1, 52 "500": 1, 53 }) 54 55 // Clone m for verification later 56 m1 := m.Clone().(*Map) 57 58 // Verify add works as expected 59 m2 := NewMap("code", NewInt(0)) 60 m2.IncKeyBy("403", NewInt(2)) 61 err := m.Add(m2) 62 if err != nil { 63 t.Errorf("Add two maps produced error. Err: %v", err) 64 } 65 verify(t, m, []string{"200", "403", "404", "500"}, map[string]int64{ 66 "200": 4000, 67 "403": 2, 68 "404": 1, 69 "500": 1, 70 }) 71 72 // Verify that clones value has not changed 73 verify(t, m1, []string{"200", "404", "500"}, map[string]int64{ 74 "200": 4000, 75 "404": 1, 76 "500": 1, 77 }) 78 } 79 80 func TestMapSubtractCounter(t *testing.T) { 81 m1 := NewMap("code", NewInt(0)) 82 m1.IncKeyBy("200", NewInt(4000)) 83 m1.IncKeyBy("403", NewInt(2)) 84 85 m2 := m1.Clone().(*Map) 86 m2.IncKeyBy("200", NewInt(400)) 87 m2.IncKey("500") 88 m2Clone := m2.Clone() // We'll use this for reset testing below. 89 90 expectReset := false 91 wasReset, err := m2.SubtractCounter(m1) 92 if err != nil { 93 t.Errorf("Unexpected error: %v", err) 94 } 95 if wasReset != expectReset { 96 t.Errorf("wasReset=%v, expected=%v", wasReset, expectReset) 97 } 98 verify(t, m2, []string{"200", "403", "500"}, map[string]int64{ 99 "200": 400, 100 "403": 0, 101 "500": 1, 102 }) 103 104 // Expect a reset this time, as m3 (m) will be smaller than m2Clone. 105 m3 := m1.Clone() 106 expectReset = true 107 wasReset, err = m3.SubtractCounter(m2Clone) 108 if err != nil { 109 t.Errorf("Unexpected error: %v", err) 110 } 111 if wasReset != expectReset { 112 t.Errorf("wasReset=%v, expected=%v", wasReset, expectReset) 113 } 114 verify(t, m3.(*Map), []string{"200", "403"}, map[string]int64{ 115 "200": 4000, 116 "403": 2, 117 }) 118 119 } 120 121 func TestMapString(t *testing.T) { 122 m := NewMap("lat", NewFloat(0)) 123 m.IncKeyBy("p99", NewFloat(4000)) 124 m.IncKeyBy("p50", NewFloat(20)) 125 126 s := m.String() 127 expectedString := "map:lat,p50:20.000,p99:4000.000" 128 if s != expectedString { 129 t.Errorf("m.String()=%s, expected=%s", s, expectedString) 130 } 131 132 m2, err := ParseMapFromString(s) 133 if err != nil { 134 t.Errorf("ParseMapFromString(%s) returned error: %v", s, err) 135 } 136 137 s1 := m2.String() 138 if s1 != s { 139 t.Errorf("ParseMapFromString(%s).String() = %s, expected = %s", s, s1, s) 140 } 141 } 142 143 func TestMapAllocsPerRun(t *testing.T) { 144 var v *Map 145 mapNewAvg := testing.AllocsPerRun(100, func() { 146 v = NewMap("code", NewInt(0)) 147 v.IncKeyBy("200", NewInt(22)) 148 v.IncKeyBy("404", NewInt(4500)) 149 v.IncKeyBy("403", NewInt(4500)) 150 }) 151 152 mapStringAvg := testing.AllocsPerRun(100, func() { 153 _ = v.String() 154 }) 155 156 t.Logf("Average allocations per run: ForMapNew=%v, ForMapString=%v", mapNewAvg, mapStringAvg) 157 }