@@ -9,11 +9,15 @@ import (
9
9
"errors"
10
10
"fmt"
11
11
"io"
12
+ "net"
12
13
"net/http"
13
14
"net/http/httptest"
14
15
"net/http/httptrace"
16
+ "net/url"
17
+ "os"
15
18
"sort"
16
19
"strings"
20
+ "syscall"
17
21
"testing"
18
22
"time"
19
23
@@ -3096,6 +3100,148 @@ func TestGetBidType(t *testing.T) {
3096
3100
}
3097
3101
}
3098
3102
3103
+ func TestSeatNonBid (t * testing.T ) {
3104
+ type args struct {
3105
+ BidRequest * openrtb2.BidRequest
3106
+ Seat string
3107
+ SeatRequests []* adapters.RequestData
3108
+ BidderResponse func () (* http.Response , error )
3109
+ client * http.Client
3110
+ }
3111
+ type expect struct {
3112
+ seatBids []* entities.PbsOrtbSeatBid
3113
+ seatNonBids SeatNonBidBuilder
3114
+ errors []error
3115
+ }
3116
+ testCases := []struct {
3117
+ name string
3118
+ args args
3119
+ expect expect
3120
+ }{
3121
+ {
3122
+ name : "NBR_101_timeout_for_context_deadline_exceeded" ,
3123
+ args : args {
3124
+ Seat : "pubmatic" ,
3125
+ BidRequest : & openrtb2.BidRequest {
3126
+ Imp : []openrtb2.Imp {{ID : "1234" }},
3127
+ },
3128
+ SeatRequests : []* adapters.RequestData {{ImpIDs : []string {"1234" }}},
3129
+ BidderResponse : func () (* http.Response , error ) { return nil , context .DeadlineExceeded },
3130
+ client : & http.Client {Timeout : time .Nanosecond }, // for timeout
3131
+ },
3132
+ expect : expect {
3133
+ seatNonBids : SeatNonBidBuilder {
3134
+ "pubmatic" : {{
3135
+ ImpId : "1234" ,
3136
+ StatusCode : int (ErrorTimeout ),
3137
+ }},
3138
+ },
3139
+ errors : []error {& errortypes.Timeout {Message : context .DeadlineExceeded .Error ()}},
3140
+ seatBids : []* entities.PbsOrtbSeatBid {{Bids : []* entities.PbsOrtbBid {}, Currency : "USD" , Seat : "pubmatic" , HttpCalls : []* openrtb_ext.ExtHttpCall {}}},
3141
+ },
3142
+ }, {
3143
+ name : "NBR_103_Bidder_Unreachable_Connection_Refused" ,
3144
+ args : args {
3145
+ Seat : "appnexus" ,
3146
+ SeatRequests : []* adapters.RequestData {{ImpIDs : []string {"1234" , "4567" }}},
3147
+ BidRequest : & openrtb2.BidRequest {Imp : []openrtb2.Imp {{ID : "1234" }, {ID : "4567" }}},
3148
+ BidderResponse : func () (* http.Response , error ) {
3149
+ return nil , & net.OpError {Err : os .NewSyscallError (syscall .ECONNREFUSED .Error (), syscall .ECONNREFUSED )}
3150
+ },
3151
+ },
3152
+ expect : expect {
3153
+ seatNonBids : SeatNonBidBuilder {
3154
+ "appnexus" : {
3155
+ {ImpId : "1234" , StatusCode : int (ErrorBidderUnreachable )},
3156
+ {ImpId : "4567" , StatusCode : int (ErrorBidderUnreachable )},
3157
+ },
3158
+ },
3159
+ seatBids : []* entities.PbsOrtbSeatBid {{Bids : []* entities.PbsOrtbBid {}, Currency : "USD" , Seat : "appnexus" , HttpCalls : []* openrtb_ext.ExtHttpCall {}}},
3160
+ errors : []error {& url.Error {Op : "Get" , URL : "" , Err : & net.OpError {Err : os .NewSyscallError (syscall .ECONNREFUSED .Error (), syscall .ECONNREFUSED )}}},
3161
+ },
3162
+ }, {
3163
+ name : "no_impids_populated_in_request_data" ,
3164
+ args : args {
3165
+ SeatRequests : []* adapters.RequestData {{
3166
+ ImpIDs : nil , // no imp ids
3167
+ }},
3168
+ BidRequest : & openrtb2.BidRequest {Imp : []openrtb2.Imp {{ID : "1234" }}},
3169
+ BidderResponse : func () (* http.Response , error ) {
3170
+ return nil , errors .New ("some_error" )
3171
+ },
3172
+ },
3173
+ expect : expect {
3174
+ seatNonBids : SeatNonBidBuilder {},
3175
+ seatBids : []* entities.PbsOrtbSeatBid {{Bids : []* entities.PbsOrtbBid {}, Currency : "USD" , HttpCalls : []* openrtb_ext.ExtHttpCall {}}},
3176
+ errors : []error {& url.Error {Op : "Get" , URL : "" , Err : errors .New ("some_error" )}},
3177
+ },
3178
+ },
3179
+ }
3180
+ for _ , test := range testCases {
3181
+ t .Run (test .name , func (t * testing.T ) {
3182
+ mockBidder := & mockBidder {}
3183
+ mockBidder .On ("MakeRequests" , mock .Anything , mock .Anything ).Return (test .args .SeatRequests , []error (nil ))
3184
+ mockMetricsEngine := & metrics.MetricsEngineMock {}
3185
+ mockMetricsEngine .On ("RecordOverheadTime" , mock .Anything , mock .Anything ).Return (nil )
3186
+ mockMetricsEngine .On ("RecordBidderServerResponseTime" , mock .Anything ).Return (nil )
3187
+ roundTrip := & mockRoundTripper {}
3188
+ roundTrip .On ("RoundTrip" , mock .Anything ).Return (test .args .BidderResponse ())
3189
+ client := & http.Client {
3190
+ Transport : roundTrip ,
3191
+ Timeout : 0 ,
3192
+ }
3193
+ if test .args .client != nil {
3194
+ client .Timeout = test .args .client .Timeout
3195
+ }
3196
+ bidder := AdaptBidder (mockBidder , client , & config.Configuration {}, mockMetricsEngine , openrtb_ext .BidderAppnexus , & config.DebugInfo {}, test .args .Seat )
3197
+
3198
+ ctx := context .Background ()
3199
+ if client .Timeout > 0 {
3200
+ ctxTimeout , cancel := context .WithTimeout (ctx , client .Timeout )
3201
+ ctx = ctxTimeout
3202
+ defer cancel ()
3203
+ }
3204
+ seatBids , responseExtra , errors := bidder .requestBid (ctx , BidderRequest {
3205
+ BidRequest : test .args .BidRequest ,
3206
+ BidderName : openrtb_ext .BidderName (test .args .Seat ),
3207
+ }, nil , & adapters.ExtraRequestInfo {}, & MockSigner {}, bidRequestOptions {}, openrtb_ext.ExtAlternateBidderCodes {}, hookexecution.EmptyHookExecutor {}, nil )
3208
+ assert .Equal (t , test .expect .seatBids , seatBids )
3209
+ assert .Equal (t , test .expect .seatNonBids , responseExtra .seatNonBidBuilder )
3210
+ assert .Equal (t , test .expect .errors , errors )
3211
+ for _ , nonBids := range responseExtra .seatNonBidBuilder {
3212
+ for _ , nonBid := range nonBids {
3213
+ for _ , seatBid := range seatBids {
3214
+ for _ , bid := range seatBid .Bids {
3215
+ // ensure non bids are not present in seat bids
3216
+ if nonBid .ImpId == bid .Bid .ImpID {
3217
+ assert .Fail (t , "imp id [%s] present in both seat bid and non seat bid" , nonBid .ImpId )
3218
+ }
3219
+ }
3220
+ }
3221
+ }
3222
+ }
3223
+ })
3224
+ }
3225
+ }
3226
+
3227
+ type mockRoundTripper struct {
3228
+ mock.Mock
3229
+ }
3230
+
3231
+ func (rt * mockRoundTripper ) RoundTrip (request * http.Request ) (* http.Response , error ) {
3232
+ args := rt .Called (request )
3233
+ var response * http.Response
3234
+ if args .Get (0 ) != nil {
3235
+ response = args .Get (0 ).(* http.Response )
3236
+ }
3237
+ var err error
3238
+ if args .Get (1 ) != nil {
3239
+ err = args .Get (1 ).(error )
3240
+ }
3241
+
3242
+ return response , err
3243
+ }
3244
+
3099
3245
type mockBidderTmaxCtx struct {
3100
3246
startTime , deadline , now time.Time
3101
3247
ok bool
0 commit comments