From 5d62899d75c0d37b83d4710e93a2525c7b27ebe4 Mon Sep 17 00:00:00 2001 From: gezimbll Date: Wed, 10 May 2023 09:40:55 -0400 Subject: [PATCH] Improving coverage tests at engine --- engine/attributes_test.go | 43 +++++++++ engine/cdrs_test.go | 32 ++++++- engine/datamanager_test.go | 31 +++++++ engine/responder_test.go | 182 +++++++++++++++++++++++++++++++++++++ engine/routes_test.go | 118 ++++++++++++++++++++++++ 5 files changed, 404 insertions(+), 2 deletions(-) diff --git a/engine/attributes_test.go b/engine/attributes_test.go index cf9d14b7d..83466a4c1 100644 --- a/engine/attributes_test.go +++ b/engine/attributes_test.go @@ -1399,3 +1399,46 @@ func TestArgeesRPCClone(t *testing.T) { t.Errorf("expected %v,received %v", utils.ToJSON(exp), utils.ToJSON(val)) } } + +func TestAttrSV1GetAttributeForEvent(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + filterS := NewFilterS(cfg, nil, dm) + Cache.Clear(nil) + attS := NewAttributeService(dm, filterS, cfg) + args := &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "AttrEvent", + Event: map[string]interface{}{ + utils.RequestType: utils.MetaPostpaid, + }, + APIOpts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: 3, + utils.OptsContext: utils.MetaAny, + utils.OptsAttributesProfileIDs: []string{"ATTR1"}, + }, + } + postpaid, err := config.NewRSRParsers(utils.MetaPostpaid, utils.InfieldSep) + if err != nil { + t.Error(err) + } + dm.SetAttributeProfile(&AttributeProfile{ + Tenant: "cgrates.org", + ID: "ATTR1", + Contexts: []string{utils.MetaAny}, + Attributes: []*Attribute{ + { + Path: "*req.RequestType", + Type: utils.MetaConstant, + Value: postpaid, + }, + }, + Weight: 10, + }, true) + var attrPrf AttributeProfile + if err := attS.V1GetAttributeForEvent(args, &attrPrf); err != nil { + t.Error(err) + } + +} diff --git a/engine/cdrs_test.go b/engine/cdrs_test.go index 489bf2a69..c3ad3c1ed 100644 --- a/engine/cdrs_test.go +++ b/engine/cdrs_test.go @@ -2276,12 +2276,35 @@ func TestStoreSMCostErr(t *testing.T) { func TestCDRSGetCDRs(t *testing.T) { cfg := config.NewDefaultCGRConfig() + cfg.CdrsCfg().EEsConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaEEs)} + cfg.CdrsCfg().ThresholdSConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds)} + cfg.CdrsCfg().StatSConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats)} db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) dm := NewDataManager(db, cfg.CacheCfg(), nil) + clientConn := make(chan rpcclient.ClientConnector, 1) + clientConn <- clMock(func(serviceMethod string, _, _ interface{}) error { + if serviceMethod == utils.EeSv1ProcessEvent { + + return nil + } + if serviceMethod == utils.ThresholdSv1ProcessEvent { + return nil + } + if serviceMethod == utils.StatSv1ProcessEvent { + return nil + } + + return utils.ErrNotImplemented + }) cdrS := &CDRServer{ cgrCfg: cfg, cdrDb: db, dm: dm, + connMgr: NewConnManager(cfg, map[string]chan rpcclient.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaEEs): clientConn, + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds): clientConn, + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats): clientConn, + }), } arg := &ArgV1ProcessEvent{ CGREvent: utils.CGREvent{ @@ -2293,15 +2316,21 @@ func TestCDRSGetCDRs(t *testing.T) { utils.OriginHost: "host", utils.RequestType: utils.MetaPrepaid, utils.AccountField: "1001", + utils.OriginID: "OriginCDR2", + utils.CGRID: "TestCGRID", utils.Subject: "1001", + utils.RunID: utils.MetaDefault, utils.Destination: "1002", utils.SetupTime: time.Date(2018, time.January, 7, 16, 60, 0, 0, time.UTC), utils.AnswerTime: time.Date(2018, time.January, 7, 16, 60, 10, 0, time.UTC), utils.Usage: 10 * time.Minute, }, + APIOpts: map[string]interface{}{ + utils.OptsStatS: true, + }, }, Flags: []string{ - utils.MetaStore, utils.MetaRALs, + utils.MetaStore, utils.MetaRALs, utils.MetaExport, utils.MetaThresholds, }, } var reply string @@ -2318,5 +2347,4 @@ func TestCDRSGetCDRs(t *testing.T) { if err := cdrS.V1GetCDRs(args, &cdrs); err != nil { t.Error(err) } - } diff --git a/engine/datamanager_test.go b/engine/datamanager_test.go index 866dd3aa3..8562394ca 100644 --- a/engine/datamanager_test.go +++ b/engine/datamanager_test.go @@ -4980,3 +4980,34 @@ func TestDmRebuildReverseForPrefix(t *testing.T) { }) } } + +func TestDmUpdateReverseDestination(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + dst := &Destination{Id: "OldDest", Prefixes: []string{"+494", "+495", "+496"}} + dst2 := &Destination{Id: "NewDest", Prefixes: []string{"+497", "+498", "+499"}} + if _, rcvErr := dm.GetReverseDestination(dst.Id, false, true, utils.NonTransactional); rcvErr != utils.ErrNotFound { + t.Error(rcvErr) + } + if err := dm.SetReverseDestination(dst.Id, dst.Prefixes, utils.NonTransactional); err != nil { + t.Error(err) + } + for i := range dst.Prefixes { + if rcv, err := dm.GetReverseDestination(dst.Prefixes[i], false, true, utils.NonTransactional); err != nil { + t.Error(err) + } else if !reflect.DeepEqual([]string{dst.Id}, rcv) { + t.Errorf("Expecting: %v, received: %v", []string{dst.Id}, rcv) + } + } + if err := dm.UpdateReverseDestination(dst, dst2, utils.NonTransactional); err != nil { + t.Error(err) + } + for i := range dst.Prefixes { + if rcv, err := dm.GetReverseDestination(dst2.Prefixes[i], false, true, utils.NonTransactional); err != nil { + t.Error(err) + } else if !reflect.DeepEqual([]string{dst2.Id}, rcv) { + t.Errorf("Expecting: %v, received: %v", []string{dst.Id}, rcv) + } + } +} diff --git a/engine/responder_test.go b/engine/responder_test.go index a676652d4..dc558784d 100644 --- a/engine/responder_test.go +++ b/engine/responder_test.go @@ -1292,3 +1292,185 @@ func TestResponderShutDown(t *testing.T) { t.Errorf("Expected Done!,Received %v", reply) } } + +func TestResponderDebitDebit(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + tmpdm := dm + defer func() { + dm = tmpdm + }() + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + rsponder.MaxComputedUsage = map[string]time.Duration{ + utils.MetaAny: 10 * time.Minute, + utils.MetaVoice: 80 * time.Minute, + } + cd := &CallDescriptorWithAPIOpts{ + CallDescriptor: &CallDescriptor{ + Category: "call", + Tenant: "cgrates.org", + Subject: "1002", + Account: "1002", + Destination: "1004", + DurationIndex: 0, + ToR: utils.MetaVoice, + TimeStart: time.Date(2019, 3, 31, 0, 0, 0, 0, time.UTC), + TimeEnd: time.Date(2019, 3, 31, 0, 0, 20, 0, time.UTC), + }, + } + dm.SetAccount(&Account{ + ID: utils.ConcatenatedKey(cd.Tenant, cd.Account), + BalanceMap: map[string]Balances{ + utils.MetaVoice: { + &Balance{Value: 20, + DestinationIDs: utils.NewStringMap("Dest"), + Weight: 10}, + }, + }, + }) + dm.SetReverseDestination("Dest", []string{"1001", "1002", "1003", "1004"}, "") + + dm.SetRatingPlan(&RatingPlan{ + Id: "RP1", + Ratings: map[string]*RIRate{ + "qpwq8so8": { + ConnectFee: 0.5, + RoundingMethod: utils.MetaRoundingMiddle, + RoundingDecimals: 2, + Rates: RateGroups{ + &RGRate{ + GroupIntervalStart: 0, + Value: 1, + RateIncrement: 1 * time.Minute, + RateUnit: 1 * time.Minute, + }, + }, + }, + }, + Timings: map[string]*RITiming{ + "83429156": { + Years: utils.Years{}, + Months: utils.Months{}, + MonthDays: utils.MonthDays{}, + WeekDays: utils.WeekDays{}, + StartTime: "00:00:00", + tag: "*any", + }, + }, + DestinationRates: map[string]RPRateList{ + "Dest": { + { + Timing: "83429156", + Rating: "qpwq8so8", + Weight: 21, + }, + }, + }, + }) + dm.SetRatingProfile(&RatingProfile{ + Id: "*out:cgrates.org:call:1002", + RatingPlanActivations: RatingPlanActivations{ + &RatingPlanActivation{ + ActivationTime: time.Date(2019, 3, 31, 0, 0, 0, 0, time.UTC), + RatingPlanId: "RP1", + }, + }, + }) + var reply CallCost + SetDataStorage(dm) + if err := rsponder.Debit(cd, &reply); err != nil { + t.Error(err) + } else if reply.Cost != 1.5 { + t.Errorf("expected Cost to be 1.5, got %v", reply.Cost) + } +} + +func TestResponderGetCostOnRatingPlans(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + tmpdm := dm + Cache.Clear(nil) + defer func() { + dm = tmpdm + }() + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + + arg := &utils.GetCostOnRatingPlansArgs{ + Account: "1002", + RatingPlanIDs: []string{ + "RP1", + "RP2", + }, + Subject: "1002", + Destination: "1001", + Usage: 2 * time.Minute, + Tenant: "cgrates.org", + } + dm.SetAccount(&Account{ + ID: utils.ConcatenatedKey("cgrates.org", "1002"), + }) + dm.SetReverseDestination("Dest", []string{"1001", "1002", "1003", "1004"}, "") + dm.SetRatingPlan(&RatingPlan{ + Id: "RP1", + Ratings: map[string]*RIRate{ + "qpwq8so8": { + ConnectFee: 0.3, + RoundingMethod: utils.MetaRoundingUp, + RoundingDecimals: 2, + Rates: RateGroups{ + &RGRate{ + GroupIntervalStart: 0, + Value: 0.01, + RateIncrement: 1 * time.Second, + RateUnit: 1 * time.Minute, + }, + &RGRate{ + GroupIntervalStart: 60 * time.Second, + Value: 0.3, + RateIncrement: 15 * time.Second, + RateUnit: 30 * time.Second, + }, + }, + }, + }, + Timings: map[string]*RITiming{ + "83429156": { + Years: utils.Years{}, + Months: utils.Months{}, + MonthDays: utils.MonthDays{}, + WeekDays: utils.WeekDays{}, + StartTime: "00:00:00", + tag: "*any", + }, + }, + DestinationRates: map[string]RPRateList{ + "Dest": { + { + Timing: "83429156", + Rating: "qpwq8so8", + Weight: 21, + }, + }, + }, + }) + dm.SetRatingProfile(&RatingProfile{ + Id: "*out:cgrates.org:call:1002", + RatingPlanActivations: RatingPlanActivations{ + &RatingPlanActivation{ + ActivationTime: time.Date(2019, 3, 31, 0, 0, 0, 0, time.UTC), + RatingPlanId: "RP1", + }, + }, + }) + var reply map[string]interface{} + exp := map[string]interface{}{ + utils.Cost: 0.92, + utils.RatingPlanID: "RP1", + } + SetDataStorage(dm) + if err := rsponder.GetCostOnRatingPlans(arg, &reply); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(reply, exp) { + t.Errorf("expected %v, got %v", exp, reply) + } +} diff --git a/engine/routes_test.go b/engine/routes_test.go index ae8badc20..04219ecdf 100644 --- a/engine/routes_test.go +++ b/engine/routes_test.go @@ -24,6 +24,7 @@ import ( "log" "os" "reflect" + "sort" "strings" "testing" "time" @@ -2242,5 +2243,122 @@ func TestRoutesV1GetRoutes(t *testing.T) { if !reflect.DeepEqual(reply[0], rpp) { t.Errorf("expected %+v,received %+v", utils.ToJSON(rpp), utils.ToJSON(reply)) } +} + +func TestRoutesV1GetRoutesList(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + Cache.Clear(nil) + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + rpS := NewRouteService(dm, NewFilterS(cfg, nil, dm), cfg, nil) + var reply []string + + dm.SetFilter(&Filter{ + Tenant: "cgrates.org", + ID: "FLT1", + Rules: []*FilterRule{ + { + Type: utils.MetaString, + Element: "~*req.Route", + Values: []string{"RouteProfile1"}, + }, + }, + }, true) + + dm.SetRouteProfile(&RouteProfile{ + Tenant: "cgrates.org", + ID: "ROUTE1", + FilterIDs: []string{"FLT1"}, + Sorting: utils.MetaWeight, + SortingParameters: []string{}, + Routes: []*Route{ + { + ID: "route1", + Weight: 20, + Blocker: false, + RouteParameters: utils.EmptyString, + }, + { + ID: "route2", + Weight: 10, + Blocker: false, + RouteParameters: utils.EmptyString, + }, + }, + Weight: 10, + }, true) + if err := rpS.V1GetRoutesList(testRoutesArgs[0], &reply); err != nil { + t.Error(err) + } + sort.Slice(reply, func(i, j int) bool { + return reply[i] < reply[j] + }) + if !reflect.DeepEqual(reply, []string{"route1", "route2"}) { + + t.Errorf("expected %+v,received %+v", []string{"ROUTE1"}, reply) + } } + +func TestRouteServiceV1GetRoutesErr(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + cfg.RouteSCfg().AttributeSConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes)} + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + clientConn := make(chan rpcclient.ClientConnector, 1) + clientConn <- clMock(func(serviceMethod string, _, _ interface{}) error { + if serviceMethod == utils.AttributeSv1ProcessEvent { + + return errors.New("Server Error") + } + return utils.ErrNotImplemented + }) + rpS := NewRouteService(dm, NewFilterS(cfg, nil, dm), cfg, NewConnManager(cfg, map[string]chan rpcclient.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes): clientConn, + })) + + testCases := []struct { + name string + args *utils.CGREvent + reply SortedRoutesList + }{ + { + name: "Missing StructFields", + args: &utils.CGREvent{ + Event: map[string]interface{}{ + "Account": "1003", + }, + }, + reply: SortedRoutesList{}, + }, + { + name: "Missing Event", + args: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "RouteProcessEvent", + }, + reply: SortedRoutesList{}, + }, + { + name: "Failed to process event ", + args: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "RouteProcessEvent", + Event: map[string]interface{}{ + utils.RequestType: utils.MetaPostpaid, + utils.Category: utils.Call, + utils.AccountField: "1003", + utils.Subject: "1003", + utils.Destination: "1002", + }, + }, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + if err := rpS.V1GetRoutes(tc.args, &tc.reply); err == nil { + t.Errorf("expected error, received nil") + } + }) + } +}