From 67d9c634f64a2a02b64f4602a6254b760306af1c Mon Sep 17 00:00:00 2001 From: gezimbll Date: Thu, 9 Mar 2023 10:57:57 -0500 Subject: [PATCH] Improving coverage tests engine --- engine/cdrs_test.go | 49 ++++++++- engine/chargers_test.go | 133 +++++++++++++++++++++++ engine/datamanager_test.go | 20 +++- engine/stats_test.go | 214 +++++++++++++++++++++++++++++++++++++ engine/suppliers_test.go | 61 +++++++++++ 5 files changed, 474 insertions(+), 3 deletions(-) diff --git a/engine/cdrs_test.go b/engine/cdrs_test.go index b33475145..4a0ddfe22 100644 --- a/engine/cdrs_test.go +++ b/engine/cdrs_test.go @@ -20,11 +20,12 @@ package engine import ( "fmt" + "testing" + "time" + "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/utils" "github.com/cgrates/rpcclient" - "testing" - "time" ) type clMock func(_ string, _ interface{}, _ interface{}) error @@ -223,3 +224,47 @@ func TestCDRSV1V1ProcessExternalCDRNoTenant(t *testing.T) { t.Error(err) } } + +func TestCDRSRateExportCDRS(t *testing.T) { + cfg, err := config.NewDefaultCGRConfig() + if err != nil { + t.Error(err) + } + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + cfg.CdrsCfg().OnlineCDRExports = []string{"stringy"} + cfg.CdreProfiles = map[string]*config.CdreCfg{"stringy": {}} + cdrs := &CDRServer{ + cgrCfg: cfg, + connMgr: nil, + cdrDb: db, + dm: dm, + } + cdr := &CDR{ + ToR: utils.VOICE, + OriginID: "testDspCDRsProcessExternalCDR", + OriginHost: "127.0.0.1", + Source: utils.UNIT_TEST, + RequestType: utils.META_RATED, + Tenant: "cgrates.org", + Category: "call", + Account: "1003", + Subject: "1003", + Destination: "1001", + + Usage: time.Second, + } + if err := cdrs.cdrDb.SetCDR(cdr, true); err != nil { + t.Error(err) + } + arg := &ArgRateCDRs{ + Flags: []string{"*export:true"}, + RPCCDRsFilter: utils.RPCCDRsFilter{}, + } + var reply string + if err := cdrs.V1RateCDRs(arg, &reply); err != nil { + t.Error(err) + } else if reply != utils.OK { + t.Errorf("Expected ok ,received %v", reply) + } +} diff --git a/engine/chargers_test.go b/engine/chargers_test.go index a7a8e82b3..9a055511b 100755 --- a/engine/chargers_test.go +++ b/engine/chargers_test.go @@ -24,6 +24,7 @@ import ( "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/utils" + "github.com/cgrates/rpcclient" ) var ( @@ -221,3 +222,135 @@ func TestChargerProcessEvent(t *testing.T) { t.Errorf("Expecting: %+v, received: %+v ", utils.ToJSON(rpl[0]), utils.ToJSON(rcv[0])) } } + +func TestChargerV1GetChargersForEvent(t *testing.T) { + cfg, err := config.NewDefaultCGRConfig() + if err != nil { + t.Error(err) + } + Cache.Clear(nil) + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + chgS := &ChargerService{ + dm: dm, + cfg: cfg, + filterS: NewFilterS(cfg, nil, dm), + } + args := &utils.CGREventWithArgDispatcher{ + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: utils.GenUUID(), + Event: map[string]interface{}{ + "Charger": "ChargerProfile1", + utils.AnswerTime: time.Date(2014, 7, 14, 14, 30, 0, 0, time.UTC), + "UsageInterval": "1s", + utils.Weight: "180.0", + }, + }, + } + flt := &Filter{ + Tenant: "cgrates.org", + ID: "FLTR_CP_1", + Rules: []*FilterRule{ + { + Type: utils.MetaString, + Element: "~*req.Charger", + Values: []string{"ChargerProfile1"}, + }, + }, + } + if err := dm.SetFilter(flt); err != nil { + t.Error(err) + } + chP := &ChargerProfile{ + Tenant: "cgrates.org", + ID: "CPP_1", + FilterIDs: []string{"FLTR_CP_1"}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + }, + RunID: "TestRunID", + AttributeIDs: []string{"*none"}, + Weight: 20, + } + if err := dm.SetChargerProfile(chP, true); err != nil { + t.Error(err) + } + var reply ChargerProfiles + exp := ChargerProfiles{ + chP, + } + if err := chgS.V1GetChargersForEvent(args, &reply); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(reply, exp) { + t.Errorf("Expected %v,Received %v", utils.ToJSON(exp), utils.ToJSON(reply)) + } + +} + +func TestChargerV1ProcessEvent(t *testing.T) { + cfg, err := config.NewDefaultCGRConfig() + if err != nil { + t.Error(err) + } + Cache.Clear(nil) + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + cfg.ChargerSCfg().AttributeSConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes)} + clientConn := make(chan rpcclient.ClientConnector, 1) + clientConn <- clMock(func(_ string, _, _ interface{}) error { + return nil + }) + connMngr := NewConnManager(cfg, map[string]chan rpcclient.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes): clientConn, + }) + chgS := &ChargerService{ + dm: dm, + cfg: cfg, + filterS: NewFilterS(cfg, nil, dm), + connMgr: connMngr, + } + args := &utils.CGREventWithArgDispatcher{ + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: utils.GenUUID(), + Event: map[string]interface{}{ + "Charger": "ChargerProfile1", + utils.AnswerTime: time.Date(2014, 7, 14, 14, 30, 0, 0, time.UTC), + "UsageInterval": "1s", + utils.Weight: "180.0", + }, + }} + flt := &Filter{ + Tenant: "cgrates.org", + ID: "FLTR_CP_1", + Rules: []*FilterRule{ + { + Type: utils.MetaString, + Element: "~*req.Charger", + Values: []string{"ChargerProfile1"}, + }, + }, + } + if err := dm.SetFilter(flt); err != nil { + t.Error(err) + } + chP := &ChargerProfile{ + Tenant: "cgrates.org", + ID: "CPP_1", + FilterIDs: []string{"FLTR_CP_1"}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + }, + RunID: "TestRunID", + AttributeIDs: []string{"ATTR_1"}, + } + if err := dm.SetChargerProfile(chP, true); err != nil { + t.Error(err) + } + var reply []*ChrgSProcessEventReply + if err := chgS.V1ProcessEvent(args, &reply); err != nil { + t.Error(err) + } + +} diff --git a/engine/datamanager_test.go b/engine/datamanager_test.go index ec818cf50..eaffb0cf2 100644 --- a/engine/datamanager_test.go +++ b/engine/datamanager_test.go @@ -136,8 +136,25 @@ func TestDmSetSupplierProfileRpl(t *testing.T) { func TestDmMatchFilterIndexFromKey(t *testing.T) { cfg, _ := config.NewDefaultCGRConfig() + defer func() { + cfg2, _ := config.NewDefaultCGRConfig() + config.SetCgrConfig(cfg2) + }() db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) - dm := NewDataManager(db, cfg.CacheCfg(), nil) + cfg.DataDbCfg().Items[utils.MetaFilterIndexes].Remote = true + cfg.DataDbCfg().RmtConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.ReplicatorSv1)} + clientConn := make(chan rpcclient.ClientConnector, 1) + clientConn <- &ccMock{ + calls: map[string]func(args interface{}, reply interface{}) error{ + utils.ReplicatorSv1MatchFilterIndex: func(args, reply interface{}) error { + return nil + }, + }, + } + connMgr := NewConnManager(cfg, map[string]chan rpcclient.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.ReplicatorSv1): clientConn, + }) + dm := NewDataManager(db, cfg.CacheCfg(), connMgr) fltr := &Filter{ Tenant: "cgrates.org", ID: "RES_FLT_1", @@ -164,6 +181,7 @@ func TestDmMatchFilterIndexFromKey(t *testing.T) { if err := dm.SetResourceProfile(rp, true); err != nil { t.Error(err) } + config.SetCgrConfig(cfg) if err := dm.MatchFilterIndexFromKey(utils.CacheResourceFilterIndexes, "cgrates.org:*string:Account:1002"); err == nil { t.Error(err) } diff --git a/engine/stats_test.go b/engine/stats_test.go index c756ff6f4..5605e40ea 100644 --- a/engine/stats_test.go +++ b/engine/stats_test.go @@ -401,3 +401,217 @@ func TestStatQueuesV1ProcessEvent(t *testing.T) { t.Errorf("Expecting: %+v, received: %+v", expected, reply) } } + +func TestStatQueueFloatMetrics(t *testing.T) { + cfg, err := config.NewDefaultCGRConfig() + if err != nil { + t.Error(err) + } + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + + sS, err := NewStatService(dm, cfg, nil, nil) + if err != nil { + t.Error(err) + } + sq := &StatQueue{ + Tenant: "cgrates.org", + ID: "TestStats", + SQItems: []SQItem{ + {EventID: "cgrates.org:ev1"}, + {EventID: "cgrates.org:ev2"}, + {EventID: "cgrates.org:ev3"}, + }, + SQMetrics: map[string]StatMetric{ + utils.MetaASR: &StatASR{ + Answered: 2, + Count: 3, + Events: map[string]*StatWithCompress{ + "cgrates.org:ev1": {Stat: 1}, + "cgrates.org:ev2": {Stat: 1}, + "cgrates.org:ev3": {Stat: 0}, + }, + }, + }, + } + dm.SetStatQueue(sq) + args := &utils.TenantID{ + Tenant: "cgrates.org", + ID: "TestStats", + } + var reply map[string]float64 + exp := map[string]float64{ + utils.MetaASR: 66.66667, + } + if err := sS.V1GetQueueFloatMetrics(args, &reply); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(reply, exp) { + t.Errorf("Expected %v,Received %v", utils.ToJSON(exp), utils.ToJSON(reply)) + } +} + +func TestStatStoreStatQueue(t *testing.T) { + cfg, err := config.NewDefaultCGRConfig() + if err != nil { + t.Error(err) + } + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + + sS, err := NewStatService(dm, cfg, nil, nil) + if err != nil { + t.Error(err) + } + sq := &StatQueue{ + dirty: utils.BoolPointer(true), + SQMetrics: map[string]StatMetric{ + utils.MetaASR: &StatASR{ + Answered: 1, + Count: 1, + Events: map[string]*StatWithCompress{ + "cgrates.org:TestStatRemExpired_1": {Stat: 1, CompressFactor: 1}, + }, + }, + }, + sqPrfl: &StatQueueProfile{ + QueueLength: 2, //unlimited que + }, + } + if err := sS.StoreStatQueue(sq); err != nil { + t.Error(err) + } else if *sq.dirty { + t.Error("Expected false") + } +} + +func TestStatsGetStatQueuesForEvent(t *testing.T) { + cfg, err := config.NewDefaultCGRConfig() + if err != nil { + t.Error(err) + } + Cache.Clear(nil) + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + sS, err := NewStatService(dm, cfg, NewFilterS(cfg, nil, dm), nil) + if err != nil { + t.Error(err) + } + args := &StatsArgsProcessEvent{ + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: utils.GenUUID(), + Event: map[string]interface{}{ + "Stat": "Stat1_1", + utils.AnswerTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + utils.Usage: time.Duration(11 * time.Second), + utils.COST: 12.5, + utils.PDD: time.Duration(12 * time.Second), + }, + }, + } + fltr := &Filter{ + Tenant: "cgrates.org", + ID: "FLTR_STAT_1", + Rules: []*FilterRule{{ + Type: "*string", + Element: "~*req.Stat", + Values: []string{"Stat1_1"}, + }, + }, + } + dm.SetFilter(fltr) + sqP := &StatQueueProfile{ + Tenant: "cgrates.org", + ID: "Stats1", + FilterIDs: []string{ + "FLTR_STAT_1", + }, + QueueLength: 10, + TTL: time.Duration(10) * time.Second, + Metrics: []*MetricWithFilters{ + { + MetricID: utils.MetaACD, + }, + { + MetricID: utils.MetaTCD, + }, + }, + ThresholdIDs: []string{"*none"}, + Weight: 20, + MinItems: 1, + } + sq := &StatQueue{ + Tenant: "cgrates.org", + ID: "Stats1", + SQItems: []SQItem{ + {EventID: "cgrates.org:ev1", ExpiryTime: utils.TimePointer(time.Date(2023, 12, 24, 17, 0, 0, 0, time.UTC))}, + }, + SQMetrics: map[string]StatMetric{ + utils.MetaASR: &StatASR{ + Answered: 2, + Count: 3, + Events: map[string]*StatWithCompress{ + "cgrates.org:ev1": {Stat: 1}, + }, + }, + }, + } + dm.SetStatQueue(sq) + dm.SetStatQueueProfile(sqP, true) + var reply []string + expIds := []string{ + "Stats1", + } + if err := sS.V1GetStatQueuesForEvent(args, &reply); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(expIds, reply) { + t.Errorf("Expected %v,Received %v", expIds, reply) + } +} + +func TestStatSGetQueueIDs(t *testing.T) { + cfg, err := config.NewDefaultCGRConfig() + if err != nil { + t.Error(err) + } + Cache.Clear(nil) + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + sS, err := NewStatService(dm, cfg, NewFilterS(cfg, nil, dm), nil) + if err != nil { + t.Error(err) + } + sqs := StatQueues{ + &StatQueue{ + Tenant: "cgrates.org", + ID: "Stats1", + SQMetrics: map[string]StatMetric{ + "*tcc": nil, + "*sum:~Usage": nil, + "*avreage:~Cost": nil, + }, + }, + &StatQueue{ + Tenant: "cgrates.org", + ID: "Stats2", + SQMetrics: map[string]StatMetric{ + utils.MetaASR: &StatASR{ + Answered: 2, + Count: 3, + }, + }, + }, + } + for _, sq := range sqs { + dm.SetStatQueue(sq) + } + var qIDs []string + expqIds := []string{ + "Stats1", "Stats2", + } + if err := sS.V1GetQueueIDs("cgrates.org", &qIDs); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(expqIds, qIDs) { + t.Errorf("Expected %v,Received %v", expqIds, qIDs) + } +} diff --git a/engine/suppliers_test.go b/engine/suppliers_test.go index b6e887e86..84682e5c0 100644 --- a/engine/suppliers_test.go +++ b/engine/suppliers_test.go @@ -911,3 +911,64 @@ func TestV1GetSuppliersWithAttributeS(t *testing.T) { } } + +func TestSupplierServicePopulateSortingData(t *testing.T) { + cfg, err := config.NewDefaultCGRConfig() + if err != nil { + t.Error(err) + } + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + fltr := &Filter{ + Tenant: "cgrates.org", + ID: "FLTR_2", + Rules: []*FilterRule{ + { + Type: utils.MetaString, + Element: "~*req.Supplier", + Values: []string{"SupplierProfile2"}, + }, + { + Type: utils.MetaGreaterOrEqual, + Element: "~*req.PddInterval", + Values: []string{(1 * time.Second).String()}, + }, + { + Type: utils.MetaGreaterOrEqual, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Weight, + Values: []string{"15.0"}, + }, + }, + } + if err := dm.SetFilter(fltr); err != nil { + t.Error(err) + } + spl, err := NewSupplierService(dm, NewFilterS(cfg, nil, dm), cfg, nil) + if err != nil { + t.Error(err) + } + + ev := &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "utils.CGREvent1", + Event: map[string]interface{}{ + "Supplier": "SupplierProfile2", + utils.AnswerTime: time.Date(2014, 7, 14, 14, 30, 0, 0, time.UTC), + "UsageInterval": "1s", + "PddInterval": "1s", + "Weight": "20.0", + }, + } + sup := &Supplier{ + ID: "SPL2", + FilterIDs: []string{"FLTR_2"}, + Weight: 20, + Blocker: true, + SupplierParameters: "SortingParameter2", + } + extraOpt := &optsGetSuppliers{} + + if _, pass, err := spl.populateSortingData(ev, sup, extraOpt, nil); err != nil || !pass { + t.Error(err) + } +}