From bfa3fb7a4ce8bc06569afc8d84e61913ad7c551b Mon Sep 17 00:00:00 2001 From: ionutboangiu Date: Wed, 2 Jun 2021 16:57:39 +0300 Subject: [PATCH] Fix integration tests in apis after changing GetAttrForEvent reply type --- apis/attributes.go | 2 +- apis/attributes_it_test.go | 37 +- apis/attributes_test.go | 12 +- apis/filter_update_it_test.go | 412 ----------------- .../fltr_update_e1_mongo/cgrates.json | 2 +- .../fltr_update_e1_mysql/cgrates.json | 2 +- engine/attributes.go | 4 +- general_tests/cgrloader_it_test.go | 1 + general_tests/filter_update_it_test.go | 413 ++++++++++++++++++ general_tests/libtest.go | 8 +- 10 files changed, 442 insertions(+), 451 deletions(-) delete mode 100644 apis/filter_update_it_test.go create mode 100644 general_tests/filter_update_it_test.go diff --git a/apis/attributes.go b/apis/attributes.go index b8e1773ab..41a576b01 100644 --- a/apis/attributes.go +++ b/apis/attributes.go @@ -154,7 +154,7 @@ type AttributeSv1 struct { // GetAttributeForEvent returns matching AttributeProfile for Event func (alSv1 *AttributeSv1) GetAttributeForEvent(ctx *context.Context, args *engine.AttrArgsProcessEvent, - reply *engine.AttributeProfile) (err error) { + reply *engine.APIAttributeProfile) (err error) { return alSv1.attrS.V1GetAttributeForEvent(ctx, args, reply) } diff --git a/apis/attributes_it_test.go b/apis/attributes_it_test.go index df8131969..684c4fcaa 100644 --- a/apis/attributes_it_test.go +++ b/apis/attributes_it_test.go @@ -436,27 +436,25 @@ func testAttributeSGetAttributeForEventAnyContext(t *testing.T) { if !reflect.DeepEqual(eAttrPrf2.APIAttributeProfile, reply) { t.Errorf("Expecting : %+v, received: %+v", eAttrPrf2.APIAttributeProfile, reply) } - var attrReply *engine.AttributeProfile + var attrReply *engine.APIAttributeProfile if err := attrSRPC.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, ev, &attrReply); err != nil { t.Fatal(err) } - expAttrFromEv := &engine.AttributeProfile{ + expAttrFromEv := &engine.APIAttributeProfile{ Tenant: ev.Tenant, ID: "ATTR_2", FilterIDs: []string{"*string:~*req.Account:dan"}, - Attributes: []*engine.Attribute{ + Attributes: []*engine.ExternalAttribute{ { Path: utils.MetaReq + utils.NestingSep + utils.AccountField, Type: utils.MetaConstant, - Value: config.NewRSRParsersMustCompile("1001", utils.InfieldSep), + Value: "1001", }, }, Weight: 10.0, } - expAttrFromEv.Compile() - attrReply.Compile() if !reflect.DeepEqual(expAttrFromEv, attrReply) { t.Errorf("Expecting: %s, received: %s", utils.ToJSON(expAttrFromEv), utils.ToJSON(attrReply)) } @@ -473,27 +471,25 @@ func testAttributeSGetAttributeForEventSameAnyContext(t *testing.T) { }, }, } - var attrReply *engine.AttributeProfile + var attrReply *engine.APIAttributeProfile if err := attrSRPC.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, ev, &attrReply); err != nil { t.Fatal(err) } - expAttrFromEv := &engine.AttributeProfile{ + expAttrFromEv := &engine.APIAttributeProfile{ Tenant: ev.Tenant, ID: "ATTR_2", FilterIDs: []string{"*string:~*req.Account:dan"}, - Attributes: []*engine.Attribute{ + Attributes: []*engine.ExternalAttribute{ { Path: utils.MetaReq + utils.NestingSep + utils.AccountField, Type: utils.MetaConstant, - Value: config.NewRSRParsersMustCompile("1001", utils.InfieldSep), + Value: "1001", }, }, Weight: 10.0, } - expAttrFromEv.Compile() - attrReply.Compile() if !reflect.DeepEqual(expAttrFromEv, attrReply) { t.Errorf("Expecting: %s, received: %s", utils.ToJSON(expAttrFromEv), utils.ToJSON(attrReply)) } @@ -513,7 +509,7 @@ func testAttributeSGetAttributeForEventNotFound(t *testing.T) { }, }, } - var attrReply *engine.AttributeProfile + var attrReply *engine.APIAttributeProfile if err := attrSRPC.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, ev, &attrReply); err == nil || err.Error() != utils.ErrNotFound.Error() { t.Error(err) @@ -535,20 +531,20 @@ func testAttributeSGetAttributeForEvent(t *testing.T) { }, } - eAttrPrf := &engine.AttributeProfile{ + eAttrPrf := &engine.APIAttributeProfile{ Tenant: ev.Tenant, ID: "ATTR_1", FilterIDs: []string{"*string:~*req.Account:1007", "*string:~*opts.*context:*cdrs|*sessions"}, - Attributes: []*engine.Attribute{ + Attributes: []*engine.ExternalAttribute{ { Path: utils.MetaReq + utils.NestingSep + utils.AccountField, - Value: config.NewRSRParsersMustCompile("1001", utils.InfieldSep), + Value: "1001", Type: utils.MetaConstant, FilterIDs: []string{}, }, { Path: utils.MetaReq + utils.NestingSep + utils.Subject, - Value: config.NewRSRParsersMustCompile("1001", utils.InfieldSep), + Value: "1001", Type: utils.MetaConstant, FilterIDs: []string{}, }, @@ -589,26 +585,23 @@ func testAttributeSGetAttributeForEvent(t *testing.T) { t.Error("Unexpected reply returned", result) } - var attrReply *engine.AttributeProfile + var attrReply *engine.APIAttributeProfile if err := attrSRPC.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, ev, &attrReply); err != nil { t.Fatal(err) } - attrReply.Compile() - eAttrPrf.Compile() if !reflect.DeepEqual(eAttrPrf, attrReply) { t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eAttrPrf), utils.ToJSON(attrReply)) } ev.Tenant = utils.EmptyString ev.ID = "randomID" - var attrPrf *engine.AttributeProfile + var attrPrf *engine.APIAttributeProfile if err := attrSRPC.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, ev, &attrPrf); err != nil { t.Fatal(err) } - attrPrf.Compile() // Populate private variables in RSRParsers if !reflect.DeepEqual(eAttrPrf, attrPrf) { t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eAttrPrf), utils.ToJSON(attrPrf)) diff --git a/apis/attributes_test.go b/apis/attributes_test.go index b01017765..f1bfab738 100644 --- a/apis/attributes_test.go +++ b/apis/attributes_test.go @@ -492,21 +492,17 @@ func TestAttributesGetAttributeForEvent(t *testing.T) { }, }, } - var reply engine.AttributeProfile + var reply engine.APIAttributeProfile - rsr, err := config.NewRSRParsers(utils.MetaPrepaid, utils.InInFieldSep) - if err != nil { - t.Error(err) - } - expAttrPrf := &engine.AttributeProfile{ + expAttrPrf := &engine.APIAttributeProfile{ Tenant: "cgrates.org", ID: "TestGetAttributeProfile", FilterIDs: []string{"*string:~*req.Account:1002"}, - Attributes: []*engine.Attribute{ + Attributes: []*engine.ExternalAttribute{ { Path: "*req.RequestType", Type: utils.MetaConstant, - Value: rsr, + Value: utils.MetaPrepaid, }, }, } diff --git a/apis/filter_update_it_test.go b/apis/filter_update_it_test.go deleted file mode 100644 index 9eb7b1add..000000000 --- a/apis/filter_update_it_test.go +++ /dev/null @@ -1,412 +0,0 @@ -// +build integration - -/* -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 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 General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see -*/ - -package apis - -// var ( -// fltrUpdateCfgPath1, fltrUpdateCfgPath2 string -// fltrUpdateCfgDIR1, fltrUpdateCfgDIR2 string -// fltrUpdateCfg1, fltrUpdateCfg2 *config.CGRConfig -// fltrUpdateRPC1, fltrUpdateRPC2 *birpc.Client -// testEng1 *exec.Cmd -// sTestsFilterUpdate = []func(t *testing.T){ -// testFilterUpdateInitCfg, -// testFilterUpdateResetDB, -// testFilterUpdateStartEngine, -// testFilterUpdateRpcConn, -// testFilterUpdateSetFilterE1, -// testFilterUpdateSetAttrProfileE1, -// testFilterUpdateGetAttrProfileForEventEv1E1, -// testFilterUpdateGetAttrProfileForEventEv1E2, -// testFilterUpdateGetAttrProfileForEventEv2E1NotMatching, -// testFilterUpdateGetAttrProfileForEventEv2E2NotMatching, -// testFilterUpdateSetFilterAfterAttrE1, -// testFilterUpdateGetAttrProfileForEventEv1E1NotMatching, -// testFilterUpdateGetAttrProfileForEventEv1E2NotMatching, -// testFilterUpdateGetAttrProfileForEventEv2E1, -// testFilterUpdateGetAttrProfileForEventEv2E2, -// testFilterUpdateStopEngine, -// } -// ev1 = &utils.CGREvent{ -// Tenant: "cgrates.org", -// ID: "Event1", -// Event: map[string]interface{}{ -// utils.AccountField: "1001", -// }, -// } -// ev2 = &utils.CGREvent{ -// Tenant: "cgrates.org", -// ID: "Event2", -// Event: map[string]interface{}{ -// utils.AccountField: "1002", -// }, -// } -// ) - -// func TestFilterUpdateIT(t *testing.T) { -// switch *dbType { -// case utils.MetaInternal: -// t.SkipNow() -// case utils.MetaMySQL: -// fltrUpdateCfgDIR1 = "fltr_update_e1_mysql" -// fltrUpdateCfgDIR2 = "tutmysql" -// case utils.MetaMongo: -// fltrUpdateCfgDIR1 = "fltr_update_e1_mongo" -// fltrUpdateCfgDIR2 = "tutmongo" -// case utils.MetaPostgres: -// t.SkipNow() -// default: -// t.Fatal("Unknown Database type") -// } - -// for _, stest1 := range sTestsFilterUpdate { -// t.Run(*dbType, stest1) -// } -// } - -// //Init Config -// func testFilterUpdateInitCfg(t *testing.T) { -// var err error -// fltrUpdateCfgPath1 = path.Join(*dataDir, "conf", "samples", "cache_replicate", fltrUpdateCfgDIR1) -// if fltrUpdateCfg1, err = config.NewCGRConfigFromPath(fltrUpdateCfgPath1); err != nil { -// t.Fatal(err) -// } -// fltrUpdateCfgPath2 = path.Join(*dataDir, "conf", "samples", fltrUpdateCfgDIR2) -// if fltrUpdateCfg2, err = config.NewCGRConfigFromPath(fltrUpdateCfgPath2); err != nil { -// t.Fatal(err) -// } -// } - -// // Remove data in both rating and accounting db -// func testFilterUpdateResetDB(t *testing.T) { -// if err := engine.InitDataDB(fltrUpdateCfg1); err != nil { -// t.Fatal(err) -// } -// if err := engine.InitStorDB(fltrUpdateCfg1); err != nil { -// t.Fatal(err) -// } -// } - -// // Start CGR Engine -// func testFilterUpdateStartEngine(t *testing.T) { -// var err error -// if _, err = engine.StopStartEngine(fltrUpdateCfgPath1, *waitRater); err != nil { -// t.Fatal(err) -// } -// if testEng1, err = engine.StartEngine(fltrUpdateCfgPath2, *waitRater); err != nil { -// t.Fatal(err) -// } - -// } - -// // Connect rpc client to rater -// func testFilterUpdateRpcConn(t *testing.T) { -// var err error -// if fltrUpdateRPC1, err = newRPCClient(fltrUpdateCfg1.ListenCfg()); err != nil { -// t.Fatal(err) -// } -// if fltrUpdateRPC2, err = newRPCClient(fltrUpdateCfg2.ListenCfg()); err != nil { -// t.Fatal(err) -// } -// } - -// func testFilterUpdateStopEngine(t *testing.T) { -// if err := engine.KillEngine(100); err != nil { -// t.Error(err) -// } -// } - -// func testFilterUpdateSetFilterE1(t *testing.T) { -// fltr := &engine.FilterWithAPIOpts{ -// Filter: &engine.Filter{ -// ID: "FLTR_ID", -// Tenant: "cgrates.org", -// Rules: []*engine.FilterRule{ -// { -// Type: utils.MetaString, -// Element: "~*req.Account", -// Values: []string{"1001"}, -// }, -// }, -// }, -// APIOpts: map[string]interface{}{ -// utils.CacheOpt: utils.MetaLoad, -// }, -// } - -// var reply string -// if err := fltrUpdateRPC1.Call(context.Background(), utils.AdminSv1SetFilter, fltr, &reply); err != nil { -// t.Error(err) -// } else if reply != utils.OK { -// t.Error("Unexpected reply returned", reply) -// } - -// var result *engine.Filter -// if err := fltrUpdateRPC1.Call(context.Background(), utils.AdminSv1GetFilter, -// &utils.TenantID{Tenant: "cgrates.org", ID: "FLTR_ID"}, &result); err != nil { -// t.Error(err) -// } else if !reflect.DeepEqual(fltr.Filter, result) { -// t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(fltr.Filter), utils.ToJSON(result)) -// } -// } - -// func testFilterUpdateSetAttrProfileE1(t *testing.T) { -// attrPrf := &engine.AttributeProfileWithAPIOpts{ -// AttributeProfile: &engine.AttributeProfile{ -// FilterIDs: []string{"FLTR_ID"}, -// ID: "ATTR_ID", -// Tenant: "cgrates.org", -// Weight: 10, -// Attributes: []*engine.Attribute{ -// { -// Path: "*req.Account", -// Value: config.NewRSRParsersMustCompile("1003", ";"), -// Type: utils.MetaConstant, -// }, -// }, -// }, -// APIOpts: map[string]interface{}{ -// utils.CacheOpt: utils.MetaNone, -// }, -// } - -// attrPrf.Compile() -// var reply string -// if err := fltrUpdateRPC1.Call(context.Background(), utils.AdminSv1SetAttributeProfile, attrPrf, &reply); err != nil { -// t.Error(err) -// } else if reply != utils.OK { -// t.Error("Unexpected reply returned", reply) -// } -// var result *engine.AttributeProfile -// if err := fltrUpdateRPC1.Call(context.Background(), utils.AdminSv1GetAttributeProfile, -// utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: "ATTR_ID"}}, &result); err != nil { -// t.Fatal(err) -// } -// result.Compile() -// if !reflect.DeepEqual(attrPrf.AttributeProfile, result) { -// t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(attrPrf.AttributeProfile), utils.ToJSON(result)) -// } -// } - -// func testFilterUpdateGetAttrProfileForEventEv1E1(t *testing.T) { -// attrProcessEv := &engine.AttrArgsProcessEvent{ -// CGREvent: ev1, -// } - -// eAttrPrf := &engine.AttributeProfile{ -// Tenant: "cgrates.org", -// FilterIDs: []string{"FLTR_ID"}, -// ID: "ATTR_ID", -// Weight: 10, -// Attributes: []*engine.Attribute{ -// { -// Path: "*req.Account", -// Value: config.NewRSRParsersMustCompile("1003", ";"), -// Type: utils.MetaConstant, -// }, -// }, -// } - -// eAttrPrf.Compile() -// var attrReply *engine.AttributeProfile -// if err := fltrUpdateRPC1.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, -// attrProcessEv, &attrReply); err != nil { -// t.Fatal(err) -// } -// attrReply.Compile() // Populate private variables in RSRParsers -// if !reflect.DeepEqual(eAttrPrf, attrReply) { -// t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(eAttrPrf), utils.ToJSON(attrReply)) -// } -// } - -// func testFilterUpdateGetAttrProfileForEventEv1E2(t *testing.T) { -// attrProcessEv := &engine.AttrArgsProcessEvent{ -// CGREvent: ev1, -// } - -// eAttrPrf := &engine.AttributeProfile{ -// Tenant: "cgrates.org", -// FilterIDs: []string{"FLTR_ID"}, -// ID: "ATTR_ID", -// Weight: 10, -// Attributes: []*engine.Attribute{ -// { -// Path: "*req.Account", -// Value: config.NewRSRParsersMustCompile("1003", ";"), -// Type: utils.MetaConstant, -// }, -// }, -// } - -// eAttrPrf.Compile() -// var attrReply *engine.AttributeProfile -// if err := fltrUpdateRPC2.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, -// attrProcessEv, &attrReply); err != nil { -// t.Fatal(err) -// } -// attrReply.Compile() // Populate private variables in RSRParsers -// if !reflect.DeepEqual(eAttrPrf, attrReply) { -// t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(eAttrPrf), utils.ToJSON(attrReply)) -// } -// } - -// func testFilterUpdateGetAttrProfileForEventEv2E1(t *testing.T) { -// attrProcessEv := &engine.AttrArgsProcessEvent{ -// CGREvent: ev2, -// } - -// eAttrPrf := &engine.AttributeProfile{ -// Tenant: "cgrates.org", -// FilterIDs: []string{"FLTR_ID"}, -// ID: "ATTR_ID", -// Weight: 10, -// Attributes: []*engine.Attribute{ -// { -// Path: "*req.Account", -// Value: config.NewRSRParsersMustCompile("1003", ";"), -// Type: utils.MetaConstant, -// }, -// }, -// } - -// eAttrPrf.Compile() -// var attrReply *engine.AttributeProfile -// if err := fltrUpdateRPC1.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, -// attrProcessEv, &attrReply); err != nil { -// t.Fatal(err) -// } -// attrReply.Compile() // Populate private variables in RSRParsers -// if !reflect.DeepEqual(eAttrPrf, attrReply) { -// t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(eAttrPrf), utils.ToJSON(attrReply)) -// } -// } - -// func testFilterUpdateGetAttrProfileForEventEv2E2(t *testing.T) { -// attrProcessEv := &engine.AttrArgsProcessEvent{ -// CGREvent: ev2, -// } - -// eAttrPrf := &engine.AttributeProfile{ -// Tenant: "cgrates.org", -// FilterIDs: []string{"FLTR_ID"}, -// ID: "ATTR_ID", -// Weight: 10, -// Attributes: []*engine.Attribute{ -// { -// Path: "*req.Account", -// Value: config.NewRSRParsersMustCompile("1003", ";"), -// Type: utils.MetaConstant, -// }, -// }, -// } - -// eAttrPrf.Compile() -// var attrReply *engine.AttributeProfile -// if err := fltrUpdateRPC2.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, -// attrProcessEv, &attrReply); err != nil { -// t.Fatal(err) -// } -// attrReply.Compile() // Populate private variables in RSRParsers -// if !reflect.DeepEqual(eAttrPrf, attrReply) { -// t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(eAttrPrf), utils.ToJSON(attrReply)) -// } -// } - -// func testFilterUpdateSetFilterAfterAttrE1(t *testing.T) { -// fltr := &engine.FilterWithAPIOpts{ -// Filter: &engine.Filter{ -// ID: "FLTR_ID", -// Tenant: "cgrates.org", -// Rules: []*engine.FilterRule{ -// { -// Type: utils.MetaString, -// Element: "~*req.Account", -// Values: []string{"1002"}, -// }, -// }, -// }, -// APIOpts: map[string]interface{}{ -// utils.CacheOpt: utils.MetaLoad, -// }, -// } - -// var reply string -// if err := fltrUpdateRPC1.Call(context.Background(), utils.AdminSv1SetFilter, fltr, &reply); err != nil { -// t.Error(err) -// } else if reply != utils.OK { -// t.Error("Unexpected reply returned", reply) -// } - -// var result *engine.Filter -// if err := fltrUpdateRPC1.Call(context.Background(), utils.AdminSv1GetFilter, -// &utils.TenantID{Tenant: "cgrates.org", ID: "FLTR_ID"}, &result); err != nil { -// t.Error(err) -// } else if !reflect.DeepEqual(fltr.Filter, result) { -// t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(fltr.Filter), utils.ToJSON(result)) -// } -// } - -// func testFilterUpdateGetAttrProfileForEventEv1E1NotMatching(t *testing.T) { -// attrProcessEv := &engine.AttrArgsProcessEvent{ -// CGREvent: ev1, -// } - -// var attrReply *engine.AttributeProfile -// if err := fltrUpdateRPC1.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, -// attrProcessEv, &attrReply); err == nil || err.Error() != utils.ErrNotFound.Error() { -// t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) -// } -// } - -// func testFilterUpdateGetAttrProfileForEventEv1E2NotMatching(t *testing.T) { -// attrProcessEv := &engine.AttrArgsProcessEvent{ -// CGREvent: ev1, -// } - -// var attrReply *engine.AttributeProfile -// if err := fltrUpdateRPC2.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, -// attrProcessEv, &attrReply); err == nil || err.Error() != utils.ErrNotFound.Error() { -// t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) -// } -// } - -// func testFilterUpdateGetAttrProfileForEventEv2E1NotMatching(t *testing.T) { -// attrProcessEv := &engine.AttrArgsProcessEvent{ -// CGREvent: ev2, -// } - -// var attrReply *engine.AttributeProfile -// if err := fltrUpdateRPC1.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, -// attrProcessEv, &attrReply); err == nil || err.Error() != utils.ErrNotFound.Error() { -// t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) -// } -// } - -// func testFilterUpdateGetAttrProfileForEventEv2E2NotMatching(t *testing.T) { -// attrProcessEv := &engine.AttrArgsProcessEvent{ -// CGREvent: ev2, -// } - -// var attrReply *engine.AttributeProfile -// if err := fltrUpdateRPC2.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, -// attrProcessEv, &attrReply); err == nil || err.Error() != utils.ErrNotFound.Error() { -// t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) -// } -// } diff --git a/data/conf/samples/cache_replicate/fltr_update_e1_mongo/cgrates.json b/data/conf/samples/cache_replicate/fltr_update_e1_mongo/cgrates.json index 510e53bbb..6c3e9101e 100644 --- a/data/conf/samples/cache_replicate/fltr_update_e1_mongo/cgrates.json +++ b/data/conf/samples/cache_replicate/fltr_update_e1_mongo/cgrates.json @@ -40,7 +40,7 @@ "enabled": true }, - "apiers": { + "admins": { "enabled": true, "caches_conns":["cache_conn"], }, diff --git a/data/conf/samples/cache_replicate/fltr_update_e1_mysql/cgrates.json b/data/conf/samples/cache_replicate/fltr_update_e1_mysql/cgrates.json index 24b9310d7..447c9e5d6 100644 --- a/data/conf/samples/cache_replicate/fltr_update_e1_mysql/cgrates.json +++ b/data/conf/samples/cache_replicate/fltr_update_e1_mysql/cgrates.json @@ -36,7 +36,7 @@ "enabled": true }, - "apiers": { + "admins": { "enabled": true, "caches_conns":["cache_conn"], }, diff --git a/engine/attributes.go b/engine/attributes.go index b8796bbfb..a6a6c4383 100644 --- a/engine/attributes.go +++ b/engine/attributes.go @@ -231,7 +231,7 @@ func (alS *AttributeService) processEvent(ctx *context.Context, tnt string, args // V1GetAttributeForEvent returns the AttributeProfile that matches the event func (alS *AttributeService) V1GetAttributeForEvent(ctx *context.Context, args *AttrArgsProcessEvent, - attrPrfl *AttributeProfile) (err error) { + attrPrfl *APIAttributeProfile) (err error) { if args.CGREvent == nil { return utils.NewErrMandatoryIeMissing(utils.CGREventString) } @@ -252,7 +252,7 @@ func (alS *AttributeService) V1GetAttributeForEvent(ctx *context.Context, args * } return err } - *attrPrfl = *attrPrf + *attrPrfl = *(NewAPIAttributeProfile(attrPrf)) return } diff --git a/general_tests/cgrloader_it_test.go b/general_tests/cgrloader_it_test.go index eff34c5a9..867208e23 100644 --- a/general_tests/cgrloader_it_test.go +++ b/general_tests/cgrloader_it_test.go @@ -1,4 +1,5 @@ // +build integration + /* Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments Copyright (C) ITsysCOM GmbH diff --git a/general_tests/filter_update_it_test.go b/general_tests/filter_update_it_test.go new file mode 100644 index 000000000..dab408f45 --- /dev/null +++ b/general_tests/filter_update_it_test.go @@ -0,0 +1,413 @@ +/* +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 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package general_tests + +import ( + "os/exec" + "path" + "reflect" + "testing" + + "github.com/cgrates/birpc" + "github.com/cgrates/birpc/context" + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" +) + +var ( + fltrUpdateCfgPath1, fltrUpdateCfgPath2 string + fltrUpdateCfgDIR1, fltrUpdateCfgDIR2 string + fltrUpdateCfg1, fltrUpdateCfg2 *config.CGRConfig + fltrUpdateRPC1, fltrUpdateRPC2 *birpc.Client + testEng1 *exec.Cmd + sTestsFilterUpdate = []func(t *testing.T){ + testFilterUpdateInitCfg, + testFilterUpdateResetDB, + testFilterUpdateStartEngine, + testFilterUpdateRpcConn, + testFilterUpdateSetFilterE1, + testFilterUpdateSetAttrProfileE1, + testFilterUpdateGetAttrProfileForEventEv1E1, + testFilterUpdateGetAttrProfileForEventEv1E2, + testFilterUpdateGetAttrProfileForEventEv2E1NotMatching, + testFilterUpdateGetAttrProfileForEventEv2E2NotMatching, + testFilterUpdateSetFilterAfterAttrE1, + testFilterUpdateGetAttrProfileForEventEv1E1NotMatching, + testFilterUpdateGetAttrProfileForEventEv1E2NotMatching, + testFilterUpdateGetAttrProfileForEventEv2E1, + testFilterUpdateGetAttrProfileForEventEv2E2, + testFilterUpdateStopEngine, + } + ev1 = &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "Event1", + Event: map[string]interface{}{ + utils.AccountField: "1001", + }, + } + ev2 = &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "Event2", + Event: map[string]interface{}{ + utils.AccountField: "1002", + }, + } +) + +func TestFilterUpdateIT(t *testing.T) { + switch *dbType { + case utils.MetaInternal: + t.SkipNow() + case utils.MetaMySQL: + fltrUpdateCfgDIR1 = "fltr_update_e1_mysql" + fltrUpdateCfgDIR2 = "tutmysql" + case utils.MetaMongo: + fltrUpdateCfgDIR1 = "fltr_update_e1_mongo" + fltrUpdateCfgDIR2 = "tutmongo" + case utils.MetaPostgres: + t.SkipNow() + default: + t.Fatal("Unknown Database type") + } + + for _, stest1 := range sTestsFilterUpdate { + t.Run(*dbType, stest1) + } +} + +//Init Config +func testFilterUpdateInitCfg(t *testing.T) { + var err error + fltrUpdateCfgPath1 = path.Join(*dataDir, "conf", "samples", "cache_replicate", fltrUpdateCfgDIR1) + if fltrUpdateCfg1, err = config.NewCGRConfigFromPath(fltrUpdateCfgPath1); err != nil { + t.Fatal(err) + } + fltrUpdateCfgPath2 = path.Join(*dataDir, "conf", "samples", fltrUpdateCfgDIR2) + if fltrUpdateCfg2, err = config.NewCGRConfigFromPath(fltrUpdateCfgPath2); err != nil { + t.Fatal(err) + } +} + +// Remove data in both rating and accounting db +func testFilterUpdateResetDB(t *testing.T) { + if err := engine.InitDataDB(fltrUpdateCfg1); err != nil { + t.Fatal(err) + } + if err := engine.InitStorDB(fltrUpdateCfg1); err != nil { + t.Fatal(err) + } +} + +// Start CGR Engine +func testFilterUpdateStartEngine(t *testing.T) { + var err error + if _, err = engine.StopStartEngine(fltrUpdateCfgPath1, *waitRater); err != nil { + t.Fatal(err) + } + if testEng1, err = engine.StartEngine(fltrUpdateCfgPath2, *waitRater); err != nil { + t.Fatal(err) + } + +} + +// Connect rpc client to rater +func testFilterUpdateRpcConn(t *testing.T) { + var err error + if fltrUpdateRPC1, err = newRPCClient(fltrUpdateCfg1.ListenCfg()); err != nil { + t.Fatal(err) + } + if fltrUpdateRPC2, err = newRPCClient(fltrUpdateCfg2.ListenCfg()); err != nil { + t.Fatal(err) + } +} + +func testFilterUpdateStopEngine(t *testing.T) { + if err := engine.KillEngine(100); err != nil { + t.Error(err) + } +} + +func testFilterUpdateSetFilterE1(t *testing.T) { + fltr := &engine.FilterWithAPIOpts{ + Filter: &engine.Filter{ + ID: "FLTR_ID", + Tenant: "cgrates.org", + Rules: []*engine.FilterRule{ + { + Type: utils.MetaString, + Element: "~*req.Account", + Values: []string{"1001"}, + }, + }, + }, + APIOpts: map[string]interface{}{ + utils.CacheOpt: utils.MetaLoad, + }, + } + + var reply string + if err := fltrUpdateRPC1.Call(context.Background(), utils.AdminSv1SetFilter, fltr, &reply); err != nil { + t.Error(err) + } else if reply != utils.OK { + t.Error("Unexpected reply returned", reply) + } + + var result *engine.Filter + if err := fltrUpdateRPC1.Call(context.Background(), utils.AdminSv1GetFilter, + &utils.TenantID{Tenant: "cgrates.org", ID: "FLTR_ID"}, &result); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(fltr.Filter, result) { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(fltr.Filter), utils.ToJSON(result)) + } +} + +func testFilterUpdateSetAttrProfileE1(t *testing.T) { + attrPrf := &engine.APIAttributeProfileWithAPIOpts{ + APIAttributeProfile: &engine.APIAttributeProfile{ + FilterIDs: []string{"FLTR_ID"}, + ID: "ATTR_ID", + Tenant: "cgrates.org", + Weight: 10, + Attributes: []*engine.ExternalAttribute{ + { + Path: "*req.Account", + Value: "1003", + Type: utils.MetaConstant, + }, + }, + }, + APIOpts: map[string]interface{}{ + utils.CacheOpt: utils.MetaNone, + }, + } + + var reply string + if err := fltrUpdateRPC1.Call(context.Background(), utils.AdminSv1SetAttributeProfile, attrPrf, &reply); err != nil { + t.Error(err) + } else if reply != utils.OK { + t.Error("Unexpected reply returned", reply) + } + var result *engine.APIAttributeProfile + if err := fltrUpdateRPC1.Call(context.Background(), utils.AdminSv1GetAttributeProfile, + utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: "ATTR_ID"}}, &result); err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(attrPrf.APIAttributeProfile, result) { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(attrPrf.APIAttributeProfile), utils.ToJSON(result)) + } +} + +func testFilterUpdateGetAttrProfileForEventEv1E1(t *testing.T) { + attrProcessEv := &engine.AttrArgsProcessEvent{ + CGREvent: ev1, + } + + eAttrPrf := &engine.APIAttributeProfile{ + Tenant: "cgrates.org", + FilterIDs: []string{"FLTR_ID"}, + ID: "ATTR_ID", + Weight: 10, + Attributes: []*engine.ExternalAttribute{ + { + Path: "*req.Account", + Value: "1003", + Type: utils.MetaConstant, + }, + }, + } + + var attrReply *engine.APIAttributeProfile + if err := fltrUpdateRPC1.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, + attrProcessEv, &attrReply); err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(eAttrPrf, attrReply) { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(eAttrPrf), utils.ToJSON(attrReply)) + } +} + +func testFilterUpdateGetAttrProfileForEventEv1E2(t *testing.T) { + attrProcessEv := &engine.AttrArgsProcessEvent{ + CGREvent: ev1, + } + + eAttrPrf := &engine.APIAttributeProfile{ + Tenant: "cgrates.org", + FilterIDs: []string{"FLTR_ID"}, + ID: "ATTR_ID", + Weight: 10, + Attributes: []*engine.ExternalAttribute{ + { + Path: "*req.Account", + Value: "1003", + Type: utils.MetaConstant, + }, + }, + } + + var attrReply *engine.APIAttributeProfile + if err := fltrUpdateRPC2.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, + attrProcessEv, &attrReply); err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(eAttrPrf, attrReply) { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(eAttrPrf), utils.ToJSON(attrReply)) + } +} + +func testFilterUpdateGetAttrProfileForEventEv2E1(t *testing.T) { + attrProcessEv := &engine.AttrArgsProcessEvent{ + CGREvent: ev2, + } + + eAttrPrf := &engine.APIAttributeProfile{ + Tenant: "cgrates.org", + FilterIDs: []string{"FLTR_ID"}, + ID: "ATTR_ID", + Weight: 10, + Attributes: []*engine.ExternalAttribute{ + { + Path: "*req.Account", + Value: "1003", + Type: utils.MetaConstant, + }, + }, + } + + var attrReply *engine.APIAttributeProfile + if err := fltrUpdateRPC1.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, + attrProcessEv, &attrReply); err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(eAttrPrf, attrReply) { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(eAttrPrf), utils.ToJSON(attrReply)) + } +} + +func testFilterUpdateGetAttrProfileForEventEv2E2(t *testing.T) { + attrProcessEv := &engine.AttrArgsProcessEvent{ + CGREvent: ev2, + } + + eAttrPrf := &engine.APIAttributeProfile{ + Tenant: "cgrates.org", + FilterIDs: []string{"FLTR_ID"}, + ID: "ATTR_ID", + Weight: 10, + Attributes: []*engine.ExternalAttribute{ + { + Path: "*req.Account", + Value: "1003", + Type: utils.MetaConstant, + }, + }, + } + + var attrReply *engine.APIAttributeProfile + if err := fltrUpdateRPC2.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, + attrProcessEv, &attrReply); err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(eAttrPrf, attrReply) { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(eAttrPrf), utils.ToJSON(attrReply)) + } +} + +func testFilterUpdateSetFilterAfterAttrE1(t *testing.T) { + fltr := &engine.FilterWithAPIOpts{ + Filter: &engine.Filter{ + ID: "FLTR_ID", + Tenant: "cgrates.org", + Rules: []*engine.FilterRule{ + { + Type: utils.MetaString, + Element: "~*req.Account", + Values: []string{"1002"}, + }, + }, + }, + APIOpts: map[string]interface{}{ + utils.CacheOpt: utils.MetaLoad, + }, + } + + var reply string + if err := fltrUpdateRPC1.Call(context.Background(), utils.AdminSv1SetFilter, fltr, &reply); err != nil { + t.Error(err) + } else if reply != utils.OK { + t.Error("Unexpected reply returned", reply) + } + + var result *engine.Filter + if err := fltrUpdateRPC1.Call(context.Background(), utils.AdminSv1GetFilter, + &utils.TenantID{Tenant: "cgrates.org", ID: "FLTR_ID"}, &result); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(fltr.Filter, result) { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(fltr.Filter), utils.ToJSON(result)) + } +} + +func testFilterUpdateGetAttrProfileForEventEv1E1NotMatching(t *testing.T) { + attrProcessEv := &engine.AttrArgsProcessEvent{ + CGREvent: ev1, + } + + var attrReply *engine.APIAttributeProfile + if err := fltrUpdateRPC1.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, + attrProcessEv, &attrReply); err == nil || err.Error() != utils.ErrNotFound.Error() { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) + } +} + +func testFilterUpdateGetAttrProfileForEventEv1E2NotMatching(t *testing.T) { + attrProcessEv := &engine.AttrArgsProcessEvent{ + CGREvent: ev1, + } + + var attrReply *engine.APIAttributeProfile + if err := fltrUpdateRPC2.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, + attrProcessEv, &attrReply); err == nil || err.Error() != utils.ErrNotFound.Error() { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) + } +} + +func testFilterUpdateGetAttrProfileForEventEv2E1NotMatching(t *testing.T) { + attrProcessEv := &engine.AttrArgsProcessEvent{ + CGREvent: ev2, + } + + var attrReply *engine.APIAttributeProfile + if err := fltrUpdateRPC1.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, + attrProcessEv, &attrReply); err == nil || err.Error() != utils.ErrNotFound.Error() { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) + } +} + +func testFilterUpdateGetAttrProfileForEventEv2E2NotMatching(t *testing.T) { + attrProcessEv := &engine.AttrArgsProcessEvent{ + CGREvent: ev2, + } + + var attrReply *engine.APIAttributeProfile + if err := fltrUpdateRPC2.Call(context.Background(), utils.AttributeSv1GetAttributeForEvent, + attrProcessEv, &attrReply); err == nil || err.Error() != utils.ErrNotFound.Error() { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) + } +} diff --git a/general_tests/libtest.go b/general_tests/libtest.go index d8944e709..acad0d51d 100644 --- a/general_tests/libtest.go +++ b/general_tests/libtest.go @@ -20,9 +20,9 @@ package general_tests import ( "errors" "flag" - "net/rpc" - "net/rpc/jsonrpc" + "github.com/cgrates/birpc" + "github.com/cgrates/birpc/jsonrpc" "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/utils" ) @@ -35,12 +35,12 @@ var ( err error ) -func newRPCClient(cfg *config.ListenCfg) (c *rpc.Client, err error) { +func newRPCClient(cfg *config.ListenCfg) (c *birpc.Client, err error) { switch *encoding { case utils.MetaJSON: return jsonrpc.Dial(utils.TCP, cfg.RPCJSONListen) case utils.MetaGOB: - return rpc.Dial(utils.TCP, cfg.RPCGOBListen) + return birpc.Dial(utils.TCP, cfg.RPCGOBListen) default: return nil, errors.New("UNSUPPORTED_RPC") }