Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate Bid ID Test Hardening #3491

Merged
merged 5 commits into from
Mar 5, 2024
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
13 changes: 7 additions & 6 deletions exchange/exchange.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ type bidResponseWrapper struct {
}

type BidIDGenerator interface {
New() (string, error)
New(bidder string) (string, error)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a bidder name as input to the generator for deterministic results during test. May be useful if hosts want to add per-bidder logic.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally I'm skeptical about modifying non-test code to enhance tests. It's probably ok in this case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with you. I need some way in these tests to get around the random ordering of bidders to fit into the json test framework. I could pull this out into a separate unit test and not need to make this change. I also feel it's probably ok in this case since this isn't a literal "if test, do this" code block and there are potential use cases where an bid generator might want to generate bidder specific ids.

Enabled() bool
}

Expand All @@ -116,7 +116,7 @@ func (big *bidIDGenerator) Enabled() bool {
return big.enabled
}

func (big *bidIDGenerator) New() (string, error) {
func (big *bidIDGenerator) New(bidder string) (string, error) {
rawUuid, err := uuid.NewV4()
return rawUuid.String(), err
}
Expand Down Expand Up @@ -415,10 +415,11 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog
}

if e.bidIDGenerator.Enabled() {
for _, seatBid := range adapterBids {
for _, pbsBid := range seatBid.Bids {
pbsBid.GeneratedBidID, err = e.bidIDGenerator.New()
if err != nil {
for bidder, seatBid := range adapterBids {
for i := range seatBid.Bids {
if bidID, err := e.bidIDGenerator.New(bidder.String()); err == nil {
seatBid.Bids[i].GeneratedBidID = bidID
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to referencing the slice via index instead of an accessor, but this is not a loop bug since the accessor is a pointer.

} else {
errs = append(errs, errors.New("Error generating bid.ext.prebid.bidid"))
}
}
Expand Down
52 changes: 28 additions & 24 deletions exchange/exchange_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@ func TestOverrideWithCustomCurrency(t *testing.T) {
}.Builder
e.currencyConverter = mockCurrencyConverter
e.categoriesFetcher = categoriesFetcher
e.bidIDGenerator = &mockBidIDGenerator{false, false}
e.bidIDGenerator = &fakeBidIDGenerator{GenerateBidID: false, ReturnError: false}
e.requestSplitter = requestSplitter{
me: e.me,
gdprPermsBuilder: e.gdprPermsBuilder,
Expand Down Expand Up @@ -766,7 +766,7 @@ func TestAdapterCurrency(t *testing.T) {
}.Builder,
currencyConverter: currencyConverter,
categoriesFetcher: nilCategoryFetcher{},
bidIDGenerator: &mockBidIDGenerator{false, false},
bidIDGenerator: &fakeBidIDGenerator{GenerateBidID: false, ReturnError: false},
adapterMap: map[openrtb_ext.BidderName]AdaptedBidder{
openrtb_ext.BidderName("appnexus"): AdaptBidder(mockBidder, nil, &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, openrtb_ext.BidderName("appnexus"), nil, ""),
},
Expand Down Expand Up @@ -844,7 +844,7 @@ func TestFloorsSignalling(t *testing.T) {
}.Builder,
currencyConverter: currencyConverter,
categoriesFetcher: nilCategoryFetcher{},
bidIDGenerator: &mockBidIDGenerator{false, false},
bidIDGenerator: &fakeBidIDGenerator{GenerateBidID: false, ReturnError: false},
priceFloorEnabled: true,
priceFloorFetcher: &mockPriceFloorFetcher{},
}
Expand Down Expand Up @@ -1127,7 +1127,7 @@ func TestReturnCreativeEndToEnd(t *testing.T) {
}.Builder
e.currencyConverter = currency.NewRateConverter(&http.Client{}, "", time.Duration(0))
e.categoriesFetcher = categoriesFetcher
e.bidIDGenerator = &mockBidIDGenerator{false, false}
e.bidIDGenerator = &fakeBidIDGenerator{GenerateBidID: false, ReturnError: false}
e.requestSplitter = requestSplitter{
me: e.me,
gdprPermsBuilder: e.gdprPermsBuilder,
Expand Down Expand Up @@ -2131,9 +2131,9 @@ func runSpec(t *testing.T, filename string, spec *exchangeSpec) {
},
},
}
bidIdGenerator := &mockBidIDGenerator{}
bidIdGenerator := &fakeBidIDGenerator{}
if spec.BidIDGenerator != nil {
*bidIdGenerator = *spec.BidIDGenerator
bidIdGenerator = spec.BidIDGenerator
}
ex := newExchangeForTests(t, filename, spec.OutgoingRequests, aliases, privacyConfig, bidIdGenerator, spec.HostSChainFlag, spec.FloorsEnabled, spec.HostConfigBidValidation, spec.Server)
biddersInAuction := findBiddersInAuction(t, filename, &spec.IncomingRequest.OrtbRequest)
Expand Down Expand Up @@ -2449,31 +2449,35 @@ func newExchangeForTests(t *testing.T, filename string, expectations map[string]
}
}

type mockBidIDGenerator struct {
type fakeBidIDGenerator struct {
GenerateBidID bool `json:"generateBidID"`
ReturnError bool `json:"returnError"`
bidCount map[string]int
}

func (big *mockBidIDGenerator) Enabled() bool {
return big.GenerateBidID
func (f *fakeBidIDGenerator) Enabled() bool {
return f.GenerateBidID
}

func (big *mockBidIDGenerator) New() (string, error) {
func (f *fakeBidIDGenerator) New(bidder string) (string, error) {
if f.ReturnError {
return "", errors.New("Test error generating bid.ext.prebid.bidid")
}

if big.ReturnError {
err := errors.New("Test error generating bid.ext.prebid.bidid")
return "", err
if f.bidCount == nil {
f.bidCount = make(map[string]int)
}
return "mock_uuid", nil

f.bidCount[bidder] += 1
return fmt.Sprintf("bid-%v-%v", bidder, f.bidCount[bidder]), nil
}

type fakeRandomDeduplicateBidBooleanGenerator struct {
returnValue bool
type fakeBooleanGenerator struct {
value bool
}

func (m *fakeRandomDeduplicateBidBooleanGenerator) Generate() bool {
return m.returnValue
func (f *fakeBooleanGenerator) Generate() bool {
return f.value
}

func newExtRequest() openrtb_ext.ExtRequest {
Expand Down Expand Up @@ -2841,7 +2845,7 @@ func TestCategoryDedupe(t *testing.T) {
Currency: "USD",
},
}
deduplicateGenerator := fakeRandomDeduplicateBidBooleanGenerator{returnValue: tt.dedupeGeneratorValue}
deduplicateGenerator := fakeBooleanGenerator{value: tt.dedupeGeneratorValue}
bidCategory, adapterBids, rejections, err := applyCategoryMapping(nil, *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &deduplicateGenerator, &nonBids{})

assert.Nil(t, err)
Expand Down Expand Up @@ -3278,7 +3282,7 @@ func TestCategoryMappingTwoBiddersManyBidsEachNoCategorySamePrice(t *testing.T)
adapterBids[bidderNameApn1] = &seatBidApn1
adapterBids[bidderNameApn2] = &seatBidApn2

_, adapterBids, rejections, err := applyCategoryMapping(nil, *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &fakeRandomDeduplicateBidBooleanGenerator{true}, &nonBids{})
_, adapterBids, rejections, err := applyCategoryMapping(nil, *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &fakeBooleanGenerator{value: true}, &nonBids{})

assert.NoError(t, err, "Category mapping error should be empty")

Expand Down Expand Up @@ -4102,7 +4106,7 @@ func TestStoredAuctionResponses(t *testing.T) {
e.cache = &wellBehavedCache{}
e.me = &metricsConf.NilMetricsEngine{}
e.categoriesFetcher = categoriesFetcher
e.bidIDGenerator = &mockBidIDGenerator{false, false}
e.bidIDGenerator = &fakeBidIDGenerator{GenerateBidID: false, ReturnError: false}
e.currencyConverter = currency.NewRateConverter(&http.Client{}, "", time.Duration(0))
e.gdprPermsBuilder = fakePermissionsBuilder{
permissions: &permissionsMock{
Expand Down Expand Up @@ -4468,7 +4472,7 @@ func TestAuctionDebugEnabled(t *testing.T) {
e.cache = &wellBehavedCache{}
e.me = &metricsConf.NilMetricsEngine{}
e.categoriesFetcher = categoriesFetcher
e.bidIDGenerator = &mockBidIDGenerator{false, false}
e.bidIDGenerator = &fakeBidIDGenerator{GenerateBidID: false, ReturnError: false}
e.currencyConverter = currency.NewRateConverter(&http.Client{}, "", time.Duration(0))
e.gdprPermsBuilder = fakePermissionsBuilder{
permissions: &permissionsMock{
Expand Down Expand Up @@ -5029,7 +5033,7 @@ func TestOverrideConfigAlternateBidderCodesWithRequestValues(t *testing.T) {
}.Builder
e.currencyConverter = currency.NewRateConverter(&http.Client{}, "", time.Duration(0))
e.categoriesFetcher = categoriesFetcher
e.bidIDGenerator = &mockBidIDGenerator{false, false}
e.bidIDGenerator = &fakeBidIDGenerator{GenerateBidID: false, ReturnError: false}
e.requestSplitter = requestSplitter{
me: e.me,
gdprPermsBuilder: e.gdprPermsBuilder,
Expand Down Expand Up @@ -5426,7 +5430,7 @@ type exchangeSpec struct {
DebugLog *DebugLog `json:"debuglog,omitempty"`
EventsEnabled bool `json:"events_enabled,omitempty"`
StartTime int64 `json:"start_time_ms,omitempty"`
BidIDGenerator *mockBidIDGenerator `json:"bidIDGenerator,omitempty"`
BidIDGenerator *fakeBidIDGenerator `json:"bidIDGenerator,omitempty"`
RequestType *metrics.RequestType `json:"requestType,omitempty"`
PassthroughFlag bool `json:"passthrough_flag,omitempty"`
HostSChainFlag bool `json:"host_schain_flag,omitempty"`
Expand Down
200 changes: 0 additions & 200 deletions exchange/exchangetest/bid-id-invalid.json

This file was deleted.

Loading
Loading