From 05a989aec05b23af182d400986f0368267e98617 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 5 Dec 2019 16:02:39 +0200 Subject: [PATCH] Added test for Threshold with filter on BalanceSummaries in CDRServer --- apier/v2/cdrs_it_test.go | 100 +++++++++++++++++++++++++++++++++++++++ engine/filterhelpers.go | 12 ++--- engine/thresholds.go | 2 +- utils/reflect.go | 2 +- 4 files changed, 106 insertions(+), 10 deletions(-) diff --git a/apier/v2/cdrs_it_test.go b/apier/v2/cdrs_it_test.go index 1b67a487e..34a2773ab 100644 --- a/apier/v2/cdrs_it_test.go +++ b/apier/v2/cdrs_it_test.go @@ -20,6 +20,7 @@ along with this program. If not, see package v2 import ( + "fmt" "net/rpc" "path" "reflect" @@ -59,6 +60,10 @@ var sTestsCDRsIT = []func(t *testing.T){ testV2CDRsRateCDRsWithRatingPlan, testV2CDRsGetCdrsWithRattingPlan, + testV2CDRsSetThreshold, + testV2CDRsProcessCDRWithThreshold, + testV2CDRsGetThreshold, + testV2CDRsKillEngine, } @@ -707,6 +712,101 @@ func testV2CDRsGetCdrsWithRattingPlan(t *testing.T) { } } } +func testV2CDRsSetThreshold(t *testing.T) { + var reply string + if err := cdrsRpc.Call(utils.ApierV2SetActions, &utils.AttrSetActions{ + ActionsId: "ACT_LOG", + Actions: []*utils.TPAction{{Identifier: utils.LOG}}, + }, &reply); err != nil && err.Error() != utils.ErrExists.Error() { + t.Error(err) + } else if reply != utils.OK { + t.Errorf("Calling ApierV2.SetActions received: %s", reply) + } + tPrfl := engine.ThresholdWithCache{ + ThresholdProfile: &engine.ThresholdProfile{ + Tenant: "cgrates.org", + ID: "THD_Test", + FilterIDs: []string{ + "*lt:~*req.CostDetails.AccountSummary.BalanceSummaries[0].Value:10", + "*string:~*req.Account:1005", // only for indexes + }, + MaxHits: -1, + Weight: 30, + ActionIDs: []string{"ACT_LOG"}, + }, + } + if err := cdrsRpc.Call(utils.ApierV1SetThresholdProfile, tPrfl, &reply); err != nil { + t.Error(err) + } else if reply != utils.OK { + t.Error("Unexpected reply returned", reply) + } + attrSetAcnt := AttrSetAccount{ + Tenant: "cgrates.org", + Account: "1005", + ExtraOptions: map[string]bool{ + utils.AllowNegative: true, + }, + } + if err := cdrsRpc.Call(utils.ApierV2SetAccount, attrSetAcnt, &reply); err != nil { + t.Fatal(err) + } + attrs := &utils.AttrSetBalance{ + Tenant: "cgrates.org", + Account: "1005", + BalanceType: utils.MONETARY, + Balance: map[string]interface{}{ + utils.ID: utils.META_DEFAULT, + utils.Value: 1, + utils.Weight: 10.0, + }, + } + if err := cdrsRpc.Call(utils.ApierV2SetBalance, attrs, &reply); err != nil { + t.Fatal(err) + } +} + +func testV2CDRsProcessCDRWithThreshold(t *testing.T) { + args := &engine.ArgV1ProcessEvent{ + Flags: []string{ + fmt.Sprintf("%s:true", utils.MetaThresholds), + fmt.Sprintf("%s:true", utils.MetaRALs), + }, + CGREvent: utils.CGREvent{ + Tenant: "cgrates.org", + Event: map[string]interface{}{ + utils.OriginID: "testV2CDRsProcessCDRWithThreshold", + utils.OriginHost: "192.168.1.1", + utils.Source: "testV2CDRsProcessCDRWithThreshold", + utils.RequestType: utils.META_PREPAID, + utils.Category: "call", + utils.Account: "1005", + utils.Subject: "ANY2CNT", + utils.Destination: "+4986517174963", + utils.AnswerTime: time.Date(2018, 8, 24, 16, 00, 26, 0, time.UTC), + utils.Usage: 100 * time.Minute, + "field_extr1": "val_extr1", + "fieldextr2": "valextr2", + }, + }, + } + var reply string + if err := cdrsRpc.Call(utils.CDRsV1ProcessEvent, args, &reply); err != nil { + t.Error("Unexpected error: ", err.Error()) + } else if reply != utils.OK { + t.Error("Unexpected reply received: ", reply) + } + time.Sleep(time.Duration(100) * time.Millisecond) // Give time for CDR to be rated +} + +func testV2CDRsGetThreshold(t *testing.T) { + var td engine.Threshold + if err := cdrsRpc.Call(utils.ThresholdSv1GetThreshold, + &utils.TenantIDWithArgDispatcher{TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: "THD_Test"}}, &td); err != nil { + t.Error(err) + } else if td.Hits != 1 { + t.Errorf("Expecting threshold to be hit once") + } +} func testV2CDRsKillEngine(t *testing.T) { if err := engine.KillEngine(*waitRater); err != nil { diff --git a/engine/filterhelpers.go b/engine/filterhelpers.go index 774360845..e69aa9040 100644 --- a/engine/filterhelpers.go +++ b/engine/filterhelpers.go @@ -36,7 +36,6 @@ func MatchingItemIDsForEvent(ev map[string]interface{}, stringFldIDs, prefixFldI // Guard will protect the function with automatic locking lockID := utils.CacheInstanceToPrefix[cacheID] + itemIDPrefix guardian.Guardian.Guard(func() (gRes interface{}, gErr error) { - if !indexedSelects { var keysWithID []string if keysWithID, err = dm.DataDB().GetKeysForPrefix(utils.CacheIndexesToPrefix[cacheID]); err != nil { @@ -53,14 +52,11 @@ func MatchingItemIDsForEvent(ev map[string]interface{}, stringFldIDs, prefixFldI i := 0 for fldID := range ev { allFieldIDs[i] = fldID - i += 1 + i++ } - stringFieldVals := map[string]string{utils.ANY: utils.ANY} // cache here field string values, start with default one - filterIndexTypes := []string{utils.MetaString, utils.MetaPrefix, utils.META_NONE} - for i, fieldIDs := range []*[]string{stringFldIDs, prefixFldIDs, nil} { // same routine for both string and prefix filter types - if filterIndexTypes[i] == utils.META_NONE { - fieldIDs = &[]string{utils.ANY} // so we can query DB for unindexed filters - } + stringFieldVals := map[string]string{utils.ANY: utils.ANY} // cache here field string values, start with default one + filterIndexTypes := []string{utils.MetaString, utils.MetaPrefix, utils.META_NONE} // the META_NONE is used for all items that do not have filters + for i, fieldIDs := range []*[]string{stringFldIDs, prefixFldIDs, &[]string{utils.ANY}} { // same routine for both string and prefix filter types if fieldIDs == nil { fieldIDs = &allFieldIDs } diff --git a/engine/thresholds.go b/engine/thresholds.go index 24be9aee4..a6b80de80 100644 --- a/engine/thresholds.go +++ b/engine/thresholds.go @@ -299,7 +299,7 @@ func (tS *ThresholdService) processEvent(args *ArgsProcessEvent) (thresholdsIDs var tIDs []string for _, t := range matchTs { tIDs = append(tIDs, t.ID) - t.Hits += 1 + t.Hits++ err = t.ProcessEvent(args, tS.dm) if err != nil { utils.Logger.Warning( diff --git a/utils/reflect.go b/utils/reflect.go index be29d0ef0..db2dd8e07 100644 --- a/utils/reflect.go +++ b/utils/reflect.go @@ -646,7 +646,7 @@ func ReflectFieldMethodInterface(obj interface{}, fldName string) (retIf interfa if err != nil { return nil, err } - if idx > v.Len()-1 { + if idx >= v.Len() { return nil, fmt.Errorf("index out of range") } field = v.Index(idx)