github.com/prebid/prebid-server/v2@v2.18.0/metrics/go_metrics_test.go (about) 1 package metrics 2 3 import ( 4 "fmt" 5 "testing" 6 "time" 7 8 "github.com/prebid/prebid-server/v2/config" 9 "github.com/prebid/prebid-server/v2/openrtb_ext" 10 metrics "github.com/rcrowley/go-metrics" 11 "github.com/stretchr/testify/assert" 12 ) 13 14 func TestNewMetrics(t *testing.T) { 15 registry := metrics.NewRegistry() 16 syncerKeys := []string{"foo"} 17 moduleStageNames := map[string][]string{"foobar": {"entry", "raw"}, "another_module": {"raw", "auction"}} 18 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("Adapter1"), openrtb_ext.BidderName("Adapter2")}, config.DisabledMetrics{}, syncerKeys, moduleStageNames) 19 20 ensureContains(t, registry, "app_requests", m.AppRequestMeter) 21 ensureContains(t, registry, "debug_requests", m.DebugRequestMeter) 22 ensureContains(t, registry, "no_cookie_requests", m.NoCookieMeter) 23 ensureContains(t, registry, "request_time", m.RequestTimer) 24 ensureContains(t, registry, "amp_no_cookie_requests", m.AmpNoCookieMeter) 25 ensureContainsAdapterMetrics(t, registry, "adapter.adapter1", m.AdapterMetrics["adapter1"]) 26 ensureContainsAdapterMetrics(t, registry, "adapter.adapter2", m.AdapterMetrics["adapter2"]) 27 ensureContains(t, registry, "cookie_sync_requests", m.CookieSyncMeter) 28 ensureContains(t, registry, "cookie_sync_requests.ok", m.CookieSyncStatusMeter[CookieSyncOK]) 29 ensureContains(t, registry, "cookie_sync_requests.bad_request", m.CookieSyncStatusMeter[CookieSyncBadRequest]) 30 ensureContains(t, registry, "cookie_sync_requests.opt_out", m.CookieSyncStatusMeter[CookieSyncOptOut]) 31 ensureContains(t, registry, "cookie_sync_requests.gdpr_blocked_host_cookie", m.CookieSyncStatusMeter[CookieSyncGDPRHostCookieBlocked]) 32 ensureContains(t, registry, "setuid_requests", m.SetUidMeter) 33 ensureContains(t, registry, "setuid_requests.ok", m.SetUidStatusMeter[SetUidOK]) 34 ensureContains(t, registry, "setuid_requests.bad_request", m.SetUidStatusMeter[SetUidBadRequest]) 35 ensureContains(t, registry, "setuid_requests.opt_out", m.SetUidStatusMeter[SetUidOptOut]) 36 ensureContains(t, registry, "setuid_requests.gdpr_blocked_host_cookie", m.SetUidStatusMeter[SetUidGDPRHostCookieBlocked]) 37 ensureContains(t, registry, "setuid_requests.syncer_unknown", m.SetUidStatusMeter[SetUidSyncerUnknown]) 38 ensureContains(t, registry, "stored_responses", m.StoredResponsesMeter) 39 40 ensureContains(t, registry, "prebid_cache_request_time.ok", m.PrebidCacheRequestTimerSuccess) 41 ensureContains(t, registry, "prebid_cache_request_time.err", m.PrebidCacheRequestTimerError) 42 43 ensureContains(t, registry, "requests.ok.openrtb2-web", m.RequestStatuses[ReqTypeORTB2Web][RequestStatusOK]) 44 ensureContains(t, registry, "requests.badinput.openrtb2-web", m.RequestStatuses[ReqTypeORTB2Web][RequestStatusBadInput]) 45 ensureContains(t, registry, "requests.err.openrtb2-web", m.RequestStatuses[ReqTypeORTB2Web][RequestStatusErr]) 46 ensureContains(t, registry, "requests.networkerr.openrtb2-web", m.RequestStatuses[ReqTypeORTB2Web][RequestStatusNetworkErr]) 47 ensureContains(t, registry, "requests.ok.openrtb2-app", m.RequestStatuses[ReqTypeORTB2App][RequestStatusOK]) 48 ensureContains(t, registry, "requests.badinput.openrtb2-app", m.RequestStatuses[ReqTypeORTB2App][RequestStatusBadInput]) 49 ensureContains(t, registry, "requests.err.openrtb2-app", m.RequestStatuses[ReqTypeORTB2App][RequestStatusErr]) 50 ensureContains(t, registry, "requests.networkerr.openrtb2-app", m.RequestStatuses[ReqTypeORTB2App][RequestStatusNetworkErr]) 51 ensureContains(t, registry, "requests.ok.amp", m.RequestStatuses[ReqTypeAMP][RequestStatusOK]) 52 ensureContains(t, registry, "requests.badinput.amp", m.RequestStatuses[ReqTypeAMP][RequestStatusBadInput]) 53 ensureContains(t, registry, "requests.err.amp", m.RequestStatuses[ReqTypeAMP][RequestStatusErr]) 54 ensureContains(t, registry, "requests.networkerr.amp", m.RequestStatuses[ReqTypeAMP][RequestStatusNetworkErr]) 55 ensureContains(t, registry, "requests.ok.video", m.RequestStatuses[ReqTypeVideo][RequestStatusOK]) 56 ensureContains(t, registry, "requests.badinput.video", m.RequestStatuses[ReqTypeVideo][RequestStatusBadInput]) 57 ensureContains(t, registry, "requests.err.video", m.RequestStatuses[ReqTypeVideo][RequestStatusErr]) 58 ensureContains(t, registry, "requests.networkerr.video", m.RequestStatuses[ReqTypeVideo][RequestStatusNetworkErr]) 59 60 ensureContains(t, registry, "queued_requests.video.rejected", m.RequestsQueueTimer[ReqTypeVideo][false]) 61 ensureContains(t, registry, "queued_requests.video.accepted", m.RequestsQueueTimer[ReqTypeVideo][true]) 62 63 ensureContains(t, registry, "timeout_notification.ok", m.TimeoutNotificationSuccess) 64 ensureContains(t, registry, "timeout_notification.failed", m.TimeoutNotificationFailure) 65 66 ensureContains(t, registry, "privacy.request.ccpa.specified", m.PrivacyCCPARequest) 67 ensureContains(t, registry, "privacy.request.ccpa.opt-out", m.PrivacyCCPARequestOptOut) 68 ensureContains(t, registry, "privacy.request.coppa", m.PrivacyCOPPARequest) 69 ensureContains(t, registry, "privacy.request.lmt", m.PrivacyLMTRequest) 70 ensureContains(t, registry, "privacy.request.tcf.v2", m.PrivacyTCFRequestVersion[TCFVersionV2]) 71 ensureContains(t, registry, "privacy.request.tcf.err", m.PrivacyTCFRequestVersion[TCFVersionErr]) 72 73 ensureContains(t, registry, "syncer.foo.request.ok", m.SyncerRequestsMeter["foo"][SyncerCookieSyncOK]) 74 ensureContains(t, registry, "syncer.foo.request.privacy_blocked", m.SyncerRequestsMeter["foo"][SyncerCookieSyncPrivacyBlocked]) 75 ensureContains(t, registry, "syncer.foo.request.already_synced", m.SyncerRequestsMeter["foo"][SyncerCookieSyncAlreadySynced]) 76 ensureContains(t, registry, "syncer.foo.request.type_not_supported", m.SyncerRequestsMeter["foo"][SyncerCookieSyncTypeNotSupported]) 77 ensureContains(t, registry, "syncer.foo.set.ok", m.SyncerSetsMeter["foo"][SyncerSetUidOK]) 78 ensureContains(t, registry, "syncer.foo.set.cleared", m.SyncerSetsMeter["foo"][SyncerSetUidCleared]) 79 80 ensureContains(t, registry, "ads_cert_requests.ok", m.AdsCertRequestsSuccess) 81 ensureContains(t, registry, "ads_cert_requests.failed", m.AdsCertRequestsFailure) 82 83 ensureContains(t, registry, "request_over_head_time.pre-bidder", m.OverheadTimer[PreBidder]) 84 ensureContains(t, registry, "request_over_head_time.make-auction-response", m.OverheadTimer[MakeAuctionResponse]) 85 ensureContains(t, registry, "request_over_head_time.make-bidder-requests", m.OverheadTimer[MakeBidderRequests]) 86 ensureContains(t, registry, "bidder_server_response_time_seconds", m.BidderServerResponseTimer) 87 ensureContains(t, registry, "tmax_timeout", m.TMaxTimeoutCounter) 88 89 for module, stages := range moduleStageNames { 90 for _, stage := range stages { 91 ensureContainsModuleMetrics(t, registry, fmt.Sprintf("modules.module.%s.stage.%s", module, stage), m.ModuleMetrics[module][stage]) 92 } 93 } 94 } 95 96 func TestRecordBidType(t *testing.T) { 97 registry := metrics.NewRegistry() 98 adapterName := "FOO" 99 lowerCaseAdapterName := "foo" 100 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapterName)}, config.DisabledMetrics{}, nil, nil) 101 102 m.RecordAdapterBidReceived(AdapterLabels{ 103 Adapter: openrtb_ext.BidderName(adapterName), 104 }, openrtb_ext.BidTypeBanner, true) 105 VerifyMetrics(t, "foo Banner Adm Bids", m.AdapterMetrics[lowerCaseAdapterName].MarkupMetrics[openrtb_ext.BidTypeBanner].AdmMeter.Count(), 1) 106 VerifyMetrics(t, "foo Banner Nurl Bids", m.AdapterMetrics[lowerCaseAdapterName].MarkupMetrics[openrtb_ext.BidTypeBanner].NurlMeter.Count(), 0) 107 108 m.RecordAdapterBidReceived(AdapterLabels{ 109 Adapter: openrtb_ext.BidderName(adapterName), 110 }, openrtb_ext.BidTypeVideo, false) 111 VerifyMetrics(t, "foo Video Adm Bids", m.AdapterMetrics[lowerCaseAdapterName].MarkupMetrics[openrtb_ext.BidTypeVideo].AdmMeter.Count(), 0) 112 VerifyMetrics(t, "foo Video Nurl Bids", m.AdapterMetrics[lowerCaseAdapterName].MarkupMetrics[openrtb_ext.BidTypeVideo].NurlMeter.Count(), 1) 113 } 114 115 func ensureContains(t *testing.T, registry metrics.Registry, name string, metric interface{}) { 116 t.Helper() 117 if inRegistry := registry.Get(name); inRegistry == nil { 118 t.Errorf("No metric in registry at %s.", name) 119 } else if inRegistry != metric { 120 t.Errorf("Bad value stored at metric %s.", name) 121 } 122 } 123 124 func ensureContainsAdapterMetrics(t *testing.T, registry metrics.Registry, name string, adapterMetrics *AdapterMetrics) { 125 t.Helper() 126 ensureContains(t, registry, name+".no_cookie_requests", adapterMetrics.NoCookieMeter) 127 ensureContains(t, registry, name+".requests.gotbids", adapterMetrics.GotBidsMeter) 128 ensureContains(t, registry, name+".requests.nobid", adapterMetrics.NoBidMeter) 129 ensureContains(t, registry, name+".requests.badinput", adapterMetrics.ErrorMeters[AdapterErrorBadInput]) 130 ensureContains(t, registry, name+".requests.badserverresponse", adapterMetrics.ErrorMeters[AdapterErrorBadServerResponse]) 131 ensureContains(t, registry, name+".requests.timeout", adapterMetrics.ErrorMeters[AdapterErrorTimeout]) 132 ensureContains(t, registry, name+".requests.unknown_error", adapterMetrics.ErrorMeters[AdapterErrorUnknown]) 133 134 ensureContains(t, registry, name+".request_time", adapterMetrics.RequestTimer) 135 ensureContains(t, registry, name+".prices", adapterMetrics.PriceHistogram) 136 ensureContainsBidTypeMetrics(t, registry, name, adapterMetrics.MarkupMetrics) 137 138 ensureContains(t, registry, name+".connections_created", adapterMetrics.ConnCreated) 139 ensureContains(t, registry, name+".connections_reused", adapterMetrics.ConnReused) 140 ensureContains(t, registry, name+".connection_wait_time", adapterMetrics.ConnWaitTime) 141 142 ensureContains(t, registry, name+".response.validation.size.err", adapterMetrics.BidValidationCreativeSizeErrorMeter) 143 ensureContains(t, registry, name+".response.validation.size.warn", adapterMetrics.BidValidationCreativeSizeWarnMeter) 144 ensureContains(t, registry, name+".response.validation.secure.err", adapterMetrics.BidValidationSecureMarkupErrorMeter) 145 ensureContains(t, registry, name+".response.validation.secure.warn", adapterMetrics.BidValidationSecureMarkupWarnMeter) 146 147 } 148 149 func ensureContainsModuleMetrics(t *testing.T, registry metrics.Registry, name string, moduleMetrics *ModuleMetrics) { 150 t.Helper() 151 ensureContains(t, registry, name+".duration", moduleMetrics.DurationTimer) 152 ensureContains(t, registry, name+".call", moduleMetrics.CallCounter) 153 ensureContains(t, registry, name+".failure", moduleMetrics.FailureCounter) 154 ensureContains(t, registry, name+".success.noop", moduleMetrics.SuccessNoopCounter) 155 ensureContains(t, registry, name+".success.update", moduleMetrics.SuccessUpdateCounter) 156 ensureContains(t, registry, name+".success.reject", moduleMetrics.SuccessRejectCounter) 157 ensureContains(t, registry, name+".execution_error", moduleMetrics.ExecutionErrorCounter) 158 ensureContains(t, registry, name+".timeout", moduleMetrics.TimeoutCounter) 159 } 160 161 func TestRecordBidTypeDisabledConfig(t *testing.T) { 162 testCases := []struct { 163 hasAdm bool 164 DisabledMetrics config.DisabledMetrics 165 ExpectedAdmMeterCount int64 166 ExpectedNurlMeterCount int64 167 BidType openrtb_ext.BidType 168 PubID string 169 }{ 170 { 171 hasAdm: true, 172 DisabledMetrics: config.DisabledMetrics{}, 173 ExpectedAdmMeterCount: 1, 174 ExpectedNurlMeterCount: 0, 175 BidType: openrtb_ext.BidTypeBanner, 176 PubID: "acct-id", 177 }, 178 { 179 hasAdm: false, 180 DisabledMetrics: config.DisabledMetrics{}, 181 ExpectedAdmMeterCount: 0, 182 ExpectedNurlMeterCount: 1, 183 BidType: openrtb_ext.BidTypeVideo, 184 PubID: "acct-id", 185 }, 186 { 187 hasAdm: false, 188 DisabledMetrics: config.DisabledMetrics{AccountAdapterDetails: true}, 189 ExpectedAdmMeterCount: 0, 190 ExpectedNurlMeterCount: 1, 191 BidType: openrtb_ext.BidTypeVideo, 192 PubID: "acct-id", 193 }, 194 { 195 hasAdm: true, 196 DisabledMetrics: config.DisabledMetrics{AccountAdapterDetails: true}, 197 ExpectedAdmMeterCount: 1, 198 ExpectedNurlMeterCount: 0, 199 BidType: openrtb_ext.BidTypeBanner, 200 PubID: "acct-id", 201 }, 202 } 203 adapter := "AnyName" 204 lowerCaseAdapter := "anyname" 205 for _, test := range testCases { 206 registry := metrics.NewRegistry() 207 208 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, test.DisabledMetrics, nil, nil) 209 210 m.RecordAdapterBidReceived(AdapterLabels{ 211 Adapter: openrtb_ext.BidderName(adapter), 212 PubID: test.PubID, 213 }, test.BidType, test.hasAdm) 214 assert.Equal(t, test.ExpectedAdmMeterCount, m.AdapterMetrics[lowerCaseAdapter].MarkupMetrics[test.BidType].AdmMeter.Count(), "AnyName Banner Adm Bids") 215 assert.Equal(t, test.ExpectedNurlMeterCount, m.AdapterMetrics[lowerCaseAdapter].MarkupMetrics[test.BidType].NurlMeter.Count(), "AnyName Banner Nurl Bids") 216 217 if test.DisabledMetrics.AccountAdapterDetails { 218 assert.Len(t, m.accountMetrics[test.PubID].adapterMetrics, 0, "Test failed. Account metrics that contain adapter information are disabled, therefore we expect no entries in m.accountMetrics[accountId].adapterMetrics, we have %d \n", len(m.accountMetrics[test.PubID].adapterMetrics)) 219 } else { 220 assert.NotEqual(t, 0, len(m.accountMetrics[test.PubID].adapterMetrics), "Test failed. Account metrics that contain adapter information are disabled, therefore we expect no entries in m.accountMetrics[accountId].adapterMetrics, we have %d \n", len(m.accountMetrics[test.PubID].adapterMetrics)) 221 } 222 } 223 } 224 225 func TestRecordDebugRequest(t *testing.T) { 226 testCases := []struct { 227 description string 228 givenDisabledMetrics config.DisabledMetrics 229 givenDebugEnabledFlag bool 230 givenPubID string 231 expectedAccountDebugCount int64 232 expectedDebugCount int64 233 }{ 234 { 235 description: "Debug is enabled and account debug is enabled, both metrics should be updated", 236 givenDisabledMetrics: config.DisabledMetrics{ 237 AccountAdapterDetails: true, 238 AccountDebug: false, 239 }, 240 givenDebugEnabledFlag: true, 241 givenPubID: "acct-id", 242 expectedAccountDebugCount: 1, 243 expectedDebugCount: 1, 244 }, 245 { 246 description: "Debug and account debug are disabled, niether metrics should be updated", 247 givenDisabledMetrics: config.DisabledMetrics{ 248 AccountAdapterDetails: true, 249 AccountDebug: true, 250 }, 251 givenDebugEnabledFlag: false, 252 givenPubID: "acct-id", 253 expectedAccountDebugCount: 0, 254 expectedDebugCount: 0, 255 }, 256 { 257 description: "Debug is enabled and account debug is enabled, but unknown PubID leads to account debug being 0", 258 givenDisabledMetrics: config.DisabledMetrics{ 259 AccountAdapterDetails: true, 260 AccountDebug: false, 261 }, 262 givenDebugEnabledFlag: true, 263 givenPubID: PublisherUnknown, 264 expectedAccountDebugCount: 0, 265 expectedDebugCount: 1, 266 }, 267 { 268 description: "Debug is disabled, account debug is enabled, niether metric should update", 269 givenDisabledMetrics: config.DisabledMetrics{ 270 AccountAdapterDetails: true, 271 AccountDebug: false, 272 }, 273 givenDebugEnabledFlag: false, 274 givenPubID: "acct-id", 275 expectedAccountDebugCount: 0, 276 expectedDebugCount: 0, 277 }, 278 } 279 adapter := "AnyName" 280 for _, test := range testCases { 281 registry := metrics.NewRegistry() 282 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, test.givenDisabledMetrics, nil, nil) 283 284 m.RecordDebugRequest(test.givenDebugEnabledFlag, test.givenPubID) 285 am := m.getAccountMetrics(test.givenPubID) 286 287 assert.Equal(t, test.expectedDebugCount, m.DebugRequestMeter.Count()) 288 assert.Equal(t, test.expectedAccountDebugCount, am.debugRequestMeter.Count()) 289 } 290 } 291 292 func TestRecordBidValidationCreativeSize(t *testing.T) { 293 testCases := []struct { 294 description string 295 givenDisabledMetrics config.DisabledMetrics 296 givenPubID string 297 expectedAccountCount int64 298 expectedAdapterCount int64 299 }{ 300 { 301 description: "Account Metric isn't disabled, so both metrics should be incremented", 302 givenDisabledMetrics: config.DisabledMetrics{ 303 AccountAdapterDetails: false, 304 }, 305 givenPubID: "acct-id", 306 expectedAdapterCount: 1, 307 expectedAccountCount: 1, 308 }, 309 { 310 description: "Account Metric is disabled, so only the adapter metric should increment", 311 givenDisabledMetrics: config.DisabledMetrics{ 312 AccountAdapterDetails: true, 313 }, 314 givenPubID: "acct-id", 315 expectedAdapterCount: 1, 316 expectedAccountCount: 0, 317 }, 318 } 319 adapter := "AnyName" 320 lowerCaseAdapter := "anyname" 321 for _, test := range testCases { 322 registry := metrics.NewRegistry() 323 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, test.givenDisabledMetrics, nil, nil) 324 325 m.RecordBidValidationCreativeSizeError(openrtb_ext.BidderName(adapter), test.givenPubID) 326 m.RecordBidValidationCreativeSizeWarn(openrtb_ext.BidderName(adapter), test.givenPubID) 327 am := m.getAccountMetrics(test.givenPubID) 328 329 assert.Equal(t, test.expectedAdapterCount, m.AdapterMetrics[lowerCaseAdapter].BidValidationCreativeSizeErrorMeter.Count()) 330 assert.Equal(t, test.expectedAdapterCount, m.AdapterMetrics[lowerCaseAdapter].BidValidationCreativeSizeWarnMeter.Count()) 331 assert.Equal(t, test.expectedAccountCount, am.bidValidationCreativeSizeMeter.Count()) 332 assert.Equal(t, test.expectedAccountCount, am.bidValidationCreativeSizeWarnMeter.Count()) 333 } 334 } 335 336 func TestRecordBidValidationSecureMarkup(t *testing.T) { 337 testCases := []struct { 338 description string 339 givenDisabledMetrics config.DisabledMetrics 340 givenPubID string 341 expectedAccountCount int64 342 expectedAdapterCount int64 343 }{ 344 { 345 description: "Account Metric isn't disabled, so both metrics should be incremented", 346 givenDisabledMetrics: config.DisabledMetrics{ 347 AccountAdapterDetails: false, 348 }, 349 givenPubID: "acct-id", 350 expectedAdapterCount: 1, 351 expectedAccountCount: 1, 352 }, 353 { 354 description: "Account Metric is disabled, so only the adapter metric should increment", 355 givenDisabledMetrics: config.DisabledMetrics{ 356 AccountAdapterDetails: true, 357 }, 358 givenPubID: "acct-id", 359 expectedAdapterCount: 1, 360 expectedAccountCount: 0, 361 }, 362 } 363 adapter := "AnyName" 364 lowerCaseAdapter := "anyname" 365 for _, test := range testCases { 366 registry := metrics.NewRegistry() 367 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, test.givenDisabledMetrics, nil, nil) 368 369 m.RecordBidValidationSecureMarkupError(openrtb_ext.BidderName(adapter), test.givenPubID) 370 m.RecordBidValidationSecureMarkupWarn(openrtb_ext.BidderName(adapter), test.givenPubID) 371 am := m.getAccountMetrics(test.givenPubID) 372 373 assert.Equal(t, test.expectedAdapterCount, m.AdapterMetrics[lowerCaseAdapter].BidValidationSecureMarkupErrorMeter.Count()) 374 assert.Equal(t, test.expectedAdapterCount, m.AdapterMetrics[lowerCaseAdapter].BidValidationSecureMarkupWarnMeter.Count()) 375 assert.Equal(t, test.expectedAccountCount, am.bidValidationSecureMarkupMeter.Count()) 376 assert.Equal(t, test.expectedAccountCount, am.bidValidationSecureMarkupWarnMeter.Count()) 377 } 378 } 379 380 func TestRecordDNSTime(t *testing.T) { 381 testCases := []struct { 382 description string 383 inDnsLookupDuration time.Duration 384 outExpDuration time.Duration 385 }{ 386 { 387 description: "Five second DNS lookup time", 388 inDnsLookupDuration: time.Second * 5, 389 outExpDuration: time.Second * 5, 390 }, 391 { 392 description: "Zero DNS lookup time", 393 inDnsLookupDuration: time.Duration(0), 394 outExpDuration: time.Duration(0), 395 }, 396 } 397 adapter := "AnyName" 398 for _, test := range testCases { 399 registry := metrics.NewRegistry() 400 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) 401 402 m.RecordDNSTime(test.inDnsLookupDuration) 403 404 assert.Equal(t, test.outExpDuration.Nanoseconds(), m.DNSLookupTimer.Sum(), test.description) 405 } 406 } 407 408 func TestRecordTLSHandshakeTime(t *testing.T) { 409 testCases := []struct { 410 description string 411 tLSHandshakeDuration time.Duration 412 expectedDuration time.Duration 413 }{ 414 { 415 description: "Five second TLS handshake time", 416 tLSHandshakeDuration: time.Second * 5, 417 expectedDuration: time.Second * 5, 418 }, 419 { 420 description: "Zero TLS handshake time", 421 tLSHandshakeDuration: time.Duration(0), 422 expectedDuration: time.Duration(0), 423 }, 424 } 425 adapter := "AnyName" 426 for _, test := range testCases { 427 registry := metrics.NewRegistry() 428 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) 429 430 m.RecordTLSHandshakeTime(test.tLSHandshakeDuration) 431 432 assert.Equal(t, test.expectedDuration.Nanoseconds(), m.TLSHandshakeTimer.Sum(), test.description) 433 } 434 } 435 436 func TestRecordBidderServerResponseTime(t *testing.T) { 437 testCases := []struct { 438 name string 439 time time.Duration 440 expectedCount int64 441 expectedSum int64 442 }{ 443 { 444 name: "record-bidder-server-response-time-1", 445 time: time.Duration(500), 446 expectedCount: 1, 447 expectedSum: 500, 448 }, 449 { 450 name: "record-bidder-server-response-time-2", 451 time: time.Duration(500), 452 expectedCount: 2, 453 expectedSum: 1000, 454 }, 455 } 456 adapter := "AnyName" 457 for _, test := range testCases { 458 registry := metrics.NewRegistry() 459 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) 460 461 m.RecordBidderServerResponseTime(test.time) 462 463 assert.Equal(t, test.time.Nanoseconds(), m.BidderServerResponseTimer.Sum(), test.name) 464 } 465 } 466 467 func TestRecordAdapterConnections(t *testing.T) { 468 var fakeBidder openrtb_ext.BidderName = "fooAdvertising" 469 470 type testIn struct { 471 adapterName openrtb_ext.BidderName 472 connWasReused bool 473 connWait time.Duration 474 connMetricsDisabled bool 475 } 476 477 type testOut struct { 478 expectedConnReusedCount int64 479 expectedConnCreatedCount int64 480 expectedConnWaitTime time.Duration 481 } 482 adapter := "AnyName" 483 lowerCaseAdapterName := "anyname" 484 testCases := []struct { 485 description string 486 in testIn 487 out testOut 488 }{ 489 { 490 description: "Successful, new connection created, has connection wait", 491 in: testIn{ 492 adapterName: openrtb_ext.BidderName(adapter), 493 connWasReused: false, 494 connWait: time.Second * 5, 495 connMetricsDisabled: false, 496 }, 497 out: testOut{ 498 expectedConnReusedCount: 0, 499 expectedConnCreatedCount: 1, 500 expectedConnWaitTime: time.Second * 5, 501 }, 502 }, 503 { 504 description: "Successful, new connection created, has connection wait", 505 in: testIn{ 506 adapterName: openrtb_ext.BidderName(adapter), 507 connWasReused: false, 508 connWait: time.Second * 4, 509 connMetricsDisabled: false, 510 }, 511 out: testOut{ 512 expectedConnCreatedCount: 1, 513 expectedConnWaitTime: time.Second * 4, 514 }, 515 }, 516 { 517 description: "Successful, was reused, no connection wait", 518 in: testIn{ 519 adapterName: openrtb_ext.BidderName(adapter), 520 connWasReused: true, 521 connMetricsDisabled: false, 522 }, 523 out: testOut{ 524 expectedConnReusedCount: 1, 525 expectedConnWaitTime: 0, 526 }, 527 }, 528 { 529 description: "Successful, was reused, has connection wait", 530 in: testIn{ 531 adapterName: openrtb_ext.BidderName(adapter), 532 connWasReused: true, 533 connWait: time.Second * 5, 534 connMetricsDisabled: false, 535 }, 536 out: testOut{ 537 expectedConnReusedCount: 1, 538 expectedConnWaitTime: time.Second * 5, 539 }, 540 }, 541 { 542 description: "Fake bidder, nothing gets updated", 543 in: testIn{ 544 adapterName: fakeBidder, 545 connWasReused: false, 546 connWait: 0, 547 connMetricsDisabled: false, 548 }, 549 out: testOut{}, 550 }, 551 { 552 description: "Adapter connection metrics are disabled, nothing gets updated", 553 in: testIn{ 554 adapterName: openrtb_ext.BidderName(adapter), 555 connWasReused: false, 556 connWait: time.Second * 5, 557 connMetricsDisabled: true, 558 }, 559 out: testOut{}, 560 }, 561 } 562 563 for i, test := range testCases { 564 registry := metrics.NewRegistry() 565 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, config.DisabledMetrics{AdapterConnectionMetrics: test.in.connMetricsDisabled}, nil, nil) 566 567 m.RecordAdapterConnections(test.in.adapterName, test.in.connWasReused, test.in.connWait) 568 assert.Equal(t, test.out.expectedConnReusedCount, m.AdapterMetrics[lowerCaseAdapterName].ConnReused.Count(), "Test [%d] incorrect number of reused connections to adapter", i) 569 assert.Equal(t, test.out.expectedConnCreatedCount, m.AdapterMetrics[lowerCaseAdapterName].ConnCreated.Count(), "Test [%d] incorrect number of new connections to adapter created", i) 570 assert.Equal(t, test.out.expectedConnWaitTime.Nanoseconds(), m.AdapterMetrics[lowerCaseAdapterName].ConnWaitTime.Sum(), "Test [%d] incorrect wait time in connection to adapter", i) 571 } 572 } 573 574 func TestNewMetricsWithDisabledConfig(t *testing.T) { 575 registry := metrics.NewRegistry() 576 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("Foo"), openrtb_ext.BidderName("bar")}, config.DisabledMetrics{AccountAdapterDetails: true, AccountModulesMetrics: true}, nil, map[string][]string{"foobar": {"entry", "raw"}}) 577 578 assert.True(t, m.MetricsDisabled.AccountAdapterDetails, "Accound adapter metrics should be disabled") 579 assert.True(t, m.MetricsDisabled.AccountModulesMetrics, "Accound modules metrics should be disabled") 580 } 581 582 func TestRecordPrebidCacheRequestTimeWithSuccess(t *testing.T) { 583 registry := metrics.NewRegistry() 584 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("Foo")}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) 585 586 m.RecordPrebidCacheRequestTime(true, 42) 587 588 assert.Equal(t, m.PrebidCacheRequestTimerSuccess.Count(), int64(1)) 589 assert.Equal(t, m.PrebidCacheRequestTimerError.Count(), int64(0)) 590 } 591 592 func TestRecordPrebidCacheRequestTimeWithNotSuccess(t *testing.T) { 593 registry := metrics.NewRegistry() 594 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("Foo")}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) 595 596 m.RecordPrebidCacheRequestTime(false, 42) 597 598 assert.Equal(t, m.PrebidCacheRequestTimerSuccess.Count(), int64(0)) 599 assert.Equal(t, m.PrebidCacheRequestTimerError.Count(), int64(1)) 600 } 601 602 func TestRecordStoredDataFetchTime(t *testing.T) { 603 tests := []struct { 604 description string 605 dataType StoredDataType 606 fetchType StoredDataFetchType 607 }{ 608 { 609 description: "Update stored_account_fetch_time.all timer", 610 dataType: AccountDataType, 611 fetchType: FetchAll, 612 }, 613 { 614 description: "Update stored_amp_fetch_time.all timer", 615 dataType: AMPDataType, 616 fetchType: FetchAll, 617 }, 618 { 619 description: "Update stored_category_fetch_time.all timer", 620 dataType: CategoryDataType, 621 fetchType: FetchAll, 622 }, 623 { 624 description: "Update stored_request_fetch_time.all timer", 625 dataType: RequestDataType, 626 fetchType: FetchAll, 627 }, 628 { 629 description: "Update stored_video_fetch_time.all timer", 630 dataType: VideoDataType, 631 fetchType: FetchAll, 632 }, 633 { 634 description: "Update stored_account_fetch_time.delta timer", 635 dataType: AccountDataType, 636 fetchType: FetchDelta, 637 }, 638 { 639 description: "Update stored_amp_fetch_time.delta timer", 640 dataType: AMPDataType, 641 fetchType: FetchDelta, 642 }, 643 { 644 description: "Update stored_category_fetch_time.delta timer", 645 dataType: CategoryDataType, 646 fetchType: FetchDelta, 647 }, 648 { 649 description: "Update stored_request_fetch_time.delta timer", 650 dataType: RequestDataType, 651 fetchType: FetchDelta, 652 }, 653 { 654 description: "Update stored_video_fetch_time.delta timer", 655 dataType: VideoDataType, 656 fetchType: FetchDelta, 657 }, 658 } 659 660 for _, tt := range tests { 661 registry := metrics.NewRegistry() 662 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("Foo"), openrtb_ext.BidderName("Bar")}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) 663 m.RecordStoredDataFetchTime(StoredDataLabels{ 664 DataType: tt.dataType, 665 DataFetchType: tt.fetchType, 666 }, time.Duration(500)) 667 668 actualCount := m.StoredDataFetchTimer[tt.dataType][tt.fetchType].Count() 669 assert.Equal(t, int64(1), actualCount, tt.description) 670 671 actualDuration := m.StoredDataFetchTimer[tt.dataType][tt.fetchType].Sum() 672 assert.Equal(t, int64(500), actualDuration, tt.description) 673 } 674 } 675 676 func TestRecordStoredDataError(t *testing.T) { 677 tests := []struct { 678 description string 679 dataType StoredDataType 680 errorType StoredDataError 681 }{ 682 { 683 description: "Increment stored_account_error.network meter", 684 dataType: AccountDataType, 685 errorType: StoredDataErrorNetwork, 686 }, 687 { 688 description: "Increment stored_amp_error.network meter", 689 dataType: AMPDataType, 690 errorType: StoredDataErrorNetwork, 691 }, 692 { 693 description: "Increment stored_category_error.network meter", 694 dataType: CategoryDataType, 695 errorType: StoredDataErrorNetwork, 696 }, 697 { 698 description: "Increment stored_request_error.network meter", 699 dataType: RequestDataType, 700 errorType: StoredDataErrorNetwork, 701 }, 702 { 703 description: "Increment stored_video_error.network meter", 704 dataType: VideoDataType, 705 errorType: StoredDataErrorNetwork, 706 }, 707 { 708 description: "Increment stored_account_error.undefined meter", 709 dataType: AccountDataType, 710 errorType: StoredDataErrorUndefined, 711 }, 712 { 713 description: "Increment stored_amp_error.undefined meter", 714 dataType: AMPDataType, 715 errorType: StoredDataErrorUndefined, 716 }, 717 { 718 description: "Increment stored_category_error.undefined meter", 719 dataType: CategoryDataType, 720 errorType: StoredDataErrorUndefined, 721 }, 722 { 723 description: "Increment stored_request_error.undefined meter", 724 dataType: RequestDataType, 725 errorType: StoredDataErrorUndefined, 726 }, 727 { 728 description: "Increment stored_video_error.undefined meter", 729 dataType: VideoDataType, 730 errorType: StoredDataErrorUndefined, 731 }, 732 } 733 734 for _, tt := range tests { 735 registry := metrics.NewRegistry() 736 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("Foo"), openrtb_ext.BidderName("Bar")}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) 737 m.RecordStoredDataError(StoredDataLabels{ 738 DataType: tt.dataType, 739 Error: tt.errorType, 740 }) 741 742 actualCount := m.StoredDataErrorMeter[tt.dataType][tt.errorType].Count() 743 assert.Equal(t, int64(1), actualCount, tt.description) 744 } 745 } 746 747 func TestRecordRequestPrivacy(t *testing.T) { 748 registry := metrics.NewRegistry() 749 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("Foo"), openrtb_ext.BidderName("Bar")}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) 750 751 // CCPA 752 m.RecordRequestPrivacy(PrivacyLabels{ 753 CCPAEnforced: true, 754 CCPAProvided: true, 755 }) 756 m.RecordRequestPrivacy(PrivacyLabels{ 757 CCPAEnforced: true, 758 CCPAProvided: false, 759 }) 760 m.RecordRequestPrivacy(PrivacyLabels{ 761 CCPAEnforced: false, 762 CCPAProvided: true, 763 }) 764 765 // COPPA 766 m.RecordRequestPrivacy(PrivacyLabels{ 767 COPPAEnforced: true, 768 }) 769 770 // LMT 771 m.RecordRequestPrivacy(PrivacyLabels{ 772 LMTEnforced: true, 773 }) 774 775 // GDPR 776 m.RecordRequestPrivacy(PrivacyLabels{ 777 GDPREnforced: true, 778 GDPRTCFVersion: TCFVersionErr, 779 }) 780 m.RecordRequestPrivacy(PrivacyLabels{ 781 GDPREnforced: true, 782 GDPRTCFVersion: TCFVersionV2, 783 }) 784 785 assert.Equal(t, m.PrivacyCCPARequest.Count(), int64(2), "CCPA") 786 assert.Equal(t, m.PrivacyCCPARequestOptOut.Count(), int64(1), "CCPA Opt Out") 787 assert.Equal(t, m.PrivacyCOPPARequest.Count(), int64(1), "COPPA") 788 assert.Equal(t, m.PrivacyLMTRequest.Count(), int64(1), "LMT") 789 assert.Equal(t, m.PrivacyTCFRequestVersion[TCFVersionErr].Count(), int64(1), "TCF Err") 790 assert.Equal(t, m.PrivacyTCFRequestVersion[TCFVersionV2].Count(), int64(1), "TCF V2") 791 } 792 793 func TestRecordAdapterBuyerUIDScrubbed(t *testing.T) { 794 var fakeBidder openrtb_ext.BidderName = "fooAdvertising" 795 adapter := "AnyName" 796 lowerCaseAdapterName := "anyname" 797 798 tests := []struct { 799 name string 800 metricsDisabled bool 801 adapterName openrtb_ext.BidderName 802 expectedCount int64 803 }{ 804 { 805 name: "enabled_bidder_found", 806 metricsDisabled: false, 807 adapterName: openrtb_ext.BidderName(adapter), 808 expectedCount: 1, 809 }, 810 { 811 name: "enabled_bidder_not_found", 812 metricsDisabled: false, 813 adapterName: fakeBidder, 814 expectedCount: 0, 815 }, 816 { 817 name: "disabled", 818 metricsDisabled: true, 819 adapterName: openrtb_ext.BidderName(adapter), 820 expectedCount: 0, 821 }, 822 } 823 for _, tt := range tests { 824 t.Run(tt.name, func(t *testing.T) { 825 registry := metrics.NewRegistry() 826 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, config.DisabledMetrics{AdapterBuyerUIDScrubbed: tt.metricsDisabled}, nil, nil) 827 828 m.RecordAdapterBuyerUIDScrubbed(tt.adapterName) 829 830 assert.Equal(t, tt.expectedCount, m.AdapterMetrics[lowerCaseAdapterName].BuyerUIDScrubbed.Count()) 831 }) 832 } 833 } 834 835 func TestRecordAdapterGDPRRequestBlocked(t *testing.T) { 836 var fakeBidder openrtb_ext.BidderName = "fooAdvertising" 837 adapter := "AnyName" 838 lowerCaseAdapterName := "anyname" 839 840 tests := []struct { 841 name string 842 metricsDisabled bool 843 adapterName openrtb_ext.BidderName 844 expectedCount int64 845 }{ 846 { 847 name: "enabled_bidder_found", 848 metricsDisabled: false, 849 adapterName: openrtb_ext.BidderName(adapter), 850 expectedCount: 1, 851 }, 852 { 853 name: "enabled_bidder_not_found", 854 metricsDisabled: false, 855 adapterName: fakeBidder, 856 expectedCount: 0, 857 }, 858 { 859 name: "disabled", 860 metricsDisabled: true, 861 adapterName: openrtb_ext.BidderName(adapter), 862 expectedCount: 0, 863 }, 864 } 865 for _, tt := range tests { 866 t.Run(tt.name, func(t *testing.T) { 867 registry := metrics.NewRegistry() 868 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, config.DisabledMetrics{AdapterGDPRRequestBlocked: tt.metricsDisabled}, nil, nil) 869 870 m.RecordAdapterGDPRRequestBlocked(tt.adapterName) 871 872 assert.Equal(t, tt.expectedCount, m.AdapterMetrics[lowerCaseAdapterName].GDPRRequestBlocked.Count()) 873 }) 874 } 875 } 876 877 func TestRecordCookieSync(t *testing.T) { 878 registry := metrics.NewRegistry() 879 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("Foo"), openrtb_ext.BidderName("Bar")}, config.DisabledMetrics{}, nil, nil) 880 881 // Known 882 m.RecordCookieSync(CookieSyncBadRequest) 883 884 // Unknown 885 m.RecordCookieSync(CookieSyncStatus("unknown status")) 886 887 assert.Equal(t, m.CookieSyncMeter.Count(), int64(2)) 888 assert.Equal(t, m.CookieSyncStatusMeter[CookieSyncOK].Count(), int64(0)) 889 assert.Equal(t, m.CookieSyncStatusMeter[CookieSyncBadRequest].Count(), int64(1)) 890 assert.Equal(t, m.CookieSyncStatusMeter[CookieSyncOptOut].Count(), int64(0)) 891 assert.Equal(t, m.CookieSyncStatusMeter[CookieSyncGDPRHostCookieBlocked].Count(), int64(0)) 892 } 893 894 func TestRecordSyncerRequest(t *testing.T) { 895 registry := metrics.NewRegistry() 896 syncerKeys := []string{"foo"} 897 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("Adapter1"), openrtb_ext.BidderName("Adapter2")}, config.DisabledMetrics{}, syncerKeys, nil) 898 899 // Known 900 m.RecordSyncerRequest("foo", SyncerCookieSyncOK) 901 902 // Unknown Bidder 903 m.RecordSyncerRequest("bar", SyncerCookieSyncOK) 904 905 // Unknown Status 906 m.RecordSyncerRequest("foo", SyncerCookieSyncStatus("unknown status")) 907 908 assert.Equal(t, m.SyncerRequestsMeter["foo"][SyncerCookieSyncOK].Count(), int64(1)) 909 assert.Equal(t, m.SyncerRequestsMeter["foo"][SyncerCookieSyncPrivacyBlocked].Count(), int64(0)) 910 assert.Equal(t, m.SyncerRequestsMeter["foo"][SyncerCookieSyncAlreadySynced].Count(), int64(0)) 911 assert.Equal(t, m.SyncerRequestsMeter["foo"][SyncerCookieSyncTypeNotSupported].Count(), int64(0)) 912 } 913 914 func TestRecordSetUid(t *testing.T) { 915 registry := metrics.NewRegistry() 916 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("Foo"), openrtb_ext.BidderName("Bar")}, config.DisabledMetrics{}, nil, nil) 917 918 // Known 919 m.RecordSetUid(SetUidOptOut) 920 921 // Unknown 922 m.RecordSetUid(SetUidStatus("unknown status")) 923 924 assert.Equal(t, m.SetUidMeter.Count(), int64(2)) 925 assert.Equal(t, m.SetUidStatusMeter[SetUidOK].Count(), int64(0)) 926 assert.Equal(t, m.SetUidStatusMeter[SetUidBadRequest].Count(), int64(0)) 927 assert.Equal(t, m.SetUidStatusMeter[SetUidOptOut].Count(), int64(1)) 928 assert.Equal(t, m.SetUidStatusMeter[SetUidGDPRHostCookieBlocked].Count(), int64(0)) 929 assert.Equal(t, m.SetUidStatusMeter[SetUidSyncerUnknown].Count(), int64(0)) 930 } 931 932 func TestRecordSyncerSet(t *testing.T) { 933 registry := metrics.NewRegistry() 934 syncerKeys := []string{"foo"} 935 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("Adapter1"), openrtb_ext.BidderName("Adapter2")}, config.DisabledMetrics{}, syncerKeys, nil) 936 937 // Known 938 m.RecordSyncerSet("foo", SyncerSetUidCleared) 939 940 // Unknown Bidder 941 m.RecordSyncerSet("bar", SyncerSetUidCleared) 942 943 // Unknown Status 944 m.RecordSyncerSet("foo", SyncerSetUidStatus("unknown status")) 945 946 assert.Equal(t, m.SyncerSetsMeter["foo"][SyncerSetUidOK].Count(), int64(0)) 947 assert.Equal(t, m.SyncerSetsMeter["foo"][SyncerSetUidCleared].Count(), int64(1)) 948 } 949 950 func TestStoredResponses(t *testing.T) { 951 testCases := []struct { 952 description string 953 givenPubID string 954 accountStoredResponsesMetricsDisabled bool 955 expectedAccountStoredResponsesCount int64 956 expectedStoredResponsesCount int64 957 }{ 958 { 959 description: "Publisher id is given, account stored responses disabled, both metrics should be updated", 960 givenPubID: "acct-id", 961 accountStoredResponsesMetricsDisabled: true, 962 expectedAccountStoredResponsesCount: 0, 963 expectedStoredResponsesCount: 1, 964 }, 965 { 966 description: "Publisher id is given, account stored responses enabled, both metrics should be updated", 967 givenPubID: "acct-id", 968 accountStoredResponsesMetricsDisabled: false, 969 expectedAccountStoredResponsesCount: 1, 970 expectedStoredResponsesCount: 1, 971 }, 972 { 973 description: "Publisher id is unknown, account stored responses enabled, only expectedStoredResponsesCount metric should be updated", 974 givenPubID: PublisherUnknown, 975 accountStoredResponsesMetricsDisabled: false, 976 expectedAccountStoredResponsesCount: 0, 977 expectedStoredResponsesCount: 1, 978 }, 979 { 980 description: "Publisher id is unknown, account stored responses disabled, only expectedStoredResponsesCount metric should be updated", 981 givenPubID: PublisherUnknown, 982 accountStoredResponsesMetricsDisabled: true, 983 expectedAccountStoredResponsesCount: 0, 984 expectedStoredResponsesCount: 1, 985 }, 986 } 987 for _, test := range testCases { 988 registry := metrics.NewRegistry() 989 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("AnyName")}, config.DisabledMetrics{AccountStoredResponses: test.accountStoredResponsesMetricsDisabled}, nil, nil) 990 991 m.RecordStoredResponse(test.givenPubID) 992 am := m.getAccountMetrics(test.givenPubID) 993 994 assert.Equal(t, test.expectedStoredResponsesCount, m.StoredResponsesMeter.Count()) 995 assert.Equal(t, test.expectedAccountStoredResponsesCount, am.storedResponsesMeter.Count()) 996 } 997 } 998 999 func TestRecordAdsCertSignTime(t *testing.T) { 1000 testCases := []struct { 1001 description string 1002 inAdsCertSignDuration time.Duration 1003 outExpDuration time.Duration 1004 }{ 1005 { 1006 description: "Five second AdsCertSign time", 1007 inAdsCertSignDuration: time.Second * 5, 1008 outExpDuration: time.Second * 5, 1009 }, 1010 { 1011 description: "Five millisecond AdsCertSign time", 1012 inAdsCertSignDuration: time.Millisecond * 5, 1013 outExpDuration: time.Millisecond * 5, 1014 }, 1015 { 1016 description: "Zero AdsCertSign time", 1017 inAdsCertSignDuration: time.Duration(0), 1018 outExpDuration: time.Duration(0), 1019 }, 1020 } 1021 for _, test := range testCases { 1022 registry := metrics.NewRegistry() 1023 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("AnyName")}, config.DisabledMetrics{}, nil, nil) 1024 1025 m.RecordAdsCertSignTime(test.inAdsCertSignDuration) 1026 1027 assert.Equal(t, test.outExpDuration.Nanoseconds(), m.adsCertSignTimer.Sum(), test.description) 1028 } 1029 } 1030 1031 func TestRecordAdsCertReqMetric(t *testing.T) { 1032 testCases := []struct { 1033 description string 1034 requestSuccess bool 1035 expectedSuccessRequestsCount int64 1036 expectedFailedRequestsCount int64 1037 }{ 1038 { 1039 description: "Record failed request, expected success request count is 0 and failed request count is 1", 1040 requestSuccess: false, 1041 expectedSuccessRequestsCount: 0, 1042 expectedFailedRequestsCount: 1, 1043 }, 1044 { 1045 description: "Record successful request, expected success request count is 1 and failed request count is 0", 1046 requestSuccess: true, 1047 expectedSuccessRequestsCount: 1, 1048 expectedFailedRequestsCount: 0, 1049 }, 1050 } 1051 1052 for _, test := range testCases { 1053 registry := metrics.NewRegistry() 1054 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("AnyName")}, config.DisabledMetrics{}, nil, nil) 1055 1056 m.RecordAdsCertReq(test.requestSuccess) 1057 1058 assert.Equal(t, test.expectedSuccessRequestsCount, m.AdsCertRequestsSuccess.Count(), test.description) 1059 assert.Equal(t, test.expectedFailedRequestsCount, m.AdsCertRequestsFailure.Count(), test.description) 1060 } 1061 } 1062 1063 func TestRecordModuleAccountMetrics(t *testing.T) { 1064 registry := metrics.NewRegistry() 1065 module := "foobar" 1066 stage1 := "entrypoint" 1067 stage2 := "raw_auction" 1068 stage3 := "processed_auction" 1069 1070 testCases := []struct { 1071 description string 1072 givenModuleName string 1073 givenStageName string 1074 givenPubID string 1075 givenDisabledMetrics config.DisabledMetrics 1076 expectedModuleMetricCount int64 1077 expectedAccountMetricCount int64 1078 }{ 1079 { 1080 description: "Entrypoint stage should not record account metrics", 1081 givenModuleName: module, 1082 givenStageName: stage1, 1083 givenDisabledMetrics: config.DisabledMetrics{AccountModulesMetrics: false}, 1084 expectedModuleMetricCount: 1, 1085 expectedAccountMetricCount: 0, 1086 }, 1087 { 1088 description: "Rawauction stage should record both metrics", 1089 givenModuleName: module, 1090 givenStageName: stage2, 1091 givenPubID: "acc-1", 1092 givenDisabledMetrics: config.DisabledMetrics{AccountModulesMetrics: false}, 1093 expectedModuleMetricCount: 1, 1094 expectedAccountMetricCount: 1, 1095 }, 1096 { 1097 description: "Rawauction stage should not record account metrics because they are disabled", 1098 givenModuleName: module, 1099 givenStageName: stage3, 1100 givenPubID: "acc-1", 1101 givenDisabledMetrics: config.DisabledMetrics{AccountModulesMetrics: true}, 1102 expectedModuleMetricCount: 1, 1103 expectedAccountMetricCount: 0, 1104 }, 1105 } 1106 for _, test := range testCases { 1107 m := NewMetrics(registry, nil, test.givenDisabledMetrics, nil, map[string][]string{module: {stage1, stage2, stage3}}) 1108 1109 m.RecordModuleCalled(ModuleLabels{ 1110 Module: test.givenModuleName, 1111 Stage: test.givenStageName, 1112 AccountID: test.givenPubID, 1113 }, time.Microsecond) 1114 am := m.getAccountMetrics(test.givenPubID) 1115 1116 assert.Equal(t, test.expectedModuleMetricCount, m.ModuleMetrics[test.givenModuleName][test.givenStageName].CallCounter.Count()) 1117 if !test.givenDisabledMetrics.AccountModulesMetrics { 1118 assert.Equal(t, test.expectedAccountMetricCount, am.moduleMetrics[test.givenModuleName].CallCounter.Count()) 1119 assert.Equal(t, test.expectedAccountMetricCount, am.moduleMetrics[test.givenModuleName].DurationTimer.Count()) 1120 } else { 1121 assert.Len(t, am.moduleMetrics, 0, "Account modules metrics are disabled, they should not be collected. Actual result %d account metrics collected \n", len(am.moduleMetrics)) 1122 } 1123 } 1124 } 1125 1126 func TestRecordOverheadTime(t *testing.T) { 1127 testCases := []struct { 1128 name string 1129 time time.Duration 1130 overheadType OverheadType 1131 expectedCount int64 1132 expectedSum int64 1133 }{ 1134 { 1135 name: "record-pre-bidder-overhead-time-1", 1136 time: time.Duration(500), 1137 overheadType: PreBidder, 1138 expectedCount: 1, 1139 expectedSum: 500, 1140 }, 1141 { 1142 name: "record-pre-bidder-overhead-time-2", 1143 time: time.Duration(500), 1144 overheadType: PreBidder, 1145 expectedCount: 2, 1146 expectedSum: 1000, 1147 }, 1148 { 1149 name: "record-auction-response-overhead-time", 1150 time: time.Duration(500), 1151 overheadType: MakeAuctionResponse, 1152 expectedCount: 1, 1153 expectedSum: 500, 1154 }, 1155 { 1156 name: "record-make-bidder-requests-overhead-time", 1157 time: time.Duration(500), 1158 overheadType: MakeBidderRequests, 1159 expectedCount: 1, 1160 expectedSum: 500, 1161 }, 1162 } 1163 registry := metrics.NewRegistry() 1164 for _, test := range testCases { 1165 t.Run(test.name, func(t *testing.T) { 1166 m := NewMetrics(registry, []openrtb_ext.BidderName{}, config.DisabledMetrics{}, nil, nil) 1167 m.RecordOverheadTime(test.overheadType, test.time) 1168 overheadMetrics := m.OverheadTimer[test.overheadType] 1169 assert.Equal(t, test.expectedCount, overheadMetrics.Count()) 1170 assert.Equal(t, test.expectedSum, overheadMetrics.Sum()) 1171 }) 1172 } 1173 } 1174 1175 func ensureContainsBidTypeMetrics(t *testing.T, registry metrics.Registry, prefix string, mdm map[openrtb_ext.BidType]*MarkupDeliveryMetrics) { 1176 ensureContains(t, registry, prefix+".banner.adm_bids_received", mdm[openrtb_ext.BidTypeBanner].AdmMeter) 1177 ensureContains(t, registry, prefix+".banner.nurl_bids_received", mdm[openrtb_ext.BidTypeBanner].NurlMeter) 1178 ensureContains(t, registry, prefix+".video.adm_bids_received", mdm[openrtb_ext.BidTypeVideo].AdmMeter) 1179 ensureContains(t, registry, prefix+".video.nurl_bids_received", mdm[openrtb_ext.BidTypeVideo].NurlMeter) 1180 ensureContains(t, registry, prefix+".audio.adm_bids_received", mdm[openrtb_ext.BidTypeAudio].AdmMeter) 1181 ensureContains(t, registry, prefix+".audio.nurl_bids_received", mdm[openrtb_ext.BidTypeAudio].NurlMeter) 1182 ensureContains(t, registry, prefix+".native.adm_bids_received", mdm[openrtb_ext.BidTypeNative].AdmMeter) 1183 ensureContains(t, registry, prefix+".native.nurl_bids_received", mdm[openrtb_ext.BidTypeNative].NurlMeter) 1184 } 1185 1186 func VerifyMetrics(t *testing.T, name string, expected int64, actual int64) { 1187 if expected != actual { 1188 t.Errorf("Error in metric %s: expected %d, got %d.", name, expected, actual) 1189 } 1190 } 1191 1192 func TestRecordAdapterPanic(t *testing.T) { 1193 registry := metrics.NewRegistry() 1194 adapter := "AnyName" 1195 lowerCaseAdapterName := "anyname" 1196 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, config.DisabledMetrics{AccountAdapterDetails: true, AccountModulesMetrics: true}, nil, map[string][]string{"foobar": {"entry", "raw"}}) 1197 m.RecordAdapterPanic(AdapterLabels{Adapter: openrtb_ext.BidderName(adapter)}) 1198 assert.Equal(t, m.AdapterMetrics[lowerCaseAdapterName].PanicMeter.Count(), int64(1)) 1199 } 1200 1201 func TestRecordAdapterPrice(t *testing.T) { 1202 registry := metrics.NewRegistry() 1203 syncerKeys := []string{"foo"} 1204 adapter := "AnyName" 1205 lowerCaseAdapterName := "anyname" 1206 pubID := "pub1" 1207 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter), openrtb_ext.BidderAppnexus}, config.DisabledMetrics{}, syncerKeys, nil) 1208 m.RecordAdapterPrice(AdapterLabels{Adapter: openrtb_ext.BidderName(adapter), PubID: pubID}, 1000) 1209 assert.Equal(t, m.AdapterMetrics[lowerCaseAdapterName].PriceHistogram.Max(), int64(1000)) 1210 assert.Equal(t, m.getAccountMetrics(pubID).adapterMetrics[lowerCaseAdapterName].PriceHistogram.Max(), int64(1000)) 1211 } 1212 1213 func TestRecordAdapterTime(t *testing.T) { 1214 registry := metrics.NewRegistry() 1215 syncerKeys := []string{"foo"} 1216 adapter := "AnyName" 1217 lowerCaseAdapterName := "anyname" 1218 pubID := "pub1" 1219 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter), openrtb_ext.BidderAppnexus, openrtb_ext.BidderName("Adapter2")}, config.DisabledMetrics{}, syncerKeys, nil) 1220 m.RecordAdapterTime(AdapterLabels{Adapter: openrtb_ext.BidderName(adapter), PubID: pubID}, 1000) 1221 assert.Equal(t, m.AdapterMetrics[lowerCaseAdapterName].RequestTimer.Max(), int64(1000)) 1222 assert.Equal(t, m.getAccountMetrics(pubID).adapterMetrics[lowerCaseAdapterName].RequestTimer.Max(), int64(1000)) 1223 } 1224 1225 func TestRecordAdapterRequest(t *testing.T) { 1226 syncerKeys := []string{"foo"} 1227 moduleStageNames := map[string][]string{"foobar": {"entry", "raw"}, "another_module": {"raw", "auction"}} 1228 adapter := "AnyName" 1229 lowerCaseAdapter := "anyname" 1230 type errorCount struct { 1231 badInput, badServer, timeout, failedToRequestBid, validation, tmaxTimeout, unknown int64 1232 } 1233 type adapterBidsCount struct { 1234 NoBid, GotBid int64 1235 } 1236 tests := []struct { 1237 description string 1238 labels AdapterLabels 1239 expectedNoCookieCount int64 1240 expectedAdapterBidsCount adapterBidsCount 1241 expectedErrorCount errorCount 1242 }{ 1243 { 1244 description: "no-bid", 1245 labels: AdapterLabels{ 1246 Adapter: openrtb_ext.BidderName(adapter), 1247 AdapterBids: AdapterBidNone, 1248 PubID: "acc-1", 1249 }, 1250 expectedAdapterBidsCount: adapterBidsCount{NoBid: 1}, 1251 }, 1252 { 1253 description: "got-bid", 1254 labels: AdapterLabels{ 1255 Adapter: openrtb_ext.BidderName(adapter), 1256 AdapterBids: AdapterBidPresent, 1257 PubID: "acc-2", 1258 }, 1259 expectedAdapterBidsCount: adapterBidsCount{GotBid: 1}, 1260 }, 1261 { 1262 description: "adapter-errors", 1263 labels: AdapterLabels{ 1264 Adapter: openrtb_ext.BidderName(adapter), 1265 PubID: "acc-1", 1266 AdapterErrors: map[AdapterError]struct{}{ 1267 AdapterErrorBadInput: {}, 1268 AdapterErrorBadServerResponse: {}, 1269 AdapterErrorFailedToRequestBids: {}, 1270 AdapterErrorTimeout: {}, 1271 AdapterErrorValidation: {}, 1272 AdapterErrorTmaxTimeout: {}, 1273 AdapterErrorUnknown: {}, 1274 }, 1275 }, 1276 expectedErrorCount: errorCount{ 1277 badInput: 1, 1278 badServer: 1, 1279 timeout: 1, 1280 failedToRequestBid: 1, 1281 validation: 1, 1282 tmaxTimeout: 1, 1283 unknown: 1, 1284 }, 1285 }, 1286 } 1287 for _, test := range tests { 1288 t.Run(test.description, func(t *testing.T) { 1289 registry := metrics.NewRegistry() 1290 m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, config.DisabledMetrics{}, syncerKeys, moduleStageNames) 1291 m.RecordAdapterRequest(test.labels) 1292 adapterMetric := m.AdapterMetrics[lowerCaseAdapter] 1293 if assert.NotNil(t, adapterMetric) { 1294 assert.Equal(t, test.expectedAdapterBidsCount, adapterBidsCount{ 1295 NoBid: adapterMetric.NoBidMeter.Count(), 1296 GotBid: adapterMetric.GotBidsMeter.Count(), 1297 }) 1298 } 1299 assert.Equal(t, test.expectedNoCookieCount, adapterMetric.NoCookieMeter.Count()) 1300 adapterErrMetric := adapterMetric.ErrorMeters 1301 if assert.NotNil(t, adapterErrMetric) { 1302 assert.Equal(t, test.expectedErrorCount, errorCount{ 1303 badInput: adapterErrMetric[AdapterErrorBadInput].Count(), 1304 badServer: adapterErrMetric[AdapterErrorBadServerResponse].Count(), 1305 timeout: adapterErrMetric[AdapterErrorTimeout].Count(), 1306 failedToRequestBid: adapterErrMetric[AdapterErrorFailedToRequestBids].Count(), 1307 validation: adapterErrMetric[AdapterErrorValidation].Count(), 1308 tmaxTimeout: adapterErrMetric[AdapterErrorTmaxTimeout].Count(), 1309 unknown: adapterErrMetric[AdapterErrorUnknown].Count(), 1310 }) 1311 } 1312 }) 1313 } 1314 }