github.com/GoogleCloudPlatform/testgrid@v0.0.174/util/metrics/prometheus/prometheus_test.go (about) 1 /* 2 Copyright 2021 The TestGrid Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package prometheus 18 19 import ( 20 "strings" 21 "sync" 22 "testing" 23 "time" 24 25 "github.com/google/go-cmp/cmp" 26 ) 27 28 func TestInt64Set(t *testing.T) { 29 cases := []struct { 30 name string 31 fields []string 32 sets []map[int64][]string 33 want map[string]float64 34 }{ 35 { 36 name: "zero", 37 want: map[string]float64{}, 38 }, 39 { 40 name: "basic", 41 fields: []string{"component"}, 42 sets: []map[int64][]string{ 43 {64: {"updater"}}, 44 }, 45 want: map[string]float64{ 46 "updater": float64(64), 47 }, 48 }, 49 { 50 name: "fields", 51 fields: []string{"component", "source"}, 52 sets: []map[int64][]string{ 53 {64: {"updater", "prow"}}, 54 }, 55 want: map[string]float64{ 56 "updater|prow": float64(64), 57 }, 58 }, 59 { 60 name: "serial values", 61 fields: []string{"component"}, 62 sets: []map[int64][]string{ 63 {64: {"updater"}}, 64 {32: {"updater"}}, 65 }, 66 want: map[string]float64{ 67 "updater": float64(32), 68 }, 69 }, 70 { 71 name: "complex", 72 fields: []string{"component", "source"}, 73 sets: []map[int64][]string{ 74 { 75 64: {"updater", "prow"}, 76 66: {"updater", "google"}, 77 32: {"summarizer", "google"}, 78 }, 79 { 80 64: {"updater", "prow"}, 81 22: {"summarizer", "google"}, 82 }, 83 }, 84 want: map[string]float64{ 85 "updater|prow": float64(64), 86 "updater|google": float64(66), 87 "summarizer|google": float64(22), 88 }, 89 }, 90 } 91 92 for _, tc := range cases { 93 t.Run(tc.name, func(t *testing.T) { 94 mName := strings.Replace(tc.name, " ", "_", -1) + "_int" 95 m := NewInt64(mName, "fake desc", tc.fields...) 96 var wg sync.WaitGroup 97 for _, set := range tc.sets { 98 for n, fields := range set { 99 wg.Add(1) 100 go func(n int64, fields []string) { 101 m.Set(n, fields...) 102 m.(Valuer).Values() // Set and Values must be able to run concurrently 103 wg.Done() 104 }(n, fields) 105 } 106 wg.Wait() 107 } 108 got := m.(Valuer).Values() 109 if diff := cmp.Diff(tc.want, got); diff != "" { 110 t.Errorf("Set() got unexpected diff (-want +got):\n%s", diff) 111 } 112 }) 113 } 114 } 115 116 func TestCounterAdd(t *testing.T) { 117 cases := []struct { 118 name string 119 fields []string 120 adds []map[int64][]string 121 want map[string]float64 122 }{ 123 { 124 name: "zero", 125 want: map[string]float64{}, 126 }, 127 { 128 name: "basic", 129 fields: []string{"component"}, 130 adds: []map[int64][]string{ 131 { 132 12: {"updater"}, 133 }, 134 }, 135 want: map[string]float64{ 136 "updater": float64(12), 137 }, 138 }, 139 { 140 name: "fields", 141 fields: []string{"component", "source"}, 142 adds: []map[int64][]string{ 143 {64: {"updater", "prow"}}, 144 }, 145 want: map[string]float64{ 146 "updater|prow": float64(64), 147 }, 148 }, 149 { 150 name: "concurrent values", 151 fields: []string{"component"}, 152 adds: []map[int64][]string{ 153 { 154 32: {"updater"}, 155 64: {"updater"}, 156 }, 157 {32: {"updater"}}, 158 }, 159 want: map[string]float64{ 160 "updater": float64(32 + 32 + 64), 161 }, 162 }, 163 { 164 name: "fields and values", 165 fields: []string{"component", "source"}, 166 adds: []map[int64][]string{ 167 {64: {"updater", "prow"}}, 168 {32: {"updater", "prow"}}, 169 }, 170 want: map[string]float64{ 171 "updater|prow": float64(64 + 32), 172 }, 173 }, 174 { 175 name: "complex", 176 fields: []string{"component", "source"}, 177 adds: []map[int64][]string{ 178 { 179 64: {"updater", "prow"}, 180 66: {"updater", "google"}, 181 32: {"summarizer", "google"}, 182 22: {"summarizer", "google"}, 183 }, 184 }, 185 want: map[string]float64{ 186 "updater|prow": float64(64), 187 "updater|google": float64(66), 188 "summarizer|google": float64(32 + 22), 189 }, 190 }, 191 } 192 193 for _, tc := range cases { 194 t.Run(tc.name, func(t *testing.T) { 195 mName := strings.Replace(tc.name, " ", "_", -1) + "_counter" 196 m := NewCounter(mName, "fake desc", tc.fields...) 197 var wg sync.WaitGroup 198 for _, add := range tc.adds { 199 for n, values := range add { 200 wg.Add(1) 201 go func(n int64, values []string) { 202 m.Add(n, values...) 203 m.(Valuer).Values() // Add and Values must be able to run concurrently 204 wg.Done() 205 }(n, values) 206 } 207 wg.Wait() 208 } 209 got := m.(Valuer).Values() 210 if diff := cmp.Diff(tc.want, got); diff != "" { 211 t.Errorf("Add() got unexpected diff (-want +got):\n%s", diff) 212 } 213 }) 214 } 215 } 216 217 func TestDurationSet(t *testing.T) { 218 cases := []struct { 219 name string 220 fields []string 221 sets []map[time.Duration][]string 222 want map[string]float64 223 }{ 224 { 225 name: "zero", 226 want: map[string]float64{}, 227 }, 228 { 229 name: "basic", 230 fields: []string{"component"}, 231 sets: []map[time.Duration][]string{ 232 {(1100 * time.Millisecond): {"updater"}}, 233 }, 234 want: map[string]float64{ 235 "updater": float64(1.1), 236 }, 237 }, 238 { 239 name: "fields", 240 fields: []string{"component", "source"}, 241 sets: []map[time.Duration][]string{ 242 {time.Second: {"updater", "prow"}}, 243 }, 244 want: map[string]float64{ 245 "updater|prow": float64(1), 246 }, 247 }, 248 { 249 name: "serial values", 250 fields: []string{"component"}, 251 sets: []map[time.Duration][]string{ 252 {time.Second: {"updater"}}, 253 {time.Minute: {"updater"}}, 254 }, 255 want: map[string]float64{ 256 "updater": float64(60), 257 }, 258 }, 259 { 260 name: "complex", 261 fields: []string{"component", "source"}, 262 sets: []map[time.Duration][]string{ 263 { 264 time.Second: {"updater", "prow"}, 265 time.Minute: {"updater", "google"}, 266 time.Millisecond: {"summarizer", "google"}, 267 }, 268 { 269 time.Second: {"updater", "prow"}, 270 (2 * time.Second): {"summarizer", "google"}, 271 }, 272 }, 273 want: map[string]float64{ 274 "updater|prow": float64(1), 275 "updater|google": float64(60), 276 "summarizer|google": float64(2), 277 }, 278 }, 279 } 280 281 for _, tc := range cases { 282 t.Run(tc.name, func(t *testing.T) { 283 mName := strings.Replace(tc.name, " ", "_", -1) + "_duration" 284 m := NewDuration(mName, "fake desc", tc.fields...) 285 var wg sync.WaitGroup 286 for _, set := range tc.sets { 287 for n, fields := range set { 288 wg.Add(1) 289 go func(n time.Duration, fields []string) { 290 m.Set(n, fields...) 291 m.(Valuer).Values() // Set and Values must be able to run concurrently 292 wg.Done() 293 }(n, fields) 294 } 295 wg.Wait() 296 } 297 got := m.(Valuer).Values() 298 if diff := cmp.Diff(tc.want, got); diff != "" { 299 t.Errorf("Set() got unexpected diff (-want +got):\n%s", diff) 300 } 301 }) 302 } 303 }