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))
+ }
+ }
+}