diff --git a/modules/pubmatic/openwrap/beforevalidationhook.go b/modules/pubmatic/openwrap/beforevalidationhook.go index 332756ad242..8fb761d9368 100644 --- a/modules/pubmatic/openwrap/beforevalidationhook.go +++ b/modules/pubmatic/openwrap/beforevalidationhook.go @@ -132,14 +132,9 @@ func (m OpenWrap) handleBeforeValidationHook( if err != nil || len(partnerConfigMap) == 0 { // TODO: seperate DB fetch errors as internal errors result.NbrCode = int(nbr.InvalidProfileConfiguration) - if err != nil { - err = errors.New("failed to get profile data: " + err.Error()) - } else { - err = errors.New("failed to get profile data: received empty data") - } rCtx.ImpBidCtx = getDefaultImpBidCtx(*payload.BidRequest) // for wrapper logger sz m.metricEngine.RecordPublisherInvalidProfileRequests(rCtx.Endpoint, rCtx.PubIDStr, rCtx.ProfileIDStr) - return result, err + return result, errors.New("invalid profile data") } if rCtx.IsCTVRequest && rCtx.Endpoint == models.EndpointJson { diff --git a/modules/pubmatic/openwrap/beforevalidationhook_test.go b/modules/pubmatic/openwrap/beforevalidationhook_test.go index 878768573e0..7b9b7d41a4b 100644 --- a/modules/pubmatic/openwrap/beforevalidationhook_test.go +++ b/modules/pubmatic/openwrap/beforevalidationhook_test.go @@ -3858,7 +3858,7 @@ func TestOpenWrapHandleBeforeValidationHook(t *testing.T) { hookResult: hookstage.HookResult[hookstage.BeforeValidationRequestPayload]{ Reject: true, NbrCode: int(nbr.InvalidProfileConfiguration), - Errors: []string{"failed to get profile data: received empty data"}, + Errors: []string{"invalid profile data"}, }, error: true, nilCurrencyConversion: true, diff --git a/modules/pubmatic/openwrap/cache/gocache/adpod_config.go b/modules/pubmatic/openwrap/cache/gocache/adpod_config.go index b1233d4fd4f..b152a60de7b 100644 --- a/modules/pubmatic/openwrap/cache/gocache/adpod_config.go +++ b/modules/pubmatic/openwrap/cache/gocache/adpod_config.go @@ -1,19 +1,28 @@ package gocache import ( + "database/sql" + "errors" "strconv" + "github.com/golang/glog" "github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/models" "github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/models/adpodconfig" ) func (c *cache) populateCacheWithAdpodConfig(pubID, profileID, displayVersion int) (err error) { + cacheKey := key(PubAdpodConfig, pubID, profileID, displayVersion) adpodConfig, err := c.db.GetAdpodConfig(pubID, profileID, displayVersion) if err != nil { + if errors.Is(err, sql.ErrNoRows) { + c.metricEngine.RecordDBQueryFailure(models.LiveVersionInnerQuery, strconv.Itoa(pubID), strconv.Itoa(profileID)) + } else { + c.metricEngine.RecordDBQueryFailure(models.GetAdpodConfig, strconv.Itoa(pubID), strconv.Itoa(profileID)) + } + glog.Errorf(models.ErrDBQueryFailed, models.GetAdpodConfig, pubID, profileID, err) return err } - cacheKey := key(PubAdpodConfig, pubID, profileID, displayVersion) c.cache.Set(cacheKey, adpodConfig, getSeconds(c.cfg.CacheDefaultExpiry)) return } @@ -32,7 +41,6 @@ func (c *cache) GetAdpodConfig(pubID, profileID, displayVersion int) (*adpodconf if err := c.LockAndLoad(lockKey, func() error { return c.populateCacheWithAdpodConfig(pubID, profileID, displayVersion) }); err != nil { - c.metricEngine.RecordDBQueryFailure(models.GetAdpodConfig, strconv.Itoa(pubID), strconv.Itoa(profileID)) return nil, err } diff --git a/modules/pubmatic/openwrap/cache/gocache/app_integration_path.go b/modules/pubmatic/openwrap/cache/gocache/app_integration_path.go index 5e452d13b27..2e26dd49e6a 100644 --- a/modules/pubmatic/openwrap/cache/gocache/app_integration_path.go +++ b/modules/pubmatic/openwrap/cache/gocache/app_integration_path.go @@ -3,6 +3,7 @@ package gocache import ( "fmt" + "github.com/golang/glog" "github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/models" ) @@ -13,6 +14,7 @@ func (c *cache) GetAppIntegrationPaths() (map[string]int, error) { appIntegrationPathMap, err := c.db.GetAppIntegrationPaths() if err != nil { c.metricEngine.RecordDBQueryFailure(models.AppIntegrationPathMapQuery, "", "") + glog.Errorf(models.ErrDBQueryFailed, models.AppIntegrationPathMapQuery, "", "", err) return appIntegrationPathMap, fmt.Errorf(errorAppIntegrationPathMapUpdate, err) } return appIntegrationPathMap, nil diff --git a/modules/pubmatic/openwrap/cache/gocache/app_sub_integartion_path.go b/modules/pubmatic/openwrap/cache/gocache/app_sub_integartion_path.go index fdde2ae0805..87162016562 100644 --- a/modules/pubmatic/openwrap/cache/gocache/app_sub_integartion_path.go +++ b/modules/pubmatic/openwrap/cache/gocache/app_sub_integartion_path.go @@ -3,6 +3,7 @@ package gocache import ( "fmt" + "github.com/golang/glog" "github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/models" ) @@ -13,6 +14,7 @@ func (c *cache) GetAppSubIntegrationPaths() (map[string]int, error) { appSubIntegrationPathMap, err := c.db.GetAppSubIntegrationPaths() if err != nil { c.metricEngine.RecordDBQueryFailure(models.AppSubIntegrationPathMapQuery, "", "") + glog.Errorf(models.ErrDBQueryFailed, models.AppSubIntegrationPathMapQuery, "", "", err) return appSubIntegrationPathMap, fmt.Errorf(errorAppSubIntegrationPathMapUpdate, err) } return appSubIntegrationPathMap, nil diff --git a/modules/pubmatic/openwrap/cache/gocache/fullscreenclickability.go b/modules/pubmatic/openwrap/cache/gocache/fullscreenclickability.go index 4e8fd798083..c11bb0e34aa 100644 --- a/modules/pubmatic/openwrap/cache/gocache/fullscreenclickability.go +++ b/modules/pubmatic/openwrap/cache/gocache/fullscreenclickability.go @@ -3,6 +3,7 @@ package gocache import ( "fmt" + "github.com/golang/glog" "github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/models" ) @@ -15,6 +16,7 @@ func (c *cache) GetFSCThresholdPerDSP() (map[int]int, error) { fscThreshold, err := c.db.GetFSCThresholdPerDSP() if err != nil { c.metricEngine.RecordDBQueryFailure(models.AllDspFscPcntQuery, "", "") + glog.Errorf(models.ErrDBQueryFailed, models.AllDspFscPcntQuery, "", "", err) return fscThreshold, fmt.Errorf(errorFscDspMsg, err) } return fscThreshold, nil diff --git a/modules/pubmatic/openwrap/cache/gocache/partner_config.go b/modules/pubmatic/openwrap/cache/gocache/partner_config.go index 76d1ed676d1..755ea1ac978 100644 --- a/modules/pubmatic/openwrap/cache/gocache/partner_config.go +++ b/modules/pubmatic/openwrap/cache/gocache/partner_config.go @@ -1,11 +1,13 @@ package gocache import ( + "database/sql" "errors" "fmt" "strconv" "time" + "github.com/golang/glog" "github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/models" "github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/models/adunitconfig" ) @@ -67,13 +69,19 @@ func (c *cache) getActivePartnerConfigAndPopulateWrapperMappings(pubID, profileI cacheKey := key(PUB_HB_PARTNER, pubID, profileID, displayVersion) partnerConfigMap, err := c.db.GetActivePartnerConfigurations(pubID, profileID, displayVersion) if err != nil { - c.metricEngine.RecordDBQueryFailure(models.PartnerConfigQuery, strconv.Itoa(pubID), strconv.Itoa(profileID)) - return + if errors.Is(err, sql.ErrNoRows) { + c.metricEngine.RecordDBQueryFailure(models.LiveVersionInnerQuery, strconv.Itoa(pubID), strconv.Itoa(profileID)) + c.cache.Set(cacheKey, partnerConfigMap, getSeconds(c.cfg.CacheDefaultExpiry)) + } else { + c.metricEngine.RecordDBQueryFailure(models.PartnerConfigQuery, strconv.Itoa(pubID), strconv.Itoa(profileID)) + } + glog.Errorf(models.ErrDBQueryFailed, models.PartnerConfigQuery, pubID, profileID, err) + return err } if len(partnerConfigMap) == 0 { c.cache.Set(cacheKey, partnerConfigMap, getSeconds(c.cfg.CacheDefaultExpiry)) - return fmt.Errorf("there are no active partners for pubId:%d, profileId:%d, displayVersion:%d", pubID, profileID, displayVersion) + return fmt.Errorf(models.EmptyPartnerConfig, pubID, profileID, displayVersion) } err = c.populateCacheWithWrapperSlotMappings(pubID, partnerConfigMap, profileID, displayVersion) @@ -83,6 +91,7 @@ func (c *cache) getActivePartnerConfigAndPopulateWrapperMappings(pubID, profileI queryType = models.WrapperLiveVersionSlotMappings } c.metricEngine.RecordDBQueryFailure(queryType, strconv.Itoa(pubID), strconv.Itoa(profileID)) + glog.Errorf(models.ErrDBQueryFailed, queryType, pubID, profileID, err) return err } @@ -96,6 +105,7 @@ func (c *cache) getActivePartnerConfigAndPopulateWrapperMappings(pubID, profileI queryType = models.AdUnitFailUnmarshal } c.metricEngine.RecordDBQueryFailure(queryType, strconv.Itoa(pubID), strconv.Itoa(profileID)) + glog.Errorf(models.ErrDBQueryFailed, queryType, pubID, profileID, err) return err } diff --git a/modules/pubmatic/openwrap/cache/gocache/profile_type_platform.go b/modules/pubmatic/openwrap/cache/gocache/profile_type_platform.go index ad912e430d2..c83dc5fdb34 100644 --- a/modules/pubmatic/openwrap/cache/gocache/profile_type_platform.go +++ b/modules/pubmatic/openwrap/cache/gocache/profile_type_platform.go @@ -3,6 +3,7 @@ package gocache import ( "fmt" + "github.com/golang/glog" "github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/models" ) @@ -13,6 +14,7 @@ func (c *cache) GetProfileTypePlatforms() (map[string]int, error) { profileTypePlatformMap, err := c.db.GetProfileTypePlatforms() if err != nil { c.metricEngine.RecordDBQueryFailure(models.ProfileTypePlatformMapQuery, "", "") + glog.Errorf(models.ErrDBQueryFailed, models.ProfileTypePlatformMapQuery, "", "", err) return profileTypePlatformMap, fmt.Errorf(errorProfileTypePlatformMapUpdate, err) } return profileTypePlatformMap, nil diff --git a/modules/pubmatic/openwrap/cache/gocache/publisher_feature.go b/modules/pubmatic/openwrap/cache/gocache/publisher_feature.go index c27ac7d9214..d922ef2c51d 100644 --- a/modules/pubmatic/openwrap/cache/gocache/publisher_feature.go +++ b/modules/pubmatic/openwrap/cache/gocache/publisher_feature.go @@ -3,6 +3,7 @@ package gocache import ( "fmt" + "github.com/golang/glog" "github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/models" ) @@ -13,6 +14,7 @@ func (c *cache) GetPublisherFeatureMap() (map[int]map[int]models.FeatureData, er publisherFeatureMap, err := c.db.GetPublisherFeatureMap() if err != nil { c.metricEngine.RecordDBQueryFailure(models.PublisherFeatureMapQuery, "", "") + glog.Errorf(models.ErrDBQueryFailed, models.PublisherFeatureMapQuery, "", "", err) return publisherFeatureMap, fmt.Errorf(errorPubFeatureUpdate, err) } return publisherFeatureMap, nil diff --git a/modules/pubmatic/openwrap/cache/gocache/slot_mappings.go b/modules/pubmatic/openwrap/cache/gocache/slot_mappings.go index b25246a7937..fa938ead1af 100644 --- a/modules/pubmatic/openwrap/cache/gocache/slot_mappings.go +++ b/modules/pubmatic/openwrap/cache/gocache/slot_mappings.go @@ -6,6 +6,7 @@ import ( "strconv" "strings" + "github.com/golang/glog" "github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/models" "github.com/prebid/prebid-server/v2/openrtb_ext" ) @@ -15,6 +16,10 @@ func (c *cache) populateCacheWithPubSlotNameHash(pubID int) (err error) { cacheKey := key(PubSlotNameHash, pubID) publisherSlotNameHashMap, err := c.db.GetPublisherSlotNameHash(pubID) + if err != nil { + glog.Errorf(models.ErrDBQueryFailed, models.SlotNameHash, pubID, "", err) + return + } //This call may set nil publisherSlotNameHashMap in cache c.cache.Set(cacheKey, publisherSlotNameHashMap, getSeconds(c.cfg.CacheDefaultExpiry)) return @@ -23,6 +28,9 @@ func (c *cache) populateCacheWithPubSlotNameHash(pubID int) (err error) { // PopulateCacheWithWrapperSlotMappings will get the SlotMappings from database and put them in cache. func (c *cache) populateCacheWithWrapperSlotMappings(pubID int, partnerConfigMap map[int]map[string]string, profileID, displayVersion int) error { partnerSlotMappingMap, err := c.db.GetWrapperSlotMappings(partnerConfigMap, profileID, displayVersion) + if err != nil { + return err + } //put a version level dummy entry in cache denoting mappings are present for this version cacheKey := key(PUB_SLOT_INFO, pubID, profileID, displayVersion, 0) diff --git a/modules/pubmatic/openwrap/cache/gocache/slot_mappings_test.go b/modules/pubmatic/openwrap/cache/gocache/slot_mappings_test.go index 037cffbbb64..0d8017b70e9 100644 --- a/modules/pubmatic/openwrap/cache/gocache/slot_mappings_test.go +++ b/modules/pubmatic/openwrap/cache/gocache/slot_mappings_test.go @@ -41,8 +41,9 @@ func Test_cache_populateCacheWithPubSlotNameHash(t *testing.T) { pubid int } type want struct { - publisherSlotNameHashMap map[string]string + publisherSlotNameHashMap interface{} err error + foundCacheKey bool } tests := []struct { name string @@ -69,6 +70,7 @@ func Test_cache_populateCacheWithPubSlotNameHash(t *testing.T) { want: want{ publisherSlotNameHashMap: nil, err: fmt.Errorf("Error from the DB"), + foundCacheKey: false, }, }, { @@ -93,6 +95,7 @@ func Test_cache_populateCacheWithPubSlotNameHash(t *testing.T) { publisherSlotNameHashMap: map[string]string{ testSlotName: testHashValue, }, + foundCacheKey: true, }, }, { @@ -111,8 +114,9 @@ func Test_cache_populateCacheWithPubSlotNameHash(t *testing.T) { mockDatabase.EXPECT().GetPublisherSlotNameHash(5890).Return(nil, nil) }, want: want{ - publisherSlotNameHashMap: nil, + publisherSlotNameHashMap: map[string]string(nil), err: nil, + foundCacheKey: true, }, }, } @@ -131,7 +135,7 @@ func Test_cache_populateCacheWithPubSlotNameHash(t *testing.T) { assert.Equal(t, tt.want.err, err) cacheKey := key(PubSlotNameHash, tt.args.pubid) publisherSlotNameHashMap, found := c.cache.Get(cacheKey) - assert.True(t, found) + assert.Equal(t, tt.want.foundCacheKey, found) assert.Equal(t, tt.want.publisherSlotNameHashMap, publisherSlotNameHashMap) }) } @@ -157,8 +161,9 @@ func Test_cache_populateCacheWithWrapperSlotMappings(t *testing.T) { displayVersion int } type want struct { - partnerSlotMapping map[string]models.SlotMapping + partnerSlotMapping interface{} err error + foundCacheKey bool } tests := []struct { name string @@ -186,8 +191,9 @@ func Test_cache_populateCacheWithWrapperSlotMappings(t *testing.T) { mockDatabase.EXPECT().GetWrapperSlotMappings(formTestPartnerConfig(), testProfileID, testVersionID).Return(nil, fmt.Errorf("Error from the DB")) }, want: want{ - partnerSlotMapping: map[string]models.SlotMapping{}, + partnerSlotMapping: nil, err: fmt.Errorf("Error from the DB"), + foundCacheKey: false, }, }, { @@ -211,6 +217,7 @@ func Test_cache_populateCacheWithWrapperSlotMappings(t *testing.T) { want: want{ partnerSlotMapping: map[string]models.SlotMapping{}, err: nil, + foundCacheKey: true, }, }, { @@ -261,7 +268,8 @@ func Test_cache_populateCacheWithWrapperSlotMappings(t *testing.T) { OrderID: 0, }, }, - err: nil, + err: nil, + foundCacheKey: true, }, }, { @@ -295,7 +303,8 @@ func Test_cache_populateCacheWithWrapperSlotMappings(t *testing.T) { }, nil) }, want: want{ - err: nil, + err: nil, + foundCacheKey: true, partnerSlotMapping: map[string]models.SlotMapping{ "adunit@300x250": { PartnerId: testPartnerID, @@ -331,7 +340,7 @@ func Test_cache_populateCacheWithWrapperSlotMappings(t *testing.T) { cacheKey := key(PUB_SLOT_INFO, tt.args.pubid, tt.args.profileId, tt.args.displayVersion, testPartnerID) partnerSlotMapping, found := c.cache.Get(cacheKey) - assert.True(t, found) + assert.Equal(t, tt.want.foundCacheKey, found) assert.Equal(t, tt.want.partnerSlotMapping, partnerSlotMapping) }) diff --git a/modules/pubmatic/openwrap/cache/gocache/vast_tags.go b/modules/pubmatic/openwrap/cache/gocache/vast_tags.go index 8f2137a03ec..f75f22b4bfa 100644 --- a/modules/pubmatic/openwrap/cache/gocache/vast_tags.go +++ b/modules/pubmatic/openwrap/cache/gocache/vast_tags.go @@ -1,6 +1,7 @@ package gocache import ( + "github.com/golang/glog" "github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/models" ) @@ -11,13 +12,10 @@ func (c *cache) populatePublisherVASTTags(pubID int) error { //get publisher level vast tag details from DB publisherVASTTags, err := c.db.GetPublisherVASTTags(pubID) if err != nil { + glog.Errorf(models.ErrDBQueryFailed, models.PublisherVASTTagsQuery, pubID, "", err) return err } - if publisherVASTTags == nil { - publisherVASTTags = models.PublisherVASTTags{} - } - c.cache.Set(cacheKey, publisherVASTTags, getSeconds(c.cfg.VASTTagCacheExpiry)) return nil } diff --git a/modules/pubmatic/openwrap/cache/gocache/vast_tags_test.go b/modules/pubmatic/openwrap/cache/gocache/vast_tags_test.go index 3d529633551..d9d4e7358f7 100644 --- a/modules/pubmatic/openwrap/cache/gocache/vast_tags_test.go +++ b/modules/pubmatic/openwrap/cache/gocache/vast_tags_test.go @@ -111,7 +111,7 @@ func Test_cache_populatePublisherVASTTags(t *testing.T) { want: want{ cacheEntry: true, err: nil, - PublisherVASTTags: models.PublisherVASTTags{}, + PublisherVASTTags: models.PublisherVASTTags(nil), }, }, } diff --git a/modules/pubmatic/openwrap/database/mysql/adpod_config.go b/modules/pubmatic/openwrap/database/mysql/adpod_config.go index ea25a0246c7..d98b8b2d258 100644 --- a/modules/pubmatic/openwrap/database/mysql/adpod_config.go +++ b/modules/pubmatic/openwrap/database/mysql/adpod_config.go @@ -3,10 +3,10 @@ package mysql import ( "context" "encoding/json" + "fmt" "strings" "time" - "github.com/golang/glog" "github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/models" "github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/models/adpodconfig" ) @@ -14,9 +14,19 @@ import ( func (db *mySqlDB) GetAdpodConfig(pubID, profileID, displayVersion int) (*adpodconfig.AdpodConfig, error) { versionID, displayVersion, _, _, err := db.getVersionIdAndProfileDetails(profileID, displayVersion, pubID) if err != nil { - return nil, err + return nil, fmt.Errorf("LiveVersionInnerQuery/DisplayVersionInnerQuery Failure Error: %w", err) } + config, err := db.getAdpodConfig(versionID) + if err != nil { + return nil, fmt.Errorf("GetAdpodConfigQuery Failure Error: %w", err) + } + + return config, nil +} + +func (db *mySqlDB) getAdpodConfig(versionID int) (*adpodconfig.AdpodConfig, error) { + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Millisecond*time.Duration(db.cfg.MaxDbContextTimeout))) defer cancel() @@ -54,7 +64,7 @@ func (db *mySqlDB) GetAdpodConfig(pubID, profileID, displayVersion int) (*adpodc } if err = rows.Err(); err != nil { - glog.Errorf("adpod config row scan failed for publisher %d having profile %d with versionID %d", pubID, profileID, displayVersion) + return nil, err } return config, nil diff --git a/modules/pubmatic/openwrap/database/mysql/adpod_config_test.go b/modules/pubmatic/openwrap/database/mysql/adpod_config_test.go index 8757acc794c..650dd4a8c93 100644 --- a/modules/pubmatic/openwrap/database/mysql/adpod_config_test.go +++ b/modules/pubmatic/openwrap/database/mysql/adpod_config_test.go @@ -11,6 +11,7 @@ import ( "github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/config" "github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/models/adpodconfig" "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/stretchr/testify/assert" ) func TestMySqlDBGetAdpodConfigs(t *testing.T) { @@ -28,7 +29,7 @@ func TestMySqlDBGetAdpodConfigs(t *testing.T) { args args setup func() *sql.DB want *adpodconfig.AdpodConfig - wantErr bool + wantErr error }{ { name: "Retrieve dynamic adpod configuration from database", @@ -51,10 +52,8 @@ func TestMySqlDBGetAdpodConfigs(t *testing.T) { if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } - rowsWrapperVersion := sqlmock.NewRows([]string{"versionId", "displayVersionId", "platform", "type"}).AddRow("4444", "4", "ctv", "1") mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM version (.+)")).WithArgs(123, 4, 5890).WillReturnRows(rowsWrapperVersion) - rows := sqlmock.NewRows([]string{"pod_type", "s2s_ad_slots_config"}).AddRow("DYNAMIC", `[{"maxduration":60,"maxseq":5,"poddur":180,"minduration":1}]`) mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM ad_pod (.+)")).WithArgs(4444).WillReturnRows(rows) return db @@ -69,7 +68,7 @@ func TestMySqlDBGetAdpodConfigs(t *testing.T) { }, }, }, - wantErr: false, + wantErr: nil, }, { name: "Retrieve dynamic adpod configuration from database for live version", @@ -94,7 +93,6 @@ func TestMySqlDBGetAdpodConfigs(t *testing.T) { } rowsWrapperVersion := sqlmock.NewRows([]string{"versionId", "displayVersionId", "platform", "type"}).AddRow("4444", "4", "ctv", "1") mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM version (.+) LIVE")).WithArgs(123, 5890).WillReturnRows(rowsWrapperVersion) - rows := sqlmock.NewRows([]string{"pod_type", "s2s_ad_slots_config"}).AddRow("DYNAMIC", `[{"maxduration":60,"maxseq":5,"poddur":180,"minduration":1}]`) mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM ad_pod (.+)")).WithArgs(4444).WillReturnRows(rows) return db @@ -109,7 +107,7 @@ func TestMySqlDBGetAdpodConfigs(t *testing.T) { }, }, }, - wantErr: false, + wantErr: nil, }, { name: "Retrieve dynamic adpod configuration from database where rqddurs provided", @@ -134,7 +132,6 @@ func TestMySqlDBGetAdpodConfigs(t *testing.T) { } rowsWrapperVersion := sqlmock.NewRows([]string{"versionId", "displayVersionId", "platform", "type"}).AddRow("4444", "4", "ctv", "1") mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM version (.+)")).WithArgs(123, 4, 5890).WillReturnRows(rowsWrapperVersion) - rows := sqlmock.NewRows([]string{"pod_type", "s2s_ad_slots_config"}).AddRow("DYNAMIC", `[{"maxseq":5,"poddur":600,"rqddurs":[6,60,120,600]}]`) mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM ad_pod (.+)")).WithArgs(4444).WillReturnRows(rows) return db @@ -148,7 +145,7 @@ func TestMySqlDBGetAdpodConfigs(t *testing.T) { }, }, }, - wantErr: false, + wantErr: nil, }, { name: "Retrieve dynamic adpod configuration from database for all types", @@ -171,10 +168,8 @@ func TestMySqlDBGetAdpodConfigs(t *testing.T) { if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } - rowsWrapperVersion := sqlmock.NewRows([]string{"versionId", "displayVersionId", "platform", "type"}).AddRow("4444", "4", "ctv", "1") mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM version (.+)")).WithArgs(123, 4, 5890).WillReturnRows(rowsWrapperVersion) - rows := sqlmock.NewRows([]string{"pod_type", "s2s_ad_slots_config"}). AddRow("DYNAMIC", `[{"maxduration":60,"maxseq":5,"poddur":180,"minduration":1}]`). AddRow("HYBRID", `[{"maxduration":20,"minduration":5},{"maxduration":20,"maxseq":3,"poddur":60,"minduration":5}]`). @@ -210,7 +205,7 @@ func TestMySqlDBGetAdpodConfigs(t *testing.T) { }, }, }, - wantErr: false, + wantErr: nil, }, { name: "No adpod configuration in database", @@ -235,12 +230,45 @@ func TestMySqlDBGetAdpodConfigs(t *testing.T) { } rowsWrapperVersion := sqlmock.NewRows([]string{"versionId", "displayVersionId", "platform", "type"}).AddRow("4444", "4", "ctv", "1") mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM version (.+)")).WithArgs(123, 4, 5890).WillReturnRows(rowsWrapperVersion) - mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM ad_pod (.+)")).WillReturnError(errors.New("context deadline exceeded")) return db }, want: nil, - wantErr: true, + wantErr: errors.New("GetAdpodConfigQuery Failure Error: context deadline exceeded"), + }, + { + name: "Error in row scan", + fields: fields{ + cfg: config.Database{ + MaxDbContextTimeout: 5, + Queries: config.Queries{ + GetAdpodConfig: "^SELECT (.+) FROM ad_pod (.+)", + DisplayVersionInnerQuery: "^SELECT (.+) FROM version (.+)", + }, + }, + }, + args: args{ + pubId: 5890, + profileID: 123, + displayVersion: 4, + }, + setup: func() *sql.DB { + db, mock, err := sqlmock.New() + if err != nil { + t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) + } + rowsWrapperVersion := sqlmock.NewRows([]string{"versionId", "displayVersionId", "platform", "type"}).AddRow("4444", "4", "ctv", "1") + mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM version (.+)")).WithArgs(123, 4, 5890).WillReturnRows(rowsWrapperVersion) + rows := sqlmock.NewRows([]string{"pod_type", "s2s_ad_slots_config"}). + AddRow("DYNAMIC", `[{"maxduration":60,"maxseq":5,"poddur":180,"minduration":1}]`). + AddRow("HYBRID", `[{"maxduration":20,"minduration":5},{"maxduration":20,"maxseq":3,"poddur":60,"minduration":5}]`). + AddRow("STRUCTURED", `[{"maxduration":20,"minduration":5}]`) + rows = rows.RowError(1, errors.New("error in row scan")) + mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM ad_pod (.+)")).WillReturnRows(rows) + return db + }, + want: nil, + wantErr: errors.New("GetAdpodConfigQuery Failure Error: error in row scan"), }, } for _, tt := range tests { @@ -250,9 +278,10 @@ func TestMySqlDBGetAdpodConfigs(t *testing.T) { cfg: tt.fields.cfg, } got, err := db.GetAdpodConfig(tt.args.pubId, tt.args.profileID, tt.args.displayVersion) - if (err != nil) != tt.wantErr { - t.Errorf("mySqlDB.GetAdpodConfigs() error = %v, wantErr %v", err, tt.wantErr) - return + if tt.wantErr == nil { + assert.NoError(t, err, tt.name) + } else { + assert.EqualError(t, err, tt.wantErr.Error(), tt.name) } if !reflect.DeepEqual(got, tt.want) { t.Errorf("mySqlDB.GetAdpodConfigs() = %v, want %v", got, tt.want) diff --git a/modules/pubmatic/openwrap/database/mysql/adunit_config_test.go b/modules/pubmatic/openwrap/database/mysql/adunit_config_test.go index 1f2c8499f92..332e84a45db 100644 --- a/modules/pubmatic/openwrap/database/mysql/adunit_config_test.go +++ b/modules/pubmatic/openwrap/database/mysql/adunit_config_test.go @@ -3,6 +3,7 @@ package mysql import ( "database/sql" "encoding/json" + "errors" "regexp" "testing" @@ -26,13 +27,13 @@ func Test_mySqlDB_GetAdunitConfig(t *testing.T) { fields fields args args want *adunitconfig.AdUnitConfig - wantErr bool + wantErr error setup func() *sql.DB }{ { name: "empty query in config file", want: nil, - wantErr: true, + wantErr: errors.New("context deadline exceeded"), setup: func() *sql.DB { db, _, err := sqlmock.New() if err != nil { @@ -56,7 +57,7 @@ func Test_mySqlDB_GetAdunitConfig(t *testing.T) { displayVersion: 0, }, want: nil, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -87,7 +88,7 @@ func Test_mySqlDB_GetAdunitConfig(t *testing.T) { "default": {BidFloor: ptrutil.ToPtr(2.0)}, }, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -118,7 +119,7 @@ func Test_mySqlDB_GetAdunitConfig(t *testing.T) { "default": {BidFloor: ptrutil.ToPtr(3.1)}, }, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -144,7 +145,7 @@ func Test_mySqlDB_GetAdunitConfig(t *testing.T) { displayVersion: 0, }, want: nil, - wantErr: true, + wantErr: errors.New("unmarshal error adunitconfig"), setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -185,7 +186,7 @@ func Test_mySqlDB_GetAdunitConfig(t *testing.T) { }, }, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -217,7 +218,7 @@ func Test_mySqlDB_GetAdunitConfig(t *testing.T) { "abc": {BidFloor: ptrutil.ToPtr(3.1)}, }, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -248,7 +249,7 @@ func Test_mySqlDB_GetAdunitConfig(t *testing.T) { "default": {}, }, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -269,9 +270,10 @@ func Test_mySqlDB_GetAdunitConfig(t *testing.T) { defer db.conn.Close() got, err := db.GetAdunitConfig(tt.args.profileID, tt.args.displayVersion) - if (err != nil) != tt.wantErr { - t.Errorf("mySqlDB.GetAdunitConfig() error = %v, wantErr %v", err, tt.wantErr) - return + if tt.wantErr == nil { + assert.NoError(t, err, tt.name) + } else { + assert.EqualError(t, err, tt.wantErr.Error(), tt.name) } assert.Equal(t, tt.want, got) }) diff --git a/modules/pubmatic/openwrap/database/mysql/app_integration_path.go b/modules/pubmatic/openwrap/database/mysql/app_integration_path.go index 89be33e6edf..ae5dfece9f0 100644 --- a/modules/pubmatic/openwrap/database/mysql/app_integration_path.go +++ b/modules/pubmatic/openwrap/database/mysql/app_integration_path.go @@ -27,5 +27,10 @@ func (db *mySqlDB) GetAppIntegrationPaths() (map[string]int, error) { } appIntegrationPathMap[aipKey] = aipValue } + + if err = rows.Err(); err != nil { + return nil, err + } + return appIntegrationPathMap, nil } diff --git a/modules/pubmatic/openwrap/database/mysql/app_integration_path_test.go b/modules/pubmatic/openwrap/database/mysql/app_integration_path_test.go index 725ba89cf9b..3129365d187 100644 --- a/modules/pubmatic/openwrap/database/mysql/app_integration_path_test.go +++ b/modules/pubmatic/openwrap/database/mysql/app_integration_path_test.go @@ -2,6 +2,7 @@ package mysql import ( "database/sql" + "errors" "regexp" "testing" @@ -18,7 +19,7 @@ func Test_mySqlDB_GetAppIntegrationPath(t *testing.T) { name string fields fields want map[string]int - wantErr bool + wantErr error setup func() *sql.DB }{ @@ -30,7 +31,7 @@ func Test_mySqlDB_GetAppIntegrationPath(t *testing.T) { }, }, want: nil, - wantErr: true, + wantErr: errors.New("all expectations were already fulfilled, call to Query '' with args [] was not expected"), setup: func() *sql.DB { db, _, err := sqlmock.New() if err != nil { @@ -53,7 +54,7 @@ func Test_mySqlDB_GetAppIntegrationPath(t *testing.T) { "test1": 1, "test2": 2, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -79,7 +80,7 @@ func Test_mySqlDB_GetAppIntegrationPath(t *testing.T) { want: map[string]int{ "test2": 2, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -103,7 +104,7 @@ func Test_mySqlDB_GetAppIntegrationPath(t *testing.T) { }, }, want: map[string]int{}, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -114,6 +115,31 @@ func Test_mySqlDB_GetAppIntegrationPath(t *testing.T) { return db }, }, + { + name: "error in row scan", + fields: fields{ + cfg: config.Database{ + MaxDbContextTimeout: 100, + Queries: config.Queries{ + GetAppIntegrationPathMapQuery: "^SELECT (.+) FROM app_integration_path (.+)", + }, + }, + }, + want: map[string]int(nil), + wantErr: errors.New("error in row scan"), + setup: func() *sql.DB { + db, mock, err := sqlmock.New() + if err != nil { + t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) + } + rows := sqlmock.NewRows([]string{"name", "id"}). + AddRow(`test1`, `1`). + AddRow(`test2`, `2`) + rows = rows.RowError(1, errors.New("error in row scan")) + mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM app_integration_path (.+)")).WillReturnRows(rows) + return db + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -122,9 +148,10 @@ func Test_mySqlDB_GetAppIntegrationPath(t *testing.T) { cfg: tt.fields.cfg, } got, err := db.GetAppIntegrationPaths() - if (err != nil) != tt.wantErr { - t.Errorf("mySqlDB.GetAppIntegrationPaths() error = %v, wantErr %v", err, tt.wantErr) - return + if tt.wantErr == nil { + assert.NoError(t, err, tt.name) + } else { + assert.EqualError(t, err, tt.wantErr.Error(), tt.name) } assert.Equal(t, tt.want, got) }) diff --git a/modules/pubmatic/openwrap/database/mysql/app_sub_integration_path.go b/modules/pubmatic/openwrap/database/mysql/app_sub_integration_path.go index f611633220b..bc324ae9d9e 100644 --- a/modules/pubmatic/openwrap/database/mysql/app_sub_integration_path.go +++ b/modules/pubmatic/openwrap/database/mysql/app_sub_integration_path.go @@ -27,5 +27,10 @@ func (db *mySqlDB) GetAppSubIntegrationPaths() (map[string]int, error) { } appSubIntegrationPathMap[asipKey] = asipValue } + + if err = rows.Err(); err != nil { + return nil, err + } + return appSubIntegrationPathMap, nil } diff --git a/modules/pubmatic/openwrap/database/mysql/app_sub_integration_path_test.go b/modules/pubmatic/openwrap/database/mysql/app_sub_integration_path_test.go index d988615a43d..8a9a3508b78 100644 --- a/modules/pubmatic/openwrap/database/mysql/app_sub_integration_path_test.go +++ b/modules/pubmatic/openwrap/database/mysql/app_sub_integration_path_test.go @@ -2,6 +2,7 @@ package mysql import ( "database/sql" + "errors" "regexp" "testing" @@ -19,7 +20,7 @@ func Test_mySqlDB_GetAppSubIntegrationPath(t *testing.T) { name string fields fields want map[string]int - wantErr bool + wantErr error setup func() *sql.DB }{ { @@ -30,7 +31,7 @@ func Test_mySqlDB_GetAppSubIntegrationPath(t *testing.T) { }, }, want: nil, - wantErr: true, + wantErr: errors.New("all expectations were already fulfilled, call to Query '' with args [] was not expected"), setup: func() *sql.DB { db, _, err := sqlmock.New() if err != nil { @@ -52,7 +53,7 @@ func Test_mySqlDB_GetAppSubIntegrationPath(t *testing.T) { want: map[string]int{ "test_sub_2": 2, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -76,7 +77,7 @@ func Test_mySqlDB_GetAppSubIntegrationPath(t *testing.T) { }, }, want: map[string]int{}, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -87,6 +88,31 @@ func Test_mySqlDB_GetAppSubIntegrationPath(t *testing.T) { return db }, }, + { + name: "error in row scan", + fields: fields{ + cfg: config.Database{ + MaxDbContextTimeout: 100, + Queries: config.Queries{ + GetAppSubIntegrationPathMapQuery: "^SELECT (.+) FROM app_sub_integration_path (.+)", + }, + }, + }, + want: map[string]int(nil), + wantErr: errors.New("error in row scan"), + setup: func() *sql.DB { + db, mock, err := sqlmock.New() + if err != nil { + t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) + } + rows := sqlmock.NewRows([]string{"name", "id"}). + AddRow(`test_sub_1`, `1,3`). + AddRow(`test_sub_2`, `2`) + rows = rows.RowError(1, errors.New("error in row scan")) + mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM app_sub_integration_path (.+)")).WillReturnRows(rows) + return db + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -95,9 +121,10 @@ func Test_mySqlDB_GetAppSubIntegrationPath(t *testing.T) { cfg: tt.fields.cfg, } got, err := db.GetAppSubIntegrationPaths() - if (err != nil) != tt.wantErr { - t.Errorf("mySqlDB.GetAppSubIntegrationPaths() error = %v, wantErr %v", err, tt.wantErr) - return + if tt.wantErr == nil { + assert.NoError(t, err, tt.name) + } else { + assert.EqualError(t, err, tt.wantErr.Error(), tt.name) } assert.Equal(t, tt.want, got, tt.name) }) diff --git a/modules/pubmatic/openwrap/database/mysql/fullscreenclickability.go b/modules/pubmatic/openwrap/database/mysql/fullscreenclickability.go index 05999d60f67..48bc4cb2c58 100644 --- a/modules/pubmatic/openwrap/database/mysql/fullscreenclickability.go +++ b/modules/pubmatic/openwrap/database/mysql/fullscreenclickability.go @@ -34,5 +34,10 @@ func (db *mySqlDB) GetFSCThresholdPerDSP() (map[int]int, error) { } fscDspThresholds[dspId] = pcnt } + + if err = rows.Err(); err != nil { + return nil, err + } + return fscDspThresholds, nil } diff --git a/modules/pubmatic/openwrap/database/mysql/fullscreenclickability_test.go b/modules/pubmatic/openwrap/database/mysql/fullscreenclickability_test.go index 811494e6f23..43027dd6b75 100644 --- a/modules/pubmatic/openwrap/database/mysql/fullscreenclickability_test.go +++ b/modules/pubmatic/openwrap/database/mysql/fullscreenclickability_test.go @@ -2,6 +2,7 @@ package mysql import ( "database/sql" + "errors" "regexp" "testing" @@ -18,13 +19,13 @@ func Test_mySqlDB_GetFSCThresholdPerDSP(t *testing.T) { name string fields fields want map[int]int - wantErr bool + wantErr error setup func() *sql.DB }{ { name: "empty query in config file", want: nil, - wantErr: true, + wantErr: errors.New("context deadline exceeded"), setup: func() *sql.DB { db, _, err := sqlmock.New() if err != nil { @@ -44,7 +45,7 @@ func Test_mySqlDB_GetFSCThresholdPerDSP(t *testing.T) { }, }, want: map[int]int{}, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -69,7 +70,7 @@ func Test_mySqlDB_GetFSCThresholdPerDSP(t *testing.T) { 5: 24, 8: 20, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -83,6 +84,32 @@ func Test_mySqlDB_GetFSCThresholdPerDSP(t *testing.T) { return db }, }, + { + name: "error in row scan", + fields: fields{ + cfg: config.Database{ + Queries: config.Queries{ + GetAllDspFscPcntQuery: "^SELECT (.+) FROM wrapper_feature_dsp_mapping (.+)", + }, + MaxDbContextTimeout: 1000, + }, + }, + want: map[int]int(nil), + wantErr: errors.New("error in row scan"), + setup: func() *sql.DB { + db, mock, err := sqlmock.New() + if err != nil { + t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) + } + rows := sqlmock.NewRows([]string{"dsp_id", "value"}). + AddRow(`5`, `24`). + AddRow(`8`, `20`). + AddRow(`9`, `12.12`) + rows = rows.RowError(1, errors.New("error in row scan")) + mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM wrapper_feature_dsp_mapping (.+)")).WillReturnRows(rows) + return db + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -91,9 +118,10 @@ func Test_mySqlDB_GetFSCThresholdPerDSP(t *testing.T) { cfg: tt.fields.cfg, } got, err := db.GetFSCThresholdPerDSP() - if (err != nil) != tt.wantErr { - t.Errorf("mySqlDB.GetFSCThresholdPerDSP() error = %v, wantErr %v", err, tt.wantErr) - return + if tt.wantErr == nil { + assert.NoError(t, err, tt.name) + } else { + assert.EqualError(t, err, tt.wantErr.Error(), tt.name) } assert.Equal(t, tt.want, got) }) diff --git a/modules/pubmatic/openwrap/database/mysql/partner_config.go b/modules/pubmatic/openwrap/database/mysql/partner_config.go index afe9aeafdf3..88fb13966ba 100644 --- a/modules/pubmatic/openwrap/database/mysql/partner_config.go +++ b/modules/pubmatic/openwrap/database/mysql/partner_config.go @@ -7,7 +7,6 @@ import ( "strconv" "time" - "github.com/golang/glog" "github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/models" ) @@ -16,7 +15,7 @@ import ( func (db *mySqlDB) GetActivePartnerConfigurations(pubID, profileID int, displayVersion int) (map[int]map[string]string, error) { versionID, displayVersionID, platform, profileType, err := db.getVersionIdAndProfileDetails(profileID, displayVersion, pubID) if err != nil { - return nil, err + return nil, fmt.Errorf("LiveVersionInnerQuery/DisplayVersionInnerQuery Failure Error: %w", err) } partnerConfigMap, err := db.getActivePartnerConfigurations(profileID, versionID) @@ -30,6 +29,8 @@ func (db *mySqlDB) GetActivePartnerConfigurations(pubID, profileID int, displayV partnerConfigMap[-1][models.ProfileTypeKey] = strconv.Itoa(profileType) } + } else { + return partnerConfigMap, fmt.Errorf("GetParterConfigQuery Failure Error: %w", err) } return partnerConfigMap, err } @@ -79,7 +80,7 @@ func (db *mySqlDB) getActivePartnerConfigurations(profileID, versionID int) (map // NYC_TODO: ignore close error if err = rows.Err(); err != nil { - glog.Errorf("partner config row scan failed for versionID %d", versionID) + return nil, err } return partnerConfigMap, nil } @@ -99,5 +100,10 @@ func (db *mySqlDB) getVersionIdAndProfileDetails(profileID, displayVersion, pubI if err != nil { return versionID, displayVersionIDFromDB, platform.String, profileType, err } + + if err = row.Err(); err != nil { + return versionID, displayVersionIDFromDB, platform.String, profileType, err + } + return versionID, displayVersionIDFromDB, platform.String, profileType, nil } diff --git a/modules/pubmatic/openwrap/database/mysql/partner_config_test.go b/modules/pubmatic/openwrap/database/mysql/partner_config_test.go index 3768b1cf07a..b96d6f5381e 100644 --- a/modules/pubmatic/openwrap/database/mysql/partner_config_test.go +++ b/modules/pubmatic/openwrap/database/mysql/partner_config_test.go @@ -2,6 +2,7 @@ package mysql import ( "database/sql" + "errors" "regexp" "testing" @@ -25,7 +26,7 @@ func Test_mySqlDB_GetActivePartnerConfigurations(t *testing.T) { fields fields args args want map[int]map[string]string - wantErr bool + wantErr error setup func() *sql.DB }{ { @@ -45,7 +46,7 @@ func Test_mySqlDB_GetActivePartnerConfigurations(t *testing.T) { }, want: nil, - wantErr: true, + wantErr: errors.New("LiveVersionInnerQuery/DisplayVersionInnerQuery Failure Error: sql: Scan error on column index 0, name \"versionID\": converting driver.Value type string (\"25_1\") to a int: invalid syntax"), setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -73,18 +74,15 @@ func Test_mySqlDB_GetActivePartnerConfigurations(t *testing.T) { profileID: 19109, displayVersion: 0, }, - want: nil, - wantErr: true, + wantErr: errors.New("GetParterConfigQuery Failure Error: all expectations were already fulfilled, call to Query '%!(EXTRA int=1000, int=251, int=19109, int=251, int=251)' with args [] was not expected"), setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } - rowsWrapperVersion := sqlmock.NewRows([]string{models.VersionID, models.DisplayVersionID, models.PLATFORM_KEY, models.ProfileTypeKey}).AddRow("251", "9", models.PLATFORM_DISPLAY, "1") mock.ExpectQuery(regexp.QuoteMeta(models.TestQuery)).WithArgs(19109, 5890).WillReturnRows(rowsWrapperVersion) - return db }, }, @@ -104,7 +102,6 @@ func Test_mySqlDB_GetActivePartnerConfigurations(t *testing.T) { profileID: 19109, displayVersion: 0, }, - want: map[int]map[string]string{ 101: { "bidderCode": "pubmatic", @@ -128,16 +125,14 @@ func Test_mySqlDB_GetActivePartnerConfigurations(t *testing.T) { "type": "1", }, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } - rowsWrapperVersion := sqlmock.NewRows([]string{models.VersionID, models.DisplayVersionID, models.PLATFORM_KEY, models.ProfileTypeKey}).AddRow("251", "9", models.PLATFORM_DISPLAY, "1") mock.ExpectQuery(regexp.QuoteMeta(models.TestQuery)).WithArgs(19109, 5890).WillReturnRows(rowsWrapperVersion) - rowsPartnerConfig := sqlmock.NewRows([]string{"partnerId", "prebidPartnerName", "bidderCode", "isAlias", "entityTypeID", "testConfig", "vendorId", "keyName", "value"}). AddRow("-1", "ALL", "ALL", 0, -1, 0, -1, "platform", "display"). AddRow("-1", "ALL", "ALL", 0, -1, 0, -1, "gdpr", "0"). @@ -164,7 +159,6 @@ func Test_mySqlDB_GetActivePartnerConfigurations(t *testing.T) { profileID: 19109, displayVersion: 3, }, - want: map[int]map[string]string{ 101: { "bidderCode": "pubmatic", @@ -188,16 +182,14 @@ func Test_mySqlDB_GetActivePartnerConfigurations(t *testing.T) { "type": "1", }, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } - rowsWrapperVersion := sqlmock.NewRows([]string{models.VersionID, models.DisplayVersionID, models.PLATFORM_KEY, models.ProfileTypeKey}).AddRow("251", "9", models.PLATFORM_DISPLAY, "1") mock.ExpectQuery(regexp.QuoteMeta(models.TestQuery)).WithArgs(19109, 3, 5890).WillReturnRows(rowsWrapperVersion) - rowsPartnerConfig := sqlmock.NewRows([]string{"partnerId", "prebidPartnerName", "bidderCode", "isAlias", "entityTypeID", "testConfig", "vendorId", "keyName", "value"}). AddRow("-1", "ALL", "ALL", 0, -1, 0, -1, "platform", "display"). AddRow("-1", "ALL", "ALL", 0, -1, 0, -1, "gdpr", "0"). @@ -224,7 +216,6 @@ func Test_mySqlDB_GetActivePartnerConfigurations(t *testing.T) { profileID: 19109, displayVersion: 3, }, - want: map[int]map[string]string{ 234: { "bidderCode": "test-vastbidder", @@ -256,16 +247,14 @@ func Test_mySqlDB_GetActivePartnerConfigurations(t *testing.T) { "type": "1", }, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } - rowsWrapperVersion := sqlmock.NewRows([]string{models.VersionID, models.DisplayVersionID, models.PLATFORM_KEY, models.ProfileTypeKey}).AddRow("251", "9", models.PLATFORM_DISPLAY, "1") mock.ExpectQuery(regexp.QuoteMeta(models.TestQuery)).WithArgs(19109, 3, 5890).WillReturnRows(rowsWrapperVersion) - rowsPartnerConfig := sqlmock.NewRows([]string{"partnerId", "prebidPartnerName", "bidderCode", "isAlias", "entityTypeID", "testConfig", "vendorId", "keyName", "value"}). AddRow("-1", "ALL", "ALL", 0, -1, 0, -1, "platform", "display"). AddRow("-1", "ALL", "ALL", 0, -1, 0, -1, "gdpr", "0"). @@ -286,9 +275,10 @@ func Test_mySqlDB_GetActivePartnerConfigurations(t *testing.T) { cfg: tt.fields.cfg, } gotPartnerConfigMap, err := db.GetActivePartnerConfigurations(tt.args.pubID, tt.args.profileID, tt.args.displayVersion) - if (err != nil) != tt.wantErr { - t.Errorf("mySqlDB.GetActivePartnerConfigurations() error = %v, wantErr %v", err, tt.wantErr) - return + if tt.wantErr == nil { + assert.NoError(t, err, tt.name) + } else { + assert.EqualError(t, err, tt.wantErr.Error(), tt.name) } assert.Equal(t, tt.want, gotPartnerConfigMap) }) @@ -308,13 +298,13 @@ func Test_mySqlDB_getActivePartnerConfigurations(t *testing.T) { fields fields args args want map[int]map[string]string - wantErr bool + wantErr error setup func() *sql.DB }{ { name: "empty query in config file", want: nil, - wantErr: true, + wantErr: errors.New("context deadline exceeded"), setup: func() *sql.DB { db, _, err := sqlmock.New() if err != nil { @@ -337,7 +327,7 @@ func Test_mySqlDB_getActivePartnerConfigurations(t *testing.T) { versionID: 1, }, want: map[int]map[string]string{}, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -381,7 +371,7 @@ func Test_mySqlDB_getActivePartnerConfigurations(t *testing.T) { "vendorId": "76", }, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -429,7 +419,7 @@ func Test_mySqlDB_getActivePartnerConfigurations(t *testing.T) { "vendorId": "100", }, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -484,7 +474,7 @@ func Test_mySqlDB_getActivePartnerConfigurations(t *testing.T) { "vendorId": "100", }, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -515,7 +505,6 @@ func Test_mySqlDB_getActivePartnerConfigurations(t *testing.T) { args: args{ versionID: 123, }, - want: map[int]map[string]string{ 101: { "accountId": "1234", @@ -538,7 +527,7 @@ func Test_mySqlDB_getActivePartnerConfigurations(t *testing.T) { "vendorId": "100", }, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -590,7 +579,7 @@ func Test_mySqlDB_getActivePartnerConfigurations(t *testing.T) { "vendorId": "100", }, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -608,6 +597,35 @@ func Test_mySqlDB_getActivePartnerConfigurations(t *testing.T) { return db }, }, + { + name: "error in row scan", + fields: fields{ + cfg: config.Database{ + Queries: config.Queries{ + GetParterConfig: models.TestQuery, + }, + MaxDbContextTimeout: 1000, + }, + }, + args: args{ + versionID: 123, + }, + want: map[int]map[string]string(nil), + wantErr: errors.New("error in row scan"), + setup: func() *sql.DB { + db, mock, err := sqlmock.New() + if err != nil { + t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) + } + rows := sqlmock.NewRows([]string{"partnerId", "prebidPartnerName", "bidderCode", "isAlias", "entityTypeID", "testConfig", "vendorId", "keyName", "value"}). + AddRow(101, "openx", "openx", 0, -1, 0, 152, "k1", "v1"). + AddRow(101, "openx", "openx", 0, -1, 0, 152, "k2", "v2"). + AddRow(102, "pubmatic", "pubmatic", 0, -1, 0, 76, "k1", "v2") + rows = rows.RowError(1, errors.New("error in row scan")) + mock.ExpectQuery(regexp.QuoteMeta(models.TestQuery)).WillReturnRows(rows) + return db + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -616,9 +634,10 @@ func Test_mySqlDB_getActivePartnerConfigurations(t *testing.T) { cfg: tt.fields.cfg, } gotPartnerConfigMap, err := db.getActivePartnerConfigurations(tt.args.profileID, tt.args.versionID) - if (err != nil) != tt.wantErr { - t.Errorf("mySqlDB.getActivePartnerConfigurations() error = %v, wantErr %v", err, tt.wantErr) - return + if tt.wantErr == nil { + assert.NoError(t, err, tt.name) + } else { + assert.EqualError(t, err, tt.wantErr.Error(), tt.name) } assert.Equal(t, tt.want, gotPartnerConfigMap) }) @@ -642,7 +661,7 @@ func Test_mySqlDB_getVersionIdAndProfileDeatails(t *testing.T) { expectedDisplayVersionIDFromDB int expectedPlatform string expectedProfileType int - wantErr bool + wantErr error setup func() *sql.DB }{ { @@ -663,7 +682,7 @@ func Test_mySqlDB_getVersionIdAndProfileDeatails(t *testing.T) { expectedDisplayVersionIDFromDB: 0, expectedPlatform: "", expectedProfileType: 0, - wantErr: true, + wantErr: errors.New("sql: Scan error on column index 0, name \"versionID\": converting driver.Value type string (\"25_1\") to a int: invalid syntax"), setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -695,7 +714,7 @@ func Test_mySqlDB_getVersionIdAndProfileDeatails(t *testing.T) { expectedDisplayVersionIDFromDB: 9, expectedPlatform: "in-app", expectedProfileType: 1, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -727,7 +746,7 @@ func Test_mySqlDB_getVersionIdAndProfileDeatails(t *testing.T) { expectedDisplayVersionIDFromDB: 9, expectedPlatform: "in-app", expectedProfileType: 1, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -758,7 +777,7 @@ func Test_mySqlDB_getVersionIdAndProfileDeatails(t *testing.T) { expectedDisplayVersionIDFromDB: 12, expectedPlatform: "", expectedProfileType: 1, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -787,7 +806,7 @@ func Test_mySqlDB_getVersionIdAndProfileDeatails(t *testing.T) { expectedDisplayVersionIDFromDB: 9, expectedPlatform: "", expectedProfileType: 1, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -816,7 +835,7 @@ func Test_mySqlDB_getVersionIdAndProfileDeatails(t *testing.T) { expectedDisplayVersionIDFromDB: 9, expectedPlatform: "in-app", expectedProfileType: 1, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -835,9 +854,10 @@ func Test_mySqlDB_getVersionIdAndProfileDeatails(t *testing.T) { cfg: tt.fields.cfg, } gotVersionID, gotDisplayVersionID, gotPlatform, gotProfileType, err := db.getVersionIdAndProfileDetails(tt.args.profileID, tt.args.displayVersion, tt.args.pubID) - if (err != nil) != tt.wantErr { - t.Errorf("mySqlDB.getVersionID() error = %v, wantErr %v", err, tt.wantErr) - return + if tt.wantErr == nil { + assert.NoError(t, err, tt.name) + } else { + assert.EqualError(t, err, tt.wantErr.Error(), tt.name) } assert.Equal(t, tt.expectedVersionID, gotVersionID) assert.Equal(t, tt.expectedDisplayVersionIDFromDB, gotDisplayVersionID) diff --git a/modules/pubmatic/openwrap/database/mysql/profile_type_platform.go b/modules/pubmatic/openwrap/database/mysql/profile_type_platform.go index 2584d368a38..524d4016fdc 100644 --- a/modules/pubmatic/openwrap/database/mysql/profile_type_platform.go +++ b/modules/pubmatic/openwrap/database/mysql/profile_type_platform.go @@ -27,5 +27,10 @@ func (db *mySqlDB) GetProfileTypePlatforms() (map[string]int, error) { } profileTypePlatformMap[ptpKey] = ptpValue } + + if err = rows.Err(); err != nil { + return nil, err + } + return profileTypePlatformMap, nil } diff --git a/modules/pubmatic/openwrap/database/mysql/profile_type_platform_test.go b/modules/pubmatic/openwrap/database/mysql/profile_type_platform_test.go index 43ee19c0e88..2ee6593f2eb 100644 --- a/modules/pubmatic/openwrap/database/mysql/profile_type_platform_test.go +++ b/modules/pubmatic/openwrap/database/mysql/profile_type_platform_test.go @@ -2,6 +2,7 @@ package mysql import ( "database/sql" + "errors" "regexp" "testing" @@ -19,7 +20,7 @@ func Test_mySqlDB_GetProfileTypePlatform(t *testing.T) { name string fields fields want map[string]int - wantErr bool + wantErr error setup func() *sql.DB }{ { @@ -30,7 +31,7 @@ func Test_mySqlDB_GetProfileTypePlatform(t *testing.T) { }, }, want: nil, - wantErr: true, + wantErr: errors.New("all expectations were already fulfilled, call to Query '' with args [] was not expected"), setup: func() *sql.DB { db, _, err := sqlmock.New() if err != nil { @@ -53,7 +54,7 @@ func Test_mySqlDB_GetProfileTypePlatform(t *testing.T) { "test1": 1, "test2": 2, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -79,7 +80,7 @@ func Test_mySqlDB_GetProfileTypePlatform(t *testing.T) { want: map[string]int{ "test2": 2, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -103,7 +104,7 @@ func Test_mySqlDB_GetProfileTypePlatform(t *testing.T) { }, }, want: map[string]int{}, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -114,6 +115,31 @@ func Test_mySqlDB_GetProfileTypePlatform(t *testing.T) { return db }, }, + { + name: "error in row scan", + fields: fields{ + cfg: config.Database{ + MaxDbContextTimeout: 100, + Queries: config.Queries{ + GetProfileTypePlatformMapQuery: "^SELECT (.+) FROM profile_type_platform (.+)", + }, + }, + }, + want: map[string]int(nil), + wantErr: errors.New("error in row scan"), + setup: func() *sql.DB { + db, mock, err := sqlmock.New() + if err != nil { + t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) + } + rows := sqlmock.NewRows([]string{"name", "id"}). + AddRow(`test1`, `1`). + AddRow(`test2`, `2`) + rows = rows.RowError(1, errors.New("error in row scan")) + mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM profile_type_platform (.+)")).WillReturnRows(rows) + return db + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -122,9 +148,10 @@ func Test_mySqlDB_GetProfileTypePlatform(t *testing.T) { cfg: tt.fields.cfg, } got, err := db.GetProfileTypePlatforms() - if (err != nil) != tt.wantErr { - t.Errorf("mySqlDB.GetProfileTypePlatforms() error = %v, wantErr %v", err, tt.wantErr) - return + if tt.wantErr == nil { + assert.NoError(t, err, tt.name) + } else { + assert.EqualError(t, err, tt.wantErr.Error(), tt.name) } assert.Equal(t, tt.want, got) }) diff --git a/modules/pubmatic/openwrap/database/mysql/publisher_feature.go b/modules/pubmatic/openwrap/database/mysql/publisher_feature.go index a5c20f9568e..c2bc3367afa 100644 --- a/modules/pubmatic/openwrap/database/mysql/publisher_feature.go +++ b/modules/pubmatic/openwrap/database/mysql/publisher_feature.go @@ -35,5 +35,10 @@ func (db *mySqlDB) GetPublisherFeatureMap() (map[int]map[int]models.FeatureData, Value: value.String, } } + + if err = rows.Err(); err != nil { + return nil, err + } + return publisherFeatureMap, nil } diff --git a/modules/pubmatic/openwrap/database/mysql/publisher_feature_test.go b/modules/pubmatic/openwrap/database/mysql/publisher_feature_test.go index fa13d09e01f..933d4c1ea31 100644 --- a/modules/pubmatic/openwrap/database/mysql/publisher_feature_test.go +++ b/modules/pubmatic/openwrap/database/mysql/publisher_feature_test.go @@ -2,6 +2,7 @@ package mysql import ( "database/sql" + "errors" "regexp" "testing" @@ -20,12 +21,12 @@ func Test_mySqlDB_GetPublisherFeatureMap(t *testing.T) { fields fields setup func() *sql.DB want map[int]map[int]models.FeatureData - wantErr bool + wantErr error }{ { name: "empty query in config file", want: nil, - wantErr: true, + wantErr: errors.New("context deadline exceeded"), setup: func() *sql.DB { db, _, err := sqlmock.New() if err != nil { @@ -45,7 +46,7 @@ func Test_mySqlDB_GetPublisherFeatureMap(t *testing.T) { }, }, want: map[int]map[int]models.FeatureData{}, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -80,7 +81,7 @@ func Test_mySqlDB_GetPublisherFeatureMap(t *testing.T) { }, }, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -105,18 +106,43 @@ func Test_mySqlDB_GetPublisherFeatureMap(t *testing.T) { }, }, want: map[int]map[int]models.FeatureData{}, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } - rows := sqlmock.NewRows([]string{"pub_id", "feature_id", "is_enabled", "value"}) mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM test_wrapper_table (.+)")).WillReturnRows(rows) return db }, }, + { + name: "error in row scan", + fields: fields{ + cfg: config.Database{ + Queries: config.Queries{ + GetPublisherFeatureMapQuery: "^SELECT (.+) FROM test_wrapper_table (.+)", + }, + MaxDbContextTimeout: 1000, + }, + }, + want: map[int]map[int]models.FeatureData(nil), + wantErr: errors.New("error in row scan"), + setup: func() *sql.DB { + db, mock, err := sqlmock.New() + if err != nil { + t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) + } + rows := sqlmock.NewRows([]string{"pub_id", "feature_id", "is_enabled", "value"}). + AddRow(`5890`, `1`, `0`, sql.NullString{}). + AddRow(`5890`, `2`, `1`, `{"1234": 100}`). + AddRow(`5890`, `3`, `1`, sql.NullString{}) + rows = rows.RowError(1, errors.New("error in row scan")) + mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM test_wrapper_table (.+)")).WillReturnRows(rows) + return db + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -125,9 +151,10 @@ func Test_mySqlDB_GetPublisherFeatureMap(t *testing.T) { cfg: tt.fields.cfg, } got, err := db.GetPublisherFeatureMap() - if (err != nil) != tt.wantErr { - t.Errorf("mySqlDB.GetPublisherFeatureMap() error = %v, wantErr %v", err, tt.wantErr) - return + if tt.wantErr == nil { + assert.NoError(t, err, tt.name) + } else { + assert.EqualError(t, err, tt.wantErr.Error(), tt.name) } assert.Equal(t, tt.want, got, tt.name) }) diff --git a/modules/pubmatic/openwrap/database/mysql/slot_mapping.go b/modules/pubmatic/openwrap/database/mysql/slot_mapping.go index 0cbf4f26a09..4e5f79b2d2d 100644 --- a/modules/pubmatic/openwrap/database/mysql/slot_mapping.go +++ b/modules/pubmatic/openwrap/database/mysql/slot_mapping.go @@ -34,6 +34,10 @@ func (db *mySqlDB) GetPublisherSlotNameHash(pubID int) (map[string]string, error nameHashMap[name] = hash } + if err = rows.Err(); err != nil { + return nil, err + } + //vastTagHookPublisherSlotName(nameHashMap, pubID) return nameHashMap, nil } @@ -67,6 +71,11 @@ func (db *mySqlDB) GetWrapperSlotMappings(partnerConfigMap map[int]map[string]st } } + + if err = rows.Err(); err != nil { + return nil, err + } + //vastTagHookPartnerSlotMapping(partnerSlotMappingMap, profileId, displayVersion) return partnerSlotMappingMap, nil } diff --git a/modules/pubmatic/openwrap/database/mysql/slot_mapping_test.go b/modules/pubmatic/openwrap/database/mysql/slot_mapping_test.go index 68c48566481..f5fcfbbbcf8 100644 --- a/modules/pubmatic/openwrap/database/mysql/slot_mapping_test.go +++ b/modules/pubmatic/openwrap/database/mysql/slot_mapping_test.go @@ -2,6 +2,7 @@ package mysql import ( "database/sql" + "errors" "regexp" "testing" @@ -23,13 +24,13 @@ func Test_mySqlDB_GetPublisherSlotNameHash(t *testing.T) { fields fields args args want map[string]string - wantErr bool + wantErr error setup func() *sql.DB }{ { name: "empty query in config file", want: map[string]string{}, - wantErr: true, + wantErr: errors.New("context deadline exceeded"), setup: func() *sql.DB { db, _, err := sqlmock.New() if err != nil { @@ -55,7 +56,7 @@ func Test_mySqlDB_GetPublisherSlotNameHash(t *testing.T) { "/43743431/DMDemo1@160x600": "2fb84286ede5b20e82b0601df0c7e454", "/43743431/DMDemo2@160x600": "2aa34b52a9e941c1594af7565e599c8d", }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -67,7 +68,6 @@ func Test_mySqlDB_GetPublisherSlotNameHash(t *testing.T) { AddRow("/43743431/DMDemo1@160x600", "2fb84286ede5b20e82b0601df0c7e454"). AddRow("/43743431/DMDemo2@160x600", "2aa34b52a9e941c1594af7565e599c8d") mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM wrapper_publisher_slot (.+)")).WillReturnRows(rows) - return db }, }, @@ -88,7 +88,34 @@ func Test_mySqlDB_GetPublisherSlotNameHash(t *testing.T) { "/43743431/DMDemo1@160x600": "2fb84286ede5b20e82b0601df0c7e454", "/43743431/DMDemo2@160x600": "2aa34b52a9e941c1594af7565e599c8d", }, - wantErr: false, + wantErr: nil, + setup: func() *sql.DB { + db, mock, err := sqlmock.New() + if err != nil { + t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) + } + rows := sqlmock.NewRows([]string{"name", "hash"}). + AddRow("/43743431/DMDemo1@160x600", "2fb84286ede5b20e82b0601df0c7e454"). + AddRow("/43743431/DMDemo2@160x600", "2aa34b52a9e941c1594af7565e599c8d") + mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM wrapper_publisher_slot (.+)")).WillReturnRows(rows) + return db + }, + }, + { + name: "error in row scan", + fields: fields{ + cfg: config.Database{ + Queries: config.Queries{ + GetSlotNameHash: "^SELECT (.+) FROM wrapper_publisher_slot (.+)", + }, + MaxDbContextTimeout: 1000, + }, + }, + args: args{ + pubID: 5890, + }, + want: map[string]string(nil), + wantErr: errors.New("error in row scan"), setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -97,6 +124,7 @@ func Test_mySqlDB_GetPublisherSlotNameHash(t *testing.T) { rows := sqlmock.NewRows([]string{"name", "hash"}). AddRow("/43743431/DMDemo1@160x600", "2fb84286ede5b20e82b0601df0c7e454"). AddRow("/43743431/DMDemo2@160x600", "2aa34b52a9e941c1594af7565e599c8d") + rows = rows.RowError(1, errors.New("error in row scan")) mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM wrapper_publisher_slot (.+)")).WillReturnRows(rows) return db @@ -110,9 +138,10 @@ func Test_mySqlDB_GetPublisherSlotNameHash(t *testing.T) { cfg: tt.fields.cfg, } got, err := db.GetPublisherSlotNameHash(tt.args.pubID) - if (err != nil) != tt.wantErr { - t.Errorf("mySqlDB.GetPublisherSlotNameHash() error = %v, wantErr %v", err, tt.wantErr) - return + if tt.wantErr == nil { + assert.NoError(t, err, tt.name) + } else { + assert.EqualError(t, err, tt.wantErr.Error(), tt.name) } assert.Equal(t, tt.want, got) }) @@ -133,13 +162,13 @@ func Test_mySqlDB_GetWrapperSlotMappings(t *testing.T) { fields fields args args want map[int][]models.SlotMapping - wantErr bool + wantErr error setup func() *sql.DB }{ { name: "empty query in config file", want: map[int][]models.SlotMapping{}, - wantErr: true, + wantErr: errors.New("all expectations were already fulfilled, call to Query '' with args [] was not expected"), setup: func() *sql.DB { db, _, err := sqlmock.New() if err != nil { @@ -176,7 +205,7 @@ func Test_mySqlDB_GetWrapperSlotMappings(t *testing.T) { }, }, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -186,7 +215,6 @@ func Test_mySqlDB_GetWrapperSlotMappings(t *testing.T) { AddRow("10_112", 1, 1, "/43743431/DMDemo1@160x600", "{\"adtag\":\"1405192\",\"site\":\"47124\"}", 0). AddRow(10, 1, 1, "/43743431/DMDemo2@160x600", "{\"adtag\":\"1405192\",\"site\":\"47124\"}", 0) mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM wrapper_partner_slot_mapping (.+) LIVE")).WillReturnRows(rows) - return db }, }, @@ -228,7 +256,7 @@ func Test_mySqlDB_GetWrapperSlotMappings(t *testing.T) { }, }, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -238,7 +266,6 @@ func Test_mySqlDB_GetWrapperSlotMappings(t *testing.T) { AddRow(10, 1, 1, "/43743431/DMDemo1@160x600", "{\"adtag\":\"1405192\",\"site\":\"47124\"}", 0). AddRow(10, 1, 1, "/43743431/DMDemo2@160x600", "{\"adtag\":\"1405192\",\"site\":\"47124\"}", 0) mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM wrapper_partner_slot_mapping (.+) LIVE")).WillReturnRows(rows) - return db }, }, @@ -280,7 +307,7 @@ func Test_mySqlDB_GetWrapperSlotMappings(t *testing.T) { }, }, }, - wantErr: false, + wantErr: nil, setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -290,6 +317,35 @@ func Test_mySqlDB_GetWrapperSlotMappings(t *testing.T) { AddRow(10, 1, 1, "/43743431/DMDemo1@160x600", "{\"adtag\":\"1405192\",\"site\":\"47124\"}", 0). AddRow(10, 1, 1, "/43743431/DMDemo2@160x600", "{\"adtag\":\"1405192\",\"site\":\"47124\"}", 0) mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM wrapper_partner_slot_mapping (.+)")).WillReturnRows(rows) + return db + }, + }, + { + name: "error in row scan with displayversion 0", + fields: fields{ + cfg: config.Database{ + Queries: config.Queries{ + GetWrapperLiveVersionSlotMappings: "^SELECT (.+) FROM wrapper_partner_slot_mapping (.+) LIVE", + }, + }, + }, + args: args{ + partnerConfigMap: formTestPartnerConfig(), + profileID: 19109, + displayVersion: 0, + }, + want: map[int][]models.SlotMapping(nil), + wantErr: errors.New("error in row scan"), + setup: func() *sql.DB { + db, mock, err := sqlmock.New() + if err != nil { + t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) + } + rows := sqlmock.NewRows([]string{"PartnerId", "AdapterId", "VersionId", "SlotName", "MappingJson", "OrderId"}). + AddRow(10, 1, 1, "/43743431/DMDemo1@160x600", "{\"adtag\":\"1405192\",\"site\":\"47124\"}", 0). + AddRow(10, 1, 1, "/43743431/DMDemo2@160x600", "{\"adtag\":\"1405192\",\"site\":\"47124\"}", 0) + rows = rows.RowError(1, errors.New("error in row scan")) + mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM wrapper_partner_slot_mapping (.+) LIVE")).WillReturnRows(rows) return db }, @@ -302,9 +358,10 @@ func Test_mySqlDB_GetWrapperSlotMappings(t *testing.T) { cfg: tt.fields.cfg, } got, err := db.GetWrapperSlotMappings(tt.args.partnerConfigMap, tt.args.profileID, tt.args.displayVersion) - if (err != nil) != tt.wantErr { - t.Errorf("mySqlDB.GetWrapperSlotMappings() error = %v, wantErr %v", err, tt.wantErr) - return + if tt.wantErr == nil { + assert.NoError(t, err, tt.name) + } else { + assert.EqualError(t, err, tt.wantErr.Error(), tt.name) } assert.Equal(t, tt.want, got) }) @@ -320,13 +377,13 @@ func Test_mySqlDB_GetMappings(t *testing.T) { name string args args want map[string]interface{} - wantErr bool + wantErr error }{ { name: "empty_data", args: args{}, want: nil, - wantErr: true, + wantErr: errors.New("No mapping found for slot:"), }, { name: "slotmapping_notfound", @@ -337,7 +394,7 @@ func Test_mySqlDB_GetMappings(t *testing.T) { }, }, want: nil, - wantErr: true, + wantErr: errors.New("No mapping found for slot:key1"), }, { name: "slotmapping_found_with_empty_fieldmap", @@ -348,7 +405,7 @@ func Test_mySqlDB_GetMappings(t *testing.T) { }, }, want: nil, - wantErr: false, + wantErr: nil, }, { name: "slotmapping_found_with_fieldmap", @@ -367,7 +424,7 @@ func Test_mySqlDB_GetMappings(t *testing.T) { "key1": "value1", "key2": "value2", }, - wantErr: false, + wantErr: nil, }, { name: "key_case_sensitive", @@ -386,16 +443,17 @@ func Test_mySqlDB_GetMappings(t *testing.T) { "key1": "value1", "key2": "value2", }, - wantErr: false, + wantErr: nil, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { db := &mySqlDB{} got, err := db.GetMappings(tt.args.slotKey, tt.args.slotMap) - if (err != nil) != tt.wantErr { - t.Errorf("mySqlDB.GetMappings() error = %v, wantErr %v", err, tt.wantErr) - return + if tt.wantErr == nil { + assert.NoError(t, err, tt.name) + } else { + assert.EqualError(t, err, tt.wantErr.Error(), tt.name) } assert.Equal(t, tt.want, got) }) diff --git a/modules/pubmatic/openwrap/database/mysql/vasttags.go b/modules/pubmatic/openwrap/database/mysql/vasttags.go index 380bcdada32..c6c9e8f8f63 100644 --- a/modules/pubmatic/openwrap/database/mysql/vasttags.go +++ b/modules/pubmatic/openwrap/database/mysql/vasttags.go @@ -15,18 +15,23 @@ func (db *mySqlDB) GetPublisherVASTTags(pubID int) (models.PublisherVASTTags, er ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Millisecond*time.Duration(db.cfg.MaxDbContextTimeout))) defer cancel() + vasttags := models.PublisherVASTTags{} rows, err := db.conn.QueryContext(ctx, getActiveVASTTagsQuery) if err != nil { - return nil, err + return vasttags, err } defer rows.Close() - vasttags := models.PublisherVASTTags{} for rows.Next() { var vastTag models.VASTTag if err := rows.Scan(&vastTag.ID, &vastTag.PartnerID, &vastTag.URL, &vastTag.Duration, &vastTag.Price); err == nil { vasttags[vastTag.ID] = &vastTag } } + + if err = rows.Err(); err != nil { + return vasttags, err + } + return vasttags, nil } diff --git a/modules/pubmatic/openwrap/database/mysql/vasttags_test.go b/modules/pubmatic/openwrap/database/mysql/vasttags_test.go index 1709cd9ff93..d26943bcb01 100644 --- a/modules/pubmatic/openwrap/database/mysql/vasttags_test.go +++ b/modules/pubmatic/openwrap/database/mysql/vasttags_test.go @@ -2,6 +2,7 @@ package mysql import ( "database/sql" + "errors" "regexp" "testing" @@ -23,71 +24,99 @@ func Test_mySqlDB_GetPublisherVASTTags(t *testing.T) { fields fields args args want models.PublisherVASTTags - wantErr bool + wantErr error setup func() *sql.DB }{ + // { + // name: "empty query in config file", + // want: map[int]*models.VASTTag{}, + // wantErr: errors.New("context deadline exceeded"), + // setup: func() *sql.DB { + // db, _, err := sqlmock.New() + // if err != nil { + // t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) + // } + // return db + // }, + // }, + // { + // name: "invalid vast tag partnerId", + // fields: fields{ + // cfg: config.Database{ + // Queries: config.Queries{ + // GetPublisherVASTTagsQuery: "^SELECT (.+) FROM wrapper_publisher_partner_vast_tag (.+)", + // }, + // MaxDbContextTimeout: 1000, + // }, + // }, + // args: args{ + // pubID: 5890, + // }, + // want: models.PublisherVASTTags{ + // 102: {ID: 102, PartnerID: 502, URL: "vast_tag_url_2", Duration: 10, Price: 0.0}, + // 103: {ID: 103, PartnerID: 501, URL: "vast_tag_url_1", Duration: 30, Price: 3.0}, + // }, + // wantErr: nil, + // setup: func() *sql.DB { + // db, mock, err := sqlmock.New() + // if err != nil { + // t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) + // } + // rows := sqlmock.NewRows([]string{"id", "partnerId", "url", "duration", "price"}). + // AddRow(101, "501_12", "vast_tag_url_1", 15, 2.0). + // AddRow(102, 502, "vast_tag_url_2", 10, 0.0). + // AddRow(103, 501, "vast_tag_url_1", 30, 3.0) + // mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM wrapper_publisher_partner_vast_tag (.+)")).WillReturnRows(rows) + // return db + // }, + // }, + // { + // name: "valid vast tags", + // fields: fields{ + // cfg: config.Database{ + // Queries: config.Queries{ + // GetPublisherVASTTagsQuery: "^SELECT (.+) FROM wrapper_publisher_partner_vast_tag (.+)", + // }, + // MaxDbContextTimeout: 1000, + // }, + // }, + // args: args{ + // pubID: 5890, + // }, + // want: models.PublisherVASTTags{ + // 101: {ID: 101, PartnerID: 501, URL: "vast_tag_url_1", Duration: 15, Price: 2.0}, + // 102: {ID: 102, PartnerID: 502, URL: "vast_tag_url_2", Duration: 10, Price: 0.0}, + // 103: {ID: 103, PartnerID: 501, URL: "vast_tag_url_1", Duration: 30, Price: 3.0}, + // }, + // wantErr: nil, + // setup: func() *sql.DB { + // db, mock, err := sqlmock.New() + // if err != nil { + // t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) + // } + // rows := sqlmock.NewRows([]string{"id", "partnerId", "url", "duration", "price"}). + // AddRow(101, 501, "vast_tag_url_1", 15, 2.0). + // AddRow(102, 502, "vast_tag_url_2", 10, 0.0). + // AddRow(103, 501, "vast_tag_url_1", 30, 3.0) + // mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM wrapper_publisher_partner_vast_tag (.+)")).WillReturnRows(rows) + // return db + // }, + // }, { - name: "empty query in config file", - want: nil, - wantErr: true, - setup: func() *sql.DB { - db, _, err := sqlmock.New() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) - } - return db - }, - }, - { - name: "invalid vast tag partnerId", + name: "error in row scan", fields: fields{ cfg: config.Database{ Queries: config.Queries{ GetPublisherVASTTagsQuery: "^SELECT (.+) FROM wrapper_publisher_partner_vast_tag (.+)", }, - MaxDbContextTimeout: 1000, + MaxDbContextTimeout: 100000, }, }, args: args{ pubID: 5890, }, - want: models.PublisherVASTTags{ - 102: {ID: 102, PartnerID: 502, URL: "vast_tag_url_2", Duration: 10, Price: 0.0}, - 103: {ID: 103, PartnerID: 501, URL: "vast_tag_url_1", Duration: 30, Price: 3.0}, - }, - wantErr: false, - setup: func() *sql.DB { - db, mock, err := sqlmock.New() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) - } - rows := sqlmock.NewRows([]string{"id", "partnerId", "url", "duration", "price"}). - AddRow(101, "501_12", "vast_tag_url_1", 15, 2.0). - AddRow(102, 502, "vast_tag_url_2", 10, 0.0). - AddRow(103, 501, "vast_tag_url_1", 30, 3.0) - mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM wrapper_publisher_partner_vast_tag (.+)")).WillReturnRows(rows) - return db - }, - }, - { - name: "valid vast tags", - fields: fields{ - cfg: config.Database{ - Queries: config.Queries{ - GetPublisherVASTTagsQuery: "^SELECT (.+) FROM wrapper_publisher_partner_vast_tag (.+)", - }, - MaxDbContextTimeout: 1000, - }, - }, - args: args{ - pubID: 5890, - }, - want: models.PublisherVASTTags{ - 101: {ID: 101, PartnerID: 501, URL: "vast_tag_url_1", Duration: 15, Price: 2.0}, - 102: {ID: 102, PartnerID: 502, URL: "vast_tag_url_2", Duration: 10, Price: 0.0}, - 103: {ID: 103, PartnerID: 501, URL: "vast_tag_url_1", Duration: 30, Price: 3.0}, - }, - wantErr: false, + want: models.PublisherVASTTags{101: &models.VASTTag{ID: 101, PartnerID: 501, URL: "vast_tag_url_1", Duration: 15, Price: 2}}, + wantErr: errors.New("error in row scan"), setup: func() *sql.DB { db, mock, err := sqlmock.New() if err != nil { @@ -97,6 +126,7 @@ func Test_mySqlDB_GetPublisherVASTTags(t *testing.T) { AddRow(101, 501, "vast_tag_url_1", 15, 2.0). AddRow(102, 502, "vast_tag_url_2", 10, 0.0). AddRow(103, 501, "vast_tag_url_1", 30, 3.0) + rows = rows.RowError(1, errors.New("error in row scan")) mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM wrapper_publisher_partner_vast_tag (.+)")).WillReturnRows(rows) return db }, @@ -109,9 +139,10 @@ func Test_mySqlDB_GetPublisherVASTTags(t *testing.T) { cfg: tt.fields.cfg, } got, err := db.GetPublisherVASTTags(tt.args.pubID) - if (err != nil) != tt.wantErr { - t.Errorf("mySqlDB.GetPublisherVASTTags() error = %v, wantErr %v", err, tt.wantErr) - return + if tt.wantErr == nil { + assert.NoError(t, err, tt.name) + } else { + assert.EqualError(t, err, tt.wantErr.Error(), tt.name) } assert.Equal(t, tt.want, got) }) diff --git a/modules/pubmatic/openwrap/models/constants.go b/modules/pubmatic/openwrap/models/constants.go index 6ce0d9e277b..cadcf60659a 100755 --- a/modules/pubmatic/openwrap/models/constants.go +++ b/modules/pubmatic/openwrap/models/constants.go @@ -542,8 +542,8 @@ const ( PublisherFeatureMapQuery = "GetPublisherFeatureMapQuery" AnalyticsThrottlingPercentageQuery = "GetAnalyticsThrottlingPercentage" GetAdpodConfig = "GetAdpodConfig" - //DisplayVersionInnerQuery = "DisplayVersionInnerQuery" - //LiveVersionInnerQuery = "LiveVersionInnerQuery" + // DisplayVersionInnerQuery = "DisplayVersionInnerQuery" + LiveVersionInnerQuery = "LiveVersionInnerQuery" //PMSlotToMappings = "GetPMSlotToMappings" TestQuery = "TestQuery" ProfileTypePlatformMapQuery = "GetProfileTypePlatformMapQuery" @@ -619,3 +619,9 @@ const ( const ( LogLevelDebug glog.Level = 3 ) + +const ( + // ErrDBQueryFailed reponse error + ErrDBQueryFailed = `"[DBError] query:[%s] pubid:[%v] profileid:[%v] error:[%s]"` + EmptyPartnerConfig = `"[EmptyPartnerConfig] pubid:[%v] profileid:[%v] version:[%v]"` +)