From 8911ab3622a3fa16cdee7a6708e589ab877fc9c3 Mon Sep 17 00:00:00 2001 From: gezimbll Date: Tue, 20 Dec 2022 10:51:34 -0500 Subject: [PATCH] Improving coverage at engine --- engine/actions_test.go | 92 +++++++++- engine/datamanager_test.go | 366 +++++++++++++++++++++++++++++++++++++ engine/dynamicdp_test.go | 38 ++++ 3 files changed, 489 insertions(+), 7 deletions(-) diff --git a/engine/actions_test.go b/engine/actions_test.go index 7d00dc15b..f1bc7ca49 100644 --- a/engine/actions_test.go +++ b/engine/actions_test.go @@ -19,6 +19,7 @@ package engine import ( "bytes" + "errors" "fmt" "io" "log" @@ -3722,15 +3723,59 @@ func TestRemoveAccountAcc(t *testing.T) { func TestRemoveAccountActionErr(t *testing.T) { tmp := Cache tmpDm := dm - utils.Logger.SetLogLevel(4) - utils.Logger.SetSyslog(nil) - var buf bytes.Buffer - log.SetOutput(&buf) + + setLogger := func(buf *bytes.Buffer) { + utils.Logger.SetLogLevel(4) + utils.Logger.SetSyslog(nil) + log.SetOutput(buf) + } + removeLogger := func() { + utils.Logger.SetLogLevel(0) + log.SetOutput(os.Stderr) + } + buf := new(bytes.Buffer) + setLogger(buf) + cfg := config.NewDefaultCGRConfig() defer func() { + removeLogger() Cache = tmp SetDataStorage(tmpDm) - log.SetOutput(os.Stderr) + + config.SetCgrConfig(config.NewDefaultCGRConfig()) }() + cfg.DataDbCfg().Items = map[string]*config.ItemOpt{ + utils.CacheAccounts: { + Limit: 3, + TTL: 2 * time.Minute, + Remote: true, + }, + utils.CacheAccountActionPlans: { + Limit: 3, + StaticTTL: true, + Remote: true, + }, + utils.CacheActionPlans: { + Remote: true, + Limit: 3, + StaticTTL: true, + }, + } + cfg.DataDbCfg().RmtConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaReplicator)} + clientConn := make(chan rpcclient.ClientConnector, 1) + clientConn <- &ccMock{ + calls: map[string]func(args interface{}, reply interface{}) error{ + utils.ReplicatorSv1GetAccountActionPlans: func(args, reply interface{}) error { + + return errors.New("ActionPlans not found") + }, + utils.ReplicatorSv1GetActionPlan: func(args, reply interface{}) error { + return errors.New("ActionPlan not found") + }, + }, + } + connMgr := NewConnManager(cfg, map[string]chan rpcclient.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaReplicator): clientConn, + }) a := &Action{ Id: "CDRLog1", ActionType: utils.CDRLog, @@ -3760,13 +3805,14 @@ func TestRemoveAccountActionErr(t *testing.T) { APIOpts: map[string]interface{}{}, } ub := &Account{ - BalanceMap: map[string]Balances{ utils.MetaMonetary: {&Balance{ Value: 10, }}, }, } + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), connMgr) SetDataStorage(nil) if err := removeAccountAction(ub, a, acs, nil, extraData); err == nil || err != utils.ErrInvalidKey { t.Error(err) @@ -3779,7 +3825,39 @@ func TestRemoveAccountActionErr(t *testing.T) { t.Errorf("expected log <%+v> to be included in: <%+v>", expLog, rcvLog) } - utils.Logger.SetLogLevel(0) + SetDataStorage(dm) + config.SetCgrConfig(cfg) + ub.ID = "acc_id" + if err := dm.SetAccount(ub); err != nil { + t.Error(err) + } + removeLogger() + buf2 := new(bytes.Buffer) + setLogger(buf2) + expLog = `Could not get action plans` + if err := removeAccountAction(ub, a, acs, nil, extraData); err == nil { + t.Error(err) + } else if rcvLog := buf2.String(); !strings.Contains(rcvLog, expLog) { + t.Errorf("Logger %v doesn't contain %v", rcvLog, expLog) + } + removeLogger() + buf3 := new(bytes.Buffer) + setLogger(buf3) + expLog = `Could not retrieve action plan:` + dm.SetAccountActionPlans(ub.ID, []string{"acc1"}, true) + if err := removeAccountAction(ub, a, acs, nil, extraData); err == nil { + t.Error(err) + } else if rcvLog := buf3.String(); !strings.Contains(rcvLog, expLog) { + t.Errorf("Logger %v doesn't contain %v", rcvLog, expLog) + } + // if err := dm.SetActionPlan("acc1", &ActionPlan{ + // ActionTimings: []*ActionTiming{ + // {ActionsID: "ENABLE_ACNT"}, + // }, + // }, true, utils.NonTransactional); err != nil { + // t.Error(err) + // } + } func TestRemoveExpiredErrs(t *testing.T) { diff --git a/engine/datamanager_test.go b/engine/datamanager_test.go index 606930aab..9fac837f3 100644 --- a/engine/datamanager_test.go +++ b/engine/datamanager_test.go @@ -1600,3 +1600,369 @@ func TestRatingPlanRemote(t *testing.T) { t.Error("should been removed from the caches") } } + +func TestGetResourceRemote(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().RmtConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaReplicator)} + cfg.DataDbCfg().RplFiltered = true + cfg.DataDbCfg().Items = map[string]*config.ItemOpt{ + utils.CacheResources: { + Limit: 3, + Replicate: true, + APIKey: "key", + RouteID: "route", + Remote: true, + }, + } + + rS := &Resource{ + Tenant: "cgrates.org", + ID: "ResGroup3", + Usages: map[string]*ResourceUsage{ + "651a8db2-4f67-4cf8-b622-169e8a482e21": { + Tenant: "cgrates.org", + ID: "651a8db2-4f67-4cf8-b622-169e8a482e21", + Units: 2, + }, + }, + } + clientConn := make(chan rpcclient.ClientConnector, 1) + clientConn <- &ccMock{ + calls: map[string]func(args interface{}, reply interface{}) error{ + utils.ReplicatorSv1GetResource: func(args, reply interface{}) error { + tntApiOpts, cancast := args.(*utils.TenantIDWithAPIOpts) + if !cancast { + return utils.ErrNotConvertible + } + dm.DataDB().GetResourceDrv(tntApiOpts.Tenant, tntApiOpts.ID) + *reply.(**Resource) = rS + return nil + }, + }, + } + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + connMgr := NewConnManager(cfg, map[string]chan rpcclient.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaReplicator): clientConn, + }) + dm := NewDataManager(db, cfg.CacheCfg(), connMgr) + config.SetCgrConfig(cfg) + SetDataStorage(dm) + + if val, err := dm.GetResource(rS.Tenant, rS.ID, false, true, utils.NonTransactional); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(rS, val) { + t.Errorf("expected %v,received %v", utils.ToJSON(rS), utils.ToJSON(val)) + } +} + +func TestGetResourceProfileRemote(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().RmtConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaReplicator)} + cfg.DataDbCfg().RplFiltered = true + cfg.DataDbCfg().Items = map[string]*config.ItemOpt{ + utils.CacheResourceProfiles: { + Limit: 3, + Replicate: true, + APIKey: "key", + RouteID: "route", + Remote: true, + }, + } + rsP := &ResourceProfile{ + ID: "RES_ULTIMITED2", + UsageTTL: time.Nanosecond, + Limit: 10, + AllocationMessage: "MessageAllocation", + Blocker: true, + Stored: true, + Weight: 20, + ThresholdIDs: []string{"Val1"}, + } + clientConn := make(chan rpcclient.ClientConnector, 1) + clientConn <- &ccMock{ + calls: map[string]func(args interface{}, reply interface{}) error{ + utils.ReplicatorSv1GetResourceProfile: func(args, reply interface{}) error { + tntApiOpts, cancast := args.(*utils.TenantIDWithAPIOpts) + if !cancast { + return utils.ErrNotConvertible + } + dm.DataDB().GetResourceProfileDrv(tntApiOpts.Tenant, tntApiOpts.ID) + *reply.(**ResourceProfile) = rsP + return nil + }, + }, + } + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + connMgr := NewConnManager(cfg, map[string]chan rpcclient.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaReplicator): clientConn, + }) + dm := NewDataManager(db, cfg.CacheCfg(), connMgr) + config.SetCgrConfig(cfg) + SetDataStorage(dm) + if val, err := dm.GetResourceProfile(rsP.Tenant, rsP.ID, false, true, utils.NonTransactional); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(val, rsP) { + t.Errorf("expected %v,received %v", utils.ToJSON(rsP), utils.ToJSON(val)) + } +} + +// func TestGetActionTriggers(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().RmtConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.ReplicatorSv1)} +// cfg.DataDbCfg().RplFiltered = true +// cfg.DataDbCfg().Items = map[string]*config.ItemOpt{ +// utils.CacheActionTriggers: { +// Limit: 3, +// Replicate: true, +// APIKey: "key", +// RouteID: "route", +// Remote: true, +// }, +// } +// aT := ActionTriggers{ +// &ActionTrigger{ +// ID: "Test", +// }, +// } +// clientConn := make(chan rpcclient.ClientConnector, 1) +// clientConn <- &ccMock{ +// calls: map[string]func(args interface{}, reply interface{}) error{ +// utils.ReplicatorSv1GetActionTriggers: func(args, reply interface{}) error { +// strApiOpts, cancast := args.(*utils.StringWithAPIOpts) +// if !cancast { +// return utils.ErrNotConvertible +// } +// dm.DataDB().GetActionTriggersDrv(strApiOpts.Arg) +// *reply.(*ActionTriggers) = aT +// 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) +// Cache.Set(utils.CacheActionTriggers, "Test", ActionTriggers{}, []string{}, false, utils.NonTransactional) +// if _, err := dm.GetActionTriggers(aT[0].ID, false, utils.NonTransactional); err != nil { +// t.Error(err) +// } +// } + +func TestGetSharedGroupRemote(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().RmtConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaReplicator)} + cfg.DataDbCfg().RplFiltered = true + cfg.DataDbCfg().Items = map[string]*config.ItemOpt{ + utils.CacheSharedGroups: { + Limit: 3, + Replicate: true, + APIKey: "key", + RouteID: "route", + Remote: true, + }, + } + shG := &SharedGroup{ + Id: "testID", + AccountParameters: map[string]*SharingParameters{ + "string1": { + Strategy: "strategyTEST1", + RatingSubject: "RatingSubjectTEST1", + }, + "string2": { + Strategy: "strategyTEST2", + RatingSubject: "RatingSubjectTEST2", + }, + }, + MemberIds: utils.StringMap{ + "string1": true, + "string2": false, + }, + } + clientConn := make(chan rpcclient.ClientConnector, 1) + clientConn <- &ccMock{ + calls: map[string]func(args interface{}, reply interface{}) error{ + utils.ReplicatorSv1GetSharedGroup: func(args, reply interface{}) error { + strApiOpts, cancast := args.(*utils.StringWithAPIOpts) + if !cancast { + return utils.ErrNotConvertible + } + dm.DataDB().GetSharedGroupDrv(strApiOpts.Arg) + *reply.(**SharedGroup) = shG + return nil + }, + }, + } + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + connMgr := NewConnManager(cfg, map[string]chan rpcclient.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaReplicator): clientConn, + }) + dm := NewDataManager(db, cfg.CacheCfg(), connMgr) + config.SetCgrConfig(cfg) + SetDataStorage(dm) + if val, err := dm.GetSharedGroup(shG.Id, true, utils.NonTransactional); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(val, shG) { + t.Errorf("expected %v,received %v", utils.ToJSON(shG), utils.ToJSON(val)) + } +} + +func TestGetStatQueueProfileRemote(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().RmtConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaReplicator)} + cfg.DataDbCfg().RplFiltered = true + cfg.DataDbCfg().Items = map[string]*config.ItemOpt{ + utils.CacheStatQueueProfiles: { + Limit: 3, + Replicate: true, + APIKey: "key", + RouteID: "route", + Remote: true, + }, + } + sqP := &StatQueueProfile{ + Tenant: "cgrates.org", + ID: "SQ_ID", + FilterIDs: []string{"FLTR_ID"}, + Weight: 10, + } + clientConn := make(chan rpcclient.ClientConnector, 1) + clientConn <- &ccMock{ + calls: map[string]func(args interface{}, reply interface{}) error{ + utils.ReplicatorSv1GetStatQueueProfile: func(args, reply interface{}) error { + tntApiOpts, cancast := args.(*utils.TenantIDWithAPIOpts) + if !cancast { + return utils.ErrNotConvertible + } + dm.DataDB().GetStatQueueProfileDrv(tntApiOpts.Tenant, tntApiOpts.ID) + *reply.(**StatQueueProfile) = sqP + return nil + }, + }, + } + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + connMgr := NewConnManager(cfg, map[string]chan rpcclient.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaReplicator): clientConn, + }) + dm := NewDataManager(db, cfg.CacheCfg(), connMgr) + config.SetCgrConfig(cfg) + SetDataStorage(dm) + if val, err := dm.GetStatQueueProfile(sqP.Tenant, sqP.ID, true, true, utils.NonTransactional); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(val, sqP) { + t.Errorf("expected %v,received %v", utils.ToJSON(sqP), utils.ToJSON(val)) + } +} + +func TestStatQueueProfileRemote(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().RmtConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaReplicator)} + cfg.DataDbCfg().RplConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaReplicator)} + cfg.DataDbCfg().RplFiltered = true + cfg.DataDbCfg().Items = map[string]*config.ItemOpt{ + utils.CacheStatQueueProfiles: { + Limit: 3, + Replicate: true, + APIKey: "key", + RouteID: "route", + Remote: true, + }, + utils.CacheStatQueues: { + Limit: 3, + Replicate: true, + APIKey: "key", + RouteID: "route", + Remote: true, + }, + } + sqP := &StatQueueProfile{ + Tenant: "cgrates.org", + ID: "SQ_ID", + FilterIDs: []string{"FLTR_ID"}, + Weight: 10, + } + clientConn := make(chan rpcclient.ClientConnector, 1) + clientConn <- &ccMock{ + calls: map[string]func(args interface{}, reply interface{}) error{ + utils.ReplicatorSv1SetStatQueueProfile: func(args, reply interface{}) error { + sqPApiOpts, cancast := args.(StatQueueProfileWithAPIOpts) + if !cancast { + return utils.ErrNotConvertible + } + dm.DataDB().SetStatQueueProfileDrv(sqPApiOpts.StatQueueProfile) + return nil + }, + utils.ReplicatorSv1SetStatQueue: func(args, reply interface{}) error { + sqApiOpts, cancast := args.(StatQueueWithAPIOpts) + if !cancast { + return utils.ErrNotConvertible + } + dm.DataDB().SetStatQueueDrv(nil, sqApiOpts.StatQueue) + return nil + }, + }, + } + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + connMgr := NewConnManager(cfg, map[string]chan rpcclient.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaReplicator): clientConn, + }) + dm := NewDataManager(db, cfg.CacheCfg(), connMgr) + config.SetCgrConfig(cfg) + SetDataStorage(dm) + Cache.Set(utils.CacheStatQueueProfiles, utils.ConcatenatedKey(sqP.Tenant, sqP.ID), &StatQueueProfile{ + QueueLength: 2, + }, []string{}, true, utils.NonTransactional) + if err := dm.SetStatQueueProfile(sqP, false); err != nil { + t.Error(err) + } +} diff --git a/engine/dynamicdp_test.go b/engine/dynamicdp_test.go index 7e36a8f19..d418eaf18 100644 --- a/engine/dynamicdp_test.go +++ b/engine/dynamicdp_test.go @@ -18,6 +18,10 @@ along with this program. If not, see package engine import ( + "bytes" + "log" + "os" + "strings" "testing" "github.com/cgrates/cgrates/config" @@ -59,6 +63,15 @@ func TestDynamicDpFieldAsInterface(t *testing.T) { } func TestDDPFieldAsInterface(t *testing.T) { + utils.Logger.SetLogLevel(4) + utils.Logger.SetSyslog(nil) + buf := new(bytes.Buffer) + log.SetOutput(buf) + defer func() { + utils.Logger.SetLogLevel(0) + log.SetOutput(os.Stderr) + }() + libDP, err := newLibPhoneNumberDP("+447975777666") if err != nil { t.Error(err) @@ -142,4 +155,29 @@ func TestDDPFieldAsInterface(t *testing.T) { t.Errorf("expected %v,reveived %v", 1, val) } + dDP = &libphonenumberDP{ + cache: utils.MapStorage{}, + pNumber: &phonenumbers.PhoneNumber{}, + } + expLog := `when getting GeoLocation for number` + if _, err := dDP.fieldAsInterface([]string{"GeoLocation"}); err != nil { + t.Error(err) + } else if rcvLog := buf.String(); !strings.Contains(rcvLog, expLog) { + t.Errorf("Logger %v doesn't contain %v", rcvLog, expLog) + } + dDP = &libphonenumberDP{ + cache: utils.MapStorage{}, + pNumber: &phonenumbers.PhoneNumber{}, + } + dDP.setDefaultFields() + utils.Logger.SetLogLevel(0) + log.SetOutput(os.Stderr) + utils.Logger.SetLogLevel(4) + utils.Logger.SetSyslog(nil) + buf2 := new(bytes.Buffer) + log.SetOutput(buf2) + expLog = ` when getting GeoLocation for number` + if rcvLog := buf2.String(); strings.Contains(rcvLog, expLog) { + t.Errorf("Logger %v doesn't contain %v", rcvLog, expLog) + } }