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  }