diff --git a/engine/actions_test.go b/engine/actions_test.go index 739a536d6..43f1d6999 100644 --- a/engine/actions_test.go +++ b/engine/actions_test.go @@ -24,6 +24,7 @@ import ( "testing" "time" + "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/utils" "github.com/cgrates/rpcclient" ) @@ -2585,6 +2586,77 @@ func TestCacheGetClonedActions(t *testing.T) { } } +func TestRemoveSessionCosts(t *testing.T) { + cfg, _ := config.NewDefaultCGRConfig() + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + tmpDM := dm + dm := NewDataManager(db, cfg.CacheCfg(), nil) + defer func() { + SetCdrStorage(cdrStorage) + SetDataStorage(tmpDM) + }() + aT := &ActionTiming{ + ActionsID: "ACT_LOG", + } + SetDataStorage(dm) + SetCdrStorage(db) + fltrs := []*Filter{ + { + Tenant: "cgrates.org", + ID: "FLTR_1", + Rules: []*FilterRule{ + { + Element: utils.DynamicDataPrefix + utils.RunID, + Type: utils.MetaString, + Values: []string{"RunID"}, + }, + }, + }, + { + Tenant: "cgrates.org", + ID: "FLTR_2", + Rules: []*FilterRule{ + { + Type: utils.MetaGreaterOrEqual, + Element: "~Usage", + Values: []string{"12s", "33s"}, + }, + }, + }, + } + for _, fltr := range fltrs { + dm.SetFilter(fltr) + } + acs := Actions{ + { + ActionType: utils.MetaRemoveSessionCosts, + Balance: &BalanceFilter{ + Type: utils.StringPointer(utils.MONETARY), + Value: &utils.ValueFormula{Static: 25}, + DestinationIDs: utils.StringMapPointer(utils.NewStringMap("RET")), + Weight: utils.Float64Pointer(20)}, + ExtraParameters: "FLTR_1;FLTR_2", + }, + } + smCost := &SMCost{ + RunID: "RunID", + Usage: 12 * time.Second, + CostDetails: &EventCost{ + CGRID: "EventCost_CGRID", + Cost: utils.Float64Pointer(0.74), + }, + } + if err := db.SetSMCost(smCost); err != nil { + t.Error(err) + } + if err := dm.SetActions("ACT_LOG", acs, utils.NonTransactional); err != nil { + t.Error(err) + } + if err := aT.Execute(nil, nil); err != nil { + t.Error(err) + } +} + // TestCdrLogAction type RPCMock struct { args *ArgV1ProcessEvent diff --git a/engine/datamanager_test.go b/engine/datamanager_test.go index eaffb0cf2..a6936eb36 100644 --- a/engine/datamanager_test.go +++ b/engine/datamanager_test.go @@ -18,6 +18,8 @@ along with this program. If not, see package engine import ( + "errors" + "reflect" "testing" "time" @@ -187,3 +189,157 @@ func TestDmMatchFilterIndexFromKey(t *testing.T) { } //unifinished } + +func TestCacheDataFromDB(t *testing.T) { + cfg, _ := config.NewDefaultCGRConfig() + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + chgS := ChargerProfiles{ + &ChargerProfile{ + Tenant: "cgrates.org", + ID: "Charger1", + FilterIDs: []string{"*string:~*req.Account:1015", "*gt:~*req.Usage:10"}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 7, 29, 15, 0, 0, 0, time.UTC), + }, + RunID: utils.MetaDefault, + AttributeIDs: []string{"*none"}, + Weight: 20, + }, + &ChargerProfile{ + Tenant: "cgrates.com", + ID: "CHRG_1", + FilterIDs: []string{"*string:Account:1001"}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + ExpiryTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + }, + AttributeIDs: []string{"ATTR_1"}, + Weight: 20, + }, + } + for _, chg := range chgS { + if err := dm.SetChargerProfile(chg, true); err != nil { + t.Error(err) + } + } + if err := dm.CacheDataFromDB(utils.ChargerProfilePrefix, nil, false); err != nil { + t.Error(err) + } +} + +func TestCacheDataFromDBFilterIndexes(t *testing.T) { + cfg, _ := config.NewDefaultCGRConfig() + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + + fltr := &Filter{ + Tenant: "cgrates.org", + ID: "FLTR_ATTR_1", + Rules: []*FilterRule{ + { + Type: utils.MetaString, + Element: "~*req.Attribute", + Values: []string{"AttributeProfile1"}, + }, + { + Type: utils.MetaGreaterOrEqual, + Element: "~*req.UsageInterval", + Values: []string{(1 * time.Second).String()}, + }, + { + Type: utils.MetaGreaterOrEqual, + Element: "~*req." + utils.Weight, + Values: []string{"9.0"}, + }, + }, + } + dm.SetFilter(fltr) + attr := &AttributeProfile{ + Tenant: "cgrates.org", + ID: "ATTR_1001_SIMPLEAUTH", + FilterIDs: []string{"FLTR_ATTR_1"}, + Contexts: []string{"simpleauth"}, + Attributes: []*Attribute{ + { + FilterIDs: []string{}, + Path: utils.MetaReq + utils.NestingSep + "Password", + Type: utils.META_CONSTANT, + Value: config.NewRSRParsersMustCompile("CGRateS.org", true, utils.INFIELD_SEP), + }, + }, + Weight: 20.0, + } + dm.SetAttributeProfile(attr, true) + if err := dm.CacheDataFromDB(utils.AttributeFilterIndexes, nil, false); err != nil { + t.Error(err) + } +} + +func TestFilterIndexesRmtRpl(t *testing.T) { + cfg, _ := config.NewDefaultCGRConfig() + Cache.Clear(nil) + cfg.DataDbCfg().Items[utils.MetaFilterIndexes].Remote = true + cfg.DataDbCfg().Items[utils.MetaFilterIndexes].Replicate = true + cfg.DataDbCfg().RplConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.ReplicatorSv1)} + cfg.DataDbCfg().RmtConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.ReplicatorSv1)} + defer func() { + cfg2, _ := config.NewDefaultCGRConfig() + config.SetCgrConfig(cfg2) + }() + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + expIndx := map[string]utils.StringMap{ + "*string:Account:1001": { + "RL1": true, + }, + "*string:Account:1002": { + "RL1": true, + "RL2": true, + }, + } + clientConn := make(chan rpcclient.ClientConnector, 1) + clientConn <- clMock(func(m string, a, r interface{}) error { + if m == utils.ReplicatorSv1SetFilterIndexes { + setFltrIndxArg, concat := a.(*utils.SetFilterIndexesArg) + if !concat { + return errors.New("Can't convert interfacea") + } + if err := dm.DataDB().SetFilterIndexesDrv(setFltrIndxArg.CacheID, setFltrIndxArg.ItemIDPrefix, setFltrIndxArg.Indexes, false, utils.EmptyString); err == nil { + *r.(*string) = utils.OK + } + return nil + } else if m == utils.ReplicatorSv1GetFilterIndexes { + + rpl := expIndx + *r.(*map[string]utils.StringMap) = rpl + return nil + } + return utils.ErrNotImplemented + }) + connMgr := NewConnManager(cfg, map[string]chan rpcclient.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.ReplicatorSv1): clientConn, + }) + dm := NewDataManager(db, cfg.CacheCfg(), connMgr) + idx := map[string]utils.StringMap{ + "*string:Account:1001": { + "DSP1": true, + "DSP2": true, + }, + "*suffix:*opts.Destination:+100": { + "Dsp1": true, + "Dsp2": true, + }, + } + config.SetCgrConfig(cfg) + if err := dm.SetFilterIndexes(utils.CacheDispatcherProfiles, "cgrates.org", idx, false, utils.NonTransactional); err != nil { + t.Error(err) + } + if err := dm.RemoveFilterIndexes(utils.CacheDispatcherProfiles, "cgrates.org"); err != nil { + t.Error(err) + } + if rcvIdx, err := dm.GetFilterIndexes(utils.CacheResourceProfiles, "cgrates.org", utils.EmptyString, nil); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(expIndx, rcvIdx) { + t.Errorf("Expected %+v,Received %+v", utils.ToJSON(expIndx), utils.ToJSON(idx)) + } +} diff --git a/engine/storage_test.go b/engine/storage_test.go index 6414f14a5..ce773d796 100644 --- a/engine/storage_test.go +++ b/engine/storage_test.go @@ -18,6 +18,7 @@ along with this program. If not, see package engine import ( + "fmt" "reflect" "testing" "time" @@ -466,3 +467,182 @@ func TestTPThresholds(t *testing.T) { t.Errorf("Expected %v,Received %v", utils.ToJSON(thresholds), utils.ToJSON(thds)) } } + +func TestTPFilters(t *testing.T) { + cfg, _ := config.NewDefaultCGRConfig() + db := NewInternalDB(nil, nil, false, cfg.StorDbCfg().Items) + tpFltr := []*utils.TPFilterProfile{ + { + TPid: "TP1", + Tenant: "cgrates.org", + ID: "FLT_1", + Filters: []*utils.TPFilter{ + { + Element: "Account", + Type: utils.MetaString, + Values: []string{"1001", "1002"}, + }, + { + Type: utils.MetaGreaterOrEqual, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Weight, + Values: []string{"15.0"}, + }, + }, + }, + { + TPid: "TP1", + Tenant: "cgrates.org", + ID: "FLT_2", + Filters: []*utils.TPFilter{ + { + Type: utils.MetaPrefix, + Element: "~*req.Cost", + Values: []string{"10", "15", "210"}, + }, + }, + }, + } + if err := db.SetTPFilters(tpFltr); err != nil { + t.Error(err) + } + for i := range tpFltr { + if fltr, err := db.GetTPFilters("TP1", "cgrates.org", fmt.Sprintf("FLT_%d", i+1)); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(fltr, tpFltr[i:i+1]) { + t.Errorf("Expected %v,Received %v", utils.ToJSON(tpFltr[i:i+1]), utils.ToJSON(fltr)) + } + } +} + +func TestTPAttributes(t *testing.T) { + cfg, _ := config.NewDefaultCGRConfig() + db := NewInternalDB(nil, nil, false, cfg.StorDbCfg().Items) + tpAttr := []*utils.TPAttributeProfile{ + { + TPid: "TP1", + Tenant: "cgrates.org", + ID: "Attr1", + + ActivationInterval: &utils.TPActivationInterval{ + ActivationTime: "2019-07-29T15:00:00Z", + ExpiryTime: "", + }, + Contexts: []string{"con1"}, + Attributes: []*utils.TPAttribute{ + { + Path: utils.MetaReq + utils.NestingSep + "FL1", + Value: "Al1", + FilterIDs: []string{}, + }, + }, + Weight: 20, + }, + { + TPid: "TP1", + Tenant: "cgrates.org", + ID: "Attr2", + Contexts: []string{"con1"}, + ActivationInterval: &utils.TPActivationInterval{ + ActivationTime: "2019-07-14T14:35:00Z", + ExpiryTime: "", + }, + Attributes: []*utils.TPAttribute{ + { + Path: utils.MetaReq + utils.NestingSep + "FL1", + Value: "Al1", + }, + }, + Weight: 20}, + } + if err := db.SetTPAttributes(tpAttr); err != nil { + t.Error(err) + } + for i := range tpAttr { + if attr, err := db.GetTPAttributes("TP1", "cgrates.org", fmt.Sprintf("Attr%d", i+1)); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(attr, tpAttr[i:i+1]) { + t.Errorf("Expected %v,Received %v", utils.ToJSON(tpAttr[i:i+1]), utils.ToJSON(attr)) + } + } +} + +func TestTPChargers(t *testing.T) { + cfg, _ := config.NewDefaultCGRConfig() + db := NewInternalDB(nil, nil, false, cfg.StorDbCfg().Items) + tpChrg := []*utils.TPChargerProfile{ + { + TPid: "TP1", + Tenant: "cgrates.org", + ID: "Charger1", + RunID: "*rated", + ActivationInterval: &utils.TPActivationInterval{ + ActivationTime: "2022-07-14T14:35:00Z", + ExpiryTime: "", + }, + Weight: 20}, + { + TPid: "TP1", + Tenant: "cgrates.org", + ID: "Charger2", + RunID: "*prepaid", + ActivationInterval: &utils.TPActivationInterval{ + ActivationTime: "2022-08-14T14:35:00Z", + ExpiryTime: "", + }, + Weight: 20, + }, + } + if err := db.SetTPChargers(tpChrg); err != nil { + t.Error(err) + } + for i := range tpChrg { + if cpps, err := db.GetTPChargers("TP1", "cgrates.org", fmt.Sprintf("Charger%d", i+1)); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(cpps, tpChrg[i:i+1]) { + t.Errorf("Expected %v,Received %v", utils.ToJSON(tpChrg[i:i+1]), utils.ToJSON(cpps)) + } + } +} + +func TestTPDispatcher(t *testing.T) { + cfg, _ := config.NewDefaultCGRConfig() + db := NewInternalDB(nil, nil, false, cfg.StorDbCfg().Items) + tpDsp := []*utils.TPDispatcherProfile{ + { + TPid: "TP1", + Tenant: "cgrates.org", + ID: "Dsp1", + FilterIDs: []string{"*string:Account:1002"}, + ActivationInterval: &utils.TPActivationInterval{ + ActivationTime: "2021-07-29T15:00:00Z", + ExpiryTime: "", + }, + Strategy: utils.MetaFirst, + Weight: 10, + }, { + + TPid: "TP1", + Tenant: "cgrates.org", + ID: "Dsp2", + Subsystems: []string{"*any"}, + FilterIDs: []string{}, + Strategy: utils.MetaFirst, + ActivationInterval: &utils.TPActivationInterval{ + ActivationTime: "2022-07-14T14:35:00Z", + ExpiryTime: "", + }, + StrategyParams: []interface{}{}, + Weight: 20, + }, + } + if err := db.SetTPDispatcherProfiles(tpDsp); err != nil { + t.Error(err) + } + for i := range tpDsp { + if dpp, err := db.GetTPDispatcherProfiles("TP1", "cgrates.org", fmt.Sprintf("Dsp%d", i+1)); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(dpp, tpDsp[i:i+1]) { + t.Errorf("Expected %v,Received %v", utils.ToJSON(tpDsp[i:i+1]), utils.ToJSON(dpp)) + } + } +}