Skip to content
Open
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 @@ -61,6 +61,7 @@ class PrebidServerService implements ObjectMapperWrapper {
static final String CURRENCY_RATES_ENDPOINT = "/currency/rates"
static final String HTTP_INTERACTION_ENDPOINT = "/logging/httpinteraction"
static final String COLLECTED_METRICS_ENDPOINT = "/collected-metrics"
static final String TRACELOG_ENDPOINT = "/pbs-admin/tracelog"
static final String PROMETHEUS_METRICS_ENDPOINT = "/metrics"
static final String INFLUX_DB_ENDPOINT = "/query"
static final String UIDS_COOKIE_NAME = "uids"
Expand Down Expand Up @@ -297,6 +298,21 @@ class PrebidServerService implements ObjectMapperWrapper {
decode(response.asString(), new TypeReference<Map<String, Number>>() {})
}

void sendAccountTracelogConfig(String accountId, BidderName bidderCode) {
def params = [
level : "info",
duration : 300000L,
bidderCode: bidderCode.value,
account : accountId
]

def response = given(adminRequestSpecification)
.queryParams(params)
.get(TRACELOG_ENDPOINT)

checkResponseStatusCode(response)
}

Map<String, Number> sendInfluxMetricsRequest() {
def response = given(influxRequestSpecification)
.queryParams(["db": influxdbContainer.getDatabase(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ LIMIT 1
["admin-endpoints.collected-metrics.enabled": "true"].asImmutable()
}

static Map<String, String> getTracelogConfig() {
["admin-endpoints.tracelog.enabled": "true"].asImmutable()
}

// due to a config validation we'll need to circumvent all future aliases this way
static Map<String, String> getBidderAliasConfig() {
["adapters.generic.aliases.cwire.meta-info.site-media-types" : "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class PrebidServerContainer extends GenericContainer<PrebidServerContainer> {
def commonConfig = [:] << DEFAULT_ENV
<< PbsConfig.defaultBiddersConfig
<< PbsConfig.metricConfig
<< PbsConfig.tracelogConfig
<< PbsConfig.adminEndpointConfig
<< PbsConfig.bidderConfig
<< PbsConfig.bidderAliasConfig
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,13 @@ abstract class BaseSpec extends Specification implements ObjectMapperWrapper {
logs.findAll { it.contains(text) }
}

protected static BidResponse getTraceLoggedResponse(List<String> logs, String bidRequestId) {
def logLine = getLogsByText(logs, bidRequestId)?[0]
def restoredResponse = logLine?.find(/\{.*/)

restoredResponse ? decode(restoredResponse, BidResponse) : null
}

protected static String getRoundedTargetingValueWithDownPrecision(BigDecimal value) {
roundWithDefaultPrecisionAndRoundingType(value, DOWN)
}
Expand Down
135 changes: 126 additions & 9 deletions src/test/groovy/org/prebid/server/functional/tests/EventsSpec.groovy
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
package org.prebid.server.functional.tests

import org.prebid.server.functional.model.ChannelType
import org.prebid.server.functional.model.bidder.BidderName
import org.prebid.server.functional.model.config.AccountAnalyticsConfig
import org.prebid.server.functional.model.config.AccountConfig
import org.prebid.server.functional.model.db.Account
import org.prebid.server.functional.model.db.StoredRequest
import org.prebid.server.functional.model.request.amp.AmpRequest
import org.prebid.server.functional.model.request.auction.BidRequest
import org.prebid.server.functional.model.request.auction.Events
import org.prebid.server.functional.model.request.auction.PrebidStoredRequest
import org.prebid.server.functional.util.PBSUtils

import java.time.Instant

import static org.prebid.server.functional.model.ChannelType.AMP
import static org.prebid.server.functional.model.request.auction.DistributionChannel.APP
import static org.prebid.server.functional.model.request.auction.DistributionChannel.DOOH
import static org.prebid.server.functional.model.request.auction.DistributionChannel.SITE
Expand Down Expand Up @@ -126,8 +131,7 @@ class EventsSpec extends BaseSpec {
}

and: "Account with analytics events disabled for corresponding channel"
def analyticsConfig = new AccountAnalyticsConfig(auctionEvents: [(accountConfigChannelType): false])
def account = new Account(uuid: accountId, eventsEnabled: true, config: new AccountConfig(analytics: analyticsConfig))
def account = getAccountWithAuctionEvent(accountId, [(accountConfigChannelType): false])
accountDao.save(account)

when: "Auction request is processed"
Expand All @@ -152,8 +156,7 @@ class EventsSpec extends BaseSpec {
}

and: "Account with analytics events disabled for corresponding channel"
def analyticsConfig = new AccountAnalyticsConfig(auctionEvents: [(accountConfigChannelType): false])
def account = new Account(uuid: accountId, eventsEnabled: true, config: new AccountConfig(analytics: analyticsConfig))
def account = getAccountWithAuctionEvent(accountId, [(accountConfigChannelType): false])
accountDao.save(account)

when: "Auction request is processed"
Expand All @@ -178,15 +181,13 @@ class EventsSpec extends BaseSpec {
def "Request-level events disabled should override account-level analytics settings"() {
given: "BidRequest with events explicitly disabled at request level"
def accountId = PBSUtils.randomNumber as String

def bidRequest = BidRequest.getDefaultBidRequest(requestType).tap {
setAccountId(accountId)
ext.prebid.events = new Events(enabled: false)
}

and: "Account with analytics events enabled for corresponding channel"
def analyticsConfig = new AccountAnalyticsConfig(auctionEvents: [(accountConfigChannelType): true])
def account = new Account(uuid: accountId, eventsEnabled: true, config: new AccountConfig(analytics: analyticsConfig))
def account = getAccountWithAuctionEvent(accountId, [(accountConfigChannelType): true])
accountDao.save(account)

when: "Auction request is processed"
Expand Down Expand Up @@ -219,8 +220,7 @@ class EventsSpec extends BaseSpec {
storedRequestDao.save(StoredRequest.getStoredRequest(accountId, storedRequestId, storedRequest))

and: "Account with analytics events enabled for corresponding channel"
def analyticsConfig = new AccountAnalyticsConfig(auctionEvents: [(accountConfigChannelType): true])
def account = new Account(uuid: accountId, eventsEnabled: true, config: new AccountConfig(analytics: analyticsConfig))
def account = getAccountWithAuctionEvent(accountId, [(accountConfigChannelType): true])
accountDao.save(account)

when: "Auction request is processed"
Expand All @@ -235,4 +235,121 @@ class EventsSpec extends BaseSpec {
APP | ChannelType.APP
DOOH | ChannelType.DOOH
}

def "AMP request-level events config should override account analytics settings"() {
given: "Test start time"
def startTime = Instant.now()

and: "Stored AMP request with events enabled at request level"
def accountId = PBSUtils.randomNumber as String
def ampStoredRequest = BidRequest.getDefaultBidRequest(SITE).tap {
setAccountId(accountId)
ext.prebid.events = requestEventToggle
}

and: "AMP request referencing stored request"
def ampRequest = AmpRequest.defaultAmpRequest.tap {
it.account = ampStoredRequest.accountId
}

and: "Stored request saved in DB"
def storedRequest = StoredRequest.getStoredRequest(ampRequest, ampStoredRequest)
storedRequestDao.save(storedRequest)

and: "Account with analytics events disabled for AMP channel"
def account = getAccountWithAuctionEvent(accountId, [(AMP): false])
accountDao.save(account)

and: "Trace logging enabled for account"
defaultPbsService.sendAccountTracelogConfig(accountId, BidderName.GENERIC)

when: "AMP request is processed"
defaultPbsService.sendAmpRequest(ampRequest)

then: "Events should be present in trace logs bid response"
def logs = defaultPbsService.getLogsByTime(startTime)
def loggedBidResponse = getTraceLoggedResponse(logs, ampStoredRequest.id)
verifyAll(loggedBidResponse?.seatbid[0]?.bid[0]?.ext?.prebid?.events) {
it.win?.contains("a=${accountId}")
it.imp?.contains("a=${accountId}")
}

where:
requestEventToggle << [new Events(), new Events(enabled: true)]
}

def "AMP request-level events disabled should override account analytics settings"() {
given: "Test start time"
def startTime = Instant.now()

and: "Stored AMP request with events explicitly disabled"
def accountId = PBSUtils.randomNumber as String
def ampStoredRequest = BidRequest.getDefaultBidRequest(SITE).tap {
setAccountId(accountId)
ext.prebid.events = new Events(enabled: false)
}

and: "AMP request referencing stored request"
def ampRequest = AmpRequest.defaultAmpRequest.tap {
it.account = accountId
}

and: "Stored request saved in DB"
storedRequestDao.save(StoredRequest.getStoredRequest(ampRequest, ampStoredRequest))

and: "Account with analytics events enabled for AMP channel"
def account = getAccountWithAuctionEvent(accountId, [(AMP): true])
accountDao.save(account)

and: "Trace logging enabled for account"
defaultPbsService.sendAccountTracelogConfig(accountId, BidderName.GENERIC)

when: "AMP request is processed"
defaultPbsService.sendAmpRequest(ampRequest)

then: "Events should not be present in trace logs due to request-level disablement"
def logs = defaultPbsService.getLogsByTime(startTime)
def loggedBidResponse = getTraceLoggedResponse(logs, ampStoredRequest.id)
assert !loggedBidResponse?.seatbid[0]?.bid[0]?.ext?.prebid?.events
}

def "AMP request without events config should fallback to account analytics settings"() {
given: "Test start time"
def startTime = Instant.now()

and: "Stored AMP request with null events config"
def accountId = PBSUtils.randomNumber as String
def ampStoredRequest = BidRequest.getDefaultBidRequest(SITE).tap {
setAccountId(accountId)
ext.prebid.events = null
}

and: "AMP request referencing stored request"
def ampRequest = AmpRequest.defaultAmpRequest.tap {
it.account = ampStoredRequest.accountId
}

and: "Stored request saved in DB"
storedRequestDao.save(StoredRequest.getStoredRequest(ampRequest, ampStoredRequest))

and: "Account with analytics events disabled for AMP channel"
def account = getAccountWithAuctionEvent(accountId, [(AMP): false])
accountDao.save(account)

and: "Trace logging enabled for account"
defaultPbsService.sendAccountTracelogConfig(accountId, BidderName.GENERIC)

when: "AMP request is processed"
defaultPbsService.sendAmpRequest(ampRequest)

then: "Events should not be present in trace logs due to fallback to account-level disablement"
def logs = defaultPbsService.getLogsByTime(startTime)
def loggedBidResponse = getTraceLoggedResponse(logs, ampStoredRequest.id)
assert !loggedBidResponse?.seatbid[0]?.bid[0]?.ext?.prebid?.events
}

private static Account getAccountWithAuctionEvent(String accountId, Map<ChannelType, Boolean> auctionEvents) {
def analyticsConfig = new AccountAnalyticsConfig(auctionEvents: auctionEvents)
new Account(uuid: accountId, eventsEnabled: true, config: new AccountConfig(analytics: analyticsConfig))
}
}
Loading