diff --git a/apis/attributes_it_test.go b/apis/attributes_it_test.go index df8144492..ae1e8977c 100644 --- a/apis/attributes_it_test.go +++ b/apis/attributes_it_test.go @@ -1,3 +1,5 @@ +// +build integration + /* Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments Copyright (C) ITsysCOM GmbH @@ -17,3 +19,179 @@ along with this program. If not, see */ package apis + +import ( + "path" + "reflect" + "testing" + "time" + + "github.com/cgrates/birpc/context" + + "github.com/cgrates/birpc" + + "github.com/cgrates/cgrates/utils" + + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" +) + +var ( + alsPrfCfgPath string + alsPrfCfg *config.CGRConfig + attrSRPC *birpc.Client + alsPrf *engine.AttributeProfileWithAPIOpts + alsPrfConfigDIR string //run tests for specific configuration + + sTestsAlsPrf = []func(t *testing.T){ + testAttributeSInitCfg, + testAttributeSInitDataDb, + testAttributeSResetStorDb, + testAttributeSStartEngine, + testAttributeSRPCConn, + testGetAttributeProfileBeforeSet, + //testAttributeSLoadFromFolder, + testAttributeSetAttributeProfile, + testAttributeSKillEngine, + } +) + +func TestAttributeSIT(t *testing.T) { + switch *dbType { + case utils.MetaInternal: + alsPrfConfigDIR = "attributes_internal" + default: + t.Fatal("Unknown Database type") + } + for _, stest := range sTestsAlsPrf { + t.Run(alsPrfConfigDIR, stest) + } +} + +func testAttributeSInitCfg(t *testing.T) { + var err error + alsPrfCfgPath = path.Join(*dataDir, "conf", "samples", alsPrfConfigDIR) + alsPrfCfg, err = config.NewCGRConfigFromPath(alsPrfCfgPath) + if err != nil { + t.Error(err) + } +} + +func testAttributeSInitDataDb(t *testing.T) { + if err := engine.InitDataDB(alsPrfCfg); err != nil { + t.Fatal(err) + } +} + +func testAttributeSResetStorDb(t *testing.T) { + if err := engine.InitStorDB(alsPrfCfg); err != nil { + t.Fatal(err) + } +} + +// Start CGR Engine +func testAttributeSStartEngine(t *testing.T) { + if _, err := engine.StopStartEngine(alsPrfCfgPath, *waitRater); err != nil { + t.Fatal(err) + } +} + +func testAttributeSRPCConn(t *testing.T) { + var err error + attrSRPC, err = newRPCClient(alsPrfCfg.ListenCfg()) // We connect over JSON so we can also troubleshoot if needed + if err != nil { + t.Fatal(err) + } +} + +func testGetAttributeProfileBeforeSet(t *testing.T) { + var reply *engine.APIAttributeProfile + if err := attrSRPC.Call(context.Background(), utils.AdminSv1GetAttributeProfile, + &utils.TenantIDWithAPIOpts{ + TenantID: &utils.TenantID{ + Tenant: utils.CGRateSorg, + ID: "TEST_ATTRIBUTES_IT_TEST", + }, + }, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { + t.Error(err) + } +} + +func testAttributeSLoadFromFolder(t *testing.T) { + var reply string + attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "oldtutorial")} + if err := attrSRPC.Call(context.Background(), + utils.APIerSv1LoadTariffPlanFromFolder, attrs, &reply); err != nil { + t.Error(err) + } + time.Sleep(100 * time.Millisecond) +} + +func testAttributeSetAttributeProfile(t *testing.T) { + time.Sleep(1000 * time.Millisecond) + attrPrf := &engine.AttributeWithAPIOpts{ + APIAttributeProfile: &engine.APIAttributeProfile{ + Tenant: utils.CGRateSorg, + ID: "TEST_ATTRIBUTES_IT_TEST", + Contexts: []string{"*any"}, + FilterIDs: []string{"*string:~*req.Account:1002"}, + Attributes: []*engine.ExternalAttribute{ + { + Path: utils.AccountField, + Type: utils.MetaConstant, + Value: "1002", + }, + { + Path: "*tenant", + Type: utils.MetaConstant, + Value: "cgrates.itsyscom", + }, + }, + }, + } + var reply string + if err := attrSRPC.Call(context.Background(), utils.AdminSv1SetAttributeProfile, + attrPrf, &reply); err != nil { + t.Error(err) + } else if reply != utils.OK { + t.Error(err) + } + + expectedAttr := &engine.APIAttributeProfile{ + Tenant: utils.CGRateSorg, + ID: "TEST_ATTRIBUTES_IT_TEST", + Contexts: []string{"*any"}, + FilterIDs: []string{"*string:~*req.Account:1002"}, + Attributes: []*engine.ExternalAttribute{ + { + Path: utils.AccountField, + Type: utils.MetaConstant, + Value: "1002", + }, + { + Path: "*tenant", + Type: utils.MetaConstant, + Value: "cgrates.itsyscom", + }, + }, + } + var result *engine.APIAttributeProfile + if err := attrSRPC.Call(context.Background(), utils.AdminSv1GetAttributeProfile, + &utils.TenantIDWithAPIOpts{ + TenantID: &utils.TenantID{ + Tenant: utils.CGRateSorg, + ID: "TEST_ATTRIBUTES_IT_TEST", + }, + }, &result); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(result, expectedAttr) { + t.Errorf("Expected %+v, received %+v", utils.ToJSON(expectedAttr), utils.ToJSON(result)) + } +} + +//Kill the engine when it is about to be finished +func testAttributeSKillEngine(t *testing.T) { + if err := engine.KillEngine(100); err != nil { + t.Error(err) + } +} diff --git a/apis/lib_test.go b/apis/lib_test.go new file mode 100644 index 000000000..cce810551 --- /dev/null +++ b/apis/lib_test.go @@ -0,0 +1,48 @@ +/* +Real-time Online/Offline Charging System (OerS) 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 + +import ( + "errors" + "flag" + + "github.com/cgrates/birpc" + "github.com/cgrates/birpc/jsonrpc" + + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/utils" +) + +var ( + dataDir = flag.String("data_dir", "/usr/share/cgrates", "CGR data dir path here") + waitRater = flag.Int("wait_rater", 100, "Number of milliseconds to wait for rater to start and cache") + encoding = flag.String("rpc", utils.MetaJSON, "what encoding would be used for rpc communication") + dbType = flag.String("dbtype", utils.MetaInternal, "The type of DataBase (Internal/Mongo/mySql)") +) + +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 birpc.Dial(utils.TCP, cfg.RPCGOBListen) + default: + return nil, errors.New("UNSUPPORTED_RPC") + } +} diff --git a/console/attributes_profile.go b/console/attributes_profile.go index 347314a0a..fa54f57ec 100644 --- a/console/attributes_profile.go +++ b/console/attributes_profile.go @@ -26,7 +26,7 @@ import ( func init() { c := &CmdGetAttributes{ name: "attributes_profile", - rpcMethod: utils.APIerSv1GetAttributeProfile, + rpcMethod: utils.AdminSv1GetAttributeProfile, rpcParams: &utils.TenantIDWithAPIOpts{}, } commands[c.Name()] = c diff --git a/console/attributes_profile_set.go b/console/attributes_profile_set.go index e0d5aa739..71432353d 100644 --- a/console/attributes_profile_set.go +++ b/console/attributes_profile_set.go @@ -26,7 +26,7 @@ import ( func init() { c := &CmdSetAttributes{ name: "attributes_profile_set", - rpcMethod: utils.APIerSv2SetAttributeProfile, + rpcMethod: utils.AdminSv1SetAttributeProfile, rpcParams: &engine.AttributeWithAPIOpts{}, } commands[c.Name()] = c diff --git a/data/conf/samples/attributes_internal/cgrates.json b/data/conf/samples/attributes_internal/cgrates.json index da2a6e4b0..690c45f0a 100644 --- a/data/conf/samples/attributes_internal/cgrates.json +++ b/data/conf/samples/attributes_internal/cgrates.json @@ -2,24 +2,20 @@ // CGRateS Configuration file // will be used in apis/attributes_it_test.go - "general": { - "log_level": 7, - "reply_timeout": "50s" + + "data_db": { + "db_type": "*internal", }, - "listen": { - "rpc_json": ":2012", - "rpc_gob": ":2013", - "http": ":2080" + "stor_db": { + "db_type": "*internal", }, "attributes": { "enabled": true, - "apiers_conns": ["*localhost"] }, - "sessions": { + "admins": { "enabled": true, - "attributes_conns": ["*internal"], } }, \ No newline at end of file diff --git a/general_tests/sessions_concur_test.go b/general_tests/sessions_concur_test.go index 8f05d8cac..d93db1a88 100644 --- a/general_tests/sessions_concur_test.go +++ b/general_tests/sessions_concur_test.go @@ -138,7 +138,7 @@ func testSCncrLoadTP(t *testing.T) { }, } var resAttrSet string - if err := sCncrRPC.Call(utils.APIerSv2SetAttributeProfile, attrPrfl, &resAttrSet); err != nil { + if err := sCncrRPC.Call(utils.APIerSv1SetAttributeProfile, attrPrfl, &resAttrSet); err != nil { t.Error(err) } else if resAttrSet != utils.OK { t.Errorf("unexpected reply returned: <%s>", resAttrSet) diff --git a/utils/consts.go b/utils/consts.go index d5b5be206..ce4010d47 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -1347,11 +1347,10 @@ const ( // AttributeS APIs const ( - APIerSv1SetAttributeProfile = "APIerSv1.SetAttributeProfile" - APIerSv1GetAttributeProfile = "APIerSv1.GetAttributeProfile" + AdminSv1SetAttributeProfile = "AdminSv1.SetAttributeProfile" + AdminSv1GetAttributeProfile = "AdminSv1.GetAttributeProfile" APIerSv1GetAttributeProfileIDs = "APIerSv1.GetAttributeProfileIDs" APIerSv1RemoveAttributeProfile = "APIerSv1.RemoveAttributeProfile" - APIerSv2SetAttributeProfile = "APIerSv2.SetAttributeProfile" AttributeSv1GetAttributeForEvent = "AttributeSv1.GetAttributeForEvent" AttributeSv1ProcessEvent = "AttributeSv1.ProcessEvent" AttributeSv1Ping = "AttributeSv1.Ping"