From 1e887e9c792fa2d2ab3b162d25b2b350547b79e6 Mon Sep 17 00:00:00 2001 From: osulzhenko Date: Tue, 18 Feb 2025 15:17:52 +0200 Subject: [PATCH 1/5] Add functional tests for prebid cache trace ability --- .../model/request/cache/BidCachePut.groovy | 1 + .../server/functional/tests/CacheSpec.groovy | 230 ++++++++++++++++-- 2 files changed, 213 insertions(+), 18 deletions(-) diff --git a/src/test/groovy/org/prebid/server/functional/model/request/cache/BidCachePut.groovy b/src/test/groovy/org/prebid/server/functional/model/request/cache/BidCachePut.groovy index 45556c3a4d1..054cc76663b 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/cache/BidCachePut.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/cache/BidCachePut.groovy @@ -14,4 +14,5 @@ class BidCachePut implements ObjectMapperWrapper { String bidder Long timestamp String aid + String key } diff --git a/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy index 4f8dcf7675e..a1edff2c6c2 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy @@ -20,10 +20,20 @@ import static org.prebid.server.functional.model.response.auction.MediaType.VIDE class CacheSpec extends BaseSpec { private final static String PBS_API_HEADER = 'x-pbc-api-key' + private static final Integer MAX_DATACENTER_REGION_LENGTH = 4 + + private final static String XML_CREATIVE_SIZE_METRIC = "account.%s.prebid_cache.creative_size.xml" + private final static String JSON_CREATIVE_SIZE_METRIC = "account.%s.prebid_cache.creative_size.json" + private final static String XML_CREATIVE_TTL_METRIC = "account.%s.prebid_cache.creative_ttl.xml" + private final static String JSON_CREATIVE_TTL_METRIC = "account.%s.prebid_cache.creative_ttl.json" + private final static String CACHE_REQUEST_OK_METRIC = "account.%s.prebid_cache.requests.ok" + private final static String XML_CREATIVE_SIZE_GENERAL_METRIC = "prebid_cache.creative_size.xml" + private final static String JSON_CREATIVE_SIZE_GENERAL_METRIC = "prebid_cache.creative_size.json" + private final static String OK_GENERAL_METRIC = "prebid_cache.requests.ok" def "PBS should update prebid_cache.creative_size.xml metric when xml creative is received"() { given: "Current value of metric prebid_cache.requests.ok" - def initialValue = getCurrentMetricValue(defaultPbsService, "prebid_cache.requests.ok") + def initialValue = getCurrentMetricValue(defaultPbsService, OK_GENERAL_METRIC) and: "Default VtrackRequest" def accountId = PBSUtils.randomNumber.toString() @@ -36,17 +46,17 @@ class CacheSpec extends BaseSpec { then: "prebid_cache.creative_size.xml metric should be updated" def metrics = defaultPbsService.sendCollectedMetricsRequest() def creativeSize = creative.bytes.length - assert metrics["prebid_cache.creative_size.xml"] == creativeSize - assert metrics["prebid_cache.requests.ok"] == initialValue + 1 + assert metrics[OK_GENERAL_METRIC] == initialValue + 1 + assert metrics[XML_CREATIVE_SIZE_GENERAL_METRIC] == creativeSize and: "account..prebid_cache.creative_size.xml should be updated" - assert metrics["account.${accountId}.prebid_cache.creative_size.xml" as String] == creativeSize - assert metrics["account.${accountId}.prebid_cache.requests.ok" as String] == 1 + assert metrics[CACHE_REQUEST_OK_METRIC.formatted(accountId)] == 1 + assert metrics[XML_CREATIVE_SIZE_METRIC.formatted(accountId)] == creativeSize } def "PBS should update prebid_cache.creative_size.json metric when json creative is received"() { given: "Current value of metric prebid_cache.requests.ok" - def initialValue = getCurrentMetricValue(defaultPbsService, "prebid_cache.requests.ok") + def initialValue = getCurrentMetricValue(defaultPbsService, OK_GENERAL_METRIC) and: "Default BidRequest with cache, targeting" def bidRequest = BidRequest.defaultBidRequest @@ -64,18 +74,18 @@ class CacheSpec extends BaseSpec { when: "PBS processes auction request" defaultPbsService.sendAuctionRequest(bidRequest) - and: "PBS processes collected metrics request" - def metrics = defaultPbsService.sendCollectedMetricsRequest() - then: "prebid_cache.creative_size.json should be update" def adm = bidResponse.seatbid[0].bid[0].getAdm() def creativeSize = adm.bytes.length - assert metrics["prebid_cache.creative_size.json"] == creativeSize - assert metrics["prebid_cache.requests.ok"] == initialValue + 1 + + and: "prebid_cache.creative_size.json metric should be updated" + def metrics = defaultPbsService.sendCollectedMetricsRequest() + assert metrics[OK_GENERAL_METRIC] == initialValue + 1 + assert metrics[JSON_CREATIVE_SIZE_GENERAL_METRIC] == creativeSize and: "account..prebid_cache.creative_size.json should be update" - def accountId = bidRequest.site.publisher.id - assert metrics["account.${accountId}.prebid_cache.requests.ok" as String] == 1 + assert metrics[CACHE_REQUEST_OK_METRIC.formatted(bidRequest.accountId)] == 1 + assert metrics[JSON_CREATIVE_SIZE_METRIC.formatted(bidRequest.accountId)] == creativeSize } def "PBS should cache bids when targeting is specified"() { @@ -108,7 +118,6 @@ class CacheSpec extends BaseSpec { pbsService.sendAuctionRequest(bidRequest) then: "PBS should call PBC" - prebidCache.getRequest() assert prebidCache.getRequestCount(bidRequest.imp[0].id) == 1 and: "PBS call shouldn't include api-key" @@ -129,13 +138,198 @@ class CacheSpec extends BaseSpec { pbsService.sendAuctionRequest(bidRequest) then: "PBS should call PBC" - prebidCache.getRequest() assert prebidCache.getRequestCount(bidRequest.imp[0].id) == 1 and: "PBS call should include api-key" assert prebidCache.getRequestHeaders(bidRequest.imp[0].id)[PBS_API_HEADER] == [apiKey] } + def "PBS should cache banner bids with cache key that include account and datacenter short name when append-trace-info-to-cache-id enabled"() { + given: "Pbs config with append-trace-info-to-cache-id" + def serverDataCenter = PBSUtils.randomString + def bannerHostTtl = PBSUtils.getRandomNumber(300, 1500) + def pbsConfig = ['cache.default-ttl-seconds.banner' : bannerHostTtl.toString(), + 'datacenter-region' : serverDataCenter, + 'cache.append-trace-info-to-cache-id': 'true' + ] + def pbsService = pbsServiceFactory.getService(pbsConfig) + + and: "Default BidRequest with cache, targeting" + def bidRequest = BidRequest.defaultBidRequest + bidRequest.enableCache() + bidRequest.ext.prebid.targeting = new Targeting() + + and: "Set bidder response" + def bidResponse = BidResponse.getDefaultBidResponse(bidRequest) + bidder.setResponse(bidRequest.id, bidResponse) + + when: "PBS processes auction request" + pbsService.sendAuctionRequest(bidRequest) + + then: "PBS should call PBC" + assert prebidCache.getRequestCount(bidRequest.imp[0].id) == 1 + + and: "PBS cache key should start with account and datacenter short name" + def cacheKey = prebidCache.getRecordedRequests(bidRequest.imp.id.first).puts.flatten().first.key + assert cacheKey.startsWith("${bidRequest.accountId}-${serverDataCenter.take(MAX_DATACENTER_REGION_LENGTH)}") + + and: "PBS cache key should have length equal to default UUID" + assert cacheKey.length() == UUID.randomUUID().toString().length() + + and: "PBS should include metrics for request" + def metrics = pbsService.sendCollectedMetricsRequest() + assert metrics[JSON_CREATIVE_TTL_METRIC.formatted(bidRequest.accountId)] == bannerHostTtl + assert metrics[CACHE_REQUEST_OK_METRIC.formatted(bidRequest.accountId)] == 1 + + cleanup: "Stop and remove pbs container" + pbsServiceFactory.removeContainer(pbsConfig) + } + + def "PBS should cache video bids with cache key that include account and datacenter short name when append-trace-info-to-cache-id enabled"() { + given: "Pbs config with append-trace-info-to-cache-id" + def serverDataCenter = PBSUtils.randomString + def videoHostTtl = PBSUtils.getRandomNumber(300, 1500) + def pbsConfig = ['cache.default-ttl-seconds.video' : videoHostTtl.toString(), + 'datacenter-region' : serverDataCenter, + 'cache.append-trace-info-to-cache-id': 'true' + ] + def pbsService = pbsServiceFactory.getService(pbsConfig) + + and: "Default BidRequest with cache, targeting" + def bidRequest = BidRequest.defaultVideoRequest + bidRequest.enableCache() + bidRequest.ext.prebid.targeting = new Targeting() + + and: "Set bidder response" + def bidResponse = BidResponse.getDefaultBidResponse(bidRequest) + bidder.setResponse(bidRequest.id, bidResponse) + + when: "PBS processes auction request" + pbsService.sendAuctionRequest(bidRequest) + + then: "PBS should call PBC" + assert prebidCache.getRequestCount(bidRequest.imp[0].id) == 1 + + and: "PBS cache key should start with account and datacenter short name" + def cacheKey = prebidCache.getRecordedRequests(bidRequest.imp.id.first).puts.flatten().first.key + assert cacheKey.startsWith("${bidRequest.accountId}-${serverDataCenter.take(MAX_DATACENTER_REGION_LENGTH)}") + + and: "PBS cache key should have length equal to default UUID" + assert cacheKey.length() == UUID.randomUUID().toString().length() + + and: "PBS should include metrics for request" + def metrics = pbsService.sendCollectedMetricsRequest() + assert metrics[JSON_CREATIVE_TTL_METRIC.formatted(bidRequest.accountId)] == videoHostTtl + assert metrics[XML_CREATIVE_TTL_METRIC.formatted(bidRequest.accountId)] == videoHostTtl + assert metrics[CACHE_REQUEST_OK_METRIC.formatted(bidRequest.accountId)] == 1 + + cleanup: "Stop and remove pbs container" + pbsServiceFactory.removeContainer(pbsConfig) + } + + def "PBS should cache bids with cache key that include account when append-trace-info-to-cache-id enabled and datacenter is null"() { + given: "Pbs config with append-trace-info-to-cache-id" + def bannerHostTtl = PBSUtils.getRandomNumber(300, 1500) + def pbsConfig = ['cache.default-ttl-seconds.banner' : bannerHostTtl.toString(), + 'datacenter-region' : null, + 'cache.append-trace-info-to-cache-id': 'true' + ] + def pbsService = pbsServiceFactory.getService(pbsConfig) + + and: "Default BidRequest with cache, targeting" + def bidRequest = BidRequest.defaultBidRequest + bidRequest.enableCache() + bidRequest.ext.prebid.targeting = new Targeting() + + when: "PBS processes auction request" + pbsService.sendAuctionRequest(bidRequest) + + then: "PBS should call PBC" + assert prebidCache.getRequestCount(bidRequest.imp[0].id) == 1 + + and: "PBS cache key should start with account and datacenter short name" + def cacheKey = prebidCache.getRecordedRequests(bidRequest.imp.id.first).puts.flatten().first.key + assert cacheKey.startsWith("${bidRequest.accountId}-") + + and: "PBS cache key should have length equal to default UUID" + assert cacheKey.length() == UUID.randomUUID().toString().length() + + and: "PBS should include metrics for request" + def metrics = pbsService.sendCollectedMetricsRequest() + assert metrics[JSON_CREATIVE_TTL_METRIC.formatted(bidRequest.accountId)] == bannerHostTtl + assert metrics[CACHE_REQUEST_OK_METRIC.formatted(bidRequest.accountId)] == 1 + + cleanup: "Stop and remove pbs container" + pbsServiceFactory.removeContainer(pbsConfig) + } + + def "PBS should cache bids without cache key when account ID is too large"() { + given: "Pbs config with append-trace-info-to-cache-id" + def serverDataCenter = PBSUtils.randomString + def bannerHostTtl = PBSUtils.getRandomNumber(300, 1500) + def pbsConfig = ['cache.default-ttl-seconds.banner' : bannerHostTtl.toString(), + 'datacenter-region' : serverDataCenter, + 'cache.append-trace-info-to-cache-id': 'true' + ] + def pbsService = pbsServiceFactory.getService(pbsConfig) + + and: "Default BidRequest with cache, targeting and large account ID" + def bidRequest = BidRequest.defaultBidRequest + bidRequest.enableCache() + bidRequest.ext.prebid.targeting = new Targeting() + bidRequest.setAccountId(UUID.randomUUID().toString()) + + when: "PBS processes auction request" + pbsService.sendAuctionRequest(bidRequest) + + then: "PBS should call PBC" + assert prebidCache.getRequestCount(bidRequest.imp[0].id) == 1 + + and: "PBS shouldn't contain cache key" + assert !prebidCache.getRecordedRequests(bidRequest.imp.id.first).puts.flatten().first.key + + and: "PBS should include metrics for request" + def metrics = pbsService.sendCollectedMetricsRequest() + assert metrics[JSON_CREATIVE_TTL_METRIC.formatted(bidRequest.accountId)] == bannerHostTtl + assert metrics[CACHE_REQUEST_OK_METRIC.formatted(bidRequest.accountId)] == 1 + + cleanup: "Stop and remove pbs container" + pbsServiceFactory.removeContainer(pbsConfig) + } + + def "PBS should cache bids without cache key when append-trace-info-to-cache-id disabled"() { + given: "Pbs config with append-trace-info-to-cache-id" + def bannerHostTtl = PBSUtils.getRandomNumber(300, 1500) + def serverDataCenter = PBSUtils.randomString + def pbsConfig = ['cache.default-ttl-seconds.banner' : bannerHostTtl.toString(), + 'datacenter-region' : serverDataCenter, + 'cache.append-trace-info-to-cache-id': 'false' + ] + def pbsService = pbsServiceFactory.getService(pbsConfig) + + and: "Default BidRequest with cache, targeting" + def bidRequest = BidRequest.defaultBidRequest + bidRequest.enableCache() + bidRequest.ext.prebid.targeting = new Targeting() + + when: "PBS processes auction request" + pbsService.sendAuctionRequest(bidRequest) + + then: "PBS should call PBC" + assert prebidCache.getRequestCount(bidRequest.imp[0].id) == 1 + + and: "PBS shouldn't contain cache key" + assert !prebidCache.getRecordedRequests(bidRequest.imp.id.first).puts.flatten().first.key + + and: "PBS should include metrics for request" + def metrics = pbsService.sendCollectedMetricsRequest() + assert metrics[JSON_CREATIVE_TTL_METRIC.formatted(bidRequest.accountId)] == bannerHostTtl + assert metrics[CACHE_REQUEST_OK_METRIC.formatted(bidRequest.accountId)] == 1 + + cleanup: "Stop and remove pbs container" + pbsServiceFactory.removeContainer(pbsConfig) + } + def "PBS should not cache bids when targeting isn't specified"() { given: "Default BidRequest with cache" def bidRequest = BidRequest.defaultBidRequest @@ -246,7 +440,7 @@ class CacheSpec extends BaseSpec { def "PBS should update prebid_cache.creative_size.xml metric and adding tracking xml when xml creative contain #wrapper and impression are valid xml value"() { given: "Current value of metric prebid_cache.requests.ok" - def initialValue = getCurrentMetricValue(defaultPbsService, "prebid_cache.requests.ok") + def initialValue = getCurrentMetricValue(defaultPbsService, OK_GENERAL_METRIC) and: "Create and save enabled events config in account" def accountId = PBSUtils.randomNumber.toString() @@ -275,10 +469,10 @@ class CacheSpec extends BaseSpec { and: "prebid_cache.creative_size.xml metric should be updated" def metrics = defaultPbsService.sendCollectedMetricsRequest() - assert metrics["prebid_cache.requests.ok"] == initialValue + 1 + assert metrics[OK_GENERAL_METRIC] == initialValue + 1 and: "account..prebid_cache.creative_size.xml should be updated" - assert metrics["account.${accountId}.prebid_cache.requests.ok" as String] == 1 + assert metrics[CACHE_REQUEST_OK_METRIC.formatted(accountId) as String] == 1 where: wrapper | impression From 2879ee8b45c592c1e31287ccbf76b8f8c3ed2a92 Mon Sep 17 00:00:00 2001 From: osulzhenko Date: Tue, 18 Feb 2025 17:36:27 +0200 Subject: [PATCH 2/5] update test --- .../org/prebid/server/functional/tests/CacheSpec.groovy | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy index a1edff2c6c2..671bf97a48f 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy @@ -13,6 +13,7 @@ import org.prebid.server.functional.model.request.vtrack.xml.Vast import org.prebid.server.functional.model.response.auction.Adm import org.prebid.server.functional.model.response.auction.BidResponse import org.prebid.server.functional.util.PBSUtils +import spock.lang.IgnoreRest import static org.prebid.server.functional.model.response.auction.MediaType.BANNER import static org.prebid.server.functional.model.response.auction.MediaType.VIDEO @@ -277,7 +278,8 @@ class CacheSpec extends BaseSpec { def bidRequest = BidRequest.defaultBidRequest bidRequest.enableCache() bidRequest.ext.prebid.targeting = new Targeting() - bidRequest.setAccountId(UUID.randomUUID().toString()) + def accountOverflowLength = UUID.randomUUID().toString().length() - MAX_DATACENTER_REGION_LENGTH - 2 + bidRequest.setAccountId(PBSUtils.getRandomString(accountOverflowLength)) when: "PBS processes auction request" pbsService.sendAuctionRequest(bidRequest) From 611e472d6ecfba44a61b690b0da50c27e2fd6a00 Mon Sep 17 00:00:00 2001 From: osulzhenko Date: Wed, 19 Feb 2025 15:07:24 +0200 Subject: [PATCH 3/5] Update after review --- .../server/functional/tests/CacheSpec.groovy | 72 +++++++++---------- 1 file changed, 34 insertions(+), 38 deletions(-) diff --git a/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy index 671bf97a48f..8d18097d8f1 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy @@ -13,28 +13,28 @@ import org.prebid.server.functional.model.request.vtrack.xml.Vast import org.prebid.server.functional.model.response.auction.Adm import org.prebid.server.functional.model.response.auction.BidResponse import org.prebid.server.functional.util.PBSUtils -import spock.lang.IgnoreRest import static org.prebid.server.functional.model.response.auction.MediaType.BANNER import static org.prebid.server.functional.model.response.auction.MediaType.VIDEO class CacheSpec extends BaseSpec { - private final static String PBS_API_HEADER = 'x-pbc-api-key' + private static final String PBS_API_HEADER = 'x-pbc-api-key' private static final Integer MAX_DATACENTER_REGION_LENGTH = 4 - private final static String XML_CREATIVE_SIZE_METRIC = "account.%s.prebid_cache.creative_size.xml" - private final static String JSON_CREATIVE_SIZE_METRIC = "account.%s.prebid_cache.creative_size.json" - private final static String XML_CREATIVE_TTL_METRIC = "account.%s.prebid_cache.creative_ttl.xml" - private final static String JSON_CREATIVE_TTL_METRIC = "account.%s.prebid_cache.creative_ttl.json" - private final static String CACHE_REQUEST_OK_METRIC = "account.%s.prebid_cache.requests.ok" - private final static String XML_CREATIVE_SIZE_GENERAL_METRIC = "prebid_cache.creative_size.xml" - private final static String JSON_CREATIVE_SIZE_GENERAL_METRIC = "prebid_cache.creative_size.json" - private final static String OK_GENERAL_METRIC = "prebid_cache.requests.ok" + private static final String XML_CREATIVE_SIZE_ACCOUNT_METRIC = "account.%s.prebid_cache.creative_size.xml" + private static final String JSON_CREATIVE_SIZE_ACCOUNT_METRIC = "account.%s.prebid_cache.creative_size.json" + private static final String XML_CREATIVE_TTL_ACCOUNT_METRIC = "account.%s.prebid_cache.creative_ttl.xml" + private static final String JSON_CREATIVE_TTL_ACCOUNT_METRIC = "account.%s.prebid_cache.creative_ttl.json" + private static final String CACHE_REQUEST_OK_ACCOUNT_METRIC = "account.%s.prebid_cache.requests.ok" + + private static final String XML_CREATIVE_SIZE_GLOBAL_METRIC = "prebid_cache.creative_size.xml" + private static final String JSON_CREATIVE_SIZE_GLOBAL_METRIC = "prebid_cache.creative_size.json" + private static final String CACHE_REQUEST_OK_GLOBAL_METRIC = "prebid_cache.requests.ok" def "PBS should update prebid_cache.creative_size.xml metric when xml creative is received"() { given: "Current value of metric prebid_cache.requests.ok" - def initialValue = getCurrentMetricValue(defaultPbsService, OK_GENERAL_METRIC) + def initialValue = getCurrentMetricValue(defaultPbsService, CACHE_REQUEST_OK_GLOBAL_METRIC) and: "Default VtrackRequest" def accountId = PBSUtils.randomNumber.toString() @@ -47,17 +47,17 @@ class CacheSpec extends BaseSpec { then: "prebid_cache.creative_size.xml metric should be updated" def metrics = defaultPbsService.sendCollectedMetricsRequest() def creativeSize = creative.bytes.length - assert metrics[OK_GENERAL_METRIC] == initialValue + 1 - assert metrics[XML_CREATIVE_SIZE_GENERAL_METRIC] == creativeSize + assert metrics[CACHE_REQUEST_OK_GLOBAL_METRIC] == initialValue + 1 + assert metrics[XML_CREATIVE_SIZE_GLOBAL_METRIC] == creativeSize and: "account..prebid_cache.creative_size.xml should be updated" - assert metrics[CACHE_REQUEST_OK_METRIC.formatted(accountId)] == 1 - assert metrics[XML_CREATIVE_SIZE_METRIC.formatted(accountId)] == creativeSize + assert metrics[CACHE_REQUEST_OK_ACCOUNT_METRIC.formatted(accountId)] == 1 + assert metrics[XML_CREATIVE_SIZE_ACCOUNT_METRIC.formatted(accountId)] == creativeSize } def "PBS should update prebid_cache.creative_size.json metric when json creative is received"() { given: "Current value of metric prebid_cache.requests.ok" - def initialValue = getCurrentMetricValue(defaultPbsService, OK_GENERAL_METRIC) + def initialValue = getCurrentMetricValue(defaultPbsService, CACHE_REQUEST_OK_GLOBAL_METRIC) and: "Default BidRequest with cache, targeting" def bidRequest = BidRequest.defaultBidRequest @@ -81,12 +81,12 @@ class CacheSpec extends BaseSpec { and: "prebid_cache.creative_size.json metric should be updated" def metrics = defaultPbsService.sendCollectedMetricsRequest() - assert metrics[OK_GENERAL_METRIC] == initialValue + 1 - assert metrics[JSON_CREATIVE_SIZE_GENERAL_METRIC] == creativeSize + assert metrics[CACHE_REQUEST_OK_GLOBAL_METRIC] == initialValue + 1 + assert metrics[JSON_CREATIVE_SIZE_GLOBAL_METRIC] == creativeSize and: "account..prebid_cache.creative_size.json should be update" - assert metrics[CACHE_REQUEST_OK_METRIC.formatted(bidRequest.accountId)] == 1 - assert metrics[JSON_CREATIVE_SIZE_METRIC.formatted(bidRequest.accountId)] == creativeSize + assert metrics[CACHE_REQUEST_OK_ACCOUNT_METRIC.formatted(bidRequest.accountId)] == 1 + assert metrics[JSON_CREATIVE_SIZE_ACCOUNT_METRIC.formatted(bidRequest.accountId)] == creativeSize } def "PBS should cache bids when targeting is specified"() { @@ -160,10 +160,6 @@ class CacheSpec extends BaseSpec { bidRequest.enableCache() bidRequest.ext.prebid.targeting = new Targeting() - and: "Set bidder response" - def bidResponse = BidResponse.getDefaultBidResponse(bidRequest) - bidder.setResponse(bidRequest.id, bidResponse) - when: "PBS processes auction request" pbsService.sendAuctionRequest(bidRequest) @@ -179,8 +175,8 @@ class CacheSpec extends BaseSpec { and: "PBS should include metrics for request" def metrics = pbsService.sendCollectedMetricsRequest() - assert metrics[JSON_CREATIVE_TTL_METRIC.formatted(bidRequest.accountId)] == bannerHostTtl - assert metrics[CACHE_REQUEST_OK_METRIC.formatted(bidRequest.accountId)] == 1 + assert metrics[JSON_CREATIVE_TTL_ACCOUNT_METRIC.formatted(bidRequest.accountId)] == bannerHostTtl + assert metrics[CACHE_REQUEST_OK_ACCOUNT_METRIC.formatted(bidRequest.accountId)] == 1 cleanup: "Stop and remove pbs container" pbsServiceFactory.removeContainer(pbsConfig) @@ -220,9 +216,9 @@ class CacheSpec extends BaseSpec { and: "PBS should include metrics for request" def metrics = pbsService.sendCollectedMetricsRequest() - assert metrics[JSON_CREATIVE_TTL_METRIC.formatted(bidRequest.accountId)] == videoHostTtl - assert metrics[XML_CREATIVE_TTL_METRIC.formatted(bidRequest.accountId)] == videoHostTtl - assert metrics[CACHE_REQUEST_OK_METRIC.formatted(bidRequest.accountId)] == 1 + assert metrics[JSON_CREATIVE_TTL_ACCOUNT_METRIC.formatted(bidRequest.accountId)] == videoHostTtl + assert metrics[XML_CREATIVE_TTL_ACCOUNT_METRIC.formatted(bidRequest.accountId)] == videoHostTtl + assert metrics[CACHE_REQUEST_OK_ACCOUNT_METRIC.formatted(bidRequest.accountId)] == 1 cleanup: "Stop and remove pbs container" pbsServiceFactory.removeContainer(pbsConfig) @@ -257,8 +253,8 @@ class CacheSpec extends BaseSpec { and: "PBS should include metrics for request" def metrics = pbsService.sendCollectedMetricsRequest() - assert metrics[JSON_CREATIVE_TTL_METRIC.formatted(bidRequest.accountId)] == bannerHostTtl - assert metrics[CACHE_REQUEST_OK_METRIC.formatted(bidRequest.accountId)] == 1 + assert metrics[JSON_CREATIVE_TTL_ACCOUNT_METRIC.formatted(bidRequest.accountId)] == bannerHostTtl + assert metrics[CACHE_REQUEST_OK_ACCOUNT_METRIC.formatted(bidRequest.accountId)] == 1 cleanup: "Stop and remove pbs container" pbsServiceFactory.removeContainer(pbsConfig) @@ -292,8 +288,8 @@ class CacheSpec extends BaseSpec { and: "PBS should include metrics for request" def metrics = pbsService.sendCollectedMetricsRequest() - assert metrics[JSON_CREATIVE_TTL_METRIC.formatted(bidRequest.accountId)] == bannerHostTtl - assert metrics[CACHE_REQUEST_OK_METRIC.formatted(bidRequest.accountId)] == 1 + assert metrics[JSON_CREATIVE_TTL_ACCOUNT_METRIC.formatted(bidRequest.accountId)] == bannerHostTtl + assert metrics[CACHE_REQUEST_OK_ACCOUNT_METRIC.formatted(bidRequest.accountId)] == 1 cleanup: "Stop and remove pbs container" pbsServiceFactory.removeContainer(pbsConfig) @@ -325,8 +321,8 @@ class CacheSpec extends BaseSpec { and: "PBS should include metrics for request" def metrics = pbsService.sendCollectedMetricsRequest() - assert metrics[JSON_CREATIVE_TTL_METRIC.formatted(bidRequest.accountId)] == bannerHostTtl - assert metrics[CACHE_REQUEST_OK_METRIC.formatted(bidRequest.accountId)] == 1 + assert metrics[JSON_CREATIVE_TTL_ACCOUNT_METRIC.formatted(bidRequest.accountId)] == bannerHostTtl + assert metrics[CACHE_REQUEST_OK_ACCOUNT_METRIC.formatted(bidRequest.accountId)] == 1 cleanup: "Stop and remove pbs container" pbsServiceFactory.removeContainer(pbsConfig) @@ -442,7 +438,7 @@ class CacheSpec extends BaseSpec { def "PBS should update prebid_cache.creative_size.xml metric and adding tracking xml when xml creative contain #wrapper and impression are valid xml value"() { given: "Current value of metric prebid_cache.requests.ok" - def initialValue = getCurrentMetricValue(defaultPbsService, OK_GENERAL_METRIC) + def initialValue = getCurrentMetricValue(defaultPbsService, CACHE_REQUEST_OK_GLOBAL_METRIC) and: "Create and save enabled events config in account" def accountId = PBSUtils.randomNumber.toString() @@ -471,10 +467,10 @@ class CacheSpec extends BaseSpec { and: "prebid_cache.creative_size.xml metric should be updated" def metrics = defaultPbsService.sendCollectedMetricsRequest() - assert metrics[OK_GENERAL_METRIC] == initialValue + 1 + assert metrics[CACHE_REQUEST_OK_GLOBAL_METRIC] == initialValue + 1 and: "account..prebid_cache.creative_size.xml should be updated" - assert metrics[CACHE_REQUEST_OK_METRIC.formatted(accountId) as String] == 1 + assert metrics[CACHE_REQUEST_OK_ACCOUNT_METRIC.formatted(accountId) as String] == 1 where: wrapper | impression From 9c265332ab8d43030b05bbc882d59cbe31c9a117 Mon Sep 17 00:00:00 2001 From: osulzhenko Date: Wed, 19 Feb 2025 17:07:32 +0200 Subject: [PATCH 4/5] Update after review --- .../server/functional/tests/CacheSpec.groovy | 112 +++++++++++------- 1 file changed, 68 insertions(+), 44 deletions(-) diff --git a/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy index 8d18097d8f1..fa4c6d4ec8b 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy @@ -21,6 +21,7 @@ class CacheSpec extends BaseSpec { private static final String PBS_API_HEADER = 'x-pbc-api-key' private static final Integer MAX_DATACENTER_REGION_LENGTH = 4 + private static final Integer DEFAULT_UUID_LENGTH = 36 private static final String XML_CREATIVE_SIZE_ACCOUNT_METRIC = "account.%s.prebid_cache.creative_size.xml" private static final String JSON_CREATIVE_SIZE_ACCOUNT_METRIC = "account.%s.prebid_cache.creative_size.json" @@ -60,8 +61,9 @@ class CacheSpec extends BaseSpec { def initialValue = getCurrentMetricValue(defaultPbsService, CACHE_REQUEST_OK_GLOBAL_METRIC) and: "Default BidRequest with cache, targeting" - def bidRequest = BidRequest.defaultBidRequest - bidRequest.enableCache() + def bidRequest = BidRequest.defaultBidRequest.tap { + it.enableCache() + } and: "Default basic bid with banner creative" def asset = new Asset(id: PBSUtils.randomNumber) @@ -91,9 +93,11 @@ class CacheSpec extends BaseSpec { def "PBS should cache bids when targeting is specified"() { given: "Default BidRequest with cache, targeting" - def bidRequest = BidRequest.defaultBidRequest - bidRequest.enableCache() - bidRequest.ext.prebid.targeting = new Targeting() + def bidRequest = BidRequest.defaultBidRequest.tap { + it.ext.prebid.targeting = new Targeting() + + it.enableCache() + } when: "PBS processes auction request" defaultPbsService.sendAuctionRequest(bidRequest) @@ -111,9 +115,11 @@ class CacheSpec extends BaseSpec { def pbsService = pbsServiceFactory.getService(['pbc.api.key': apiKey, 'cache.api-key-secured': 'false']) and: "Default BidRequest with cache, targeting" - def bidRequest = BidRequest.defaultBidRequest - bidRequest.enableCache() - bidRequest.ext.prebid.targeting = new Targeting() + def bidRequest = BidRequest.defaultBidRequest.tap { + it.ext.prebid.targeting = new Targeting() + + it.enableCache() + } when: "PBS processes auction request" pbsService.sendAuctionRequest(bidRequest) @@ -131,9 +137,11 @@ class CacheSpec extends BaseSpec { def pbsService = pbsServiceFactory.getService(['pbc.api.key': apiKey, 'cache.api-key-secured': 'true']) and: "Default BidRequest with cache, targeting" - def bidRequest = BidRequest.defaultBidRequest - bidRequest.enableCache() - bidRequest.ext.prebid.targeting = new Targeting() + def bidRequest = BidRequest.defaultBidRequest.tap { + it.ext.prebid.targeting = new Targeting() + + it.enableCache() + } when: "PBS processes auction request" pbsService.sendAuctionRequest(bidRequest) @@ -156,9 +164,11 @@ class CacheSpec extends BaseSpec { def pbsService = pbsServiceFactory.getService(pbsConfig) and: "Default BidRequest with cache, targeting" - def bidRequest = BidRequest.defaultBidRequest - bidRequest.enableCache() - bidRequest.ext.prebid.targeting = new Targeting() + def bidRequest = BidRequest.defaultBidRequest.tap { + it.ext.prebid.targeting = new Targeting() + + it.enableCache() + } when: "PBS processes auction request" pbsService.sendAuctionRequest(bidRequest) @@ -171,7 +181,7 @@ class CacheSpec extends BaseSpec { assert cacheKey.startsWith("${bidRequest.accountId}-${serverDataCenter.take(MAX_DATACENTER_REGION_LENGTH)}") and: "PBS cache key should have length equal to default UUID" - assert cacheKey.length() == UUID.randomUUID().toString().length() + assert cacheKey.length() == DEFAULT_UUID_LENGTH and: "PBS should include metrics for request" def metrics = pbsService.sendCollectedMetricsRequest() @@ -193,9 +203,11 @@ class CacheSpec extends BaseSpec { def pbsService = pbsServiceFactory.getService(pbsConfig) and: "Default BidRequest with cache, targeting" - def bidRequest = BidRequest.defaultVideoRequest - bidRequest.enableCache() - bidRequest.ext.prebid.targeting = new Targeting() + def bidRequest = BidRequest.defaultVideoRequest.tap { + it.ext.prebid.targeting = new Targeting() + + it.enableCache() + } and: "Set bidder response" def bidResponse = BidResponse.getDefaultBidResponse(bidRequest) @@ -212,7 +224,7 @@ class CacheSpec extends BaseSpec { assert cacheKey.startsWith("${bidRequest.accountId}-${serverDataCenter.take(MAX_DATACENTER_REGION_LENGTH)}") and: "PBS cache key should have length equal to default UUID" - assert cacheKey.length() == UUID.randomUUID().toString().length() + assert cacheKey.length() == DEFAULT_UUID_LENGTH and: "PBS should include metrics for request" def metrics = pbsService.sendCollectedMetricsRequest() @@ -234,9 +246,11 @@ class CacheSpec extends BaseSpec { def pbsService = pbsServiceFactory.getService(pbsConfig) and: "Default BidRequest with cache, targeting" - def bidRequest = BidRequest.defaultBidRequest - bidRequest.enableCache() - bidRequest.ext.prebid.targeting = new Targeting() + def bidRequest = BidRequest.defaultBidRequest.tap { + it.ext.prebid.targeting = new Targeting() + + it.enableCache() + } when: "PBS processes auction request" pbsService.sendAuctionRequest(bidRequest) @@ -249,7 +263,7 @@ class CacheSpec extends BaseSpec { assert cacheKey.startsWith("${bidRequest.accountId}-") and: "PBS cache key should have length equal to default UUID" - assert cacheKey.length() == UUID.randomUUID().toString().length() + assert cacheKey.length() == DEFAULT_UUID_LENGTH and: "PBS should include metrics for request" def metrics = pbsService.sendCollectedMetricsRequest() @@ -271,11 +285,13 @@ class CacheSpec extends BaseSpec { def pbsService = pbsServiceFactory.getService(pbsConfig) and: "Default BidRequest with cache, targeting and large account ID" - def bidRequest = BidRequest.defaultBidRequest - bidRequest.enableCache() - bidRequest.ext.prebid.targeting = new Targeting() - def accountOverflowLength = UUID.randomUUID().toString().length() - MAX_DATACENTER_REGION_LENGTH - 2 - bidRequest.setAccountId(PBSUtils.getRandomString(accountOverflowLength)) + def accountOverflowLength = DEFAULT_UUID_LENGTH - MAX_DATACENTER_REGION_LENGTH - 2 + def bidRequest = BidRequest.defaultBidRequest.tap { + it.ext.prebid.targeting = new Targeting() + + it.setAccountId(PBSUtils.getRandomString(accountOverflowLength)) + it.enableCache() + } when: "PBS processes auction request" pbsService.sendAuctionRequest(bidRequest) @@ -306,9 +322,11 @@ class CacheSpec extends BaseSpec { def pbsService = pbsServiceFactory.getService(pbsConfig) and: "Default BidRequest with cache, targeting" - def bidRequest = BidRequest.defaultBidRequest - bidRequest.enableCache() - bidRequest.ext.prebid.targeting = new Targeting() + def bidRequest = BidRequest.defaultBidRequest.tap { + it.ext.prebid.targeting = new Targeting() + + it.enableCache() + } when: "PBS processes auction request" pbsService.sendAuctionRequest(bidRequest) @@ -330,9 +348,11 @@ class CacheSpec extends BaseSpec { def "PBS should not cache bids when targeting isn't specified"() { given: "Default BidRequest with cache" - def bidRequest = BidRequest.defaultBidRequest - bidRequest.enableCache() - bidRequest.ext.prebid.targeting = null + def bidRequest = BidRequest.defaultBidRequest.tap { + it.ext.prebid.targeting = null + + it.enableCache() + } when: "PBS processes auction request" defaultPbsService.sendAuctionRequest(bidRequest) @@ -344,8 +364,9 @@ class CacheSpec extends BaseSpec { def "PBS shouldn't response with seatbid.bid.adm in response when ext.prebid.cache.bids.returnCreative=false"() { given: "Default BidRequest with cache" def bidRequest = BidRequest.defaultBidRequest.tap { - enableCache() - ext.prebid.cache.bids.returnCreative = false + it.ext.prebid.cache.bids.returnCreative = false + + it.enableCache() } and: "Default basic bid with banner creative" @@ -366,8 +387,9 @@ class CacheSpec extends BaseSpec { def "PBS should response with seatbid.bid.adm in response when ext.prebid.cache.bids.returnCreative=true"() { given: "Default BidRequest with cache" def bidRequest = BidRequest.defaultBidRequest.tap { - enableCache() - ext.prebid.cache.bids.returnCreative = true + it.ext.prebid.cache.bids.returnCreative = true + + it.enableCache() } and: "Default basic bid with banner creative" @@ -388,9 +410,10 @@ class CacheSpec extends BaseSpec { def "PBS shouldn't response with seatbid.bid.adm in response when ext.prebid.cache.vastXml.returnCreative=false and video request"() { given: "Default BidRequest with cache" def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0] = Imp.getDefaultImpression(VIDEO) - enableCache() - ext.prebid.cache.vastXml.returnCreative = false + it.imp[0] = Imp.getDefaultImpression(VIDEO) + it.ext.prebid.cache.vastXml.returnCreative = false + + it.enableCache() } and: "Default basic bid with banner creative" @@ -411,9 +434,10 @@ class CacheSpec extends BaseSpec { def "PBS should response with seatbid.bid.adm in response when ext.prebid.cache.vastXml.returnCreative=#returnCreative and imp.#mediaType"() { given: "Default BidRequest with cache" def bidRequest = BidRequest.defaultBidRequest.tap { - enableCache() - imp[0] = Imp.getDefaultImpression(mediaType) - ext.prebid.cache.vastXml.returnCreative = returnCreative + it.imp[0] = Imp.getDefaultImpression(mediaType) + it.ext.prebid.cache.vastXml.returnCreative = returnCreative + + it.enableCache() } and: "Default basic bid with banner creative" From d6af9d1b9c8d9d77db925800f1ba2ccf6c4367cb Mon Sep 17 00:00:00 2001 From: osulzhenko Date: Wed, 19 Feb 2025 17:28:01 +0200 Subject: [PATCH 5/5] Update after review --- .../server/functional/tests/CacheSpec.groovy | 39 +++++++------------ 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy index fa4c6d4ec8b..e145e5a972f 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy @@ -94,9 +94,8 @@ class CacheSpec extends BaseSpec { def "PBS should cache bids when targeting is specified"() { given: "Default BidRequest with cache, targeting" def bidRequest = BidRequest.defaultBidRequest.tap { - it.ext.prebid.targeting = new Targeting() - it.enableCache() + it.ext.prebid.targeting = new Targeting() } when: "PBS processes auction request" @@ -116,9 +115,8 @@ class CacheSpec extends BaseSpec { and: "Default BidRequest with cache, targeting" def bidRequest = BidRequest.defaultBidRequest.tap { - it.ext.prebid.targeting = new Targeting() - it.enableCache() + it.ext.prebid.targeting = new Targeting() } when: "PBS processes auction request" @@ -138,9 +136,8 @@ class CacheSpec extends BaseSpec { and: "Default BidRequest with cache, targeting" def bidRequest = BidRequest.defaultBidRequest.tap { - it.ext.prebid.targeting = new Targeting() - it.enableCache() + it.ext.prebid.targeting = new Targeting() } when: "PBS processes auction request" @@ -165,9 +162,8 @@ class CacheSpec extends BaseSpec { and: "Default BidRequest with cache, targeting" def bidRequest = BidRequest.defaultBidRequest.tap { - it.ext.prebid.targeting = new Targeting() - it.enableCache() + it.ext.prebid.targeting = new Targeting() } when: "PBS processes auction request" @@ -204,9 +200,8 @@ class CacheSpec extends BaseSpec { and: "Default BidRequest with cache, targeting" def bidRequest = BidRequest.defaultVideoRequest.tap { - it.ext.prebid.targeting = new Targeting() - it.enableCache() + it.ext.prebid.targeting = new Targeting() } and: "Set bidder response" @@ -247,9 +242,8 @@ class CacheSpec extends BaseSpec { and: "Default BidRequest with cache, targeting" def bidRequest = BidRequest.defaultBidRequest.tap { - it.ext.prebid.targeting = new Targeting() - it.enableCache() + it.ext.prebid.targeting = new Targeting() } when: "PBS processes auction request" @@ -287,10 +281,9 @@ class CacheSpec extends BaseSpec { and: "Default BidRequest with cache, targeting and large account ID" def accountOverflowLength = DEFAULT_UUID_LENGTH - MAX_DATACENTER_REGION_LENGTH - 2 def bidRequest = BidRequest.defaultBidRequest.tap { + it.enableCache() it.ext.prebid.targeting = new Targeting() - it.setAccountId(PBSUtils.getRandomString(accountOverflowLength)) - it.enableCache() } when: "PBS processes auction request" @@ -323,9 +316,8 @@ class CacheSpec extends BaseSpec { and: "Default BidRequest with cache, targeting" def bidRequest = BidRequest.defaultBidRequest.tap { - it.ext.prebid.targeting = new Targeting() - it.enableCache() + it.ext.prebid.targeting = new Targeting() } when: "PBS processes auction request" @@ -349,9 +341,8 @@ class CacheSpec extends BaseSpec { def "PBS should not cache bids when targeting isn't specified"() { given: "Default BidRequest with cache" def bidRequest = BidRequest.defaultBidRequest.tap { - it.ext.prebid.targeting = null - it.enableCache() + it.ext.prebid.targeting = null } when: "PBS processes auction request" @@ -364,9 +355,8 @@ class CacheSpec extends BaseSpec { def "PBS shouldn't response with seatbid.bid.adm in response when ext.prebid.cache.bids.returnCreative=false"() { given: "Default BidRequest with cache" def bidRequest = BidRequest.defaultBidRequest.tap { - it.ext.prebid.cache.bids.returnCreative = false - it.enableCache() + it.ext.prebid.cache.bids.returnCreative = false } and: "Default basic bid with banner creative" @@ -387,9 +377,8 @@ class CacheSpec extends BaseSpec { def "PBS should response with seatbid.bid.adm in response when ext.prebid.cache.bids.returnCreative=true"() { given: "Default BidRequest with cache" def bidRequest = BidRequest.defaultBidRequest.tap { - it.ext.prebid.cache.bids.returnCreative = true - it.enableCache() + it.ext.prebid.cache.bids.returnCreative = true } and: "Default basic bid with banner creative" @@ -410,10 +399,9 @@ class CacheSpec extends BaseSpec { def "PBS shouldn't response with seatbid.bid.adm in response when ext.prebid.cache.vastXml.returnCreative=false and video request"() { given: "Default BidRequest with cache" def bidRequest = BidRequest.defaultBidRequest.tap { + it.enableCache() it.imp[0] = Imp.getDefaultImpression(VIDEO) it.ext.prebid.cache.vastXml.returnCreative = false - - it.enableCache() } and: "Default basic bid with banner creative" @@ -434,10 +422,9 @@ class CacheSpec extends BaseSpec { def "PBS should response with seatbid.bid.adm in response when ext.prebid.cache.vastXml.returnCreative=#returnCreative and imp.#mediaType"() { given: "Default BidRequest with cache" def bidRequest = BidRequest.defaultBidRequest.tap { + it.enableCache() it.imp[0] = Imp.getDefaultImpression(mediaType) it.ext.prebid.cache.vastXml.returnCreative = returnCreative - - it.enableCache() } and: "Default basic bid with banner creative"