Updated tests and methods for stats.go with tenant default value

This commit is contained in:
porosnicuadrian
2020-10-14 13:18:06 +03:00
committed by Dan Christian Bogos
parent cbc3151a95
commit 0af62ead8d
6 changed files with 188 additions and 35 deletions

View File

@@ -567,6 +567,12 @@ func testV1FIdxCaGetStatQueuesWithNotFound(t *testing.T) {
err.Error() != utils.ErrNotFound.Error() {
t.Error(err)
}
tEv.CGREventWithOpts.CGREvent.Tenant = utils.EmptyString
if err := tFIdxCaRpc.Call(utils.StatSv1ProcessEvent, tEv, &reply); err == nil ||
err.Error() != utils.ErrNotFound.Error() {
t.Error(err)
}
}
func testV1FIdxCaSetStatQueueProfile(t *testing.T) {

View File

@@ -27,10 +27,14 @@ import (
// GetStatQueueProfile returns a StatQueue profile
func (apierSv1 *APIerSv1) GetStatQueueProfile(arg *utils.TenantID, reply *engine.StatQueueProfile) (err error) {
if missing := utils.MissingStructFields(arg, []string{"Tenant", "ID"}); len(missing) != 0 { //Params missing
if missing := utils.MissingStructFields(arg, []string{utils.ID}); len(missing) != 0 { //Params missing
return utils.NewErrMandatoryIeMissing(missing...)
}
if sCfg, err := apierSv1.DataManager.GetStatQueueProfile(arg.Tenant, arg.ID,
tnt := arg.Tenant
if tnt == utils.EmptyString {
tnt = apierSv1.Config.GeneralCfg().DefaultTenant
}
if sCfg, err := apierSv1.DataManager.GetStatQueueProfile(tnt, arg.ID,
true, true, utils.NonTransactional); err != nil {
return utils.APIErrorHandler(err)
} else {
@@ -41,10 +45,11 @@ func (apierSv1 *APIerSv1) GetStatQueueProfile(arg *utils.TenantID, reply *engine
// GetStatQueueProfileIDs returns list of statQueueProfile IDs registered for a tenant
func (apierSv1 *APIerSv1) GetStatQueueProfileIDs(args *utils.PaginatorWithTenant, stsPrfIDs *[]string) error {
if missing := utils.MissingStructFields(args, []string{utils.Tenant}); len(missing) != 0 { //Params missing
return utils.NewErrMandatoryIeMissing(missing...)
tnt := args.Tenant
if tnt == utils.EmptyString {
tnt = apierSv1.Config.GeneralCfg().DefaultTenant
}
prfx := utils.StatQueueProfilePrefix + args.Tenant + ":"
prfx := utils.StatQueueProfilePrefix + tnt + ":"
keys, err := apierSv1.DataManager.DataDB().GetKeysForPrefix(prfx)
if err != nil {
return err
@@ -62,9 +67,12 @@ func (apierSv1 *APIerSv1) GetStatQueueProfileIDs(args *utils.PaginatorWithTenant
// SetStatQueueProfile alters/creates a StatQueueProfile
func (apierSv1 *APIerSv1) SetStatQueueProfile(arg *engine.StatQueueWithCache, reply *string) (err error) {
if missing := utils.MissingStructFields(arg.StatQueueProfile, []string{"Tenant", "ID"}); len(missing) != 0 {
if missing := utils.MissingStructFields(arg.StatQueueProfile, []string{utils.ID}); len(missing) != 0 {
return utils.NewErrMandatoryIeMissing(missing...)
}
if arg.Tenant == utils.EmptyString {
arg.Tenant = apierSv1.Config.GeneralCfg().DefaultTenant
}
if err = apierSv1.DataManager.SetStatQueueProfile(arg.StatQueueProfile, true); err != nil {
return utils.APIErrorHandler(err)
}
@@ -99,18 +107,22 @@ func (apierSv1 *APIerSv1) SetStatQueueProfile(arg *engine.StatQueueWithCache, re
// Remove a specific stat configuration
func (apierSv1 *APIerSv1) RemoveStatQueueProfile(args *utils.TenantIDWithCache, reply *string) error {
if missing := utils.MissingStructFields(args, []string{"Tenant", "ID"}); len(missing) != 0 { //Params missing
if missing := utils.MissingStructFields(args, []string{utils.ID}); len(missing) != 0 { //Params missing
return utils.NewErrMandatoryIeMissing(missing...)
}
if err := apierSv1.DataManager.RemoveStatQueueProfile(args.Tenant, args.ID, utils.NonTransactional, true); err != nil {
tnt := args.Tenant
if tnt == utils.EmptyString {
tnt = apierSv1.Config.GeneralCfg().DefaultTenant
}
if err := apierSv1.DataManager.RemoveStatQueueProfile(tnt, args.ID, utils.NonTransactional, true); err != nil {
return utils.APIErrorHandler(err)
}
//handle caching for StatQueueProfile
if err := apierSv1.CallCache(args.Cache, args.Tenant, utils.CacheStatQueueProfiles,
args.TenantID(), nil, nil, args.Opts); err != nil {
if err := apierSv1.CallCache(args.Cache, tnt, utils.CacheStatQueueProfiles,
utils.ConcatenatedKey(tnt, args.ID), nil, nil, args.Opts); err != nil {
return utils.APIErrorHandler(err)
}
if err := apierSv1.DataManager.RemoveStatQueue(args.Tenant, args.ID, utils.NonTransactional); err != nil {
if err := apierSv1.DataManager.RemoveStatQueue(tnt, args.ID, utils.NonTransactional); err != nil {
return utils.APIErrorHandler(err)
}
//generate a loadID for CacheStatQueueProfiles and CacheStatQueues and store it in database
@@ -120,8 +132,8 @@ func (apierSv1 *APIerSv1) RemoveStatQueueProfile(args *utils.TenantIDWithCache,
return utils.APIErrorHandler(err)
}
//handle caching for StatQueues
if err := apierSv1.CallCache(args.Cache, args.Tenant, utils.CacheStatQueues,
args.TenantID(), nil, nil, args.Opts); err != nil {
if err := apierSv1.CallCache(args.Cache, tnt, utils.CacheStatQueues,
utils.ConcatenatedKey(tnt, args.ID), nil, nil, args.Opts); err != nil {
return utils.APIErrorHandler(err)
}
*reply = utils.OK

View File

@@ -81,6 +81,8 @@ var (
testV1STSProcessMetricsWithFilter,
testV1STSProcessStaticMetrics,
testV1STSProcessStatWithThreshold,
testV1STSGetStatQueueProfileWithoutTenant,
testV1STSRemStatQueueProfileWithoutTenant,
//testV1STSProcessCDRStat,
testV1STSOverWriteStats,
testV1STSProcessStatWithThreshold2,
@@ -313,6 +315,13 @@ func testV1STSProcessEvent(t *testing.T) {
t.Errorf("expecting: %+v, received reply: %+v", expectedFloatMetrics2, floatMetrics2)
}
if err := stsV1Rpc.Call(utils.StatSv1GetQueueFloatMetrics,
&utils.TenantIDWithOpts{TenantID: &utils.TenantID{ID: "Stats1"}}, &floatMetrics2); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expectedFloatMetrics2, floatMetrics2) {
t.Errorf("expecting: %+v, received reply: %+v", expectedFloatMetrics2, floatMetrics2)
}
}
func testV1STSGetStatsAfterRestart(t *testing.T) {
@@ -434,6 +443,11 @@ func testV1STSSetStatQueueProfile(t *testing.T) {
func testV1STSGetStatQueueProfileIDs(t *testing.T) {
expected := []string{"Stats1", "TEST_PROFILE1"}
var result []string
if err := stsV1Rpc.Call(utils.APIerSv1GetStatQueueProfileIDs, &utils.PaginatorWithTenant{}, &result); err != nil {
t.Error(err)
} else if len(expected) != len(result) {
t.Errorf("Expecting : %+v, received: %+v", expected, result)
}
if err := stsV1Rpc.Call(utils.APIerSv1GetStatQueueProfileIDs, &utils.PaginatorWithTenant{Tenant: "cgrates.org"}, &result); err != nil {
t.Error(err)
} else if len(expected) != len(result) {
@@ -1170,3 +1184,63 @@ func BenchmarkSTSV1GetQueueStringMetrics(b *testing.B) {
}
}
}
func testV1STSGetStatQueueProfileWithoutTenant(t *testing.T) {
statConfig := &engine.StatQueueWithCache{
StatQueueProfile: &engine.StatQueueProfile{
ID: "TEST_PROFILE10",
FilterIDs: []string{"FLTR_1"},
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),
},
QueueLength: 10,
TTL: time.Duration(10) * time.Second,
Metrics: []*engine.MetricWithFilters{
{
MetricID: utils.MetaACD,
},
{
MetricID: utils.MetaTCD,
},
},
ThresholdIDs: []string{"Val1", "Val2"},
Blocker: true,
Stored: true,
Weight: 20,
MinItems: 1,
},
}
var result string
if err := stsV1Rpc.Call(utils.APIerSv1SetStatQueueProfile, statConfig, &result); err != nil {
t.Error(err)
} else if result != utils.OK {
t.Error("Unexpected reply returned", result)
}
statConfig.Tenant = "cgrates.org"
var reply *engine.StatQueueProfile
if err := stsV1Rpc.Call(utils.APIerSv1GetStatQueueProfile,
&utils.TenantID{ID: "TEST_PROFILE10"},
&reply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(reply, statConfig.StatQueueProfile) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(statConfig.StatQueueProfile), utils.ToJSON(reply))
}
}
func testV1STSRemStatQueueProfileWithoutTenant(t *testing.T) {
var reply string
if err := stsV1Rpc.Call(utils.APIerSv1RemoveStatQueueProfile,
&utils.TenantIDWithCache{ID: "TEST_PROFILE10"},
&reply); err != nil {
t.Error(err)
} else if reply != utils.OK {
t.Error("Unexpected reply returned", reply)
}
var result *engine.StatQueueProfile
if err := stsV1Rpc.Call(utils.APIerSv1GetStatQueueProfile,
&utils.TenantID{ID: "TEST_PROFILE10"},
&result); err == nil || utils.ErrNotFound.Error() != err.Error() {
t.Error(err)
}
}

View File

@@ -153,6 +153,23 @@ func testDspStsGetStatFailover(t *testing.T) {
t.Errorf("Expected error NOT_FOUND but recived %v and reply %v\n", err, reply)
}
allEngine2.startEngine(t)
args2.Tenant = utils.EmptyString
allEngine.stopEngine(t)
if err := dispEngine.RPC.Call(utils.StatSv1GetQueueStringMetrics,
args2, &metrics); err != nil {
t.Error(err)
}
allEngine.startEngine(t)
allEngine2.stopEngine(t)
if err := dispEngine.RPC.Call(utils.StatSv1GetQueueStringMetrics,
args2, &metrics); err == nil || err.Error() != utils.ErrNotFound.Error() {
t.Errorf("Expected error NOT_FOUND but recived %v and reply %v\n", err, reply)
}
allEngine2.startEngine(t)
}
func testDspStsPing(t *testing.T) {
@@ -369,4 +386,28 @@ func testDspStsTestAuthKey3(t *testing.T) {
} else if !reflect.DeepEqual(estats, reply) {
t.Errorf("expecting: %+v, received reply: %v", estats, reply)
}
if err := dispEngine.RPC.Call(utils.StatSv1GetStatQueuesForEvent,
&engine.StatsArgsProcessEvent{
CGREventWithOpts: &utils.CGREventWithOpts{
CGREvent: &utils.CGREvent{
ID: "GetStats",
Event: map[string]interface{}{
utils.Account: "1002",
utils.AnswerTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
utils.Usage: time.Duration(45 * time.Second),
utils.RunID: utils.MetaDefault,
utils.COST: 10.0,
utils.Destination: "1001",
},
},
Opts: map[string]interface{}{
utils.OptsAPIKey: "stat12345",
},
},
}, &reply); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(estats, reply) {
t.Errorf("expecting: %+v, received reply: %v", estats, reply)
}
}

View File

@@ -150,7 +150,7 @@ func (sS *StatService) StoreStatQueue(sq *StatQueue) (err error) {
}
// matchingStatQueuesForEvent returns ordered list of matching resources which are active by the time of the call
func (sS *StatService) matchingStatQueuesForEvent(args *StatsArgsProcessEvent) (sqs StatQueues, err error) {
func (sS *StatService) matchingStatQueuesForEvent(tnt string, args *StatsArgsProcessEvent) (sqs StatQueues, err error) {
evNm := utils.MapStorage{
utils.MetaReq: args.Event,
utils.MetaOpts: args.Opts,
@@ -161,7 +161,7 @@ func (sS *StatService) matchingStatQueuesForEvent(args *StatsArgsProcessEvent) (
sS.cgrcfg.StatSCfg().StringIndexedFields,
sS.cgrcfg.StatSCfg().PrefixIndexedFields,
sS.cgrcfg.StatSCfg().SuffixIndexedFields,
sS.dm, utils.CacheStatFilterIndexes, args.Tenant,
sS.dm, utils.CacheStatFilterIndexes, tnt,
sS.cgrcfg.StatSCfg().IndexedSelects,
sS.cgrcfg.StatSCfg().NestedFields,
)
@@ -171,7 +171,7 @@ func (sS *StatService) matchingStatQueuesForEvent(args *StatsArgsProcessEvent) (
}
sqs = make(StatQueues, 0, len(sqIDs))
for sqID := range sqIDs {
sqPrfl, err := sS.dm.GetStatQueueProfile(args.Tenant, sqID, true, true, utils.NonTransactional)
sqPrfl, err := sS.dm.GetStatQueueProfile(tnt, sqID, true, true, utils.NonTransactional)
if err != nil {
if err == utils.ErrNotFound {
continue
@@ -182,7 +182,7 @@ func (sS *StatService) matchingStatQueuesForEvent(args *StatsArgsProcessEvent) (
!sqPrfl.ActivationInterval.IsActiveAtTime(*args.Time) { // not active
continue
}
if pass, err := sS.filterS.Pass(args.Tenant, sqPrfl.FilterIDs,
if pass, err := sS.filterS.Pass(tnt, sqPrfl.FilterIDs,
evNm); err != nil {
return nil, err
} else if !pass {
@@ -263,8 +263,8 @@ func (attr *StatsArgsProcessEvent) Clone() *StatsArgsProcessEvent {
// processEvent processes a new event, dispatching to matching queues
// queues matching are also cached to speed up
func (sS *StatService) processEvent(args *StatsArgsProcessEvent) (statQueueIDs []string, err error) {
matchSQs, err := sS.matchingStatQueuesForEvent(args)
func (sS *StatService) processEvent(tnt string, args *StatsArgsProcessEvent) (statQueueIDs []string, err error) {
matchSQs, err := sS.matchingStatQueuesForEvent(tnt, args)
if err != nil {
return nil, err
}
@@ -287,7 +287,7 @@ func (sS *StatService) processEvent(args *StatsArgsProcessEvent) (statQueueIDs [
if err != nil {
utils.Logger.Warning(
fmt.Sprintf("<StatS> Queue: %s, ignoring event: %s, error: %s",
sq.TenantID(), args.TenantID(), err.Error()))
sq.TenantID(), utils.ConcatenatedKey(tnt, args.ID), err.Error()))
withErrors = true
}
if sS.cgrcfg.StatSCfg().StoreInterval != 0 && sq.dirty != nil { // don't save
@@ -352,13 +352,17 @@ func (sS *StatService) V1ProcessEvent(args *StatsArgsProcessEvent, reply *[]stri
if args.CGREvent == nil {
return utils.NewErrMandatoryIeMissing(utils.CGREventString)
}
if missing := utils.MissingStructFields(args, []string{utils.Tenant, utils.ID}); len(missing) != 0 { //Params missing
if missing := utils.MissingStructFields(args, []string{utils.ID}); len(missing) != 0 { //Params missing
return utils.NewErrMandatoryIeMissing(missing...)
} else if args.Event == nil {
return utils.NewErrMandatoryIeMissing(utils.Event)
}
tnt := args.Tenant
if tnt == utils.EmptyString {
tnt = sS.cgrcfg.GeneralCfg().DefaultTenant
}
var ids []string
if ids, err = sS.processEvent(args); err != nil {
if ids, err = sS.processEvent(tnt, args); err != nil {
return
}
*reply = ids
@@ -370,13 +374,17 @@ func (sS *StatService) V1GetStatQueuesForEvent(args *StatsArgsProcessEvent, repl
if args.CGREvent == nil {
return utils.NewErrMandatoryIeMissing(utils.CGREventString)
}
if missing := utils.MissingStructFields(args, []string{utils.Tenant, utils.ID}); len(missing) != 0 { //Params missing
if missing := utils.MissingStructFields(args, []string{utils.ID}); len(missing) != 0 { //Params missing
return utils.NewErrMandatoryIeMissing(missing...)
} else if args.Event == nil {
return utils.NewErrMandatoryIeMissing(utils.Event)
}
tnt := args.Tenant
if tnt == utils.EmptyString {
tnt = sS.cgrcfg.GeneralCfg().DefaultTenant
}
var sQs StatQueues
if sQs, err = sS.matchingStatQueuesForEvent(args); err != nil {
if sQs, err = sS.matchingStatQueuesForEvent(tnt, args); err != nil {
return
}
ids := make([]string, len(sQs))
@@ -389,7 +397,11 @@ func (sS *StatService) V1GetStatQueuesForEvent(args *StatsArgsProcessEvent, repl
// V1GetStatQueue returns a StatQueue object
func (sS *StatService) V1GetStatQueue(args *utils.TenantIDWithOpts, reply *StatQueue) (err error) {
sq, err := sS.dm.GetStatQueue(args.Tenant, args.ID, true, true, "")
tnt := args.Tenant
if tnt == utils.EmptyString {
tnt = sS.cgrcfg.GeneralCfg().DefaultTenant
}
sq, err := sS.dm.GetStatQueue(tnt, args.ID, true, true, "")
if err != nil {
return err
}
@@ -399,10 +411,14 @@ func (sS *StatService) V1GetStatQueue(args *utils.TenantIDWithOpts, reply *StatQ
// V1GetQueueStringMetrics returns the metrics of a Queue as string values
func (sS *StatService) V1GetQueueStringMetrics(args *utils.TenantID, reply *map[string]string) (err error) {
if missing := utils.MissingStructFields(args, []string{utils.Tenant, utils.ID}); len(missing) != 0 { //Params missing
if missing := utils.MissingStructFields(args, []string{utils.ID}); len(missing) != 0 { //Params missing
return utils.NewErrMandatoryIeMissing(missing...)
}
sq, err := sS.dm.GetStatQueue(args.Tenant, args.ID, true, true, "")
tnt := args.Tenant
if tnt == utils.EmptyString {
tnt = sS.cgrcfg.GeneralCfg().DefaultTenant
}
sq, err := sS.dm.GetStatQueue(tnt, args.ID, true, true, "")
if err != nil {
if err != utils.ErrNotFound {
err = utils.NewErrServerError(err)
@@ -421,10 +437,14 @@ func (sS *StatService) V1GetQueueStringMetrics(args *utils.TenantID, reply *map[
// V1GetQueueFloatMetrics returns the metrics as float64 values
func (sS *StatService) V1GetQueueFloatMetrics(args *utils.TenantID, reply *map[string]float64) (err error) {
if missing := utils.MissingStructFields(args, []string{utils.Tenant, utils.ID}); len(missing) != 0 { //Params missing
if missing := utils.MissingStructFields(args, []string{utils.ID}); len(missing) != 0 { //Params missing
return utils.NewErrMandatoryIeMissing(missing...)
}
sq, err := sS.dm.GetStatQueue(args.Tenant, args.ID, true, true, "")
tnt := args.Tenant
if tnt == utils.EmptyString {
tnt = sS.cgrcfg.GeneralCfg().DefaultTenant
}
sq, err := sS.dm.GetStatQueue(tnt, args.ID, true, true, "")
if err != nil {
if err != utils.ErrNotFound {
err = utils.NewErrServerError(err)

View File

@@ -250,7 +250,7 @@ func TestStatQueuesPopulateStatsService(t *testing.T) {
}
func TestStatQueuesMatchingStatQueuesForEvent(t *testing.T) {
msq, err := statService.matchingStatQueuesForEvent(statsEvs[0])
msq, err := statService.matchingStatQueuesForEvent(statsEvs[0].Tenant, statsEvs[0])
if err != nil {
t.Errorf("Error: %+v", err)
}
@@ -261,7 +261,7 @@ func TestStatQueuesMatchingStatQueuesForEvent(t *testing.T) {
} else if !reflect.DeepEqual(stqs[0].sqPrfl, msq[0].sqPrfl) {
t.Errorf("Expecting: %+v, received: %+v", stqs[0].sqPrfl, msq[0].sqPrfl)
}
msq, err = statService.matchingStatQueuesForEvent(statsEvs[1])
msq, err = statService.matchingStatQueuesForEvent(statsEvs[1].Tenant, statsEvs[1])
if err != nil {
t.Errorf("Error: %+v", err)
}
@@ -272,7 +272,7 @@ func TestStatQueuesMatchingStatQueuesForEvent(t *testing.T) {
} else if !reflect.DeepEqual(stqs[1].sqPrfl, msq[0].sqPrfl) {
t.Errorf("Expecting: %+v, received: %+v", stqs[1].sqPrfl, msq[0].sqPrfl)
}
msq, err = statService.matchingStatQueuesForEvent(statsEvs[2])
msq, err = statService.matchingStatQueuesForEvent(statsEvs[2].Tenant, statsEvs[2])
if err != nil {
t.Errorf("Error: %+v", err)
}
@@ -327,7 +327,7 @@ func TestStatQueuesProcessEvent(t *testing.T) {
func TestStatQueuesMatchWithIndexFalse(t *testing.T) {
statService.cgrcfg.StatSCfg().IndexedSelects = false
msq, err := statService.matchingStatQueuesForEvent(statsEvs[0])
msq, err := statService.matchingStatQueuesForEvent(statsEvs[0].Tenant, statsEvs[0])
if err != nil {
t.Errorf("Error: %+v", err)
}
@@ -338,7 +338,7 @@ func TestStatQueuesMatchWithIndexFalse(t *testing.T) {
} else if !reflect.DeepEqual(stqs[0].sqPrfl, msq[0].sqPrfl) {
t.Errorf("Expecting: %+v, received: %+v", stqs[0].sqPrfl, msq[0].sqPrfl)
}
msq, err = statService.matchingStatQueuesForEvent(statsEvs[1])
msq, err = statService.matchingStatQueuesForEvent(statsEvs[1].Tenant, statsEvs[1])
if err != nil {
t.Errorf("Error: %+v", err)
}
@@ -349,7 +349,7 @@ func TestStatQueuesMatchWithIndexFalse(t *testing.T) {
} else if !reflect.DeepEqual(stqs[1].sqPrfl, msq[0].sqPrfl) {
t.Errorf("Expecting: %+v, received: %+v", stqs[1].sqPrfl, msq[0].sqPrfl)
}
msq, err = statService.matchingStatQueuesForEvent(statsEvs[2])
msq, err = statService.matchingStatQueuesForEvent(statsEvs[2].Tenant, statsEvs[2])
if err != nil {
t.Errorf("Error: %+v", err)
}