Skip to content

Commit

Permalink
Video endpoint bid selection enhancement: return all winning bids pe…
Browse files Browse the repository at this point in the history
…r bidder instead of one overall winning bid
  • Loading branch information
Veronika Solovei committed Aug 7, 2020
1 parent f1582a4 commit c89fc29
Show file tree
Hide file tree
Showing 3 changed files with 204 additions and 7 deletions.
1 change: 1 addition & 0 deletions endpoints/openrtb2/video_auction.go
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,7 @@ func createBidExtension(videoRequest *openrtb_ext.BidRequestVideo) ([]byte, erro
IncludeWinners: true,
IncludeBrandCategory: inclBrandCat,
DurationRangeSec: durationRangeSec,
IncludeBidderKeys: true,
}

vastXml := openrtb_ext.ExtRequestPrebidCacheVAST{}
Expand Down
32 changes: 25 additions & 7 deletions exchange/auction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,25 @@ func TestCacheJSON(t *testing.T) {
t.Fatalf("Failed to load contents of file %s: %v", fileDisplayName, err)
}

runCacheSpec(t, fileDisplayName, specData)
runCacheSpec(t, fileDisplayName, specData, false)
}
} else {
t.Fatalf("Failed to read contents of directory exchange/cachetest/: %v", err)
}
}

//In case of video request return all winning bids per bidder
func TestCacheJSONVideo(t *testing.T) {
if specFiles, err := ioutil.ReadDir("./cachetest"); err == nil {
for _, specFile := range specFiles {
fileName := "./cachetest/" + specFile.Name()
fileDisplayName := "exchange/cachetest/" + specFile.Name()
specData, err := loadCacheSpec(fileName)
if err != nil {
t.Fatalf("Failed to load contents of file %s: %v", fileDisplayName, err)
}

runCacheSpec(t, fileDisplayName, specData, true)
}
} else {
t.Fatalf("Failed to read contents of directory exchange/cachetest/: %v", err)
Expand All @@ -128,7 +146,7 @@ func TestCustomCacheKeyJSON(t *testing.T) {
t.Fatalf("Failed to load contents of file %s: %v", fileDisplayName, err)
}

runCacheSpec(t, fileDisplayName, specData)
runCacheSpec(t, fileDisplayName, specData, false)
}
} else {
t.Fatalf("Failed to read contents of directory exchange/customcachekeytest/: %v", err)
Expand All @@ -147,7 +165,7 @@ func TestCustomCacheKeyMultiImp(t *testing.T) {
t.Fatalf("Failed to load contents of file %s: %v", fileDisplayName, err)
}

runCacheSpec(t, fileDisplayName, multiImpSpecData)
runCacheSpec(t, fileDisplayName, multiImpSpecData, false)
}
} else {
t.Fatalf("Failed to read contents of directory exchange/customcachekeytest/: %v", err)
Expand All @@ -172,7 +190,7 @@ func loadCacheSpec(filename string) (*cacheSpec, error) {
// runCacheSpec has been modified to handle multi-Imp and multi-bid Json test files,
// it cycles through the bids found in the test cases hardcoded in json files and
// finds the highest bid of every Imp.
func runCacheSpec(t *testing.T, fileDisplayName string, specData *cacheSpec) {
func runCacheSpec(t *testing.T, fileDisplayName string, specData *cacheSpec, isVideo bool) {
var bid *pbsOrtbBid
winningBidsByImp := make(map[string]*pbsOrtbBid)
winningBidsByBidder := make(map[string]map[openrtb_ext.BidderName]*pbsOrtbBid)
Expand Down Expand Up @@ -245,13 +263,13 @@ func runCacheSpec(t *testing.T, fileDisplayName string, specData *cacheSpec) {
winningBidsByBidder: winningBidsByBidder,
roundedPrices: roundedPrices,
}
_ = testAuction.doCache(ctx, cache, targData, &specData.BidRequest, 60, &specData.DefaultTTLs, bidCategory, &specData.DebugLog)
_ = testAuction.doCache(ctx, cache, targData, &specData.BidRequest, 60, &specData.DefaultTTLs, bidCategory, &specData.DebugLog, isVideo)

if len(specData.ExpectedCacheables) > len(cache.items) {
t.Errorf("%s: [CACHE_ERROR] Less elements were cached than expected \n", fileDisplayName)
} else if len(specData.ExpectedCacheables) < len(cache.items) {
} else if len(specData.ExpectedCacheables) < len(cache.items) && !isVideo {
t.Errorf("%s: [CACHE_ERROR] More elements were cached than expected \n", fileDisplayName)
} else { // len(specData.ExpectedCacheables) == len(cache.items)
} else { //if len(specData.ExpectedCacheables) == len(cache.items)
// We cached the exact number of elements we expected, now we compare them side by side in n^2
var matched int = 0
var formattedExpectedData string
Expand Down
178 changes: 178 additions & 0 deletions exchange/targeting_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,184 @@ func TestTargetingCache(t *testing.T) {

}

func TestSetTargeting(t *testing.T) {

isApp := true
isVideo := false
cacheId := "15c30a3c-5bef-497c-ab51-12a901e46cb3"

categoryMapping, auc, td := createMockAuc(cacheId)

td.setTargeting(auc, isApp, categoryMapping, isVideo)

assert.Equal(t, "", auc.winningBidsByBidder["1_0"]["appnexus"].bidTargets["hb_pb"], "Targeting data is wrong")
assert.Equal(t, "", auc.winningBidsByBidder["1_0"]["appnexus"].bidTargets["hb_cache_id"], "Targeting data is wrong")
assert.Equal(t, "", auc.winningBidsByBidder["1_0"]["appnexus"].bidTargets["hb_pb_cat_dur"], "Targeting data is wrong")

assert.Equal(t, "35.00", auc.winningBidsByBidder["1_0"]["spotx"].bidTargets["hb_pb"], "Targeting data is wrong")
assert.Equal(t, cacheId, auc.winningBidsByBidder["1_0"]["spotx"].bidTargets["hb_cache_id"], "Targeting data is wrong")
assert.Equal(t, "35.00_599_30s", auc.winningBidsByBidder["1_0"]["spotx"].bidTargets["hb_pb_cat_dur"], "Targeting data is wrong")

assert.Equal(t, "12.00", auc.winningBidsByBidder["1_1"]["appnexus"].bidTargets["hb_pb"], "Targeting data is wrong")
assert.Equal(t, cacheId, auc.winningBidsByBidder["1_1"]["appnexus"].bidTargets["hb_cache_id"], "Targeting data is wrong")
assert.Equal(t, "12.00_423_30s", auc.winningBidsByBidder["1_1"]["appnexus"].bidTargets["hb_pb_cat_dur"], "Targeting data is wrong")

assert.Equal(t, "12.00", auc.winningBidsByBidder["1_2"]["appnexus"].bidTargets["hb_pb"], "Targeting data is wrong")
assert.Equal(t, cacheId, auc.winningBidsByBidder["1_2"]["appnexus"].bidTargets["hb_cache_id"], "Targeting data is wrong")
assert.Equal(t, "12.00_432_30s", auc.winningBidsByBidder["1_2"]["appnexus"].bidTargets["hb_pb_cat_dur"], "Targeting data is wrong")

}

func TestSetTargetingVideo(t *testing.T) {

isApp := true
isVideo := true
cacheId := "15c30a3c-5bef-497c-ab51-12a901e46cb3"

categoryMapping, auc, td := createMockAuc(cacheId)

td.setTargeting(auc, isApp, categoryMapping, isVideo)

assert.Equal(t, "12.00", auc.winningBidsByBidder["1_0"]["appnexus"].bidTargets["hb_pb"], "Targeting data is wrong")
assert.Equal(t, cacheId, auc.winningBidsByBidder["1_0"]["appnexus"].bidTargets["hb_cache_id"], "Targeting data is wrong")
assert.Equal(t, "12.00_427_30s", auc.winningBidsByBidder["1_0"]["appnexus"].bidTargets["hb_pb_cat_dur"], "Targeting data is wrong")

assert.Equal(t, "35.00", auc.winningBidsByBidder["1_0"]["spotx"].bidTargets["hb_pb"], "Targeting data is wrong")
assert.Equal(t, cacheId, auc.winningBidsByBidder["1_0"]["spotx"].bidTargets["hb_cache_id"], "Targeting data is wrong")
assert.Equal(t, "35.00_599_30s", auc.winningBidsByBidder["1_0"]["spotx"].bidTargets["hb_pb_cat_dur"], "Targeting data is wrong")

assert.Equal(t, "12.00", auc.winningBidsByBidder["1_1"]["appnexus"].bidTargets["hb_pb"], "Targeting data is wrong")
assert.Equal(t, cacheId, auc.winningBidsByBidder["1_1"]["appnexus"].bidTargets["hb_cache_id"], "Targeting data is wrong")
assert.Equal(t, "12.00_423_30s", auc.winningBidsByBidder["1_1"]["appnexus"].bidTargets["hb_pb_cat_dur"], "Targeting data is wrong")

assert.Equal(t, "12.00", auc.winningBidsByBidder["1_2"]["appnexus"].bidTargets["hb_pb"], "Targeting data is wrong")
assert.Equal(t, cacheId, auc.winningBidsByBidder["1_2"]["appnexus"].bidTargets["hb_cache_id"], "Targeting data is wrong")
assert.Equal(t, "12.00_432_30s", auc.winningBidsByBidder["1_2"]["appnexus"].bidTargets["hb_pb_cat_dur"], "Targeting data is wrong")

}

func createMockAuc(cacheId string) (categoryMapping map[string]string, auc *auction, td targetData) {
winningBidsByImp := make(map[string]*pbsOrtbBid)
winningBidsByBidder := make(map[string]map[openrtb_ext.BidderName]*pbsOrtbBid)
roundedPrices := make(map[*pbsOrtbBid]string)
categoryMapping = make(map[string]string)
vastCacheIds := make(map[*openrtb.Bid]string)
auctionCacheIds := make(map[*openrtb.Bid]string)

var bid1 *pbsOrtbBid = nil
bid1 = &pbsOrtbBid{
bid: &openrtb.Bid{
ID: "10",
ImpID: "1_0",
Price: 12.00,
W: 1280,
H: 720,
Ext: []byte(`{"duration":30,"tier":"1"}`)},
bidType: "video",
}

var bid2 *pbsOrtbBid = nil
bid2 = &pbsOrtbBid{
bid: &openrtb.Bid{
ID: "11",
ImpID: "1_1",
Price: 12.00,
W: 1280,
H: 720,
Ext: []byte(`{"duration":30,"tier":"1"}`)},
bidType: "video",
}

var bid3 *pbsOrtbBid = nil
bid3 = &pbsOrtbBid{
bid: &openrtb.Bid{
ID: "12",
ImpID: "1_2",
Price: 12.00,
W: 1280,
H: 720,
Ext: []byte(`{"duration":30,"tier":"1"}`)},
bidType: "video",
}

var bid4 *pbsOrtbBid = nil
bid4 = &pbsOrtbBid{
bid: &openrtb.Bid{
ID: "1_00",
ImpID: "1_0",
Price: 35.00,
W: 1280,
H: 720,
Ext: []byte(`{"duration":30,"tier":"1"}`)},
bidType: "video",
}

categoryMapping["10"] = "12.00_427_30s"
categoryMapping["11"] = "12.00_423_30s"
categoryMapping["12"] = "12.00_432_30s"
categoryMapping["1_00"] = "35.00_599_30s"

winningBidsByImp["1_0"] = bid4
winningBidsByImp["1_1"] = bid2
winningBidsByImp["1_2"] = bid3

bidsPerBidder1_0 := make(map[openrtb_ext.BidderName]*pbsOrtbBid)
bidsPerBidder1_1 := make(map[openrtb_ext.BidderName]*pbsOrtbBid)
bidsPerBidder1_2 := make(map[openrtb_ext.BidderName]*pbsOrtbBid)

bidsPerBidder1_0["appnexus"] = bid1
bidsPerBidder1_0["spotx"] = bid4

bidsPerBidder1_1["appnexus"] = bid2

bidsPerBidder1_2["appnexus"] = bid3

winningBidsByBidder["1_0"] = bidsPerBidder1_0
winningBidsByBidder["1_1"] = bidsPerBidder1_1
winningBidsByBidder["1_2"] = bidsPerBidder1_2

roundedPrices[bid1] = "12.00"
roundedPrices[bid2] = "12.00"
roundedPrices[bid3] = "12.00"
roundedPrices[bid4] = "35.00"

vastCacheIds[bid1.bid] = cacheId
vastCacheIds[bid2.bid] = cacheId
vastCacheIds[bid3.bid] = cacheId
vastCacheIds[bid4.bid] = cacheId

auctionCacheIds[bid1.bid] = cacheId
auctionCacheIds[bid2.bid] = cacheId
auctionCacheIds[bid3.bid] = cacheId
auctionCacheIds[bid4.bid] = cacheId

//var auc *auction = nil
auc = &auction{
winningBids: winningBidsByImp,
winningBidsByBidder: winningBidsByBidder,
roundedPrices: roundedPrices,
cacheIds: auctionCacheIds,
vastCacheIds: vastCacheIds}

pg := make([]openrtb_ext.GranularityRange, 0)
pg = append(pg, openrtb_ext.GranularityRange{Min: 0, Max: 50, Increment: 3})
pg = append(pg, openrtb_ext.GranularityRange{Min: 50, Max: 100, Increment: 3})
td = targetData{
priceGranularity: openrtb_ext.PriceGranularity{
Precision: 2,
Ranges: pg,
},
includeBidderKeys: false,
includeWinners: true,
includeCacheBids: false,
includeCacheVast: true,
cacheHost: "",
cachePath: "",
}

return
}

func assertKeyExists(t *testing.T, bid *openrtb.Bid, key string, expected bool) {
t.Helper()
targets := parseTargets(t, bid)
Expand Down

0 comments on commit c89fc29

Please sign in to comment.