From 43438c3806d4f1e1f2840e0c532e9753538f8e51 Mon Sep 17 00:00:00 2001 From: Viral Vala <63396712+pm-viral-vala@users.noreply.github.com> Date: Tue, 3 Sep 2024 17:54:33 +0530 Subject: [PATCH] UOE-8632: refactoring macro replacement in video event injection (#858) OTT-1824: using fastxml for video event injection --- adapters/vastbidder/fastxml_parser.go | 8 +- adapters/vastbidder/vastbidder.go | 4 +- endpoints/events/events_ow.go | 192 ++++ endpoints/events/events_ow_test.go | 591 +++++++++++++ endpoints/events/test/base64_vast.txt.tar.gz | Bin 0 -> 171 bytes endpoints/events/test/benchmark_results.txt | 415 +++++++++ endpoints/events/test/raw_vast.txt | 101 +++ endpoints/events/vtrack_ow.go | 376 ++++---- endpoints/events/vtrack_ow_benchmark_test.go | 68 ++ endpoints/events/vtrack_ow_test.go | 836 ++++++++---------- exchange/events.go | 27 +- exchange/events_ow.go | 37 + exchange/events_ow_test.go | 74 ++ exchange/events_test.go | 111 --- exchange/exchange.go | 7 +- exchange/exchange_ow.go | 2 +- go.mod | 5 +- go.sum | 12 +- .../pubmatic/openwrap/tracker/video_test.go | 4 +- 19 files changed, 2021 insertions(+), 849 deletions(-) create mode 100644 endpoints/events/events_ow.go create mode 100644 endpoints/events/events_ow_test.go create mode 100644 endpoints/events/test/base64_vast.txt.tar.gz create mode 100644 endpoints/events/test/benchmark_results.txt create mode 100644 endpoints/events/test/raw_vast.txt create mode 100644 endpoints/events/vtrack_ow_benchmark_test.go create mode 100644 exchange/events_ow.go create mode 100644 exchange/events_ow_test.go diff --git a/adapters/vastbidder/fastxml_parser.go b/adapters/vastbidder/fastxml_parser.go index dfbde606db7..a83cfd293f0 100644 --- a/adapters/vastbidder/fastxml_parser.go +++ b/adapters/vastbidder/fastxml_parser.go @@ -70,7 +70,7 @@ func (p *fastXMLParser) GetPricingDetails() (price float64, currency string) { return 0.0, "" } - priceValue, err := strconv.ParseFloat(strings.TrimSpace(p.reader.Text(node, true)), 64) + priceValue, err := strconv.ParseFloat(strings.TrimSpace(p.reader.RawText(node)), 64) if nil != err { return 0.0, "" } @@ -89,7 +89,7 @@ func (p *fastXMLParser) GetAdvertiser() (advertisers []string) { if p.reader.SelectAttrValue(ext, "type") == "advertiser" { ele := p.reader.SelectElement(ext, "Advertiser") if ele != nil { - if value := strings.TrimSpace(p.reader.Text(ele, true)); len(value) > 0 { + if value := strings.TrimSpace(p.reader.Text(ele)); len(value) > 0 { advertisers = append(advertisers, value) } } @@ -98,7 +98,7 @@ func (p *fastXMLParser) GetAdvertiser() (advertisers []string) { case vastVersion4x: if ele := p.reader.SelectElement(p.adElement, "Advertiser"); ele != nil { - if value := strings.TrimSpace(p.reader.Text(ele, true)); len(value) > 0 { + if value := strings.TrimSpace(p.reader.Text(ele)); len(value) > 0 { advertisers = append(advertisers, value) } } @@ -126,7 +126,7 @@ func (p *fastXMLParser) GetDuration() (int, error) { if node == nil { return 0, errEmptyVideoDuration } - return parseDuration(strings.TrimSpace(p.reader.Text(node, true))) + return parseDuration(strings.TrimSpace(p.reader.RawText(node))) } func (p *fastXMLParser) getAdElement(vast *fastxml.Element) *fastxml.Element { diff --git a/adapters/vastbidder/vastbidder.go b/adapters/vastbidder/vastbidder.go index 06b3abff67a..b6a4897f10a 100644 --- a/adapters/vastbidder/vastbidder.go +++ b/adapters/vastbidder/vastbidder.go @@ -101,13 +101,13 @@ func (a *VASTBidder) fastXMLTesting(handler *responseHandler, responseData *adap } } - vastBidderInfo := &openrtb_ext.FastXMLMetrics{ + xmlParsingMetrics := &openrtb_ext.FastXMLMetrics{ XMLParserTime: handlerTime, EtreeParserTime: etreeParserTime, IsRespMismatch: isVASTMismatch, } - responseData.FastXMLMetrics = vastBidderInfo + responseData.FastXMLMetrics = xmlParsingMetrics } // NewTagBidder is an constructor for TagBidder diff --git a/endpoints/events/events_ow.go b/endpoints/events/events_ow.go new file mode 100644 index 00000000000..00a7ba726ef --- /dev/null +++ b/endpoints/events/events_ow.go @@ -0,0 +1,192 @@ +package events + +import ( + "encoding/json" + "net/url" + "strings" + + "github.com/golang/glog" + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v2/openrtb_ext" +) + +// standard VAST macros +// https://interactiveadvertisingbureau.github.io/vast/vast4macros/vast4-macros-latest.html#macro-spec-adcount +const ( + VASTAdTypeMacro = "[ADTYPE]" //VASTAdTypeMacro openwrap macro for ADTYPE + VASTAppBundleMacro = "[APPBUNDLE]" //VASTAppBundleMacro openwrap macro for APPBUNDLE + VASTDomainMacro = "[DOMAIN]" //VASTDomainMacro openwrap macro for DOMAIN + VASTPageURLMacro = "[PAGEURL]" //VASTPageURLMacro openwrap macro for PAGEURL + PBSEventIDMacro = "[EVENT_ID]" // PBSEventIDMacro macro for injecting PBS defined video event tracker id + PBSAccountMacro = "[PBS-ACCOUNT]" // PBSAccountMacro represents publisher id / account id + PBSBidderMacro = "[PBS-BIDDER]" // PBSBidderMacro represents bidder name + PBSOrigBidIDMacro = "[PBS-ORIG_BIDID]" // PBSOrigBidIDMacro represents original bid id. + PBSBidIDMacro = "[PBS-BIDID]" // PBSBidIDMacro represents bid id. If auction.generate-bid-id config is on, then resolve with response.seatbid.bid.ext.prebid.bidid. Else replace with response.seatbid.bid.id + PBSAdvertiserNameMacro = "[ADVERTISER_NAME]" // [ADERVERTISER_NAME] represents advertiser name + PBSAdUnitIDMacro = "[AD_UNIT]" // PBSAdUnitIDMacro Pass imp.tagId using this macro + PBSBidderCodeMacro = "[BIDDER_CODE]" // PBSBidderCodeMacro represents an alias id or core bidder id. +) + +// PubMatic specific event IDs +// This will go in event-config once PreBid modular design is in place +var trackingEventIDMap = map[string]string{ + "start": "2", + "firstQuartile": "4", + "midpoint": "3", + "thirdQuartile": "5", + "complete": "6", +} + +var trackingEvents = []string{"start", "firstQuartile", "midpoint", "thirdQuartile", "complete"} + +// GetVideoEventTracking returns map containing key as event name value as associaed video event tracking URL +// By default PBS will expect [EVENT_ID] macro in trackerURL to inject event information +// [EVENT_ID] will be injected with one of the following values +// +// firstQuartile, midpoint, thirdQuartile, complete +// +// If your company can not use [EVENT_ID] and has its own macro. provide config.TrackerMacros implementation +// and ensure that your macro is part of trackerURL configuration +// GetVideoEventTracking returns map containing key as event name value as associaed video event tracking URL +// By default PBS will expect [EVENT_ID] macro in trackerURL to inject event information +// [EVENT_ID] will be injected with one of the following values +// +// firstQuartile, midpoint, thirdQuartile, complete +// +// If your company can not use [EVENT_ID] and has its own macro. provide config.TrackerMacros implementation +// and ensure that your macro is part of trackerURL configuration +func GetVideoEventTracking( + req *openrtb2.BidRequest, + imp *openrtb2.Imp, + bid *openrtb2.Bid, + trackerURL string, + prebidGenBidId, requestingBidder, bidderCoreName string, + timestamp int64) map[string]string { + + if req == nil || imp == nil || bid == nil || strings.TrimSpace(trackerURL) == "" { + return nil + } + + // replace standard macros + // NYC shall we put all macros with their default values here? + macroMap := map[string]string{ + PBSAdUnitIDMacro: imp.TagID, + PBSBidIDMacro: bid.ID, + PBSOrigBidIDMacro: bid.ID, + PBSBidderMacro: bidderCoreName, + PBSBidderCodeMacro: requestingBidder, + PBSAdvertiserNameMacro: "", + VASTAdTypeMacro: string(openrtb_ext.BidTypeVideo), + } + + /* Use generated bidId if present, else use bid.ID */ + if len(prebidGenBidId) > 0 && prebidGenBidId != bid.ID { + macroMap[PBSBidIDMacro] = prebidGenBidId + } + + if len(bid.ADomain) > 0 { + var err error + //macroMap[PBSAdvertiserNameMacro] = strings.Join(bid.ADomain, ",") + macroMap[PBSAdvertiserNameMacro], err = extractDomain(bid.ADomain[0]) + if err != nil { + glog.Warningf("Unable to extract domain from '%s'. [%s]", bid.ADomain[0], err.Error()) + } + } + + if req.App != nil { + // macroMap[VASTAppBundleMacro] = req.App.Bundle + macroMap[VASTDomainMacro] = req.App.Bundle + if req.App.Publisher != nil { + macroMap[PBSAccountMacro] = req.App.Publisher.ID + } + } else if req.Site != nil { + macroMap[VASTDomainMacro] = getDomain(req.Site) + macroMap[VASTPageURLMacro] = req.Site.Page + if req.Site.Publisher != nil { + macroMap[PBSAccountMacro] = req.Site.Publisher.ID + } + } + + // lookup in custom macros - keep this block at last for highest priority + var reqExt openrtb_ext.ExtRequest + if req.Ext != nil { + err := json.Unmarshal(req.Ext, &reqExt) + if err != nil { + glog.Warningf("Error in unmarshling req.Ext.Prebid.Vast: [%s]", err.Error()) + } + } + for key, value := range reqExt.Prebid.Macros { + macroMap[strings.TrimSpace(key)] = strings.TrimSpace(value) + } + + eventURLMap := make(map[string]string) + for name, id := range trackingEventIDMap { // NYC check if trackingEvents and macroMap can be clubbed + // replace [EVENT_ID] macro with PBS defined event ID + macroMap[PBSEventIDMacro] = id + eventURLMap[name] = replaceMacros(trackerURL, macroMap) + } + return eventURLMap +} + +func replaceMacros(trackerURL string, macroMap map[string]string) string { + var builder strings.Builder + + for i := 0; i < len(trackerURL); i++ { + if trackerURL[i] == '[' { + found := false + j := i + 1 + for ; j < len(trackerURL); j++ { + if trackerURL[j] == ']' { + found = true + break + } + } + if found { + n := j + 1 + k := trackerURL[i:n] + if v, ok := macroMap[k]; ok { + v = url.QueryEscape(v) // NYC move QueryEscape while creating map, no need to do this everytime + _, _ = builder.Write([]byte(v)) + i = j + continue + } + } + } + _ = builder.WriteByte(trackerURL[i]) + } + + return builder.String() +} + +func extractDomain(rawURL string) (string, error) { + if !strings.HasPrefix(rawURL, "http") { + rawURL = "http://" + rawURL + } + // decode rawURL + rawURL, err := url.QueryUnescape(rawURL) + if nil != err { + return "", err + } + url, err := url.Parse(rawURL) + if nil != err { + return "", err + } + // remove www if present + return strings.TrimPrefix(url.Hostname(), "www."), nil +} + +func getDomain(site *openrtb2.Site) string { + if site.Domain != "" { + return site.Domain + } + + hostname := "" + + if site.Page != "" { + pageURL, err := url.Parse(site.Page) + if err == nil && pageURL != nil { + hostname = pageURL.Host + } + } + return hostname +} diff --git a/endpoints/events/events_ow_test.go b/endpoints/events/events_ow_test.go new file mode 100644 index 00000000000..300e3ed01b2 --- /dev/null +++ b/endpoints/events/events_ow_test.go @@ -0,0 +1,591 @@ +package events + +import ( + "testing" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/stretchr/testify/assert" +) + +func TestGetVideoEventTracking(t *testing.T) { + type args struct { + trackerURL string + bid *openrtb2.Bid + requestingBidder string + gen_bidid string + bidderCoreName string + timestamp int64 + req *openrtb2.BidRequest + } + type want struct { + trackerURLMap map[string]string + } + tests := []struct { + name string + args args + want want + }{ + { + name: "valid_scenario", + args: args{ + trackerURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", + bid: &openrtb2.Bid{ + // AdM: vastXMLWith2Creatives, + }, + req: &openrtb2.BidRequest{ + App: &openrtb2.App{ + Bundle: "someappbundle", + }, + Imp: []openrtb2.Imp{ + { + Video: &openrtb2.Video{}, + }, + }, + }, + }, + want: want{ + trackerURLMap: map[string]string{ + "firstQuartile": "http://company.tracker.com?eventId=4&appbundle=someappbundle", + "midpoint": "http://company.tracker.com?eventId=3&appbundle=someappbundle", + "thirdQuartile": "http://company.tracker.com?eventId=5&appbundle=someappbundle", + "start": "http://company.tracker.com?eventId=2&appbundle=someappbundle", + "complete": "http://company.tracker.com?eventId=6&appbundle=someappbundle"}, + }, + }, + { + name: "no_macro_value", // expect no replacement + args: args{ + trackerURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", + bid: &openrtb2.Bid{}, + req: &openrtb2.BidRequest{ + App: &openrtb2.App{}, // no app bundle value + Imp: []openrtb2.Imp{ + { + Video: &openrtb2.Video{}, + }, + }, + }, + }, + want: want{ + trackerURLMap: map[string]string{ + "firstQuartile": "http://company.tracker.com?eventId=4&appbundle=", + "midpoint": "http://company.tracker.com?eventId=3&appbundle=", + "thirdQuartile": "http://company.tracker.com?eventId=5&appbundle=", + "start": "http://company.tracker.com?eventId=2&appbundle=", + "complete": "http://company.tracker.com?eventId=6&appbundle="}, + }, + }, + { + name: "prefer_company_value_for_standard_macro", + args: args{ + trackerURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", + bid: &openrtb2.Bid{}, + req: &openrtb2.BidRequest{ + App: &openrtb2.App{ + Bundle: "myapp", // do not expect this value + }, + Imp: []openrtb2.Imp{ + { + Video: &openrtb2.Video{}, + }, + }, + Ext: []byte(`{"prebid":{ + "macros": { + "[DOMAIN]": "my_custom_value" + } + }}`), + }, + }, + want: want{ + trackerURLMap: map[string]string{ + "firstQuartile": "http://company.tracker.com?eventId=4&appbundle=my_custom_value", + "midpoint": "http://company.tracker.com?eventId=3&appbundle=my_custom_value", + "thirdQuartile": "http://company.tracker.com?eventId=5&appbundle=my_custom_value", + "start": "http://company.tracker.com?eventId=2&appbundle=my_custom_value", + "complete": "http://company.tracker.com?eventId=6&appbundle=my_custom_value"}, + }, + }, + { + name: "multireplace_macro", + args: args{ + trackerURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]¶meter2=[DOMAIN]", + bid: &openrtb2.Bid{}, + req: &openrtb2.BidRequest{ + App: &openrtb2.App{ + Bundle: "myapp123", + }, + Imp: []openrtb2.Imp{ + { + Video: &openrtb2.Video{}, + }, + }, + }, + }, + want: want{ + trackerURLMap: map[string]string{ + "firstQuartile": "http://company.tracker.com?eventId=4&appbundle=myapp123¶meter2=myapp123", + "midpoint": "http://company.tracker.com?eventId=3&appbundle=myapp123¶meter2=myapp123", + "thirdQuartile": "http://company.tracker.com?eventId=5&appbundle=myapp123¶meter2=myapp123", + "start": "http://company.tracker.com?eventId=2&appbundle=myapp123¶meter2=myapp123", + "complete": "http://company.tracker.com?eventId=6&appbundle=myapp123¶meter2=myapp123"}, + }, + }, + { + name: "custom_macro_without_prefix_and_suffix", + args: args{ + trackerURL: "http://company.tracker.com?eventId=[EVENT_ID]¶m1=[CUSTOM_MACRO]", + bid: &openrtb2.Bid{}, + req: &openrtb2.BidRequest{ + Ext: []byte(`{"prebid":{ + "macros": { + "CUSTOM_MACRO": "my_custom_value" + } + }}`), + Imp: []openrtb2.Imp{ + { + Video: &openrtb2.Video{}, + }, + }, + }, + }, + want: want{ + trackerURLMap: map[string]string{ + "firstQuartile": "http://company.tracker.com?eventId=4¶m1=[CUSTOM_MACRO]", + "midpoint": "http://company.tracker.com?eventId=3¶m1=[CUSTOM_MACRO]", + "thirdQuartile": "http://company.tracker.com?eventId=5¶m1=[CUSTOM_MACRO]", + "start": "http://company.tracker.com?eventId=2¶m1=[CUSTOM_MACRO]", + "complete": "http://company.tracker.com?eventId=6¶m1=[CUSTOM_MACRO]"}, + }, + }, + { + name: "empty_macro", + args: args{ + trackerURL: "http://company.tracker.com?eventId=[EVENT_ID]¶m1=[CUSTOM_MACRO]", + bid: &openrtb2.Bid{}, + req: &openrtb2.BidRequest{ + Ext: []byte(`{"prebid":{ + "macros": { + "": "my_custom_value" + } + }}`), + Imp: []openrtb2.Imp{ + { + Video: &openrtb2.Video{}, + }, + }, + }, + }, + want: want{ + trackerURLMap: map[string]string{ + "firstQuartile": "http://company.tracker.com?eventId=4¶m1=[CUSTOM_MACRO]", + "midpoint": "http://company.tracker.com?eventId=3¶m1=[CUSTOM_MACRO]", + "thirdQuartile": "http://company.tracker.com?eventId=5¶m1=[CUSTOM_MACRO]", + "start": "http://company.tracker.com?eventId=2¶m1=[CUSTOM_MACRO]", + "complete": "http://company.tracker.com?eventId=6¶m1=[CUSTOM_MACRO]"}, + }, + }, + { + name: "macro_is_case_sensitive", + args: args{ + trackerURL: "http://company.tracker.com?eventId=[EVENT_ID]¶m1=[CUSTOM_MACRO]", + bid: &openrtb2.Bid{}, + req: &openrtb2.BidRequest{ + Ext: []byte(`{"prebid":{ + "macros": { + "": "my_custom_value" + } + }}`), + Imp: []openrtb2.Imp{ + { + Video: &openrtb2.Video{}, + }, + }, + }, + }, + want: want{ + trackerURLMap: map[string]string{ + "firstQuartile": "http://company.tracker.com?eventId=4¶m1=[CUSTOM_MACRO]", + "midpoint": "http://company.tracker.com?eventId=3¶m1=[CUSTOM_MACRO]", + "thirdQuartile": "http://company.tracker.com?eventId=5¶m1=[CUSTOM_MACRO]", + "start": "http://company.tracker.com?eventId=2¶m1=[CUSTOM_MACRO]", + "complete": "http://company.tracker.com?eventId=6¶m1=[CUSTOM_MACRO]"}, + }, + }, + { + name: "empty_tracker_url", + args: args{ + trackerURL: " ", + bid: &openrtb2.Bid{}, + req: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + { + Video: &openrtb2.Video{}, + }, + }, + }, + }, + want: want{ + trackerURLMap: nil, + }, + }, + { + name: "site_domain_tracker_url", + args: args{ + trackerURL: "https://company.tracker.com?operId=8&e=[EVENT_ID]&p=[PBS-ACCOUNT]&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=[PBS-BIDDER]&advertiser_id=[ADVERTISER_NAME]&sURL=[DOMAIN]&pfi=[PLATFORM]&af=[ADTYPE]&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=[AD_UNIT]&bidid=[PBS-BIDID]", + bid: &openrtb2.Bid{}, + req: &openrtb2.BidRequest{ + Site: &openrtb2.Site{ + Name: "test", + Domain: "www.test.com", + Publisher: &openrtb2.Publisher{ + ID: "5890"}, + }, + Imp: []openrtb2.Imp{ + { + Video: &openrtb2.Video{}, + }, + }, + }, + }, + want: want{ + map[string]string{ + "complete": "https://company.tracker.com?operId=8&e=6&p=5890&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=&advertiser_id=&sURL=www.test.com&pfi=[PLATFORM]&af=video&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=&bidid=", + "firstQuartile": "https://company.tracker.com?operId=8&e=4&p=5890&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=&advertiser_id=&sURL=www.test.com&pfi=[PLATFORM]&af=video&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=&bidid=", + "midpoint": "https://company.tracker.com?operId=8&e=3&p=5890&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=&advertiser_id=&sURL=www.test.com&pfi=[PLATFORM]&af=video&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=&bidid=", + "start": "https://company.tracker.com?operId=8&e=2&p=5890&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=&advertiser_id=&sURL=www.test.com&pfi=[PLATFORM]&af=video&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=&bidid=", + "thirdQuartile": "https://company.tracker.com?operId=8&e=5&p=5890&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=&advertiser_id=&sURL=www.test.com&pfi=[PLATFORM]&af=video&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=&bidid=", + }, + }, + }, + { + name: "site_page_tracker_url", + args: args{trackerURL: "https://company.tracker.com?operId=8&e=[EVENT_ID]&p=[PBS-ACCOUNT]&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=[PBS-BIDDER]&advertiser_id=[ADVERTISER_NAME]&sURL=[DOMAIN]&pfi=[PLATFORM]&af=[ADTYPE]&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=[AD_UNIT]&bidid=[PBS-BIDID]", + bid: &openrtb2.Bid{}, req: &openrtb2.BidRequest{ + Site: &openrtb2.Site{ + Name: "test", + Page: "https://www.test.com/", + Publisher: &openrtb2.Publisher{ + ID: "5890", + }, + }, + Imp: []openrtb2.Imp{ + { + Video: &openrtb2.Video{}, + }, + }, + }, + }, + want: want{ + map[string]string{ + "complete": "https://company.tracker.com?operId=8&e=6&p=5890&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=&advertiser_id=&sURL=www.test.com&pfi=[PLATFORM]&af=video&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=&bidid=", + "firstQuartile": "https://company.tracker.com?operId=8&e=4&p=5890&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=&advertiser_id=&sURL=www.test.com&pfi=[PLATFORM]&af=video&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=&bidid=", + "midpoint": "https://company.tracker.com?operId=8&e=3&p=5890&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=&advertiser_id=&sURL=www.test.com&pfi=[PLATFORM]&af=video&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=&bidid=", + "start": "https://company.tracker.com?operId=8&e=2&p=5890&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=&advertiser_id=&sURL=www.test.com&pfi=[PLATFORM]&af=video&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=&bidid=", + "thirdQuartile": "https://company.tracker.com?operId=8&e=5&p=5890&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=&advertiser_id=&sURL=www.test.com&pfi=[PLATFORM]&af=video&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=&bidid=", + }, + }, + }, + { + name: "all_macros with generated_bidId", // expect encoding for WRAPPER_IMPRESSION_ID macro + args: args{ + trackerURL: "https://company.tracker.com?operId=8&e=[EVENT_ID]&p=[PBS-ACCOUNT]&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=[PBS-BIDDER]&advertiser_id=[ADVERTISER_NAME]&sURL=[DOMAIN]&pfi=[PLATFORM]&af=[ADTYPE]&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=[AD_UNIT]&bidid=[PBS-BIDID]&origbidid=[PBS-ORIG_BIDID]&bc=[BIDDER_CODE]", + req: &openrtb2.BidRequest{ + App: &openrtb2.App{Bundle: "com.someapp.com", Publisher: &openrtb2.Publisher{ID: "5890"}}, + Ext: []byte(`{ + "prebid": { + "macros": { + "[PROFILE_ID]": "100", + "[PROFILE_VERSION]": "2", + "[UNIX_TIMESTAMP]": "1234567890", + "[PLATFORM]": "7", + "[WRAPPER_IMPRESSION_ID]": "abc~!@#$%^&&*()_+{}|:\"<>?[]\\;',./" + } + } + }`), + Imp: []openrtb2.Imp{ + { + TagID: "/testadunit/1", + ID: "imp_1", + Video: &openrtb2.Video{}, + }, + }, + }, + bid: &openrtb2.Bid{ADomain: []string{"http://a.com/32?k=v", "b.com"}, ImpID: "imp_1", ID: "test_bid_id"}, + gen_bidid: "random_bid_id", + requestingBidder: "test_bidder:234", + bidderCoreName: "test_core_bidder:234", + }, + want: want{ + trackerURLMap: map[string]string{ + "firstQuartile": "https://company.tracker.com?operId=8&e=4&p=5890&pid=100&v=2&ts=1234567890&pn=test_core_bidder%3A234&advertiser_id=a.com&sURL=com.someapp.com&pfi=7&af=video&iid=abc~%21%40%23%24%25%5E%26%26%2A%28%29_%2B%7B%7D%7C%3A%22%3C%3E%3F%5B%5D%5C%3B%27%2C.%2F&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=%2Ftestadunit%2F1&bidid=random_bid_id&origbidid=test_bid_id&bc=test_bidder%3A234", + "midpoint": "https://company.tracker.com?operId=8&e=3&p=5890&pid=100&v=2&ts=1234567890&pn=test_core_bidder%3A234&advertiser_id=a.com&sURL=com.someapp.com&pfi=7&af=video&iid=abc~%21%40%23%24%25%5E%26%26%2A%28%29_%2B%7B%7D%7C%3A%22%3C%3E%3F%5B%5D%5C%3B%27%2C.%2F&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=%2Ftestadunit%2F1&bidid=random_bid_id&origbidid=test_bid_id&bc=test_bidder%3A234", + "thirdQuartile": "https://company.tracker.com?operId=8&e=5&p=5890&pid=100&v=2&ts=1234567890&pn=test_core_bidder%3A234&advertiser_id=a.com&sURL=com.someapp.com&pfi=7&af=video&iid=abc~%21%40%23%24%25%5E%26%26%2A%28%29_%2B%7B%7D%7C%3A%22%3C%3E%3F%5B%5D%5C%3B%27%2C.%2F&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=%2Ftestadunit%2F1&bidid=random_bid_id&origbidid=test_bid_id&bc=test_bidder%3A234", + "complete": "https://company.tracker.com?operId=8&e=6&p=5890&pid=100&v=2&ts=1234567890&pn=test_core_bidder%3A234&advertiser_id=a.com&sURL=com.someapp.com&pfi=7&af=video&iid=abc~%21%40%23%24%25%5E%26%26%2A%28%29_%2B%7B%7D%7C%3A%22%3C%3E%3F%5B%5D%5C%3B%27%2C.%2F&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=%2Ftestadunit%2F1&bidid=random_bid_id&origbidid=test_bid_id&bc=test_bidder%3A234", + "start": "https://company.tracker.com?operId=8&e=2&p=5890&pid=100&v=2&ts=1234567890&pn=test_core_bidder%3A234&advertiser_id=a.com&sURL=com.someapp.com&pfi=7&af=video&iid=abc~%21%40%23%24%25%5E%26%26%2A%28%29_%2B%7B%7D%7C%3A%22%3C%3E%3F%5B%5D%5C%3B%27%2C.%2F&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=%2Ftestadunit%2F1&bidid=random_bid_id&origbidid=test_bid_id&bc=test_bidder%3A234"}, + }, + }, + { + name: "all_macros with empty generated_bidId", // expect encoding for WRAPPER_IMPRESSION_ID macro + args: args{ + trackerURL: "https://company.tracker.com?operId=8&e=[EVENT_ID]&p=[PBS-ACCOUNT]&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=[PBS-BIDDER]&advertiser_id=[ADVERTISER_NAME]&sURL=[DOMAIN]&pfi=[PLATFORM]&af=[ADTYPE]&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=[AD_UNIT]&bidid=[PBS-BIDID]&origbidid=[PBS-ORIG_BIDID]&bc=[BIDDER_CODE]", + req: &openrtb2.BidRequest{ + App: &openrtb2.App{ + Bundle: "com.someapp.com", + Publisher: &openrtb2.Publisher{ + ID: "5890", + }, + }, + Ext: []byte(`{ + "prebid": { + "macros": { + "[PROFILE_ID]": "100", + "[PROFILE_VERSION]": "2", + "[UNIX_TIMESTAMP]": "1234567890", + "[PLATFORM]": "7", + "[WRAPPER_IMPRESSION_ID]": "abc~!@#$%^&&*()_+{}|:\"<>?[]\\;',./" + } + } + }`), + Imp: []openrtb2.Imp{ + { + TagID: "/testadunit/1", + ID: "imp_1", + Video: &openrtb2.Video{}, + }, + }, + }, + bid: &openrtb2.Bid{ADomain: []string{"http://a.com/32?k=v", "b.com"}, ImpID: "imp_1", ID: "test_bid_id"}, + gen_bidid: "", + requestingBidder: "test_bidder:234", + bidderCoreName: "test_core_bidder:234", + }, + want: want{ + trackerURLMap: map[string]string{ + "firstQuartile": "https://company.tracker.com?operId=8&e=4&p=5890&pid=100&v=2&ts=1234567890&pn=test_core_bidder%3A234&advertiser_id=a.com&sURL=com.someapp.com&pfi=7&af=video&iid=abc~%21%40%23%24%25%5E%26%26%2A%28%29_%2B%7B%7D%7C%3A%22%3C%3E%3F%5B%5D%5C%3B%27%2C.%2F&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=%2Ftestadunit%2F1&bidid=test_bid_id&origbidid=test_bid_id&bc=test_bidder%3A234", + "midpoint": "https://company.tracker.com?operId=8&e=3&p=5890&pid=100&v=2&ts=1234567890&pn=test_core_bidder%3A234&advertiser_id=a.com&sURL=com.someapp.com&pfi=7&af=video&iid=abc~%21%40%23%24%25%5E%26%26%2A%28%29_%2B%7B%7D%7C%3A%22%3C%3E%3F%5B%5D%5C%3B%27%2C.%2F&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=%2Ftestadunit%2F1&bidid=test_bid_id&origbidid=test_bid_id&bc=test_bidder%3A234", + "thirdQuartile": "https://company.tracker.com?operId=8&e=5&p=5890&pid=100&v=2&ts=1234567890&pn=test_core_bidder%3A234&advertiser_id=a.com&sURL=com.someapp.com&pfi=7&af=video&iid=abc~%21%40%23%24%25%5E%26%26%2A%28%29_%2B%7B%7D%7C%3A%22%3C%3E%3F%5B%5D%5C%3B%27%2C.%2F&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=%2Ftestadunit%2F1&bidid=test_bid_id&origbidid=test_bid_id&bc=test_bidder%3A234", + "complete": "https://company.tracker.com?operId=8&e=6&p=5890&pid=100&v=2&ts=1234567890&pn=test_core_bidder%3A234&advertiser_id=a.com&sURL=com.someapp.com&pfi=7&af=video&iid=abc~%21%40%23%24%25%5E%26%26%2A%28%29_%2B%7B%7D%7C%3A%22%3C%3E%3F%5B%5D%5C%3B%27%2C.%2F&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=%2Ftestadunit%2F1&bidid=test_bid_id&origbidid=test_bid_id&bc=test_bidder%3A234", + "start": "https://company.tracker.com?operId=8&e=2&p=5890&pid=100&v=2&ts=1234567890&pn=test_core_bidder%3A234&advertiser_id=a.com&sURL=com.someapp.com&pfi=7&af=video&iid=abc~%21%40%23%24%25%5E%26%26%2A%28%29_%2B%7B%7D%7C%3A%22%3C%3E%3F%5B%5D%5C%3B%27%2C.%2F&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=%2Ftestadunit%2F1&bidid=test_bid_id&origbidid=test_bid_id&bc=test_bidder%3A234"}, + }, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + eventURLMap := GetVideoEventTracking(tc.args.req, &tc.args.req.Imp[0], tc.args.bid, tc.args.trackerURL, tc.args.gen_bidid, tc.args.requestingBidder, tc.args.bidderCoreName, tc.args.timestamp) + assert.Equal(t, tc.want.trackerURLMap, eventURLMap) + }) + } +} + +func TestExtractDomain(t *testing.T) { + testCases := []struct { + description string + url string + expectedDomain string + expectedErr error + }{ + {description: "a.com", url: "a.com", expectedDomain: "a.com", expectedErr: nil}, + {description: "a.com/123", url: "a.com/123", expectedDomain: "a.com", expectedErr: nil}, + {description: "http://a.com/123", url: "http://a.com/123", expectedDomain: "a.com", expectedErr: nil}, + {description: "https://a.com/123", url: "https://a.com/123", expectedDomain: "a.com", expectedErr: nil}, + {description: "c.b.a.com", url: "c.b.a.com", expectedDomain: "c.b.a.com", expectedErr: nil}, + {description: "url_encoded_http://c.b.a.com", url: "http%3A%2F%2Fc.b.a.com", expectedDomain: "c.b.a.com", expectedErr: nil}, + {description: "url_encoded_with_www_http://c.b.a.com", url: "http%3A%2F%2Fwww.c.b.a.com", expectedDomain: "c.b.a.com", expectedErr: nil}, + } + for _, test := range testCases { + t.Run(test.description, func(t *testing.T) { + domain, err := extractDomain(test.url) + assert.Equal(t, test.expectedDomain, domain) + assert.Equal(t, test.expectedErr, err) + }) + } +} + +// replaceMacros copied test cases from older replaceMacro(), will use gofuzzy once golang is upgraded +func Test_replaceMacros(t *testing.T) { + type args struct { + trackerURL string + macroMap map[string]string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "empty_tracker_url", + args: args{ + trackerURL: "", + macroMap: map[string]string{ + "[TEST]": "testme", + }, + }, + want: "", + }, + { + name: "tracker_url_with_macro", + args: args{ + trackerURL: "http://something.com?test=[TEST]", + macroMap: map[string]string{ + "[TEST]": "testme", + }, + }, + want: "http://something.com?test=testme", + }, + { + name: "tracker_url_with_invalid_macro", + args: args{ + trackerURL: "http://something.com?test=TEST]", + macroMap: map[string]string{ + "[TEST]": "testme", + }, + }, + want: "http://something.com?test=TEST]", + }, + { + name: "tracker_url_with_repeating_macro", + args: args{ + trackerURL: "http://something.com?test=[TEST]&test1=[TEST]", + macroMap: map[string]string{ + "[TEST]": "testme", + }, + }, + want: "http://something.com?test=testme&test1=testme", + }, + { + name: "empty_macro", + args: args{ + trackerURL: "http://something.com?test=[TEST]", + macroMap: map[string]string{ + "": "testme", + }, + }, + want: "http://something.com?test=[TEST]", + }, + { + name: "macro_without_[", + args: args{ + trackerURL: "http://something.com?test=[TEST]", + macroMap: map[string]string{ + "TEST]": "testme", + }, + }, + want: "http://something.com?test=[TEST]", + }, + { + name: "macro_without_]", + args: args{ + trackerURL: "http://something.com?test=[TEST]", + macroMap: map[string]string{ + "[TEST": "testme", + }, + }, + want: "http://something.com?test=[TEST]", + }, + { + name: "empty_value", + args: args{ + trackerURL: "http://something.com?test=[TEST]", + macroMap: map[string]string{ + "[TEST]": ""}, + }, + want: "http://something.com?test=", + }, + { + name: "nested_macro_value", + args: args{ + trackerURL: "http://something.com?test=[TEST]", + macroMap: map[string]string{ + "[TEST]": "[TEST][TEST]", + }, + }, + want: "http://something.com?test=%5BTEST%5D%5BTEST%5D", + }, + { + name: "url_as_macro_value", + args: args{ + trackerURL: "http://something.com?test=[TEST]", + macroMap: map[string]string{ + "[TEST]": "http://iamurl.com", + }, + }, + want: "http://something.com?test=http%3A%2F%2Fiamurl.com", + }, + // { Moved this responsiblity to GetVideoEventTracking() + // name: "macro_with_spaces", + // args: args{ + // trackerURL: "http://something.com?test=[TEST]", + // macroMap: map[string]string{ + // " [TEST] ": "http://iamurl.com", + // }, + // }, + // want: "http://something.com?test=http%3A%2F%2Fiamurl.com", + // }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := replaceMacros(tt.args.trackerURL, tt.args.macroMap) + assert.Equal(t, tt.want, got) + }) + } +} + +// BenchmarkGetVideoEventTracking +// +// Original: +// Running tool: /usr/local/go/bin/go test -benchmem -run=^$ -bench ^BenchmarkGetVideoEventTracking$ github.com/PubMatic-OpenWrap/prebid-server/endpoints/events + +// goos: linux +// goarch: arm64 +// pkg: github.com/PubMatic-OpenWrap/prebid-server/endpoints/events +// BenchmarkGetVideoEventTracking-8 19048 78882 ns/op 31590 B/op 128 allocs/op +// BenchmarkGetVideoEventTracking-8 27333 40491 ns/op 31589 B/op 128 allocs/op +// BenchmarkGetVideoEventTracking-8 28392 45111 ns/op 31586 B/op 128 allocs/op +// BenchmarkGetVideoEventTracking-8 18160 83581 ns/op 31585 B/op 128 allocs/op +// BenchmarkGetVideoEventTracking-8 16633 77993 ns/op 31591 B/op 128 allocs/op +// PASS +// ok github.com/PubMatic-OpenWrap/prebid-server/endpoints/events 1.807s + +// Refactored-GetVideoEventTracking: +// BenchmarkGetVideoEventTracking-8 10000 108697 ns/op 33489 B/op 131 allocs/op +// BenchmarkGetVideoEventTracking-8 10000 115349 ns/op 33489 B/op 131 allocs/op +// BenchmarkGetVideoEventTracking-8 12678 80833 ns/op 33486 B/op 131 allocs/op +// BenchmarkGetVideoEventTracking-8 18840 60841 ns/op 33493 B/op 131 allocs/op +// BenchmarkGetVideoEventTracking-8 20086 57733 ns/op 33482 B/op 131 allocs/op + +// Refactored-GetVideoEventTracking-using-replaceMacros: +// BenchmarkGetVideoEventTracking-8 65928 16866 ns/op 10434 B/op 96 allocs/op +// BenchmarkGetVideoEventTracking-8 66710 18611 ns/op 10433 B/op 96 allocs/op +// BenchmarkGetVideoEventTracking-8 66448 17244 ns/op 10433 B/op 96 allocs/op +// BenchmarkGetVideoEventTracking-8 35112 38085 ns/op 10433 B/op 96 allocs/op +// BenchmarkGetVideoEventTracking-8 40941 27584 ns/op 10434 B/op 96 allocs/op +func BenchmarkGetVideoEventTracking(b *testing.B) { + // all_macros with generated_bidId + trackerURL := "https://company.tracker.com?operId=8&e=[EVENT_ID]&p=[PBS-ACCOUNT]&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=[PBS-BIDDER]&advertiser_id=[ADVERTISER_NAME]&sURL=[DOMAIN]&pfi=[PLATFORM]&af=[ADTYPE]&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=[AD_UNIT]&bidid=[PBS-BIDID]&origbidid=[PBS-ORIG_BIDID]&bc=[BIDDER_CODE]" + req := &openrtb2.BidRequest{ + App: &openrtb2.App{Bundle: "com.someapp.com", Publisher: &openrtb2.Publisher{ID: "5890"}}, + Ext: []byte(`{ + "prebid": { + "macros": { + "[PROFILE_ID]": "100", + "[PROFILE_VERSION]": "2", + "[UNIX_TIMESTAMP]": "1234567890", + "[PLATFORM]": "7", + "[WRAPPER_IMPRESSION_ID]": "abc~!@#$%^&&*()_+{}|:\"<>?[]\\;',./" + } + } + }`), + Imp: []openrtb2.Imp{ + {TagID: "/testadunit/1", ID: "imp_1"}, + }, + } + bid := &openrtb2.Bid{ADomain: []string{"http://a.com/32?k=v", "b.com"}, ImpID: "imp_1", ID: "test_bid_id"} + gen_bidid := "random_bid_id" + requestingBidder := "test_bidder:234" + bidderCoreName := "test_core_bidder:234" + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = GetVideoEventTracking(req, &req.Imp[0], bid, trackerURL, gen_bidid, requestingBidder, bidderCoreName, 0) + } +} diff --git a/endpoints/events/test/base64_vast.txt.tar.gz b/endpoints/events/test/base64_vast.txt.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..d2b6fb7105258b1e559d3af94a76c11ed9957d52 GIT binary patch literal 171 zcmV;c095}UiwFRxSjc7o153?IDag;vD=F4bElUMaC8@w5;4 Zfp*#`7zLwX6pR8I0s!aS2`~T%001MRIUxW5 literal 0 HcmV?d00001 diff --git a/endpoints/events/test/benchmark_results.txt b/endpoints/events/test/benchmark_results.txt new file mode 100644 index 00000000000..adc5267405e --- /dev/null +++ b/endpoints/events/test/benchmark_results.txt @@ -0,0 +1,415 @@ +NEW +--- +goos: linux +goarch: arm64 +pkg: github.com/PubMatic-OpenWrap/prebid-server/endpoints/events +BenchmarkInjectVideoEventTrackers-8 11994 99857 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 108619 ns/op +BenchmarkInjectVideoEventTrackers-8 7047 162741 ns/op +BenchmarkInjectVideoEventTrackers-8 6451 156722 ns/op +BenchmarkInjectVideoEventTrackers-8 8053 149871 ns/op +BenchmarkInjectVideoEventTrackers-8 12775 95663 ns/op +BenchmarkInjectVideoEventTrackers-8 12192 98921 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 119874 ns/op +BenchmarkInjectVideoEventTrackers-8 8976 148432 ns/op +BenchmarkInjectVideoEventTrackers-8 12175 104665 ns/op +BenchmarkInjectVideoEventTrackers-8 12627 96783 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 142767 ns/op +BenchmarkInjectVideoEventTrackers-8 8652 130018 ns/op +BenchmarkInjectVideoEventTrackers-8 12621 94379 ns/op +BenchmarkInjectVideoEventTrackers-8 12541 95631 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 145282 ns/op +BenchmarkInjectVideoEventTrackers-8 12675 95240 ns/op +BenchmarkInjectVideoEventTrackers-8 12620 93739 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 140531 ns/op +BenchmarkInjectVideoEventTrackers-8 7932 134085 ns/op +BenchmarkInjectVideoEventTrackers-8 12958 94909 ns/op +BenchmarkInjectVideoEventTrackers-8 12896 100047 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 150835 ns/op +BenchmarkInjectVideoEventTrackers-8 11193 93567 ns/op +BenchmarkInjectVideoEventTrackers-8 12614 95702 ns/op +BenchmarkInjectVideoEventTrackers-8 11172 147317 ns/op +BenchmarkInjectVideoEventTrackers-8 10274 98216 ns/op +BenchmarkInjectVideoEventTrackers-8 12525 94558 ns/op +BenchmarkInjectVideoEventTrackers-8 12091 135374 ns/op +BenchmarkInjectVideoEventTrackers-8 12649 92635 ns/op +BenchmarkInjectVideoEventTrackers-8 12672 93532 ns/op +BenchmarkInjectVideoEventTrackers-8 9829 160558 ns/op +BenchmarkInjectVideoEventTrackers-8 9627 109390 ns/op +BenchmarkInjectVideoEventTrackers-8 12559 95794 ns/op +BenchmarkInjectVideoEventTrackers-8 12118 99115 ns/op +BenchmarkInjectVideoEventTrackers-8 12313 96845 ns/op +BenchmarkInjectVideoEventTrackers-8 12039 108354 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 107922 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 130093 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 109274 ns/op +BenchmarkInjectVideoEventTrackers-8 12277 99076 ns/op +BenchmarkInjectVideoEventTrackers-8 12220 97172 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 106413 ns/op +BenchmarkInjectVideoEventTrackers-8 12284 96475 ns/op +BenchmarkInjectVideoEventTrackers-8 12369 97243 ns/op +BenchmarkInjectVideoEventTrackers-8 12033 102589 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 101835 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 111323 ns/op +BenchmarkInjectVideoEventTrackers-8 12139 102415 ns/op +BenchmarkInjectVideoEventTrackers-8 12520 99148 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 102187 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 103977 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 117965 ns/op +BenchmarkInjectVideoEventTrackers-8 12621 96923 ns/op +BenchmarkInjectVideoEventTrackers-8 12276 97474 ns/op +BenchmarkInjectVideoEventTrackers-8 12496 97902 ns/op +BenchmarkInjectVideoEventTrackers-8 12639 95111 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 105928 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 107623 ns/op +BenchmarkInjectVideoEventTrackers-8 12416 96683 ns/op +BenchmarkInjectVideoEventTrackers-8 12476 94106 ns/op +BenchmarkInjectVideoEventTrackers-8 12526 98440 ns/op +BenchmarkInjectVideoEventTrackers-8 12543 98846 ns/op +BenchmarkInjectVideoEventTrackers-8 12445 96899 ns/op +BenchmarkInjectVideoEventTrackers-8 12355 96749 ns/op +BenchmarkInjectVideoEventTrackers-8 12783 94215 ns/op +BenchmarkInjectVideoEventTrackers-8 12560 101970 ns/op +BenchmarkInjectVideoEventTrackers-8 12759 95018 ns/op +BenchmarkInjectVideoEventTrackers-8 12870 95196 ns/op +BenchmarkInjectVideoEventTrackers-8 12680 96009 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 104518 ns/op +BenchmarkInjectVideoEventTrackers-8 12334 95338 ns/op +BenchmarkInjectVideoEventTrackers-8 12841 97060 ns/op +BenchmarkInjectVideoEventTrackers-8 12570 95457 ns/op +BenchmarkInjectVideoEventTrackers-8 12663 92850 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 102418 ns/op +BenchmarkInjectVideoEventTrackers-8 12525 93522 ns/op +BenchmarkInjectVideoEventTrackers-8 12598 95461 ns/op +BenchmarkInjectVideoEventTrackers-8 12654 95732 ns/op +BenchmarkInjectVideoEventTrackers-8 12458 97007 ns/op +BenchmarkInjectVideoEventTrackers-8 12796 95227 ns/op +BenchmarkInjectVideoEventTrackers-8 12876 93244 ns/op +BenchmarkInjectVideoEventTrackers-8 12872 94017 ns/op +BenchmarkInjectVideoEventTrackers-8 12681 93816 ns/op +BenchmarkInjectVideoEventTrackers-8 12339 95252 ns/op +BenchmarkInjectVideoEventTrackers-8 12823 94395 ns/op +BenchmarkInjectVideoEventTrackers-8 12694 94203 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 100970 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 113119 ns/op +BenchmarkInjectVideoEventTrackers-8 12094 94384 ns/op +BenchmarkInjectVideoEventTrackers-8 12213 99525 ns/op +BenchmarkInjectVideoEventTrackers-8 12580 93890 ns/op +BenchmarkInjectVideoEventTrackers-8 12214 92876 ns/op +BenchmarkInjectVideoEventTrackers-8 12493 95199 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 102603 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 102531 ns/op +BenchmarkInjectVideoEventTrackers-8 11844 96529 ns/op +BenchmarkInjectVideoEventTrackers-8 11839 98682 ns/op +BenchmarkInjectVideoEventTrackers-8 12073 95432 ns/op +BenchmarkInjectVideoEventTrackers-8 12178 93536 ns/op +BenchmarkInjectVideoEventTrackers-8 12308 95322 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 106285 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 107198 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 127930 ns/op +BenchmarkInjectVideoEventTrackers-8 11570 100564 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 103107 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 100232 ns/op +BenchmarkInjectVideoEventTrackers-8 12183 98138 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 101463 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 100976 ns/op +BenchmarkInjectVideoEventTrackers-8 12136 101379 ns/op +BenchmarkInjectVideoEventTrackers-8 12129 97470 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 101763 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 105143 ns/op +BenchmarkInjectVideoEventTrackers-8 12036 96395 ns/op +BenchmarkInjectVideoEventTrackers-8 12370 103113 ns/op +BenchmarkInjectVideoEventTrackers-8 12097 104316 ns/op +BenchmarkInjectVideoEventTrackers-8 10578 102399 ns/op +BenchmarkInjectVideoEventTrackers-8 12114 98435 ns/op +BenchmarkInjectVideoEventTrackers-8 12199 96260 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 100708 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 100063 ns/op +BenchmarkInjectVideoEventTrackers-8 12259 99365 ns/op +BenchmarkInjectVideoEventTrackers-8 11527 105366 ns/op +BenchmarkInjectVideoEventTrackers-8 12170 98071 ns/op +BenchmarkInjectVideoEventTrackers-8 11662 98735 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 100196 ns/op +BenchmarkInjectVideoEventTrackers-8 12100 98485 ns/op +BenchmarkInjectVideoEventTrackers-8 12154 97764 ns/op +BenchmarkInjectVideoEventTrackers-8 12190 98722 ns/op +BenchmarkInjectVideoEventTrackers-8 12804 93210 ns/op +BenchmarkInjectVideoEventTrackers-8 12298 91861 ns/op +BenchmarkInjectVideoEventTrackers-8 12411 97100 ns/op +BenchmarkInjectVideoEventTrackers-8 12403 95998 ns/op +BenchmarkInjectVideoEventTrackers-8 12729 93676 ns/op +BenchmarkInjectVideoEventTrackers-8 12483 116678 ns/op +BenchmarkInjectVideoEventTrackers-8 10972 94685 ns/op +BenchmarkInjectVideoEventTrackers-8 12343 95353 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 106452 ns/op +BenchmarkInjectVideoEventTrackers-8 12540 95257 ns/op +BenchmarkInjectVideoEventTrackers-8 12612 97109 ns/op +BenchmarkInjectVideoEventTrackers-8 12655 95869 ns/op +BenchmarkInjectVideoEventTrackers-8 12564 101473 ns/op +BenchmarkInjectVideoEventTrackers-8 12268 95826 ns/op +BenchmarkInjectVideoEventTrackers-8 12158 95248 ns/op +BenchmarkInjectVideoEventTrackers-8 12248 93556 ns/op +BenchmarkInjectVideoEventTrackers-8 12874 95673 ns/op +BenchmarkInjectVideoEventTrackers-8 12544 98246 ns/op +BenchmarkInjectVideoEventTrackers-8 12751 95809 ns/op +BenchmarkInjectVideoEventTrackers-8 12650 94296 ns/op +BenchmarkInjectVideoEventTrackers-8 12152 98760 ns/op +BenchmarkInjectVideoEventTrackers-8 12526 93759 ns/op +BenchmarkInjectVideoEventTrackers-8 12052 102301 ns/op +BenchmarkInjectVideoEventTrackers-8 12291 96482 ns/op +BenchmarkInjectVideoEventTrackers-8 12262 96106 ns/op +BenchmarkInjectVideoEventTrackers-8 12348 95109 ns/op +BenchmarkInjectVideoEventTrackers-8 12496 95862 ns/op +BenchmarkInjectVideoEventTrackers-8 12453 93967 ns/op +BenchmarkInjectVideoEventTrackers-8 12153 99390 ns/op +BenchmarkInjectVideoEventTrackers-8 12423 95374 ns/op +BenchmarkInjectVideoEventTrackers-8 12615 93599 ns/op +BenchmarkInjectVideoEventTrackers-8 12516 94149 ns/op +BenchmarkInjectVideoEventTrackers-8 12460 94459 ns/op +BenchmarkInjectVideoEventTrackers-8 12094 95090 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 106277 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 142040 ns/op +BenchmarkInjectVideoEventTrackers-8 12156 94065 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 100250 ns/op +BenchmarkInjectVideoEventTrackers-8 12726 96447 ns/op +BenchmarkInjectVideoEventTrackers-8 12765 102457 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 100640 ns/op +BenchmarkInjectVideoEventTrackers-8 12506 100274 ns/op +BenchmarkInjectVideoEventTrackers-8 12260 100070 ns/op +BenchmarkInjectVideoEventTrackers-8 12308 98857 ns/op +BenchmarkInjectVideoEventTrackers-8 12379 94057 ns/op +BenchmarkInjectVideoEventTrackers-8 12340 94406 ns/op +BenchmarkInjectVideoEventTrackers-8 12625 95022 ns/op +BenchmarkInjectVideoEventTrackers-8 9602 127201 ns/op +BenchmarkInjectVideoEventTrackers-8 12022 99407 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 101338 ns/op +BenchmarkInjectVideoEventTrackers-8 12512 96420 ns/op +BenchmarkInjectVideoEventTrackers-8 12604 93874 ns/op +BenchmarkInjectVideoEventTrackers-8 12098 93844 ns/op +BenchmarkInjectVideoEventTrackers-8 12193 100286 ns/op +BenchmarkInjectVideoEventTrackers-8 12698 94057 ns/op +BenchmarkInjectVideoEventTrackers-8 12655 95501 ns/op +BenchmarkInjectVideoEventTrackers-8 12780 100857 ns/op +BenchmarkInjectVideoEventTrackers-8 12702 95481 ns/op +BenchmarkInjectVideoEventTrackers-8 12699 97814 ns/op +BenchmarkInjectVideoEventTrackers-8 12127 98798 ns/op +BenchmarkInjectVideoEventTrackers-8 12010 96081 ns/op +BenchmarkInjectVideoEventTrackers-8 12501 95398 ns/op +BenchmarkInjectVideoEventTrackers-8 12560 95790 ns/op +BenchmarkInjectVideoEventTrackers-8 12624 95461 ns/op +BenchmarkInjectVideoEventTrackers-8 12519 105760 ns/op +BenchmarkInjectVideoEventTrackers-8 11209 108704 ns/op +BenchmarkInjectVideoEventTrackers-8 12322 95732 ns/op +BenchmarkInjectVideoEventTrackers-8 12771 96915 ns/op +BenchmarkInjectVideoEventTrackers-8 12816 94830 ns/op +BenchmarkInjectVideoEventTrackers-8 12598 95256 ns/op +PASS +ok github.com/PubMatic-OpenWrap/prebid-server/endpoints/events 384.888s + +OLD +--- +goos: linux +goarch: arm64 +pkg: github.com/PubMatic-OpenWrap/prebid-server/endpoints/events +BenchmarkInjectVideoEventTrackers-8 11412 103337 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 103241 ns/op +BenchmarkInjectVideoEventTrackers-8 9614 107920 ns/op +BenchmarkInjectVideoEventTrackers-8 7446 142613 ns/op +BenchmarkInjectVideoEventTrackers-8 6985 152987 ns/op +BenchmarkInjectVideoEventTrackers-8 9717 113304 ns/op +BenchmarkInjectVideoEventTrackers-8 10687 111009 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 103443 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 161335 ns/op +BenchmarkInjectVideoEventTrackers-8 8612 141799 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 104980 ns/op +BenchmarkInjectVideoEventTrackers-8 8994 118290 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 103775 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 117957 ns/op +BenchmarkInjectVideoEventTrackers-8 7485 152072 ns/op +BenchmarkInjectVideoEventTrackers-8 11416 102757 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 106422 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 103300 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 146524 ns/op +BenchmarkInjectVideoEventTrackers-8 11280 106079 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 105962 ns/op +BenchmarkInjectVideoEventTrackers-8 11071 141065 ns/op +BenchmarkInjectVideoEventTrackers-8 9565 108086 ns/op +BenchmarkInjectVideoEventTrackers-8 9354 113106 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 103729 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 103996 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 157443 ns/op +BenchmarkInjectVideoEventTrackers-8 11301 111289 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 104083 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 102001 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 126965 ns/op +BenchmarkInjectVideoEventTrackers-8 6645 158038 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 102666 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 102557 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 108698 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 107614 ns/op +BenchmarkInjectVideoEventTrackers-8 9088 133802 ns/op +BenchmarkInjectVideoEventTrackers-8 6825 152288 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 103996 ns/op +BenchmarkInjectVideoEventTrackers-8 10992 118586 ns/op +BenchmarkInjectVideoEventTrackers-8 9406 106554 ns/op +BenchmarkInjectVideoEventTrackers-8 9822 165054 ns/op +BenchmarkInjectVideoEventTrackers-8 8284 123469 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 108410 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 104649 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 103888 ns/op +BenchmarkInjectVideoEventTrackers-8 9793 103767 ns/op +BenchmarkInjectVideoEventTrackers-8 8064 176493 ns/op +BenchmarkInjectVideoEventTrackers-8 10224 103211 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 106395 ns/op +BenchmarkInjectVideoEventTrackers-8 11578 105227 ns/op +BenchmarkInjectVideoEventTrackers-8 7761 160917 ns/op +BenchmarkInjectVideoEventTrackers-8 9730 141976 ns/op +BenchmarkInjectVideoEventTrackers-8 11352 106213 ns/op +BenchmarkInjectVideoEventTrackers-8 8799 119790 ns/op +BenchmarkInjectVideoEventTrackers-8 7743 175326 ns/op +BenchmarkInjectVideoEventTrackers-8 9674 108504 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 104176 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 107588 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 107367 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 132792 ns/op +BenchmarkInjectVideoEventTrackers-8 11179 109587 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 103266 ns/op +BenchmarkInjectVideoEventTrackers-8 9483 116627 ns/op +BenchmarkInjectVideoEventTrackers-8 9438 165878 ns/op +BenchmarkInjectVideoEventTrackers-8 8343 121643 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 104253 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 111989 ns/op +BenchmarkInjectVideoEventTrackers-8 11624 102501 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 163193 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 102279 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 103620 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 102954 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 104372 ns/op +BenchmarkInjectVideoEventTrackers-8 9360 121906 ns/op +BenchmarkInjectVideoEventTrackers-8 11402 102374 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 102101 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 103073 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 105181 ns/op +BenchmarkInjectVideoEventTrackers-8 7383 171419 ns/op +BenchmarkInjectVideoEventTrackers-8 11078 105008 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 102512 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 106887 ns/op +BenchmarkInjectVideoEventTrackers-8 11018 174666 ns/op +BenchmarkInjectVideoEventTrackers-8 11121 104063 ns/op +BenchmarkInjectVideoEventTrackers-8 11512 113785 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 108632 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 103740 ns/op +BenchmarkInjectVideoEventTrackers-8 11200 104223 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 109149 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 102092 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 104393 ns/op +BenchmarkInjectVideoEventTrackers-8 10462 104387 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 107595 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 108973 ns/op +BenchmarkInjectVideoEventTrackers-8 11140 104834 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 114135 ns/op +BenchmarkInjectVideoEventTrackers-8 9674 109976 ns/op +BenchmarkInjectVideoEventTrackers-8 9894 102282 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 104053 ns/op +BenchmarkInjectVideoEventTrackers-8 9691 103451 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 103017 ns/op +BenchmarkInjectVideoEventTrackers-8 11432 106630 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 116968 ns/op +BenchmarkInjectVideoEventTrackers-8 11148 111332 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 106245 ns/op +BenchmarkInjectVideoEventTrackers-8 11107 106324 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 125663 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 109025 ns/op +BenchmarkInjectVideoEventTrackers-8 9948 103579 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 111039 ns/op +BenchmarkInjectVideoEventTrackers-8 9982 107039 ns/op +BenchmarkInjectVideoEventTrackers-8 9532 119793 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 108138 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 107934 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 107594 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 103471 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 103766 ns/op +BenchmarkInjectVideoEventTrackers-8 11556 101248 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 114003 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 103359 ns/op +BenchmarkInjectVideoEventTrackers-8 9386 107104 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 107333 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 105346 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 104383 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 103176 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 107480 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 102885 ns/op +BenchmarkInjectVideoEventTrackers-8 9937 106700 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 112205 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 114893 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 104802 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 122574 ns/op +BenchmarkInjectVideoEventTrackers-8 9513 116394 ns/op +BenchmarkInjectVideoEventTrackers-8 9439 108796 ns/op +BenchmarkInjectVideoEventTrackers-8 8712 115626 ns/op +BenchmarkInjectVideoEventTrackers-8 9792 104656 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 112900 ns/op +BenchmarkInjectVideoEventTrackers-8 11197 108651 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 106477 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 106866 ns/op +BenchmarkInjectVideoEventTrackers-8 11379 109056 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 109240 ns/op +BenchmarkInjectVideoEventTrackers-8 9552 108889 ns/op +BenchmarkInjectVideoEventTrackers-8 11392 147023 ns/op +BenchmarkInjectVideoEventTrackers-8 11553 104010 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 102045 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 122656 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 108962 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 109847 ns/op +BenchmarkInjectVideoEventTrackers-8 9756 111888 ns/op +BenchmarkInjectVideoEventTrackers-8 11671 115049 ns/op +BenchmarkInjectVideoEventTrackers-8 9361 108008 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 108039 ns/op +BenchmarkInjectVideoEventTrackers-8 9820 107452 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 104862 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 120423 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 102096 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 105396 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 105446 ns/op +BenchmarkInjectVideoEventTrackers-8 9808 103055 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 109139 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 109291 ns/op +BenchmarkInjectVideoEventTrackers-8 9427 113156 ns/op +BenchmarkInjectVideoEventTrackers-8 10416 106213 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 104006 ns/op +BenchmarkInjectVideoEventTrackers-8 9496 106432 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 119959 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 104761 ns/op +BenchmarkInjectVideoEventTrackers-8 9834 112330 ns/op +BenchmarkInjectVideoEventTrackers-8 9410 110560 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 105160 ns/op +BenchmarkInjectVideoEventTrackers-8 9613 109464 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 104137 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 106862 ns/op +BenchmarkInjectVideoEventTrackers-8 9986 107730 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 105636 ns/op +BenchmarkInjectVideoEventTrackers-8 9934 113900 ns/op +BenchmarkInjectVideoEventTrackers-8 9727 119387 ns/op +BenchmarkInjectVideoEventTrackers-8 9901 123299 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 116341 ns/op +BenchmarkInjectVideoEventTrackers-8 9680 106484 ns/op +BenchmarkInjectVideoEventTrackers-8 11455 105962 ns/op +BenchmarkInjectVideoEventTrackers-8 10924 108121 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 206043 ns/op +BenchmarkInjectVideoEventTrackers-8 7663 179629 ns/op +BenchmarkInjectVideoEventTrackers-8 8349 146721 ns/op +BenchmarkInjectVideoEventTrackers-8 9888 162455 ns/op +BenchmarkInjectVideoEventTrackers-8 6970 167227 ns/op +BenchmarkInjectVideoEventTrackers-8 9943 166298 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 107951 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 177137 ns/op +BenchmarkInjectVideoEventTrackers-8 11049 102284 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 106085 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 105527 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 110146 ns/op +BenchmarkInjectVideoEventTrackers-8 11310 109212 ns/op +BenchmarkInjectVideoEventTrackers-8 9882 108443 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 109327 ns/op +BenchmarkInjectVideoEventTrackers-8 10000 107013 ns/op +PASS +ok github.com/PubMatic-OpenWrap/prebid-server/endpoints/events 268.193s diff --git a/endpoints/events/test/raw_vast.txt b/endpoints/events/test/raw_vast.txt new file mode 100644 index 00000000000..2bd4a7e0d79 --- /dev/null +++ b/endpoints/events/test/raw_vast.txt @@ -0,0 +1,101 @@ +creative_url +LoopMe LTD +BidSwitch +Yahoo Ad Manager PlusVAST 2.0 Linear AdVAST 2.0 Linear Ad00:00:15 +\\n\\n \\n \\n \\n AdGear RTB\\n \\n \\n \\n \\n \\n \\n \\n \\n\\n +\\n\\n \\n \\n \\n AdGear RTB\\n \\n \\n \\n \\n \\n \\n \\n \\n\\n +\\n\\n \\n \\n \\n AdGear RTB\\n \\n \\n \\n \\n \\n \\n \\n \\n\\n +\\n\\n \\n \\n \\n AdGear RTB\\n \\n \\n \\n \\n \\n \\n \\n \\n\\n +\\n\\n \\n \\n \\n AdGear RTB\\n \\n \\n \\n \\n \\n \\n \\n \\n\\n +\\n\\n \\n \\n \\n AdGear RTB\\n \\n \\n \\n \\n \\n \\n \\n \\n\\n +\\n\\n \\n \\n \\n AdGear RTB\\n \\n \\n \\n \\n \\n \\n \\n \\n\\n +\\n\\n \\n \\n \\n AdGear RTB\\n \\n \\n \\n \\n \\n \\n \\n \\n\\n +RhythmXchange Adserver +RhythmXchange Adserver +LoopMe LTD +adnxs +ebdr +RhythmXchange Adserver +RhythmXchange Adserver +BidSwitch +ebdr +ebdr +RhythmXchange Adserver +RhythmXchange Adserver +ebdr +LoopMe LTD +ebdr +RhythmXchange Adserver +PlayTime RTB +PlayTime RTB +RhythmXchange Adserver +ebdr +PlayTime RTB +GumGum +LoopMe LTD +RhythmXchange Adserver +ebdr +GumGum +RhythmXchange Adserver +ebdr +ebdr +Yahoo Ad Manager PlusVAST 2.0 Linear AdVAST 2.0 Linear Ad00:00:15 +RhythmXchange Adserver +RhythmXchange Adserver +adnxs +RhythmXchange Adserver +adnxs +adnxs +adnxs +PlayTime RTB +ebdr +BidSwitch +RhythmXchange Adserver +adnxs +RhythmXchange Adserver +ebdr +RhythmXchange Adserver +ebdr +RhythmXchange Adserver +ebdr +RhythmXchange Adserver +adnxs +MediaMath T1 VADS +adnxs +MediaMath T1 VADS +ebdr +BidSwitch +RhythmXchange Adserver +BidSwitch +Smadex +ebdr +adnxs +GumGum +RhythmXchange Adserver +RhythmXchange Adserver +ebdr +RhythmXchange Adserver +RhythmXchange Adserver +Yahoo Ad Manager PlusVAST 2.0 Linear AdVAST 2.0 Linear Ad00:02:00 +RhythmXchange Adserver +GumGum +ebdr +RhythmXchange Adserver +RTB House +ebdr +BidSwitch +Yahoo Ad Manager PlusVAST 2.0 Linear AdVAST 2.0 Linear Ad00:00:07 +ebdr +RhythmXchange Adserver +adnxs +ebdr +Yahoo Ad Manager PlusVAST 2.0 Linear AdVAST 2.0 Linear Ad00:00:07 +PlayTime RTB +RhythmXchange Adserver +RhythmXchange Adserver +RhythmXchange Adserver +RhythmXchange Adserver +RhythmXchange Adserver +ebdr +adnxs +adnxs \ No newline at end of file diff --git a/endpoints/events/vtrack_ow.go b/endpoints/events/vtrack_ow.go index 76e7ff7b707..f30e198d530 100644 --- a/endpoints/events/vtrack_ow.go +++ b/endpoints/events/vtrack_ow.go @@ -1,245 +1,214 @@ package events import ( - "encoding/json" + "bytes" "errors" - "fmt" - "net/url" "strings" + "time" + "github.com/PubMatic-OpenWrap/fastxml" "github.com/beevik/etree" - "github.com/golang/glog" "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" "github.com/prebid/prebid-server/v2/openrtb_ext" ) -// standard VAST macros -// https://interactiveadvertisingbureau.github.io/vast/vast4macros/vast4-macros-latest.html#macro-spec-adcount -const ( - VASTAdTypeMacro = "[ADTYPE]" - VASTAppBundleMacro = "[APPBUNDLE]" - VASTDomainMacro = "[DOMAIN]" - VASTPageURLMacro = "[PAGEURL]" - - // PBS specific macros - PBSEventIDMacro = "[EVENT_ID]" // macro for injecting PBS defined video event tracker id - //[PBS-ACCOUNT] represents publisher id / account id - PBSAccountMacro = "[PBS-ACCOUNT]" - // [PBS-BIDDER] represents bidder name - PBSBidderMacro = "[PBS-BIDDER]" - // [PBS-ORIG_BIDID] represents original bid id. - PBSOrigBidIDMacro = "[PBS-ORIG_BIDID]" - // [PBS-BIDID] represents bid id. If auction.generate-bid-id config is on, then resolve with response.seatbid.bid.ext.prebid.bidid. Else replace with response.seatbid.bid.id - PBSBidIDMacro = "[PBS-BIDID]" - // [ADERVERTISER_NAME] represents advertiser name - PBSAdvertiserNameMacro = "[ADVERTISER_NAME]" - // Pass imp.tagId using this macro - PBSAdUnitIDMacro = "[AD_UNIT]" - //PBSBidderCodeMacro represents an alias id or core bidder id. - PBSBidderCodeMacro = "[BIDDER_CODE]" +var ( + errEventURLNotConfigured = errors.New("event urls not configured") ) -var trackingEvents = []string{"start", "firstQuartile", "midpoint", "thirdQuartile", "complete"} - -// PubMatic specific event IDs -// This will go in event-config once PreBid modular design is in place -var eventIDMap = map[string]string{ - "start": "2", - "firstQuartile": "4", - "midpoint": "3", - "thirdQuartile": "5", - "complete": "6", -} - // InjectVideoEventTrackers injects the video tracking events // Returns VAST xml contains as first argument. Second argument indicates whether the trackers are injected and last argument indicates if there is any error in injecting the trackers -func InjectVideoEventTrackers(trackerURL, vastXML string, bid *openrtb2.Bid, prebidGenBidId, requestingBidder, bidderCoreName, accountID string, timestamp int64, bidRequest *openrtb2.BidRequest) ([]byte, bool, error) { - // parse VAST - doc := etree.NewDocument() - err := doc.ReadFromString(vastXML) - if nil != err { - err = fmt.Errorf("account:[%s] bidder:[%s] err:[vast_xml_parsing_failed:%s] vast:[%s] ", accountID, requestingBidder, err.Error(), vastXML) - glog.Error(err.Error()) - return []byte(vastXML), false, err // false indicates events trackers are not injected - } +func InjectVideoEventTrackers( + bidRequest *openrtb2.BidRequest, + bid *openrtb2.Bid, + vastXML, trackerURL, prebidGenBidId, requestingBidder, bidderCoreName string, + timestamp int64, fastXMLExperiment bool) (response string, metrics *openrtb_ext.FastXMLMetrics, err error) { //Maintaining BidRequest Impression Map (Copied from exchange.go#applyCategoryMapping) //TODO: It should be optimized by forming once and reusing - impMap := make(map[string]*openrtb2.Imp) - for i := range bidRequest.Imp { - impMap[bidRequest.Imp[i].ID] = &bidRequest.Imp[i] + var imp *openrtb2.Imp + for _, impr := range bidRequest.Imp { + if bid.ImpID == impr.ID && impr.Video != nil { + imp = &impr + break + } + } + if imp == nil { + return vastXML, nil, nil } - eventURLMap := GetVideoEventTracking(trackerURL, bid, prebidGenBidId, requestingBidder, bidderCoreName, accountID, timestamp, bidRequest, doc, impMap) - trackersInjected := false - // return if if no tracking URL + eventURLMap := GetVideoEventTracking(bidRequest, imp, bid, trackerURL, prebidGenBidId, requestingBidder, bidderCoreName, timestamp) if len(eventURLMap) == 0 { - return []byte(vastXML), false, errors.New("Event URLs are not found") + return vastXML, nil, errEventURLNotConfigured } - creatives := FindCreatives(doc) + adm := strings.TrimSpace(bid.AdM) + nurlPresent := (adm == "" || strings.HasPrefix(adm, "http")) - if adm := strings.TrimSpace(bid.AdM); adm == "" || strings.HasPrefix(adm, "http") { - // determine which creative type to be created based on linearity - if imp, ok := impMap[bid.ImpID]; ok && nil != imp.Video { - // create creative object - creatives = doc.FindElements("VAST/Ad/Wrapper/Creatives") - // var creative *etree.Element - // if len(creatives) > 0 { - // creative = creatives[0] // consider only first creative - // } else { - creative := doc.CreateElement("Creative") - creatives[0].AddChild(creative) - - // } - - switch imp.Video.Linearity { - case adcom1.LinearityLinear: - creative.AddChild(doc.CreateElement("Linear")) - case adcom1.LinearityNonLinear: - creative.AddChild(doc.CreateElement("NonLinearAds")) - default: // create both type of creatives - creative.AddChild(doc.CreateElement("Linear")) - creative.AddChild(doc.CreateElement("NonLinearAds")) - } - creatives = creative.ChildElements() // point to actual cratives - } - } - for _, creative := range creatives { - trackingEvents := creative.SelectElement("TrackingEvents") - if nil == trackingEvents { - trackingEvents = creative.CreateElement("TrackingEvents") - creative.AddChild(trackingEvents) - } - // Inject - for event, url := range eventURLMap { - trackingEle := trackingEvents.CreateElement("Tracking") - trackingEle.CreateAttr("event", event) - trackingEle.SetText(fmt.Sprintf("%s", url)) - trackersInjected = true + _startTime := time.Now() + response, err = injectVideoEventsETree(vastXML, eventURLMap, nurlPresent, imp.Video.Linearity) + etreeParserTime := time.Since(_startTime) + + if fastXMLExperiment && err == nil { + _startTime = time.Now() + fastXMLResponse, _ := injectVideoEventsFastXML(vastXML, eventURLMap, nurlPresent, imp.Video.Linearity) + fastXMLParserTime := time.Since(_startTime) + + //temporary + if fastXMLResponse != vastXML { + fastXMLResponse = strings.ReplaceAll(fastXMLResponse, " >", ">") } - } - out := []byte(vastXML) - var wErr error - if trackersInjected { - out, wErr = doc.WriteToBytes() - trackersInjected = trackersInjected && nil == wErr - if nil != wErr { - glog.Errorf("%v", wErr.Error()) + metrics = &openrtb_ext.FastXMLMetrics{ + XMLParserTime: fastXMLParserTime, + EtreeParserTime: etreeParserTime, + IsRespMismatch: (response != fastXMLResponse), } } - return out, trackersInjected, wErr + + return response, metrics, err } -// GetVideoEventTracking returns map containing key as event name value as associaed video event tracking URL -// By default PBS will expect [EVENT_ID] macro in trackerURL to inject event information -// [EVENT_ID] will be injected with one of the following values -// -// firstQuartile, midpoint, thirdQuartile, complete -// -// If your company can not use [EVENT_ID] and has its own macro. provide config.TrackerMacros implementation -// and ensure that your macro is part of trackerURL configuration -func GetVideoEventTracking(trackerURL string, bid *openrtb2.Bid, prebidGenBidId, requestingBidder string, bidderCoreName string, accountId string, timestamp int64, req *openrtb2.BidRequest, doc *etree.Document, impMap map[string]*openrtb2.Imp) map[string]string { - eventURLMap := make(map[string]string) - if "" == strings.TrimSpace(trackerURL) { - return eventURLMap +func injectVideoEventsETree(vastXML string, eventURLMap map[string]string, nurlPresent bool, linearity adcom1.LinearityMode) (string, error) { + + // parse VAST + doc := etree.NewDocument() + if err := doc.ReadFromString(vastXML); err != nil { + return vastXML, err } - // lookup custom macros - var customMacroMap map[string]string - if nil != req.Ext { - reqExt := new(openrtb_ext.ExtRequest) - err := json.Unmarshal(req.Ext, &reqExt) - if err == nil { - customMacroMap = reqExt.Prebid.Macros - } else { - glog.Warningf("Error in unmarshling req.Ext.Prebid.Vast: [%s]", err.Error()) + doc.WriteSettings.CanonicalEndTags = true + + creatives := FindCreatives(doc) + if nurlPresent { + // create creative object + creatives = doc.FindElements("VAST/Ad/Wrapper/Creatives") + creative := doc.CreateElement("Creative") + creatives[0].AddChild(creative) + + switch linearity { + case adcom1.LinearityLinear: + creative.AddChild(doc.CreateElement("Linear")) + case adcom1.LinearityNonLinear: + creative.AddChild(doc.CreateElement("NonLinearAds")) + default: // create both type of creatives + creative.AddChild(doc.CreateElement("Linear")) + creative.AddChild(doc.CreateElement("NonLinearAds")) } + creatives = creative.ChildElements() // point to actual cratives } - for _, event := range trackingEvents { - eventURL := trackerURL - // lookup in custom macros - if nil != customMacroMap { - for customMacro, value := range customMacroMap { - eventURL = replaceMacro(eventURL, customMacro, value) - } - } - // replace standard macros - eventURL = replaceMacro(eventURL, VASTAdTypeMacro, string(openrtb_ext.BidTypeVideo)) - if nil != req && nil != req.App { - // eventURL = replaceMacro(eventURL, VASTAppBundleMacro, req.App.Bundle) - eventURL = replaceMacro(eventURL, VASTDomainMacro, req.App.Bundle) - if nil != req.App.Publisher { - eventURL = replaceMacro(eventURL, PBSAccountMacro, req.App.Publisher.ID) - } + trackersInjected := false + for _, creative := range creatives { + trackingEventsNode := creative.SelectElement("TrackingEvents") + if nil == trackingEventsNode { + trackingEventsNode = creative.CreateElement("TrackingEvents") + creative.AddChild(trackingEventsNode) } - if nil != req && nil != req.Site { - eventURL = replaceMacro(eventURL, VASTDomainMacro, getDomain(req.Site)) - eventURL = replaceMacro(eventURL, VASTPageURLMacro, req.Site.Page) - if nil != req.Site.Publisher { - eventURL = replaceMacro(eventURL, PBSAccountMacro, req.Site.Publisher.ID) + // Inject + for _, event := range trackingEvents { + if url, ok := eventURLMap[event]; ok { + trackingNode := trackingEventsNode.CreateElement("Tracking") + trackingNode.CreateAttr("event", event) + trackingNode.SetText(url) + trackersInjected = true } } + } - domain := "" - if len(bid.ADomain) > 0 { - var err error - //eventURL = replaceMacro(eventURL, PBSAdvertiserNameMacro, strings.Join(bid.ADomain, ",")) - domain, err = extractDomain(bid.ADomain[0]) - if err != nil { - glog.Warningf("Unable to extract domain from '%s'. [%s]", bid.ADomain[0], err.Error()) - } - } + if !trackersInjected { + return vastXML, nil + } + + out, err := doc.WriteToBytes() + if err != nil { + return vastXML, err + } + return string(out), nil +} + +func injectVideoEventsFastXML(vastXML string, eventURLMap map[string]string, nurlPresent bool, linearity adcom1.LinearityMode) (string, error) { - eventURL = replaceMacro(eventURL, PBSAdvertiserNameMacro, domain) + //parse vast xml + doc := fastxml.NewXMLReader(nil) + if err := doc.Parse([]byte(vastXML)); err != nil { + return vastXML, err + } + + trackersInjected := false + xu := fastxml.NewXMLUpdater(doc, fastxml.WriteSettings{ + CDATAWrap: true, + ExpandInline: true, + }) - eventURL = replaceMacro(eventURL, PBSBidderMacro, bidderCoreName) - eventURL = replaceMacro(eventURL, PBSBidderCodeMacro, requestingBidder) + if nurlPresent { + creative := doc.SelectElement(nil, "VAST", "Ad", "Wrapper", "Creatives") + if creative != nil { + cr := fastxml.CreateElement("Creative") - /* Use generated bidId if present, else use bid.ID */ - if len(prebidGenBidId) > 0 && prebidGenBidId != bid.ID { - eventURL = replaceMacro(eventURL, PBSBidIDMacro, prebidGenBidId) - } else { - eventURL = replaceMacro(eventURL, PBSBidIDMacro, bid.ID) + switch linearity { + case adcom1.LinearityLinear: + cr.AddChild(fastxml.CreateElement("Linear").AddChild(getTrackingEvents(true, eventURLMap))) + case adcom1.LinearityNonLinear: + cr.AddChild(fastxml.CreateElement("NonLinearAds").AddChild(getTrackingEvents(true, eventURLMap))) + default: + cr.AddChild(fastxml.CreateElement("Linear").AddChild(getTrackingEvents(true, eventURLMap))) + cr.AddChild(fastxml.CreateElement("NonLinearAds").AddChild(getTrackingEvents(true, eventURLMap))) + } + + xu.AppendElement(creative, cr) + trackersInjected = true } - eventURL = replaceMacro(eventURL, PBSOrigBidIDMacro, bid.ID) + } else { + // Find creatives + creatives := doc.SelectElements(nil, "VAST", "Ad", "*", "Creatives", "Creative", "*") - // replace [EVENT_ID] macro with PBS defined event ID - eventURL = replaceMacro(eventURL, PBSEventIDMacro, eventIDMap[event]) + for _, linearityElement := range creatives { + name := doc.Name(linearityElement) + if !(name == "Linear" || name == "NonLinearAds") { + continue + } - if imp, ok := impMap[bid.ImpID]; ok { - eventURL = replaceMacro(eventURL, PBSAdUnitIDMacro, imp.TagID) - } else { - glog.Warningf("Setting empty value for %s macro, as failed to determine imp.TagID for bid.ImpID: %s", PBSAdUnitIDMacro, bid.ImpID) - eventURL = replaceMacro(eventURL, PBSAdUnitIDMacro, "") + createTrackingEvents := false + parent := doc.SelectElement(linearityElement, "TrackingEvents") + if parent == nil { + createTrackingEvents = true + parent = linearityElement //Linear/NonLinearAds + } + + xu.AppendElement(parent, getTrackingEvents(createTrackingEvents, eventURLMap)) + trackersInjected = true } + } - eventURLMap[event] = eventURL + if !trackersInjected { + return vastXML, nil } - return eventURLMap + + //Add CDATA and Expand Inline Nodes + xu.ApplyXMLSettingsOperations() + + var buf bytes.Buffer + xu.Build(&buf) + return buf.String(), nil } -func replaceMacro(trackerURL, macro, value string) string { - macro = strings.TrimSpace(macro) - trimmedValue := strings.TrimSpace(value) +func getTrackingEvents(createTrackingEvents bool, eventURLMap map[string]string) *fastxml.XMLElement { + te := fastxml.CreateElement("") + if createTrackingEvents { + te.SetName("TrackingEvents") + } - if strings.HasPrefix(macro, "[") && strings.HasSuffix(macro, "]") && len(trimmedValue) > 0 { - trackerURL = strings.ReplaceAll(trackerURL, macro, url.QueryEscape(value)) - } else if strings.HasPrefix(macro, "[") && strings.HasSuffix(macro, "]") && len(trimmedValue) == 0 { - trackerURL = strings.ReplaceAll(trackerURL, macro, url.QueryEscape("")) - } else { - glog.Warningf("Invalid macro '%v'. Either empty or missing prefix '[' or suffix ']", macro) + for _, event := range trackingEvents { + if url, ok := eventURLMap[event]; ok { + tracking := fastxml.CreateElement("Tracking").AddAttribute("", "event", event).SetText(url, true, fastxml.NoEscaping) + te.AddChild(tracking) + } } - return trackerURL + return te } -// FindCreatives finds Linear, NonLinearAds fro InLine and Wrapper Type of creatives -// from input doc - VAST Document -// NOTE: This function is temporarily seperated to reuse in ctv_auction.go. Because, in case of ctv -// we generate bid.id func FindCreatives(doc *etree.Document) []*etree.Element { // Find Creatives of Linear and NonLinear Type // Injecting Tracking Events for Companion is not supported here @@ -249,36 +218,3 @@ func FindCreatives(doc *etree.Document) []*etree.Element { creatives = append(creatives, doc.FindElements("VAST/Ad/Wrapper/Creatives/Creative/NonLinearAds")...) return creatives } - -func extractDomain(rawURL string) (string, error) { - if !strings.HasPrefix(rawURL, "http") { - rawURL = "http://" + rawURL - } - // decode rawURL - rawURL, err := url.QueryUnescape(rawURL) - if nil != err { - return "", err - } - url, err := url.Parse(rawURL) - if nil != err { - return "", err - } - // remove www if present - return strings.TrimPrefix(url.Hostname(), "www."), nil -} - -func getDomain(site *openrtb2.Site) string { - if site.Domain != "" { - return site.Domain - } - - hostname := "" - - if site.Page != "" { - pageURL, err := url.Parse(site.Page) - if err == nil && pageURL != nil { - hostname = pageURL.Host - } - } - return hostname -} diff --git a/endpoints/events/vtrack_ow_benchmark_test.go b/endpoints/events/vtrack_ow_benchmark_test.go new file mode 100644 index 00000000000..4761164955f --- /dev/null +++ b/endpoints/events/vtrack_ow_benchmark_test.go @@ -0,0 +1,68 @@ +package events + +import ( + "testing" + + "github.com/prebid/openrtb/v20/adcom1" + "github.com/prebid/openrtb/v20/openrtb2" +) + +var benchMarkVAST, testVAST string +var eventURLMap map[string]string + +func init() { + benchMarkVAST = `LoopMe LTD` + + testVAST = `LoopMe LTD` + eventURLMap = map[string]string{ + "firstQuartile": "http://example.com/tracking/firstQuartile?k1=v1&k2=v2", + "midpoint": "http://example.com/tracking/midpoint", + "thirdQuartile": "http://example.com/tracking/thirdQuartile", + "complete": "http://example.com/tracking/complete", + "start": "http://company.tracker.com?eventId=2&appbundle=abc", + } +} + +func BenchmarkETreeVideoInjector(b *testing.B) { + for i := 0; i < b.N; i++ { + injectVideoEventsETree(benchMarkVAST, eventURLMap, false, adcom1.LinearityLinear) + } +} + +func BenchmarkFastXMLVideoInjector(b *testing.B) { + for i := 0; i < b.N; i++ { + injectVideoEventsFastXML(benchMarkVAST, eventURLMap, false, adcom1.LinearityLinear) + } +} + +// BenchmarkInjectVideoEventTrackers +// nilesh@9fc43242aec1: git checkout origin/ci +// nilesh@9fc43242aec1:~/go/src/github.com/PubMatic-OpenWrap/prebid-server/endpoints/events$ go test -bench=BenchmarkInjectVideoEventTrackers -count 200 -run=^# | tee old1.txt +// nilesh@9fc43242aec1: git checkout origin/UOE-8632-ci-1 +// nilesh@9fc43242aec1:~/go/src/github.com/PubMatic-OpenWrap/prebid-server/endpoints/events$ go test -bench=BenchmarkInjectVideoEventTrackers -count 200 -run=^# | tee new1.txt +// nilesh@9fc43242aec1:~/go/src/github.com/PubMatic-OpenWrap/prebid-server/endpoints/events$ benchstat old1.txt new1.txt +// goos: linux +// goarch: arm64 +// pkg: github.com/PubMatic-OpenWrap/prebid-server/endpoints/events +// +// │ old1.txt │ new1.txt │ +// │ sec/op │ sec/op vs base │ +// +// InjectVideoEventTrackers-8 107.83µ ± 1% 97.62µ ± 1% -9.47% (n=200) +func BenchmarkInjectVideoEventTrackers(b *testing.B) { + trackerURL := "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]" + vastXML := `` + bid := &openrtb2.Bid{ + AdM: ``, + } + req := &openrtb2.BidRequest{ + App: &openrtb2.App{Bundle: "abc"}, + Imp: []openrtb2.Imp{{ID: "123", Video: &openrtb2.Video{}}}, + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + // no need to validate, using vast from test TestInjectVideoEventTrackers/all_inline_wrapper_liner_and_non_linear_creative + _, _, _ = InjectVideoEventTrackers(req, bid, vastXML, trackerURL, "", "test_bidder", "test_core_bidder", int64(0), false) + } +} diff --git a/endpoints/events/vtrack_ow_test.go b/endpoints/events/vtrack_ow_test.go index ac4cbbd06ac..4b7baaf39cd 100644 --- a/endpoints/events/vtrack_ow_test.go +++ b/endpoints/events/vtrack_ow_test.go @@ -1,11 +1,16 @@ package events import ( + "bufio" + "bytes" + "encoding/base64" "fmt" - "net/url" + "os" + "strings" "testing" - "github.com/beevik/etree" + "github.com/PubMatic-OpenWrap/prebid-server/v2/openrtb_ext" + "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" "github.com/stretchr/testify/assert" ) @@ -13,12 +18,15 @@ import ( func TestInjectVideoEventTrackers(t *testing.T) { type args struct { externalURL string + vastXML string genbidID string bid *openrtb2.Bid req *openrtb2.BidRequest } type want struct { - eventURLs map[string][]string + wantVastXml string + wantErr error + metrics *openrtb_ext.FastXMLMetrics } tests := []struct { name string @@ -29,608 +37,466 @@ func TestInjectVideoEventTrackers(t *testing.T) { name: "linear_creative", args: args{ externalURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", + vastXML: `http://example.com/tracking/midpointhttp://example.com/tracking/thirdQuartilehttp://example.com/tracking/completehttp://partner.tracking.url`, bid: &openrtb2.Bid{ - AdM: ` - - - - http://example.com/tracking/midpoint - http://example.com/tracking/thirdQuartile - http://example.com/tracking/complete - http://partner.tracking.url - - - `, - }, - req: &openrtb2.BidRequest{App: &openrtb2.App{Bundle: "abc"}}, + AdM: `http://example.com/tracking/midpointhttp://example.com/tracking/thirdQuartilehttp://example.com/tracking/completehttp://partner.tracking.url`, + }, + req: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{Video: &openrtb2.Video{}}}, + App: &openrtb2.App{Bundle: "abc"}, + }, }, want: want{ - eventURLs: map[string][]string{ - // "firstQuartile": {"http://example.com/tracking/firstQuartile?k1=v1&k2=v2", "http://company.tracker.com?eventId=1004&appbundle=abc"}, - // "midpoint": {"http://example.com/tracking/midpoint", "http://company.tracker.com?eventId=1003&appbundle=abc"}, - // "thirdQuartile": {"http://example.com/tracking/thirdQuartile", "http://company.tracker.com?eventId=1005&appbundle=abc"}, - // "complete": {"http://example.com/tracking/complete", "http://company.tracker.com?eventId=1006&appbundle=abc"}, - "firstQuartile": {"http://example.com/tracking/firstQuartile?k1=v1&k2=v2", "http://company.tracker.com?eventId=4&appbundle=abc"}, - "midpoint": {"http://example.com/tracking/midpoint", "http://company.tracker.com?eventId=3&appbundle=abc"}, - "thirdQuartile": {"http://example.com/tracking/thirdQuartile", "http://company.tracker.com?eventId=5&appbundle=abc"}, - "complete": {"http://example.com/tracking/complete", "http://company.tracker.com?eventId=6&appbundle=abc"}, - "start": {"http://company.tracker.com?eventId=2&appbundle=abc", "http://partner.tracking.url"}, - }, + wantVastXml: ``, + wantErr: nil, + metrics: &openrtb_ext.FastXMLMetrics{IsRespMismatch: false}, }, }, { name: "non_linear_creative", args: args{ externalURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", - bid: &openrtb2.Bid{ // Adm contains to TrackingEvents tag - AdM: ` - - - http://something.com - - - `, + vastXML: `http://something.com`, + bid: &openrtb2.Bid{ + AdM: `http://something.com`, + }, + req: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{Video: &openrtb2.Video{}}}, + App: &openrtb2.App{Bundle: "abc"}, + }, + }, + want: want{ + wantVastXml: ``, + wantErr: nil, + metrics: &openrtb_ext.FastXMLMetrics{IsRespMismatch: false}, + }, + }, + { + name: "all_inline_wrapper_liner_and_non_linear_creative", + args: args{ + externalURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", + vastXML: ``, + bid: &openrtb2.Bid{ + AdM: ``, + }, + req: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{Video: &openrtb2.Video{}}}, + App: &openrtb2.App{Bundle: "abc"}, }, - req: &openrtb2.BidRequest{App: &openrtb2.App{Bundle: "abc"}}, }, want: want{ - eventURLs: map[string][]string{ - // "firstQuartile": {"http://something.com", "http://company.tracker.com?eventId=1004&appbundle=abc"}, - // "midpoint": {"http://company.tracker.com?eventId=1003&appbundle=abc"}, - // "thirdQuartile": {"http://company.tracker.com?eventId=1005&appbundle=abc"}, - // "complete": {"http://company.tracker.com?eventId=1006&appbundle=abc"}, - "firstQuartile": {"http://something.com", "http://company.tracker.com?eventId=4&appbundle=abc"}, - "midpoint": {"http://company.tracker.com?eventId=3&appbundle=abc"}, - "thirdQuartile": {"http://company.tracker.com?eventId=5&appbundle=abc"}, - "complete": {"http://company.tracker.com?eventId=6&appbundle=abc"}, - "start": {"http://company.tracker.com?eventId=2&appbundle=abc"}, - }, - }, - }, { + wantVastXml: ``, + wantErr: nil, + metrics: &openrtb_ext.FastXMLMetrics{IsRespMismatch: false}, + }, + }, + { name: "no_traker_url_configured", // expect no injection args: args{ externalURL: "", - bid: &openrtb2.Bid{ // Adm contains to TrackingEvents tag - AdM: ` - - - `, + vastXML: ``, + bid: &openrtb2.Bid{ + AdM: ``, + }, + req: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{Video: &openrtb2.Video{}}}, + App: &openrtb2.App{Bundle: "abc"}, }, - req: &openrtb2.BidRequest{App: &openrtb2.App{Bundle: "abc"}}, }, want: want{ - eventURLs: map[string][]string{}, + wantVastXml: ``, + wantErr: errEventURLNotConfigured, + metrics: nil, }, }, { name: "wrapper_vast_xml_from_partner", // expect we are injecting trackers inside wrapper args: args{ externalURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", + vastXML: `iabtechlabhttp://somevasturl`, bid: &openrtb2.Bid{ // Adm contains to TrackingEvents tag - AdM: ` - - - iabtechlab - http://somevasturl - - - - - - `, - }, - req: &openrtb2.BidRequest{App: &openrtb2.App{Bundle: "abc"}}, + AdM: `iabtechlabhttp://somevasturl`, + }, + req: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{Video: &openrtb2.Video{}}}, + App: &openrtb2.App{Bundle: "abc"}, + }, }, want: want{ - eventURLs: map[string][]string{ - // "firstQuartile": {"http://company.tracker.com?eventId=firstQuartile&appbundle=abc"}, - // "midpoint": {"http://company.tracker.com?eventId=midpoint&appbundle=abc"}, - // "thirdQuartile": {"http://company.tracker.com?eventId=thirdQuartile&appbundle=abc"}, - // "complete": {"http://company.tracker.com?eventId=complete&appbundle=abc"}, - "firstQuartile": {"http://company.tracker.com?eventId=4&appbundle=abc"}, - "midpoint": {"http://company.tracker.com?eventId=3&appbundle=abc"}, - "thirdQuartile": {"http://company.tracker.com?eventId=5&appbundle=abc"}, - "complete": {"http://company.tracker.com?eventId=6&appbundle=abc"}, - "start": {"http://company.tracker.com?eventId=2&appbundle=abc"}, - }, + wantVastXml: ``, + wantErr: nil, + metrics: &openrtb_ext.FastXMLMetrics{IsRespMismatch: false}, }, }, - // { - // name: "vast_tag_uri_response_from_partner", - // args: args{ - // externalURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", - // bid: &openrtb2.Bid{ // Adm contains to TrackingEvents tag - // AdM: ``, - // }, - // req: &openrtb2.BidRequest{App: &openrtb2.App{Bundle: "abc"}}, - // }, - // want: want{ - // eventURLs: map[string][]string{ - // "firstQuartile": {"http://company.tracker.com?eventId=firstQuartile&appbundle=abc"}, - // "midpoint": {"http://company.tracker.com?eventId=midpoint&appbundle=abc"}, - // "thirdQuartile": {"http://company.tracker.com?eventId=thirdQuartile&appbundle=abc"}, - // "complete": {"http://company.tracker.com?eventId=complete&appbundle=abc"}, - // }, - // }, - // }, - // { - // name: "adm_empty", - // args: args{ - // externalURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", - // bid: &openrtb2.Bid{ // Adm contains to TrackingEvents tag - // AdM: "", - // NURL: "nurl_contents", - // }, - // req: &openrtb2.BidRequest{App: &openrtb2.App{Bundle: "abc"}}, - // }, - // want: want{ - // eventURLs: map[string][]string{ - // "firstQuartile": {"http://company.tracker.com?eventId=firstQuartile&appbundle=abc"}, - // "midpoint": {"http://company.tracker.com?eventId=midpoint&appbundle=abc"}, - // "thirdQuartile": {"http://company.tracker.com?eventId=thirdQuartile&appbundle=abc"}, - // "complete": {"http://company.tracker.com?eventId=complete&appbundle=abc"}, - // }, - // }, - // }, - } - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - vast := "" - if nil != tc.args.bid { - vast = tc.args.bid.AdM // original vast - } - // bind this bid id with imp object - tc.args.req.Imp = []openrtb2.Imp{{ID: "123", Video: &openrtb2.Video{}}} - tc.args.bid.ImpID = tc.args.req.Imp[0].ID - accountID := "" - timestamp := int64(0) - requestingBidder := "test_bidder" - bidderCoreName := "test_core_bidder" - injectedVast, injected, ierr := InjectVideoEventTrackers(tc.args.externalURL, vast, tc.args.bid, tc.args.genbidID, requestingBidder, bidderCoreName, accountID, timestamp, tc.args.req) - - if !injected { - // expect no change in input vast if tracking events are not injected - assert.Equal(t, vast, string(injectedVast)) - assert.NotNil(t, ierr) - } else { - assert.Nil(t, ierr) - } - actualVastDoc := etree.NewDocument() - - err := actualVastDoc.ReadFromBytes(injectedVast) - if nil != err { - assert.Fail(t, err.Error()) - } - - // fmt.Println(string(injectedVast)) - actualTrackingEvents := actualVastDoc.FindElements("VAST/Ad/InLine/Creatives/Creative/Linear/TrackingEvents/Tracking") - actualTrackingEvents = append(actualTrackingEvents, actualVastDoc.FindElements("VAST/Ad/InLine/Creatives/Creative/NonLinearAds/TrackingEvents/Tracking")...) - actualTrackingEvents = append(actualTrackingEvents, actualVastDoc.FindElements("VAST/Ad/Wrapper/Creatives/Creative/Linear/TrackingEvents/Tracking")...) - actualTrackingEvents = append(actualTrackingEvents, actualVastDoc.FindElements("VAST/Ad/Wrapper/Creatives/Creative/NonLinearAds/TrackingEvents/Tracking")...) - - totalURLCount := 0 - for event, URLs := range tc.want.eventURLs { - - for _, expectedURL := range URLs { - present := false - for _, te := range actualTrackingEvents { - if te.SelectAttr("event").Value == event && te.Text() == expectedURL { - present = true - totalURLCount++ - break // expected URL present. check for next expected URL - } - } - if !present { - assert.Fail(t, "Expected tracker URL '"+expectedURL+"' is not present") - } - } - } - // ensure all total of events are injected - assert.Equal(t, totalURLCount, len(actualTrackingEvents), fmt.Sprintf("Expected '%v' event trackers. But found '%v'", len(tc.want.eventURLs), len(actualTrackingEvents))) - - }) - } -} - -func TestGetVideoEventTracking(t *testing.T) { - type args struct { - trackerURL string - bid *openrtb2.Bid - requestingBidder string - gen_bidid string - bidderCoreName string - accountId string - timestamp int64 - req *openrtb2.BidRequest - doc *etree.Document - } - type want struct { - trackerURLMap map[string]string - } - tests := []struct { - name string - args args - want want - }{ { - name: "valid_scenario", + name: "vast_tag_uri_response_from_partner", args: args{ - trackerURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", - bid: &openrtb2.Bid{ - // AdM: vastXMLWith2Creatives, + externalURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", + vastXML: ``, + bid: &openrtb2.Bid{ + AdM: ``, }, req: &openrtb2.BidRequest{ - App: &openrtb2.App{ - Bundle: "someappbundle", - }, - Imp: []openrtb2.Imp{}, + Imp: []openrtb2.Imp{{Video: &openrtb2.Video{}}}, + App: &openrtb2.App{Bundle: "abc"}, }, }, want: want{ - trackerURLMap: map[string]string{ - // "firstQuartile": "http://company.tracker.com?eventId=firstQuartile&appbundle=someappbundle", - // "midpoint": "http://company.tracker.com?eventId=midpoint&appbundle=someappbundle", - // "thirdQuartile": "http://company.tracker.com?eventId=thirdQuartile&appbundle=someappbundle", - // "complete": "http://company.tracker.com?eventId=complete&appbundle=someappbundle"}, - "firstQuartile": "http://company.tracker.com?eventId=4&appbundle=someappbundle", - "midpoint": "http://company.tracker.com?eventId=3&appbundle=someappbundle", - "thirdQuartile": "http://company.tracker.com?eventId=5&appbundle=someappbundle", - "start": "http://company.tracker.com?eventId=2&appbundle=someappbundle", - "complete": "http://company.tracker.com?eventId=6&appbundle=someappbundle"}, + wantVastXml: ``, + wantErr: nil, + metrics: &openrtb_ext.FastXMLMetrics{IsRespMismatch: false}, }, }, { - name: "no_macro_value", // expect no replacement + name: "adm_empty_with_vast_build_from_modifyBidVAST", args: args{ - trackerURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", - bid: &openrtb2.Bid{}, + externalURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", + vastXML: `prebid.org wrapper`, + bid: &openrtb2.Bid{ + ImpID: "123", + AdM: "", + NURL: "nurl_contents", + }, req: &openrtb2.BidRequest{ - App: &openrtb2.App{}, // no app bundle value - Imp: []openrtb2.Imp{}, + Imp: []openrtb2.Imp{{ID: "123", Video: &openrtb2.Video{}}}, + App: &openrtb2.App{Bundle: "abc"}, }, }, want: want{ - trackerURLMap: map[string]string{ - // "firstQuartile": "http://company.tracker.com?eventId=firstQuartile&appbundle=[DOMAIN]", - // "midpoint": "http://company.tracker.com?eventId=midpoint&appbundle=[DOMAIN]", - // "thirdQuartile": "http://company.tracker.com?eventId=thirdQuartile&appbundle=[DOMAIN]", - // "complete": "http://company.tracker.com?eventId=complete&appbundle=[DOMAIN]"}, - "firstQuartile": "http://company.tracker.com?eventId=4&appbundle=", - "midpoint": "http://company.tracker.com?eventId=3&appbundle=", - "thirdQuartile": "http://company.tracker.com?eventId=5&appbundle=", - "start": "http://company.tracker.com?eventId=2&appbundle=", - "complete": "http://company.tracker.com?eventId=6&appbundle="}, + wantVastXml: ``, + wantErr: nil, + metrics: &openrtb_ext.FastXMLMetrics{IsRespMismatch: false}, }, }, { - name: "prefer_company_value_for_standard_macro", + name: "adm_empty_with_vast_build_from_modifyBidVAST_non_video", args: args{ - trackerURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", + externalURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", + vastXML: `prebid.org wrapper`, + bid: &openrtb2.Bid{ + ImpID: "123", + AdM: "", + NURL: "nurl_contents", + }, req: &openrtb2.BidRequest{ - App: &openrtb2.App{ - Bundle: "myapp", // do not expect this value - }, - Imp: []openrtb2.Imp{}, - Ext: []byte(`{"prebid":{ - "macros": { - "[DOMAIN]": "my_custom_value" - } - }}`), + Imp: []openrtb2.Imp{{ID: "123", Video: &openrtb2.Video{}}}, + App: &openrtb2.App{Bundle: "abc"}, }, }, want: want{ - trackerURLMap: map[string]string{ - // "firstQuartile": "http://company.tracker.com?eventId=firstQuartile&appbundle=my_custom_value", - // "midpoint": "http://company.tracker.com?eventId=midpoint&appbundle=my_custom_value", - // "thirdQuartile": "http://company.tracker.com?eventId=thirdQuartile&appbundle=my_custom_value", - // "complete": "http://company.tracker.com?eventId=complete&appbundle=my_custom_value"}, - "firstQuartile": "http://company.tracker.com?eventId=4&appbundle=my_custom_value", - "midpoint": "http://company.tracker.com?eventId=3&appbundle=my_custom_value", - "thirdQuartile": "http://company.tracker.com?eventId=5&appbundle=my_custom_value", - "start": "http://company.tracker.com?eventId=2&appbundle=my_custom_value", - "complete": "http://company.tracker.com?eventId=6&appbundle=my_custom_value"}, - }, - }, { - name: "multireplace_macro", + wantVastXml: ``, + wantErr: nil, + metrics: &openrtb_ext.FastXMLMetrics{IsRespMismatch: false}, + }, + }, + { + name: "vast_without_creative_tracking_node.Only_till_xpath_VAST/Ad/Wrapper/Creatives", args: args{ - trackerURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]¶meter2=[DOMAIN]", + externalURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", + vastXML: `prebid.org wrapper`, + bid: &openrtb2.Bid{ + ImpID: "123", + AdM: `prebid.org wrapper`, + NURL: "nurl_contents", + }, req: &openrtb2.BidRequest{ - App: &openrtb2.App{ - Bundle: "myapp123", - }, - Imp: []openrtb2.Imp{}, + Imp: []openrtb2.Imp{{ID: "123", Video: &openrtb2.Video{}}}, + App: &openrtb2.App{Bundle: "abc"}, }, }, want: want{ - trackerURLMap: map[string]string{ - // "firstQuartile": "http://company.tracker.com?eventId=firstQuartile&appbundle=myapp123¶meter2=myapp123", - // "midpoint": "http://company.tracker.com?eventId=midpoint&appbundle=myapp123¶meter2=myapp123", - // "thirdQuartile": "http://company.tracker.com?eventId=thirdQuartile&appbundle=myapp123¶meter2=myapp123", - // "complete": "http://company.tracker.com?eventId=complete&appbundle=myapp123¶meter2=myapp123"}, - "firstQuartile": "http://company.tracker.com?eventId=4&appbundle=myapp123¶meter2=myapp123", - "midpoint": "http://company.tracker.com?eventId=3&appbundle=myapp123¶meter2=myapp123", - "thirdQuartile": "http://company.tracker.com?eventId=5&appbundle=myapp123¶meter2=myapp123", - "start": "http://company.tracker.com?eventId=2&appbundle=myapp123¶meter2=myapp123", - "complete": "http://company.tracker.com?eventId=6&appbundle=myapp123¶meter2=myapp123"}, + wantVastXml: `prebid.org wrapper`, + wantErr: nil, + metrics: &openrtb_ext.FastXMLMetrics{IsRespMismatch: false}, }, }, { - name: "custom_macro_without_prefix_and_suffix", + name: "vast_without_linear_node.Only_till_xpath_VAST/Ad/Wrapper/Creatives/Creative", args: args{ - trackerURL: "http://company.tracker.com?eventId=[EVENT_ID]¶m1=[CUSTOM_MACRO]", + externalURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", + vastXML: `prebid.org wrapper`, + bid: &openrtb2.Bid{ + ImpID: "123", + AdM: `prebid.org wrapper`, + NURL: "nurl_contents", + }, req: &openrtb2.BidRequest{ - Ext: []byte(`{"prebid":{ - "macros": { - "CUSTOM_MACRO": "my_custom_value" - } - }}`), - Imp: []openrtb2.Imp{}, + Imp: []openrtb2.Imp{{ID: "123", Video: &openrtb2.Video{}}}, + App: &openrtb2.App{Bundle: "abc"}, }, }, want: want{ - trackerURLMap: map[string]string{ - // "firstQuartile": "http://company.tracker.com?eventId=firstQuartile¶m1=[CUSTOM_MACRO]", - // "midpoint": "http://company.tracker.com?eventId=midpoint¶m1=[CUSTOM_MACRO]", - // "thirdQuartile": "http://company.tracker.com?eventId=thirdQuartile¶m1=[CUSTOM_MACRO]", - // "complete": "http://company.tracker.com?eventId=complete¶m1=[CUSTOM_MACRO]"}, - "firstQuartile": "http://company.tracker.com?eventId=4¶m1=[CUSTOM_MACRO]", - "midpoint": "http://company.tracker.com?eventId=3¶m1=[CUSTOM_MACRO]", - "thirdQuartile": "http://company.tracker.com?eventId=5¶m1=[CUSTOM_MACRO]", - "start": "http://company.tracker.com?eventId=2¶m1=[CUSTOM_MACRO]", - "complete": "http://company.tracker.com?eventId=6¶m1=[CUSTOM_MACRO]"}, + wantVastXml: `prebid.org wrapper`, + wantErr: nil, + metrics: &openrtb_ext.FastXMLMetrics{IsRespMismatch: false}, }, }, { - name: "empty_macro", + name: "vast_without_tracking_node.Only_till_xpath_VAST/Ad/Wrapper/Creatives/Creative/Linear", args: args{ - trackerURL: "http://company.tracker.com?eventId=[EVENT_ID]¶m1=[CUSTOM_MACRO]", + externalURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", + vastXML: `prebid.org wrapper`, + bid: &openrtb2.Bid{ + ImpID: "123", + AdM: `prebid.org wrapper`, + NURL: "nurl_contents", + }, req: &openrtb2.BidRequest{ - Ext: []byte(`{"prebid":{ - "macros": { - "": "my_custom_value" - } - }}`), - Imp: []openrtb2.Imp{}, + Imp: []openrtb2.Imp{{ID: "123", Video: &openrtb2.Video{}}}, + App: &openrtb2.App{Bundle: "abc"}, }, }, want: want{ - trackerURLMap: map[string]string{ - // "firstQuartile": "http://company.tracker.com?eventId=firstQuartile¶m1=[CUSTOM_MACRO]", - // "midpoint": "http://company.tracker.com?eventId=midpoint¶m1=[CUSTOM_MACRO]", - // "thirdQuartile": "http://company.tracker.com?eventId=thirdQuartile¶m1=[CUSTOM_MACRO]", - // "complete": "http://company.tracker.com?eventId=complete¶m1=[CUSTOM_MACRO]"}, - "firstQuartile": "http://company.tracker.com?eventId=4¶m1=[CUSTOM_MACRO]", - "midpoint": "http://company.tracker.com?eventId=3¶m1=[CUSTOM_MACRO]", - "thirdQuartile": "http://company.tracker.com?eventId=5¶m1=[CUSTOM_MACRO]", - "start": "http://company.tracker.com?eventId=2¶m1=[CUSTOM_MACRO]", - "complete": "http://company.tracker.com?eventId=6¶m1=[CUSTOM_MACRO]"}, + wantVastXml: ``, + wantErr: nil, + metrics: &openrtb_ext.FastXMLMetrics{IsRespMismatch: false}, }, }, { - name: "macro_is_case_sensitive", + name: "vast_without_tracking_node.Only_till_xpath_VAST/Ad/Wrapper/Creatives/Creative/NonLinear", args: args{ - trackerURL: "http://company.tracker.com?eventId=[EVENT_ID]¶m1=[CUSTOM_MACRO]", + externalURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", + vastXML: `prebid.org wrapper`, + bid: &openrtb2.Bid{ + ImpID: "123", + AdM: `prebid.org wrapper`, + NURL: "nurl_contents", + }, req: &openrtb2.BidRequest{ - Ext: []byte(`{"prebid":{ - "macros": { - "": "my_custom_value" - } - }}`), - Imp: []openrtb2.Imp{}, + Imp: []openrtb2.Imp{{ID: "123", Video: &openrtb2.Video{}}}, + App: &openrtb2.App{Bundle: "abc"}, }, }, want: want{ - trackerURLMap: map[string]string{ - // "firstQuartile": "http://company.tracker.com?eventId=firstQuartile¶m1=[CUSTOM_MACRO]", - // "midpoint": "http://company.tracker.com?eventId=midpoint¶m1=[CUSTOM_MACRO]", - // "thirdQuartile": "http://company.tracker.com?eventId=thirdQuartile¶m1=[CUSTOM_MACRO]", - // "complete": "http://company.tracker.com?eventId=complete¶m1=[CUSTOM_MACRO]"}, - "firstQuartile": "http://company.tracker.com?eventId=4¶m1=[CUSTOM_MACRO]", - "midpoint": "http://company.tracker.com?eventId=3¶m1=[CUSTOM_MACRO]", - "thirdQuartile": "http://company.tracker.com?eventId=5¶m1=[CUSTOM_MACRO]", - "start": "http://company.tracker.com?eventId=2¶m1=[CUSTOM_MACRO]", - "complete": "http://company.tracker.com?eventId=6¶m1=[CUSTOM_MACRO]"}, + wantVastXml: ``, + wantErr: nil, + metrics: &openrtb_ext.FastXMLMetrics{IsRespMismatch: false}, }, }, { - name: "empty_tracker_url", - args: args{trackerURL: " ", req: &openrtb2.BidRequest{Imp: []openrtb2.Imp{}}}, - want: want{trackerURLMap: make(map[string]string)}, + name: "vast_without_creative_tracking_node.Only_till_xpath_VAST/Ad/InLine/Creatives", + args: args{ + externalURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", + vastXML: `prebid.org wrapper`, + bid: &openrtb2.Bid{ + ImpID: "123", + AdM: `prebid.org wrapper`, + NURL: "nurl_contents", + }, + req: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{ID: "123", Video: &openrtb2.Video{}}}, + App: &openrtb2.App{Bundle: "abc"}, + }, + }, + want: want{ + wantVastXml: `prebid.org wrapper`, + wantErr: nil, + metrics: &openrtb_ext.FastXMLMetrics{IsRespMismatch: false}, + }, }, { - name: "site_domain_tracker_url", - args: args{trackerURL: "https://company.tracker.com?operId=8&e=[EVENT_ID]&p=[PBS-ACCOUNT]&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=[PBS-BIDDER]&advertiser_id=[ADVERTISER_NAME]&sURL=[DOMAIN]&pfi=[PLATFORM]&af=[ADTYPE]&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=[AD_UNIT]&bidid=[PBS-BIDID]", - req: &openrtb2.BidRequest{Site: &openrtb2.Site{Name: "test", Domain: "www.test.com", Publisher: &openrtb2.Publisher{ID: "5890"}}, Imp: []openrtb2.Imp{}}}, - want: want{ - map[string]string{ - "complete": "https://company.tracker.com?operId=8&e=6&p=5890&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=&advertiser_id=&sURL=www.test.com&pfi=[PLATFORM]&af=video&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=&bidid=", - "firstQuartile": "https://company.tracker.com?operId=8&e=4&p=5890&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=&advertiser_id=&sURL=www.test.com&pfi=[PLATFORM]&af=video&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=&bidid=", - "midpoint": "https://company.tracker.com?operId=8&e=3&p=5890&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=&advertiser_id=&sURL=www.test.com&pfi=[PLATFORM]&af=video&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=&bidid=", - "start": "https://company.tracker.com?operId=8&e=2&p=5890&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=&advertiser_id=&sURL=www.test.com&pfi=[PLATFORM]&af=video&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=&bidid=", - "thirdQuartile": "https://company.tracker.com?operId=8&e=5&p=5890&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=&advertiser_id=&sURL=www.test.com&pfi=[PLATFORM]&af=video&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=&bidid=", + name: "vast_without_linear_node.Only_till_xpath_VAST/Ad/InLine/Creatives/Creative", + args: args{ + externalURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", + vastXML: `prebid.org wrapper`, + bid: &openrtb2.Bid{ + ImpID: "123", + AdM: `prebid.org wrapper`, + NURL: "nurl_contents", + }, + req: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{ID: "123", Video: &openrtb2.Video{}}}, + App: &openrtb2.App{Bundle: "abc"}, }, }, + want: want{ + wantVastXml: `prebid.org wrapper`, + wantErr: nil, + metrics: &openrtb_ext.FastXMLMetrics{IsRespMismatch: false}, + }, }, { - name: "site_page_tracker_url", - args: args{trackerURL: "https://company.tracker.com?operId=8&e=[EVENT_ID]&p=[PBS-ACCOUNT]&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=[PBS-BIDDER]&advertiser_id=[ADVERTISER_NAME]&sURL=[DOMAIN]&pfi=[PLATFORM]&af=[ADTYPE]&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=[AD_UNIT]&bidid=[PBS-BIDID]", - req: &openrtb2.BidRequest{Site: &openrtb2.Site{Name: "test", Page: "https://www.test.com/", Publisher: &openrtb2.Publisher{ID: "5890"}}, Imp: []openrtb2.Imp{}}}, + name: "vast_without_tracking_node.Only_till_xpath_VAST/Ad/InLine/Creatives/Creative/Linear", + args: args{ + externalURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", + vastXML: `prebid.org wrapper`, + bid: &openrtb2.Bid{ + ImpID: "123", + AdM: `prebid.org wrapper`, + NURL: "nurl_contents", + }, + req: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{ID: "123", Video: &openrtb2.Video{}}}, + App: &openrtb2.App{Bundle: "abc"}, + }, + }, want: want{ - map[string]string{ - "complete": "https://company.tracker.com?operId=8&e=6&p=5890&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=&advertiser_id=&sURL=www.test.com&pfi=[PLATFORM]&af=video&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=&bidid=", - "firstQuartile": "https://company.tracker.com?operId=8&e=4&p=5890&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=&advertiser_id=&sURL=www.test.com&pfi=[PLATFORM]&af=video&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=&bidid=", - "midpoint": "https://company.tracker.com?operId=8&e=3&p=5890&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=&advertiser_id=&sURL=www.test.com&pfi=[PLATFORM]&af=video&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=&bidid=", - "start": "https://company.tracker.com?operId=8&e=2&p=5890&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=&advertiser_id=&sURL=www.test.com&pfi=[PLATFORM]&af=video&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=&bidid=", - "thirdQuartile": "https://company.tracker.com?operId=8&e=5&p=5890&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=&advertiser_id=&sURL=www.test.com&pfi=[PLATFORM]&af=video&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=&bidid=", + wantVastXml: ``, + wantErr: nil, + metrics: &openrtb_ext.FastXMLMetrics{IsRespMismatch: false}, + }, + }, + { + name: "vast_without_tracking_node.Only_till_xpath_VAST/Ad/InLine/Creatives/Creative/NonLinear", + args: args{ + externalURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", + vastXML: `prebid.org wrapper`, + bid: &openrtb2.Bid{ + ImpID: "123", + AdM: `prebid.org wrapper`, + NURL: "nurl_contents", }, + req: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{ID: "123", Video: &openrtb2.Video{}}}, + App: &openrtb2.App{Bundle: "abc"}, + }, + }, + want: want{ + wantVastXml: ``, + wantErr: nil, + metrics: &openrtb_ext.FastXMLMetrics{IsRespMismatch: false}, }, }, { - name: "all_macros with generated_bidId", // expect encoding for WRAPPER_IMPRESSION_ID macro + name: "vast_without_tracking_node_and_multiple_creative.All_4_xpath_Wrapper_InLine_Linear_NonLinear", args: args{ - trackerURL: "https://company.tracker.com?operId=8&e=[EVENT_ID]&p=[PBS-ACCOUNT]&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=[PBS-BIDDER]&advertiser_id=[ADVERTISER_NAME]&sURL=[DOMAIN]&pfi=[PLATFORM]&af=[ADTYPE]&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=[AD_UNIT]&bidid=[PBS-BIDID]&origbidid=[PBS-ORIG_BIDID]&bc=[BIDDER_CODE]", + externalURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", + vastXML: `prebid.org wrapperprebid.org wrapper`, + bid: &openrtb2.Bid{ + ImpID: "123", + AdM: `prebid.org wrapperprebid.org wrapper`, + NURL: "nurl_contents", + }, req: &openrtb2.BidRequest{ - App: &openrtb2.App{Bundle: "com.someapp.com", Publisher: &openrtb2.Publisher{ID: "5890"}}, - Ext: []byte(`{ - "prebid": { - "macros": { - "[PROFILE_ID]": "100", - "[PROFILE_VERSION]": "2", - "[UNIX_TIMESTAMP]": "1234567890", - "[PLATFORM]": "7", - "[WRAPPER_IMPRESSION_ID]": "abc~!@#$%^&&*()_+{}|:\"<>?[]\\;',./" - } - } - }`), - Imp: []openrtb2.Imp{ - {TagID: "/testadunit/1", ID: "imp_1"}, - }, - }, - bid: &openrtb2.Bid{ADomain: []string{"http://a.com/32?k=v", "b.com"}, ImpID: "imp_1", ID: "test_bid_id"}, - gen_bidid: "random_bid_id", - requestingBidder: "test_bidder:234", - bidderCoreName: "test_core_bidder:234", + Imp: []openrtb2.Imp{{ID: "123", Video: &openrtb2.Video{}}}, + App: &openrtb2.App{Bundle: "abc"}, + }, }, want: want{ - trackerURLMap: map[string]string{ - "firstQuartile": "https://company.tracker.com?operId=8&e=4&p=5890&pid=100&v=2&ts=1234567890&pn=test_core_bidder%3A234&advertiser_id=a.com&sURL=com.someapp.com&pfi=7&af=video&iid=abc~%21%40%23%24%25%5E%26%26%2A%28%29_%2B%7B%7D%7C%3A%22%3C%3E%3F%5B%5D%5C%3B%27%2C.%2F&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=%2Ftestadunit%2F1&bidid=random_bid_id&origbidid=test_bid_id&bc=test_bidder%3A234", - "midpoint": "https://company.tracker.com?operId=8&e=3&p=5890&pid=100&v=2&ts=1234567890&pn=test_core_bidder%3A234&advertiser_id=a.com&sURL=com.someapp.com&pfi=7&af=video&iid=abc~%21%40%23%24%25%5E%26%26%2A%28%29_%2B%7B%7D%7C%3A%22%3C%3E%3F%5B%5D%5C%3B%27%2C.%2F&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=%2Ftestadunit%2F1&bidid=random_bid_id&origbidid=test_bid_id&bc=test_bidder%3A234", - "thirdQuartile": "https://company.tracker.com?operId=8&e=5&p=5890&pid=100&v=2&ts=1234567890&pn=test_core_bidder%3A234&advertiser_id=a.com&sURL=com.someapp.com&pfi=7&af=video&iid=abc~%21%40%23%24%25%5E%26%26%2A%28%29_%2B%7B%7D%7C%3A%22%3C%3E%3F%5B%5D%5C%3B%27%2C.%2F&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=%2Ftestadunit%2F1&bidid=random_bid_id&origbidid=test_bid_id&bc=test_bidder%3A234", - "complete": "https://company.tracker.com?operId=8&e=6&p=5890&pid=100&v=2&ts=1234567890&pn=test_core_bidder%3A234&advertiser_id=a.com&sURL=com.someapp.com&pfi=7&af=video&iid=abc~%21%40%23%24%25%5E%26%26%2A%28%29_%2B%7B%7D%7C%3A%22%3C%3E%3F%5B%5D%5C%3B%27%2C.%2F&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=%2Ftestadunit%2F1&bidid=random_bid_id&origbidid=test_bid_id&bc=test_bidder%3A234", - "start": "https://company.tracker.com?operId=8&e=2&p=5890&pid=100&v=2&ts=1234567890&pn=test_core_bidder%3A234&advertiser_id=a.com&sURL=com.someapp.com&pfi=7&af=video&iid=abc~%21%40%23%24%25%5E%26%26%2A%28%29_%2B%7B%7D%7C%3A%22%3C%3E%3F%5B%5D%5C%3B%27%2C.%2F&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=%2Ftestadunit%2F1&bidid=random_bid_id&origbidid=test_bid_id&bc=test_bidder%3A234"}, + wantVastXml: ``, + wantErr: nil, + metrics: &openrtb_ext.FastXMLMetrics{IsRespMismatch: false}, }, }, { - name: "all_macros with empty generated_bidId", // expect encoding for WRAPPER_IMPRESSION_ID macro + name: "vast_with_tracking_node_and_multiple_creative.All_4_xpath_Wrapper_InLine_Linear_NonLinear", args: args{ - trackerURL: "https://company.tracker.com?operId=8&e=[EVENT_ID]&p=[PBS-ACCOUNT]&pid=[PROFILE_ID]&v=[PROFILE_VERSION]&ts=[UNIX_TIMESTAMP]&pn=[PBS-BIDDER]&advertiser_id=[ADVERTISER_NAME]&sURL=[DOMAIN]&pfi=[PLATFORM]&af=[ADTYPE]&iid=[WRAPPER_IMPRESSION_ID]&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=[AD_UNIT]&bidid=[PBS-BIDID]&origbidid=[PBS-ORIG_BIDID]&bc=[BIDDER_CODE]", + externalURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", + vastXML: `prebid.org wrapperprebid.org wrapper`, + bid: &openrtb2.Bid{ + ImpID: "123", + AdM: `prebid.org wrapperprebid.org wrapper`, + NURL: "nurl_contents", + }, req: &openrtb2.BidRequest{ - App: &openrtb2.App{Bundle: "com.someapp.com", Publisher: &openrtb2.Publisher{ID: "5890"}}, - Ext: []byte(`{ - "prebid": { - "macros": { - "[PROFILE_ID]": "100", - "[PROFILE_VERSION]": "2", - "[UNIX_TIMESTAMP]": "1234567890", - "[PLATFORM]": "7", - "[WRAPPER_IMPRESSION_ID]": "abc~!@#$%^&&*()_+{}|:\"<>?[]\\;',./" - } - } - }`), - Imp: []openrtb2.Imp{ - {TagID: "/testadunit/1", ID: "imp_1"}, - }, - }, - bid: &openrtb2.Bid{ADomain: []string{"http://a.com/32?k=v", "b.com"}, ImpID: "imp_1", ID: "test_bid_id"}, - gen_bidid: "", - requestingBidder: "test_bidder:234", - bidderCoreName: "test_core_bidder:234", + Imp: []openrtb2.Imp{{ID: "123", Video: &openrtb2.Video{}}}, + App: &openrtb2.App{Bundle: "abc"}, + }, }, want: want{ - trackerURLMap: map[string]string{ - "firstQuartile": "https://company.tracker.com?operId=8&e=4&p=5890&pid=100&v=2&ts=1234567890&pn=test_core_bidder%3A234&advertiser_id=a.com&sURL=com.someapp.com&pfi=7&af=video&iid=abc~%21%40%23%24%25%5E%26%26%2A%28%29_%2B%7B%7D%7C%3A%22%3C%3E%3F%5B%5D%5C%3B%27%2C.%2F&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=%2Ftestadunit%2F1&bidid=test_bid_id&origbidid=test_bid_id&bc=test_bidder%3A234", - "midpoint": "https://company.tracker.com?operId=8&e=3&p=5890&pid=100&v=2&ts=1234567890&pn=test_core_bidder%3A234&advertiser_id=a.com&sURL=com.someapp.com&pfi=7&af=video&iid=abc~%21%40%23%24%25%5E%26%26%2A%28%29_%2B%7B%7D%7C%3A%22%3C%3E%3F%5B%5D%5C%3B%27%2C.%2F&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=%2Ftestadunit%2F1&bidid=test_bid_id&origbidid=test_bid_id&bc=test_bidder%3A234", - "thirdQuartile": "https://company.tracker.com?operId=8&e=5&p=5890&pid=100&v=2&ts=1234567890&pn=test_core_bidder%3A234&advertiser_id=a.com&sURL=com.someapp.com&pfi=7&af=video&iid=abc~%21%40%23%24%25%5E%26%26%2A%28%29_%2B%7B%7D%7C%3A%22%3C%3E%3F%5B%5D%5C%3B%27%2C.%2F&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=%2Ftestadunit%2F1&bidid=test_bid_id&origbidid=test_bid_id&bc=test_bidder%3A234", - "complete": "https://company.tracker.com?operId=8&e=6&p=5890&pid=100&v=2&ts=1234567890&pn=test_core_bidder%3A234&advertiser_id=a.com&sURL=com.someapp.com&pfi=7&af=video&iid=abc~%21%40%23%24%25%5E%26%26%2A%28%29_%2B%7B%7D%7C%3A%22%3C%3E%3F%5B%5D%5C%3B%27%2C.%2F&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=%2Ftestadunit%2F1&bidid=test_bid_id&origbidid=test_bid_id&bc=test_bidder%3A234", - "start": "https://company.tracker.com?operId=8&e=2&p=5890&pid=100&v=2&ts=1234567890&pn=test_core_bidder%3A234&advertiser_id=a.com&sURL=com.someapp.com&pfi=7&af=video&iid=abc~%21%40%23%24%25%5E%26%26%2A%28%29_%2B%7B%7D%7C%3A%22%3C%3E%3F%5B%5D%5C%3B%27%2C.%2F&pseq=[PODSEQUENCE]&adcnt=[ADCOUNT]&cb=[CACHEBUSTING]&au=%2Ftestadunit%2F1&bidid=test_bid_id&origbidid=test_bid_id&bc=test_bidder%3A234"}, + wantVastXml: ``, + wantErr: nil, + metrics: &openrtb_ext.FastXMLMetrics{IsRespMismatch: false}, }, }, + // { + // name: "vast_and_adm_empty - This should never be the case as modifyBidVAST always updates AdM with tempate vast", + // args: args{ + // externalURL: "http://company.tracker.com?eventId=[EVENT_ID]&appbundle=[DOMAIN]", + // vastXML: "", + // bid: &openrtb2.Bid{ // Adm contains to TrackingEvents tag + // AdM: "", + // NURL: "nurl_contents", + // }, + // req: &openrtb2.BidRequest{App: &openrtb2.App{Bundle: "abc"}}, + // }, + // want : want{ + // wantVastXml: "", + // wantErr: errors.New("error parsing VAST XML. 'EOF'"), + // metrics: &openrtb_ext.FastXMLMetrics{IsRespMismatch: false}, + // }, + // }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - - if nil == tc.args.bid { - tc.args.bid = &openrtb2.Bid{} + injectedVast, metrics, err := InjectVideoEventTrackers(tc.args.req, tc.args.bid, tc.args.vastXML, tc.args.externalURL, tc.args.genbidID, "test_bidder", "test_core_bidder", int64(0), true) + assert.Equal(t, tc.want.wantErr, err) + assert.Equal(t, tc.want.wantVastXml, string(injectedVast)) + if tc.want.metrics != nil { + assert.NotNil(t, metrics) + assert.Equal(t, tc.want.metrics.IsRespMismatch, metrics.IsRespMismatch) } + }) + } +} - impMap := map[string]*openrtb2.Imp{} - - for _, imp := range tc.args.req.Imp { - impMap[imp.ID] = &imp - } - - eventURLMap := GetVideoEventTracking(tc.args.trackerURL, tc.args.bid, tc.args.gen_bidid, tc.args.requestingBidder, tc.args.bidderCoreName, tc.args.accountId, tc.args.timestamp, tc.args.req, tc.args.doc, impMap) - - for event, eurl := range tc.want.trackerURLMap { - - u, _ := url.Parse(eurl) - expectedValues, _ := url.ParseQuery(u.RawQuery) - u, _ = url.Parse(eventURLMap[event]) - actualValues, _ := url.ParseQuery(u.RawQuery) - for k, ev := range expectedValues { - av := actualValues[k] - for i := 0; i < len(ev); i++ { - assert.Equal(t, ev[i], av[i], fmt.Sprintf("Expected '%v' for '%v'. but found %v", ev[i], k, av[i])) - } - } - - // error out if extra query params - if len(expectedValues) != len(actualValues) { - assert.Equal(t, expectedValues, actualValues, fmt.Sprintf("Expected '%v' query params but found '%v'", len(expectedValues), len(actualValues))) - break +func quoteUnescape[T []byte | string](s T) string { + buf := bytes.Buffer{} + for i := 0; i < len(s); i++ { + ch := s[i] + if ch == '\\' { + if i+1 < len(s) { + nextCh := s[i+1] + if nextCh == '\\' || nextCh == '"' || nextCh == '\'' { + i++ + ch = nextCh } } - - // check if new quartile pixels are covered inside test - assert.Equal(t, tc.want.trackerURLMap, eventURLMap) - }) + } + buf.WriteByte(ch) } + return buf.String() } -func TestReplaceMacro(t *testing.T) { - type args struct { - trackerURL string - macro string - value string - } - type want struct { - trackerURL string - } - tests := []struct { - name string - args args - want want - }{ - {name: "empty_tracker_url", args: args{trackerURL: "", macro: "[TEST]", value: "testme"}, want: want{trackerURL: ""}}, - {name: "tracker_url_with_macro", args: args{trackerURL: "http://something.com?test=[TEST]", macro: "[TEST]", value: "testme"}, want: want{trackerURL: "http://something.com?test=testme"}}, - {name: "tracker_url_with_invalid_macro", args: args{trackerURL: "http://something.com?test=TEST]", macro: "[TEST]", value: "testme"}, want: want{trackerURL: "http://something.com?test=TEST]"}}, - {name: "tracker_url_with_repeating_macro", args: args{trackerURL: "http://something.com?test=[TEST]&test1=[TEST]", macro: "[TEST]", value: "testme"}, want: want{trackerURL: "http://something.com?test=testme&test1=testme"}}, - {name: "empty_macro", args: args{trackerURL: "http://something.com?test=[TEST]", macro: "", value: "testme"}, want: want{trackerURL: "http://something.com?test=[TEST]"}}, - {name: "macro_without_[", args: args{trackerURL: "http://something.com?test=[TEST]", macro: "TEST]", value: "testme"}, want: want{trackerURL: "http://something.com?test=[TEST]"}}, - {name: "macro_without_]", args: args{trackerURL: "http://something.com?test=[TEST]", macro: "[TEST", value: "testme"}, want: want{trackerURL: "http://something.com?test=[TEST]"}}, - {name: "empty_value", args: args{trackerURL: "http://something.com?test=[TEST]", macro: "[TEST]", value: ""}, want: want{trackerURL: "http://something.com?test="}}, - {name: "nested_macro_value", args: args{trackerURL: "http://something.com?test=[TEST]", macro: "[TEST]", value: "[TEST][TEST]"}, want: want{trackerURL: "http://something.com?test=%5BTEST%5D%5BTEST%5D"}}, - {name: "url_as_macro_value", args: args{trackerURL: "http://something.com?test=[TEST]", macro: "[TEST]", value: "http://iamurl.com"}, want: want{trackerURL: "http://something.com?test=http%3A%2F%2Fiamurl.com"}}, - {name: "macro_with_spaces", args: args{trackerURL: "http://something.com?test=[TEST]", macro: " [TEST] ", value: "http://iamurl.com"}, want: want{trackerURL: "http://something.com?test=http%3A%2F%2Fiamurl.com"}}, - } - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - trackerURL := replaceMacro(tc.args.trackerURL, tc.args.macro, tc.args.value) - assert.Equal(t, tc.want.trackerURL, trackerURL) - }) - } +func TestCompareXMLParsers(t *testing.T) { + //fileName := `./test/base64_vast.txt` + fileName := `./test/raw_vast.txt` -} -func TestExtractDomain(t *testing.T) { - testCases := []struct { - description string - url string - expectedDomain string - expectedErr error - }{ - {description: "a.com", url: "a.com", expectedDomain: "a.com", expectedErr: nil}, - {description: "a.com/123", url: "a.com/123", expectedDomain: "a.com", expectedErr: nil}, - {description: "http://a.com/123", url: "http://a.com/123", expectedDomain: "a.com", expectedErr: nil}, - {description: "https://a.com/123", url: "https://a.com/123", expectedDomain: "a.com", expectedErr: nil}, - {description: "c.b.a.com", url: "c.b.a.com", expectedDomain: "c.b.a.com", expectedErr: nil}, - {description: "url_encoded_http://c.b.a.com", url: "http%3A%2F%2Fc.b.a.com", expectedDomain: "c.b.a.com", expectedErr: nil}, - {description: "url_encoded_with_www_http://c.b.a.com", url: "http%3A%2F%2Fwww.c.b.a.com", expectedDomain: "c.b.a.com", expectedErr: nil}, + base64Decode := strings.Contains(fileName, "base64") + + file, err := os.Open(fileName) + if !assert.Nil(t, err) { + return } - for _, test := range testCases { - t.Run(test.description, func(t *testing.T) { - domain, err := extractDomain(test.url) - assert.Equal(t, test.expectedDomain, domain) - assert.Equal(t, test.expectedErr, err) + + defer file.Close() + var mismatched []int + var debugLines map[int]bool + line := 0 + scanner := bufio.NewScanner(file) + scanner.Buffer(make([]byte, 0, 64*1024), 1024*1024) + //debugLines = map[int]bool{29: true, 30: true, 33: true, 50: true, 93: true} + + for scanner.Scan() { + line++ + vast := scanner.Text() + if len(debugLines) > 0 { + if debugLines[line] == false { + continue + } + } + if base64Decode { + data, err := base64.StdEncoding.DecodeString(vast) + if !assert.Nil(t, err) { + continue + } + vast = quoteUnescape(data) + } + t.Run(fmt.Sprintf("vast_%d", line), func(t *testing.T) { + etreeXML, _ := injectVideoEventsETree(vast, eventURLMap, false, adcom1.LinearityLinear) + fastXML, _ := injectVideoEventsFastXML(vast, eventURLMap, false, adcom1.LinearityLinear) + if vast != fastXML { + //replace only if trackers are injected + fastXML = strings.ReplaceAll(fastXML, " >", ">") + } + + if etreeXML != fastXML { + assert.Equal(t, etreeXML, fastXML) + mismatched = append(mismatched, line) + } }) } + fmt.Printf("\n total:[%v] mismatched:[%v] lines:[%v]", line, len(mismatched), mismatched) + assert.Equal(t, 0, len(mismatched)) + assert.Nil(t, scanner.Err()) } diff --git a/exchange/events.go b/exchange/events.go index 2ec63ccfefb..4d9f2bf4a8c 100644 --- a/exchange/events.go +++ b/exchange/events.go @@ -16,10 +16,10 @@ import ( // eventTracking has configuration fields needed for adding event tracking to an auction response type eventTracking struct { + OpenWrapEventTracking accountID string enabledForAccount bool enabledForRequest bool - enabledVideoEvents bool //TODO: OPENWRAP Video Events Flag auctionTimestampMs int64 integrationType string bidderInfos config.BidderInfos @@ -27,16 +27,16 @@ type eventTracking struct { } // getEventTracking creates an eventTracking object from the different configuration sources -func getEventTracking(requestExtPrebid *openrtb_ext.ExtRequestPrebid, ts time.Time, account *config.Account, bidderInfos config.BidderInfos, externalURL string) *eventTracking { +func getEventTracking(requestExtPrebid *openrtb_ext.ExtRequestPrebid, ts time.Time, account *config.Account, bidderInfos config.BidderInfos, externalURL string, owEventTracking OpenWrapEventTracking) *eventTracking { return &eventTracking{ - accountID: account.ID, - enabledForAccount: account.Events.Enabled, - enabledForRequest: requestExtPrebid != nil && requestExtPrebid.Events != nil, - enabledVideoEvents: requestExtPrebid == nil || !requestExtPrebid.ExtOWRequestPrebid.TrackerDisabled, - auctionTimestampMs: ts.UnixNano() / 1e+6, - integrationType: getIntegrationType(requestExtPrebid), - bidderInfos: bidderInfos, - externalURL: externalURL, + accountID: account.ID, + enabledForAccount: account.Events.Enabled, + enabledForRequest: requestExtPrebid != nil && requestExtPrebid.Events != nil, + auctionTimestampMs: ts.UnixNano() / 1e+6, + integrationType: getIntegrationType(requestExtPrebid), + bidderInfos: bidderInfos, + externalURL: externalURL, + OpenWrapEventTracking: owEventTracking, } } @@ -81,12 +81,7 @@ func (ev *eventTracking) modifyBidVAST(pbsBid *entities.PbsOrtbBid, bidderName o } } - if ev.enabledVideoEvents { - // always inject event trackers without checkign isModifyingVASTXMLAllowed - if newVastXML, injected, _ := events.InjectVideoEventTrackers(trackerURL, vastXML, bid, bidID, bidderName.String(), bidderCoreName.String(), ev.accountID, ev.auctionTimestampMs, req); injected { - bid.AdM = string(newVastXML) - } - } + ev.injectVideoEvents(req, bid, vastXML, trackerURL, bidID, bidderName.String(), bidderCoreName.String()) } // modifyBidJSON injects "wurl" (win) event url if needed, otherwise returns original json diff --git a/exchange/events_ow.go b/exchange/events_ow.go new file mode 100644 index 00000000000..3f6dfb4ac8d --- /dev/null +++ b/exchange/events_ow.go @@ -0,0 +1,37 @@ +package exchange + +import ( + "github.com/golang/glog" + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v2/endpoints/events" + "github.com/prebid/prebid-server/v2/metrics" +) + +type OpenWrapEventTracking struct { + enabledVideoEvents bool + enableFastXML bool + me metrics.MetricsEngine +} + +func (ev *eventTracking) injectVideoEvents( + bidRequest *openrtb2.BidRequest, + bid *openrtb2.Bid, + vastXML, trackerURL, bidID, requestingBidder, bidderCoreName string) { + + if !ev.enabledVideoEvents { + return + } + + // always inject event trackers without checkign isModifyingVASTXMLAllowed + newVastXML, metrics, err := events.InjectVideoEventTrackers(bidRequest, bid, vastXML, trackerURL, bidID, requestingBidder, bidderCoreName, ev.auctionTimestampMs, ev.enableFastXML) + if err == nil { + bid.AdM = newVastXML + } + + if metrics != nil && ev.me != nil { + recordFastXMLMetrics(ev.me, "vast_events_injection", requestingBidder, metrics) + if metrics.IsRespMismatch { + glog.V(2).Infof("\n[XML_PARSER_TEST] method:[vcr] creative:[%s]", vastXML) + } + } +} diff --git a/exchange/events_ow_test.go b/exchange/events_ow_test.go new file mode 100644 index 00000000000..f7bfcd4e2f3 --- /dev/null +++ b/exchange/events_ow_test.go @@ -0,0 +1,74 @@ +package exchange + +import ( + "testing" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/exchange/entities" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +func TestModifyBidVAST(t *testing.T) { + type args struct { + enabledVideoEvents bool + bidReq *openrtb2.BidRequest + bid *openrtb2.Bid + } + tests := []struct { + name string + args args + wantAdM string + }{ + { + name: "empty_adm", // expect adm contain vast tag with tracking events and VASTAdTagURI nurl contents + args: args{ + enabledVideoEvents: true, + bidReq: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{ID: "123", Video: &openrtb2.Video{}}}, + }, + bid: &openrtb2.Bid{ + AdM: "", + NURL: "nurl_contents", + ImpID: "123", + }, + }, + wantAdM: ``, + }, + { + name: "adm_containing_url", // expect adm contain vast tag with tracking events and VASTAdTagURI adm url (previous value) contents + args: args{ + enabledVideoEvents: true, + bidReq: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{ID: "123", Video: &openrtb2.Video{}}}, + }, + bid: &openrtb2.Bid{ + AdM: "http://vast_tag_inline.xml", + NURL: "nurl_contents", + ImpID: "123", + }, + }, + wantAdM: ``, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + ev := eventTracking{ + bidderInfos: config.BidderInfos{ + "somebidder": config.BidderInfo{ + ModifyingVastXmlAllowed: false, + }, + }, + OpenWrapEventTracking: OpenWrapEventTracking{ + enabledVideoEvents: tc.args.enabledVideoEvents, + }, + } + ev.modifyBidVAST(&entities.PbsOrtbBid{ + Bid: tc.args.bid, + BidType: openrtb_ext.BidTypeVideo, + }, "somebidder", "coreBidder", tc.args.bidReq, "http://company.tracker.com?e=[EVENT_ID]") + assert.Equal(t, tc.wantAdM, tc.args.bid.AdM) + }) + } +} diff --git a/exchange/events_test.go b/exchange/events_test.go index 0dd3c8a9920..a4ed587cd67 100644 --- a/exchange/events_test.go +++ b/exchange/events_test.go @@ -1,11 +1,9 @@ package exchange import ( - "strings" "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/config" "github.com/prebid/prebid-server/v2/exchange/entities" "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" @@ -194,112 +192,3 @@ func Test_isEventAllowed(t *testing.T) { }) } } - -func TestModifyBidVAST(t *testing.T) { - type args struct { - enabledVideoEvents bool - bidReq *openrtb2.BidRequest - bid *openrtb2.Bid - } - type want struct { - tags []string - } - tests := []struct { - name string - args args - want want - }{ - { - name: "empty_adm", // expect adm contain vast tag with tracking events and VASTAdTagURI nurl contents - args: args{ - enabledVideoEvents: true, - bidReq: &openrtb2.BidRequest{ - Imp: []openrtb2.Imp{{ID: "123", Video: &openrtb2.Video{}}}, - }, - bid: &openrtb2.Bid{ - AdM: "", - NURL: "nurl_contents", - ImpID: "123", - }, - }, - want: want{ - tags: []string{ - // ``, - // ``, - // ``, - // ``, - // "", - // "", - // "", - ``, - ``, - ``, - ``, - "", - "", - "", - }, - }, - }, - { - name: "adm_containing_url", // expect adm contain vast tag with tracking events and VASTAdTagURI adm url (previous value) contents - args: args{ - enabledVideoEvents: true, - bidReq: &openrtb2.BidRequest{ - Imp: []openrtb2.Imp{{ID: "123", Video: &openrtb2.Video{}}}, - }, - bid: &openrtb2.Bid{ - AdM: "http://vast_tag_inline.xml", - NURL: "nurl_contents", - ImpID: "123", - }, - }, - want: want{ - tags: []string{ - // ``, - // ``, - // ``, - // ``, - // "", - // "", - // "", - ``, - ``, - ``, - ``, - "", - "", - "", - }, - }, - }, - } - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - ev := eventTracking{ - bidderInfos: config.BidderInfos{ - "somebidder": config.BidderInfo{ - ModifyingVastXmlAllowed: false, - }, - }, - enabledVideoEvents: tc.args.enabledVideoEvents, - } - ev.modifyBidVAST(&entities.PbsOrtbBid{ - Bid: tc.args.bid, - BidType: openrtb_ext.BidTypeVideo, - }, "somebidder", "coreBidder", tc.args.bidReq, "http://company.tracker.com?e=[EVENT_ID]") - validator(t, tc.args.bid, tc.want.tags) - }) - } -} - -func validator(t *testing.T, b *openrtb2.Bid, expectedTags []string) { - adm := b.AdM - assert.NotNil(t, adm) - assert.NotEmpty(t, adm) - // check tags are present - - for _, tag := range expectedTags { - assert.True(t, strings.Contains(adm, tag), "expected '"+tag+"' tag in Adm") - } -} diff --git a/exchange/exchange.go b/exchange/exchange.go index 166a5675547..58eb99704d4 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -493,7 +493,12 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog } } - evTracking := getEventTracking(requestExtPrebid, r.StartTime, &r.Account, e.bidderInfo, e.externalURL) + evTracking := getEventTracking(requestExtPrebid, r.StartTime, &r.Account, e.bidderInfo, e.externalURL, + OpenWrapEventTracking{ + enabledVideoEvents: requestExtPrebid == nil || !requestExtPrebid.ExtOWRequestPrebid.TrackerDisabled, + enableFastXML: e.server.EnableFastXML, + me: e.me, + }) adapterBids = evTracking.modifyBidsForEvents(adapterBids, r.BidRequestWrapper.BidRequest, e.trakerURL) r.HookExecutor.ExecuteAllProcessedBidResponsesStage(adapterBids) diff --git a/exchange/exchange_ow.go b/exchange/exchange_ow.go index b02899742da..59a46e1a73f 100644 --- a/exchange/exchange_ow.go +++ b/exchange/exchange_ow.go @@ -205,7 +205,7 @@ func recordOpenWrapBidResponseMetrics(bidder *bidderAdapter, bidResponse *adapte recordFastXMLMetrics(bidder.me, "vastbidder", string(bidder.BidderName), bidResponse.FastXMLMetrics) if bidResponse.FastXMLMetrics.IsRespMismatch { resp, _ := jsonutil.Marshal(bidResponse) - glog.V(2).Infof("\n[VAST_BIDDER] Response Mismatch for Creative : %s", string(resp)) + glog.V(2).Infof("\n[XML_PARSER_TEST] method:[vast_bidder] response:[%s]", resp) } } diff --git a/go.mod b/go.mod index fed1b3bb174..2ef398dec75 100644 --- a/go.mod +++ b/go.mod @@ -51,7 +51,7 @@ require ( git.pubmatic.com/PubMatic/go-common v0.0.0-20240313090142-97ff3d63b7c3 git.pubmatic.com/PubMatic/go-netacuity-client v0.0.0-20240104092757-5d6f15e25fe3 git.pubmatic.com/vastunwrap v0.0.0-00010101000000-000000000000 - github.com/PubMatic-OpenWrap/fastxml v0.0.0-20240621094509-2f843d282179 + github.com/PubMatic-OpenWrap/fastxml v0.0.0-20240826060652-d9d5d05fdad2 github.com/diegoholiveira/jsonlogic/v3 v3.5.3 github.com/go-sql-driver/mysql v1.7.1 github.com/golang/mock v1.6.0 @@ -88,6 +88,7 @@ require ( github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect + github.com/yudai/pp v2.0.1+incompatible // indirect golang.org/x/crypto v0.21.0 // indirect golang.org/x/sys v0.18.0 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect @@ -99,6 +100,6 @@ replace github.com/prebid/prebid-server/v2 => ./ replace github.com/prebid/openrtb/v20 => github.com/PubMatic-OpenWrap/prebid-openrtb/v20 v20.0.0-20240222072752-2d647d1707ef -replace github.com/beevik/etree v1.0.2 => github.com/PubMatic-OpenWrap/etree v1.0.2-0.20210129100623-8f30cfecf9f4 +replace github.com/beevik/etree v1.0.2 => github.com/PubMatic-OpenWrap/etree v1.0.2-0.20240721064252-bb63229a1baa replace github.com/beevik/etree/110 => github.com/beevik/etree v1.1.0 diff --git a/go.sum b/go.sum index c45d6edf1be..54f721ef026 100644 --- a/go.sum +++ b/go.sum @@ -315,10 +315,12 @@ github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cq github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/PubMatic-OpenWrap/etree v1.0.2-0.20210129100623-8f30cfecf9f4 h1:EhiijwjoKTx7FVP8p2wwC/z4n5l4c8l2CGmsrFv2uhI= -github.com/PubMatic-OpenWrap/etree v1.0.2-0.20210129100623-8f30cfecf9f4/go.mod h1:5Y8qgcuDoy3XXG907UXkGnVTwihF16rXyJa4zRT7hOE= -github.com/PubMatic-OpenWrap/fastxml v0.0.0-20240621094509-2f843d282179 h1:XhtshM/kxpjzShEebApfcvPv1ue3LynvvKNCW2SMONA= -github.com/PubMatic-OpenWrap/fastxml v0.0.0-20240621094509-2f843d282179/go.mod h1:TGGzSA5ziWpfLsKvqOzgdPGEZ7SJIQjHbcJw6lWoyHU= +github.com/PubMatic-OpenWrap/etree v1.0.2-0.20240721064252-bb63229a1baa h1:3tRjI/7/JkTX2tnIvjEbOUTgJJ4rq4oz2hWSU8jvjH8= +github.com/PubMatic-OpenWrap/etree v1.0.2-0.20240721064252-bb63229a1baa/go.mod h1:5Y8qgcuDoy3XXG907UXkGnVTwihF16rXyJa4zRT7hOE= +github.com/PubMatic-OpenWrap/fastxml v0.0.0-20240823084925-e25a796a41bd h1:5IlcLRGtf1EPaVF+ySv7QidGzcwE3xKALhQxMLXOKus= +github.com/PubMatic-OpenWrap/fastxml v0.0.0-20240823084925-e25a796a41bd/go.mod h1:TGGzSA5ziWpfLsKvqOzgdPGEZ7SJIQjHbcJw6lWoyHU= +github.com/PubMatic-OpenWrap/fastxml v0.0.0-20240826060652-d9d5d05fdad2 h1:4zaGImZVnKCJudxKfsVNJAqGhCPxbjApAo0QvEThwpw= +github.com/PubMatic-OpenWrap/fastxml v0.0.0-20240826060652-d9d5d05fdad2/go.mod h1:TGGzSA5ziWpfLsKvqOzgdPGEZ7SJIQjHbcJw6lWoyHU= github.com/PubMatic-OpenWrap/prebid-openrtb/v20 v20.0.0-20240222072752-2d647d1707ef h1:CXsyYtEgZz/0++fiug6QZXrRYG6BBrl9IGveCxsnhiE= github.com/PubMatic-OpenWrap/prebid-openrtb/v20 v20.0.0-20240222072752-2d647d1707ef/go.mod h1:hLBrA/APkSrxs5MaW639l+y/EAHivDfRagO2TX/wbSc= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -824,9 +826,9 @@ github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBO github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/rs/vast v0.0.0-20180618195556-06597a11a4c3 h1:PSgAIBGyQP7KW2+EElPsa3qmaya7kCxLSI/GBR176MQ= github.com/rs/vast v0.0.0-20180618195556-06597a11a4c3/go.mod h1:gq4gkWd7KdigGXkRdN5GEgBQYAWDTmD4/U65MdCgLxQ= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible h1:j1Wcmh8OrK4Q7GXY+V7SVSY8nUWQxHW5TkBe7YUl+2s= diff --git a/modules/pubmatic/openwrap/tracker/video_test.go b/modules/pubmatic/openwrap/tracker/video_test.go index 7a4599335d5..3995b480092 100644 --- a/modules/pubmatic/openwrap/tracker/video_test.go +++ b/modules/pubmatic/openwrap/tracker/video_test.go @@ -289,7 +289,7 @@ func TestInjectVideoCreativeTrackers(t *testing.T) { }, }, }, - wantAdm: ``, + wantAdm: ` `, wantErr: false, }, { @@ -449,7 +449,7 @@ func TestInjectVideoCreativeTrackers(t *testing.T) { }, }, wantBurl: "Tracker URL&owsspburl=https://burl.com", - wantAdm: ``, + wantAdm: ` `, wantErr: false, }, }