mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Improved reverse idx code + thresholds implementation and tests
This commit is contained in:
@@ -209,7 +209,7 @@ func (api *APIerSv1) ComputeFilterIndexes(args utils.ArgsComputeFilterIndexes, r
|
||||
//ThresholdProfile Indexes
|
||||
var thdsIndexers *engine.FilterIndexer
|
||||
if args.ThresholdS {
|
||||
thdsIndexers, err = api.computeThresholdIndexes(args.Tenant, nil, transactionID)
|
||||
thdsIndexers, err = engine.ComputeThresholdIndexes(api.DataManager, args.Tenant, nil, transactionID)
|
||||
if err != nil && err != utils.ErrNotFound {
|
||||
return utils.APIErrorHandler(err)
|
||||
}
|
||||
@@ -314,7 +314,7 @@ func (api *APIerSv1) ComputeFilterIndexes(args utils.ArgsComputeFilterIndexes, r
|
||||
func (api *APIerSv1) ComputeFilterIndexIDs(args utils.ArgsComputeFilterIndexIDs, reply *string) (err error) {
|
||||
transactionID := utils.GenUUID()
|
||||
//ThresholdProfile Indexes
|
||||
thdsIndexers, err := api.computeThresholdIndexes(args.Tenant, &args.ThresholdIDs, transactionID)
|
||||
thdsIndexers, err := engine.ComputeThresholdIndexes(api.DataManager, args.Tenant, &args.ThresholdIDs, transactionID)
|
||||
if err != nil && err != utils.ErrNotFound {
|
||||
return utils.APIErrorHandler(err)
|
||||
}
|
||||
@@ -460,83 +460,6 @@ func (api *APIerSv1) ComputeFilterIndexIDs(args utils.ArgsComputeFilterIndexIDs,
|
||||
return nil
|
||||
}
|
||||
|
||||
func (api *APIerSv1) computeThresholdIndexes(tenant string, thIDs *[]string,
|
||||
transactionID string) (filterIndexer *engine.FilterIndexer, err error) {
|
||||
var thresholdIDs []string
|
||||
var thdsIndexers *engine.FilterIndexer
|
||||
if thIDs == nil {
|
||||
ids, err := api.DataManager.DataDB().GetKeysForPrefix(utils.ThresholdProfilePrefix)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, id := range ids {
|
||||
thresholdIDs = append(thresholdIDs, strings.Split(id, utils.CONCATENATED_KEY_SEP)[1])
|
||||
}
|
||||
// this will be on ComputeIndexes that contains empty indexes
|
||||
thdsIndexers = engine.NewFilterIndexer(api.DataManager, utils.ThresholdProfilePrefix, tenant)
|
||||
} else {
|
||||
// this will be on ComputeIndexesIDs that contains the old indexes from the next getter
|
||||
var oldIDx map[string]utils.StringMap
|
||||
if oldIDx, err = api.DataManager.GetFilterIndexes(utils.PrefixToIndexCache[utils.ThresholdProfilePrefix],
|
||||
tenant, utils.EmptyString, nil); err != nil || oldIDx == nil {
|
||||
thdsIndexers = engine.NewFilterIndexer(api.DataManager, utils.ThresholdProfilePrefix, tenant)
|
||||
} else {
|
||||
thdsIndexers = engine.NewFilterIndexerWithIndexes(api.DataManager, utils.ThresholdProfilePrefix, tenant, oldIDx)
|
||||
}
|
||||
thresholdIDs = *thIDs
|
||||
transactionID = utils.NonTransactional
|
||||
}
|
||||
for _, id := range thresholdIDs {
|
||||
th, err := api.DataManager.GetThresholdProfile(tenant, id, true, false, utils.NonTransactional)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fltrIDs := make([]string, len(th.FilterIDs))
|
||||
for i, fltrID := range th.FilterIDs {
|
||||
fltrIDs[i] = fltrID
|
||||
}
|
||||
if len(fltrIDs) == 0 {
|
||||
fltrIDs = []string{utils.META_NONE}
|
||||
}
|
||||
for _, fltrID := range fltrIDs {
|
||||
var fltr *engine.Filter
|
||||
if fltrID == utils.META_NONE {
|
||||
fltr = &engine.Filter{
|
||||
Tenant: th.Tenant,
|
||||
ID: th.ID,
|
||||
Rules: []*engine.FilterRule{
|
||||
{
|
||||
Type: utils.META_NONE,
|
||||
Element: utils.META_ANY,
|
||||
Values: []string{utils.META_ANY},
|
||||
},
|
||||
},
|
||||
}
|
||||
} else if fltr, err = engine.GetFilter(api.DataManager, th.Tenant, fltrID,
|
||||
true, false, utils.NonTransactional); err != nil {
|
||||
if err == utils.ErrNotFound {
|
||||
err = fmt.Errorf("broken reference to filter: %+v for threshold: %+v",
|
||||
fltrID, th)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
thdsIndexers.IndexTPFilter(engine.FilterToTPFilter(fltr), th.ID)
|
||||
}
|
||||
}
|
||||
|
||||
if transactionID == utils.NonTransactional {
|
||||
if err := thdsIndexers.StoreIndexes(true, transactionID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, nil
|
||||
} else {
|
||||
if err := thdsIndexers.StoreIndexes(false, transactionID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return thdsIndexers, nil
|
||||
}
|
||||
|
||||
func (api *APIerSv1) computeAttributeIndexes(tenant, context string, attrIDs *[]string,
|
||||
transactionID string) (filterIndexer *engine.FilterIndexer, err error) {
|
||||
var attributeIDs []string
|
||||
|
||||
@@ -788,12 +788,20 @@ func (dm *DataManager) SetThresholdProfile(th *ThresholdProfile, withIndex bool)
|
||||
th.Tenant).RemoveItemFromIndex(th.Tenant, th.ID, oldTh.FilterIDs); err != nil {
|
||||
return
|
||||
}
|
||||
if err = removeReverseFilterIndexForFilter(dm, utils.CacheThresholdFilterIndexes, utils.EmptyString,
|
||||
th.Tenant, th.ID, th.FilterIDs); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := createAndIndex(utils.ThresholdProfilePrefix, th.Tenant,
|
||||
utils.EmptyString, th.ID, th.FilterIDs, dm); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addReverseFilterIndexForFilter(dm, utils.CacheThresholdFilterIndexes, utils.EmptyString,
|
||||
th.Tenant, th.ID, th.FilterIDs); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaThresholdProfiles]; itm.Replicate {
|
||||
if err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns,
|
||||
@@ -824,6 +832,10 @@ func (dm *DataManager) RemoveThresholdProfile(tenant, id,
|
||||
tenant).RemoveItemFromIndex(tenant, id, oldTh.FilterIDs); err != nil {
|
||||
return
|
||||
}
|
||||
if err = removeReverseFilterIndexForFilter(dm, utils.CacheThresholdFilterIndexes, utils.EmptyString,
|
||||
oldTh.Tenant, oldTh.ID, oldTh.FilterIDs); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaThresholdProfiles]; itm.Replicate {
|
||||
replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns,
|
||||
|
||||
@@ -25,10 +25,87 @@ import (
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
func ComputeThresholdIndexes(dm *DataManager, tenant string, thIDs *[]string,
|
||||
transactionID string) (filterIndexer *FilterIndexer, err error) {
|
||||
var thresholdIDs []string
|
||||
var thdsIndexers *FilterIndexer
|
||||
if thIDs == nil {
|
||||
ids, err := dm.DataDB().GetKeysForPrefix(utils.ThresholdProfilePrefix)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, id := range ids {
|
||||
thresholdIDs = append(thresholdIDs, strings.Split(id, utils.CONCATENATED_KEY_SEP)[1])
|
||||
}
|
||||
// this will be on ComputeIndexes that contains empty indexes
|
||||
thdsIndexers = NewFilterIndexer(dm, utils.ThresholdProfilePrefix, tenant)
|
||||
} else {
|
||||
// this will be on ComputeIndexesIDs that contains the old indexes from the next getter
|
||||
var oldIDx map[string]utils.StringMap
|
||||
if oldIDx, err = dm.GetFilterIndexes(utils.PrefixToIndexCache[utils.ThresholdProfilePrefix],
|
||||
tenant, utils.EmptyString, nil); err != nil || oldIDx == nil {
|
||||
thdsIndexers = NewFilterIndexer(dm, utils.ThresholdProfilePrefix, tenant)
|
||||
} else {
|
||||
thdsIndexers = NewFilterIndexerWithIndexes(dm, utils.ThresholdProfilePrefix, tenant, oldIDx)
|
||||
}
|
||||
thresholdIDs = *thIDs
|
||||
transactionID = utils.NonTransactional
|
||||
}
|
||||
for _, id := range thresholdIDs {
|
||||
th, err := dm.GetThresholdProfile(tenant, id, true, false, utils.NonTransactional)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fltrIDs := make([]string, len(th.FilterIDs))
|
||||
for i, fltrID := range th.FilterIDs {
|
||||
fltrIDs[i] = fltrID
|
||||
}
|
||||
if len(fltrIDs) == 0 {
|
||||
fltrIDs = []string{utils.META_NONE}
|
||||
}
|
||||
for _, fltrID := range fltrIDs {
|
||||
var fltr *Filter
|
||||
if fltrID == utils.META_NONE {
|
||||
fltr = &Filter{
|
||||
Tenant: th.Tenant,
|
||||
ID: th.ID,
|
||||
Rules: []*FilterRule{
|
||||
{
|
||||
Type: utils.META_NONE,
|
||||
Element: utils.META_ANY,
|
||||
Values: []string{utils.META_ANY},
|
||||
},
|
||||
},
|
||||
}
|
||||
} else if fltr, err = GetFilter(dm, th.Tenant, fltrID,
|
||||
true, false, utils.NonTransactional); err != nil {
|
||||
if err == utils.ErrNotFound {
|
||||
err = fmt.Errorf("broken reference to filter: %+v for threshold: %+v",
|
||||
fltrID, th)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
thdsIndexers.IndexTPFilter(FilterToTPFilter(fltr), th.ID)
|
||||
}
|
||||
}
|
||||
|
||||
if transactionID == utils.NonTransactional {
|
||||
if err := thdsIndexers.StoreIndexes(true, transactionID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, nil
|
||||
} else {
|
||||
if err := thdsIndexers.StoreIndexes(false, transactionID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return thdsIndexers, nil
|
||||
}
|
||||
|
||||
func ComputeChargerIndexes(dm *DataManager, tenant string, cppIDs *[]string,
|
||||
transactionID string) (cppIndexes *FilterIndexer, err error) {
|
||||
transactionID string) (filterIndexer *FilterIndexer, err error) {
|
||||
var chargerIDs []string
|
||||
//var cppIndexes *FilterIndexer
|
||||
var cppIndexes *FilterIndexer
|
||||
if cppIDs == nil {
|
||||
ids, err := dm.DataDB().GetKeysForPrefix(utils.ChargerProfilePrefix)
|
||||
if err != nil {
|
||||
|
||||
@@ -116,6 +116,7 @@ func UpdateFilterIndexes(dm *DataManager, tnt string, oldFltr *Filter, newFltr *
|
||||
err = nil // if the error is NOT_FOUND, it means that no indexes were found for this filter, so no need to update
|
||||
return
|
||||
}
|
||||
|
||||
removeIndexKeys := removeRules.Slice()
|
||||
|
||||
for idxItmType, index := range rcvIndexes {
|
||||
@@ -132,6 +133,18 @@ func UpdateFilterIndexes(dm *DataManager, tnt string, oldFltr *Filter, newFltr *
|
||||
utils.NonTransactional); err != nil {
|
||||
return err
|
||||
}
|
||||
case utils.CacheThresholdFilterIndexes:
|
||||
// remove the indexes from this filter for this partition
|
||||
if err = removeFilterIndexesForFilter(dm, idxItmType, utils.CacheThresholdProfiles,
|
||||
tnt, removeIndexKeys, index); err != nil {
|
||||
return
|
||||
}
|
||||
// we removed the old reverse indexes, now we have to compute the new ones
|
||||
thresholdIDs := index.Slice()
|
||||
if _, err = ComputeThresholdIndexes(dm, newFltr.Tenant, &thresholdIDs,
|
||||
utils.NonTransactional); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -190,6 +203,9 @@ func addReverseFilterIndexForFilter(dm *DataManager, idxItmType, ctx, tnt,
|
||||
idxItmType: make(map[string]bool), // not found in database any reverse, we declare them to add in the next steps
|
||||
}
|
||||
}
|
||||
if indexes[idxItmType] == nil {
|
||||
indexes[idxItmType] = make(utils.StringMap)
|
||||
}
|
||||
indexes[idxItmType].Copy(map[string]bool{
|
||||
itemID: true,
|
||||
})
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
v1 "github.com/cgrates/cgrates/apier/v1"
|
||||
"github.com/cgrates/cgrates/config"
|
||||
@@ -104,6 +105,7 @@ var (
|
||||
testFilterIndexesCasesGetIndexesAnyContextChanged,
|
||||
testFilterIndexesCasesGetIndexesSessionsContextChanged,
|
||||
|
||||
// CHARGERS
|
||||
testFilterIndexesCasesSetIndexedFilter,
|
||||
testFilterIndexesCasesSetChargerWithFltr,
|
||||
testFilterIndexesCasesGetChargerIndexes,
|
||||
@@ -115,6 +117,17 @@ var (
|
||||
testFilterIndexesCasesGetIndexesAfterRemove,
|
||||
testFilterIndexesCasesGetReverseIndexesAfterRemove,
|
||||
|
||||
// THRESHOLDS
|
||||
testFilterIndexesCasesSetThresholdWithFltr,
|
||||
testFilterIndexesCasesGetThresholdsIndexes,
|
||||
testFilterIndexesCasesOverwriteFilterForThresholds,
|
||||
testFilterIndexesCasesGetThresholdsIndexesChanged,
|
||||
|
||||
testFilterIndexesCasesGetReverseFilterIndexes2,
|
||||
testFilterIndexesCasesRemoveThresholdsProfile,
|
||||
testFilterIndexesCasesGetIndexesAfterRemove2,
|
||||
testFilterIndexesCasesGetReverseIndexesAfterRemove2,
|
||||
|
||||
testFilterIndexesCasesStopEngine,
|
||||
}
|
||||
)
|
||||
@@ -768,6 +781,346 @@ func testFilterIndexesCasesGetReverseIndexesAfterRemove(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func testFilterIndexesCasesSetThresholdWithFltr(t *testing.T) {
|
||||
tPrfl1 := &engine.ThresholdWithCache{
|
||||
ThresholdProfile: &engine.ThresholdProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "TEST_PROFILE1",
|
||||
FilterIDs: []string{"FLTR_Charger"},
|
||||
MaxHits: 1,
|
||||
MinSleep: time.Duration(5 * time.Minute),
|
||||
Blocker: false,
|
||||
Weight: 10.0,
|
||||
Async: true,
|
||||
},
|
||||
}
|
||||
tPrfl2 := &engine.ThresholdWithCache{
|
||||
ThresholdProfile: &engine.ThresholdProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "TEST_PROFILE2",
|
||||
FilterIDs: []string{
|
||||
"FLTR_Charger4564",
|
||||
"FLTR_Charger",
|
||||
"FLTR_Charger12312",
|
||||
},
|
||||
ActivationInterval: &utils.ActivationInterval{
|
||||
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
|
||||
ExpiryTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
|
||||
},
|
||||
MaxHits: 1,
|
||||
MinSleep: time.Duration(5 * time.Minute),
|
||||
Blocker: false,
|
||||
Weight: 20.0,
|
||||
Async: true,
|
||||
},
|
||||
}
|
||||
tPrfl3 := &engine.ThresholdWithCache{
|
||||
ThresholdProfile: &engine.ThresholdProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "TEST_PROFILE3",
|
||||
FilterIDs: []string{
|
||||
"FLTR_Charger12312",
|
||||
"*prefix:~*req.Cost:4",
|
||||
"FLTR_Charger",
|
||||
},
|
||||
ActivationInterval: &utils.ActivationInterval{
|
||||
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
|
||||
ExpiryTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
|
||||
},
|
||||
MaxHits: 1,
|
||||
MinSleep: time.Duration(5 * time.Minute),
|
||||
Blocker: false,
|
||||
Weight: 40.0,
|
||||
Async: true,
|
||||
},
|
||||
}
|
||||
tPrfl4 := &engine.ThresholdWithCache{
|
||||
ThresholdProfile: &engine.ThresholdProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "TEST_PROFILE4",
|
||||
FilterIDs: []string{},
|
||||
MaxHits: 1,
|
||||
MinSleep: time.Duration(5 * time.Minute),
|
||||
Blocker: false,
|
||||
Weight: 5.0,
|
||||
Async: true,
|
||||
},
|
||||
}
|
||||
var result string
|
||||
if err := fIdxCasesRPC.Call(utils.APIerSv1SetThresholdProfile, tPrfl1, &result); err != nil {
|
||||
t.Error(err)
|
||||
} else if result != utils.OK {
|
||||
t.Error("Unexpected reply returned", result)
|
||||
}
|
||||
if err := fIdxCasesRPC.Call(utils.APIerSv1SetThresholdProfile, tPrfl2, &result); err != nil {
|
||||
t.Error(err)
|
||||
} else if result != utils.OK {
|
||||
t.Error("Unexpected reply returned", result)
|
||||
}
|
||||
if err := fIdxCasesRPC.Call(utils.APIerSv1SetThresholdProfile, tPrfl3, &result); err != nil {
|
||||
t.Error(err)
|
||||
} else if result != utils.OK {
|
||||
t.Error("Unexpected reply returned", result)
|
||||
}
|
||||
if err := fIdxCasesRPC.Call(utils.APIerSv1SetThresholdProfile, tPrfl4, &result); err != nil {
|
||||
t.Error(err)
|
||||
} else if result != utils.OK {
|
||||
t.Error("Unexpected reply returned", result)
|
||||
}
|
||||
}
|
||||
|
||||
func testFilterIndexesCasesGetThresholdsIndexes(t *testing.T) {
|
||||
arg := &v1.AttrGetFilterIndexes{
|
||||
Tenant: "cgrates.org",
|
||||
ItemType: utils.MetaThresholds,
|
||||
}
|
||||
expectedIndexes := []string{
|
||||
// TEST_PROFILE1"
|
||||
"*string:~*req.Account:12345:TEST_PROFILE1",
|
||||
// TEST_PROFILE2"
|
||||
"*string:~*req.Account:12345:TEST_PROFILE2",
|
||||
"*string:~*req.RequestType:*none:TEST_PROFILE2",
|
||||
"*string:~*req.Destination:1443:TEST_PROFILE2",
|
||||
"*prefix:~*req.SetupTime:2022:TEST_PROFILE2",
|
||||
// TEST_PROFILE3"
|
||||
"*string:~*req.Account:12345:TEST_PROFILE3",
|
||||
"*prefix:~*req.Cost:4:TEST_PROFILE3",
|
||||
"*string:~*req.Destination:1443:TEST_PROFILE3",
|
||||
"*prefix:~*req.SetupTime:2022:TEST_PROFILE3",
|
||||
// TEST_PROFILE4"
|
||||
"*none:*any:*any:TEST_PROFILE4",
|
||||
}
|
||||
sort.Strings(expectedIndexes)
|
||||
var reply []string
|
||||
if err := fIdxCasesRPC.Call(utils.APIerSv1GetFilterIndexes, arg, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if sort.Strings(reply); !reflect.DeepEqual(expectedIndexes, reply) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(expectedIndexes), utils.ToJSON(reply))
|
||||
}
|
||||
}
|
||||
|
||||
func testFilterIndexesCasesOverwriteFilterForThresholds(t *testing.T) {
|
||||
filter1 = &v1.FilterWithCache{
|
||||
Filter: &engine.Filter{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "FLTR_Charger",
|
||||
Rules: []*engine.FilterRule{
|
||||
{
|
||||
Type: utils.MetaPrefix,
|
||||
Element: "~*req.CostRefunded",
|
||||
Values: []string{"12345"},
|
||||
},
|
||||
{
|
||||
Type: utils.MetaString,
|
||||
Element: "~*req.ToR",
|
||||
Values: []string{"*voice"},
|
||||
},
|
||||
{
|
||||
Type: utils.MetaLessOrEqual,
|
||||
Element: "~*req.ProcessRuns",
|
||||
Values: []string{"1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
filter2 := &v1.FilterWithCache{
|
||||
Filter: &engine.Filter{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "FLTR_Charger4564",
|
||||
Rules: []*engine.FilterRule{
|
||||
{
|
||||
Type: utils.MetaString,
|
||||
Element: "~*req.Increment",
|
||||
Values: []string{"1s"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
var result string
|
||||
if err := fIdxCasesRPC.Call(utils.APIerSv1SetFilter, filter1, &result); err != nil {
|
||||
t.Error(err)
|
||||
} else if result != utils.OK {
|
||||
t.Error("Unexpected reply returned", result)
|
||||
}
|
||||
if err := fIdxCasesRPC.Call(utils.APIerSv1SetFilter, filter2, &result); err != nil {
|
||||
t.Error(err)
|
||||
} else if result != utils.OK {
|
||||
t.Error("Unexpected reply returned", result)
|
||||
}
|
||||
}
|
||||
|
||||
func testFilterIndexesCasesGetThresholdsIndexesChanged(t *testing.T) {
|
||||
arg := &v1.AttrGetFilterIndexes{
|
||||
Tenant: "cgrates.org",
|
||||
ItemType: utils.MetaThresholds,
|
||||
}
|
||||
expectedIndexes := []string{
|
||||
// TEST_PROFILE1"
|
||||
"*string:~*req.ToR:*voice:TEST_PROFILE1",
|
||||
"*prefix:~*req.CostRefunded:12345:TEST_PROFILE1",
|
||||
// TEST_PROFILE2"
|
||||
"*string:~*req.ToR:*voice:TEST_PROFILE2",
|
||||
"*prefix:~*req.CostRefunded:12345:TEST_PROFILE2",
|
||||
"*string:~*req.Increment:1s:TEST_PROFILE2",
|
||||
"*string:~*req.Destination:1443:TEST_PROFILE2",
|
||||
"*prefix:~*req.SetupTime:2022:TEST_PROFILE2",
|
||||
// TEST_PROFILE3"
|
||||
"*string:~*req.ToR:*voice:TEST_PROFILE3",
|
||||
"*prefix:~*req.CostRefunded:12345:TEST_PROFILE3",
|
||||
"*prefix:~*req.Cost:4:TEST_PROFILE3",
|
||||
"*string:~*req.Destination:1443:TEST_PROFILE3",
|
||||
"*prefix:~*req.SetupTime:2022:TEST_PROFILE3",
|
||||
// TEST_PROFILE4"
|
||||
"*none:*any:*any:TEST_PROFILE4",
|
||||
}
|
||||
sort.Strings(expectedIndexes)
|
||||
var reply []string
|
||||
if err := fIdxCasesRPC.Call(utils.APIerSv1GetFilterIndexes, arg, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if sort.Strings(reply); !reflect.DeepEqual(expectedIndexes, reply) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(expectedIndexes), utils.ToJSON(reply))
|
||||
}
|
||||
}
|
||||
|
||||
func testFilterIndexesCasesGetReverseFilterIndexes2(t *testing.T) {
|
||||
arg := &v1.AttrGetFilterIndexes{
|
||||
Tenant: "cgrates.org:FLTR_Charger",
|
||||
ItemType: utils.CacheReverseFilterIndexes,
|
||||
}
|
||||
expectedIndexes := []string{
|
||||
"*threshold_filter_indexes:TEST_PROFILE1",
|
||||
"*threshold_filter_indexes:TEST_PROFILE2",
|
||||
"*threshold_filter_indexes:TEST_PROFILE3",
|
||||
"*charger_filter_indexes:ChrgerIndexable",
|
||||
}
|
||||
sort.Strings(expectedIndexes)
|
||||
var reply []string
|
||||
if err := fIdxCasesRPC.Call(utils.APIerSv1GetFilterIndexes, arg, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if sort.Strings(reply); !reflect.DeepEqual(expectedIndexes, reply) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(expectedIndexes), utils.ToJSON(reply))
|
||||
}
|
||||
|
||||
arg = &v1.AttrGetFilterIndexes{
|
||||
Tenant: "cgrates.org:FLTR_Charger4564",
|
||||
ItemType: utils.CacheReverseFilterIndexes,
|
||||
}
|
||||
expectedIndexes = []string{
|
||||
"*threshold_filter_indexes:TEST_PROFILE2",
|
||||
"*charger_filter_indexes:ChrgerIndexable",
|
||||
}
|
||||
sort.Strings(expectedIndexes)
|
||||
if err := fIdxCasesRPC.Call(utils.APIerSv1GetFilterIndexes, arg, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if sort.Strings(reply); !reflect.DeepEqual(expectedIndexes, reply) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(expectedIndexes), utils.ToJSON(reply))
|
||||
}
|
||||
|
||||
arg = &v1.AttrGetFilterIndexes{
|
||||
Tenant: "cgrates.org:FLTR_Charger12312",
|
||||
ItemType: utils.CacheReverseFilterIndexes,
|
||||
}
|
||||
expectedIndexes = []string{
|
||||
"*threshold_filter_indexes:TEST_PROFILE2",
|
||||
"*threshold_filter_indexes:TEST_PROFILE3",
|
||||
"*charger_filter_indexes:ChrgerIndexable",
|
||||
}
|
||||
sort.Strings(expectedIndexes)
|
||||
if err := fIdxCasesRPC.Call(utils.APIerSv1GetFilterIndexes, arg, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if sort.Strings(reply); !reflect.DeepEqual(expectedIndexes, reply) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(expectedIndexes), utils.ToJSON(reply))
|
||||
}
|
||||
}
|
||||
|
||||
func testFilterIndexesCasesRemoveThresholdsProfile(t *testing.T) {
|
||||
var resp string
|
||||
if err := fIdxCasesRPC.Call(utils.APIerSv1RemoveThresholdProfile,
|
||||
&utils.TenantIDWithCache{Tenant: "cgrates.org", ID: "TEST_PROFILE1"}, &resp); err != nil {
|
||||
t.Error(err)
|
||||
} else if resp != utils.OK {
|
||||
t.Error("Unexpected reply returned", resp)
|
||||
}
|
||||
if err := fIdxCasesRPC.Call(utils.APIerSv1RemoveThresholdProfile,
|
||||
&utils.TenantIDWithCache{Tenant: "cgrates.org", ID: "TEST_PROFILE3"}, &resp); err != nil {
|
||||
t.Error(err)
|
||||
} else if resp != utils.OK {
|
||||
t.Error("Unexpected reply returned", resp)
|
||||
}
|
||||
}
|
||||
|
||||
func testFilterIndexesCasesGetIndexesAfterRemove2(t *testing.T) {
|
||||
arg := &v1.AttrGetFilterIndexes{
|
||||
Tenant: "cgrates.org",
|
||||
ItemType: utils.MetaThresholds,
|
||||
}
|
||||
expectedIndexes := []string{
|
||||
// TEST_PROFILE2"
|
||||
"*string:~*req.ToR:*voice:TEST_PROFILE2",
|
||||
"*prefix:~*req.CostRefunded:12345:TEST_PROFILE2",
|
||||
"*string:~*req.Increment:1s:TEST_PROFILE2",
|
||||
"*string:~*req.Destination:1443:TEST_PROFILE2",
|
||||
"*prefix:~*req.SetupTime:2022:TEST_PROFILE2",
|
||||
// TEST_PROFILE4"
|
||||
"*none:*any:*any:TEST_PROFILE4",
|
||||
}
|
||||
sort.Strings(expectedIndexes)
|
||||
var reply []string
|
||||
if err := fIdxCasesRPC.Call(utils.APIerSv1GetFilterIndexes, arg, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if sort.Strings(reply); !reflect.DeepEqual(expectedIndexes, reply) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(expectedIndexes), utils.ToJSON(reply))
|
||||
}
|
||||
}
|
||||
|
||||
func testFilterIndexesCasesGetReverseIndexesAfterRemove2(t *testing.T) {
|
||||
arg := &v1.AttrGetFilterIndexes{
|
||||
Tenant: "cgrates.org:FLTR_Charger",
|
||||
ItemType: utils.CacheReverseFilterIndexes,
|
||||
}
|
||||
expectedIndexes := []string{
|
||||
"*threshold_filter_indexes:TEST_PROFILE2",
|
||||
"*charger_filter_indexes:ChrgerIndexable",
|
||||
}
|
||||
sort.Strings(expectedIndexes)
|
||||
var reply []string
|
||||
if err := fIdxCasesRPC.Call(utils.APIerSv1GetFilterIndexes, arg, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if sort.Strings(reply); !reflect.DeepEqual(expectedIndexes, reply) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(expectedIndexes), utils.ToJSON(reply))
|
||||
}
|
||||
|
||||
arg = &v1.AttrGetFilterIndexes{
|
||||
Tenant: "cgrates.org:FLTR_Charger4564",
|
||||
ItemType: utils.CacheReverseFilterIndexes,
|
||||
}
|
||||
expectedIndexes = []string{
|
||||
"*threshold_filter_indexes:TEST_PROFILE2",
|
||||
"*charger_filter_indexes:ChrgerIndexable",
|
||||
}
|
||||
sort.Strings(expectedIndexes)
|
||||
if err := fIdxCasesRPC.Call(utils.APIerSv1GetFilterIndexes, arg, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if sort.Strings(reply); !reflect.DeepEqual(expectedIndexes, reply) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(expectedIndexes), utils.ToJSON(reply))
|
||||
}
|
||||
|
||||
arg = &v1.AttrGetFilterIndexes{
|
||||
Tenant: "cgrates.org:FLTR_Charger12312",
|
||||
ItemType: utils.CacheReverseFilterIndexes,
|
||||
}
|
||||
expectedIndexes = []string{
|
||||
"*threshold_filter_indexes:TEST_PROFILE2",
|
||||
"*charger_filter_indexes:ChrgerIndexable",
|
||||
}
|
||||
sort.Strings(expectedIndexes)
|
||||
if err := fIdxCasesRPC.Call(utils.APIerSv1GetFilterIndexes, arg, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if sort.Strings(reply); !reflect.DeepEqual(expectedIndexes, reply) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(expectedIndexes), utils.ToJSON(reply))
|
||||
}
|
||||
}
|
||||
|
||||
func testFilterIndexesCasesStopEngine(t *testing.T) {
|
||||
if err := engine.KillEngine(100); err != nil {
|
||||
t.Error(err)
|
||||
|
||||
Reference in New Issue
Block a user