/* Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments Copyright (C) ITsysCOM GmbH This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see */ package engine import ( "bytes" "fmt" "log" "os" "reflect" "sort" "strings" "testing" "time" "github.com/cgrates/birpc" "github.com/cgrates/birpc/context" "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/utils" "github.com/cgrates/ltcache" ) func TestTPReaderCallCacheNoCaching(t *testing.T) { tmp := connMgr defer func() { connMgr = tmp }() cfg := config.NewDefaultCGRConfig() Cache.Clear(nil) cM := NewConnManager(cfg, nil) args := map[string][]string{ utils.CacheFilters: {"cgrates.org:FLTR_ID1", "cgrates.org:FLTR_ID2"}, utils.CacheResources: {}, } opts := map[string]any{ utils.MetaSubsys: utils.MetaChargers, } err := CallCache(cM, []string{}, utils.MetaNone, args, []string{}, opts, true, "cgrates.org") if err != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) } } func TestTPReaderCallCacheReloadCacheFirstCallErr(t *testing.T) { tmp := connMgr defer func() { connMgr = tmp }() cfg := config.NewDefaultCGRConfig() Cache.Clear(nil) cacheConns := []string{"cacheConn1"} client := make(chan birpc.ClientConnector, 1) ccM := &ccMock{ calls: map[string]func(ctx *context.Context, args any, reply any) error{ utils.CacheSv1ReloadCache: func(ctx *context.Context, args, reply any) error { expArgs := &utils.AttrReloadCacheWithAPIOpts{ APIOpts: map[string]any{ utils.MetaSubsys: utils.MetaChargers, }, FilterIDs: []string{"cgrates.org:FLTR_ID1", "cgrates.org:FLTR_ID2"}, Tenant: "cgrates.org", } if !reflect.DeepEqual(args, expArgs) { return fmt.Errorf( "\nWrong value of args: \nexpected: <%+v>, \nreceived: <%+v>", utils.ToJSON(expArgs), utils.ToJSON(args), ) } return utils.ErrUnsupporteServiceMethod }, }, } client <- ccM cM := NewConnManager(cfg, map[string]chan birpc.ClientConnector{ "cacheConn1": client, }) caching := utils.MetaReload args := map[string][]string{ utils.CacheFilters: {"cgrates.org:FLTR_ID1", "cgrates.org:FLTR_ID2"}, } cacheIDs := []string{} opts := map[string]any{ utils.MetaSubsys: utils.MetaChargers, } var buf bytes.Buffer log.SetOutput(&buf) defer func() { log.SetOutput(os.Stderr) }() explog := "Reloading cache\n" experr := utils.ErrUnsupporteServiceMethod err := CallCache(cM, cacheConns, caching, args, cacheIDs, opts, true, "cgrates.org") if err == nil || err != experr { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", experr, err) } rcvlog := buf.String()[20:] if rcvlog != explog { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", explog, rcvlog) } } func TestTPReaderCallCacheReloadCacheSecondCallErr(t *testing.T) { tmp := connMgr defer func() { connMgr = tmp }() cfg := config.NewDefaultCGRConfig() Cache.Clear(nil) cacheConns := []string{"cacheConn1"} client := make(chan birpc.ClientConnector, 1) ccM := &ccMock{ calls: map[string]func(ctx *context.Context, args any, reply any) error{ utils.CacheSv1ReloadCache: func(ctx *context.Context, args, reply any) error { return nil }, utils.CacheSv1Clear: func(ctx *context.Context, args, reply any) error { expArgs := &utils.AttrCacheIDsWithAPIOpts{ APIOpts: map[string]any{ utils.MetaSubsys: utils.MetaChargers, }, CacheIDs: []string{"cacheID"}, Tenant: "cgrates.org", } if !reflect.DeepEqual(args, expArgs) { return fmt.Errorf( "\nWrong value of args: \nexpected: <%+v>, \nreceived: <%+v>", expArgs, args, ) } return utils.ErrUnsupporteServiceMethod }, }, } client <- ccM cM := NewConnManager(cfg, map[string]chan birpc.ClientConnector{ "cacheConn1": client, }) caching := utils.MetaReload args := map[string][]string{ utils.CacheFilters: {"cgrates.org:FLTR_ID1", "cgrates.org:FLTR_ID2"}, } cacheIDs := []string{"cacheID"} opts := map[string]any{ utils.MetaSubsys: utils.MetaChargers, } var buf bytes.Buffer log.SetOutput(&buf) defer func() { log.SetOutput(os.Stderr) }() explog1 := "Reloading cache" explog2 := "Clearing indexes" experr := utils.ErrUnsupporteServiceMethod explog3 := fmt.Sprintf("WARNING: Got error on cache clear: %s\n", experr) err := CallCache(cM, cacheConns, caching, args, cacheIDs, opts, true, "cgrates.org") if err == nil || err != experr { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", experr, err) } rcvlog1 := buf.String()[20 : 20+len(explog1)] if rcvlog1 != explog1 { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", explog1, rcvlog1) } rcvlog2 := buf.String()[41+len(rcvlog1) : 41+len(rcvlog1)+len(explog2)] if rcvlog2 != explog2 { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", explog2, rcvlog2) } rcvlog3 := buf.String()[62+len(rcvlog1)+len(explog2):] if rcvlog3 != explog3 { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", explog3, rcvlog3) } } func TestTPReaderCallCacheLoadCache(t *testing.T) { tmp := connMgr defer func() { connMgr = tmp }() cfg := config.NewDefaultCGRConfig() Cache.Clear(nil) cacheConns := []string{"cacheConn1"} client := make(chan birpc.ClientConnector, 1) ccM := &ccMock{ calls: map[string]func(ctx *context.Context, args any, reply any) error{ utils.CacheSv1LoadCache: func(ctx *context.Context, args, reply any) error { expArgs := &utils.AttrReloadCacheWithAPIOpts{ APIOpts: map[string]any{ utils.MetaSubsys: utils.MetaChargers, }, FilterIDs: []string{"cgrates.org:FLTR_ID1", "cgrates.org:FLTR_ID2"}, Tenant: "cgrates.org", } if !reflect.DeepEqual(args, expArgs) { return fmt.Errorf( "\nWrong value of args: \nexpected: <%+v>, \nreceived: <%+v>", expArgs, args, ) } return nil }, utils.CacheSv1Clear: func(ctx *context.Context, args, reply any) error { expArgs := &utils.AttrCacheIDsWithAPIOpts{ APIOpts: map[string]any{ utils.MetaSubsys: utils.MetaChargers, }, CacheIDs: []string{"cacheID"}, Tenant: "cgrates.org", } if !reflect.DeepEqual(args, expArgs) { return fmt.Errorf( "\nWrong value of args: \nexpected: <%+v>, \nreceived: <%+v>", expArgs, args, ) } return nil }, }, } client <- ccM cM := NewConnManager(cfg, map[string]chan birpc.ClientConnector{ "cacheConn1": client, }) caching := utils.MetaLoad args := map[string][]string{ utils.CacheFilters: {"cgrates.org:FLTR_ID1", "cgrates.org:FLTR_ID2"}, } cacheIDs := []string{"cacheID"} opts := map[string]any{ utils.MetaSubsys: utils.MetaChargers, } err := CallCache(cM, cacheConns, caching, args, cacheIDs, opts, false, "cgrates.org") if err != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) } } func TestTPReaderCallCacheRemoveItems(t *testing.T) { tmp := connMgr defer func() { connMgr = tmp }() cfg := config.NewDefaultCGRConfig() Cache.Clear(nil) cacheConns := []string{"cacheConn1"} client := make(chan birpc.ClientConnector, 1) ccM := &ccMock{ calls: map[string]func(ctx *context.Context, args any, reply any) error{ utils.CacheSv1RemoveItems: func(ctx *context.Context, args, reply any) error { expArgs := &utils.AttrReloadCacheWithAPIOpts{ APIOpts: map[string]any{ utils.MetaSubsys: utils.MetaChargers, }, FilterIDs: []string{"cgrates.org:FLTR_ID1", "cgrates.org:FLTR_ID2"}, Tenant: "cgrates.org", } if !reflect.DeepEqual(args, expArgs) { return fmt.Errorf( "\nWrong value of args: \nexpected: <%+v>, \nreceived: <%+v>", expArgs, args, ) } return nil }, utils.CacheSv1Clear: func(ctx *context.Context, args, reply any) error { expArgs := &utils.AttrCacheIDsWithAPIOpts{ APIOpts: map[string]any{ utils.MetaSubsys: utils.MetaChargers, }, CacheIDs: []string{"cacheID"}, Tenant: "cgrates.org", } if !reflect.DeepEqual(args, expArgs) { return fmt.Errorf( "\nWrong value of args: \nexpected: <%+v>, \nreceived: <%+v>", expArgs, args, ) } return nil }, }, } client <- ccM cM := NewConnManager(cfg, map[string]chan birpc.ClientConnector{ "cacheConn1": client, }) caching := utils.MetaRemove args := map[string][]string{ utils.CacheFilters: {"cgrates.org:FLTR_ID1", "cgrates.org:FLTR_ID2"}, } cacheIDs := []string{"cacheID"} opts := map[string]any{ utils.MetaSubsys: utils.MetaChargers, } err := CallCache(cM, cacheConns, caching, args, cacheIDs, opts, false, "cgrates.org") if err != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) } } func TestTPReaderCallCacheClear(t *testing.T) { tmp := connMgr defer func() { connMgr = tmp }() cfg := config.NewDefaultCGRConfig() Cache.Clear(nil) cacheConns := []string{"cacheConn1"} client := make(chan birpc.ClientConnector, 1) ccM := &ccMock{ calls: map[string]func(ctx *context.Context, args any, reply any) error{ utils.CacheSv1Clear: func(ctx *context.Context, args, reply any) error { expArgs := &utils.AttrCacheIDsWithAPIOpts{ APIOpts: map[string]any{ utils.MetaSubsys: utils.MetaChargers, }, Tenant: "cgrates.org", } if !reflect.DeepEqual(args, expArgs) { return fmt.Errorf( "\nWrong value of args: \nexpected: <%+v>, \nreceived: <%+v>", expArgs, args, ) } return nil }, }, } client <- ccM cM := NewConnManager(cfg, map[string]chan birpc.ClientConnector{ "cacheConn1": client, }) caching := utils.MetaClear args := map[string][]string{ utils.CacheFilters: {"cgrates.org:FLTR_ID1", "cgrates.org:FLTR_ID2"}, } cacheIDs := []string{} opts := map[string]any{ utils.MetaSubsys: utils.MetaChargers, } err := CallCache(cM, cacheConns, caching, args, cacheIDs, opts, false, "cgrates.org") if err != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) } } func TestTPReaderGetLoadedIdsDestinations(t *testing.T) { tpr := &TpReader{ destinations: map[string]*Destination{ "1001": { Id: "1001_ID", Prefixes: []string{"39", "40"}, }, "1002": { Id: "1002_ID", Prefixes: []string{"75", "82"}, }, }, } rcv, err := tpr.GetLoadedIds(utils.DestinationPrefix) if err != nil { t.Error(err) } //Test fails sometimes because of the order of the returned slice expRcv := []string{"1001", "1002"} sort.Strings(rcv) if !reflect.DeepEqual(expRcv, rcv) { t.Errorf("\nExpected %v but received \n%v", expRcv, rcv) } } func TestTPReaderGetLoadedIdsReverseDestinations(t *testing.T) { tpr := &TpReader{ destinations: map[string]*Destination{ "1001": { Id: "1001_ID", Prefixes: []string{"39", "75"}, }, "1002": { Id: "1002_ID", Prefixes: []string{"87", "21"}, }, }, } rcv, err := tpr.GetLoadedIds(utils.ReverseDestinationPrefix) if err != nil { t.Error(err) } sort.Strings(rcv) expRcv := []string{"21", "39", "75", "87"} if !reflect.DeepEqual(expRcv, rcv) { t.Errorf("\nExpected %v but received \n%v", expRcv, rcv) } } func TestTPReaderGetLoadedIdsRatingPlans(t *testing.T) { tpr := &TpReader{ ratingPlans: map[string]*RatingPlan{ "RP_RETAIL1": { Id: "RP_1001", Timings: map[string]*RITiming{ "TIMING_1001": { ID: "PEAK", Years: []int{2021}, Months: []time.Month{8}, MonthDays: []int{31}, WeekDays: []time.Weekday{5}, StartTime: "15:00:00Z", EndTime: "17:00:00Z", cronString: "21 2 5 25 8 5 2021", //sec, min, hour, monthday, month, weekday, year tag: utils.MetaAny, }, }, Ratings: map[string]*RIRate{ "RATING_1001": { ConnectFee: 0.4, RoundingMethod: utils.MetaRoundingUp, RoundingDecimals: 4, MaxCost: 0.60, MaxCostStrategy: utils.MetaMaxCostDisconnect, Rates: []*RGRate{ { GroupIntervalStart: 0, Value: 0.2, RateIncrement: 60 * time.Second, RateUnit: 60 * time.Second, }, }, tag: utils.MetaAny, }, }, DestinationRates: map[string]RPRateList{ "DR_FS_40CNT": { { Timing: "TIMING_1001", Rating: "RATING_1001", Weight: 10, }, }, }, }, }, } rcv, err := tpr.GetLoadedIds(utils.RatingPlanPrefix) if err != nil { t.Error(err) } expRcv := []string{"RP_RETAIL1"} if !reflect.DeepEqual(expRcv, rcv) { t.Errorf("\nExpected %v but received \n%v", expRcv, rcv) } } func TestTPReaderGetLoadedIdsRatingProfiles(t *testing.T) { tpr := &TpReader{ ratingProfiles: map[string]*RatingProfile{ "1001": { Id: "RP_RETAIL1", RatingPlanActivations: []*RatingPlanActivation{ { ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), RatingPlanId: "RETAIL1", }, }, }, "1002": { Id: "RP_RETAIL2", RatingPlanActivations: []*RatingPlanActivation{ { ActivationTime: time.Date(2014, 7, 21, 14, 15, 0, 0, time.UTC), RatingPlanId: "RETAIL2", }, }, }, }, } rcv, err := tpr.GetLoadedIds(utils.RatingProfilePrefix) if err != nil { t.Error(err) } sort.Strings(rcv) expRcv := []string{"1001", "1002"} if !reflect.DeepEqual(expRcv, rcv) { t.Errorf("\nExpected %v but received \n%v", expRcv, rcv) } } func TestTPReaderGetLoadedIdsActions(t *testing.T) { tpr := &TpReader{ actions: map[string][]*Action{ "TOPUP_RST_10": { { Id: "ACTION_1001", ActionType: utils.MetaSetBalance, ExtraParameters: "", ExpirationString: "", Weight: 10, balanceValue: 9.45, }, }, "TOPUP_RST_5": { { Id: "ACTION_1002", ActionType: utils.MetaPublishAccount, ExtraParameters: "", ExpirationString: "", Weight: 5, balanceValue: 12.32, }, }, }, } rcv, err := tpr.GetLoadedIds(utils.ActionPrefix) if err != nil { t.Error(err) } sort.Strings(rcv) expRcv := []string{"TOPUP_RST_10", "TOPUP_RST_5"} if !reflect.DeepEqual(expRcv, rcv) { t.Errorf("\nExpected %v but received \n%v", expRcv, rcv) } } func TestTPReaderGetLoadedIdsActionPlans(t *testing.T) { tpr := &TpReader{ actionPlans: map[string]*ActionPlan{ "PACKAGE_1001": { Id: "TOPUP_RST_10", AccountIDs: map[string]bool{ "1001": true, "1002": false, }, }, "PACKAGE_1002": { Id: "TOPUP_RST_5", AccountIDs: map[string]bool{ "1001": false, "1002": true, }, }, }, } rcv, err := tpr.GetLoadedIds(utils.ActionPlanPrefix) if err != nil { t.Error(err) } sort.Strings(rcv) expRcv := []string{"PACKAGE_1001", "PACKAGE_1002"} if !reflect.DeepEqual(expRcv, rcv) { t.Errorf("\nExpected %v but received \n%v", expRcv, rcv) } } func TestTPReaderGetLoadedIdsSharedGroup(t *testing.T) { tpr := &TpReader{ sharedGroups: map[string]*SharedGroup{ "SHARED_A": { Id: "SHARED_ID1", AccountParameters: map[string]*SharingParameters{ "PARAM_1": { Strategy: utils.MetaTopUp, RatingSubject: "1001", }, }, MemberIds: map[string]bool{ "1001": true, "1002": false, }, }, "SHARED_B": { Id: "SHARED_ID2", AccountParameters: map[string]*SharingParameters{ "PARAM_1": { Strategy: utils.MetaTopUp, RatingSubject: "1002", }, }, MemberIds: map[string]bool{ "1001": true, "1002": false, }, }, }, } rcv, err := tpr.GetLoadedIds(utils.SharedGroupPrefix) if err != nil { t.Error(err) } sort.Strings(rcv) expRcv := []string{"SHARED_A", "SHARED_B"} if !reflect.DeepEqual(expRcv, rcv) { t.Errorf("\nExpected %v but received \n%v", expRcv, rcv) } } func TestTPReaderGetLoadedIdsResourceProfiles(t *testing.T) { tpr := &TpReader{ resProfiles: map[utils.TenantID]*utils.TPResourceProfile{ {Tenant: "cgrates.org", ID: "ResGroup1"}: { TPid: testTPID, Tenant: "cgrates.org", ID: "ResGroup1", FilterIDs: []string{"*string:~*req.Account:1001"}, ActivationInterval: &utils.TPActivationInterval{ ActivationTime: "2014-07-29T15:00:00Z", }, UsageTTL: "1s", AllocationMessage: "call", Weight: 10, Limit: "2", Blocker: true, Stored: true, }, }, } rcv, err := tpr.GetLoadedIds(utils.ResourceProfilesPrefix) if err != nil { t.Error(err) } expRcv := []string{"cgrates.org:ResGroup1"} if !reflect.DeepEqual(expRcv, rcv) { t.Errorf("\nExpected %v but received \n%v", expRcv, rcv) } } func TestTPReaderGetLoadedIdsActionTriggers(t *testing.T) { tpr := &TpReader{ actionsTriggers: map[string]ActionTriggers{ "STANDARD_TRIGGERS": { { ID: "ID1", UniqueID: "", ThresholdType: "*max_balance", ThresholdValue: 20, Recurrent: false, MinSleep: 0, Weight: 10, ActionsID: "LOG_WARNING", }, }, }, } rcv, err := tpr.GetLoadedIds(utils.ActionTriggerPrefix) if err != nil { t.Error(err) } expRcv := []string{"STANDARD_TRIGGERS"} if !reflect.DeepEqual(expRcv, rcv) { t.Errorf("\nExpected %v but received \n%v", expRcv, rcv) } } func TestTPReaderGetLoadedIdsStatQueueProfiles(t *testing.T) { tpr := &TpReader{ sqProfiles: map[utils.TenantID]*utils.TPStatProfile{ {Tenant: "cgrates.org", ID: "cgratesID"}: { TPid: testTPID, Tenant: "cgrates.org", ID: "ResGroup1", FilterIDs: []string{"*string:~*req.Account:1001"}, ActivationInterval: &utils.TPActivationInterval{ ActivationTime: "2014-07-29T15:00:00Z", }, Weight: 10, Blocker: true, Stored: true, }, }, } rcv, err := tpr.GetLoadedIds(utils.StatQueueProfilePrefix) if err != nil { t.Error(err) } expRcv := []string{"cgrates.org:cgratesID"} if !reflect.DeepEqual(expRcv, rcv) { t.Errorf("\nExpected %v but received \n%v", expRcv, rcv) } } func TestTPReaderGetLoadedIdsThresholdProfiles(t *testing.T) { tpr := &TpReader{ thProfiles: map[utils.TenantID]*utils.TPThresholdProfile{ {Tenant: "cgrates.org", ID: "cgratesID"}: { TPid: testTPID, Tenant: "cgrates.org", ID: "ResGroup1", FilterIDs: []string{"*string:~*req.Account:1001"}, ActivationInterval: &utils.TPActivationInterval{ ActivationTime: "2014-07-29T15:00:00Z", }, Weight: 10, Blocker: true, MaxHits: 3, MinHits: 1, Async: true, }, }, } rcv, err := tpr.GetLoadedIds(utils.ThresholdProfilePrefix) if err != nil { t.Error(err) } expRcv := []string{"cgrates.org:cgratesID"} if !reflect.DeepEqual(expRcv, rcv) { t.Errorf("\nExpected %v but received \n%v", expRcv, rcv) } } func TestTPReaderGetLoadedIdsFilters(t *testing.T) { tpr := &TpReader{ filters: map[utils.TenantID]*utils.TPFilterProfile{ {Tenant: "cgrates.org", ID: "cgratesID"}: { TPid: testTPID, Tenant: "cgrates.org", ID: "ResGroup1", ActivationInterval: &utils.TPActivationInterval{ ActivationTime: "2014-07-29T15:00:00Z", }, Filters: []*utils.TPFilter{ { Type: "~*req", Element: "Account", Values: []string{"1001"}, }, }, }, }, } rcv, err := tpr.GetLoadedIds(utils.FilterPrefix) if err != nil { t.Error(err) } expRcv := []string{"cgrates.org:cgratesID"} if !reflect.DeepEqual(expRcv, rcv) { t.Errorf("\nExpected %v but received \n%v", expRcv, rcv) } } func TestTPReaderGetLoadedIdsRouteProfiles(t *testing.T) { tpr := &TpReader{ routeProfiles: map[utils.TenantID]*utils.TPRouteProfile{ {Tenant: "cgrates.org", ID: "cgratesID"}: { TPid: testTPID, Tenant: "cgrates.org", ID: "ResGroup1", ActivationInterval: &utils.TPActivationInterval{ ActivationTime: "2014-07-29T15:00:00Z", }, }, }, } rcv, err := tpr.GetLoadedIds(utils.RouteProfilePrefix) if err != nil { t.Error(err) } expRcv := []string{"cgrates.org:cgratesID"} if !reflect.DeepEqual(expRcv, rcv) { t.Errorf("\nExpected %v but received \n%v", expRcv, rcv) } } func TestTPReaderGetLoadedIdsAttributeProfiles(t *testing.T) { tpr := &TpReader{ attributeProfiles: map[utils.TenantID]*utils.TPAttributeProfile{ {Tenant: "cgrates.org", ID: "cgratesID"}: { TPid: testTPID, Tenant: "cgrates.org", ID: "ResGroup1", FilterIDs: []string{"*string:~*req.Account:1001"}, ActivationInterval: &utils.TPActivationInterval{ ActivationTime: "2014-07-29T15:00:00Z", }, Contexts: []string{"sessions"}, }, }, } rcv, err := tpr.GetLoadedIds(utils.AttributeProfilePrefix) if err != nil { t.Error(err) } expRcv := []string{"cgrates.org:cgratesID"} if !reflect.DeepEqual(expRcv, rcv) { t.Errorf("\nExpected %v but received \n%v", expRcv, rcv) } } func TestTPReaderGetLoadedIdsChargerProfiles(t *testing.T) { tpr := &TpReader{ chargerProfiles: map[utils.TenantID]*utils.TPChargerProfile{ {Tenant: "cgrates.org", ID: "cgratesID"}: { TPid: testTPID, Tenant: "cgrates.org", ID: "ResGroup1", ActivationInterval: &utils.TPActivationInterval{ ActivationTime: "2014-07-29T15:00:00Z", }, RunID: "RUN_ID", }, }, } rcv, err := tpr.GetLoadedIds(utils.ChargerProfilePrefix) if err != nil { t.Error(err) } expRcv := []string{"cgrates.org:cgratesID"} if !reflect.DeepEqual(expRcv, rcv) { t.Errorf("\nExpected %v but received \n%v", expRcv, rcv) } } func TestTPReaderGetLoadedIdsDispatcherProfiles(t *testing.T) { tpr := &TpReader{ dispatcherProfiles: map[utils.TenantID]*utils.TPDispatcherProfile{ {Tenant: "cgrates.org", ID: "cgratesID"}: { TPid: testTPID, Tenant: "cgrates.org", ID: "ResGroup1", ActivationInterval: &utils.TPActivationInterval{ ActivationTime: "2014-07-29T15:00:00Z", }, Strategy: utils.MetaMaxCostDisconnect, }, }, } rcv, err := tpr.GetLoadedIds(utils.DispatcherProfilePrefix) if err != nil { t.Error(err) } expRcv := []string{"cgrates.org:cgratesID"} if !reflect.DeepEqual(expRcv, rcv) { t.Errorf("\nExpected %v but received \n%v", expRcv, rcv) } } func TestTPReaderGetLoadedIdsEmptyObject(t *testing.T) { tpr := &TpReader{} rcv, err := tpr.GetLoadedIds(utils.DispatcherProfilePrefix) if err != nil { t.Error(err) } expRcv := make([]string, 0) if !reflect.DeepEqual(expRcv, rcv) { t.Errorf("\nExpected %v but received \n%v", expRcv, rcv) } } func TestTPReaderGetLoadedIdsDispatcherHosts(t *testing.T) { tpr := &TpReader{ dispatcherHosts: map[utils.TenantID]*utils.TPDispatcherHost{ {Tenant: "cgrates.org", ID: "cgratesID"}: { TPid: testTPID, Tenant: "cgrates.org", ID: "ResGroup1", }, }, } rcv, err := tpr.GetLoadedIds(utils.DispatcherHostPrefix) if err != nil { t.Error(err) } expRcv := []string{"cgrates.org:cgratesID"} if !reflect.DeepEqual(expRcv, rcv) { t.Errorf("\nExpected %v but received \n%v", expRcv, rcv) } } func TestTPReaderGetLoadedIdsError(t *testing.T) { tpr := &TpReader{} errExpect := "Unsupported load category" if _, err := tpr.GetLoadedIds(""); err == nil || err.Error() != errExpect { t.Errorf("\nExpected error %v but received \n%v", errExpect, err) } } func TestTPReaderReloadCache(t *testing.T) { cfg := config.NewDefaultCGRConfig() argExpect := &utils.AttrReloadCacheWithAPIOpts{ APIOpts: map[string]any{}, Tenant: "cgrates.org", ActionIDs: []string{"ActionsID"}, ActionPlanIDs: []string{"ActionPlansID"}, ActionTriggerIDs: []string{"ActionTriggersID"}, DestinationIDs: []string{"DestinationsID"}, TimingIDs: []string{"TimingsID"}, RatingPlanIDs: []string{"RatingPlansID"}, RatingProfileIDs: []string{"RatingProfilesID"}, SharedGroupIDs: []string{"SharedGroupsID"}, ResourceProfileIDs: []string{"cgrates.org:resourceProfilesID"}, IPProfileIDs: []string{"cgrates.org:ipProfilesID"}, StatsQueueProfileIDs: []string{"cgrates.org:statProfilesID"}, ThresholdProfileIDs: []string{"cgrates.org:thresholdProfilesID"}, TrendProfileIDs: []string{"cgrates.org:trendProfilesID"}, FilterIDs: []string{"cgrates.org:filtersID"}, RouteProfileIDs: []string{"cgrates.org:routeProfilesID"}, AttributeProfileIDs: []string{"cgrates.org:attributeProfilesID"}, ChargerProfileIDs: []string{"cgrates.org:chargerProfilesID"}, DispatcherProfileIDs: []string{"cgrates.org:dispatcherProfilesID"}, DispatcherHostIDs: []string{"cgrates.org:dispatcherHostsID"}, ResourceIDs: []string{"cgrates.org:resourceProfilesID"}, IPIDs: []string{"cgrates.org:ipProfilesID"}, StatsQueueIDs: []string{"cgrates.org:statProfilesID"}, ThresholdIDs: []string{"cgrates.org:thresholdProfilesID"}, AccountActionPlanIDs: []string{"AccountActionPlansID"}, RankingProfileIDs: []string{"cgrates.org:rankingProfilesID"}, ReverseDestinationIDs: []string{}, } rpcInternal := make(chan birpc.ClientConnector, 1) rpcInternal <- &ccMock{ calls: map[string]func(ctx *context.Context, args any, reply any) error{ utils.CacheSv1ReloadCache: func(ctx *context.Context, args any, reply any) error { if !reflect.DeepEqual(args, argExpect) { t.Errorf("Expected %v \nbut received %v", utils.ToJSON(argExpect), utils.ToJSON(args)) } return nil }, utils.CacheSv1Clear: func(ctx *context.Context, args any, reply any) error { return nil }, }, } tmp := connMgr defer func() { connMgr = tmp }() connMgr = NewConnManager(cfg, map[string]chan birpc.ClientConnector{ utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches): rpcInternal, }) idb, err := NewInternalDB(nil, nil, false, nil, cfg.DataDbCfg().Items) if err != nil { t.Fatal(err) } tpr := &TpReader{ actions: map[string][]*Action{ "ActionsID": {}, }, actionPlans: map[string]*ActionPlan{ "ActionPlansID": {}, }, actionsTriggers: map[string]ActionTriggers{ "ActionTriggersID": {}, }, destinations: map[string]*Destination{ "DestinationsID": {}, }, timings: map[string]*utils.TPTiming{ "TimingsID": {}, }, ratingPlans: map[string]*RatingPlan{ "RatingPlansID": {}, }, ratingProfiles: map[string]*RatingProfile{ "RatingProfilesID": {}, }, sharedGroups: map[string]*SharedGroup{ "SharedGroupsID": {}, }, resProfiles: map[utils.TenantID]*utils.TPResourceProfile{ {Tenant: "cgrates.org", ID: "resourceProfilesID"}: {}, }, ipProfiles: map[utils.TenantID]*utils.TPIPProfile{ {Tenant: "cgrates.org", ID: "ipProfilesID"}: {}, }, sqProfiles: map[utils.TenantID]*utils.TPStatProfile{ {Tenant: "cgrates.org", ID: "statProfilesID"}: {}, }, thProfiles: map[utils.TenantID]*utils.TPThresholdProfile{ {Tenant: "cgrates.org", ID: "thresholdProfilesID"}: {}, }, trProfiles: map[utils.TenantID]*utils.TPTrendsProfile{ {Tenant: "cgrates.org", ID: "trendProfilesID"}: {}, }, filters: map[utils.TenantID]*utils.TPFilterProfile{ {Tenant: "cgrates.org", ID: "filtersID"}: {}, }, routeProfiles: map[utils.TenantID]*utils.TPRouteProfile{ {Tenant: "cgrates.org", ID: "routeProfilesID"}: {}, }, attributeProfiles: map[utils.TenantID]*utils.TPAttributeProfile{ {Tenant: "cgrates.org", ID: "attributeProfilesID"}: {}, }, chargerProfiles: map[utils.TenantID]*utils.TPChargerProfile{ {Tenant: "cgrates.org", ID: "chargerProfilesID"}: {}, }, dispatcherProfiles: map[utils.TenantID]*utils.TPDispatcherProfile{ {Tenant: "cgrates.org", ID: "dispatcherProfilesID"}: {}, }, dispatcherHosts: map[utils.TenantID]*utils.TPDispatcherHost{ {Tenant: "cgrates.org", ID: "dispatcherHostsID"}: {}, }, acntActionPlans: map[string][]string{ "AccountActionPlansID": {}, }, rgProfiles: map[utils.TenantID]*utils.TPRankingProfile{ {Tenant: "cgrates.org", ID: "rankingProfilesID"}: {}, }, dm: NewDataManager(idb, config.CgrConfig().CacheCfg(), connMgr), } tpr.dm.SetLoadIDs(make(map[string]int64)) tpr.cacheConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches)} if err := tpr.ReloadCache(utils.MetaReload, false, make(map[string]any), "cgrates.org"); err != nil { t.Error(err) } } func TestTPReaderLoadDestinationsFiltered(t *testing.T) { cfg := config.NewDefaultCGRConfig() db, dErr := NewInternalDB(nil, nil, true, nil, cfg.DataDbCfg().Items) if dErr != nil { t.Error(dErr) } tscache := ltcache.NewTransCache( map[string]*ltcache.CacheConfig{ utils.CacheTBLTPDestinations: { MaxItems: 3, TTL: time.Minute * 30, StaticTTL: false, OnEvicted: []func(itmID string, value interface{}){ func(itmID string, value any) { }, }, }}, ) tscache.Set(utils.CacheTBLTPDestinations, "itemId", &utils.TPDestination{ TPid: "tpID", ID: "prefixes", }, []string{"groupId"}, true, "tId") db.db = tscache tpr, err := NewTpReader(db, db, "itemId", "local", nil, nil) if err != nil { t.Error(err) } if b, err := tpr.LoadDestinationsFiltered(""); (err != nil) || !b { t.Errorf("expected nil ,received %v", err) } tscache.Remove(utils.CacheTBLTPDestinations, "itemId", true, utils.NonTransactional) if b, err := tpr.LoadDestinationsFiltered(""); err == nil || err != utils.ErrNotFound || b { t.Errorf("expected nil ,received %v", err) } tpr.dm = nil tscache.Set(utils.CacheTBLTPDestinations, "itemId", &utils.TPDestination{}, []string{"groupId"}, true, "tId") if b, err := tpr.LoadDestinationsFiltered(""); err != nil || !b { t.Errorf("expected nil ,received %v", err) } } func TestTPReaderLoadAll(t *testing.T) { cfg := config.NewDefaultCGRConfig() db, dErr := NewInternalDB(nil, nil, true, nil, cfg.DataDbCfg().Items) if dErr != nil { t.Error(dErr) } tpr, err := NewTpReader(nil, db, "", "local", nil, nil) if err != nil { t.Error(err) } if err = tpr.LoadAll(); err != nil { t.Error(err) } } func TestTpReaderReloadScheduler(t *testing.T) { cfg := config.NewDefaultCGRConfig() ccMocK := &ccMock{ calls: map[string]func(ctx *context.Context, args any, reply any) error{ utils.SchedulerSv1Reload: func(ctx *context.Context, args, reply any) error { rpl := "reply" *reply.(*string) = rpl return nil }, }, } clientconn := make(chan birpc.ClientConnector, 1) clientconn <- ccMocK tmp := connMgr defer func() { connMgr = tmp }() connMgr = NewConnManager(cfg, map[string]chan birpc.ClientConnector{ utils.ConcatenatedKey(utils.MetaInternal, utils.SchedulerConnsCfg): clientconn, }) idb, err := NewInternalDB(nil, nil, false, nil, cfg.DataDbCfg().Items) if err != nil { t.Error(err) } tpr := &TpReader{ actions: map[string][]*Action{ "ActionsID": {}, }, actionPlans: map[string]*ActionPlan{ "ActionPlansID": {}, "ActionPlansID2": {}, }, resProfiles: map[utils.TenantID]*utils.TPResourceProfile{ {Tenant: "cgrates.org", ID: "resourceProfilesID"}: {}, }, ipProfiles: map[utils.TenantID]*utils.TPIPProfile{ {Tenant: "cgrates.org", ID: "ipProfilesID"}: {}, }, sqProfiles: map[utils.TenantID]*utils.TPStatProfile{ {Tenant: "cgrates.org", ID: "statProfilesID"}: {}, }, thProfiles: map[utils.TenantID]*utils.TPThresholdProfile{ {Tenant: "cgrates.org", ID: "thresholdProfilesID"}: {}, }, filters: map[utils.TenantID]*utils.TPFilterProfile{ {Tenant: "cgrates.org", ID: "filtersID"}: {}, }, routeProfiles: map[utils.TenantID]*utils.TPRouteProfile{ {Tenant: "cgrates.org", ID: "routeProfilesID"}: {}, }, attributeProfiles: map[utils.TenantID]*utils.TPAttributeProfile{ {Tenant: "cgrates.org", ID: "attributeProfilesID"}: {}, }, chargerProfiles: map[utils.TenantID]*utils.TPChargerProfile{ {Tenant: "cgrates.org", ID: "chargerProfilesID"}: {}, }, dispatcherProfiles: map[utils.TenantID]*utils.TPDispatcherProfile{ {Tenant: "cgrates.org", ID: "dispatcherProfilesID"}: {}, }, dispatcherHosts: map[utils.TenantID]*utils.TPDispatcherHost{ {Tenant: "cgrates.org", ID: "dispatcherHostsID"}: {}, }, dm: NewDataManager(idb, config.CgrConfig().CacheCfg(), connMgr), } tpr.dm.SetLoadIDs(make(map[string]int64)) tpr.schedulerConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.SchedulerConnsCfg)} if err := tpr.ReloadScheduler(false); err != nil { t.Error(err) } } func TestTpReaderIsValid(t *testing.T) { cfg := config.NewDefaultCGRConfig() db, dErr := NewInternalDB(nil, nil, true, nil, cfg.DataDbCfg().Items) if dErr != nil { t.Error(dErr) } tpr, err := NewTpReader(nil, db, "", "local", nil, nil) if err != nil { t.Error(err) } tpr.ratingPlans = map[string]*RatingPlan{ "rate": { Timings: map[string]*RITiming{ "timing": { StartTime: "00:00:00", Years: utils.Years{}, Months: utils.Months{}, MonthDays: utils.MonthDays{}, WeekDays: utils.WeekDays{}, }, }, }, } if valid := tpr.IsValid(); !valid { t.Error("expected true,received false") } } func TestTpReaderLoadAccountActions(t *testing.T) { cfg := config.NewDefaultCGRConfig() tscache := ltcache.NewTransCache( map[string]*ltcache.CacheConfig{ utils.CacheTBLTPAccountActions: { MaxItems: 3, TTL: time.Minute * 30, StaticTTL: false, OnEvicted: []func(itmID string, value any){ func(itmID string, value any) { }, }, }}, ) tscache.Set(utils.CacheTBLTPAccountActions, "*prfitemId", &utils.TPAccountActions{ TPid: "tp_acc1", Account: "acc1", Tenant: "tn1", }, []string{"groupId"}, true, "tId") tscache.Set(utils.CacheTBLTPAccountActions, "*prfitemId2", &utils.TPAccountActions{ TPid: "tp_acc2", Account: "acc2", Tenant: "tn2", ActionPlanId: "actionplans", }, []string{"groupId"}, true, "tId") db, dErr := NewInternalDB(nil, nil, true, nil, cfg.DataDbCfg().Items) if dErr != nil { t.Error(dErr) } db.db = tscache tpr, err := NewTpReader(db, db, "*prf", "local", nil, nil) if err != nil { t.Error(err) } if err := tpr.LoadAccountActions(); err == nil || err.Error() != fmt.Sprintf("could not get action plan for tag %q", "actionplans") { t.Error(err) } tpr.dm = nil if err := tpr.LoadAccountActions(); err == nil { t.Error(err) } } func TestTPCSVImporterChargerProfiles(t *testing.T) { db, err := NewInternalDB(nil, nil, true, nil, map[string]*config.ItemOpt{ utils.CacheTBLTPChargers: { Limit: 2, }, }) if err != nil { t.Fatal(err) } tpCharger := &utils.TPChargerProfile{ TPid: "chargetp", Tenant: "cgrates", ID: "id", } db.db.Set(utils.CacheTBLTPChargers, "tpid:itm1", tpCharger, []string{"grp"}, true, utils.NonTransactional) tpImp := &TPCSVImporter{ TPid: "tpid", Verbose: false, csvr: db, StorDb: db, } if err := tpImp.importChargerProfiles("fn"); err != nil { t.Error(err) } if val, has := db.db.Get(utils.CacheTBLTPChargers, utils.ConcatenatedKey(tpCharger.TPid, tpCharger.Tenant, tpCharger.ID)); !has { t.Error("has no value") } else if !reflect.DeepEqual(val, tpCharger) { t.Errorf("expected %+v,received %+v", utils.ToJSON(tpCharger), utils.ToJSON(val)) } } func TestTPCSVImporterDispatcherProfiles(t *testing.T) { db, err := NewInternalDB(nil, nil, true, nil, map[string]*config.ItemOpt{ utils.CacheTBLTPDispatchers: { Limit: 3, }, }) if err != nil { t.Fatal(err) } dsP := &utils.TPDispatcherProfile{ TPid: "disTP", Tenant: "tnt", ID: "id", } db.db.Set(utils.CacheTBLTPDispatchers, "tpid:dsp1", dsP, []string{"grp"}, true, utils.NonTransactional) tpImp := &TPCSVImporter{ TPid: "tpid", Verbose: false, csvr: db, StorDb: db, } if err := tpImp.importDispatcherProfiles("fn"); err != nil { t.Error(err) } if val, has := db.db.Get(utils.CacheTBLTPDispatchers, utils.ConcatenatedKey(dsP.TPid, dsP.Tenant, dsP.ID)); !has { t.Error("has no value") } else if !reflect.DeepEqual(val, dsP) { t.Errorf("expected %+v,received %+v", utils.ToJSON(dsP), utils.ToJSON(val)) } } func TestTPCSVImporterDispatcherHosts(t *testing.T) { db, err := NewInternalDB(nil, nil, true, nil, map[string]*config.ItemOpt{ utils.CacheTBLTPDispatcherHosts: { Limit: 3, }, }) if err != nil { t.Fatal(err) } dsH := &utils.TPDispatcherHost{ TPid: "dshTp", Tenant: "host", ID: "host_id", } db.db.Set(utils.CacheTBLTPDispatcherHosts, "tpid:dsp1", dsH, []string{"grp"}, true, utils.NonTransactional) tpImp := &TPCSVImporter{ TPid: "tpid", Verbose: false, csvr: db, StorDb: db, } if err := tpImp.importDispatcherHosts("fn"); err != nil { t.Error(err) } if val, has := db.db.Get(utils.CacheTBLTPDispatcherHosts, utils.ConcatenatedKey(dsH.TPid, dsH.Tenant, dsH.ID)); !has { t.Error("has no value") } else if !reflect.DeepEqual(val, dsH) { t.Errorf("expected %+v,received %+v", utils.ToJSON(dsH), utils.ToJSON(val)) } } func TestTPCSVImporterErrs(t *testing.T) { db, err := NewInternalDB(nil, nil, true, nil, map[string]*config.ItemOpt{ utils.CacheTBLTPDispatcherHosts: { Limit: 3, }, }) if err != nil { t.Fatal(err) } tpImp := &TPCSVImporter{ TPid: "tpid", Verbose: false, csvr: db, StorDb: db, } fn := "test" if err := tpImp.importTimings(fn); err == nil || err != utils.ErrNotFound { t.Error(err) } if err := tpImp.importDestinations(fn); err == nil || err != utils.ErrNotFound { t.Error(err) } if err := tpImp.importRates(fn); err == nil || err != utils.ErrNotFound { t.Error(err) } if err := tpImp.importDestinationRates(fn); err == nil || err != utils.ErrNotFound { t.Error(err) } if err := tpImp.importRatingPlans(fn); err == nil || err != utils.ErrNotFound { t.Error(err) } if err := tpImp.importRatingProfiles(fn); err == nil || err != utils.ErrNotFound { t.Error(err) } if err := tpImp.importSharedGroups(fn); err == nil || err != utils.ErrNotFound { t.Error(err) } if err := tpImp.importActions(fn); err == nil || err != utils.ErrNotFound { t.Error(err) } if err := tpImp.importActionTimings(fn); err == nil || err != utils.ErrNotFound { t.Error(err) } if err := tpImp.importActionTriggers(fn); err == nil || err != utils.ErrNotFound { t.Error(err) } if err := tpImp.importAccountActions(fn); err == nil || err != utils.ErrNotFound { t.Error(err) } if err := tpImp.importResources(fn); err == nil || err != utils.ErrNotFound { t.Error(err) } if err := tpImp.importIPs(fn); err == nil || err != utils.ErrNotFound { t.Error(err) } if err := tpImp.importStats(fn); err == nil || err != utils.ErrNotFound { t.Error(err) } if err := tpImp.importThresholds(fn); err == nil || err != utils.ErrNotFound { t.Error(err) } if err := tpImp.importFilters(fn); err == nil || err != utils.ErrNotFound { t.Error(err) } if err := tpImp.importRoutes(fn); err == nil || err != utils.ErrNotFound { t.Error(err) } if err := tpImp.importAttributeProfiles(fn); err == nil || err != utils.ErrNotFound { t.Error(err) } if err := tpImp.importChargerProfiles(fn); err == nil || err != utils.ErrNotFound { t.Error(err) } if err := tpImp.importDispatcherProfiles(fn); err == nil || err != utils.ErrNotFound { t.Error(err) } if err := tpImp.importDispatcherHosts(fn); err == nil || err != utils.ErrNotFound { t.Error(err) } } func TestTpReaderLoadTimingsErr(t *testing.T) { cfg := config.NewDefaultCGRConfig() tscache := ltcache.NewTransCache( map[string]*ltcache.CacheConfig{ utils.CacheTBLTPAccountActions: { MaxItems: 3, TTL: time.Minute * 30, StaticTTL: false, OnEvicted: []func(itmID string, value any){ func(itmID string, value any) { }, }, }}, ) duplicateId := "id" tscache.Set(utils.CacheTBLTPTimings, "*prfitemId", &utils.ApierTPTiming{ TPid: "tpId2", ID: duplicateId, }, []string{"groupId"}, true, "tId") tscache.Set(utils.CacheTBLTPTimings, "*prfitemId2", &utils.ApierTPTiming{ TPid: "TpId3", ID: duplicateId, }, []string{"groupId"}, true, "tId") db, dErr := NewInternalDB(nil, nil, true, nil, cfg.DataDbCfg().Items) if dErr != nil { t.Error(dErr) } db.db = tscache tpr, err := NewTpReader(db, db, "*prf", "local", nil, nil) if err != nil { t.Error(err) } if err := tpr.LoadTimings(); err == nil || err.Error() != fmt.Sprintf("duplicate timing tag: %s", duplicateId) { t.Error(err) } } func TestLoadDestinationRatesErr(t *testing.T) { cfg := config.NewDefaultCGRConfig() tscache := ltcache.NewTransCache( map[string]*ltcache.CacheConfig{ utils.CacheTBLTPDestinationRates: { MaxItems: 3, TTL: time.Minute * 30, StaticTTL: false, OnEvicted: []func(itmID string, value any){ func(itmID string, value any) { }, }, }, }, ) duplicateId := "id" tscache.Set(utils.CacheTBLTPDestinationRates, "*prfdest_rate1", &utils.TPDestinationRate{ TPid: "tpId2", ID: duplicateId, }, []string{"groupId"}, true, "tId") tscache.Set(utils.CacheTBLTPDestinationRates, "*prfdest_rate2", &utils.TPDestinationRate{ TPid: "TpId3", ID: duplicateId, }, []string{"groupId"}, true, "tId") db, dErr := NewInternalDB(nil, nil, true, nil, cfg.DataDbCfg().Items) if dErr != nil { t.Error(dErr) } db.db = tscache tpr, err := NewTpReader(db, db, "*prf", "local", nil, nil) if err != nil { t.Error(err) } if err := tpr.LoadDestinationRates(); err == nil || err.Error() != fmt.Sprintf("Non unique ID %+s", duplicateId) { t.Error(err) } tpr.rates = map[string]*utils.TPRateRALs{ "rate002": {}, } tscache.Remove(utils.CacheTBLTPDestinationRates, "*prfdest_rate2", true, utils.NonTransactional) tpDestRate := &utils.TPDestinationRate{ TPid: "tpId3", ID: "tp_rate001", DestinationRates: []*utils.DestinationRate{ { RateId: "rate001", DestinationId: "val", }, }, } tscache.Set(utils.CacheTBLTPDestinationRates, "*prfdest_rate3", tpDestRate, []string{"grpId"}, true, utils.NonTransactional) if err := tpr.LoadDestinationRates(); err == nil || err.Error() != fmt.Sprintf("could not find rate for tag %q", tpDestRate.DestinationRates[0].RateId) { t.Error(err) } tpr.rates["rate001"] = &utils.TPRateRALs{ TPid: "tariff", ID: "rals_id", RateSlots: []*utils.RateSlot{}, } tpr.dm.dataDB = db if err := tpr.LoadDestinationRates(); err == nil || err.Error() != fmt.Sprintf("could not get destination for tag %q", tpDestRate.DestinationRates[0].DestinationId) { t.Error(err) } } func TestTpReaderLoadRatingPlansFilteredErr(t *testing.T) { tmp := Cache defer func() { Cache = tmp config.SetCgrConfig(config.NewDefaultCGRConfig()) }() Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.DataDbCfg().Items = map[string]*config.ItemOpt{ utils.CacheTBLTPRatingPlans: { TTL: time.Minute * 30, StaticTTL: false, }, utils.CacheTBLTPTimings: { TTL: time.Minute * 30, StaticTTL: false, }, } db, dErr := NewInternalDB(nil, nil, true, nil, cfg.DataDbCfg().Items) if dErr != nil { t.Error(dErr) } tpr, err := NewTpReader(db, db, "*prf", "local", nil, nil) if err != nil { t.Error(err) } if b, err := tpr.LoadRatingPlansFiltered("tag"); err == nil || b || err != utils.ErrNotFound { t.Error(err) } } func TestLoadRatingProfilesFiltered(t *testing.T) { qriedRpf := &utils.TPRatingProfile{ TPid: "rate", Tenant: "cgr", } cfg := config.NewDefaultCGRConfig() tscache := ltcache.NewTransCache( map[string]*ltcache.CacheConfig{ utils.CacheTBLTPRatingProfiles: { MaxItems: 3, TTL: time.Minute * 30, StaticTTL: false, OnEvicted: []func(itmID string, value any){ func(itmID string, value any) { }, }, }, }, ) db, dErr := NewInternalDB(nil, nil, true, nil, cfg.DataDbCfg().Items) if dErr != nil { t.Error(dErr) } db.db = tscache tpr, err := NewTpReader(db, db, "*prf", "local", nil, nil) if err != nil { t.Error(err) } if err := tpr.LoadRatingProfilesFiltered(qriedRpf); err == nil || err.Error() != fmt.Sprintf("no RatingProfile for filter %v, error: %v", qriedRpf, utils.ErrNotFound) { t.Error(err) } val := []*utils.TPRatingProfile{ { LoadId: "load", Tenant: "cgrates", Category: "cat", Subject: " subj", TPid: "rating1", }, { LoadId: "load", Tenant: "cgrates", Category: "cat", Subject: " subj", TPid: "rating1", RatingPlanActivations: []*utils.TPRatingActivation{ { RatingPlanId: "RP_1001", ActivationTime: "test", }, }, }, } tscache.Set(utils.CacheTBLTPRatingProfiles, "rate:cgritm", val[0], []string{"grpId"}, true, utils.NonTransactional) tscache.Set(utils.CacheTBLTPRatingProfiles, "rate:cgritm2", val[1], []string{"grpId"}, true, utils.NonTransactional) if err := tpr.LoadRatingProfilesFiltered(qriedRpf); err == nil || err.Error() != fmt.Sprintf("Non unique id %+v", val[1].GetId()) { t.Error(err) } val[1].TPid, val[1].LoadId, val[1].Category = "rating2", "load2", "category2" if err := tpr.LoadRatingProfilesFiltered(qriedRpf); err == nil || err.Error() != fmt.Sprintf("cannot parse activation time from %v", val[1].RatingPlanActivations[0].ActivationTime) { t.Error(err) } tpr.timezone, val[1].RatingPlanActivations[0].ActivationTime = "UTC", "*monthly_estimated" if err := tpr.LoadRatingProfilesFiltered(qriedRpf); err == nil || err.Error() != fmt.Sprintf("could not load rating plans for tag: %q", val[1].RatingPlanActivations[0].RatingPlanId) { t.Error(err) } } func TestTpReaderLoadActionTriggers(t *testing.T) { Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() tscache := ltcache.NewTransCache( map[string]*ltcache.CacheConfig{ utils.CacheTBLTPActionTriggers: { MaxItems: 3, TTL: time.Minute * 30, StaticTTL: false, }, }, ) db, dErr := NewInternalDB(nil, nil, true, nil, cfg.DataDbCfg().Items) if dErr != nil { t.Error(dErr) } db.db = tscache tpr, err := NewTpReader(db, db, "*prf", "UTC", nil, nil) if err != nil { t.Error(err) } trVals := []*utils.TPActionTriggers{ { TPid: "TPAct", ID: "ID2", ActionTriggers: []*utils.TPActionTrigger{ { BalanceId: "id", Id: "STANDARD_TRIGGERS", ThresholdType: "*min_balance", ThresholdValue: 2, Recurrent: false, MinSleep: "0", BalanceRatingSubject: "rate", BalanceType: "*monetary", BalanceDestinationIds: "FS_USERS", ActionsId: "LOG_WARNING", Weight: 10, BalanceWeight: "20.12", BalanceExpirationDate: "*monthly", BalanceCategories: "monthly", }, { BalanceId: "id", Id: "STANDARD_TRIGGERS", ThresholdType: "*max_event_counter", ThresholdValue: 5, Recurrent: false, MinSleep: "0", BalanceType: "*monetary", BalanceDestinationIds: "FS_USERS", ActionsId: "LOG_WARNING", Weight: 10, BalanceWeight: "20.1", BalanceExpirationDate: "*yearly", ExpirationDate: "date", BalanceSharedGroups: "group1", BalanceTimingTags: "timing", BalanceBlocker: "true", BalanceDisabled: "false", }, }, }, } tscache.Set(utils.CacheTBLTPActionTriggers, "*prfitem1", trVals[0], []string{"*prfitem1", "*prfitem2"}, true, utils.NonTransactional) if err := tpr.LoadActionTriggers(); err == nil || err.Error() != "Unsupported time format" { t.Error(err) } trVals[0].ActionTriggers[0].ExpirationDate = "*monthly" trVals[0].ActionTriggers[0].ActivationDate = "value" if err := tpr.LoadActionTriggers(); err == nil || err.Error() != "Unsupported time format" { t.Error(err) } trVals[0].ActionTriggers[0].ActivationDate = "*monthly" trVals[0].ActionTriggers[0].MinSleep = "two" if err := tpr.LoadActionTriggers(); err == nil || err.Error() != fmt.Sprintf("time: invalid duration %q", trVals[0].ActionTriggers[0].MinSleep) { t.Error(err) } trVals[0].ActionTriggers[0].MinSleep = "5000ns" trVals[0].ActionTriggers[1].ExpirationDate = "*montly" if err := tpr.LoadActionTriggers(); err != nil { t.Error(err) } } func TestTpReaderSetDestination(t *testing.T) { dest := &Destination{ Id: "1001_ID", Prefixes: []string{"39", "75"}, } cfg := config.NewDefaultCGRConfig() tscache := ltcache.NewTransCache( map[string]*ltcache.CacheConfig{ utils.CacheDestinations: { MaxItems: 3, TTL: time.Minute * 30, StaticTTL: false, }, }, ) db, dErr := NewInternalDB(nil, nil, true, nil, cfg.DataDbCfg().Items) if dErr != nil { t.Error(dErr) } db.db = tscache tpr, err := NewTpReader(db, db, "*prf", "UTC", nil, nil) if err != nil { t.Error(err) } if err := tpr.setDestination(dest, true, ""); err != nil { t.Error(err) } if val, has := tscache.Get(utils.CacheDestinations, dest.Id); !has { t.Error("has no value") } else { if rcv, cancast := val.(*Destination); !cancast { t.Error("it's not type *Destination") } else if !reflect.DeepEqual(rcv, dest) { t.Errorf("exepcted %v,received %v", utils.ToJSON(dest), utils.ToJSON(rcv)) } } } func TestTPReaderLoadAccountActionsFilteredErr(t *testing.T) { Cache.Clear(nil) qried := &utils.TPAccountActions{ TPid: "tp_Id", AllowNegative: false, Disabled: true, } cfg := config.NewDefaultCGRConfig() cfg.DataDbCfg().Items = map[string]*config.ItemOpt{ utils.CacheTBLTPAccountActions: { Limit: 3, Remote: true, }, } db, dErr := NewInternalDB(nil, nil, true, nil, cfg.DataDbCfg().Items) if dErr != nil { t.Error(dErr) } tpr, err := NewTpReader(db, db, "*prf", "UTC", nil, nil) if err != nil { t.Error(err) } if err := tpr.LoadAccountActionsFiltered(qried); err == nil || err.Error() != fmt.Sprintf("%v: %+v", utils.ErrNotFound.Error(), qried) { t.Error(err) } db.db.Set(utils.CacheTBLTPAccountActions, "tp_Id:item", &utils.TPAccountActions{TPid: utils.TestSQL, LoadId: utils.TestSQL, Tenant: "cgrates.org", Account: "1001", ActionPlanId: "PREPAID_10", ActionTriggersId: "STANDARD_TRIGGERS"}, []string{"grpId"}, true, utils.NonTransactional) db.db.Set(utils.CacheTBLTPAccountActions, "tp_Id:item2", &utils.TPAccountActions{TPid: utils.TestSQL, LoadId: utils.TestSQL, Tenant: "cgrates.org", Account: "1001", ActionPlanId: "PREPAID_10", ActionTriggersId: "STANDARD_TRIGGERS"}, []string{"grpId"}, true, utils.NonTransactional) if err := tpr.LoadAccountActionsFiltered(qried); err == nil || err.Error() != fmt.Sprintf("Non unique ID %+v", utils.ConcatenatedKey("cgrates.org", "1001")) { t.Error(err) } db.db.Remove(utils.CacheTBLTPAccountActions, "tp_Id:item2", true, utils.NonTransactional) if err := tpr.LoadAccountActionsFiltered(qried); err == nil || err.Error() != fmt.Sprint(utils.ErrNotFound.Error()+" (ActionPlan): "+"PREPAID_10") { t.Error(err) } db.db.Set(utils.CacheTBLTPActionPlans, "*prf:PREPAID_10", &utils.TPActionPlan{ TPid: "TEST_TPID", ID: "PACKAGE_10", ActionPlan: []*utils.TPActionTiming{ { ActionsId: "TOPUP_RST_10", TimingId: "ASAP", Weight: 10.0}, { ActionsId: "TOPUP_RST_5", TimingId: "ASAP", Weight: 20.0}, }, }, []string{"grpID"}, true, utils.NonTransactional) } func TestTprRemoveFromDatabase(t *testing.T) { Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.DataDbCfg().Items = map[string]*config.ItemOpt{ utils.CacheSharedGroups: { Limit: 3, }, utils.CacheChargerProfiles: { Limit: 2, }, } db, dErr := NewInternalDB(nil, nil, true, nil, cfg.DataDbCfg().Items) if dErr != nil { t.Error(dErr) } tpr, err := NewTpReader(db, db, "*prf", "UTC", nil, nil) if err != nil { t.Error(err) } db.db.Set(utils.CacheSharedGroups, "itmID", &SharedGroup{ Id: "SG_TEST", }, []string{}, true, utils.NonTransactional) db.db.Set(utils.CacheChargerProfiles, "cgrates.org:DEFAULT", &ChargerProfile{ Tenant: "cgrates.org", ID: "DEFAULT", FilterIDs: []string{}, RunID: utils.MetaDefault, AttributeIDs: []string{"*none"}, Weight: 0, }, []string{}, true, utils.NonTransactional) tpr.sharedGroups = map[string]*SharedGroup{ "itmID": { Id: "SG_TEST", }, } tpr.chargerProfiles = map[utils.TenantID]*utils.TPChargerProfile{ {Tenant: "cgrates", ID: "item2"}: { Tenant: "cgrates.org", ID: "DEFAULT", FilterIDs: []string{}, RunID: utils.MetaDefault, AttributeIDs: []string{"*none"}, Weight: 0, }, } if err := tpr.RemoveFromDatabase(false, true); err != nil { t.Error(err) } if _, has := db.db.Get(utils.CacheSharedGroups, "itmID"); has { t.Error("should been removed from the cache") } else if _, has := db.db.Get(utils.CacheSharedGroups, "cgrates.org:DEFAULT"); has { t.Error("should been removed from the cache") } } func TestLoadActionPlansErrs(t *testing.T) { tmp := Cache cfg := config.NewDefaultCGRConfig() cfg.DataDbCfg().Items = map[string]*config.ItemOpt{ utils.CacheTBLTPActionPlans: { StaticTTL: true, Limit: 4, }, utils.CacheActions: { Limit: 2, }, } defer func() { Cache = tmp config.SetCgrConfig(config.NewDefaultCGRConfig()) }() Cache.Clear(nil) db, dErr := NewInternalDB(nil, nil, true, nil, cfg.DataDbCfg().Items) if dErr != nil { t.Error(dErr) } tpr, err := NewTpReader(db, db, "tpr", "UTC", nil, nil) if err != nil { t.Error(err) } db.db.Set(utils.CacheTBLTPActionPlans, "tpr:item1", &utils.TPActionPlan{ TPid: "TEST_TPID", ID: "PACKAGE_10", ActionPlan: []*utils.TPActionTiming{ { ActionsId: "TOPUP_RST_10", TimingId: "ASAP", Weight: 10.0}, }, }, []string{}, true, utils.NonTransactional) tpr.actions = map[string][]*Action{ "TOPUP_RST_*": {}, } if err := tpr.LoadActionPlans(); err == nil || err.Error() != fmt.Sprintf("[ActionPlans] Could not load the action for tag: %q", "TOPUP_RST_10") { t.Error(err) } db.db.Set(utils.CacheActions, "TOPUP_RST_10", nil, []string{}, true, utils.NonTransactional) if err := tpr.LoadActionPlans(); err == nil || err.Error() != fmt.Sprintf("[ActionPlans] Could not load the timing for tag: %q", "ASAP") { t.Error(err) } } func TestLoadRatingPlansFiltered(t *testing.T) { tmp := Cache defer func() { Cache = tmp }() Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.DataDbCfg().Items = map[string]*config.ItemOpt{ utils.CacheSharedGroups: { Limit: 3, }, utils.CacheTBLTPTimings: { Limit: 2, }, utils.CacheTBLTPDestinationRates: { Limit: 3, }, utils.CacheTBLTPRates: { Limit: 2, }, } db, dErr := NewInternalDB(nil, nil, true, nil, cfg.DataDbCfg().Items) if dErr != nil { t.Error(dErr) } tpr, err := NewTpReader(db, db, "*prf", "UTC", nil, nil) if err != nil { t.Error(err) } db.db.Set(utils.CacheTBLTPRatingPlans, "*prf:def:itmID", &utils.TPRatingPlan{ ID: "ID", TPid: "TPid", RatingPlanBindings: []*utils.TPRatingPlanBinding{ { DestinationRatesId: "DestinationRatesId", TimingId: "TimingId", Weight: 0.7, }, }, }, []string{}, true, utils.NonTransactional) if _, err := tpr.LoadRatingPlansFiltered("def"); err == nil || !strings.Contains(err.Error(), "no timing with id ") { t.Error(err) } db.db.Set(utils.CacheTBLTPTimings, "*prf:TimingId", &utils.ApierTPTiming{ TPid: "testTPid", ID: "TimingId", Years: "*any", Months: "*any", MonthDays: "*any", WeekDays: "1;2;3;4;5", Time: "01:00:00", }, []string{}, true, utils.NonTransactional) db.db.Set(utils.CacheTBLTPTimings, "*prf:TimingId2", &utils.ApierTPTiming{ TPid: "testTPid", ID: "TimingId", Years: "*any", Months: "*any", MonthDays: "*any", WeekDays: "1;2;3;4;5", Time: "01:00:00", }, []string{}, true, utils.NonTransactional) if _, err := tpr.LoadRatingPlansFiltered("def"); err == nil { t.Error(err) } db.db.Remove(utils.CacheTBLTPTimings, "*prf:TimingId2", true, utils.NonTransactional) if _, err := tpr.LoadRatingPlansFiltered("def"); err == nil || !strings.Contains(err.Error(), "no DestinationRates profile with id") { t.Error(err) } db.db.Set(utils.CacheTBLTPDestinationRates, "*prf:DestinationRatesId1", &utils.TPDestinationRate{ TPid: "TEST_TPID", ID: "DestinationRatesId", DestinationRates: []*utils.DestinationRate{ { DestinationId: "TEST_DEST1", RateId: "TEST_RATE1", RoundingMethod: "*up", Rate: &utils.TPRateRALs{ TPid: "TPidTpRate", ID: "RT_FS_USERS", RateSlots: []*utils.RateSlot{ { ConnectFee: 12, Rate: 3, RateUnit: "6s", RateIncrement: "6s", GroupIntervalStart: "0s", }, }, }, RoundingDecimals: 4}, { DestinationId: "TEST_DEST2", RateId: "TEST_RATE2", RoundingMethod: "*up", RoundingDecimals: 4}, }, }, []string{}, true, utils.NonTransactional) db.db.Set(utils.CacheTBLTPDestinationRates, "*prf:DestinationRatesId2", &utils.TPDestinationRate{ TPid: "TEST_TPID", ID: "DestinationRatesId", DestinationRates: []*utils.DestinationRate{ { DestinationId: "TEST_DEST1", RateId: "TEST_RATE1", RoundingMethod: "*up", RoundingDecimals: 4}, }, }, []string{}, true, utils.NonTransactional) if _, err := tpr.LoadRatingPlansFiltered("def"); err == nil { t.Error(err) } db.db.Remove(utils.CacheTBLTPDestinationRates, "*prf:DestinationRatesId2", true, utils.NonTransactional) if _, err := tpr.LoadRatingPlansFiltered("def"); err == nil || !strings.Contains(err.Error(), "no Rates profile with id ") { t.Error(err) } db.db.Set(utils.CacheTBLTPRates, "*prf:TEST_RATE1", &utils.TPRateRALs{ TPid: "TPidTpRate", ID: "RT_FS_USERS", RateSlots: []*utils.RateSlot{ { ConnectFee: 12, Rate: 3, RateUnit: "6s", RateIncrement: "6s", GroupIntervalStart: "0s", }, }, }, []string{}, true, utils.NonTransactional) db.db.Set(utils.CacheTBLTPRates, "*prf:TEST_RATE12", &utils.TPRateRALs{ TPid: "TPidTpRate", ID: "RT_FS_USERS", RateSlots: []*utils.RateSlot{ { ConnectFee: 12, Rate: 3, RateUnit: "6s", RateIncrement: "6s", GroupIntervalStart: "0s", }, }, }, []string{}, true, utils.NonTransactional) if _, err := tpr.LoadRatingPlansFiltered("def"); err == nil { t.Error(err) } } func TestTPRLoadRatingProfiles(t *testing.T) { cfg := config.NewDefaultCGRConfig() defer func() { config.SetCgrConfig(config.NewDefaultCGRConfig()) }() db, dErr := NewInternalDB(nil, nil, true, nil, cfg.DataDbCfg().Items) if dErr != nil { t.Error(dErr) } tpr, err := NewTpReader(db, db, "RP1", "", nil, nil) if err != nil { t.Error(err) } rpS := []*utils.TPRatingProfile{ { TPid: "RP1", RatingPlanActivations: []*utils.TPRatingActivation{ { ActivationTime: "2014-07-29T15:00:00Z", RatingPlanId: "PlanOne", FallbackSubjects: "FallBack", }, }, }, } if err := db.SetTPRatingProfiles(rpS); err != nil { t.Error(err) } if err = tpr.LoadRatingProfiles(); err == nil || err.Error() != fmt.Sprintf("could not load rating plans for tag: %q", rpS[0].RatingPlanActivations[0].RatingPlanId) { t.Error(err) } rpS2 := []*utils.TPRatingProfile{ { TPid: "RP2", RatingPlanActivations: []*utils.TPRatingActivation{ { ActivationTime: "2014-07-29T15:00:00Z", RatingPlanId: "PlanOne", FallbackSubjects: "FallBack", }, }, }, { TPid: "RP2", RatingPlanActivations: []*utils.TPRatingActivation{ { ActivationTime: "2012-01-01T00:00:00Z", RatingPlanId: "RPl_SAMPLE_RATING_PLAN", FallbackSubjects: utils.EmptyString, }, { ActivationTime: "test", RatingPlanId: "RPl_SAMPLE_RATING_PLAN2", FallbackSubjects: utils.EmptyString, }, }, }} if err := db.SetTPRatingProfiles(rpS2); err != nil { t.Error(err) } if err = tpr.LoadRatingProfiles(); err == nil { t.Error(err) } } func TestTPRLoadAccountActions(t *testing.T) { cfg := config.NewDefaultCGRConfig() defer func() { config.SetCgrConfig(config.NewDefaultCGRConfig()) }() db, dErr := NewInternalDB(nil, nil, true, nil, cfg.DataDbCfg().Items) if dErr != nil { t.Error(dErr) } tpr, err := NewTpReader(db, db, "", "", nil, nil) if err != nil { t.Error(err) } accAcs := []*utils.TPAccountActions{ { TPid: "testTPid", ActionPlanId: "PACKAGE_10_SHARED_A_5", ActionTriggersId: "STANDARD_TRIGGERS", AllowNegative: true, Disabled: true, }, } if err := db.SetTPAccountActions(accAcs); err != nil { t.Error(err) } if err = tpr.LoadAccountActions(); err == nil || err.Error() != fmt.Sprintf("could not get action triggers for tag %q", accAcs[0].ActionTriggersId) { t.Error(err) } } func TestTpReaderRemoveFromDatabase(t *testing.T) { cfg := config.NewDefaultCGRConfig() defer func() { config.SetCgrConfig(config.NewDefaultCGRConfig()) }() db, dErr := NewInternalDB(nil, nil, true, nil, cfg.DataDbCfg().Items) if dErr != nil { t.Error(dErr) } tpr, err := NewTpReader(db, db, "", "", nil, nil) if err != nil { t.Error(err) } dest := &Destination{ Id: "DST2", Prefixes: []string{"1001"}, } tpr.destinations = map[string]*Destination{ "GERMANY": dest, } if tpr.dm.SetDestination(dest, utils.NonTransactional); err != nil { t.Error(err) } acc := &Account{ ID: "cgrates.org:1001", } ap1 := &ActionPlan{ Id: "TestActionPlansRemoveMember1", AccountIDs: utils.StringMap{"one": true}, ActionTimings: []*ActionTiming{ { Uuid: "uuid1", Timing: &RateInterval{ Timing: &RITiming{ Years: utils.Years{2012}, Months: utils.Months{}, MonthDays: utils.MonthDays{}, WeekDays: utils.WeekDays{}, StartTime: utils.MetaASAP, }, }, Weight: 10, ActionsID: "MINI", }, }, } if err := tpr.dm.SetAccount(acc); err != nil { t.Error(err) } if err := tpr.dm.SetActionPlan(ap1.Id, ap1, true, utils.NonTransactional); err != nil { t.Error(err) } if err = tpr.dm.SetAccountActionPlans(acc.ID, []string{ap1.Id}, false); err != nil { t.Error(err) } tpr.acntActionPlans = map[string][]string{ acc.ID: {ap1.Id}, } if err := tpr.RemoveFromDatabase(false, false); err != nil { t.Error(err) } if err := tpr.RemoveFromDatabase(false, true); err == nil || err != utils.ErrNotFound { t.Error(err) } } func TestTpReaderRemoveFromDatabaseDspPrf(t *testing.T) { cfg := config.NewDefaultCGRConfig() defer func() { config.SetCgrConfig(config.NewDefaultCGRConfig()) }() db, dErr := NewInternalDB(nil, nil, true, nil, cfg.DataDbCfg().Items) if dErr != nil { t.Error(dErr) } tpr, err := NewTpReader(db, db, "", "", nil, nil) if err != nil { t.Error(err) } dspPrf := &DispatcherProfile{ Tenant: "cgrates.org", ID: "Dsp1", FilterIDs: []string{"*string:~*req.Accont:1001"}, 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), }, Strategy: utils.MetaRandom, Weight: 20, } if err := tpr.dm.SetDispatcherProfile(dspPrf, true); err != nil { t.Error(err) } tpr.dispatcherProfiles = map[utils.TenantID]*utils.TPDispatcherProfile{ { Tenant: "cgrates.org", ID: "Dsp1", }: { Tenant: "cgrates.org", ID: "Dsp1", }, } if err = tpr.RemoveFromDatabase(false, true); err != nil { t.Error(err) } if err = tpr.RemoveFromDatabase(false, true); err == nil || err != utils.ErrDSPProfileNotFound { t.Error(err) } } func TestTpReaderRemoveFromDatabaseDspHst(t *testing.T) { cfg := config.NewDefaultCGRConfig() defer func() { config.SetCgrConfig(config.NewDefaultCGRConfig()) }() db, dErr := NewInternalDB(nil, nil, true, nil, cfg.DataDbCfg().Items) if dErr != nil { t.Error(dErr) } tpr, err := NewTpReader(db, db, "", "", nil, nil) if err != nil { t.Error(err) } dspHst := &DispatcherHost{ Tenant: "cgrates.org", RemoteHost: &config.RemoteHost{ ID: "Host2", Address: "127.0.0.1:2013", TLS: false, Transport: utils.MetaGOB, }, } if err = tpr.dm.SetDispatcherHost(dspHst); err != nil { t.Error(err) } tpr.dispatcherHosts = map[utils.TenantID]*utils.TPDispatcherHost{ {}: { ID: "Host2", Tenant: "cgrates.org", }, } if err = tpr.RemoveFromDatabase(false, true); err != nil { t.Error(err) } if err = tpr.RemoveFromDatabase(false, true); err == nil || err != utils.ErrDSPHostNotFound { t.Error(err) } } func TestTprLoadAccountActionFiltered(t *testing.T) { cfg := config.NewDefaultCGRConfig() tmpConn := connMgr defer func() { config.SetCgrConfig(config.NewDefaultCGRConfig()) SetConnManager(tmpConn) }() dataDb, dErr := NewInternalDB(nil, nil, true, nil, cfg.DataDbCfg().Items) if dErr != nil { t.Error(dErr) } storDb, err := NewInternalDB(nil, nil, false, nil, cfg.StorDbCfg().Items) if err != nil { t.Error(err) } tpr, err := NewTpReader(dataDb, storDb, "TP1", "", []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches)}, nil) if err != nil { t.Error(err) } clientconn := make(chan birpc.ClientConnector, 1) clientconn <- clMock(func(serviceMethod string, _, _ any) error { if serviceMethod == utils.CacheSv1ReloadCache { return nil } return utils.ErrNotImplemented }) connMgr := NewConnManager(cfg, map[string]chan birpc.ClientConnector{ utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches): clientconn, }) timings := &utils.ApierTPTiming{ TPid: "TP1", ID: "ASAP", Years: "", Months: "05", MonthDays: "01", WeekDays: "1", Time: "15:00:00Z", } storDb.SetTPTimings([]*utils.ApierTPTiming{timings}) actions := &utils.TPActions{ TPid: "TP1", ID: "TOPUP_RST_10", Actions: []*utils.TPAction{ { Identifier: "*topup_reset", BalanceId: "BalID", BalanceType: "*data", Units: "10", ExpiryTime: "*unlimited", TimingTags: utils.MetaASAP, BalanceWeight: "10", Weight: 10, }, }, } storDb.SetTPActions([]*utils.TPActions{actions}) actionplans := []*utils.TPActionPlan{ { TPid: "TP1", ID: "PREPAID_10", ActionPlan: []*utils.TPActionTiming{ { ActionsId: "TOPUP_RST_10", TimingId: "ASAP", Weight: 10.0}, }, }, } tpatrs := &utils.TPActionTriggers{ TPid: "TP1", ID: "STANDARD_TRIGGERS", ActionTriggers: []*utils.TPActionTrigger{ { Id: "STANDARD_TRIGGERS", UniqueID: "1", ThresholdType: "*min_balance", ThresholdValue: 2.0, Recurrent: false, BalanceType: "*monetary", BalanceCategories: "call", ActionsId: "LOG_WARNING", Weight: 10}, }, } storDb.SetTPActionTriggers([]*utils.TPActionTriggers{ tpatrs, }) storDb.SetTPActionPlans(actionplans) qriedAA := &utils.TPAccountActions{ TPid: "TP1", LoadId: "ID", Tenant: "cgrates.org", Account: "1001", ActionPlanId: "PREPAID_10", ActionTriggersId: "STANDARD_TRIGGERS", AllowNegative: true, Disabled: false, } storDb.SetTPAccountActions([]*utils.TPAccountActions{ qriedAA, }) SetConnManager(connMgr) if err := tpr.LoadAccountActionsFiltered(qriedAA); err == nil { t.Error(err) } //unfinished } func TestTprLoadRatingPlansFiltered(t *testing.T) { cfg := config.NewDefaultCGRConfig() defer func() { config.SetCgrConfig(config.NewDefaultCGRConfig()) }() dataDb, dErr := NewInternalDB(nil, nil, true, nil, cfg.DataDbCfg().Items) if dErr != nil { t.Error(dErr) } storDb, err := NewInternalDB(nil, nil, false, nil, cfg.StorDbCfg().Items) if err != nil { t.Error(err) } storDb.SetTPDestinations([]*utils.TPDestination{{ TPid: "TP1", ID: "FS_USERS", Prefixes: []string{"+664", "+554"}}, }) tprt := &utils.TPRateRALs{ TPid: "TP1", ID: "RT_FS_USERS", RateSlots: []*utils.RateSlot{ { ConnectFee: 12, Rate: 3, RateUnit: "6s", RateIncrement: "6s", GroupIntervalStart: "0s", }, { ConnectFee: 12, Rate: 3, RateUnit: "4s", RateIncrement: "6s", GroupIntervalStart: "1s", }, }, } storDb.SetTPRates([]*utils.TPRateRALs{tprt}) tpdr := &utils.TPDestinationRate{ TPid: "TP1", ID: "DR_FREESWITCH_USERS", DestinationRates: []*utils.DestinationRate{ { DestinationId: "FS_USERS", RateId: "RT_FS_USERS", RoundingMethod: "*up", RoundingDecimals: 2}, }, } storDb.SetTPDestinationRates([]*utils.TPDestinationRate{tpdr}) storDb.SetTPTimings([]*utils.ApierTPTiming{ { TPid: "TP1", ID: "ALWAYS", Years: "*any", Months: "*any", MonthDays: "*any", WeekDays: "1;2;3;4;5", Time: "00:00:00"}, }) rp := &utils.TPRatingPlan{ TPid: "TP1", ID: "RPl_SAMPLE_RATING_PLAN2", RatingPlanBindings: []*utils.TPRatingPlanBinding{ { DestinationRatesId: "DR_FREESWITCH_USERS", TimingId: "ALWAYS", Weight: 10, }, }} storDb.SetTPRatingPlans([]*utils.TPRatingPlan{rp}) tpr, err := NewTpReader(dataDb, storDb, "TP1", "", []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches)}, nil) if err != nil { t.Error(err) } if load, err := tpr.LoadRatingPlansFiltered(""); err != nil || !load { t.Error(err) } }