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

Log non bid reasons in bidder framework #2891

Merged
merged 43 commits into from
Sep 19, 2024

Conversation

ShriprasadM
Copy link
Contributor

@ShriprasadM ShriprasadM commented Jul 3, 2023

Related. to - #2852
@SyntaxNode / @hhhjort : Please review this.

  1. Modified the bidder request framework to have a provision of capturing seat non bid reasons

PROPOSAL - Needs adapters to provide impression id associated with the request data

  1. As per bidder.go - MakeRequests bidder can form array of requests
    reqData, errs = bidder.Bidder.MakeRequests(bidderRequest.BidRequest, reqInfo)
  2. So, framework gets following scenarios. But, we will not be able to match up the error (if any) corresponds to which impression id, as framework will not be able to determine the relation between requestData and impressionId
  3. Scenario - Prebid Server received request with 3 impressions (Multi Impression Request) and bidder has timed out
Bidder MakeRequests behaviour Non Bid Reason
Bidder A Return requestData array of size 3 Imp1 - Bidder Responded, Imp2 - Bidder Timeout , Imp3 - Bidder Timeout then ideally non bid reason should be only for imp2 and imp3 and not for imp1. But, we are unable to identify the obtain array of RequestData and impId relation
Bidder B Return requestData array of size 1 If bidder time outs then it must be applicable for all the impressions. Because, if will single network call

type RequestData struct {

// RequestData packages together the fields needed to make an http.Request.
type RequestData struct {
	Method  string
	Uri     string
	Body    []byte
	Headers http.Header
        ImpID string // new proposed field. Bidder suppose to provide
}

@ShriprasadM ShriprasadM marked this pull request as ready for review July 4, 2023 13:23
@bsardo bsardo changed the title i2852: Added support in bidder framework to log non bid reasons Log non bid reasons in bidder framework Jul 6, 2023
@@ -22,3 +25,11 @@ func (n *NonBidReason) Val() NonBidReason {
}
return *n
}

func ErrorToNonBidReason(errorCode int) NonBidReason {
switch errorCode {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you anticipate more cases to be added to this switch statement in the future? If not, can this be simplified to just check if errorCode == errortypes.TimeoutErrorCode?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I could see we will need to incorporate more cases here in future based on the Seat Non Bid community extension

func ErrorToNonBidReason(errorCode int) NonBidReason {
switch errorCode {
case errortypes.TimeoutErrorCode:
return ErrorTimeout
Copy link
Contributor

Choose a reason for hiding this comment

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

And is there a way to test this function so that this line is covered?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Covered via

func TestSeatNonBid(t *testing.T) {

@AlexBVolcy
Copy link
Contributor

@ShriprasadM Just pinging this PR to see if you'll be able to address my comments

@ShriprasadM
Copy link
Contributor Author

@AlexBVolcy : As per discussion on bi-weekly meeting, when can we expect findings around above proposal?

@ShriprasadM
Copy link
Contributor Author

@ShriprasadM Just pinging this PR to see if you'll be able to address my comments

Yes. please check the updated PR

// seatBids: []*entities.PbsOrtbSeatBid{{Bids: []*entities.PbsOrtbBid{}, Currency: "USD", Seat: "someseat", HttpCalls: []*openrtb_ext.ExtHttpCall{}}},
},
}, /* {
name: "103_bidder_unreachable",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why is this test commented out?

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 was trying to make core unit test implementation reusable for future error code. will revert it for now

newErr := openrtb_ext.ExtBidderMessage{
Code: errortypes.ReadCode(err),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why was this change made?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Reverted this change. It is unwanted. Initially I was trying to accommodate, seatnonbid related changes here

@@ -1582,5 +1595,8 @@ func setSeatNonBid(bidResponseExt *openrtb_ext.ExtBidResponse, seatNonBids nonBi
}

bidResponseExt.Prebid.SeatNonBid = seatNonBids.get()
if adapterNonBids != nil {
bidResponseExt.Prebid.SeatNonBid = append(bidResponseExt.Prebid.SeatNonBid, adapterNonBids...)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this functionality tested anywhere?

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 have tested locally. But will add the unit test for it.

Copy link
Contributor

@AlexBVolcy AlexBVolcy left a comment

Choose a reason for hiding this comment

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

Looks good! Left one comment

@@ -3056,3 +3056,91 @@ func TestGetBidType(t *testing.T) {
})
}
}

func TestSeatNonBid(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Are there any other test cases you can think of that would make sense here? I only ask since I see only one test case and was wondering if there are any others that would make sense.

@AlexBVolcy
Copy link
Contributor

@ShriprasadM just pinging to see if you've seen the above comments made? And if you could merge with master to fix conflicts that'd be great!

@hhhjort
Copy link
Collaborator

hhhjort commented Jul 24, 2023

This PR will require that adapters return imp IDs from MakeRequests so that we know what errors go with which Imps. Blocked until a separate PR adds imps to MakeRequests return values.

@ShriprasadM
Copy link
Contributor Author

This PR will require that adapters return imp IDs from MakeRequests so that we know what errors go with which Imps. Blocked until a separate PR adds imps to MakeRequests return values.

@hhhjort and @SyntaxNode : I have created separate issue - #2973 for this

Seat: string(bidderRequest.BidderName),
NonBid: make([]openrtb_ext.NonBid, len(bidderRequest.BidRequest.Imp)),
}
for i, imp := range bidderRequest.BidRequest.Imp {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@SyntaxNode and team:
If you look at the above code snippet, we are applying nonBidReason flat across all impressions here. As, we are not able to identify per impression level scenario here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@SyntaxNode / @hhhjort : Can you update here?

Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't this address by #2973?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@SyntaxNode : #2973 will address adapter level changes. Until, adapters are not providing impression level information in RequestData, this block of implementation will apply nonBidReason flat across all impressions.

So, I am proposing, till #2973 not effective, can we move on with the above assumption. I know there will be ambiguous cases, where adapter may have bided for the impression but still will add it under non bid because other impression may have timed out

Copy link
Contributor

Choose a reason for hiding this comment

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

We can discuss at our next catchup. I was under the impression we decided to pause this issue until we implement #2973. Then we can avoid ambiguous cases.

@SyntaxNode
Copy link
Contributor

Prebid Server 2.0 has been released and Go Module name has changed from github.com/prebid/prebid-server to github.com/prebid/prebid-server/v2, per Go versioning conventions.

Please merge the master branch and update all prebid-server import statements to reference the v2 name change. Thank you.

@SyntaxNode
Copy link
Contributor

Blocked By #3364

@ShriprasadM
Copy link
Contributor Author

@SyntaxNode can you check my replies on review comments?

Copy link
Collaborator

@bsardo bsardo left a comment

Choose a reason for hiding this comment

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

@ShriprasadM Scott and I discussed offline. Please see my latest comments.


const (
NoBidUnknownError NonBidReason = 0 // No Bid - General
Copy link
Collaborator

Choose a reason for hiding this comment

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

Agreed. Please bring this back and update all of the non bid reasons on lines 17-25 to be of type NonBidReason. It is my understanding that the openrtb3.NoBidReason type is used to enumerate no bid reason codes sent back from a bidder in its response. Those reason codes will only ever be between 0-99. It is true that those no bid reason codes may end up being reported by Prebid Server as non bid reasons but they should be mapped from the no bid reason enumeration to the non bid reason enumeration even though the numbers line up since the enumerations have different meaning and are not identical. The non bid reasons could also end up being any of these Prebid Server specific codes starting at 100.

}

// isBidderUnreachableError checks if the error is due to connection refused or no such host
func isBidderUnreachableError(httpInfo *httpCallInfo) bool {
return errors.Is(httpInfo.err, syscall.ECONNREFUSED) || strings.Contains(httpInfo.err.Error(), "no such host")
var dnsErr *net.DNSError
return errors.Is(httpInfo.err, syscall.ECONNREFUSED) || (errors.As(httpInfo.err, &dnsErr) && dnsErr.IsNotFound)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is a bit cryptic. I prefer using the temporary self explanatory variable @SyntaxNode suggested:

isNoSuchHost := errors.As(err, &dnsErr) && dnsErr.IsNotFound
return errors.Is(httpInfo.err, syscall.ECONNREFUSED) || isNoSuchHost

Copy link
Contributor

Choose a reason for hiding this comment

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

done

// get returns a slice of SeatNonBid objects representing the non-bids for each seat.
// If snb is nil, it returns nil.
// It iterates over the seatNonBidsMap and appends each seat and its corresponding non-bids to the seatNonBid slice.
// Finally, it returns the seatNonBid slice.
func (snb *nonBids) get() []openrtb_ext.SeatNonBid {
Copy link
Collaborator

Choose a reason for hiding this comment

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

@SyntaxNode and I agree that this should be refactored. This file can be simplified quite a bit. This proposal also addresses other comments about proxyNonBids and function naming.

package exchange

import (
	"github.com/prebid/openrtb/v20/openrtb3"
	"github.com/prebid/prebid-server/v2/exchange/entities"
	"github.com/prebid/prebid-server/v2/openrtb_ext"
)

type SeatNonBidBuilder map[string][]openrtb_ext.NonBid

// rejectBid appends a non bid object to the builder based on a bid
func (b SeatNonBidBuilder) rejectBid(bid *entities.PbsOrtbBid, nonBidReason int, seat string) {
	if bid == nil || bid.Bid == nil {
		return
	}

	nonBid := openrtb_ext.NonBid{
		ImpId:      bid.Bid.ImpID,
		StatusCode: nonBidReason,
		Ext: &openrtb_ext.NonBidExt{
			Prebid: openrtb_ext.ExtResponseNonBidPrebid{Bid: openrtb_ext.NonBidObject{
				Price:          bid.Bid.Price,
				ADomain:        bid.Bid.ADomain,
				CatTax:         bid.Bid.CatTax,
				Cat:            bid.Bid.Cat,
				DealID:         bid.Bid.DealID,
				W:              bid.Bid.W,
				H:              bid.Bid.H,
				Dur:            bid.Bid.Dur,
				MType:          bid.Bid.MType,
				OriginalBidCPM: bid.OriginalBidCPM,
				OriginalBidCur: bid.OriginalBidCur,
			}},
		},
	}
	b[seat] = append(b[seat], nonBid)
}

// rejectImps appends a non bid object to the builder for every specified imp
func (b SeatNonBidBuilder) rejectImps(impIds []string, nonBidReason openrtb3.NoBidReason, seat string) {
	nonBids := []openrtb_ext.NonBid{}
	for _, impId := range impIds {
		nonBid := openrtb_ext.NonBid{
			ImpId:      impId,
			StatusCode: int(nonBidReason),
		}
		nonBids = append(nonBids, nonBid)
	}
	
	if len(nonBids) > 0 {
		b[seat] = append(b[seat], nonBids...)
	}
}

// slice transforms the seat non bid map into a slice of SeatNonBid objects representing the non-bids for each seat
func (b SeatNonBidBuilder) Slice() []openrtb_ext.SeatNonBid {
	seatNonBid := make([]openrtb_ext.SeatNonBid, 0)
	for seat, nonBids := range b {
		seatNonBid = append(seatNonBid, openrtb_ext.SeatNonBid{
			Seat:   seat,
			NonBid: nonBids,
		})
	}
	return seatNonBid
}

Also we shouldn't need to create the seat non bid map from within the receiver functions. We can just create an instance of the builder prior to calling the receiver methods.

@ashishshinde-pubm
Copy link
Contributor

@bsardo addressed the review comments, please check.

seatNonBid = append(seatNonBid, openrtb_ext.SeatNonBid{
Seat: seat,
NonBid: nonBids,
})
}
return seatNonBid
}

// append adds the nonBids from the input nonBids to the current nonBids.
// This method is not thread safe as we are initializing and writing to map
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think you can delete this second comment.

Copy link
Contributor

Choose a reason for hiding this comment

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

Deleted.

Comment on lines 42 to 44
// errorCode := errortypes.ReadCode(httpInfo.err)
nonBidReason := errorToNonBidReason(httpInfo.err)
// nonBidReason := errorToNonBidReason(errorCode)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Remove commented code.

seatBids := make([]*entities.PbsOrtbSeatBid, 0, len(seatBidMap))
for _, seatBid := range seatBidMap {
seatBids = append(seatBids, seatBid)
}

extraRespInfo.seatNonBidBuilder = seatNonBidBuilder
Copy link
Collaborator

Choose a reason for hiding this comment

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

It looks like this will be nil if there aren't any imps. If there is at least one imp, this will be an empty map or a map with entries if there was at least one http error. Is that correct?
I'm thinking that it might be easier if seatNonBidBuilder is always not nil. Thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

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

initialised the seatNonBidBuilder to empty map.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Please add unit tests for rejectImps and append functions.

Copy link
Contributor

Choose a reason for hiding this comment

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

Add Unit test for append and rejectImps.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I know you were probably trying to make minimal updates to the code that's here since this part is due to the refactor we asked for but I think we should remove the indirection in these tests as I find it a bit confusing. IMO it is better to be verbose in tests than introduce helper functions like the ones in this file. You can replace what's here with what I provided offline which also covers some cases that are currently missing but that I think we should have:

func TestRejectImps(t *testing.T) {
	tests := []struct{
		name    string
		impIDs  []string
		builder SeatNonBidBuilder
		want    SeatNonBidBuilder
	}{
		{
			name: "nil_imps",
			impIDs: nil,
			builder: SeatNonBidBuilder{},
			want: SeatNonBidBuilder{},
		},
		{
			name: "empty_imps",
			impIDs: []string{},
			builder: SeatNonBidBuilder{},
			want: SeatNonBidBuilder{},
		},
		{
			name: "one_imp",
			impIDs: []string{"imp1"},
			builder: SeatNonBidBuilder{},
			want: SeatNonBidBuilder{
				"seat1": []openrtb_ext.NonBid{
					{
						ImpId: "imp1",
						StatusCode: 300,
					},
				},
			},
		},
		{
			name: "many_imps",
			impIDs: []string{"imp1", "imp2"},
			builder: SeatNonBidBuilder{},
			want: SeatNonBidBuilder{
				"seat1": []openrtb_ext.NonBid{
					{
						ImpId: "imp1",
						StatusCode: 300,
					},
					{
						ImpId: "imp2",
						StatusCode: 300,
					},
				},
			},
		},
		{
			name: "many_imps_appended_to_prepopulated_list",
			impIDs: []string{"imp1", "imp2"},
			builder: SeatNonBidBuilder{
				"seat0": []openrtb_ext.NonBid{
					{
						ImpId: "imp0",
						StatusCode: 0,
					},
				},
			},
			want: SeatNonBidBuilder{
				"seat0": []openrtb_ext.NonBid{
					{
						ImpId: "imp0",
						StatusCode: 0,
					},
				},
				"seat1": []openrtb_ext.NonBid{
					{
						ImpId: "imp1",
						StatusCode: 300,
					},
					{
						ImpId: "imp2",
						StatusCode: 300,
					},
				},
			},
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			test.builder.rejectImps(test.impIDs, 300, "seat1")

			assert.Equal(t, len(test.builder), len(test.want))
			for seat := range test.want {
				assert.ElementsMatch(t, test.want[seat], test.builder[seat])
			}
		})
	}
}

func TestSlice(t *testing.T) {
	tests := []struct{
		name    string
		builder SeatNonBidBuilder
		want    []openrtb_ext.SeatNonBid
	}{
		{
			name: "nil",
			builder: nil,
			want:    []openrtb_ext.SeatNonBid{},
		},
		{
			name: "empty",
			builder: SeatNonBidBuilder{},
			want:    []openrtb_ext.SeatNonBid{},
		},
		{
			name: "one_no_nonbids",
			builder: SeatNonBidBuilder{
				"a": []openrtb_ext.NonBid{},
			},
			want: []openrtb_ext.SeatNonBid{
				{
					NonBid: []openrtb_ext.NonBid{},
					Seat: "a",
				},
			},
		},
		{
			name: "one_with_nonbids",
			builder: SeatNonBidBuilder{
				"a": []openrtb_ext.NonBid{
					{
						ImpId: "imp1",
						StatusCode: 100,
					},
					{
						ImpId: "imp2",
						StatusCode: 200,
					},
				},
			},
			want: []openrtb_ext.SeatNonBid{
				{
					NonBid: []openrtb_ext.NonBid{
						{
							ImpId: "imp1",
							StatusCode: 100,
						},
						{
							ImpId: "imp2",
							StatusCode: 200,
						},
					},
					Seat: "a",
				},
			},
		},
		{
			name: "many_no_nonbids",
			builder: SeatNonBidBuilder{
				"a": []openrtb_ext.NonBid{},
				"b": []openrtb_ext.NonBid{},
				"c": []openrtb_ext.NonBid{},
			},
			want: []openrtb_ext.SeatNonBid{
				{
					NonBid: []openrtb_ext.NonBid{},
					Seat: "a",
				},
				{
					NonBid: []openrtb_ext.NonBid{},
					Seat: "b",
				},
				{
					NonBid: []openrtb_ext.NonBid{},
					Seat: "c",
				},
			},
		},
		{
			name: "many_with_nonbids",
			builder: SeatNonBidBuilder{
				"a": []openrtb_ext.NonBid{
					{
						ImpId: "imp1",
						StatusCode: 100,
					},
					{
						ImpId: "imp2",
						StatusCode: 200,
					},
				},
				"b": []openrtb_ext.NonBid{
					{
						ImpId: "imp3",
						StatusCode: 300,
					},
				},
				"c": []openrtb_ext.NonBid{
					{
						ImpId: "imp4",
						StatusCode: 400,
					},
					{
						ImpId: "imp5",
						StatusCode: 500,
					},
				},
			},
			want: []openrtb_ext.SeatNonBid{
				{
					NonBid: []openrtb_ext.NonBid{
						{
							ImpId: "imp1",
							StatusCode: 100,
						},
						{
							ImpId: "imp2",
							StatusCode: 200,
						},
					},
					Seat: "a",
				},
				{
					NonBid: []openrtb_ext.NonBid{
						{
							ImpId: "imp3",
							StatusCode: 300,
						},
					},
					Seat: "b",
				},
				{
					NonBid: []openrtb_ext.NonBid{
						{
							ImpId: "imp4",
							StatusCode: 400,
						},
						{
							ImpId: "imp5",
							StatusCode: 500,
						},
					},
					Seat: "c",
				},
			},
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			result := test.builder.Slice()
			assert.ElementsMatch(t, test.want, result)
		})
	}
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Add Unit test for append and rejectImps.

Comment on lines +406 to +408
if extraRespInfo.seatNonBidBuilder != nil {
seatNonBidBuilder = extraRespInfo.seatNonBidBuilder
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

extraRespInfo.seatNonBidBuilder will never be nil based on how getAllBids works but perhaps we should keep this nil check given the complexity of this code and since we don't have any unit tests for getAllBids to ensure it is never nil? @SyntaxNode thoughts?

@Pubmatic-Dhruv-Sonone
Copy link
Contributor

@bsardo Addressed review comments. Please check.

@@ -107,3 +78,293 @@ var sampleSeatBids = func(seat string, nonBidCount int) []openrtb_ext.SeatNonBid
seatNonBids = append(seatNonBids, seatNonBid)
return seatNonBids
}

func TestAppend(t *testing.T) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please add the following test cases:

    {
			name:     "nil_append",
			builder:  SeatNonBidBuilder{"seat1": []openrtb_ext.NonBid{{ImpId: "imp1"}}},
			toAppend: nil,
			expected: SeatNonBidBuilder{"seat1": []openrtb_ext.NonBid{{ImpId: "imp1"}}},
		},
		{
			name:     "empty_append",
			builder:  SeatNonBidBuilder{"seat1": []openrtb_ext.NonBid{{ImpId: "imp1"}}},
			toAppend: []SeatNonBidBuilder{},
			expected: SeatNonBidBuilder{"seat1": []openrtb_ext.NonBid{{ImpId: "imp1"}}},
		},
        {
			name:     "append_multiple_same_seat",
			builder:  SeatNonBidBuilder{
				"seat1": []openrtb_ext.NonBid{
					{ImpId: "imp1"},
				},
			},
			toAppend: []SeatNonBidBuilder{
				{
					"seat1": []openrtb_ext.NonBid{
						{ImpId: "imp2"},
					},
				},
			},
			expected: SeatNonBidBuilder{
				"seat1": []openrtb_ext.NonBid{
					{ImpId: "imp1"},
					{ImpId: "imp2"},
				},
			},
		},

Copy link
Contributor

Choose a reason for hiding this comment

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

Done

expected: SeatNonBidBuilder{"seat1": []openrtb_ext.NonBid{{ImpId: "imp1"}}},
},
{
name: "multiple seats",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we rename to append_one_different_seat?

Copy link
Contributor

Choose a reason for hiding this comment

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

Done

expected: SeatNonBidBuilder{"seat1": []openrtb_ext.NonBid{{ImpId: "imp1"}}, "seat2": []openrtb_ext.NonBid{{ImpId: "imp2"}}},
},
{
name: "multiple appends",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we rename to append_multiple_different_seats?

Copy link
Contributor

Choose a reason for hiding this comment

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

Done

expected SeatNonBidBuilder
}{
{
name: "nil receiver",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we rename to nil_builder to match what t.Run does automatically with white space substitutions?

Copy link
Contributor

Choose a reason for hiding this comment

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

Done

expected: nil,
},
{
name: "empty builder",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we rename to empty_builder to match what t.Run does automatically with white space substitutions?

Copy link
Contributor

Choose a reason for hiding this comment

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

Done

},
},
},
},
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you add the following additional test case:

        {
			name:   "many_imps_appended_to_prepopulated_list_same_seat",
			impIDs: []string{"imp1", "imp2"},
			builder: SeatNonBidBuilder{
				"seat1": []openrtb_ext.NonBid{
					{
						ImpId:      "imp0",
						StatusCode: 300,
					},
				},
			},
			want: SeatNonBidBuilder{
				"seat1": []openrtb_ext.NonBid{
					{
						ImpId:      "imp0",
						StatusCode: 300,
					},
					{
						ImpId:      "imp1",
						StatusCode: 300,
					},
					{
						ImpId:      "imp2",
						StatusCode: 300,
					},
				},
			},
		},

Copy link
Contributor

Choose a reason for hiding this comment

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

Done

toAppend []SeatNonBidBuilder
expected SeatNonBidBuilder
}{
{
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nitpick: can you please reformat these test cases to multi-line format similar to how TestRejectImps is formatted?

Copy link
Contributor

Choose a reason for hiding this comment

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

Done

@@ -9,9 +9,9 @@ import (
"github.com/stretchr/testify/assert"
)

func TestSeatNonBidsAdd(t *testing.T) {
func TestRejectBid(t *testing.T) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Are you ok replacing this test with what I provided here? The version of this test that I provided will remove the level of indirection thus making it easier to follow IMO.

If you agree, please also delete the function variables sampleSeatBids and sampleSeatNonBidMap.

Copy link
Contributor

Choose a reason for hiding this comment

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

This is unit test for RejectBid function, the one you provide is for rejectImps. I have fixed this test and removed sampleSeatBids and sampleSeatNonBidMap.

@bsardo
Copy link
Collaborator

bsardo commented Sep 11, 2024

@Pubmatic-Dhruv-Sonone See comments above. Please also resolve the newly introduced merge conflict by merging with master when you get a chance.

@Pubmatic-Dhruv-Sonone
Copy link
Contributor

@bsardo Addressed review comments. Please check.

@bsardo bsardo assigned hhhjort and unassigned SyntaxNode Sep 18, 2024
Copy link
Collaborator

@hhhjort hhhjort left a comment

Choose a reason for hiding this comment

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

LGTM

@bsardo bsardo merged commit 905b3a5 into prebid:master Sep 19, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants