Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class AccountAuctionConfig {
Boolean debugAllow
AccountBidValidationConfig bidValidations
AccountEventsConfig events
AccountCacheConfig cache
AccountPriceFloorsConfig priceFloors
Targeting targeting
PaaFormat paaformat
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.prebid.server.functional.model.config

import groovy.transform.ToString

@ToString(includeNames = true, ignoreNulls = true)
class AccountCacheConfig {

Boolean enabled
}
135 changes: 135 additions & 0 deletions src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.prebid.server.functional.tests

import org.prebid.server.functional.model.config.AccountAuctionConfig
import org.prebid.server.functional.model.config.AccountCacheConfig
import org.prebid.server.functional.model.config.AccountConfig
import org.prebid.server.functional.model.config.AccountEventsConfig
import org.prebid.server.functional.model.db.Account
Expand All @@ -14,6 +15,8 @@ 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 static org.prebid.server.functional.model.AccountStatus.ACTIVE
import static org.prebid.server.functional.model.bidder.BidderName.GENERIC
import static org.prebid.server.functional.model.response.auction.MediaType.BANNER
import static org.prebid.server.functional.model.response.auction.MediaType.VIDEO

Expand Down Expand Up @@ -42,6 +45,9 @@ class CacheSpec extends BaseSpec {
def creative = encodeXml(Vast.getDefaultVastModel(PBSUtils.randomString))
def request = VtrackRequest.getDefaultVtrackRequest(creative)

and: "Flush metrics"
flushMetrics(defaultPbsService)

when: "PBS processes vtrack request"
defaultPbsService.sendVtrackRequest(request, accountId)

Expand Down Expand Up @@ -468,6 +474,9 @@ class CacheSpec extends BaseSpec {
"<${impression}> &lt;![CDATA[ ]]&gt; </${impression}><Creatives></Creatives></${wrapper}></Ad></VAST>"
def request = VtrackRequest.getDefaultVtrackRequest(creative)

and: "Flush metrics"
flushMetrics(defaultPbsService)

when: "PBS processes vtrack request"
defaultPbsService.sendVtrackRequest(request, accountId)

Expand All @@ -492,4 +501,130 @@ class CacheSpec extends BaseSpec {
PBSUtils.getRandomCase(" inline ") | " ${PBSUtils.getRandomCase(" impression ")} $PBSUtils.randomNumber "
" inline ${PBSUtils.getRandomString()} " | " ImpreSSion "
}

def "PBS should cache bids and add targeting values when account cache config #accountAuctionConfig"() {
given: "Current value of metric prebid_cache.requests.ok"
def initialValue = getCurrentMetricValue(defaultPbsService, CACHE_REQUEST_OK_GLOBAL_METRIC)

and: "Default BidRequest with cache, targeting"
def bidRequest = BidRequest.getDefaultVideoRequest().tap {
it.enableCache()
}

and: "Account in the DB"
def accountConfig = new AccountConfig(status: ACTIVE, auction: accountAuctionConfig)
def account = new Account(uuid: bidRequest.accountId, config: accountConfig)
accountDao.save(account)

and: "Default bid response"
def presetBidResponse = BidResponse.getDefaultBidResponse(bidRequest)
bidder.setResponse(bidRequest.id, presetBidResponse)

and: "Flush metrics"
flushMetrics(defaultPbsService)

when: "PBS processes auction request"
def response = defaultPbsService.sendAuctionRequest(bidRequest)

then: "PBS should call PBC"
assert prebidCache.getRequestCount(bidRequest.imp[0].id) == 1

and: "PBS response targeting contains bidder specific keys"
def targetingKeyMap = response.seatbid?.first()?.bid?.first()?.ext?.prebid?.targeting
assert targetingKeyMap.containsKey('hb_cache_id')
assert targetingKeyMap.containsKey("hb_cache_id_${GENERIC}".toString())
assert targetingKeyMap.containsKey('hb_uuid')
assert targetingKeyMap.containsKey("hb_uuid_${GENERIC}".toString())

and: "Metrics should be updated"
def metrics = defaultPbsService.sendCollectedMetricsRequest()
assert metrics[CACHE_REQUEST_OK_GLOBAL_METRIC] == initialValue + 1
assert metrics[CACHE_REQUEST_OK_ACCOUNT_METRIC.formatted(bidRequest.accountId)] == 1

where:
accountAuctionConfig << [
new AccountAuctionConfig(),
new AccountAuctionConfig(cache: new AccountCacheConfig()),
new AccountAuctionConfig(cache: new AccountCacheConfig(enabled: null)),
new AccountAuctionConfig(cache: new AccountCacheConfig(enabled: true))
]
}

def "PBS shouldn't cache bids and add targeting values when account cache config disabled"() {
given: "Current value of metric prebid_cache.requests.ok"
def initialValue = getCurrentMetricValue(defaultPbsService, CACHE_REQUEST_OK_GLOBAL_METRIC)

and: "Default BidRequest with cache, targeting"
def bidRequest = BidRequest.getDefaultVideoRequest().tap {
it.enableCache()
}

and: "Account with cache config"
def accountAuctionConfig = new AccountAuctionConfig(cache: new AccountCacheConfig(enabled: false))
def accountConfig = new AccountConfig(status: ACTIVE, auction: accountAuctionConfig)
def account = new Account(uuid: bidRequest.accountId, config: accountConfig)
accountDao.save(account)

and: "Default bid response"
def presetBidResponse = BidResponse.getDefaultBidResponse(bidRequest)
bidder.setResponse(bidRequest.id, presetBidResponse)

and: "Flush metrics"
flushMetrics(defaultPbsService)

when: "PBS processes auction request"
def response = defaultPbsService.sendAuctionRequest(bidRequest)

then: "PBS shouldn't call PBC"
assert !prebidCache.getRequestCount(bidRequest.imp[0].id)

and: "PBS response targeting shouldn't contains bidder specific keys"
def targetingKeyMap = response.seatbid?.first()?.bid?.first()?.ext?.prebid?.targeting
assert !targetingKeyMap.containsKey('hb_cache_id')
assert !targetingKeyMap.containsKey("hb_cache_id_${GENERIC}".toString())
assert !targetingKeyMap.containsKey('hb_uuid')
assert !targetingKeyMap.containsKey("hb_uuid_${GENERIC}".toString())

and: "Metrics shouldn't be updated"
def metrics = defaultPbsService.sendCollectedMetricsRequest()
assert metrics[CACHE_REQUEST_OK_GLOBAL_METRIC] == initialValue
assert !metrics[CACHE_REQUEST_OK_ACCOUNT_METRIC.formatted(bidRequest.accountId)]
}

def "PBS should update prebid_cache.creative_size.xml metric when account cache config #enabledCacheConcfig"() {
given: "Current value of metric prebid_cache.requests.ok"
def okInitialValue = getCurrentMetricValue(defaultPbsService, CACHE_REQUEST_OK_GLOBAL_METRIC)

and: "Default VtrackRequest"
def accountId = PBSUtils.randomNumber.toString()
def creative = encodeXml(Vast.getDefaultVastModel(PBSUtils.randomString))
def request = VtrackRequest.getDefaultVtrackRequest(creative)

and: "Create and save enabled events config in account"
def account = new Account().tap {
it.uuid = accountId
it.config = new AccountConfig().tap {
it.auction = new AccountAuctionConfig(cache: new AccountCacheConfig(enabled: enabledCacheConcfig))
}
}
accountDao.save(account)

and: "Flush metrics"
flushMetrics(defaultPbsService)

when: "PBS processes vtrack request"
defaultPbsService.sendVtrackRequest(request, accountId)

then: "prebid_cache.creative_size.xml metric should be updated"
def metrics = defaultPbsService.sendCollectedMetricsRequest()
def creativeSize = creative.bytes.length
assert metrics[CACHE_REQUEST_OK_GLOBAL_METRIC] == okInitialValue + 1

and: "account.<account-id>.prebid_cache.creative_size.xml should be updated"
assert metrics[CACHE_REQUEST_OK_ACCOUNT_METRIC.formatted(accountId)] == 1
assert metrics[XML_CREATIVE_SIZE_ACCOUNT_METRIC.formatted(accountId)] == creativeSize

where:
enabledCacheConcfig << [null, false, true]
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.prebid.server.functional.tests.module.responsecorrenction

import org.prebid.server.functional.model.config.AccountAuctionConfig
import org.prebid.server.functional.model.config.AccountCacheConfig
import org.prebid.server.functional.model.config.AccountConfig
import org.prebid.server.functional.model.config.AccountHooksConfiguration
import org.prebid.server.functional.model.config.AppVideoHtml
Expand Down Expand Up @@ -576,6 +578,61 @@ class ResponseCorrectionSpec extends ModuleBaseSpec {
assert !response.ext.warnings
}

def "PBS should modify response when requested video impression respond with invalid adm VAST keyword and disabled cache config"() {
given: "Start up time"
def start = Instant.now()

and: "Default bid request with APP and Video imp"
def bidRequest = getDefaultVideoRequest(APP)

and: "Set bidder response"
def bidResponse = BidResponse.getDefaultBidResponse(bidRequest).tap {
seatbid[0].bid[0].setAdm(PBSUtils.getRandomCase(admValue))
}
bidder.setResponse(bidRequest.id, bidResponse)

and: "Save account with enabled response correction module"
def accountWithResponseCorrectionModule = accountConfigWithResponseCorrectionModule(bidRequest).tap {
config.auction = new AccountAuctionConfig(cache: new AccountCacheConfig(enabled: false))
}
accountDao.save(accountWithResponseCorrectionModule)

when: "PBS processes auction request"
def response = pbsServiceWithResponseCorrectionModule.sendAuctionRequest(bidRequest)

then: "PBS should emit log"
def logsByTime = pbsServiceWithResponseCorrectionModule.getLogsByTime(start)
def bidId = bidResponse.seatbid[0].bid[0].id
def responseCorrection = getLogsByText(logsByTime, bidId)
assert responseCorrection.size() == 1
assert responseCorrection.any {
it.contains("Bid $bidId of bidder generic: changing media type to banner" as String)
}

and: "Response should contain seatBid"
assert response.seatbid.size() == 1

and: "Response should contain single seatBid with proper media type"
assert response.seatbid.bid.ext.prebid.type.flatten() == [BANNER]

and: "Response should contain single seatBid with proper meta media type"
assert response.seatbid.bid.ext.prebid.meta.mediaType.flatten() == [VIDEO.value]

and: "Response shouldn't contain errors"
assert !response.ext.errors

and: "Response shouldn't contain warnings"
assert !response.ext.warnings

where:
admValue << [
"<${' ' * PBSUtils.getRandomNumber(0, OPTIMAL_MAX_LENGTH)}VAST${PBSUtils.randomString}",
"<${' ' * PBSUtils.getRandomNumber(0, OPTIMAL_MAX_LENGTH)}VAST",
"<${' ' * PBSUtils.getRandomNumber(0, OPTIMAL_MAX_LENGTH)}VAST>",
"<${PBSUtils.randomString}VAST${' ' * PBSUtils.getRandomNumber(1, OPTIMAL_MAX_LENGTH)}"
]
}

private static Account accountConfigWithResponseCorrectionModule(BidRequest bidRequest, Boolean enabledResponseCorrection = true, Boolean enabledAppVideoHtml = true) {
def modulesConfig = new PbsModulesConfig(pbResponseCorrection: new PbResponseCorrection(
enabled: enabledResponseCorrection, appVideoHtml: new AppVideoHtml(enabled: enabledAppVideoHtml)))
Expand Down