From b8f131a9a5ecbf3cc4b9f9a22131c1d1412bd245 Mon Sep 17 00:00:00 2001 From: gezimbll Date: Tue, 6 Dec 2022 10:40:29 -0500 Subject: [PATCH] improving coverage at engine --- engine/caches_test.go | 138 ++++++++++++++++++++++++++++----------- engine/cdrs_test.go | 79 ++++++++++++++++++++++ engine/dynamicdp_test.go | 47 +++++-------- engine/routes_test.go | 28 ++++++++ engine/tpreader_test.go | 123 ++++++++++++++++++++++++++++++++++ 5 files changed, 344 insertions(+), 71 deletions(-) diff --git a/engine/caches_test.go b/engine/caches_test.go index 8d026eb2e..23a5a9a33 100644 --- a/engine/caches_test.go +++ b/engine/caches_test.go @@ -33,7 +33,7 @@ func TestCachesReplicateRemove(t *testing.T) { cfg := config.NewDefaultCGRConfig() cfg.CacheCfg().ReplicationConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.ReplicationConnsCfg)} cfg.CacheCfg().Partitions = map[string]*config.CacheParamCfg{ - "id": { + utils.ReplicatorSv1GetDispatcherHost: { Replicate: true, }, } @@ -43,7 +43,7 @@ func TestCachesReplicateRemove(t *testing.T) { clientconn <- &ccMock{ calls: map[string]func(args interface{}, reply interface{}) error{ utils.CacheSv1ReplicateRemove: func(args, reply interface{}) error { - *reply.(*string) = "reply" + *reply.(*string) = utils.OK return nil }, }, @@ -56,17 +56,15 @@ func TestCachesReplicateRemove(t *testing.T) { dm: dm, } SetConnManager(connMgr) - if err := chS.ReplicateRemove("id", "itm_id"); err != nil { - + if err := chS.ReplicateRemove(utils.ReplicatorSv1GetDispatcherHost, "itm_id"); err != nil { t.Error(err) - } } func TestCacheSSetWithReplicate(t *testing.T) { Cache.Clear(nil) args := &utils.ArgCacheReplicateSet{ - CacheID: "chID", + CacheID: utils.ReplicatorSv1GetActions, ItemID: "itemID", Value: &utils.CachedRPCResponse{Result: "reply", Error: nil}, GroupIDs: []string{"groupId", "groupId"}, @@ -78,13 +76,13 @@ func TestCacheSSetWithReplicate(t *testing.T) { Replicate: true, }, } - db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) dm := NewDataManager(db, cfg.CacheCfg(), nil) clientconn := make(chan rpcclient.ClientConnector, 1) clientconn <- &ccMock{ calls: map[string]func(args interface{}, reply interface{}) error{ utils.CacheSv1ReplicateSet: func(args, reply interface{}) error { + *reply.(*string) = "reply" return nil }, @@ -93,28 +91,21 @@ func TestCacheSSetWithReplicate(t *testing.T) { connMgr := NewConnManager(cfg, map[string]chan rpcclient.ClientConnector{ utils.ConcatenatedKey(utils.MetaInternal, utils.ReplicationConnsCfg): clientconn, }) - tscache := ltcache.NewTransCache( - map[string]*ltcache.CacheConfig{ - ltcache.DefaultCacheInstance: { - MaxItems: 3, - TTL: time.Second * 1, - StaticTTL: true, - OnEvicted: func(itmID string, value interface{}) { - - }, - }, + ltcache := ltcache.NewTransCache(map[string]*ltcache.CacheConfig{ + args.CacheID: { + MaxItems: 2, }, - ) - casheS := &CacheS{ - cfg: cfg, + }) + cacheS := &CacheS{ dm: dm, - tCache: tscache, + cfg: cfg, + tCache: ltcache, } SetConnManager(connMgr) - - if err := casheS.SetWithReplicate(args); err != nil { + if err := cacheS.SetWithReplicate(args); err != nil { t.Error(err) } + } func TestCacheSV1GetItemIDs(t *testing.T) { @@ -895,38 +886,107 @@ func TestUpdateReplicationFilters(t *testing.T) { } } -/* func TestReplicateMultipleIDs(t *testing.T) { - + tmp := Cache + defer func() { + Cache = tmp + }() + Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - cfg.ChargerSCfg().AttributeSConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes)} + cfg.ApierCfg().CachesConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches)} cfg.AttributeSCfg().Enabled = true + cfg.CacheCfg().Partitions = map[string]*config.CacheParamCfg{ + utils.CacheReplicationHosts: { + Limit: 3, + }, + } + Cache = NewCacheS(cfg, nil, nil) connClient := make(chan rpcclient.ClientConnector, 1) connClient <- &ccMock{ calls: map[string]func(args interface{}, reply interface{}) error{ - utils.AttributeSv1ProcessEvent: func(args, reply interface{}) error { + utils.CacheSv1ReloadCache: func(args, reply interface{}) error { *reply.(*string) = "reply" return nil }, }, } - connMgr := NewConnManager(cfg, map[string]chan rpcclient.ClientConnector{ - utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes): connClient, + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches): connClient, }) - - filtered := false objType := "obj" - objIds := []string{"objID2", "objID3"} - method := utils.AttributeSv1ProcessEvent - args := &utils.CGREvent{ - Tenant: "Cgrates", - ID: "id", + objIds := []string{"rpl1", "rpl2"} + method := utils.CacheSv1ReloadCache + args := &utils.AttrReloadCacheWithAPIOpts{ + AccountActionPlanIDs: []string{"accID"}, } - - if err := replicateMultipleIDs(connMgr, cfg.ChargerSCfg().AttributeSConns, filtered, objType, objIds, method, args); err != nil { + if err := replicateMultipleIDs(connMgr, cfg.ApierCfg().CachesConns, false, objType, objIds, method, args); err != nil { + t.Error(err) + } + if err := replicateMultipleIDs(connMgr, cfg.ApierCfg().CachesConns, true, objType, objIds, method, args); err != nil { t.Error(err) } } -*/ +func TestCachesGetWithRemote(t *testing.T) { + Cache.Clear(nil) + args := &utils.ArgsGetCacheItemWithAPIOpts{ + ArgsGetCacheItem: utils.ArgsGetCacheItem{ + CacheID: utils.CacheTBLTPActionPlans, + ItemID: "cacheItem", + }, + } + cfg := config.NewDefaultCGRConfig() + cfg.DataDbCfg().Items = map[string]*config.ItemOpt{ + utils.CacheTBLTPActionPlans: { + Limit: 3, + Remote: false, + }, + } + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + chS := NewCacheS(cfg, dm, nil) + clientconn := make(chan rpcclient.ClientConnector, 1) + clientconn <- &ccMock{ + calls: map[string]func(args interface{}, reply interface{}) error{ + utils.CacheSv1GetItem: func(args, reply interface{}) error { + *reply.(*string) = utils.OK + return utils.ErrNotFound + }, + }, + } + + connMgr := NewConnManager(cfg, map[string]chan rpcclient.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.RemoteConnsCfg): clientconn, + }) + SetConnManager(connMgr) + tpAc := &utils.TPActionTrigger{ + BalanceId: "id", + Id: "STANDARD_TRIGGERS", + ThresholdType: "*min_balance", + ThresholdValue: 2, + Recurrent: false, + MinSleep: "0", + ExpirationDate: "date", + BalanceType: "*monetary", + BalanceDestinationIds: "FS_USERS", + ActionsId: "LOG_WARNING", + Weight: 10, + } + chS.tCache.Set(args.CacheID, "cacheItem", tpAc, []string{"cacheItem"}, true, utils.NonTransactional) + if val, err := chS.GetWithRemote(args); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(val, tpAc) { + t.Errorf("expected %v,received %v", utils.ToJSON(tpAc), utils.ToJSON(val)) + } + chS.tCache.Remove(utils.CacheTBLTPActionPlans, "cacheItem", true, utils.NonTransactional) + if _, err := chS.GetWithRemote(args); err == nil || err != utils.ErrNotFound { + t.Errorf("expected %v,received %v", utils.ErrNotFound, err) + } + cfg.DataDbCfg().Items[utils.CacheTBLTPActionPlans].Remote = true + cfg.CacheCfg().RemoteConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.RemoteConnsCfg)} + /* + if _, err = chS.GetWithRemote(args); err == nil || err != utils.ErrNotFound { + t.Errorf("expected %v,received %v", utils.ErrNotFound, err) + } + */ +} diff --git a/engine/cdrs_test.go b/engine/cdrs_test.go index f7c7352d0..ac2bb7495 100644 --- a/engine/cdrs_test.go +++ b/engine/cdrs_test.go @@ -1692,3 +1692,82 @@ func TestCdrSRateCDR(t *testing.T) { t.Error(err) } } + +func TestChrgrSProcessEvent(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + cfg.CdrsCfg().ChargerSConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaChargers)} + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + clienConn := make(chan rpcclient.ClientConnector, 1) + clienConn <- &ccMock{ + calls: map[string]func(args interface{}, reply interface{}) error{ + utils.ChargerSv1ProcessEvent: func(args, reply interface{}) error { + *reply.(*[]*ChrgSProcessEventReply) = []*ChrgSProcessEventReply{ + { + ChargerSProfile: "Charger1", + AttributeSProfiles: []string{"cgrates.org:ATTR_1001_SIMPLEAUTH"}, + AlteredFields: []string{utils.MetaReqRunID, "*req.Password"}, + CGREvent: &utils.CGREvent{ // matching Charger1 + Tenant: "cgrates.org", + ID: "event1", + Event: map[string]interface{}{ + utils.AccountField: "1001", + "Password": "CGRateS.org", + "RunID": utils.MetaDefault, + }, + APIOpts: map[string]interface{}{ + utils.OptsContext: "simpleauth", + utils.MetaSubsys: utils.MetaChargers, + utils.OptsAttributesProfileIDs: []string{"ATTR_1001_SIMPLEAUTH"}, + }, + }, + }, + } + return nil + }, + }, + } + connMgr := NewConnManager(cfg, map[string]chan rpcclient.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaChargers): clienConn, + }) + cdrS := &CDRServer{ + cgrCfg: cfg, + cdrDb: db, + dm: dm, + connMgr: connMgr, + } + cgrEv := utils.CGREvent{ + ID: "TestV1ProcessEventNoTenant", + Event: map[string]interface{}{ + utils.CGRID: "test1", + utils.RunID: utils.MetaDefault, + utils.OriginID: "testV1CDRsRefundOutOfSessionCost", + utils.RequestType: utils.MetaPrepaid, + utils.AccountField: "testV1CDRsRefundOutOfSessionCost", + utils.Destination: "+4986517174963", + utils.AnswerTime: time.Date(2019, 11, 27, 12, 21, 26, 0, time.UTC), + utils.Usage: 123 * time.Minute, + }, + } + expcgrEv := []*utils.CGREvent{ + { + Tenant: "cgrates.org", + ID: "event1", + Event: map[string]interface{}{ + utils.AccountField: "1001", + "Password": "CGRateS.org", + "RunID": utils.MetaDefault, + }, + APIOpts: map[string]interface{}{ + utils.OptsContext: "simpleauth", + utils.MetaSubsys: utils.MetaChargers, + utils.OptsAttributesProfileIDs: []string{"ATTR_1001_SIMPLEAUTH"}, + }, + }, + } + if val, err := cdrS.chrgrSProcessEvent(&cgrEv); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(val, expcgrEv) { + t.Errorf("expected %v,received %v", utils.ToJSON(expcgrEv), utils.ToJSON(val)) + } +} diff --git a/engine/dynamicdp_test.go b/engine/dynamicdp_test.go index 8d4dcede1..041e777d2 100644 --- a/engine/dynamicdp_test.go +++ b/engine/dynamicdp_test.go @@ -18,6 +18,7 @@ along with this program. If not, see package engine import ( + "fmt" "testing" "github.com/cgrates/cgrates/config" @@ -59,38 +60,20 @@ func TestDynamicDpFieldAsInterface(t *testing.T) { } func TestDpLibPhoneNumber(t *testing.T) { - - libphonenumber := &libphonenumberDP{ - pNumber: &phonenumbers.PhoneNumber{ - CountryCode: func(i int32) *int32 { - - return &i - }(33), - NationalNumber: func(i uint64) *uint64 { - - return &i - }(121411111), - }, - cache: utils.MapStorage{}, - } - if val, err := libphonenumber.fieldAsInterface([]string{"CountryCode"}); err != nil { - t.Error(err) - } else if val != *libphonenumber.pNumber.CountryCode { - t.Errorf("expected %v,received %v", libphonenumber.pNumber.CountryCode, val) - } - - if val, err := libphonenumber.fieldAsInterface([]string{"NationalNumber"}); err != nil { - t.Error(err) - } else if val != *libphonenumber.pNumber.NationalNumber { - t.Errorf("expected %v,received %v", libphonenumber.pNumber.CountryCode, val) - } - - if val, err := libphonenumber.fieldAsInterface([]string{"Region"}); err != nil { - t.Error(err) - } else if val != "FR" { - t.Errorf("expected %v,received %v", "FR", val) - } - if _, err := libphonenumber.fieldAsInterface([]string{"NumberType"}); err != nil { + num, err := phonenumbers.ParseAndKeepRawInput("+3554735474", utils.EmptyString) + if err != nil { t.Error(err) } + dDP := &libphonenumberDP{ + pNumber: num, + cache: utils.MapStorage{}, + } + dDP.setDefaultFields() + if _, err := dDP.fieldAsInterface([]string{}); err == nil || err.Error() != fmt.Sprintf("invalid field path <%+v> for libphonenumberDP", []string{}) { + t.Error(err) + } + if _, err := dDP.fieldAsInterface([]string{"CountryCode"}); err != nil { + t.Error(err) + } + } diff --git a/engine/routes_test.go b/engine/routes_test.go index a2103b278..d1975f1f8 100644 --- a/engine/routes_test.go +++ b/engine/routes_test.go @@ -1767,3 +1767,31 @@ func TestRouteServicePopulateSortingData(t *testing.T) { t.Error(err) } } + +func TestNewOptsGetRoutes(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + ev := &utils.CGREvent{ + + APIOpts: map[string]interface{}{ + utils.OptsRoutesMaxCost: utils.MetaEventCost, + }, + Event: map[string]interface{}{ + utils.AccountField: "", + utils.Destination: "", + utils.SetupTime: "", + utils.Usage: "", + }, + } + fltr := &FilterS{cfg, dm, nil} + cfgOpt := &config.RoutesOpts{ + Limit: utils.IntPointer(12), + IgnoreErrors: true, + Offset: utils.IntPointer(21), + } + + if _, err := newOptsGetRoutes(ev, fltr, cfgOpt); err != nil { + t.Error(err) + } +} diff --git a/engine/tpreader_test.go b/engine/tpreader_test.go index 27f38a309..2f000c408 100644 --- a/engine/tpreader_test.go +++ b/engine/tpreader_test.go @@ -1545,6 +1545,7 @@ func TestLoadRatingProfilesFiltered(t *testing.T) { if err := tpr.LoadRatingProfilesFiltered(qriedRpf); err == nil || err.Error() != fmt.Sprintf("no RatingProfile for filter %v, error: %v", qriedRpf, utils.ErrNotFound) { t.Error(err) } + val := []*utils.TPRatingProfile{ { LoadId: "load", @@ -1558,6 +1559,12 @@ func TestLoadRatingProfilesFiltered(t *testing.T) { Category: "cat", Subject: " subj", TPid: "rating1", + RatingPlanActivations: []*utils.TPRatingActivation{ + { + RatingPlanId: "RP_1001", + ActivationTime: "test", + }, + }, }, } tscache.Set(utils.CacheTBLTPRatingProfiles, "rate:cgritm", val[0], []string{"grpId"}, true, utils.NonTransactional) @@ -1565,4 +1572,120 @@ func TestLoadRatingProfilesFiltered(t *testing.T) { if err := tpr.LoadRatingProfilesFiltered(qriedRpf); err == nil || err.Error() != fmt.Sprintf("Non unique id %+v", val[1].GetId()) { t.Error(err) } + val[1].TPid, val[1].LoadId, val[1].Category = "rating2", "load2", "category2" + if err := tpr.LoadRatingProfilesFiltered(qriedRpf); err == nil || err.Error() != fmt.Sprintf("cannot parse activation time from %v", val[1].RatingPlanActivations[0].ActivationTime) { + t.Error(err) + } + tpr.timezone, val[1].RatingPlanActivations[0].ActivationTime = "UTC", "*monthly_estimated" + + if err := tpr.LoadRatingProfilesFiltered(qriedRpf); err == nil || err.Error() != fmt.Sprintf("could not load rating plans for tag: %q", val[1].RatingPlanActivations[0].RatingPlanId) { + t.Error(err) + } +} + +func TestTpReaderLoadActionTriggers(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + tscache := ltcache.NewTransCache( + map[string]*ltcache.CacheConfig{ + utils.CacheTBLTPActionTriggers: { + MaxItems: 3, + TTL: time.Minute * 30, + StaticTTL: false, + }, + }, + ) + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + db.db = tscache + tpr, err := NewTpReader(db, db, "*prf", "UTC", nil, nil, true) + if err != nil { + t.Error(err) + } + trVals := []*utils.TPActionTriggers{ + { + TPid: "TPAct", + ID: "ID2", + ActionTriggers: []*utils.TPActionTrigger{ + { + BalanceId: "id", + Id: "STANDARD_TRIGGERS", + ThresholdType: "*min_balance", + ThresholdValue: 2, + Recurrent: false, + MinSleep: "0", + ExpirationDate: "date", + BalanceType: "*monetary", + BalanceDestinationIds: "FS_USERS", + ActionsId: "LOG_WARNING", + Weight: 10, + }, + { + BalanceId: "id", + Id: "STANDARD_TRIGGERS", + ThresholdType: "*max_event_counter", + ThresholdValue: 5, + Recurrent: false, + MinSleep: "0", + BalanceType: "*monetary", + BalanceDestinationIds: "FS_USERS", + ActionsId: "LOG_WARNING", + Weight: 10, + }, + }, + }, + } + tscache.Set(utils.CacheTBLTPActionTriggers, "*prfitem1", trVals[0], []string{"*prfitem1", "*prfitem2"}, true, utils.NonTransactional) + + if err := tpr.LoadActionTriggers(); err == nil || err.Error() != "Unsupported time format" { + t.Error(err) + } + trVals[0].ActionTriggers[0].ExpirationDate = "*monthly" + trVals[0].ActionTriggers[0].ActivationDate = "value" + if err := tpr.LoadActionTriggers(); err == nil || err.Error() != "Unsupported time format" { + t.Error(err) + } + + trVals[0].ActionTriggers[0].ActivationDate = "*monthly" + trVals[0].ActionTriggers[0].MinSleep = "two" + if err := tpr.LoadActionTriggers(); err == nil || err.Error() != fmt.Sprintf("time: invalid duration %q", trVals[0].ActionTriggers[0].MinSleep) { + t.Error(err) + } + trVals[0].ActionTriggers[0].MinSleep = "5000" + if err := tpr.LoadActionTriggers(); err != nil { + t.Error(err) + } +} + +func TestTpReaderSetDestination(t *testing.T) { + dest := &Destination{ + Id: "1001_ID", + Prefixes: []string{"39", "75"}, + } + cfg := config.NewDefaultCGRConfig() + tscache := ltcache.NewTransCache( + map[string]*ltcache.CacheConfig{ + utils.CacheDestinations: { + MaxItems: 3, + TTL: time.Minute * 30, + StaticTTL: false, + }, + }, + ) + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + db.db = tscache + tpr, err := NewTpReader(db, db, "*prf", "UTC", nil, nil, true) + if err != nil { + t.Error(err) + } + if err := tpr.setDestination(dest, true, ""); err != nil { + t.Error(err) + } + if val, has := tscache.Get(utils.CacheDestinations, dest.Id); !has { + t.Error("has no value") + } else { + if rcv, cancast := val.(*Destination); !cancast { + t.Error("it's not type *Destination") + } else if !reflect.DeepEqual(rcv, dest) { + t.Errorf("exepcted %v,received %v", utils.ToJSON(dest), utils.ToJSON(rcv)) + } + } }