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 00000000000..d2b6fb71052
Binary files /dev/null and b/endpoints/events/test/base64_vast.txt.tar.gz differ
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 b9f7f938308..645fe63166d 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
github.com/yudai/pp v2.0.1+incompatible // indirect
@@ -100,6 +101,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 13321359a53..cea4b242fb7 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,
},
}