mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Add coverage tests on actions
This commit is contained in:
committed by
Dan Christian Bogos
parent
3337975340
commit
a4cc9cf20f
@@ -2758,3 +2758,299 @@ func TestActDynamicRouteCfg(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestActDynamicRouteExecute(t *testing.T) {
|
||||
engine.Cache.Clear(nil)
|
||||
defer engine.Cache.Clear(nil)
|
||||
|
||||
var rpo *utils.RouteProfileWithAPIOpts
|
||||
ccM := &ccMock{
|
||||
calls: map[string]func(ctx *context.Context, args any, reply any) error{
|
||||
utils.AdminSv1SetRouteProfile: func(ctx *context.Context, args, reply any) error {
|
||||
var canCast bool
|
||||
if rpo, canCast = args.(*utils.RouteProfileWithAPIOpts); !canCast {
|
||||
return fmt.Errorf("couldnt cast")
|
||||
}
|
||||
*(reply.(*string)) = utils.OK
|
||||
return nil
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
testcases := []struct {
|
||||
name string
|
||||
diktats []*utils.APDiktat
|
||||
expRpo *utils.RouteProfileWithAPIOpts
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "SuccessfulRequest",
|
||||
expRpo: &utils.RouteProfileWithAPIOpts{
|
||||
RouteProfile: &utils.RouteProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "ROUTE_1001",
|
||||
FilterIDs: []string{"*string:~*req.Account:1001"},
|
||||
Weights: utils.DynamicWeights{
|
||||
&utils.DynamicWeight{
|
||||
FilterIDs: []string{"*weight"},
|
||||
Weight: 10.0,
|
||||
},
|
||||
},
|
||||
Blockers: utils.DynamicBlockers{
|
||||
&utils.DynamicBlocker{
|
||||
FilterIDs: []string{"*blocker"},
|
||||
Blocker: false,
|
||||
},
|
||||
},
|
||||
Sorting: "*weight",
|
||||
SortingParameters: []string{"*weight", "*cost"},
|
||||
Routes: []*utils.Route{
|
||||
{
|
||||
ID: "RT_1001",
|
||||
FilterIDs: []string{"*string:~*req.Route:1001"},
|
||||
AccountIDs: []string{"1001", "1002"},
|
||||
RateProfileIDs: []string{"RP_1001"},
|
||||
ResourceIDs: []string{"RES_1001"},
|
||||
StatIDs: []string{"STAT_1001"},
|
||||
Weights: utils.DynamicWeights{
|
||||
&utils.DynamicWeight{
|
||||
FilterIDs: []string{"*route_weight"},
|
||||
Weight: 20.0,
|
||||
},
|
||||
},
|
||||
Blockers: utils.DynamicBlockers{
|
||||
&utils.DynamicBlocker{
|
||||
FilterIDs: []string{"*route_blocker"},
|
||||
Blocker: false,
|
||||
},
|
||||
},
|
||||
RouteParameters: "param1=value1",
|
||||
},
|
||||
},
|
||||
},
|
||||
APIOpts: map[string]any{
|
||||
utils.MetaSubsys: "*sessions",
|
||||
},
|
||||
},
|
||||
diktats: []*utils.APDiktat{
|
||||
{
|
||||
ID: "d1",
|
||||
FilterIDs: []string{"*string:~*req.Account:1001"},
|
||||
Weights: utils.DynamicWeights{
|
||||
&utils.DynamicWeight{Weight: 20.0},
|
||||
},
|
||||
Opts: map[string]any{
|
||||
utils.MetaTemplate: "cgrates.org;ROUTE_1001;*string:~*req.Account:1001;*weight&10.0;*blocker&false;*weight;*weight&*cost;RT_1001;*string:~*req.Route:1001;1001&1002;RP_1001;RES_1001;STAT_1001;*route_weight&20.0;*route_blocker&false;param1=value1;*subsys:*sessions",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "SuccessfulRequestWithDynamicPaths",
|
||||
expRpo: &utils.RouteProfileWithAPIOpts{
|
||||
RouteProfile: &utils.RouteProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "ROUTE_1001",
|
||||
Sorting: "*weight",
|
||||
Routes: []*utils.Route{
|
||||
{
|
||||
ID: "RT_1001",
|
||||
AccountIDs: []string{"1001"},
|
||||
RouteParameters: "1001",
|
||||
},
|
||||
},
|
||||
},
|
||||
APIOpts: map[string]any{
|
||||
"account": "1001",
|
||||
},
|
||||
},
|
||||
diktats: []*utils.APDiktat{
|
||||
{
|
||||
ID: "d1",
|
||||
FilterIDs: []string{"*string:~*req.Account:1001"},
|
||||
Weights: utils.DynamicWeights{
|
||||
&utils.DynamicWeight{Weight: 15.0},
|
||||
},
|
||||
Opts: map[string]any{
|
||||
utils.MetaTemplate: "cgrates.org;ROUTE_<~*req.Account>;;;;*weight;;RT_<~*req.Account>;;1001;;;;;;<~*req.Account>;account:<~*req.Account>",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "SuccessfulRequestEmptyFields",
|
||||
expRpo: &utils.RouteProfileWithAPIOpts{
|
||||
RouteProfile: &utils.RouteProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "ROUTE_EMPTY",
|
||||
Sorting: "",
|
||||
},
|
||||
APIOpts: map[string]any{},
|
||||
},
|
||||
diktats: []*utils.APDiktat{
|
||||
{
|
||||
ID: "d1",
|
||||
FilterIDs: []string{"*string:~*req.Account:1001"},
|
||||
Weights: utils.DynamicWeights{
|
||||
&utils.DynamicWeight{Weight: 10.0},
|
||||
},
|
||||
Opts: map[string]any{
|
||||
utils.MetaTemplate: "cgrates.org;ROUTE_EMPTY;;;;;;;;;;;;;;;",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "EmptyDiktats",
|
||||
diktats: []*utils.APDiktat{},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "InvalidNumberOfParams",
|
||||
diktats: []*utils.APDiktat{
|
||||
{
|
||||
ID: "d1",
|
||||
Weights: utils.DynamicWeights{
|
||||
&utils.DynamicWeight{Weight: 20.0},
|
||||
},
|
||||
Opts: map[string]any{
|
||||
utils.MetaTemplate: "cgrates.org;ROUTE_INVALID;only;four;params",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "APIOptsInvalidFormat",
|
||||
diktats: []*utils.APDiktat{
|
||||
{
|
||||
ID: "d1",
|
||||
Weights: utils.DynamicWeights{
|
||||
&utils.DynamicWeight{Weight: 20.0},
|
||||
},
|
||||
Opts: map[string]any{
|
||||
utils.MetaTemplate: "cgrates.org;ROUTE_INVALID;;;;;;;;;;;;;;;;invalidformat",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
cfg := config.NewDefaultCGRConfig()
|
||||
cfg.GeneralCfg().DefaultCaching = utils.MetaNone
|
||||
cfg.ActionSCfg().AdminSConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAdminS)}
|
||||
connMgr := engine.NewConnManager(cfg)
|
||||
dataDB, _ := engine.NewInternalDB(nil, nil, nil, cfg.DataDbCfg().Items)
|
||||
dm := engine.NewDataManager(dataDB, cfg, connMgr)
|
||||
fltrS := engine.NewFilterS(cfg, connMgr, dm)
|
||||
rpcInternal := make(chan birpc.ClientConnector, 1)
|
||||
rpcInternal <- ccM
|
||||
connMgr.AddInternalConn(utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAdminS), utils.AdminSv1, rpcInternal)
|
||||
|
||||
act := &actDynamicRoute{
|
||||
config: cfg,
|
||||
connMgr: connMgr,
|
||||
dm: dm,
|
||||
fltrS: fltrS,
|
||||
tnt: "cgrates.org",
|
||||
cgrEv: &utils.CGREvent{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "evID",
|
||||
Event: map[string]any{
|
||||
utils.AccountField: "1001",
|
||||
},
|
||||
},
|
||||
aCfg: &utils.APAction{
|
||||
ID: "ACT_DYNAMIC_ROUTE",
|
||||
Diktats: tc.diktats,
|
||||
},
|
||||
}
|
||||
|
||||
t.Cleanup(func() {
|
||||
rpo = nil
|
||||
})
|
||||
|
||||
ctx := context.Background()
|
||||
data := utils.MapStorage{
|
||||
"*req": map[string]any{
|
||||
utils.AccountField: "1001",
|
||||
},
|
||||
}
|
||||
trgID := "trigger1"
|
||||
err := act.execute(ctx, data, trgID)
|
||||
|
||||
if tc.wantErr {
|
||||
if err == nil {
|
||||
t.Errorf("expected an error, but got nil")
|
||||
}
|
||||
} else if err != nil {
|
||||
t.Error(err)
|
||||
} else if tc.expRpo != nil && !reflect.DeepEqual(rpo, tc.expRpo) {
|
||||
t.Errorf("Expected <%v>\nReceived\n<%v>", utils.ToJSON(tc.expRpo), utils.ToJSON(rpo))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestActDynamicRateId(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
aL actDynamicRate
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "WithValidID",
|
||||
aL: actDynamicRate{aCfg: &utils.APAction{ID: "RateProfile1"}},
|
||||
want: "RateProfile1",
|
||||
},
|
||||
{
|
||||
name: "WithEmptyID",
|
||||
aL: actDynamicRate{aCfg: &utils.APAction{ID: ""}},
|
||||
want: "",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := tt.aL.id(); got != tt.want {
|
||||
t.Errorf("actDynamicRate.id() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestActDynamicRateCfg(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
aL actDynamicRate
|
||||
want *utils.APAction
|
||||
}{
|
||||
{
|
||||
name: "WithValidCfg",
|
||||
aL: actDynamicRate{aCfg: &utils.APAction{ID: "RateProfile1"}},
|
||||
want: &utils.APAction{ID: "RateProfile1"},
|
||||
},
|
||||
{
|
||||
name: "WithEmptyCfg",
|
||||
aL: actDynamicRate{aCfg: &utils.APAction{}},
|
||||
want: &utils.APAction{},
|
||||
},
|
||||
{
|
||||
name: "WithNilCfg",
|
||||
aL: actDynamicRate{aCfg: nil},
|
||||
want: nil,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := tt.aL.cfg(); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("actDynamicRate.cfg() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,3 +144,230 @@ func TestACActionTarget(t *testing.T) {
|
||||
t.Errorf("Expected %+v, received %+v", utils.MetaNone, rcv)
|
||||
}
|
||||
}
|
||||
|
||||
func TestActionTarget(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
act string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "ResetStatQueue",
|
||||
act: utils.MetaResetStatQueue,
|
||||
want: utils.MetaStats,
|
||||
},
|
||||
{
|
||||
name: "DynamicStats",
|
||||
act: utils.MetaDynamicStats,
|
||||
want: utils.MetaStats,
|
||||
},
|
||||
{
|
||||
name: "ResetThreshold",
|
||||
act: utils.MetaResetThreshold,
|
||||
want: utils.MetaThresholds,
|
||||
},
|
||||
{
|
||||
name: "DynamicThreshold",
|
||||
act: utils.MetaDynamicThreshold,
|
||||
want: utils.MetaThresholds,
|
||||
},
|
||||
{
|
||||
name: "AddBalance",
|
||||
act: utils.MetaAddBalance,
|
||||
want: utils.MetaAccounts,
|
||||
},
|
||||
{
|
||||
name: "SetBalance",
|
||||
act: utils.MetaSetBalance,
|
||||
want: utils.MetaAccounts,
|
||||
},
|
||||
{
|
||||
name: "RemBalance",
|
||||
act: utils.MetaRemBalance,
|
||||
want: utils.MetaAccounts,
|
||||
},
|
||||
{
|
||||
name: "DynamicAttribute",
|
||||
act: utils.MetaDynamicAttribute,
|
||||
want: utils.MetaAttributes,
|
||||
},
|
||||
{
|
||||
name: "DynamicResource",
|
||||
act: utils.MetaDynamicResource,
|
||||
want: utils.MetaResources,
|
||||
},
|
||||
{
|
||||
name: "DynamicTrend",
|
||||
act: utils.MetaDynamicTrend,
|
||||
want: utils.MetaTrends,
|
||||
},
|
||||
{
|
||||
name: "DynamicRanking",
|
||||
act: utils.MetaDynamicRanking,
|
||||
want: utils.MetaRankings,
|
||||
},
|
||||
{
|
||||
name: "DynamicFilter",
|
||||
act: utils.MetaDynamicFilter,
|
||||
want: utils.MetaFilters,
|
||||
},
|
||||
{
|
||||
name: "DynamicRoute",
|
||||
act: utils.MetaDynamicRoute,
|
||||
want: utils.MetaRoutes,
|
||||
},
|
||||
{
|
||||
name: "DynamicRate",
|
||||
act: utils.MetaDynamicRate,
|
||||
want: utils.MetaRates,
|
||||
},
|
||||
{
|
||||
name: "DynamicIP",
|
||||
act: utils.MetaDynamicIP,
|
||||
want: utils.MetaIPs,
|
||||
},
|
||||
{
|
||||
name: "DynamicAction",
|
||||
act: utils.MetaDynamicAction,
|
||||
want: utils.MetaActions,
|
||||
},
|
||||
{
|
||||
name: "UnknownAction",
|
||||
act: "unknown",
|
||||
want: utils.MetaNone,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := actionTarget(tt.act); got != tt.want {
|
||||
t.Errorf("actionTarget(%q) = %q, want %q", tt.act, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewActioner(t *testing.T) {
|
||||
cfg := config.NewDefaultCGRConfig()
|
||||
data, _ := engine.NewInternalDB(nil, nil, nil, cfg.DataDbCfg().Items)
|
||||
dm := engine.NewDataManager(data, cfg, nil)
|
||||
fltr := engine.NewFilterS(cfg, nil, nil)
|
||||
|
||||
ctx := context.Background()
|
||||
cgrEv := new(utils.CGREvent)
|
||||
connMgr := new(engine.ConnManager)
|
||||
tnt := utils.CGRateSorg
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
aCfg *utils.APAction
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
name: "UnsupportedAction",
|
||||
aCfg: &utils.APAction{Type: "not_a_type"},
|
||||
wantErr: "unsupported action type: <not_a_type>",
|
||||
},
|
||||
{
|
||||
name: "MetaLog",
|
||||
aCfg: &utils.APAction{Type: utils.MetaLog},
|
||||
},
|
||||
{
|
||||
name: "CDRLog",
|
||||
aCfg: &utils.APAction{Type: utils.CDRLog},
|
||||
},
|
||||
{
|
||||
name: "MetaHTTPPost",
|
||||
aCfg: &utils.APAction{Type: utils.MetaHTTPPost},
|
||||
},
|
||||
{
|
||||
name: "MetaExport",
|
||||
aCfg: &utils.APAction{Type: utils.MetaExport},
|
||||
},
|
||||
{
|
||||
name: "MetaResetStatQueue",
|
||||
aCfg: &utils.APAction{Type: utils.MetaResetStatQueue},
|
||||
},
|
||||
{
|
||||
name: "MetaResetThreshold",
|
||||
aCfg: &utils.APAction{Type: utils.MetaResetThreshold},
|
||||
},
|
||||
{
|
||||
name: "MetaAddBalance",
|
||||
aCfg: &utils.APAction{Type: utils.MetaAddBalance},
|
||||
},
|
||||
{
|
||||
name: "MetaSetBalance",
|
||||
aCfg: &utils.APAction{Type: utils.MetaSetBalance},
|
||||
},
|
||||
{
|
||||
name: "MetaRemBalance",
|
||||
aCfg: &utils.APAction{Type: utils.MetaRemBalance},
|
||||
},
|
||||
{
|
||||
name: "MetaDynamicThreshold",
|
||||
aCfg: &utils.APAction{Type: utils.MetaDynamicThreshold},
|
||||
},
|
||||
{
|
||||
name: "MetaDynamicStats",
|
||||
aCfg: &utils.APAction{Type: utils.MetaDynamicStats},
|
||||
},
|
||||
{
|
||||
name: "MetaDynamicAttribute",
|
||||
aCfg: &utils.APAction{Type: utils.MetaDynamicAttribute},
|
||||
},
|
||||
{
|
||||
name: "MetaDynamicResource",
|
||||
aCfg: &utils.APAction{Type: utils.MetaDynamicResource},
|
||||
},
|
||||
{
|
||||
name: "MetaDynamicTrend",
|
||||
aCfg: &utils.APAction{Type: utils.MetaDynamicTrend},
|
||||
},
|
||||
{
|
||||
name: "MetaDynamicRanking",
|
||||
aCfg: &utils.APAction{Type: utils.MetaDynamicRanking},
|
||||
},
|
||||
{
|
||||
name: "MetaDynamicFilter",
|
||||
aCfg: &utils.APAction{Type: utils.MetaDynamicFilter},
|
||||
},
|
||||
{
|
||||
name: "MetaDynamicRoute",
|
||||
aCfg: &utils.APAction{Type: utils.MetaDynamicRoute},
|
||||
},
|
||||
{
|
||||
name: "MetaDynamicRate",
|
||||
aCfg: &utils.APAction{Type: utils.MetaDynamicRate},
|
||||
},
|
||||
{
|
||||
name: "MetaDynamicIP",
|
||||
aCfg: &utils.APAction{Type: utils.MetaDynamicIP},
|
||||
},
|
||||
{
|
||||
name: "MetaDynamicAction",
|
||||
aCfg: &utils.APAction{Type: utils.MetaDynamicAction},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
act, err := newActioner(ctx, cgrEv, cfg, fltr, dm, connMgr, tt.aCfg, tnt)
|
||||
if tt.wantErr != "" {
|
||||
if err == nil || err.Error() != tt.wantErr {
|
||||
t.Errorf("Expected error: %q, got: %v", tt.wantErr, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
return
|
||||
}
|
||||
if act == nil {
|
||||
t.Errorf("Expected non-nil action, got nil")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user