From 33635856c12f2cba1a20454f92c4d5898bc33805 Mon Sep 17 00:00:00 2001 From: gezimbll Date: Tue, 13 Dec 2022 11:02:34 -0500 Subject: [PATCH] Improving coverage at engine --- engine/action_trigger_test.go | 54 ++++-- engine/datamanager_test.go | 335 ++++++++++++++++++++++++++++++++++ engine/routes_test.go | 46 ++--- engine/tpreader_test.go | 68 +++++++ 4 files changed, 461 insertions(+), 42 deletions(-) diff --git a/engine/action_trigger_test.go b/engine/action_trigger_test.go index 59798e683..a8bd8c5ac 100644 --- a/engine/action_trigger_test.go +++ b/engine/action_trigger_test.go @@ -257,17 +257,30 @@ func TestActionTriggerCreateBalance(t *testing.T) { } func TestATExecute(t *testing.T) { - Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() + tmp := Cache + tmpDm := dm + defer func() { + Cache = tmp + SetDataStorage(tmpDm) + config.SetCgrConfig(config.NewDefaultCGRConfig()) + }() + Cache.Clear(nil) + cfg.DataDbCfg().Items = map[string]*config.ItemOpt{ + utils.CacheActions: { + Limit: 2, + }, + } db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) dm := NewDataManager(db, cfg.CacheCfg(), nil) at := &ActionTrigger{ - ActionsID: "id", - ID: "id", - UniqueID: "uid", - ThresholdType: "*min_event_counter", - Recurrent: true, - MinSleep: 10 * time.Minute, + ID: "STANDARD_TRIGGER", + ActionsID: "actID", + UniqueID: "st0", + ThresholdType: utils.TriggerMinEventCounter, + ThresholdValue: 10, + Recurrent: true, + MinSleep: 10 * time.Minute, } ub := &Account{ ID: "acc_id", @@ -277,10 +290,27 @@ func TestATExecute(t *testing.T) { AllowNegative: false, UpdateTime: time.Date(2019, 3, 1, 12, 0, 0, 0, time.UTC), } - - fltrs := NewFilterS(cfg, nil, dm) - - if err := at.Execute(ub, fltrs); err == nil || err != utils.ErrNotFound { - t.Errorf("expected <%+v>,received <%+v>", utils.ErrNotFound, err) + fltrStr := `*lt:~*req.BalanceMap.*monetary.GetTotalValue:3` + db.db.Set(utils.CacheActions, "actID", Actions{ + { + Id: "cgrates.org:id1", + ActionType: "VALID_FUNCTION_TYPE", + Balance: &BalanceFilter{ + Type: utils.StringPointer("test"), + Value: &utils.ValueFormula{Static: 1.1}, + }, + Filters: []string{fltrStr}, + }, + }, []string{}, true, utils.NonTransactional) + SetDataStorage(dm) + fltr := NewFilterS(cfg, nil, dm) + db.db.Set(utils.CacheFilters, utils.ConcatenatedKey("cgrates.org", fltrStr), &Filter{ + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2022, 1, 12, 1, 0, 0, 0, time.UTC), + ExpiryTime: time.Date(2024, 1, 12, 1, 0, 0, 0, time.UTC), + }, + }, []string{}, true, utils.NonTransactional) + if err := at.Execute(ub, fltr); err != nil { + t.Error(err) } } diff --git a/engine/datamanager_test.go b/engine/datamanager_test.go index 823652114..da0976264 100644 --- a/engine/datamanager_test.go +++ b/engine/datamanager_test.go @@ -372,3 +372,338 @@ func TestDMGetStatQueue(t *testing.T) { t.Errorf("expected %+v,received %+v", utils.ToJSON(exp), utils.ToJSON(val)) } } + +func TestRebuildReverseForPrefix(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + tmpDm := dm + tmp := Cache + defer func() { + config.SetCgrConfig(config.NewDefaultCGRConfig()) + Cache = tmp + SetDataStorage(tmpDm) + }() + Cache.Clear(nil) + cfg.DataDbCfg().Items = map[string]*config.ItemOpt{ + utils.CacheReverseDestinations: { + Limit: 3, + Remote: true, + }, + } + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + dm.dataDB = &DataDBMock{} + db.db.Set(utils.CacheReverseDestinations, utils.ConcatenatedKey(utils.ReverseDestinationPrefix, "item1"), &Destination{}, []string{}, true, utils.NonTransactional) + if err := dm.RebuildReverseForPrefix(utils.ReverseDestinationPrefix); err == nil || err != utils.ErrNotImplemented { + t.Error(err) + } + dm.dataDB = db + if err := dm.RebuildReverseForPrefix(utils.ReverseDestinationPrefix); err != nil { + t.Error(err) + } + +} + +func TestDMSetAccount(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + tmpDm := dm + tmp := Cache + defer func() { + config.SetCgrConfig(config.NewDefaultCGRConfig()) + Cache = tmp + SetDataStorage(tmpDm) + }() + Cache.Clear(nil) + cfg.DataDbCfg().RplConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.ReplicatorSv1)} + cfg.DataDbCfg().RplFiltered = true + cfg.DataDbCfg().Items = map[string]*config.ItemOpt{ + utils.CacheAccounts: { + Limit: 3, + Replicate: true, + APIKey: "key", + RouteID: "route", + }, + } + acc := &Account{ + ID: "vdf:broker", + BalanceMap: map[string]Balances{ + utils.MetaVoice: { + &Balance{Value: 20 * float64(time.Second), + DestinationIDs: utils.NewStringMap("NAT"), + Weight: 10, RatingSubject: "rif"}, + &Balance{Value: 100 * float64(time.Second), + DestinationIDs: utils.NewStringMap("RET"), Weight: 20}, + }}, + } + clientConn := make(chan rpcclient.ClientConnector, 1) + clientConn <- &ccMock{ + calls: map[string]func(args interface{}, reply interface{}) error{ + utils.ReplicatorSv1SetAccount: func(args, reply interface{}) error { + accApiOpts, cancast := args.(AccountWithAPIOpts) + if !cancast { + return utils.ErrNotConvertible + } + dm.dataDB.SetAccountDrv(accApiOpts.Account) + + return nil + }, + }, + } + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + connMgr := NewConnManager(cfg, map[string]chan rpcclient.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.ReplicatorSv1): clientConn, + }) + dm := NewDataManager(db, cfg.CacheCfg(), connMgr) + dm.ms = &JSONMarshaler{} + config.SetCgrConfig(cfg) + SetDataStorage(dm) + if err := dm.SetAccount(acc); err != nil { + t.Error(err) + } + var dmnil *DataManager + if err = dmnil.SetAccount(acc); err == nil || err != utils.ErrNoDatabaseConn { + t.Error(err) + } + dm.dataDB = &DataDBMock{} + if err = dm.SetAccount(acc); err == nil || err != utils.ErrNotImplemented { + t.Error(err) + } +} + +func TestDMRemoveAccount(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + tmpDm := dm + tmp := Cache + defer func() { + config.SetCgrConfig(config.NewDefaultCGRConfig()) + Cache = tmp + SetDataStorage(tmpDm) + }() + Cache.Clear(nil) + cfg.DataDbCfg().RplConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.ReplicatorSv1)} + cfg.DataDbCfg().RplFiltered = true + cfg.DataDbCfg().Items = map[string]*config.ItemOpt{ + utils.CacheAccounts: { + Limit: 3, + Replicate: true, + APIKey: "key", + RouteID: "route", + }, + } + acc := &Account{ + ID: "vdf:broker", + BalanceMap: map[string]Balances{ + utils.MetaVoice: { + &Balance{Value: 20 * float64(time.Second), + DestinationIDs: utils.NewStringMap("NAT"), + Weight: 10, RatingSubject: "rif"}, + &Balance{Value: 100 * float64(time.Second), + DestinationIDs: utils.NewStringMap("RET"), Weight: 20}, + }}, + } + if err = dm.dataDB.SetAccountDrv(acc); err != nil { + t.Error(err) + } + + clientConn := make(chan rpcclient.ClientConnector, 1) + clientConn <- &ccMock{ + calls: map[string]func(args interface{}, reply interface{}) error{ + utils.ReplicatorSv1RemoveAccount: func(args, reply interface{}) error { + strApiOpts, cancast := args.(utils.StringWithAPIOpts) + if !cancast { + return utils.ErrNotConvertible + } + dm.dataDB.RemoveAccountDrv(strApiOpts.Arg) + return nil + }, + }, + } + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + connMgr := NewConnManager(cfg, map[string]chan rpcclient.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.ReplicatorSv1): clientConn, + }) + dm := NewDataManager(db, cfg.CacheCfg(), connMgr) + config.SetCgrConfig(cfg) + SetDataStorage(dm) + if err = dm.RemoveAccount(acc.ID); err != nil { + t.Error(err) + } + var dmnil *DataManager + if err = dmnil.RemoveAccount(acc.ID); err == nil || err != utils.ErrNoDatabaseConn { + t.Error(err) + } + dm.dataDB = &DataDBMock{} + if err = dm.RemoveAccount(acc.ID); err == nil || err != utils.ErrNotImplemented { + t.Error(err) + } +} + +func TestDmSetFilter(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + tmpDm := dm + tmp := Cache + defer func() { + config.SetCgrConfig(config.NewDefaultCGRConfig()) + Cache = tmp + SetDataStorage(tmpDm) + }() + Cache.Clear(nil) + cfg.DataDbCfg().RplConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.ReplicatorSv1)} + cfg.DataDbCfg().RplFiltered = true + cfg.DataDbCfg().Items = map[string]*config.ItemOpt{ + utils.CacheFilters: { + Limit: 3, + Replicate: true, + APIKey: "key", + RouteID: "route", + }, + } + filter := &Filter{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "FLTR_CP_1", + Rules: []*FilterRule{ + { + Type: utils.MetaString, + Element: "~*req.Charger", + Values: []string{"ChargerProfile1"}, + }, + }, + } + clientConn := make(chan rpcclient.ClientConnector, 1) + clientConn <- &ccMock{ + calls: map[string]func(args interface{}, reply interface{}) error{ + utils.ReplicatorSv1SetFilter: func(args, reply interface{}) error { + fltr, cancast := args.(FilterWithAPIOpts) + if !cancast { + return utils.ErrNotConvertible + } + dm.dataDB.SetFilterDrv(fltr.Filter) + return nil + }, + }, + } + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + connMgr := NewConnManager(cfg, map[string]chan rpcclient.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.ReplicatorSv1): clientConn, + }) + dm := NewDataManager(db, cfg.CacheCfg(), connMgr) + config.SetCgrConfig(cfg) + SetDataStorage(dm) + if err := dm.SetFilter(filter, false); err != nil { + t.Error(err) + } + var dmnil *DataManager + if err = dmnil.SetFilter(filter, false); err == nil || err != utils.ErrNoDatabaseConn { + t.Error(err) + } +} + +func TestDMSetThreshold(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + tmpDm := dm + tmp := Cache + defer func() { + config.SetCgrConfig(config.NewDefaultCGRConfig()) + Cache = tmp + SetDataStorage(tmpDm) + }() + Cache.Clear(nil) + Cache.Clear(nil) + cfg.DataDbCfg().RplConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.ReplicatorSv1)} + cfg.DataDbCfg().RplFiltered = true + cfg.DataDbCfg().Items = map[string]*config.ItemOpt{ + utils.CacheThresholds: { + Limit: 3, + Replicate: true, + APIKey: "key", + RouteID: "route", + }, + } + thS := &Threshold{ + Tenant: "cgrates.org", + ID: "THD_ACNT_1001", + Hits: 0, + } + clientConn := make(chan rpcclient.ClientConnector, 1) + clientConn <- &ccMock{ + calls: map[string]func(args interface{}, reply interface{}) error{ + utils.ReplicatorSv1SetThreshold: func(args, reply interface{}) error { + thS, cancast := args.(ThresholdWithAPIOpts) + if !cancast { + return utils.ErrNotConvertible + } + dm.dataDB.SetThresholdDrv(thS.Threshold) + return nil + }, + }, + } + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + connMgr := NewConnManager(cfg, map[string]chan rpcclient.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.ReplicatorSv1): clientConn, + }) + dm := NewDataManager(db, cfg.CacheCfg(), connMgr) + config.SetCgrConfig(cfg) + SetDataStorage(dm) + + if err = dm.SetThreshold(thS); err != nil { + t.Error(err) + } + dm.dataDB = &DataDBMock{} + if err = dm.SetThreshold(thS); err == nil || err != utils.ErrNotImplemented { + t.Error(err) + } +} + +func TestDmRemoveThreshold(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + tmpDm := dm + tmp := Cache + defer func() { + config.SetCgrConfig(config.NewDefaultCGRConfig()) + Cache = tmp + SetDataStorage(tmpDm) + }() + Cache.Clear(nil) + Cache.Clear(nil) + cfg.DataDbCfg().RplConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.ReplicatorSv1)} + cfg.DataDbCfg().RplFiltered = true + cfg.DataDbCfg().Items = map[string]*config.ItemOpt{ + utils.CacheThresholds: { + Limit: 3, + Replicate: true, + APIKey: "key", + RouteID: "route", + }, + } + thS := &Threshold{ + Tenant: "cgrates.org", + ID: "THD_ACNT_1001", + Hits: 0, + } + clientConn := make(chan rpcclient.ClientConnector, 1) + clientConn <- &ccMock{ + calls: map[string]func(args interface{}, reply interface{}) error{ + utils.ReplicatorSv1RemoveThreshold: func(args, reply interface{}) error { + tntApiOpts, cancast := args.(utils.TenantIDWithAPIOpts) + if !cancast { + return utils.ErrNotConvertible + } + dm.dataDB.RemoveThresholdDrv(tntApiOpts.TenantID.Tenant, tntApiOpts.TenantID.ID) + return nil + }, + }, + } + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + connMgr := NewConnManager(cfg, map[string]chan rpcclient.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.ReplicatorSv1): clientConn, + }) + dm := NewDataManager(db, cfg.CacheCfg(), connMgr) + config.SetCgrConfig(cfg) + SetDataStorage(dm) + if err := dm.RemoveThreshold(thS.Tenant, thS.ID); err != nil { + t.Error(err) + } + dm.dataDB = &DataDBMock{} + if err = dm.RemoveThreshold(thS.Tenant, thS.ID); err == nil || err != utils.ErrNotImplemented { + t.Error(err) + } +} diff --git a/engine/routes_test.go b/engine/routes_test.go index b708ebf72..24812fdb9 100644 --- a/engine/routes_test.go +++ b/engine/routes_test.go @@ -1433,6 +1433,7 @@ func TestReaSortRoutes(t *testing.T) { } } func TestHCRSortRoutes(t *testing.T) { + Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() data := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) dmSPP := NewDataManager(data, config.CgrConfig().CacheCfg(), nil) @@ -1534,7 +1535,14 @@ func TestHCRSortRoutes(t *testing.T) { } } func TestLoadDistributionSorterSortRoutes(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + tmpDm := dm + defer func() { + config.SetCgrConfig(config.NewDefaultCGRConfig()) + SetDataStorage(tmpDm) + }() + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) dm := NewDataManager(db, config.CgrConfig().CacheCfg(), nil) cfg.RouteSCfg().RALsConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaRALs)} @@ -1585,20 +1593,6 @@ func TestLoadDistributionSorterSortRoutes(t *testing.T) { "*ratio": "ratio", }, }, - "sorted_route2": { - ID: "id", - FilterIDs: []string{"filterid1"}, - AccountIDs: []string{"acc_id1"}, - RatingPlanIDs: []string{"rate1"}, - ResourceIDs: []string{}, - StatIDs: []string{"statID"}, - Weight: 2.3, - Blocker: true, - RouteParameters: "route", - cacheRoute: map[string]interface{}{ - "*ratio": "ratio", - }, - }, } ev := &utils.CGREvent{ Tenant: "cgrates.org", @@ -1635,32 +1629,24 @@ func TestLoadDistributionSorterSortRoutes(t *testing.T) { "Ratio": 0.0, "Weight": 2.3, }, - }, { - RouteID: "id", - RouteParameters: "route", - SortingData: map[string]interface{}{ - "Load": 21.11, - "MaxUsage": 180000000000, - "Ratio": 0, - "Weight": 2.3, - }, - sortingDataF64: map[string]float64{ - "Load": 21.11, - "MaxUsage": 180000000000.0, - "Ratio": 0.0, - "Weight": 2.3, - }, }, }} if val, err := lds.SortRoutes(prflID, routes, ev, extraOpts); err != nil { t.Error(err) - } else if reflect.DeepEqual(val, expSr) { + } else if reflect.DeepEqual(val.Routes[0].SortingData, expSr.Routes[0].SortingData) { t.Errorf("expected %v,received %v", utils.ToJSON(expSr), utils.ToJSON(val)) } + // routes["sorted_id2"] = &Route{ + // StatIDs: []string{}, + // } + // if _, err = lds.SortRoutes(prflID, routes, ev, extraOpts); err == nil { + // t.Error(err) + // } } func TestRouteServicePopulateSortingData(t *testing.T) { + Cache.Clear(nil) ccMock := &ccMock{ calls: map[string]func(args, reply interface{}) error{ diff --git a/engine/tpreader_test.go b/engine/tpreader_test.go index 2e7eb0506..e665c3007 100644 --- a/engine/tpreader_test.go +++ b/engine/tpreader_test.go @@ -1734,6 +1734,9 @@ func TestTprRemoveFromDatabase(t *testing.T) { utils.CacheSharedGroups: { Limit: 3, }, + utils.CacheChargerProfiles: { + Limit: 2, + }, } db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) tpr, err := NewTpReader(db, db, "*prf", "UTC", nil, nil, true) @@ -1743,15 +1746,80 @@ func TestTprRemoveFromDatabase(t *testing.T) { db.db.Set(utils.CacheSharedGroups, "itmID", &SharedGroup{ Id: "SG_TEST", }, []string{}, true, utils.NonTransactional) + db.db.Set(utils.CacheChargerProfiles, "cgrates.org:DEFAULT", &ChargerProfile{ + Tenant: "cgrates.org", + ID: "DEFAULT", + FilterIDs: []string{}, + RunID: utils.MetaDefault, + AttributeIDs: []string{"*none"}, + Weight: 0, + }, []string{}, true, utils.NonTransactional) + tpr.sharedGroups = map[string]*SharedGroup{ "itmID": { Id: "SG_TEST", }, } + tpr.chargerProfiles = map[utils.TenantID]*utils.TPChargerProfile{ + {Tenant: "cgrates", ID: "item2"}: { + Tenant: "cgrates.org", + ID: "DEFAULT", + FilterIDs: []string{}, + RunID: utils.MetaDefault, + AttributeIDs: []string{"*none"}, + Weight: 0, + }, + } if err := tpr.RemoveFromDatabase(false, true); err != nil { t.Error(err) } if _, has := db.db.Get(utils.CacheSharedGroups, "itmID"); has { t.Error("should been removed from the cache") + } else if _, has := db.db.Get(utils.CacheSharedGroups, "cgrates.org:DEFAULT"); has { + t.Error("should been removed from the cache") + } +} + +func TestLoadActionPlansErrs(t *testing.T) { + tmp := Cache + cfg := config.NewDefaultCGRConfig() + cfg.DataDbCfg().Items = map[string]*config.ItemOpt{ + utils.CacheTBLTPActionPlans: { + StaticTTL: true, + Limit: 4, + }, + utils.CacheActions: { + Limit: 2, + }, + } + defer func() { + Cache = tmp + config.SetCgrConfig(config.NewDefaultCGRConfig()) + }() + Cache.Clear(nil) + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + tpr, err := NewTpReader(db, db, "tpr", "UTC", nil, nil, true) + if err != nil { + t.Error(err) + } + db.db.Set(utils.CacheTBLTPActionPlans, "tpr:item1", &utils.TPActionPlan{ + TPid: "TEST_TPID", + ID: "PACKAGE_10", + ActionPlan: []*utils.TPActionTiming{ + { + ActionsId: "TOPUP_RST_10", + TimingId: "ASAP", + Weight: 10.0}, + }, + }, []string{}, true, utils.NonTransactional) + tpr.actions = map[string][]*Action{ + "TOPUP_RST_*": {}, + } + if err := tpr.LoadActionPlans(); err == nil || err.Error() != fmt.Sprintf("[ActionPlans] Could not load the action for tag: %q", "TOPUP_RST_10") { + t.Error(err) + } + db.db.Set(utils.CacheActions, "TOPUP_RST_10", nil, []string{}, true, utils.NonTransactional) + if err := tpr.LoadActionPlans(); err == nil || err.Error() != fmt.Sprintf("[ActionPlans] Could not load the timing for tag: %q", "ASAP") { + t.Error(err) } }