Skip to content

Commit 658790c

Browse files
Core: Add Zero Non Deal Bids Warning Only in Debug (#3522)
1 parent 98e8065 commit 658790c

9 files changed

Lines changed: 214 additions & 59 deletions

File tree

src/main/java/org/prebid/server/auction/ExchangeService.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,8 @@ private Future<AuctionContext> runAuction(AuctionContext receivedContext) {
273273
storedAuctionResponses,
274274
bidRequest.getImp(),
275275
context.getBidRejectionTrackers()))
276-
.map(auctionParticipations -> dropZeroNonDealBids(auctionParticipations, debugWarnings))
276+
.map(auctionParticipations -> dropZeroNonDealBids(
277+
auctionParticipations, debugWarnings, context.getDebugContext().isDebugEnabled()))
277278
.map(auctionParticipations ->
278279
bidsAdjuster.validateAndAdjustBids(auctionParticipations, context, aliases))
279280
.map(auctionParticipations -> updateResponsesMetrics(auctionParticipations, account, aliases))
@@ -1269,15 +1270,18 @@ private BidderResponse rejectBidderResponseOrProceed(HookStageExecutionResult<Bi
12691270
}
12701271

12711272
private List<AuctionParticipation> dropZeroNonDealBids(List<AuctionParticipation> auctionParticipations,
1272-
List<String> debugWarnings) {
1273+
List<String> debugWarnings,
1274+
boolean isDebugEnabled) {
12731275

12741276
return auctionParticipations.stream()
1275-
.map(auctionParticipation -> dropZeroNonDealBids(auctionParticipation, debugWarnings))
1277+
.map(auctionParticipation -> dropZeroNonDealBids(auctionParticipation, debugWarnings, isDebugEnabled))
12761278
.toList();
12771279
}
12781280

12791281
private AuctionParticipation dropZeroNonDealBids(AuctionParticipation auctionParticipation,
1280-
List<String> debugWarnings) {
1282+
List<String> debugWarnings,
1283+
boolean isDebugEnabled) {
1284+
12811285
final BidderResponse bidderResponse = auctionParticipation.getBidderResponse();
12821286
final BidderSeatBid seatBid = bidderResponse.getSeatBid();
12831287
final List<BidderBid> bidderBids = seatBid.getBids();
@@ -1287,8 +1291,11 @@ private AuctionParticipation dropZeroNonDealBids(AuctionParticipation auctionPar
12871291
final Bid bid = bidderBid.getBid();
12881292
if (isZeroNonDealBids(bid.getPrice(), bid.getDealid())) {
12891293
metrics.updateAdapterRequestErrorMetric(bidderResponse.getBidder(), MetricName.unknown_error);
1290-
debugWarnings.add("Dropped bid '%s'. Does not contain a positive (or zero if there is a deal) 'price'"
1291-
.formatted(bid.getId()));
1294+
if (isDebugEnabled) {
1295+
debugWarnings.add(
1296+
"Dropped bid '%s'. Does not contain a positive (or zero if there is a deal) 'price'"
1297+
.formatted(bid.getId()));
1298+
}
12921299
} else {
12931300
validBids.add(bidderBid);
12941301
}

src/test/groovy/org/prebid/server/functional/model/request/auction/BidRequest.groovy

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import groovy.transform.EqualsAndHashCode
55
import groovy.transform.ToString
66
import org.prebid.server.functional.model.Currency
77

8+
import static org.prebid.server.functional.model.request.auction.DebugCondition.ENABLED
89
import static org.prebid.server.functional.model.request.auction.DistributionChannel.APP
910
import static org.prebid.server.functional.model.request.auction.DistributionChannel.DOOH
1011
import static org.prebid.server.functional.model.request.auction.DistributionChannel.SITE
@@ -22,7 +23,7 @@ class BidRequest {
2223
Dooh dooh
2324
Device device
2425
User user
25-
Integer test
26+
DebugCondition test
2627
Integer at
2728
Long tmax
2829
List<String> wseat
@@ -63,7 +64,7 @@ class BidRequest {
6364
regs = Regs.defaultRegs
6465
id = UUID.randomUUID()
6566
tmax = 2500
66-
ext = new BidRequestExt(prebid: new Prebid(debug: 1))
67+
ext = new BidRequestExt(prebid: new Prebid(debug: ENABLED))
6768
if (channel == SITE) {
6869
site = Site.defaultSite
6970
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package org.prebid.server.functional.model.request.auction
2+
3+
import com.fasterxml.jackson.annotation.JsonValue
4+
5+
enum DebugCondition {
6+
7+
DISABLED(0), ENABLED(1)
8+
9+
@JsonValue
10+
final int value
11+
12+
private DebugCondition(int value) {
13+
this.value = value
14+
}
15+
}

src/test/groovy/org/prebid/server/functional/model/request/auction/Prebid.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import org.prebid.server.functional.model.bidder.BidderName
1010
@ToString(includeNames = true, ignoreNulls = true)
1111
class Prebid {
1212

13-
Integer debug
13+
DebugCondition debug
1414
Boolean returnAllBidStatus
1515
Map<String, BidderName> aliases
1616
Map<String, Integer> aliasgvlids

src/test/groovy/org/prebid/server/functional/tests/BidValidationSpec.groovy

Lines changed: 118 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import spock.lang.PendingFeature
1818
import java.time.Instant
1919

2020
import static org.prebid.server.functional.model.bidder.BidderName.GENERIC
21+
import static org.prebid.server.functional.model.request.auction.DebugCondition.DISABLED
22+
import static org.prebid.server.functional.model.request.auction.DebugCondition.ENABLED
2123
import static org.prebid.server.functional.model.request.auction.DistributionChannel.DOOH
2224
import static org.prebid.server.functional.util.HttpUtil.REFERER_HEADER
2325

@@ -133,7 +135,7 @@ class BidValidationSpec extends BaseSpec {
133135
dooh.id = null
134136
dooh.venueType = null
135137
}
136-
bidDoohRequest.ext.prebid.debug = 1
138+
bidDoohRequest.ext.prebid.debug = ENABLED
137139

138140
when: "PBS processes auction request"
139141
defaultPbsService.sendAuctionRequest(bidDoohRequest)
@@ -148,7 +150,7 @@ class BidValidationSpec extends BaseSpec {
148150
given: "Default basic BidRequest"
149151
def bidRequest = BidRequest.defaultBidRequest
150152
bidRequest.site = new Site(id: null, name: PBSUtils.randomString, page: null)
151-
bidRequest.ext.prebid.debug = 1
153+
bidRequest.ext.prebid.debug = ENABLED
152154

153155
when: "PBS processes auction request"
154156
defaultPbsService.sendAuctionRequest(bidRequest)
@@ -159,9 +161,9 @@ class BidValidationSpec extends BaseSpec {
159161
}
160162

161163
def "PBS should treat bids with 0 price as valid when deal id is present"() {
162-
given: "Default basic BidRequest with generic bidder"
164+
given: "Default basic BidRequest with generic bidder and enabled debug"
163165
def bidRequest = BidRequest.defaultBidRequest
164-
bidRequest.ext.prebid.debug = 1
166+
bidRequest.ext.prebid.debug = ENABLED
165167

166168
and: "Bid response with 0 price bid"
167169
def bidResponse = BidResponse.getDefaultBidResponse(bidRequest)
@@ -183,16 +185,21 @@ class BidValidationSpec extends BaseSpec {
183185
}
184186

185187
def "PBS should drop invalid bid and emit debug error when bid price is #bidPrice and deal id is #dealId"() {
186-
given: "Default basic BidRequest with generic bidder"
187-
def bidRequest = BidRequest.defaultBidRequest
188-
bidRequest.ext.prebid.debug = 1
188+
given: "Default basic BidRequest with generic bidder and enabled debug"
189+
def bidRequest = BidRequest.defaultBidRequest.tap {
190+
it.ext.prebid.debug = debug
191+
it.test = test
192+
}
189193

190194
and: "Bid response"
191-
def bidResponse = BidResponse.getDefaultBidResponse(bidRequest)
192-
def bid = bidResponse.seatbid.first().bid.first()
193-
bid.dealid = dealId
194-
bid.price = bidPrice
195-
def bidId = bid.id
195+
def bidId = PBSUtils.randomString
196+
def bidResponse = BidResponse.getDefaultBidResponse(bidRequest).tap {
197+
it.seatbid.first.bid.first.tap {
198+
id = bidId
199+
dealid = dealId
200+
price = bidPrice
201+
}
202+
}
196203

197204
and: "Set bidder response"
198205
bidder.setResponse(bidRequest.id, bidResponse)
@@ -201,13 +208,61 @@ class BidValidationSpec extends BaseSpec {
201208
def response = defaultPbsService.sendAuctionRequest(bidRequest)
202209

203210
then: "Invalid bid should be deleted"
204-
assert response.seatbid.size() == 0
211+
assert !response.seatbid
212+
assert !response.ext.seatnonbid
205213

206214
and: "PBS should emit an error"
207215
assert response.ext?.warnings[ErrorType.PREBID]*.code == [999]
208216
assert response.ext?.warnings[ErrorType.PREBID]*.message ==
209217
["Dropped bid '$bidId'. Does not contain a positive (or zero if there is a deal) 'price'" as String]
210218

219+
where:
220+
debug | test | bidPrice | dealId
221+
DISABLED | ENABLED | PBSUtils.randomNegativeNumber | null
222+
DISABLED | ENABLED | PBSUtils.randomNegativeNumber | PBSUtils.randomNumber
223+
DISABLED | ENABLED | 0 | null
224+
DISABLED | ENABLED | null | PBSUtils.randomNumber
225+
DISABLED | ENABLED | null | null
226+
ENABLED | DISABLED | PBSUtils.randomNegativeNumber | null
227+
ENABLED | DISABLED | PBSUtils.randomNegativeNumber | PBSUtils.randomNumber
228+
ENABLED | DISABLED | 0 | null
229+
ENABLED | DISABLED | null | PBSUtils.randomNumber
230+
ENABLED | DISABLED | null | null
231+
}
232+
233+
def "PBS should drop invalid bid without debug error when request debug disabled and bid price is #bidPrice and deal id is #dealId"() {
234+
given: "Default basic BidRequest with generic bidder"
235+
def bidRequest = BidRequest.defaultBidRequest.tap {
236+
test = DISABLED
237+
ext.prebid.debug = DISABLED
238+
}
239+
240+
and: "Bid response"
241+
def bidResponse = BidResponse.getDefaultBidResponse(bidRequest).tap {
242+
it.seatbid.first.bid.first.tap {
243+
dealid = dealId
244+
price = bidPrice
245+
}
246+
}
247+
248+
and: "Set bidder response"
249+
bidder.setResponse(bidRequest.id, bidResponse)
250+
251+
when: "PBS processes auction request"
252+
def response = defaultPbsService.sendAuctionRequest(bidRequest)
253+
254+
then: "Invalid bid should be deleted"
255+
assert !response.seatbid
256+
assert !response.ext.seatnonbid
257+
258+
and: "PBS shouldn't emit an error"
259+
assert !response.ext?.warnings
260+
assert !response.ext?.warnings
261+
262+
and: "PBS should call bidder"
263+
def bidderRequests = bidder.getBidderRequests(bidResponse.id)
264+
assert bidderRequests.size() == 1
265+
211266
where:
212267
bidPrice | dealId
213268
PBSUtils.randomNegativeNumber | null
@@ -220,7 +275,7 @@ class BidValidationSpec extends BaseSpec {
220275
def "PBS should only drop invalid bid without discarding whole seat"() {
221276
given: "Default basic BidRequest with generic bidder"
222277
def bidRequest = BidRequest.defaultBidRequest
223-
bidRequest.ext.prebid.debug = 1
278+
bidRequest.ext.prebid.debug = ENABLED
224279
bidRequest.ext.prebid.multibid = [new MultiBid(bidder: GENERIC, maxBids: 2)]
225280

226281
and: "Bid response with 2 bids"
@@ -239,14 +294,61 @@ class BidValidationSpec extends BaseSpec {
239294
when: "PBS processes auction request"
240295
def response = defaultPbsService.sendAuctionRequest(bidRequest)
241296

242-
then: "Invalid bids should be deleted"
297+
then: "Bid response contains only valid bid"
243298
assert response.seatbid?.first()?.bid*.id == [validBidId]
244299

245300
and: "PBS should emit an error"
246301
assert response.ext?.warnings[ErrorType.PREBID]*.code == [999]
247302
assert response.ext?.warnings[ErrorType.PREBID]*.message ==
248303
["Dropped bid '$invalidBid.id'. Does not contain a positive (or zero if there is a deal) 'price'" as String]
249304

305+
where:
306+
debug | test | bidPrice | dealId
307+
0 | 1 | PBSUtils.randomNegativeNumber | null
308+
0 | 1 | PBSUtils.randomNegativeNumber | PBSUtils.randomNumber
309+
0 | 1 | 0 | null
310+
0 | 1 | null | PBSUtils.randomNumber
311+
0 | 1 | null | null
312+
1 | 0 | PBSUtils.randomNegativeNumber | null
313+
1 | 0 | PBSUtils.randomNegativeNumber | PBSUtils.randomNumber
314+
1 | 0 | 0 | null
315+
1 | 0 | null | PBSUtils.randomNumber
316+
1 | 0 | null | null
317+
}
318+
319+
def "PBS should only drop invalid bid without discarding whole seat without debug error when request debug disabled "() {
320+
given: "Default basic BidRequest with generic bidder"
321+
def bidRequest = BidRequest.defaultBidRequest.tap {
322+
test = DISABLED
323+
ext.prebid.tap {
324+
debug = DISABLED
325+
multibid = [new MultiBid(bidder: GENERIC, maxBids: 2)]
326+
}
327+
}
328+
329+
and: "Bid response with 2 bids"
330+
def bidResponse = BidResponse.getDefaultBidResponse(bidRequest)
331+
bidResponse.seatbid[0].bid << Bid.getDefaultBid(bidRequest.imp.first())
332+
333+
and: "One of the bids is invalid"
334+
def invalidBid = bidResponse.seatbid.first().bid.first()
335+
invalidBid.dealid = dealId
336+
invalidBid.price = bidPrice
337+
def validBidId = bidResponse.seatbid.first().bid.last().id
338+
339+
and: "Set bidder response"
340+
bidder.setResponse(bidRequest.id, bidResponse)
341+
342+
when: "PBS processes auction request"
343+
def response = defaultPbsService.sendAuctionRequest(bidRequest)
344+
345+
then: "Bid response contains only valid bid"
346+
assert response.seatbid?.first()?.bid*.id == [validBidId]
347+
348+
and: "PBS shouldn't emit an error"
349+
assert !response.ext?.warnings
350+
assert !response.ext?.warnings
351+
250352
where:
251353
bidPrice | dealId
252354
PBSUtils.randomNegativeNumber | null
@@ -257,10 +359,7 @@ class BidValidationSpec extends BaseSpec {
257359
}
258360

259361
def "PBS should update 'adapter.generic.requests.bid_validation' metric when bid validation error appears"() {
260-
given: "Initial 'adapter.generic.requests.bid_validation' metric value"
261-
def initialMetricValue = getCurrentMetricValue(defaultPbsService, "adapter.generic.requests.bid_validation")
262-
263-
and: "Bid request"
362+
given: "Bid request"
264363
def bidRequest = BidRequest.defaultBidRequest
265364

266365
and: "Set invalid bid response"

0 commit comments

Comments
 (0)