From 519a11cebbfea8588dd1358a81e846028db2971c Mon Sep 17 00:00:00 2001 From: adragusin Date: Fri, 25 Oct 2019 16:31:58 +0300 Subject: [PATCH] Updated general tests with sub-tests --- general_tests/accounts_it_test.go | 42 +- general_tests/cdre_it_test.go | 26 +- general_tests/cdrs_it_test.go | 74 +- general_tests/cdrs_onlexp_it_test.go | 67 +- general_tests/data_it_test.go | 38 +- general_tests/dest_management_it_test.go | 67 +- general_tests/filters_it_test.go | 32 +- general_tests/multiplecdrc_it_test.go | 58 +- general_tests/rpcclient_it_test.go | 57 +- general_tests/sentinel_it_test.go | 572 ++++---- general_tests/session2_it_test.go | 36 +- general_tests/session_it_test.go | 39 +- general_tests/sessionrefund_it_test.go | 48 +- general_tests/supplier_it_test.go | 38 +- general_tests/suretax_it_test.go | 51 +- general_tests/tls_it_test.go | 336 ++--- general_tests/tp_it_test.go | 72 +- general_tests/tut_smgeneric_it_test.go | 27 +- general_tests/tutorial2_it_test.go | 630 ++++---- general_tests/tutorial_calls_test.go | 1692 +++++++++++----------- general_tests/tutorial_it_test.go | 296 ++-- 21 files changed, 2255 insertions(+), 2043 deletions(-) diff --git a/general_tests/accounts_it_test.go b/general_tests/accounts_it_test.go index 5f30d4b48..e5f6a9fb4 100644 --- a/general_tests/accounts_it_test.go +++ b/general_tests/accounts_it_test.go @@ -39,28 +39,28 @@ var ( accConfDIR string //run tests for specific configuration account *engine.Account accDelay int -) -var sTestsAcc = []func(t *testing.T){ - testV1AccLoadConfig, - testV1AccInitDataDb, - testAccResetStorDb, - testV1AccStartEngine, - testV1AccRpcConn, - testV1AccGetAccountBeforeSet, - testV1AccLoadTarrifPlans, - testV1AccGetAccountAfterLoad, - testV1AccRemAccount, - testV1AccGetAccountAfterDelete, - testV1AccSetAccount, - testV1AccGetAccountAfterSet, - testV1AccRemAccountSet, - testV1AccGetAccountSetAfterDelete, - //testV1AccRemAccountAfterDelete, - testV1AccMonthly, - testV1AccSendToThreshold, - testV1AccStopEngine, -} + sTestsAcc = []func(t *testing.T){ + testV1AccLoadConfig, + testV1AccInitDataDb, + testAccResetStorDb, + testV1AccStartEngine, + testV1AccRpcConn, + testV1AccGetAccountBeforeSet, + testV1AccLoadTarrifPlans, + testV1AccGetAccountAfterLoad, + testV1AccRemAccount, + testV1AccGetAccountAfterDelete, + testV1AccSetAccount, + testV1AccGetAccountAfterSet, + testV1AccRemAccountSet, + testV1AccGetAccountSetAfterDelete, + //testV1AccRemAccountAfterDelete, + testV1AccMonthly, + testV1AccSendToThreshold, + testV1AccStopEngine, + } +) // Test start here func TestAccITMySQL(t *testing.T) { diff --git a/general_tests/cdre_it_test.go b/general_tests/cdre_it_test.go index b29564dbc..f4a9766c2 100644 --- a/general_tests/cdre_it_test.go +++ b/general_tests/cdre_it_test.go @@ -40,20 +40,20 @@ var ( cdreDataDir = "/usr/share/cgrates" cdreDelay int cdreConfigDIR string -) -var sTestsCDRE = []func(t *testing.T){ - testCDREInitCfg, - testCDREInitDataDb, - testCDREResetStorDb, - testCDREStartEngine, - testCDRERpcConn, - testCDREGetCdrs, - testCDREExportNotFound, - testCDREProcessCdr, - testCDREExport, - testCDREStopEngine, -} + sTestsCDRE = []func(t *testing.T){ + testCDREInitCfg, + testCDREInitDataDb, + testCDREResetStorDb, + testCDREStartEngine, + testCDRERpcConn, + testCDREGetCdrs, + testCDREExportNotFound, + testCDREProcessCdr, + testCDREExport, + testCDREStopEngine, + } +) func TestCDREITMySql(t *testing.T) { cdreConfigDIR = "tutmysql" diff --git a/general_tests/cdrs_it_test.go b/general_tests/cdrs_it_test.go index d2d813e52..888d7772c 100644 --- a/general_tests/cdrs_it_test.go +++ b/general_tests/cdrs_it_test.go @@ -35,47 +35,49 @@ import ( "github.com/cgrates/cgrates/utils" ) -var cdrsCfgPath string -var cdrsCfg *config.CGRConfig -var cdrsRpc *rpc.Client -var cdrsConfDIR string // run the tests for specific configuration +var ( + cdrsCfgPath string + cdrsCfg *config.CGRConfig + cdrsRpc *rpc.Client + cdrsConfDIR string // run the tests for specific configuration -// subtests to be executed for each confDIR -var sTestsCDRsIT = []func(t *testing.T){ - testV2CDRsInitConfig, - testV2CDRsInitDataDb, - testV2CDRsInitCdrDb, - testV2CDRsStartEngine, - testV2CDRsRpcConn, - testV2CDRsLoadTariffPlanFromFolder, - //default process - testV2CDRsProcessCDR, - testV2CDRsGetCdrs, - //custom process - testV2CDRsProcessCDR2, - testV2CDRsGetCdrs2, - testV2CDRsProcessCDR3, - testV2CDRsGetCdrs3, + // subtests to be executed for each confDIR + sTestsCDRsIT = []func(t *testing.T){ + testV2CDRsInitConfig, + testV2CDRsInitDataDb, + testV2CDRsInitCdrDb, + testV2CDRsStartEngine, + testV2CDRsRpcConn, + testV2CDRsLoadTariffPlanFromFolder, + //default process + testV2CDRsProcessCDR, + testV2CDRsGetCdrs, + //custom process + testV2CDRsProcessCDR2, + testV2CDRsGetCdrs2, + testV2CDRsProcessCDR3, + testV2CDRsGetCdrs3, - testV2CDRsProcessCDR4, - testV2CDRsGetCdrs4, + testV2CDRsProcessCDR4, + testV2CDRsGetCdrs4, - testV2CDRsSetStats, - testV2CDRsSetThresholdProfile, + testV2CDRsSetStats, + testV2CDRsSetThresholdProfile, - testV2CDRsProcessCDR5, - testV2CDRsGetCdrs5, - testV2CDRsGetStats1, - testV2CDRsGetThreshold1, - testV2CDRsProcessCDR6, - testV2CDRsGetCdrs5, - testV2CDRsGetStats2, - testV2CDRsGetThreshold2, - testV2CDRsProcessCDR7, - testV2CDRsGetCdrs7, + testV2CDRsProcessCDR5, + testV2CDRsGetCdrs5, + testV2CDRsGetStats1, + testV2CDRsGetThreshold1, + testV2CDRsProcessCDR6, + testV2CDRsGetCdrs5, + testV2CDRsGetStats2, + testV2CDRsGetThreshold2, + testV2CDRsProcessCDR7, + testV2CDRsGetCdrs7, - testV2CDRsKillEngine, -} + testV2CDRsKillEngine, + } +) // Tests starting here func TestCDRsITMySQL(t *testing.T) { diff --git a/general_tests/cdrs_onlexp_it_test.go b/general_tests/cdrs_onlexp_it_test.go index f720cbc08..98a53a99c 100644 --- a/general_tests/cdrs_onlexp_it_test.go +++ b/general_tests/cdrs_onlexp_it_test.go @@ -40,11 +40,38 @@ import ( "github.com/streadway/amqp" ) -var cdrsMasterCfgPath, cdrsSlaveCfgPath string -var cdrsMasterCfg, cdrsSlaveCfg *config.CGRConfig -var cdrsMasterRpc *rpcclient.RpcClient +var ( + cdrsMasterCfgPath, cdrsSlaveCfgPath string + cdrsMasterCfg, cdrsSlaveCfg *config.CGRConfig + cdrsMasterRpc *rpcclient.RpcClient -func TestCDRsOnExpInitConfig(t *testing.T) { + sTestsCDRsOnExp = []func(t *testing.T){ + testCDRsOnExpInitConfig, + testCDRsOnExpInitCdrDb, + testCDRsOnExpStartMasterEngine, + testCDRsOnExpStartSlaveEngine, + testCDRsOnExpAMQPQueuesCreation, + testCDRsOnExpInitMasterRPC, + testCDRsOnExpDisableOnlineExport, + testCDRsOnExpHttpCdrReplication, + testCDRsOnExpAMQPReplication, + testCDRsOnExpHTTPPosterFileFailover, + testCDRsOnExpAMQPPosterFileFailover, + testCDRsOnExpAWSAMQPPosterFileFailover, + testCDRsOnExpKafkaPosterFileFailover, + testCDRsOnExpSQSPosterFileFailover, + testCDRsOnExpS3PosterFileFailover, + testCDRsOnExpStopEngine, + } +) + +func TestCDRsOnExp(t *testing.T) { + for _, stest := range sTestsCDRsOnExp { + t.Run("TestCDRsOnExp", stest) + } +} + +func testCDRsOnExpInitConfig(t *testing.T) { var err error cdrsMasterCfgPath = path.Join(*dataDir, "conf", "samples", "cdrsonexpmaster") if cdrsMasterCfg, err = config.NewCGRConfigFromPath(cdrsMasterCfgPath); err != nil { @@ -57,7 +84,7 @@ func TestCDRsOnExpInitConfig(t *testing.T) { } // InitDb so we can rely on count -func TestCDRsOnExpInitCdrDb(t *testing.T) { +func testCDRsOnExpInitCdrDb(t *testing.T) { if err := engine.InitStorDb(cdrsMasterCfg); err != nil { t.Fatal(err) } @@ -74,13 +101,13 @@ func TestCDRsOnExpInitCdrDb(t *testing.T) { } -func TestCDRsOnExpStartMasterEngine(t *testing.T) { +func testCDRsOnExpStartMasterEngine(t *testing.T) { if _, err := engine.StopStartEngine(cdrsMasterCfgPath, *waitRater); err != nil { t.Fatal(err) } } -func TestCDRsOnExpStartSlaveEngine(t *testing.T) { +func testCDRsOnExpStartSlaveEngine(t *testing.T) { if _, err := engine.StartEngine(cdrsSlaveCfgPath, *waitRater); err != nil { t.Fatal(err) } @@ -88,7 +115,7 @@ func TestCDRsOnExpStartSlaveEngine(t *testing.T) { // Create Queues dor amq -func TestCDRsOnExpAMQPQueuesCreation(t *testing.T) { +func testCDRsOnExpAMQPQueuesCreation(t *testing.T) { conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/") if err != nil { t.Fatal(err) @@ -113,7 +140,7 @@ func TestCDRsOnExpAMQPQueuesCreation(t *testing.T) { } // Connect rpc client to rater -func TestCDRsOnExpInitMasterRPC(t *testing.T) { +func testCDRsOnExpInitMasterRPC(t *testing.T) { var err error cdrsMasterRpc, err = rpcclient.NewRpcClient("tcp", cdrsMasterCfg.ListenCfg().RPCJSONListen, false, "", "", "", 1, 1, time.Duration(1*time.Second), time.Duration(2*time.Second), "json", nil, false) @@ -123,7 +150,7 @@ func TestCDRsOnExpInitMasterRPC(t *testing.T) { } // Disable ExportCDR -func TestCDRsOnExpDisableOnlineExport(t *testing.T) { +func testCDRsOnExpDisableOnlineExport(t *testing.T) { // stop RabbitMQ server so we can test reconnects if err := exec.Command("service", "rabbitmq-server", "stop").Run(); err != nil { t.Error(err) @@ -170,7 +197,7 @@ func TestCDRsOnExpDisableOnlineExport(t *testing.T) { time.Sleep(5 * time.Second) } -func TestCDRsOnExpHttpCdrReplication(t *testing.T) { +func testCDRsOnExpHttpCdrReplication(t *testing.T) { //add a default charger chargerProfile := &engine.ChargerProfile{ Tenant: "cgrates.org", @@ -250,7 +277,7 @@ func TestCDRsOnExpHttpCdrReplication(t *testing.T) { } } -func TestCDRsOnExpAMQPReplication(t *testing.T) { +func testCDRsOnExpAMQPReplication(t *testing.T) { conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/") if err != nil { t.Fatal(err) @@ -388,7 +415,7 @@ func TestCDRsOnExpAMQPReplication(t *testing.T) { } -func TestCDRsOnExpHTTPPosterFileFailover(t *testing.T) { +func testCDRsOnExpHTTPPosterFileFailover(t *testing.T) { time.Sleep(time.Duration(5 * time.Second)) failoverContent := [][]byte{[]byte(`OriginID=httpjsonrpc1`), []byte(`OriginID=amqpreconnect`)} filesInDir, _ := ioutil.ReadDir(cdrsMasterCfg.GeneralCfg().FailedPostsDir) @@ -417,7 +444,7 @@ func TestCDRsOnExpHTTPPosterFileFailover(t *testing.T) { } } -func TestCDRsOnExpAMQPPosterFileFailover(t *testing.T) { +func testCDRsOnExpAMQPPosterFileFailover(t *testing.T) { time.Sleep(time.Duration(5 * time.Second)) failoverContent := [][]byte{[]byte(`{"CGRID":"57548d485d61ebcba55afbe5d939c82a8e9ff670"}`), []byte(`{"CGRID":"88ed9c38005f07576a1e1af293063833b60edcc6"}`)} filesInDir, _ := ioutil.ReadDir(cdrsMasterCfg.GeneralCfg().FailedPostsDir) @@ -446,7 +473,7 @@ func TestCDRsOnExpAMQPPosterFileFailover(t *testing.T) { } } -func TestCDRsOnExpAWSAMQPPosterFileFailover(t *testing.T) { +func testCDRsOnExpAWSAMQPPosterFileFailover(t *testing.T) { time.Sleep(time.Duration(10 * time.Second)) failoverContent := [][]byte{[]byte(`{"CGRID":"57548d485d61ebcba55afbe5d939c82a8e9ff670"}`), []byte(`{"CGRID":"88ed9c38005f07576a1e1af293063833b60edcc6"}`)} filesInDir, _ := ioutil.ReadDir(cdrsMasterCfg.GeneralCfg().FailedPostsDir) @@ -475,7 +502,7 @@ func TestCDRsOnExpAWSAMQPPosterFileFailover(t *testing.T) { } } -func TestCDRsOnExpKafkaPosterFileFailover(t *testing.T) { +func testCDRsOnExpKafkaPosterFileFailover(t *testing.T) { failoverContent := [][]byte{[]byte(`{"CGRID":"57548d485d61ebcba55afbe5d939c82a8e9ff670"}`), []byte(`{"CGRID":"88ed9c38005f07576a1e1af293063833b60edcc6"}`)} reader := kafka.NewReader(kafka.ReaderConfig{ @@ -497,7 +524,7 @@ func TestCDRsOnExpKafkaPosterFileFailover(t *testing.T) { } } -func TestCDRsOnExpSQSPosterFileFailover(t *testing.T) { +func testCDRsOnExpSQSPosterFileFailover(t *testing.T) { time.Sleep(time.Duration(10 * time.Second)) failoverContent := [][]byte{[]byte(`{"CGRID":"57548d485d61ebcba55afbe5d939c82a8e9ff670"}`), []byte(`{"CGRID":"88ed9c38005f07576a1e1af293063833b60edcc6"}`)} filesInDir, _ := ioutil.ReadDir(cdrsMasterCfg.GeneralCfg().FailedPostsDir) @@ -526,7 +553,7 @@ func TestCDRsOnExpSQSPosterFileFailover(t *testing.T) { } } -func TestCDRsOnExpS3PosterFileFailover(t *testing.T) { +func testCDRsOnExpS3PosterFileFailover(t *testing.T) { time.Sleep(time.Duration(10 * time.Second)) failoverContent := [][]byte{[]byte(`{"CGRID":"57548d485d61ebcba55afbe5d939c82a8e9ff670"}`), []byte(`{"CGRID":"88ed9c38005f07576a1e1af293063833b60edcc6"}`)} filesInDir, _ := ioutil.ReadDir(cdrsMasterCfg.GeneralCfg().FailedPostsDir) @@ -558,7 +585,7 @@ func TestCDRsOnExpS3PosterFileFailover(t *testing.T) { /* // Performance test, check `lsof -a -p 8427 | wc -l` -func TestCdrsHttpCdrReplication2(t *testing.T) { +func testCdrsHttpCdrReplication2(t *testing.T) { cdrs := make([]*engine.CDR, 0) for i := 0; i < 10000; i++ { cdr := &engine.CDR{OriginID: fmt.Sprintf("httpjsonrpc_%d", i), @@ -579,7 +606,7 @@ func TestCdrsHttpCdrReplication2(t *testing.T) { } */ -func TestCDRsOnExpStopEngine(t *testing.T) { +func testCDRsOnExpStopEngine(t *testing.T) { if err := engine.KillEngine(100); err != nil { t.Error(err) } diff --git a/general_tests/data_it_test.go b/general_tests/data_it_test.go index 8046a7ed2..e16cab22f 100644 --- a/general_tests/data_it_test.go +++ b/general_tests/data_it_test.go @@ -39,26 +39,26 @@ var ( dataRpc *rpc.Client dataConfDIR string //run tests for specific configuration dataDelay int -) -var sTestsData = []func(t *testing.T){ - testV1DataLoadConfig, - testV1DataInitDataDb, - testV1DataResetStorDb, - testV1DataStartEngine, - testV1DataRpcConn, - testV1DataLoadTarrifPlans, - // testV1DataDataDebitUsageWith10Kilo, - // testV1DataGetCostWith10Kilo, - // testV1DataDebitBalanceWith10Kilo, - // testV1DataDataDebitUsage1G0, - // testV1DataGetCost1G0, - // testV1DataDebitBalance1G0, - testV1DataInitSession, - testV1DataUpdateWith1Mo, - testV1DataUpdateWith1Go, - testV1DataStopEngine, -} + sTestsData = []func(t *testing.T){ + testV1DataLoadConfig, + testV1DataInitDataDb, + testV1DataResetStorDb, + testV1DataStartEngine, + testV1DataRpcConn, + testV1DataLoadTarrifPlans, + // testV1DataDataDebitUsageWith10Kilo, + // testV1DataGetCostWith10Kilo, + // testV1DataDebitBalanceWith10Kilo, + // testV1DataDataDebitUsage1G0, + // testV1DataGetCost1G0, + // testV1DataDebitBalance1G0, + testV1DataInitSession, + testV1DataUpdateWith1Mo, + testV1DataUpdateWith1Go, + testV1DataStopEngine, + } +) // Test start here func TestDataITMongo(t *testing.T) { diff --git a/general_tests/dest_management_it_test.go b/general_tests/dest_management_it_test.go index a283848d4..f8a9d4c65 100644 --- a/general_tests/dest_management_it_test.go +++ b/general_tests/dest_management_it_test.go @@ -34,11 +34,38 @@ import ( "github.com/cgrates/cgrates/utils" ) -var destCfgPath string -var destCfg *config.CGRConfig -var destRPC *rpc.Client +var ( + destCfgPath string + destCfg *config.CGRConfig + destRPC *rpc.Client -func TestDestManagInitCfg(t *testing.T) { + sTestDestManag = []func (t *testing.T){ + testDestManagInitCfg, + testDestManagResetDataDb, + testDestManagResetStorDb, + testDestManagStartEngine, + testDestManagRpcConn, + testDestManagLoadTariffPlanFromFolderAll, + testDestManagAllDestinationLoaded, + testDestManagLoadTariffPlanFromFolderRemoveSome, + testDestManagRemoveSomeDestinationLoaded, + testDestManagLoadTariffPlanFromFolderRemoveSomeFlush, + testDestManagRemoveSomeFlushDestinationLoaded, + testDestManagLoadTariffPlanFromFolderAddBack, + testDestManagAddBackDestinationLoaded, + testDestManagLoadTariffPlanFromFolderAddOne, + testDestManagAddOneDestinationLoaded, + testDestManagCacheWithGetCache, + testDestManagCacheWithGetCost, + } +) + +func TestDestManag(t *testing.T) { + for _, stest := range sTestDestManag { + t.Run("TestDestManag", stest) + } +} +func testDestManagInitCfg(t *testing.T) { destCfgPath = path.Join(*dataDir, "conf", "samples", "tutmysql") // Init config first var err error @@ -51,28 +78,28 @@ func TestDestManagInitCfg(t *testing.T) { } // Remove data in both rating and accounting db -func TestDestManagResetDataDb(t *testing.T) { +func testDestManagResetDataDb(t *testing.T) { if err := engine.InitDataDb(destCfg); err != nil { t.Fatal(err) } } // Wipe out the cdr database -func TestDestManagResetStorDb(t *testing.T) { +func testDestManagResetStorDb(t *testing.T) { if err := engine.InitStorDb(destCfg); err != nil { t.Fatal(err) } } // Start CGR Engine -func TestDestManagStartEngine(t *testing.T) { +func testDestManagStartEngine(t *testing.T) { if _, err := engine.StopStartEngine(destCfgPath, *waitRater); err != nil { t.Fatal(err) } } // Connect rpc client to rater -func TestDestManagRpcConn(t *testing.T) { +func testDestManagRpcConn(t *testing.T) { var err error destRPC, err = jsonrpc.Dial("tcp", destCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed if err != nil { @@ -81,7 +108,7 @@ func TestDestManagRpcConn(t *testing.T) { } // Load the tariff plan, creating accounts and their balances -func TestDestManagLoadTariffPlanFromFolderAll(t *testing.T) { +func testDestManagLoadTariffPlanFromFolderAll(t *testing.T) { attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "test", "destinations", "alldests")} var destLoadInst utils.LoadInstance if err := destRPC.Call("ApierV2.LoadTariffPlanFromFolder", attrs, &destLoadInst); err != nil { @@ -91,7 +118,7 @@ func TestDestManagLoadTariffPlanFromFolderAll(t *testing.T) { } -func TestDestManagAllDestinationLoaded(t *testing.T) { +func testDestManagAllDestinationLoaded(t *testing.T) { dests := make([]*engine.Destination, 0) if err := destRPC.Call("ApierV2.GetDestinations", v2.AttrGetDestinations{DestinationIDs: []string{}}, &dests); err != nil { t.Error("Got error on ApierV2.GetDestinations: ", err.Error()) @@ -108,7 +135,7 @@ func TestDestManagAllDestinationLoaded(t *testing.T) { } -func TestDestManagLoadTariffPlanFromFolderRemoveSome(t *testing.T) { +func testDestManagLoadTariffPlanFromFolderRemoveSome(t *testing.T) { attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "test", "destinations", "removesome")} var destLoadInst utils.LoadInstance if err := destRPC.Call("ApierV2.LoadTariffPlanFromFolder", attrs, &destLoadInst); err != nil { @@ -117,7 +144,7 @@ func TestDestManagLoadTariffPlanFromFolderRemoveSome(t *testing.T) { time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups } -func TestDestManagRemoveSomeDestinationLoaded(t *testing.T) { +func testDestManagRemoveSomeDestinationLoaded(t *testing.T) { dests := make([]*engine.Destination, 0) if err := destRPC.Call("ApierV2.GetDestinations", v2.AttrGetDestinations{DestinationIDs: []string{}}, &dests); err != nil { t.Error("Got error on ApierV2.GetDestinations: ", err.Error()) @@ -133,7 +160,7 @@ func TestDestManagRemoveSomeDestinationLoaded(t *testing.T) { } } -func TestDestManagLoadTariffPlanFromFolderRemoveSomeFlush(t *testing.T) { +func testDestManagLoadTariffPlanFromFolderRemoveSomeFlush(t *testing.T) { attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "test", "destinations", "removesome"), FlushDb: true} var destLoadInst utils.LoadInstance if err := destRPC.Call("ApierV2.LoadTariffPlanFromFolder", attrs, &destLoadInst); err != nil { @@ -142,7 +169,7 @@ func TestDestManagLoadTariffPlanFromFolderRemoveSomeFlush(t *testing.T) { time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups } -func TestDestManagRemoveSomeFlushDestinationLoaded(t *testing.T) { +func testDestManagRemoveSomeFlushDestinationLoaded(t *testing.T) { dests := make([]*engine.Destination, 0) if err := destRPC.Call("ApierV2.GetDestinations", v2.AttrGetDestinations{DestinationIDs: []string{}}, &dests); err != nil { t.Error("Got error on ApierV2.GetDestinations: ", err.Error()) @@ -158,7 +185,7 @@ func TestDestManagRemoveSomeFlushDestinationLoaded(t *testing.T) { } } -func TestDestManagLoadTariffPlanFromFolderAddBack(t *testing.T) { +func testDestManagLoadTariffPlanFromFolderAddBack(t *testing.T) { attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "test", "destinations", "addback")} var destLoadInst utils.LoadInstance if err := destRPC.Call("ApierV2.LoadTariffPlanFromFolder", attrs, &destLoadInst); err != nil { @@ -167,7 +194,7 @@ func TestDestManagLoadTariffPlanFromFolderAddBack(t *testing.T) { time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups } -func TestDestManagAddBackDestinationLoaded(t *testing.T) { +func testDestManagAddBackDestinationLoaded(t *testing.T) { dests := make([]*engine.Destination, 0) if err := destRPC.Call("ApierV2.GetDestinations", v2.AttrGetDestinations{DestinationIDs: []string{}}, &dests); err != nil { t.Error("Got error on ApierV2.GetDestinations: ", err.Error()) @@ -183,7 +210,7 @@ func TestDestManagAddBackDestinationLoaded(t *testing.T) { } } -func TestDestManagLoadTariffPlanFromFolderAddOne(t *testing.T) { +func testDestManagLoadTariffPlanFromFolderAddOne(t *testing.T) { attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "test", "destinations", "addone")} var destLoadInst utils.LoadInstance if err := destRPC.Call("ApierV2.LoadTariffPlanFromFolder", attrs, &destLoadInst); err != nil { @@ -192,7 +219,7 @@ func TestDestManagLoadTariffPlanFromFolderAddOne(t *testing.T) { time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups } -func TestDestManagAddOneDestinationLoaded(t *testing.T) { +func testDestManagAddOneDestinationLoaded(t *testing.T) { dests := make([]*engine.Destination, 0) if err := destRPC.Call("ApierV2.GetDestinations", v2.AttrGetDestinations{DestinationIDs: []string{}}, &dests); err != nil { t.Error("Got error on ApierV2.GetDestinations: ", err.Error()) @@ -208,7 +235,7 @@ func TestDestManagAddOneDestinationLoaded(t *testing.T) { } } -func TestDestManagCacheWithGetCache(t *testing.T) { +func testDestManagCacheWithGetCache(t *testing.T) { if err := engine.InitDataDb(destCfg); err != nil { t.Fatal(err) } @@ -259,7 +286,7 @@ func TestDestManagCacheWithGetCache(t *testing.T) { } } -func TestDestManagCacheWithGetCost(t *testing.T) { +func testDestManagCacheWithGetCost(t *testing.T) { if err := engine.InitDataDb(destCfg); err != nil { t.Fatal(err) } diff --git a/general_tests/filters_it_test.go b/general_tests/filters_it_test.go index 41222997b..98dd1e1ce 100644 --- a/general_tests/filters_it_test.go +++ b/general_tests/filters_it_test.go @@ -39,23 +39,23 @@ var ( fltrRpc *rpc.Client fltrConfDIR string //run tests for specific configuration fltrDelay int -) -var sTestsFltr = []func(t *testing.T){ - testV1FltrLoadConfig, - testV1FltrInitDataDb, - testV1FltrResetStorDb, - testV1FltrStartEngine, - testV1FltrRpcConn, - testV1FltrLoadTarrifPlans, - testV1FltrAddStats, - testV1FltrPupulateThreshold, - testV1FltrGetThresholdForEvent, - testV1FltrGetThresholdForEvent2, - testV1FltrPopulateResources, - testV1FltrAccounts, - testV1FltrStopEngine, -} + sTestsFltr = []func(t *testing.T){ + testV1FltrLoadConfig, + testV1FltrInitDataDb, + testV1FltrResetStorDb, + testV1FltrStartEngine, + testV1FltrRpcConn, + testV1FltrLoadTarrifPlans, + testV1FltrAddStats, + testV1FltrPupulateThreshold, + testV1FltrGetThresholdForEvent, + testV1FltrGetThresholdForEvent2, + testV1FltrPopulateResources, + testV1FltrAccounts, + testV1FltrStopEngine, + } +) // Test start here func TestFltrIT(t *testing.T) { diff --git a/general_tests/multiplecdrc_it_test.go b/general_tests/multiplecdrc_it_test.go index a66303573..0ea8bb82c 100644 --- a/general_tests/multiplecdrc_it_test.go +++ b/general_tests/multiplecdrc_it_test.go @@ -35,16 +35,38 @@ import ( "github.com/cgrates/cgrates/utils" ) -var cfgPath string -var cfg *config.CGRConfig -var rater *rpc.Client +var ( + cfgPath string + cfg *config.CGRConfig + rater *rpc.Client -var testCalls = flag.Bool("calls", false, "Run test calls simulation, not by default.") -var dataDir = flag.String("data_dir", "/usr/share/cgrates", "CGR data dir path here") -var storDbType = flag.String("stordb_type", "mysql", "The type of the storDb database ") -var waitRater = flag.Int("wait_rater", 100, "Number of miliseconds to wait for rater to start and cache") + testCalls = flag.Bool("calls", false, "Run test calls simulation, not by default.") + dataDir = flag.String("data_dir", "/usr/share/cgrates", "CGR data dir path here") + storDbType = flag.String("stordb_type", "mysql", "The type of the storDb database ") + waitRater = flag.Int("wait_rater", 100, "Number of miliseconds to wait for rater to start and cache") -func TestMCDRCLoadConfig(t *testing.T) { + sTestMCDRC = []func(t *testing.T){ + testMCDRCLoadConfig, + testMCDRCResetDataDb, + testMCDRCEmptyTables, + testMCDRCCreateCdrDirs, + testMCDRCStartEngine, + testMCDRCRpcConn, + testMCDRCApierLoadTariffPlanFromFolder, + testMCDRCHandleCdr1File, + testMCDRCHandleCdr2File, + testMCDRCHandleCdr3File, + testMCDRCStopEngine, + } +) + +func TestMCDRC(t *testing.T) { + for _, stest := range sTestMCDRC { + t.Run("TestsMCDRC", stest) + } +} + +func testMCDRCLoadConfig(t *testing.T) { var err error cfgPath = path.Join(*dataDir, "conf", "samples", "multiplecdrc") if cfg, err = config.NewCGRConfigFromPath(cfgPath); err != nil { @@ -53,19 +75,19 @@ func TestMCDRCLoadConfig(t *testing.T) { } // Remove data in both rating and accounting db -func TestMCDRCResetDataDb(t *testing.T) { +func testMCDRCResetDataDb(t *testing.T) { if err := engine.InitDataDb(cfg); err != nil { t.Fatal(err) } } -func TestMCDRCEmptyTables(t *testing.T) { +func testMCDRCEmptyTables(t *testing.T) { if err := engine.InitStorDb(cfg); err != nil { t.Fatal(err) } } -func TestMCDRCCreateCdrDirs(t *testing.T) { +func testMCDRCCreateCdrDirs(t *testing.T) { for _, cdrcProfiles := range cfg.CdrcProfiles { for _, cdrcInst := range cdrcProfiles { for _, dir := range []string{cdrcInst.CDRInPath, cdrcInst.CDROutPath} { @@ -79,14 +101,14 @@ func TestMCDRCCreateCdrDirs(t *testing.T) { } } } -func TestMCDRCStartEngine(t *testing.T) { +func testMCDRCStartEngine(t *testing.T) { if _, err := engine.StopStartEngine(cfgPath, *waitRater); err != nil { t.Fatal(err) } } // Connect rpc client to rater -func TestMCDRCRpcConn(t *testing.T) { +func testMCDRCRpcConn(t *testing.T) { var err error rater, err = jsonrpc.Dial("tcp", cfg.ListenCfg().RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed if err != nil { @@ -95,7 +117,7 @@ func TestMCDRCRpcConn(t *testing.T) { } // Test here LoadTariffPlanFromFolder -func TestMCDRCApierLoadTariffPlanFromFolder(t *testing.T) { +func testMCDRCApierLoadTariffPlanFromFolder(t *testing.T) { reply := "" // Simple test that command is executed without errors attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "testtp")} @@ -108,7 +130,7 @@ func TestMCDRCApierLoadTariffPlanFromFolder(t *testing.T) { } // The default scenario, out of cdrc defined in .cfg file -func TestMCDRCHandleCdr1File(t *testing.T) { +func testMCDRCHandleCdr1File(t *testing.T) { var fileContent1 = `dbafe9c8614c785a65aabd116dd3959c3c56f7f6,default,*voice,dsafdsaf,rated,*out,cgrates.org,call,1001,1001,+4986517174963,2013-11-07 08:42:25 +0000 UTC,2013-11-07 08:42:26 +0000 UTC,10000000000,1.0100,val_extra3,"",val_extra1 dbafe9c8614c785a65aabd116dd3959c3c56f7f7,default,*voice,dsafdsag,rated,*out,cgrates.org,call,1001,1001,+4986517174964,2013-11-07 09:42:25 +0000 UTC,2013-11-07 09:42:26 +0000 UTC,20000000000,1.0100,val_extra3,"",val_extra1 ` @@ -123,7 +145,7 @@ dbafe9c8614c785a65aabd116dd3959c3c56f7f7,default,*voice,dsafdsag,rated,*out,cgra } // Scenario out of first .xml config -func TestMCDRCHandleCdr2File(t *testing.T) { +func testMCDRCHandleCdr2File(t *testing.T) { var fileContent = `616350843,20131022145011,20131022172857,3656,1001,,,data,mo,640113,0.000000,1.222656,1.222660 616199016,20131022154924,20131022154955,3656,1001,086517174963,,voice,mo,31,0.000000,0.000000,0.000000 800873243,20140516063739,20140516063739,9774,1001,+49621621391,,sms,mo,1,0.00000,0.00000,0.00000` @@ -138,7 +160,7 @@ func TestMCDRCHandleCdr2File(t *testing.T) { } // Scenario out of second .xml config -func TestMCDRCHandleCdr3File(t *testing.T) { +func testMCDRCHandleCdr3File(t *testing.T) { var fileContent = `4986517174960;4986517174963;Sample Mobile;08.04.2014 22:14:29;08.04.2014 22:14:29;1;193;Offeak;0,072728833;31619 4986517174960;4986517174964;National;08.04.2014 20:34:55;08.04.2014 20:34:55;1;21;Offeak;0,0079135;311` fileName := "file3.csv" @@ -151,7 +173,7 @@ func TestMCDRCHandleCdr3File(t *testing.T) { } } -func TestMCDRCStopEngine(t *testing.T) { +func testMCDRCStopEngine(t *testing.T) { if err := engine.KillEngine(100); err != nil { t.Error(err) } diff --git a/general_tests/rpcclient_it_test.go b/general_tests/rpcclient_it_test.go index 0bf148fd3..66d71d915 100644 --- a/general_tests/rpcclient_it_test.go +++ b/general_tests/rpcclient_it_test.go @@ -53,7 +53,32 @@ var ( // configuration opts RemoteRALsAddr2 = "192.168.244.138:2012" ) -func TestRPCITLclInitCfg(t *testing.T) { +//subtests to be executed +var sTestRPCITLcl = []func(t *testing.T){ + testRPCITLclInitCfg, + testRPCITLclStartSecondEngine, + testRPCITLclRpcConnPoolFirst, + testRPCITLclStatusSecondEngine, + testRPCITLclStartFirstEngine, + testRPCITLclStatusFirstInitial, + testRPCITLclStatusFirstFailover, + testRPCITLclStatusFirstFailback, + testRPCITLclTDirectedRPC, + testRPCITLclRpcConnPoolBcast, + testRPCITLclBcastStatusInitial, + testRPCITLclBcastStatusNoRals1, + testRPCITLclBcastStatusBcastNoRals, + testRPCITLclBcastStatusRALs2Up, + testRPCITLclStatusBcastRALs1Up, +} + +func TestRPCITLcl(t *testing.T) { + for _, stest := range sTestRPCITLcl { + t.Run("sTestRPCITLcl", stest) + } +} + +func testRPCITLclInitCfg(t *testing.T) { rpcITCfgPath1 = path.Join(*dataDir, "conf", "samples", "multiral1") rpcITCfgPath2 = path.Join(*dataDir, "conf", "samples", "multiral2") rpcITCfg1, err = config.NewCGRConfigFromPath(rpcITCfgPath1) @@ -69,14 +94,14 @@ func TestRPCITLclInitCfg(t *testing.T) { } } -func TestRPCITLclStartSecondEngine(t *testing.T) { +func testRPCITLclStartSecondEngine(t *testing.T) { if ral2, err = engine.StopStartEngine(rpcITCfgPath2, *waitRater); err != nil { t.Fatal(err) } } // Connect rpc client to rater -func TestRPCITLclRpcConnPoolFirst(t *testing.T) { +func testRPCITLclRpcConnPoolFirst(t *testing.T) { rpcPoolFirst = rpcclient.NewRpcClientPool(rpcclient.POOL_FIRST, 0) rpcRAL1, err = rpcclient.NewRpcClient("tcp", rpcITCfg1.ListenCfg().RPCJSONListen, false, "", "", "", 3, 1, time.Duration(1*time.Second), time.Duration(2*time.Second), rpcclient.JSON_RPC, nil, false) @@ -93,7 +118,7 @@ func TestRPCITLclRpcConnPoolFirst(t *testing.T) { } // Connect rpc client to rater -func TestRPCITLclStatusSecondEngine(t *testing.T) { +func testRPCITLclStatusSecondEngine(t *testing.T) { var status map[string]interface{} if err := rpcPoolFirst.Call(utils.CoreSv1Status, utils.TenantWithArgDispatcher{}, &status); err != nil { t.Error(err) @@ -108,14 +133,14 @@ func TestRPCITLclStatusSecondEngine(t *testing.T) { } // Start first engine -func TestRPCITLclStartFirstEngine(t *testing.T) { +func testRPCITLclStartFirstEngine(t *testing.T) { if ral1, err = engine.StartEngine(rpcITCfgPath1, *waitRater); err != nil { t.Fatal(err) } } // Connect rpc client to rater -func TestRPCITLclStatusFirstInitial(t *testing.T) { +func testRPCITLclStatusFirstInitial(t *testing.T) { var status map[string]interface{} if err := rpcPoolFirst.Call(utils.CoreSv1Status, utils.TenantWithArgDispatcher{}, &status); err != nil { t.Error(err) @@ -132,7 +157,7 @@ func TestRPCITLclStatusFirstInitial(t *testing.T) { } // Connect rpc client to rater -func TestRPCITLclStatusFirstFailover(t *testing.T) { +func testRPCITLclStatusFirstFailover(t *testing.T) { if err := ral1.Process.Kill(); err != nil { // Kill the first RAL t.Error(err) } @@ -152,7 +177,7 @@ func TestRPCITLclStatusFirstFailover(t *testing.T) { } } -func TestRPCITLclStatusFirstFailback(t *testing.T) { +func testRPCITLclStatusFirstFailback(t *testing.T) { if ral1, err = engine.StartEngine(rpcITCfgPath1, *waitRater); err != nil { t.Fatal(err) } @@ -170,14 +195,14 @@ func TestRPCITLclStatusFirstFailback(t *testing.T) { } // Make sure it executes on the first node supporting the command -func TestRPCITLclTDirectedRPC(t *testing.T) { +func testRPCITLclTDirectedRPC(t *testing.T) { var sessions []*sessions.ExternalSession if err := rpcPoolFirst.Call(utils.SessionSv1GetActiveSessions, utils.SessionFilter{}, &sessions); err == nil || err.Error() != utils.ErrNotFound.Error() { t.Error(err) } } -// func TestRPCITLclTimeout(t *testing.T) { +// func testRPCITLclTimeout(t *testing.T) { // var status map[string]interface{} // if err := rpcPoolFirst.Call(utils.CoreSv1Status, "10s", &status); err == nil { // t.Error("Expecting timeout") @@ -187,13 +212,13 @@ func TestRPCITLclTDirectedRPC(t *testing.T) { // } // Connect rpc client to rater -func TestRPCITLclRpcConnPoolBcast(t *testing.T) { +func testRPCITLclRpcConnPoolBcast(t *testing.T) { rpcPoolBroadcast = rpcclient.NewRpcClientPool(rpcclient.POOL_BROADCAST, time.Duration(2*time.Second)) rpcPoolBroadcast.AddClient(rpcRAL1) rpcPoolBroadcast.AddClient(rpcRAL2) } -func TestRPCITLclBcastStatusInitial(t *testing.T) { +func testRPCITLclBcastStatusInitial(t *testing.T) { var status map[string]interface{} if err := rpcPoolBroadcast.Call(utils.CoreSv1Status, utils.TenantWithArgDispatcher{}, &status); err != nil { t.Error(err) @@ -207,7 +232,7 @@ func TestRPCITLclBcastStatusInitial(t *testing.T) { } } -func TestRPCITLclBcastStatusNoRals1(t *testing.T) { +func testRPCITLclBcastStatusNoRals1(t *testing.T) { if err := ral1.Process.Kill(); err != nil { // Kill the first RAL t.Error(err) } @@ -225,7 +250,7 @@ func TestRPCITLclBcastStatusNoRals1(t *testing.T) { } } -func TestRPCITLclBcastStatusBcastNoRals(t *testing.T) { +func testRPCITLclBcastStatusBcastNoRals(t *testing.T) { if err := ral2.Process.Kill(); err != nil { // Kill the first RAL t.Error(err) } @@ -236,7 +261,7 @@ func TestRPCITLclBcastStatusBcastNoRals(t *testing.T) { } } -func TestRPCITLclBcastStatusRALs2Up(t *testing.T) { +func testRPCITLclBcastStatusRALs2Up(t *testing.T) { if ral2, err = engine.StartEngine(rpcITCfgPath2, *waitRater); err != nil { t.Fatal(err) } @@ -253,7 +278,7 @@ func TestRPCITLclBcastStatusRALs2Up(t *testing.T) { } } -func TestRPCITLclStatusBcastRALs1Up(t *testing.T) { +func testRPCITLclStatusBcastRALs1Up(t *testing.T) { if ral1, err = engine.StartEngine(rpcITCfgPath1, *waitRater); err != nil { t.Fatal(err) } diff --git a/general_tests/sentinel_it_test.go b/general_tests/sentinel_it_test.go index b547e3aef..4e9433ab9 100755 --- a/general_tests/sentinel_it_test.go +++ b/general_tests/sentinel_it_test.go @@ -1,286 +1,286 @@ -// +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 general_tests - -import ( - "flag" - "net/rpc" - "net/rpc/jsonrpc" - "os/exec" - "path" - "reflect" - "testing" - - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" -) - -var ( - node1ConfigPath = path.Join(*dataDir, "redis_sentinel", "node1.conf") - node2ConfigPath = path.Join(*dataDir, "redis_sentinel", "node2.conf") - sentinel1ConfigPath = path.Join(*dataDir, "redis_sentinel", "sentinel1.conf") - sentinel2ConfigPath = path.Join(*dataDir, "redis_sentinel", "sentinel2.conf") - engineConfigPath = path.Join(*dataDir, "conf", "samples", "tutsentinel") - sentinelConfig *config.CGRConfig - sentinelRPC *rpc.Client - node1Exec, node2Exec, - stlExec1, stlExec2 *exec.Cmd - redisSentinel = flag.Bool("redis_sentinel", false, "Run tests with redis sentinel") -) - -var sTestsRds = []func(t *testing.T){ - testRedisSentinelStartNodes, - testRedisSentinelInitConfig, - testRedisSentinelFlushDb, - testRedisSentinelStartEngine, - testRedisSentinelRPCCon, - testRedisSentinelSetGetAttribute, - testRedisSentinelInsertion, - testRedisSentinelGetAttrAfterFailover, - testRedisSentinelKillEngine, -} - -// Before running these tests make sure node1.conf, node2.conf, sentinel1.conf are the next -// Node1 will be master and start at port 16379 -// Node2 will be slave of node1 and start at port 16380 -// Sentinel1 will be started at port 16381 and will watch Node1 -// Sentinel2 will be started at port 16382 and will watch Node1 -func TestRedisSentinel(t *testing.T) { - if !*redisSentinel { - return - } - for _, stest := range sTestsRds { - t.Run("", stest) - } -} - -func testRedisSentinelStartNodes(t *testing.T) { - node1Exec = exec.Command("redis-server", node1ConfigPath) - if err := node1Exec.Start(); err != nil { - t.Error(err) - } - node2Exec = exec.Command("redis-server", node2ConfigPath) - if err := node2Exec.Start(); err != nil { - t.Error(err) - } - stlExec1 = exec.Command("redis-sentinel", sentinel1ConfigPath) - if err := stlExec1.Start(); err != nil { - t.Error(err) - } - stlExec2 = exec.Command("redis-sentinel", sentinel2ConfigPath) - if err := stlExec2.Start(); err != nil { - t.Error(err) - } -} - -func testRedisSentinelInitConfig(t *testing.T) { - var err error - sentinelConfig, err = config.NewCGRConfigFromPath(engineConfigPath) - if err != nil { - t.Error(err) - } - sentinelConfig.DataFolderPath = *dataDir // Share DataFolderPath through config towards StoreDb for Flush() - config.SetCgrConfig(sentinelConfig) -} - -func testRedisSentinelFlushDb(t *testing.T) { - if err := engine.InitDataDb(sentinelConfig); err != nil { - t.Fatal(err) - } -} - -func testRedisSentinelStartEngine(t *testing.T) { - if _, err := engine.StopStartEngine(engineConfigPath, 2000); err != nil { - t.Fatal(err) - } -} - -func testRedisSentinelRPCCon(t *testing.T) { - var err error - sentinelRPC, err = jsonrpc.Dial("tcp", sentinelConfig.ListenCfg().RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed - if err != nil { - t.Fatal(err) - } -} - -func testRedisSentinelSetGetAttribute(t *testing.T) { - alsPrf := &engine.AttributeProfile{ - Tenant: "cgrates.org", - ID: "ApierTest", - Contexts: []string{utils.MetaSessionS, utils.MetaCDRs}, - FilterIDs: []string{"*string:Account:1001"}, - Attributes: []*engine.Attribute{ - { - FieldName: utils.Subject, - Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), - }, - }, - Weight: 20, - } - alsPrf.Compile() - var result string - if err := sentinelRPC.Call("ApierV1.SetAttributeProfile", alsPrf, &result); err != nil { - t.Error(err) - } else if result != utils.OK { - t.Error("Unexpected reply returned", result) - } - var reply *engine.AttributeProfile - if err := sentinelRPC.Call("ApierV1.GetAttributeProfile", - &utils.TenantID{Tenant: "cgrates.org", ID: "ApierTest"}, &reply); err != nil { - t.Error(err) - } - reply.Compile() - if !reflect.DeepEqual(alsPrf, reply) { - t.Errorf("Expecting : %+v, received: %+v", alsPrf, reply) - } -} - -func testRedisSentinelInsertion(t *testing.T) { - nrFails1 := 0 - nrFails2 := 0 - alsPrf := &engine.AttributeProfile{ - Tenant: "cgrates.org", - ID: "ApierTest", - Contexts: []string{utils.MetaSessionS, utils.MetaCDRs}, - FilterIDs: []string{"*string:Account:1001"}, - Attributes: []*engine.Attribute{ - { - FieldName: utils.Subject, - Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), - }, - }, - Weight: 20, - } - orgiginID := alsPrf.ID + "_" - id := alsPrf.ID + "_0" - index := 0 - var result string - addFunc := func(t *testing.T, nrFail *int) { - alsPrf.ID = id - if err := sentinelRPC.Call("ApierV1.SetAttributeProfile", alsPrf, &result); err != nil { - if err.Error() == "SERVER_ERROR: No sentinels active" { - *nrFail = *nrFail + 1 - } else { - t.Error(err) - } - } - index = index + 1 - id = orgiginID + string(index) - } - forFunc1 := func(t *testing.T) { - for i := 0; i < 25; i++ { - t.Run("add", func(t *testing.T) { - t.Parallel() - addFunc(t, &nrFails1) - }) - if i == 5 { - t.Run("stop1", func(t *testing.T) { - t.Parallel() - if err := stlExec1.Process.Kill(); err != nil { - t.Error(err) - } - }) - } - if i == 10 { - t.Run("stop2", func(t *testing.T) { - t.Parallel() - if err := stlExec2.Process.Kill(); err != nil { - t.Error(err) - } - }) - } - t.Run("add2", func(t *testing.T) { - t.Parallel() - addFunc(t, &nrFails1) - }) - } - } - forFunc2 := func(t *testing.T) { - for i := 0; i < 10; i++ { - t.Run("add", func(t *testing.T) { - t.Parallel() - addFunc(t, &nrFails2) - }) - t.Run("add2", func(t *testing.T) { - t.Parallel() - addFunc(t, &nrFails2) - }) - } - } - t.Run("for1", forFunc1) - if nrFails1 == 0 { - t.Error("Fail tests in case of failover") - } - if err := exec.Command("redis-sentinel", sentinel1ConfigPath).Start(); err != nil { // Kill the master - t.Error(err) - } - t.Run("for2", forFunc2) - if nrFails2 > 19 { - t.Errorf("Fail tests in case of failback ") - } -} - -// After we kill node1 check the data if was replicated in node2 -func testRedisSentinelGetAttrAfterFailover(t *testing.T) { - alsPrf := &engine.AttributeProfile{ - Tenant: "cgrates.org", - ID: "ApierTest", - Contexts: []string{utils.MetaSessionS, utils.MetaCDRs}, - FilterIDs: []string{"*string:Account:1001"}, - Attributes: []*engine.Attribute{ - { - FieldName: utils.Subject, - Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), - }, - }, - Weight: 20, - } - alsPrf.Compile() - var reply *engine.AttributeProfile - if err := sentinelRPC.Call("ApierV1.GetAttributeProfile", - &utils.TenantID{Tenant: "cgrates.org", ID: "ApierTest"}, &reply); err != nil { - t.Error(err) - } - reply.Compile() - if !reflect.DeepEqual(alsPrf, reply) { - t.Errorf("Expecting : %+v, received: %+v", alsPrf, reply) - } -} - -func testRedisSentinelKillEngine(t *testing.T) { - if err := exec.Command("pkill", "redis-server").Run(); err != nil { - t.Error(err) - } - if err := exec.Command("pkill", "redis-sentinel").Run(); err != nil { - t.Error(err) - } - if err := exec.Command("pkill", "redis-ser").Run(); err != nil { - t.Error(err) - } - if err := exec.Command("pkill", "redis-sen").Run(); err != nil { - t.Error(err) - } - - if err := engine.KillEngine(2000); err != nil { - t.Error(err) - } -} +// +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 general_tests + +import ( + "flag" + "net/rpc" + "net/rpc/jsonrpc" + "os/exec" + "path" + "reflect" + "testing" + + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" +) + +var ( + node1ConfigPath = path.Join(*dataDir, "redis_sentinel", "node1.conf") + node2ConfigPath = path.Join(*dataDir, "redis_sentinel", "node2.conf") + sentinel1ConfigPath = path.Join(*dataDir, "redis_sentinel", "sentinel1.conf") + sentinel2ConfigPath = path.Join(*dataDir, "redis_sentinel", "sentinel2.conf") + engineConfigPath = path.Join(*dataDir, "conf", "samples", "tutsentinel") + sentinelConfig *config.CGRConfig + sentinelRPC *rpc.Client + node1Exec, node2Exec, + stlExec1, stlExec2 *exec.Cmd + redisSentinel = flag.Bool("redis_sentinel", false, "Run tests with redis sentinel") + + sTestsRds = []func(t *testing.T){ + testRedisSentinelStartNodes, + testRedisSentinelInitConfig, + testRedisSentinelFlushDb, + testRedisSentinelStartEngine, + testRedisSentinelRPCCon, + testRedisSentinelSetGetAttribute, + testRedisSentinelInsertion, + testRedisSentinelGetAttrAfterFailover, + testRedisSentinelKillEngine, + } +) + +// Before running these tests make sure node1.conf, node2.conf, sentinel1.conf are the next +// Node1 will be master and start at port 16379 +// Node2 will be slave of node1 and start at port 16380 +// Sentinel1 will be started at port 16381 and will watch Node1 +// Sentinel2 will be started at port 16382 and will watch Node1 +func TestRedisSentinel(t *testing.T) { + if !*redisSentinel { + return + } + for _, stest := range sTestsRds { + t.Run("", stest) + } +} + +func testRedisSentinelStartNodes(t *testing.T) { + node1Exec = exec.Command("redis-server", node1ConfigPath) + if err := node1Exec.Start(); err != nil { + t.Error(err) + } + node2Exec = exec.Command("redis-server", node2ConfigPath) + if err := node2Exec.Start(); err != nil { + t.Error(err) + } + stlExec1 = exec.Command("redis-sentinel", sentinel1ConfigPath) + if err := stlExec1.Start(); err != nil { + t.Error(err) + } + stlExec2 = exec.Command("redis-sentinel", sentinel2ConfigPath) + if err := stlExec2.Start(); err != nil { + t.Error(err) + } +} + +func testRedisSentinelInitConfig(t *testing.T) { + var err error + sentinelConfig, err = config.NewCGRConfigFromPath(engineConfigPath) + if err != nil { + t.Error(err) + } + sentinelConfig.DataFolderPath = *dataDir // Share DataFolderPath through config towards StoreDb for Flush() + config.SetCgrConfig(sentinelConfig) +} + +func testRedisSentinelFlushDb(t *testing.T) { + if err := engine.InitDataDb(sentinelConfig); err != nil { + t.Fatal(err) + } +} + +func testRedisSentinelStartEngine(t *testing.T) { + if _, err := engine.StopStartEngine(engineConfigPath, 2000); err != nil { + t.Fatal(err) + } +} + +func testRedisSentinelRPCCon(t *testing.T) { + var err error + sentinelRPC, err = jsonrpc.Dial("tcp", sentinelConfig.ListenCfg().RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed + if err != nil { + t.Fatal(err) + } +} + +func testRedisSentinelSetGetAttribute(t *testing.T) { + alsPrf := &engine.AttributeProfile{ + Tenant: "cgrates.org", + ID: "ApierTest", + Contexts: []string{utils.MetaSessionS, utils.MetaCDRs}, + FilterIDs: []string{"*string:Account:1001"}, + Attributes: []*engine.Attribute{ + { + FieldName: utils.Subject, + Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), + }, + }, + Weight: 20, + } + alsPrf.Compile() + var result string + if err := sentinelRPC.Call("ApierV1.SetAttributeProfile", alsPrf, &result); err != nil { + t.Error(err) + } else if result != utils.OK { + t.Error("Unexpected reply returned", result) + } + var reply *engine.AttributeProfile + if err := sentinelRPC.Call("ApierV1.GetAttributeProfile", + &utils.TenantID{Tenant: "cgrates.org", ID: "ApierTest"}, &reply); err != nil { + t.Error(err) + } + reply.Compile() + if !reflect.DeepEqual(alsPrf, reply) { + t.Errorf("Expecting : %+v, received: %+v", alsPrf, reply) + } +} + +func testRedisSentinelInsertion(t *testing.T) { + nrFails1 := 0 + nrFails2 := 0 + alsPrf := &engine.AttributeProfile{ + Tenant: "cgrates.org", + ID: "ApierTest", + Contexts: []string{utils.MetaSessionS, utils.MetaCDRs}, + FilterIDs: []string{"*string:Account:1001"}, + Attributes: []*engine.Attribute{ + { + FieldName: utils.Subject, + Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), + }, + }, + Weight: 20, + } + orgiginID := alsPrf.ID + "_" + id := alsPrf.ID + "_0" + index := 0 + var result string + addFunc := func(t *testing.T, nrFail *int) { + alsPrf.ID = id + if err := sentinelRPC.Call("ApierV1.SetAttributeProfile", alsPrf, &result); err != nil { + if err.Error() == "SERVER_ERROR: No sentinels active" { + *nrFail = *nrFail + 1 + } else { + t.Error(err) + } + } + index = index + 1 + id = orgiginID + string(index) + } + forFunc1 := func(t *testing.T) { + for i := 0; i < 25; i++ { + t.Run("add", func(t *testing.T) { + t.Parallel() + addFunc(t, &nrFails1) + }) + if i == 5 { + t.Run("stop1", func(t *testing.T) { + t.Parallel() + if err := stlExec1.Process.Kill(); err != nil { + t.Error(err) + } + }) + } + if i == 10 { + t.Run("stop2", func(t *testing.T) { + t.Parallel() + if err := stlExec2.Process.Kill(); err != nil { + t.Error(err) + } + }) + } + t.Run("add2", func(t *testing.T) { + t.Parallel() + addFunc(t, &nrFails1) + }) + } + } + forFunc2 := func(t *testing.T) { + for i := 0; i < 10; i++ { + t.Run("add", func(t *testing.T) { + t.Parallel() + addFunc(t, &nrFails2) + }) + t.Run("add2", func(t *testing.T) { + t.Parallel() + addFunc(t, &nrFails2) + }) + } + } + t.Run("for1", forFunc1) + if nrFails1 == 0 { + t.Error("Fail tests in case of failover") + } + if err := exec.Command("redis-sentinel", sentinel1ConfigPath).Start(); err != nil { // Kill the master + t.Error(err) + } + t.Run("for2", forFunc2) + if nrFails2 > 19 { + t.Errorf("Fail tests in case of failback ") + } +} + +// After we kill node1 check the data if was replicated in node2 +func testRedisSentinelGetAttrAfterFailover(t *testing.T) { + alsPrf := &engine.AttributeProfile{ + Tenant: "cgrates.org", + ID: "ApierTest", + Contexts: []string{utils.MetaSessionS, utils.MetaCDRs}, + FilterIDs: []string{"*string:Account:1001"}, + Attributes: []*engine.Attribute{ + { + FieldName: utils.Subject, + Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), + }, + }, + Weight: 20, + } + alsPrf.Compile() + var reply *engine.AttributeProfile + if err := sentinelRPC.Call("ApierV1.GetAttributeProfile", + &utils.TenantID{Tenant: "cgrates.org", ID: "ApierTest"}, &reply); err != nil { + t.Error(err) + } + reply.Compile() + if !reflect.DeepEqual(alsPrf, reply) { + t.Errorf("Expecting : %+v, received: %+v", alsPrf, reply) + } +} + +func testRedisSentinelKillEngine(t *testing.T) { + if err := exec.Command("pkill", "redis-server").Run(); err != nil { + t.Error(err) + } + if err := exec.Command("pkill", "redis-sentinel").Run(); err != nil { + t.Error(err) + } + if err := exec.Command("pkill", "redis-ser").Run(); err != nil { + t.Error(err) + } + if err := exec.Command("pkill", "redis-sen").Run(); err != nil { + t.Error(err) + } + + if err := engine.KillEngine(2000); err != nil { + t.Error(err) + } +} diff --git a/general_tests/session2_it_test.go b/general_tests/session2_it_test.go index ebb6754a0..579e9c7da 100644 --- a/general_tests/session2_it_test.go +++ b/general_tests/session2_it_test.go @@ -40,15 +40,15 @@ var ( ses2RPC *rpc.Client ses2Tests = []func(t *testing.T){ - testSesItLoadConfig, - testSesItResetDataDB, - testSesItResetStorDb, - testSesItStartEngine, - testSesItRPCConn, - testSesItLoadFromFolder, - testSesItInitSession, - testSesItAsActiveSessions, - testSesItStopCgrEngine, + testSes2ItLoadConfig, + testSes2ItResetDataDB, + testSes2ItResetStorDb, + testSes2ItStartEngine, + testSes2ItRPCConn, + testSes2ItLoadFromFolder, + testSes2ItInitSession, + testSes2ItAsActiveSessions, + testSes2ItStopCgrEngine, } ) @@ -66,32 +66,32 @@ func TestSes2ItTutMysql(t *testing.T) { } } -func testSesItLoadConfig(t *testing.T) { +func testSes2ItLoadConfig(t *testing.T) { ses2CfgPath = path.Join(*dataDir, "conf", "samples", ses2CfgDir) if ses2Cfg, err = config.NewCGRConfigFromPath(ses2CfgPath); err != nil { t.Error(err) } } -func testSesItResetDataDB(t *testing.T) { +func testSes2ItResetDataDB(t *testing.T) { if err := engine.InitDataDb(ses2Cfg); err != nil { t.Fatal(err) } } -func testSesItResetStorDb(t *testing.T) { +func testSes2ItResetStorDb(t *testing.T) { if err := engine.InitStorDb(ses2Cfg); err != nil { t.Fatal(err) } } -func testSesItStartEngine(t *testing.T) { +func testSes2ItStartEngine(t *testing.T) { if _, err := engine.StopStartEngine(ses2CfgPath, *waitRater); err != nil { t.Fatal(err) } } -func testSesItRPCConn(t *testing.T) { +func testSes2ItRPCConn(t *testing.T) { var err error ses2RPC, err = jsonrpc.Dial("tcp", ses2Cfg.ListenCfg().RPCJSONListen) if err != nil { @@ -99,7 +99,7 @@ func testSesItRPCConn(t *testing.T) { } } -func testSesItLoadFromFolder(t *testing.T) { +func testSes2ItLoadFromFolder(t *testing.T) { var reply string attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "tutorial")} if err := ses2RPC.Call("ApierV1.LoadTariffPlanFromFolder", attrs, &reply); err != nil { @@ -108,7 +108,7 @@ func testSesItLoadFromFolder(t *testing.T) { time.Sleep(500 * time.Millisecond) } -func testSesItInitSession(t *testing.T) { +func testSes2ItInitSession(t *testing.T) { // Set balance attrSetBalance := utils.AttrSetBalance{ Tenant: "cgrates.org", @@ -151,7 +151,7 @@ func testSesItInitSession(t *testing.T) { } -func testSesItAsActiveSessions(t *testing.T) { +func testSes2ItAsActiveSessions(t *testing.T) { var count int if err := ses2RPC.Call(utils.SessionSv1GetActiveSessionsCount, utils.SessionFilter{ Filters: []string{"*string:~Account:1001"}, @@ -169,7 +169,7 @@ func testSesItAsActiveSessions(t *testing.T) { } } -func testSesItStopCgrEngine(t *testing.T) { +func testSes2ItStopCgrEngine(t *testing.T) { if err := engine.KillEngine(100); err != nil { t.Error(err) } diff --git a/general_tests/session_it_test.go b/general_tests/session_it_test.go index e92d97630..d2bd31f32 100644 --- a/general_tests/session_it_test.go +++ b/general_tests/session_it_test.go @@ -38,35 +38,54 @@ var ( sesRPC *rpc.Client sesAccount = "refundAcc" sesTenant = "cgrates.org" + + sTestSesIt = []func(t *testing.T){ + testSesItLoadConfig, + testSesItResetDataDB, + testSesItResetStorDb, + testSesItStartEngine, + testSesItRPCConn, + testSesItLoadFromFolder, + testSesItAddVoiceBalance, + testSesItInitSession, + testSesItTerminateSession, + testSesItStopCgrEngine, + } ) +func TestSesIt(t *testing.T) { + for _, stest := range sTestSesIt { + t.Run("TestSesIT", stest) + } +} + // test for 0 balance with session terminate with 1s usage -func TestSesItLoadConfig(t *testing.T) { +func testSesItLoadConfig(t *testing.T) { sesCfgPath = path.Join(*dataDir, "conf", "samples", "tutmysql_internal") if sesCfg, err = config.NewCGRConfigFromPath(sesCfgPath); err != nil { t.Error(err) } } -func TestSesItResetDataDB(t *testing.T) { +func testSesItResetDataDB(t *testing.T) { if err := engine.InitDataDb(sesCfg); err != nil { t.Fatal(err) } } -func TestSesItResetStorDb(t *testing.T) { +func testSesItResetStorDb(t *testing.T) { if err := engine.InitStorDb(sesCfg); err != nil { t.Fatal(err) } } -func TestSesItStartEngine(t *testing.T) { +func testSesItStartEngine(t *testing.T) { if _, err := engine.StopStartEngine(sesCfgPath, *waitRater); err != nil { t.Fatal(err) } } -func TestSesItRPCConn(t *testing.T) { +func testSesItRPCConn(t *testing.T) { var err error sesRPC, err = jsonrpc.Dial("tcp", sesCfg.ListenCfg().RPCJSONListen) if err != nil { @@ -74,7 +93,7 @@ func TestSesItRPCConn(t *testing.T) { } } -func TestSesItLoadFromFolder(t *testing.T) { +func testSesItLoadFromFolder(t *testing.T) { var reply string attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "testit")} if err := sesRPC.Call("ApierV1.LoadTariffPlanFromFolder", attrs, &reply); err != nil { @@ -97,7 +116,7 @@ func testAccountBalance2(t *testing.T, sracc, srten, balType string, expected fl } } -func TestSesItAddVoiceBalance(t *testing.T) { +func testSesItAddVoiceBalance(t *testing.T) { attrSetBalance := utils.AttrSetBalance{ Tenant: sesTenant, Account: sesAccount, @@ -115,7 +134,7 @@ func TestSesItAddVoiceBalance(t *testing.T) { t.Run("TestAddVoiceBalance", func(t *testing.T) { testAccountBalance2(t, sesAccount, sesTenant, utils.MONETARY, 0) }) } -func TestSesItInitSession(t *testing.T) { +func testSesItInitSession(t *testing.T) { args1 := &sessions.V1InitSessionArgs{ InitSession: true, CGREvent: &utils.CGREvent{ @@ -147,7 +166,7 @@ func TestSesItInitSession(t *testing.T) { t.Run("TestInitSession", func(t *testing.T) { testAccountBalance2(t, sesAccount, sesTenant, utils.MONETARY, 0) }) } -func TestSesItTerminateSession(t *testing.T) { +func testSesItTerminateSession(t *testing.T) { args := &sessions.V1TerminateSessionArgs{ TerminateSession: true, CGREvent: &utils.CGREvent{ @@ -184,7 +203,7 @@ func TestSesItTerminateSession(t *testing.T) { t.Run("TestTerminateSession", func(t *testing.T) { testAccountBalance2(t, sesAccount, sesTenant, utils.MONETARY, 0) }) } -func TestSesItStopCgrEngine(t *testing.T) { +func testSesItStopCgrEngine(t *testing.T) { if err := engine.KillEngine(100); err != nil { t.Error(err) } diff --git a/general_tests/sessionrefund_it_test.go b/general_tests/sessionrefund_it_test.go index 669c019c0..55364fed9 100644 --- a/general_tests/sessionrefund_it_test.go +++ b/general_tests/sessionrefund_it_test.go @@ -38,34 +38,56 @@ var ( srrpc *rpc.Client sraccount = "refundAcc" srtenant = "cgrates.org" + + sTestSrIt = []func(t *testing.T){ + testSrItLoadConfig, + testSrItResetDataDB, + testSrItResetStorDb, + testSrItStartEngine, + testSrItRPCConn, + testSrItLoadFromFolder, + testSrItAddVoiceBalance, + testSrItInitSession, + testSrItTerminateSession, + testSrItAddMonetaryBalance, + testSrItInitSession2, + testSrItTerminateSession2, + testSrItStopCgrEngine, + } ) -func TestSrItLoadConfig(t *testing.T) { +func TestSrIt(t *testing.T) { + for _, stest := range sTestSrIt { + t.Run("sTestSrIt", stest) + } +} + +func testSrItLoadConfig(t *testing.T) { srCfgPath = path.Join(*dataDir, "conf", "samples", "tutmongo") if srCfg, err = config.NewCGRConfigFromPath(srCfgPath); err != nil { t.Error(err) } } -func TestSrItResetDataDB(t *testing.T) { +func testSrItResetDataDB(t *testing.T) { if err := engine.InitDataDb(srCfg); err != nil { t.Fatal(err) } } -func TestSrItResetStorDb(t *testing.T) { +func testSrItResetStorDb(t *testing.T) { if err := engine.InitStorDb(srCfg); err != nil { t.Fatal(err) } } -func TestSrItStartEngine(t *testing.T) { +func testSrItStartEngine(t *testing.T) { if _, err := engine.StopStartEngine(srCfgPath, *waitRater); err != nil { t.Fatal(err) } } -func TestSrItRPCConn(t *testing.T) { +func testSrItRPCConn(t *testing.T) { var err error srrpc, err = jsonrpc.Dial("tcp", srCfg.ListenCfg().RPCJSONListen) if err != nil { @@ -73,7 +95,7 @@ func TestSrItRPCConn(t *testing.T) { } } -func TestSrItLoadFromFolder(t *testing.T) { +func testSrItLoadFromFolder(t *testing.T) { var reply string attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "oldtutorial")} if err := srrpc.Call("ApierV1.LoadTariffPlanFromFolder", attrs, &reply); err != nil { @@ -96,7 +118,7 @@ func testAccountBalance(t *testing.T, sracc, srten, balType string, expected flo } } -func TestSrItAddVoiceBalance(t *testing.T) { +func testSrItAddVoiceBalance(t *testing.T) { attrSetBalance := utils.AttrSetBalance{ Tenant: srtenant, Account: sraccount, @@ -114,7 +136,7 @@ func TestSrItAddVoiceBalance(t *testing.T) { t.Run("TestAddVoiceBalance", func(t *testing.T) { testAccountBalance(t, sraccount, srtenant, utils.VOICE, 5*float64(time.Second)) }) } -func TestSrItInitSession(t *testing.T) { +func testSrItInitSession(t *testing.T) { args1 := &sessions.V1InitSessionArgs{ InitSession: true, CGREvent: &utils.CGREvent{ @@ -146,7 +168,7 @@ func TestSrItInitSession(t *testing.T) { t.Run("TestInitSession", func(t *testing.T) { testAccountBalance(t, sraccount, srtenant, utils.VOICE, 3*float64(time.Second)) }) } -func TestSrItTerminateSession(t *testing.T) { +func testSrItTerminateSession(t *testing.T) { args := &sessions.V1TerminateSessionArgs{ TerminateSession: true, CGREvent: &utils.CGREvent{ @@ -183,7 +205,7 @@ func TestSrItTerminateSession(t *testing.T) { t.Run("TestTerminateSession", func(t *testing.T) { testAccountBalance(t, sraccount, srtenant, utils.VOICE, 5*float64(time.Second)) }) } -func TestSrItAddMonetaryBalance(t *testing.T) { +func testSrItAddMonetaryBalance(t *testing.T) { sraccount += "2" attrs := &utils.AttrSetBalance{ Tenant: srtenant, @@ -201,7 +223,7 @@ func TestSrItAddMonetaryBalance(t *testing.T) { t.Run("TestAddMonetaryBalance", func(t *testing.T) { testAccountBalance(t, sraccount, srtenant, utils.MONETARY, 10.65) }) } -func TestSrItInitSession2(t *testing.T) { +func testSrItInitSession2(t *testing.T) { args1 := &sessions.V1InitSessionArgs{ InitSession: true, CGREvent: &utils.CGREvent{ @@ -233,7 +255,7 @@ func TestSrItInitSession2(t *testing.T) { t.Run("TestInitSession", func(t *testing.T) { testAccountBalance(t, sraccount, srtenant, utils.MONETARY, 10.3002) }) } -func TestSrItTerminateSession2(t *testing.T) { +func testSrItTerminateSession2(t *testing.T) { args := &sessions.V1TerminateSessionArgs{ TerminateSession: true, CGREvent: &utils.CGREvent{ @@ -270,7 +292,7 @@ func TestSrItTerminateSession2(t *testing.T) { t.Run("TestTerminateSession", func(t *testing.T) { testAccountBalance(t, sraccount, srtenant, utils.MONETARY, 10.65) }) } -func TestSrItStopCgrEngine(t *testing.T) { +func testSrItStopCgrEngine(t *testing.T) { if err := engine.KillEngine(100); err != nil { t.Error(err) } diff --git a/general_tests/supplier_it_test.go b/general_tests/supplier_it_test.go index 39f7cf46b..42a428275 100644 --- a/general_tests/supplier_it_test.go +++ b/general_tests/supplier_it_test.go @@ -39,26 +39,26 @@ var ( splSv1Rpc *rpc.Client splPrf *engine.SupplierProfile splSv1ConfDIR string //run tests for specific configuration -) -var sTestsSupplierSV1 = []func(t *testing.T){ - testV1SplSLoadConfig, - testV1SplSInitDataDb, - testV1SplSResetStorDb, - testV1SplSStartEngine, - testV1SplSRpcConn, - testV1SplSFromFolder, - testV1SplSSetSupplierProfilesWithoutRatingPlanIDs, - //tests for *reas sorting strategy - testV1SplSAddNewSplPrf, - testV1SplSAddNewResPrf, - testV1SplSPopulateResUsage, - testV1SplSGetSortedSuppliers, - //tests for *reds sorting strategy - testV1SplSAddNewSplPrf2, - testV1SplSGetSortedSuppliers2, - testV1SplSStopEngine, -} + sTestsSupplierSV1 = []func(t *testing.T){ + testV1SplSLoadConfig, + testV1SplSInitDataDb, + testV1SplSResetStorDb, + testV1SplSStartEngine, + testV1SplSRpcConn, + testV1SplSFromFolder, + testV1SplSSetSupplierProfilesWithoutRatingPlanIDs, + //tests for *reas sorting strategy + testV1SplSAddNewSplPrf, + testV1SplSAddNewResPrf, + testV1SplSPopulateResUsage, + testV1SplSGetSortedSuppliers, + //tests for *reds sorting strategy + testV1SplSAddNewSplPrf2, + testV1SplSGetSortedSuppliers2, + testV1SplSStopEngine, + } +) // Test start here func TestSuplSV1ITMySQL(t *testing.T) { diff --git a/general_tests/suretax_it_test.go b/general_tests/suretax_it_test.go index 92d1d425e..224845a74 100644 --- a/general_tests/suretax_it_test.go +++ b/general_tests/suretax_it_test.go @@ -38,14 +38,35 @@ Integration tests with SureTax platform. Configuration file is kept outside of CGRateS repository since it contains sensitive customer information */ -var configDir = flag.String("config_path", "", "CGR config dir path here") -var tpDir = flag.String("tp_dir", "", "CGR config dir path here") +var ( + configDir = flag.String("config_path", "", "CGR config dir path here") + tpDir = flag.String("tp_dir", "", "CGR config dir path here") -var stiCfg *config.CGRConfig -var stiRpc *rpc.Client -var stiLoadInst utils.LoadInstance + stiCfg *config.CGRConfig + stiRpc *rpc.Client + stiLoadInst utils.LoadInstance -func TestSTIInitCfg(t *testing.T) { + sTestSTI = []func(t *testing.T){ + testSTIInitCfg, + testSTIResetDataDb, + testSTIResetStorDb, + testSTIStartEngine, + testSTIRpcConn, + testSTILoadTariffPlanFromFolder, + testSTICacheStats, + testSTIProcessExternalCdr, + testSTIGetCdrs, + testSTIStopCgrEngine, + } +) + +func TestSTI(t *testing.T) { + for _, stest := range sTestSTI { + t.Run("TestSTI", stest) + } +} + +func testSTIInitCfg(t *testing.T) { // Init config first var err error stiCfg, err = config.NewCGRConfigFromPath(*configDir) @@ -55,28 +76,28 @@ func TestSTIInitCfg(t *testing.T) { } // Remove data in both rating and accounting db -func TestSTIResetDataDb(t *testing.T) { +func testSTIResetDataDb(t *testing.T) { if err := engine.InitDataDb(stiCfg); err != nil { t.Fatal(err) } } // Wipe out the cdr database -func TestSTIResetStorDb(t *testing.T) { +func testSTIResetStorDb(t *testing.T) { if err := engine.InitStorDb(stiCfg); err != nil { t.Fatal(err) } } // Start CGR Engine -func TestSTIStartEngine(t *testing.T) { +func testSTIStartEngine(t *testing.T) { if _, err := engine.StopStartEngine(*configDir, *waitRater); err != nil { t.Fatal(err) } } // Connect rpc client to rater -func TestSTIRpcConn(t *testing.T) { +func testSTIRpcConn(t *testing.T) { var err error stiRpc, err = jsonrpc.Dial("tcp", stiCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed if err != nil { @@ -85,7 +106,7 @@ func TestSTIRpcConn(t *testing.T) { } // Load the tariff plan, creating accounts and their balances -func TestSTILoadTariffPlanFromFolder(t *testing.T) { +func testSTILoadTariffPlanFromFolder(t *testing.T) { attrs := &utils.AttrLoadTpFromFolder{FolderPath: *tpDir} if err := stiRpc.Call("ApierV2.LoadTariffPlanFromFolder", attrs, &stiLoadInst); err != nil { t.Error(err) @@ -96,7 +117,7 @@ func TestSTILoadTariffPlanFromFolder(t *testing.T) { } // Check loaded stats -func TestSTICacheStats(t *testing.T) { +func testSTICacheStats(t *testing.T) { var rcvStats *utils.CacheStats expectedStats := &utils.CacheStats{Destinations: 1, RatingPlans: 1, RatingProfiles: 1} var args utils.AttrCacheStats @@ -108,7 +129,7 @@ func TestSTICacheStats(t *testing.T) { } // Test CDR from external sources -func TestSTIProcessExternalCdr(t *testing.T) { +func testSTIProcessExternalCdr(t *testing.T) { cdr := &engine.ExternalCDR{ToR: utils.VOICE, OriginID: "teststicdr1", OriginHost: "192.168.1.1", Source: "STI_TEST", RequestType: utils.META_RATED, Direction: utils.META_OUT, Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "+14082342500", Destination: "+16268412300", Supplier: "SUPPL1", @@ -124,7 +145,7 @@ func TestSTIProcessExternalCdr(t *testing.T) { time.Sleep(time.Duration(2) * time.Second) } -func TestSTIGetCdrs(t *testing.T) { +func testSTIGetCdrs(t *testing.T) { var cdrs []*engine.ExternalCDR req := utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}, Accounts: []string{"1001"}} if err := stiRpc.Call(utils.ApierV2GetCDRs, req, &cdrs); err != nil { @@ -148,7 +169,7 @@ func TestSTIGetCdrs(t *testing.T) { } } -func TestSTIStopCgrEngine(t *testing.T) { +func testSTIStopCgrEngine(t *testing.T) { if err := engine.KillEngine(100); err != nil { t.Error(err) } diff --git a/general_tests/tls_it_test.go b/general_tests/tls_it_test.go index 6228ea8ae..02ae36b85 100755 --- a/general_tests/tls_it_test.go +++ b/general_tests/tls_it_test.go @@ -1,168 +1,168 @@ -// +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 general_tests - -import ( - "path" - "testing" - "time" - - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/sessions" - "github.com/cgrates/cgrates/utils" - "github.com/cgrates/rpcclient" -) - -var ( - tlsCfgPath string - tlsCfg *config.CGRConfig - tlsRpcClientJson *rpcclient.RpcClient - tlsRpcClientGob *rpcclient.RpcClient - tlsHTTPJson *rpcclient.RpcClient - tlsConfDIR string //run tests for specific configuration - tlsDelay int -) - -var sTestsTLS = []func(t *testing.T){ - testTLSLoadConfig, - testTLSInitDataDb, - testTLSStartEngine, - testTLSRpcConn, - testTLSPing, - testTLSStopEngine, -} - -// Test start here -func TestTLS(t *testing.T) { - tlsConfDIR = "tls" - for _, stest := range sTestsTLS { - t.Run(tlsConfDIR, stest) - } -} - -func testTLSLoadConfig(t *testing.T) { - var err error - tlsCfgPath = path.Join(*dataDir, "conf", "samples", tlsConfDIR) - if tlsCfg, err = config.NewCGRConfigFromPath(tlsCfgPath); err != nil { - t.Error(err) - } - tlsDelay = 2000 -} - -func testTLSInitDataDb(t *testing.T) { - if err := engine.InitDataDb(tlsCfg); err != nil { - t.Fatal(err) - } -} - -func testTLSStartEngine(t *testing.T) { - if _, err := engine.StopStartEngine(tlsCfgPath, tlsDelay); err != nil { - t.Fatal(err) - } -} - -func testTLSRpcConn(t *testing.T) { - var err error - tlsRpcClientJson, err = rpcclient.NewRpcClient("tcp", "localhost:2022", true, tlsCfg.TlsCfg().ClientKey, - tlsCfg.TlsCfg().ClientCerificate, tlsCfg.TlsCfg().CaCertificate, 3, 3, - time.Duration(1*time.Second), time.Duration(5*time.Minute), utils.JSON, nil, false) - if err != nil { - t.Errorf("Error: %s when dialing", err) - } - - tlsRpcClientGob, err = rpcclient.NewRpcClient("tcp", "localhost:2023", true, tlsCfg.TlsCfg().ClientKey, - tlsCfg.TlsCfg().ClientCerificate, tlsCfg.TlsCfg().CaCertificate, 3, 3, - time.Duration(1*time.Second), time.Duration(5*time.Minute), utils.GOB, nil, false) - if err != nil { - t.Errorf("Error: %s when dialing", err) - } - - tlsHTTPJson, err = rpcclient.NewRpcClient("tcp", "https://localhost:2280/jsonrpc", true, tlsCfg.TlsCfg().ClientKey, - tlsCfg.TlsCfg().ClientCerificate, tlsCfg.TlsCfg().CaCertificate, 3, 3, - time.Duration(1*time.Second), time.Duration(5*time.Minute), rpcclient.JSON_HTTP, nil, false) - if err != nil { - t.Errorf("Error: %s when dialing", err) - } -} - -func testTLSPing(t *testing.T) { - var reply string - - if err := tlsRpcClientJson.Call(utils.ThresholdSv1Ping, new(utils.CGREvent), &reply); err != nil { - t.Error(err) - } else if reply != utils.Pong { - t.Errorf("Received: %s", reply) - } - if err := tlsRpcClientGob.Call(utils.ThresholdSv1Ping, new(utils.CGREvent), &reply); err != nil { - t.Error(err) - } else if reply != utils.Pong { - t.Errorf("Received: %s", reply) - } - if err := tlsHTTPJson.Call(utils.ThresholdSv1Ping, new(utils.CGREvent), &reply); err != nil { - t.Error(err) - } else if reply != utils.Pong { - t.Errorf("Received: %s", reply) - } - if err := tlsRpcClientJson.Call(utils.DispatcherSv1Ping, "", &reply); err == nil { - t.Error(err) - } - if err := tlsRpcClientGob.Call(utils.DispatcherSv1Ping, "", &reply); err == nil { - t.Error(err) - } - if err := tlsHTTPJson.Call(utils.DispatcherSv1Ping, "", &reply); err == nil { - t.Error(err) - } - - initUsage := time.Duration(5 * time.Minute) - args := &sessions.V1InitSessionArgs{ - InitSession: true, - AllocateResources: true, - GetAttributes: true, - CGREvent: &utils.CGREvent{ - Tenant: "cgrates.org", - ID: "TestSSv1ItInitiateSession", - Event: map[string]interface{}{ - utils.Tenant: "cgrates.org", - utils.Category: "call", - utils.ToR: utils.VOICE, - utils.OriginID: "TestSSv1It1", - utils.RequestType: utils.META_PREPAID, - utils.Account: "1001", - utils.Subject: "ANY2CNT", - utils.Destination: "1002", - utils.SetupTime: time.Date(2018, time.January, 7, 16, 60, 0, 0, time.UTC), - utils.AnswerTime: time.Date(2018, time.January, 7, 16, 60, 10, 0, time.UTC), - utils.Usage: initUsage, - }, - }, - } - var rply sessions.V1InitReplyWithDigest - if err := tlsHTTPJson.Call(utils.SessionSv1InitiateSessionWithDigest, - args, &rply); err == nil { - t.Error(err) - } -} - -func testTLSStopEngine(t *testing.T) { - if err := engine.KillEngine(100); err != nil { - t.Error(err) - } -} +// +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 general_tests + +import ( + "path" + "testing" + "time" + + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/sessions" + "github.com/cgrates/cgrates/utils" + "github.com/cgrates/rpcclient" +) + +var ( + tlsCfgPath string + tlsCfg *config.CGRConfig + tlsRpcClientJson *rpcclient.RpcClient + tlsRpcClientGob *rpcclient.RpcClient + tlsHTTPJson *rpcclient.RpcClient + tlsConfDIR string //run tests for specific configuration + tlsDelay int + + sTestsTLS = []func(t *testing.T){ + testTLSLoadConfig, + testTLSInitDataDb, + testTLSStartEngine, + testTLSRpcConn, + testTLSPing, + testTLSStopEngine, + } +) + +// Test start here +func TestTLS(t *testing.T) { + tlsConfDIR = "tls" + for _, stest := range sTestsTLS { + t.Run(tlsConfDIR, stest) + } +} + +func testTLSLoadConfig(t *testing.T) { + var err error + tlsCfgPath = path.Join(*dataDir, "conf", "samples", tlsConfDIR) + if tlsCfg, err = config.NewCGRConfigFromPath(tlsCfgPath); err != nil { + t.Error(err) + } + tlsDelay = 2000 +} + +func testTLSInitDataDb(t *testing.T) { + if err := engine.InitDataDb(tlsCfg); err != nil { + t.Fatal(err) + } +} + +func testTLSStartEngine(t *testing.T) { + if _, err := engine.StopStartEngine(tlsCfgPath, tlsDelay); err != nil { + t.Fatal(err) + } +} + +func testTLSRpcConn(t *testing.T) { + var err error + tlsRpcClientJson, err = rpcclient.NewRpcClient("tcp", "localhost:2022", true, tlsCfg.TlsCfg().ClientKey, + tlsCfg.TlsCfg().ClientCerificate, tlsCfg.TlsCfg().CaCertificate, 3, 3, + time.Duration(1*time.Second), time.Duration(5*time.Minute), utils.JSON, nil, false) + if err != nil { + t.Errorf("Error: %s when dialing", err) + } + + tlsRpcClientGob, err = rpcclient.NewRpcClient("tcp", "localhost:2023", true, tlsCfg.TlsCfg().ClientKey, + tlsCfg.TlsCfg().ClientCerificate, tlsCfg.TlsCfg().CaCertificate, 3, 3, + time.Duration(1*time.Second), time.Duration(5*time.Minute), utils.GOB, nil, false) + if err != nil { + t.Errorf("Error: %s when dialing", err) + } + + tlsHTTPJson, err = rpcclient.NewRpcClient("tcp", "https://localhost:2280/jsonrpc", true, tlsCfg.TlsCfg().ClientKey, + tlsCfg.TlsCfg().ClientCerificate, tlsCfg.TlsCfg().CaCertificate, 3, 3, + time.Duration(1*time.Second), time.Duration(5*time.Minute), rpcclient.JSON_HTTP, nil, false) + if err != nil { + t.Errorf("Error: %s when dialing", err) + } +} + +func testTLSPing(t *testing.T) { + var reply string + + if err := tlsRpcClientJson.Call(utils.ThresholdSv1Ping, new(utils.CGREvent), &reply); err != nil { + t.Error(err) + } else if reply != utils.Pong { + t.Errorf("Received: %s", reply) + } + if err := tlsRpcClientGob.Call(utils.ThresholdSv1Ping, new(utils.CGREvent), &reply); err != nil { + t.Error(err) + } else if reply != utils.Pong { + t.Errorf("Received: %s", reply) + } + if err := tlsHTTPJson.Call(utils.ThresholdSv1Ping, new(utils.CGREvent), &reply); err != nil { + t.Error(err) + } else if reply != utils.Pong { + t.Errorf("Received: %s", reply) + } + if err := tlsRpcClientJson.Call(utils.DispatcherSv1Ping, "", &reply); err == nil { + t.Error(err) + } + if err := tlsRpcClientGob.Call(utils.DispatcherSv1Ping, "", &reply); err == nil { + t.Error(err) + } + if err := tlsHTTPJson.Call(utils.DispatcherSv1Ping, "", &reply); err == nil { + t.Error(err) + } + + initUsage := time.Duration(5 * time.Minute) + args := &sessions.V1InitSessionArgs{ + InitSession: true, + AllocateResources: true, + GetAttributes: true, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSSv1ItInitiateSession", + Event: map[string]interface{}{ + utils.Tenant: "cgrates.org", + utils.Category: "call", + utils.ToR: utils.VOICE, + utils.OriginID: "TestSSv1It1", + utils.RequestType: utils.META_PREPAID, + utils.Account: "1001", + utils.Subject: "ANY2CNT", + utils.Destination: "1002", + utils.SetupTime: time.Date(2018, time.January, 7, 16, 60, 0, 0, time.UTC), + utils.AnswerTime: time.Date(2018, time.January, 7, 16, 60, 10, 0, time.UTC), + utils.Usage: initUsage, + }, + }, + } + var rply sessions.V1InitReplyWithDigest + if err := tlsHTTPJson.Call(utils.SessionSv1InitiateSessionWithDigest, + args, &rply); err == nil { + t.Error(err) + } +} + +func testTLSStopEngine(t *testing.T) { + if err := engine.KillEngine(100); err != nil { + t.Error(err) + } +} diff --git a/general_tests/tp_it_test.go b/general_tests/tp_it_test.go index 2833a101e..c9bd54b00 100644 --- a/general_tests/tp_it_test.go +++ b/general_tests/tp_it_test.go @@ -34,12 +34,40 @@ import ( "github.com/cgrates/cgrates/utils" ) -var tpCfgPath string -var tpCfg *config.CGRConfig -var tpRPC *rpc.Client -var tpLoadInst utils.LoadInstance // Share load information between tests +var ( + tpCfgPath string + tpCfg *config.CGRConfig + tpRPC *rpc.Client + tpLoadInst utils.LoadInstance // Share load information between tests -func TestTpInitCfg(t *testing.T) { + sTestTp = []func(t *testing.T){ + testTpInitCfg, + testTpResetDataDb, + testTpResetStorDb, + testTpStartEngine, + testTpRpcConn, + testTpLoadTariffPlanFromFolder, + testTpBalanceCounter, + testTpActionTriggers, + testTpZeroCost, + testTpZeroNegativeCost, + testTpExecuteActionCgrRpc, + testTpExecuteActionCgrRpcAcc, + //testTpExecuteActionCgrRpcCdrStats, + testTpCreateExecuteActionMatch, + testTpSetRemoveActions, + testTpRemoveActionsRefenced, + testTpApierResetAccountActionTriggers, + testTpStopCgrEngine, + } +) + +func TestTp(t *testing.T) { + for _, stest := range sTestTp { + t.Run("TestTp", stest) + } +} +func testTpInitCfg(t *testing.T) { tpCfgPath = path.Join(*dataDir, "conf", "samples", "tutmysql") // Init config first var err error @@ -52,28 +80,28 @@ func TestTpInitCfg(t *testing.T) { } // Remove data in both rating and accounting db -func TestTpResetDataDb(t *testing.T) { +func testTpResetDataDb(t *testing.T) { if err := engine.InitDataDb(tpCfg); err != nil { t.Fatal(err) } } // Wipe out the cdr database -func TestTpResetStorDb(t *testing.T) { +func testTpResetStorDb(t *testing.T) { if err := engine.InitStorDb(tpCfg); err != nil { t.Fatal(err) } } // Start CGR Engine -func TestTpStartEngine(t *testing.T) { +func testTpStartEngine(t *testing.T) { if _, err := engine.StopStartEngine(tpCfgPath, 1000); err != nil { t.Fatal(err) } } // Connect rpc client to rater -func TestTpRpcConn(t *testing.T) { +func testTpRpcConn(t *testing.T) { var err error tpRPC, err = jsonrpc.Dial("tcp", tpCfg.ListenCfg().RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed if err != nil { @@ -82,7 +110,7 @@ func TestTpRpcConn(t *testing.T) { } // Load the tariff plan, creating accounts and their balances -func TestTpLoadTariffPlanFromFolder(t *testing.T) { +func testTpLoadTariffPlanFromFolder(t *testing.T) { attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "testtp")} if err := tpRPC.Call("ApierV2.LoadTariffPlanFromFolder", attrs, &tpLoadInst); err != nil { t.Error(err) @@ -90,7 +118,7 @@ func TestTpLoadTariffPlanFromFolder(t *testing.T) { time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups } -func TestTpBalanceCounter(t *testing.T) { +func testTpBalanceCounter(t *testing.T) { tStart := time.Date(2016, 3, 31, 0, 0, 0, 0, time.UTC) cd := engine.CallDescriptor{ Category: "call", @@ -116,7 +144,7 @@ func TestTpBalanceCounter(t *testing.T) { } } -func TestTpActionTriggers(t *testing.T) { +func testTpActionTriggers(t *testing.T) { var atrs engine.ActionTriggers if err := tpRPC.Call("ApierV1.GetActionTriggers", v1.AttrGetActionTriggers{GroupIDs: []string{}}, &atrs); err != nil { t.Error("Got error on ApierV1.GetActionTriggers: ", err.Error()) @@ -157,7 +185,7 @@ func TestTpActionTriggers(t *testing.T) { } } -func TestTpZeroCost(t *testing.T) { +func testTpZeroCost(t *testing.T) { var acnt *engine.Account attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1012"} if err := tpRPC.Call("ApierV2.GetAccount", attrs, &acnt); err != nil { @@ -195,7 +223,7 @@ func TestTpZeroCost(t *testing.T) { } } -func TestTpZeroNegativeCost(t *testing.T) { +func testTpZeroNegativeCost(t *testing.T) { tStart := time.Date(2016, 3, 31, 0, 0, 0, 0, time.UTC) cd := engine.CallDescriptor{ Category: "call", @@ -222,7 +250,7 @@ func TestTpZeroNegativeCost(t *testing.T) { } } -func TestTpExecuteActionCgrRpc(t *testing.T) { +func testTpExecuteActionCgrRpc(t *testing.T) { var reply string if err := tpRPC.Call("ApierV2.ExecuteAction", utils.AttrExecuteAction{ActionsId: "RPC"}, &reply); err != nil { t.Error("Got error on ApierV2.ExecuteAction: ", err.Error()) @@ -236,7 +264,7 @@ func TestTpExecuteActionCgrRpc(t *testing.T) { } } -func TestTpExecuteActionCgrRpcAcc(t *testing.T) { +func testTpExecuteActionCgrRpcAcc(t *testing.T) { var reply string if err := tpRPC.Call("ApierV2.ExecuteAction", utils.AttrExecuteAction{ Tenant: "cgrates.org", @@ -255,7 +283,7 @@ func TestTpExecuteActionCgrRpcAcc(t *testing.T) { } // Deprecated -// func TestTpExecuteActionCgrRpcCdrStats(t *testing.T) { +// func //(t *testing.T) { // var reply string // if err := tpRPC.Call("ApierV2.ExecuteAction", utils.AttrExecuteAction{ // ActionsId: "RPC_CDRSTATS", @@ -271,7 +299,7 @@ func TestTpExecuteActionCgrRpcAcc(t *testing.T) { // } // } -func TestTpCreateExecuteActionMatch(t *testing.T) { +func testTpCreateExecuteActionMatch(t *testing.T) { var reply string if err := tpRPC.Call("ApierV2.SetActions", utils.AttrSetActions{ ActionsId: "PAYMENT_2056bd2fe137082970f97102b64e42fd", @@ -319,7 +347,7 @@ func TestTpCreateExecuteActionMatch(t *testing.T) { } } -func TestTpSetRemoveActions(t *testing.T) { +func testTpSetRemoveActions(t *testing.T) { var reply string if err := tpRPC.Call("ApierV2.SetActions", utils.AttrSetActions{ ActionsId: "TO_BE_DELETED", @@ -359,7 +387,7 @@ func TestTpSetRemoveActions(t *testing.T) { } } -func TestTpRemoveActionsRefenced(t *testing.T) { +func testTpRemoveActionsRefenced(t *testing.T) { actionsMap := make(map[string]engine.Actions) if err := tpRPC.Call("ApierV2.GetActions", v2.AttrGetActions{ ActionIDs: []string{"TOPUP_VOICE"}, @@ -385,7 +413,7 @@ func TestTpRemoveActionsRefenced(t *testing.T) { */ } -func TestTpApierResetAccountActionTriggers(t *testing.T) { +func testTpApierResetAccountActionTriggers(t *testing.T) { var acnt engine.Account attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1005"} if err := tpRPC.Call("ApierV2.GetAccount", attrs, &acnt); err != nil { @@ -411,7 +439,7 @@ func TestTpApierResetAccountActionTriggers(t *testing.T) { } } -func TestTpStopCgrEngine(t *testing.T) { +func testTpStopCgrEngine(t *testing.T) { if err := engine.KillEngine(100); err != nil { t.Error(err) } diff --git a/general_tests/tut_smgeneric_it_test.go b/general_tests/tut_smgeneric_it_test.go index a54ea8bbf..38cf22515 100644 --- a/general_tests/tut_smgeneric_it_test.go +++ b/general_tests/tut_smgeneric_it_test.go @@ -34,10 +34,29 @@ import ( "github.com/cgrates/ltcache" ) -var tutSMGCfgPath string -var tutSMGCfg *config.CGRConfig -var tutSMGRpc *rpc.Client -var smgLoadInst utils.LoadInstance // Share load information between tests +var ( + tutSMGCfgPath string + tutSMGCfg *config.CGRConfig + tutSMGRpc *rpc.Client + smgLoadInst utils.LoadInstance // Share load information between tests + + sTestTutSMG = []func(t *testing.T){ + TestTutSMGInitCfg, + TestTutSMGResetDataDb, + TestTutSMGResetStorDb, + TestTutSMGStartEngine, + TestTutSMGRpcConn, + TestTutSMGLoadTariffPlanFromFolder, + TestTutSMGCacheStats, + TestTutSMGStopCgrEngine, + } +) + +func TestTutSMG(t *testing.T) { + for _, stest := range sTestTutSMG { + t.Run("TestTutSMG", stest) + } +} func TestTutSMGInitCfg(t *testing.T) { tutSMGCfgPath = path.Join(*dataDir, "conf", "samples", "smgeneric") diff --git a/general_tests/tutorial2_it_test.go b/general_tests/tutorial2_it_test.go index a5ad69741..7c23aaee0 100644 --- a/general_tests/tutorial2_it_test.go +++ b/general_tests/tutorial2_it_test.go @@ -1,315 +1,315 @@ -// +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 general_tests - -import ( - "net/rpc" - "net/rpc/jsonrpc" - "path" - "testing" - "time" - - v1 "github.com/cgrates/cgrates/apier/v1" - v2 "github.com/cgrates/cgrates/apier/v2" - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" -) - -var ( - tutCfgPath string - tutCfg *config.CGRConfig - tutRpc *rpc.Client - tutCfgDir string //run tests for specific configuration - tutDelay int -) - -var sTutTests = []func(t *testing.T){ - testTutLoadConfig, - testTutResetDB, - testTutStartEngine, - testTutRpcConn, - testTutFromFolder, - testTutGetCost, - testTutAccounts, - testTutStopEngine, -} - -//Test start here -func TestTutorial2MySQL(t *testing.T) { - tutCfgDir = "tutmysql2" - for _, stest := range sTutTests { - t.Run(tutCfgDir, stest) - } -} - -func TestTutorial2Mongo(t *testing.T) { - tutCfgDir = "tutmongo2" - for _, stest := range sTutTests { - t.Run(tutCfgDir, stest) - } -} - -func testTutLoadConfig(t *testing.T) { - var err error - tutCfgPath = path.Join(*dataDir, "conf", "samples", tutCfgDir) - if tutCfg, err = config.NewCGRConfigFromPath(tutCfgPath); err != nil { - t.Error(err) - } - tutDelay = 2000 -} - -func testTutResetDB(t *testing.T) { - if err := engine.InitDataDb(tutCfg); err != nil { - t.Fatal(err) - } - if err := engine.InitStorDb(tutCfg); err != nil { - t.Fatal(err) - } -} - -func testTutStartEngine(t *testing.T) { - if _, err := engine.StopStartEngine(tutCfgPath, tutDelay); err != nil { - t.Fatal(err) - } -} - -func testTutRpcConn(t *testing.T) { - var err error - if tutRpc, err = jsonrpc.Dial("tcp", tutCfg.ListenCfg().RPCJSONListen); err != nil { - t.Fatal("could not connect to rater: ", err.Error()) - } -} - -func testTutFromFolder(t *testing.T) { - var reply string - attrs := &utils.AttrLoadTpFromFolder{ - FolderPath: path.Join(*dataDir, "tariffplans", "tutorial2")} - if err := tutRpc.Call(utils.ApierV1LoadTariffPlanFromFolder, - attrs, &reply); err != nil { - t.Error(err) - } - time.Sleep(500 * time.Millisecond) -} - -func testTutGetCost(t *testing.T) { - // Standard pricing for 1001->1002 - attrs := v1.AttrGetCost{ - Subject: "1001", - Destination: "1002", - AnswerTime: "*now", - Usage: "45s", - } - var rply *engine.EventCost - if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil { - t.Error("Unexpected nil error received: ", err.Error()) - } else if *rply.Cost != 0.550000 { - t.Errorf("Unexpected cost received: %f", *rply.Cost) - } - // Fallback pricing from *any, Usage will be rounded to 60s - attrs = v1.AttrGetCost{ - Subject: "1001", - Destination: "1003", - AnswerTime: "2019-03-11T09:00:00Z", - Usage: "45s", - } - if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil { - t.Error("Unexpected nil error received: ", err.Error()) - } else if *rply.Cost != 1.4 { - t.Errorf("Unexpected cost received: %f", *rply.Cost) - } - // Fallback pricing from *any, Usage will be rounded to 60s - attrs = v1.AttrGetCost{ - Subject: "1001", - Destination: "1003", - AnswerTime: "2019-03-11T21:00:00Z", - Usage: "45s", - } - // *any to 2001 - attrs = v1.AttrGetCost{ - Subject: "1002", - Destination: "2001", - AnswerTime: "*now", - Usage: "45s", - } - if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil { - t.Error("Unexpected nil error received: ", err.Error()) - } else if *rply.Cost != 1.4 { - t.Errorf("Unexpected cost received: %f", *rply.Cost) - } - // *any to 2001 on NEW_YEAR - attrs = v1.AttrGetCost{ - Subject: "1002", - Destination: "2001", - AnswerTime: "2020-01-01T21:00:00Z", - Usage: "45s", - } - if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil { - t.Error("Unexpected nil error received: ", err.Error()) - } else if *rply.Cost != 0.55 { - t.Errorf("Unexpected cost received: %f", *rply.Cost) - } - // Fallback pricing from *any, Usage will be rounded to 60s - attrs = v1.AttrGetCost{ - Subject: "1001", - Destination: "1003", - AnswerTime: "2019-03-11T21:00:00Z", - Usage: "45s", - } - if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil { - t.Error("Unexpected nil error received: ", err.Error()) - } else if *rply.Cost != 0.55 { - t.Errorf("Unexpected cost received: %f", *rply.Cost) - } - // Unauthorized destination - attrs = v1.AttrGetCost{ - Subject: "1001", - Destination: "4003", - AnswerTime: "2019-03-11T09:00:00Z", - Usage: "1m", - } - if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err == nil || - err.Error() != "SERVER_ERROR: UNAUTHORIZED_DESTINATION" { - t.Error("Unexpected nil error received: ", err) - } - // Data charging - attrs = v1.AttrGetCost{ - Category: "data", - Subject: "1001", - AnswerTime: "*now", - Usage: "2048", - } - if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil { - t.Error("Unexpected nil error received: ", err.Error()) - } else if *rply.Cost != 2.0 { // FixMe: missing ConnectFee out of Cost - t.Errorf("Unexpected cost received: %f", *rply.Cost) - } - // SMS charging 1002 - attrs = v1.AttrGetCost{ - Category: "sms", - Subject: "1003", - Destination: "1002", - AnswerTime: "*now", - Usage: "1", - } - if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil { - t.Error("Unexpected nil error received: ", err.Error()) - } else if *rply.Cost != 0.1 { - t.Errorf("Unexpected cost received: %f", *rply.Cost) - } - // SMS charging 10 - attrs = v1.AttrGetCost{ - Category: "sms", - Subject: "1001", - Destination: "1003", - AnswerTime: "*now", - Usage: "1", - } - if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil { - t.Error("Unexpected nil error received: ", err.Error()) - } else if *rply.Cost != 0.2 { - t.Errorf("Unexpected cost received: %f", *rply.Cost) - } - // SMS charging UNAUTHORIZED - attrs = v1.AttrGetCost{ - Category: "sms", - Subject: "1001", - Destination: "2001", - AnswerTime: "*now", - Usage: "1", - } - if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err == nil || - err.Error() != "SERVER_ERROR: UNAUTHORIZED_DESTINATION" { - t.Error("Unexpected nil error received: ", err) - } - // Per call charges - attrs = v1.AttrGetCost{ - Category: "call", - Subject: "RPF_SPECIAL_BLC", - Destination: "1002", - AnswerTime: "*now", - Usage: "5m", - } - if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil { - t.Error("Unexpected nil error received: ", err.Error()) - } else if *rply.Cost != 0.1 { - t.Errorf("Unexpected cost received: %f", *rply.Cost) - } -} - -func testTutAccounts(t *testing.T) { - // make sure Account was created - var acnt *engine.Account - if err := tutRpc.Call(utils.ApierV2GetAccount, - &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"}, - &acnt); err != nil { - t.Fatal(err) - } - if len(acnt.BalanceMap) != 4 || - len(acnt.BalanceMap[utils.MONETARY]) != 1 || - acnt.BalanceMap[utils.MONETARY][0].Value != 10 || - len(acnt.BalanceMap[utils.VOICE]) != 2 || - len(acnt.BalanceMap[utils.SMS]) != 1 || - acnt.BalanceMap[utils.SMS][0].Value != 100 || - len(acnt.BalanceMap[utils.DATA]) != 1 || - acnt.BalanceMap[utils.DATA][0].Value != 1024 || - len(acnt.ActionTriggers) != 2 || - acnt.Disabled { - t.Errorf("received account: %s", utils.ToIJSON(acnt)) - } - // test ActionTriggers - attrs := &v1.AttrAddBalance{Tenant: "cgrates.org", Account: "1001", - BalanceId: utils.StringPointer(utils.MetaDefault), - BalanceType: utils.MONETARY, Value: 101} - var reply string - if err := tutRpc.Call(utils.ApierV1SetBalance, attrs, &reply); err != nil { - t.Error("Got error on ApierV1.SetBalance: ", err.Error()) - } - if err := tutRpc.Call(utils.ApierV2GetAccount, - &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"}, - &acnt); err != nil { - t.Error(err) - } else if !acnt.Disabled { - t.Errorf("account: %s", utils.ToIJSON(acnt)) - } - // enable the account again - if err := tutRpc.Call(utils.ApierV2SetAccount, - v2.AttrSetAccount{ - Tenant: "cgrates.org", - Account: "1001", - Disabled: utils.BoolPointer(false), - }, &reply); err != nil { - t.Error(err) - } - if err := tutRpc.Call(utils.ApierV2GetAccount, - &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"}, - &acnt); err != nil { - t.Error(err) - } else if acnt.Disabled { - t.Errorf("account: %s", utils.ToIJSON(acnt)) - } -} - -func testTutStopEngine(t *testing.T) { - if err := engine.KillEngine(tutDelay); err != nil { - t.Error(err) - } -} +// +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 general_tests + +import ( + "net/rpc" + "net/rpc/jsonrpc" + "path" + "testing" + "time" + + v1 "github.com/cgrates/cgrates/apier/v1" + v2 "github.com/cgrates/cgrates/apier/v2" + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" +) + +var ( + tutCfgPath string + tutCfg *config.CGRConfig + tutRpc *rpc.Client + tutCfgDir string //run tests for specific configuration + tutDelay int +) + +var sTutTests = []func(t *testing.T){ + testTutLoadConfig, + testTutResetDB, + testTutStartEngine, + testTutRpcConn, + testTutFromFolder, + testTutGetCost, + testTutAccounts, + testTutStopEngine, +} + +//Test start here +func TestTutorial2MySQL(t *testing.T) { + tutCfgDir = "tutmysql2" + for _, stest := range sTutTests { + t.Run(tutCfgDir, stest) + } +} + +func TestTutorial2Mongo(t *testing.T) { + tutCfgDir = "tutmongo2" + for _, stest := range sTutTests { + t.Run(tutCfgDir, stest) + } +} + +func testTutLoadConfig(t *testing.T) { + var err error + tutCfgPath = path.Join(*dataDir, "conf", "samples", tutCfgDir) + if tutCfg, err = config.NewCGRConfigFromPath(tutCfgPath); err != nil { + t.Error(err) + } + tutDelay = 2000 +} + +func testTutResetDB(t *testing.T) { + if err := engine.InitDataDb(tutCfg); err != nil { + t.Fatal(err) + } + if err := engine.InitStorDb(tutCfg); err != nil { + t.Fatal(err) + } +} + +func testTutStartEngine(t *testing.T) { + if _, err := engine.StopStartEngine(tutCfgPath, tutDelay); err != nil { + t.Fatal(err) + } +} + +func testTutRpcConn(t *testing.T) { + var err error + if tutRpc, err = jsonrpc.Dial("tcp", tutCfg.ListenCfg().RPCJSONListen); err != nil { + t.Fatal("could not connect to rater: ", err.Error()) + } +} + +func testTutFromFolder(t *testing.T) { + var reply string + attrs := &utils.AttrLoadTpFromFolder{ + FolderPath: path.Join(*dataDir, "tariffplans", "tutorial2")} + if err := tutRpc.Call(utils.ApierV1LoadTariffPlanFromFolder, + attrs, &reply); err != nil { + t.Error(err) + } + time.Sleep(500 * time.Millisecond) +} + +func testTutGetCost(t *testing.T) { + // Standard pricing for 1001->1002 + attrs := v1.AttrGetCost{ + Subject: "1001", + Destination: "1002", + AnswerTime: "*now", + Usage: "45s", + } + var rply *engine.EventCost + if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil { + t.Error("Unexpected nil error received: ", err.Error()) + } else if *rply.Cost != 0.550000 { + t.Errorf("Unexpected cost received: %f", *rply.Cost) + } + // Fallback pricing from *any, Usage will be rounded to 60s + attrs = v1.AttrGetCost{ + Subject: "1001", + Destination: "1003", + AnswerTime: "2019-03-11T09:00:00Z", + Usage: "45s", + } + if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil { + t.Error("Unexpected nil error received: ", err.Error()) + } else if *rply.Cost != 1.4 { + t.Errorf("Unexpected cost received: %f", *rply.Cost) + } + // Fallback pricing from *any, Usage will be rounded to 60s + attrs = v1.AttrGetCost{ + Subject: "1001", + Destination: "1003", + AnswerTime: "2019-03-11T21:00:00Z", + Usage: "45s", + } + // *any to 2001 + attrs = v1.AttrGetCost{ + Subject: "1002", + Destination: "2001", + AnswerTime: "*now", + Usage: "45s", + } + if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil { + t.Error("Unexpected nil error received: ", err.Error()) + } else if *rply.Cost != 1.4 { + t.Errorf("Unexpected cost received: %f", *rply.Cost) + } + // *any to 2001 on NEW_YEAR + attrs = v1.AttrGetCost{ + Subject: "1002", + Destination: "2001", + AnswerTime: "2020-01-01T21:00:00Z", + Usage: "45s", + } + if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil { + t.Error("Unexpected nil error received: ", err.Error()) + } else if *rply.Cost != 0.55 { + t.Errorf("Unexpected cost received: %f", *rply.Cost) + } + // Fallback pricing from *any, Usage will be rounded to 60s + attrs = v1.AttrGetCost{ + Subject: "1001", + Destination: "1003", + AnswerTime: "2019-03-11T21:00:00Z", + Usage: "45s", + } + if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil { + t.Error("Unexpected nil error received: ", err.Error()) + } else if *rply.Cost != 0.55 { + t.Errorf("Unexpected cost received: %f", *rply.Cost) + } + // Unauthorized destination + attrs = v1.AttrGetCost{ + Subject: "1001", + Destination: "4003", + AnswerTime: "2019-03-11T09:00:00Z", + Usage: "1m", + } + if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err == nil || + err.Error() != "SERVER_ERROR: UNAUTHORIZED_DESTINATION" { + t.Error("Unexpected nil error received: ", err) + } + // Data charging + attrs = v1.AttrGetCost{ + Category: "data", + Subject: "1001", + AnswerTime: "*now", + Usage: "2048", + } + if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil { + t.Error("Unexpected nil error received: ", err.Error()) + } else if *rply.Cost != 2.0 { // FixMe: missing ConnectFee out of Cost + t.Errorf("Unexpected cost received: %f", *rply.Cost) + } + // SMS charging 1002 + attrs = v1.AttrGetCost{ + Category: "sms", + Subject: "1003", + Destination: "1002", + AnswerTime: "*now", + Usage: "1", + } + if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil { + t.Error("Unexpected nil error received: ", err.Error()) + } else if *rply.Cost != 0.1 { + t.Errorf("Unexpected cost received: %f", *rply.Cost) + } + // SMS charging 10 + attrs = v1.AttrGetCost{ + Category: "sms", + Subject: "1001", + Destination: "1003", + AnswerTime: "*now", + Usage: "1", + } + if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil { + t.Error("Unexpected nil error received: ", err.Error()) + } else if *rply.Cost != 0.2 { + t.Errorf("Unexpected cost received: %f", *rply.Cost) + } + // SMS charging UNAUTHORIZED + attrs = v1.AttrGetCost{ + Category: "sms", + Subject: "1001", + Destination: "2001", + AnswerTime: "*now", + Usage: "1", + } + if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err == nil || + err.Error() != "SERVER_ERROR: UNAUTHORIZED_DESTINATION" { + t.Error("Unexpected nil error received: ", err) + } + // Per call charges + attrs = v1.AttrGetCost{ + Category: "call", + Subject: "RPF_SPECIAL_BLC", + Destination: "1002", + AnswerTime: "*now", + Usage: "5m", + } + if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil { + t.Error("Unexpected nil error received: ", err.Error()) + } else if *rply.Cost != 0.1 { + t.Errorf("Unexpected cost received: %f", *rply.Cost) + } +} + +func testTutAccounts(t *testing.T) { + // make sure Account was created + var acnt *engine.Account + if err := tutRpc.Call(utils.ApierV2GetAccount, + &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"}, + &acnt); err != nil { + t.Fatal(err) + } + if len(acnt.BalanceMap) != 4 || + len(acnt.BalanceMap[utils.MONETARY]) != 1 || + acnt.BalanceMap[utils.MONETARY][0].Value != 10 || + len(acnt.BalanceMap[utils.VOICE]) != 2 || + len(acnt.BalanceMap[utils.SMS]) != 1 || + acnt.BalanceMap[utils.SMS][0].Value != 100 || + len(acnt.BalanceMap[utils.DATA]) != 1 || + acnt.BalanceMap[utils.DATA][0].Value != 1024 || + len(acnt.ActionTriggers) != 2 || + acnt.Disabled { + t.Errorf("received account: %s", utils.ToIJSON(acnt)) + } + // test ActionTriggers + attrs := &v1.AttrAddBalance{Tenant: "cgrates.org", Account: "1001", + BalanceId: utils.StringPointer(utils.MetaDefault), + BalanceType: utils.MONETARY, Value: 101} + var reply string + if err := tutRpc.Call(utils.ApierV1SetBalance, attrs, &reply); err != nil { + t.Error("Got error on ApierV1.SetBalance: ", err.Error()) + } + if err := tutRpc.Call(utils.ApierV2GetAccount, + &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"}, + &acnt); err != nil { + t.Error(err) + } else if !acnt.Disabled { + t.Errorf("account: %s", utils.ToIJSON(acnt)) + } + // enable the account again + if err := tutRpc.Call(utils.ApierV2SetAccount, + v2.AttrSetAccount{ + Tenant: "cgrates.org", + Account: "1001", + Disabled: utils.BoolPointer(false), + }, &reply); err != nil { + t.Error(err) + } + if err := tutRpc.Call(utils.ApierV2GetAccount, + &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"}, + &acnt); err != nil { + t.Error(err) + } else if acnt.Disabled { + t.Errorf("account: %s", utils.ToIJSON(acnt)) + } +} + +func testTutStopEngine(t *testing.T) { + if err := engine.KillEngine(tutDelay); err != nil { + t.Error(err) + } +} diff --git a/general_tests/tutorial_calls_test.go b/general_tests/tutorial_calls_test.go index 1d55b7552..ae092f7d6 100755 --- a/general_tests/tutorial_calls_test.go +++ b/general_tests/tutorial_calls_test.go @@ -1,846 +1,846 @@ -// +build call - -/* -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 ( - "flag" - "net/rpc" - "net/rpc/jsonrpc" - "os" - "path" - "reflect" - "strings" - "testing" - "time" - - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/sessions" - "github.com/cgrates/cgrates/utils" -) - -var tutorialCallsCfg *config.CGRConfig -var tutorialCallsRpc *rpc.Client -var tutorialCallsPjSuaListener *os.File -var waitRater = flag.Int("wait_rater", 1000, "Number of miliseconds to wait for rater to start and cache") -var dataDir = flag.String("data_dir", "/usr/share/cgrates", "CGR data dir path here") -var fsConfig = flag.String("fsConfig", "/usr/share/cgrates/tutorial_tests/fs_evsock", "FreeSwitch tutorial folder") -var kamConfig = flag.String("kamConfig", "/usr/share/cgrates/tutorial_tests/kamevapi", "Kamailio tutorial folder") -var oSipsConfig = flag.String("osConfig", "/usr/share/cgrates/tutorial_tests/osips", "OpenSips tutorial folder") -var ariConf = flag.String("ariConf", "/usr/share/cgrates/tutorial_tests/asterisk_ari", "Asterisk tutorial folder") -var optConf string - -var sTestsCalls = []func(t *testing.T){ - testCallInitCfg, - testCallResetDataDb, - testCallResetStorDb, - testCallStartFS, - testCallStartEngine, - testCallRestartFS, - testCallRpcConn, - testCallLoadTariffPlanFromFolder, - testCallAccountsBefore, - testCallStatMetricsBefore, - testCallCheckResourceBeforeAllocation, - testCallCheckThreshold1001Before, - testCallCheckThreshold1002Before, - testCallStartPjsuaListener, - testCallCall1001To1002, - testCallGetActiveSessions, - testCallCall1002To1001, - testCallCall1001To1003, - testCallCall1003To1001, - testCallCall1003To1001SecondTime, - testCallCheckResourceAllocation, - testCallAccount1001, - testCall1001Cdrs, - testCall1002Cdrs, - testCall1003Cdrs, - testCallStatMetrics, - testCallCheckResourceRelease, - testCallCheckThreshold1001After, - testCallCheckThreshold1002After, - testCallSyncSessions, - testCallStopPjsuaListener, - testCallStopCgrEngine, - testCallStopFS, -} - -//Test start here -func TestFreeswitchCalls(t *testing.T) { - optConf = utils.Freeswitch - for _, stest := range sTestsCalls { - t.Run("", stest) - } -} - -func TestKamailioCalls(t *testing.T) { - optConf = utils.Kamailio - for _, stest := range sTestsCalls { - t.Run("", stest) - } -} - -func TestOpensipsCalls(t *testing.T) { - optConf = utils.Opensips - for _, stest := range sTestsCalls { - t.Run("", stest) - } -} - -func TestAsteriskCalls(t *testing.T) { - optConf = utils.Asterisk - for _, stest := range sTestsCalls { - t.Run("", stest) - } -} - -func testCallInitCfg(t *testing.T) { - // Init config first - var err error - switch optConf { - case utils.Freeswitch: - tutorialCallsCfg, err = config.NewCGRConfigFromPath(path.Join(*fsConfig, "cgrates", "etc", "cgrates")) - if err != nil { - t.Error(err) - } - case utils.Kamailio: - tutorialCallsCfg, err = config.NewCGRConfigFromPath(path.Join(*kamConfig, "cgrates", "etc", "cgrates")) - if err != nil { - t.Error(err) - } - case utils.Opensips: - tutorialCallsCfg, err = config.NewCGRConfigFromPath(path.Join(*oSipsConfig, "cgrates", "etc", "cgrates")) - if err != nil { - t.Error(err) - } - case utils.Asterisk: - tutorialCallsCfg, err = config.NewCGRConfigFromPath(path.Join(*ariConf, "cgrates", "etc", "cgrates")) - if err != nil { - t.Error(err) - } - default: - t.Error("Invalid option") - } - - tutorialCallsCfg.DataFolderPath = *dataDir // Share DataFolderPath through config towards StoreDb for Flush() - config.SetCgrConfig(tutorialCallsCfg) -} - -// Remove data in both rating and accounting db -func testCallResetDataDb(t *testing.T) { - if err := engine.InitDataDb(tutorialCallsCfg); err != nil { - t.Fatal(err) - } -} - -// Wipe out the cdr database -func testCallResetStorDb(t *testing.T) { - if err := engine.InitStorDb(tutorialCallsCfg); err != nil { - t.Fatal(err) - } -} - -// start FS server -func testCallStartFS(t *testing.T) { - switch optConf { - case utils.Freeswitch: - engine.KillProcName(utils.Freeswitch, 5000) - if err := engine.CallScript(path.Join(*fsConfig, "freeswitch", "etc", "init.d", "freeswitch"), "start", 3000); err != nil { - t.Fatal(err) - } - case utils.Kamailio: - engine.KillProcName(utils.Kamailio, 5000) - if err := engine.CallScript(path.Join(*kamConfig, "kamailio", "etc", "init.d", "kamailio"), "start", 3000); err != nil { - t.Fatal(err) - } - case utils.Opensips: - engine.KillProcName(utils.Kamailio, 5000) - if err := engine.CallScript(path.Join(*oSipsConfig, "opensips", "etc", "init.d", "opensips"), "start", 3000); err != nil { - t.Fatal(err) - } - case utils.Asterisk: - engine.KillProcName(utils.Asterisk, 5000) - if err := engine.CallScript(path.Join(*ariConf, "asterisk", "etc", "init.d", "asterisk"), "start", 3000); err != nil { - t.Fatal(err) - } - default: - t.Error("Invalid option") - } -} - -// Start CGR Engine -func testCallStartEngine(t *testing.T) { - engine.KillProcName("cgr-engine", *waitRater) - switch optConf { - case utils.Freeswitch: - if err := engine.CallScript(path.Join(*fsConfig, "cgrates", "etc", "init.d", "cgrates"), "start", 100); err != nil { - t.Fatal(err) - } - case utils.Kamailio: - if err := engine.CallScript(path.Join(*kamConfig, "cgrates", "etc", "init.d", "cgrates"), "start", 100); err != nil { - t.Fatal(err) - } - case utils.Opensips: - if err := engine.CallScript(path.Join(*oSipsConfig, "cgrates", "etc", "init.d", "cgrates"), "start", 100); err != nil { - t.Fatal(err) - } - case utils.Asterisk: - if err := engine.CallScript(path.Join(*ariConf, "cgrates", "etc", "init.d", "cgrates"), "start", 100); err != nil { - t.Fatal(err) - } - default: - t.Error("invalid option") - } -} - -// Restart FS so we make sure reconnects are working -func testCallRestartFS(t *testing.T) { - switch optConf { - case utils.Freeswitch: - engine.KillProcName(utils.Freeswitch, 5000) - if err := engine.CallScript(path.Join(*fsConfig, "freeswitch", "etc", "init.d", "freeswitch"), "restart", 3000); err != nil { - t.Fatal(err) - } - case utils.Kamailio: - engine.KillProcName(utils.Kamailio, 5000) - if err := engine.CallScript(path.Join(*kamConfig, "kamailio", "etc", "init.d", "kamailio"), "restart", 3000); err != nil { - t.Fatal(err) - } - case utils.Opensips: - engine.KillProcName(utils.Kamailio, 5000) - if err := engine.CallScript(path.Join(*oSipsConfig, "opensips", "etc", "init.d", "opensips"), "restart", 3000); err != nil { - t.Fatal(err) - } - case utils.Asterisk: - engine.KillProcName(utils.Asterisk, 5000) - if err := engine.CallScript(path.Join(*ariConf, "asterisk", "etc", "init.d", "asterisk"), "restart", 3000); err != nil { - t.Fatal(err) - } - default: - t.Error("Invalid option") - } -} - -// Connect rpc client to rater -func testCallRpcConn(t *testing.T) { - var err error - tutorialCallsRpc, err = jsonrpc.Dial("tcp", tutorialCallsCfg.ListenCfg().RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed - if err != nil { - t.Fatal(err) - } -} - -// Load the tariff plan, creating accounts and their balances -func testCallLoadTariffPlanFromFolder(t *testing.T) { - var reply string - attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "tutorial")} - if err := tutorialCallsRpc.Call("ApierV1.LoadTariffPlanFromFolder", attrs, &reply); err != nil { - t.Error(err) - } - time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups -} - -// Make sure account was debited properly -func testCallAccountsBefore(t *testing.T) { - var reply *engine.Account - attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} - if err := tutorialCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } - var reply2 *engine.Account - attrs2 := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1002"} - if err := tutorialCallsRpc.Call("ApierV2.GetAccount", attrs2, &reply2); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply2.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { - t.Errorf("Calling ApierV1.GetBalance received: %f", reply2.BalanceMap[utils.MONETARY].GetTotalValue()) - } - var reply3 *engine.Account - attrs3 := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1003"} - if err := tutorialCallsRpc.Call("ApierV2.GetAccount", attrs3, &reply3); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply3.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { - t.Errorf("Calling ApierV1.GetBalance received: %f", reply3.BalanceMap[utils.MONETARY].GetTotalValue()) - } -} - -func testCallStatMetricsBefore(t *testing.T) { - var metrics map[string]string - expectedMetrics := map[string]string{ - utils.MetaTCC: utils.NOT_AVAILABLE, - utils.MetaTCD: utils.NOT_AVAILABLE, - } - if err := tutorialCallsRpc.Call(utils.StatSv1GetQueueStringMetrics, - &utils.TenantID{Tenant: "cgrates.org", ID: "Stats2"}, &metrics); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(expectedMetrics, metrics) { - t.Errorf("expecting: %+v, received reply: %s", expectedMetrics, metrics) - } - if err := tutorialCallsRpc.Call(utils.StatSv1GetQueueStringMetrics, - &utils.TenantID{Tenant: "cgrates.org", ID: "Stats2_1"}, &metrics); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(expectedMetrics, metrics) { - t.Errorf("expecting: %+v, received reply: %s", expectedMetrics, metrics) - } -} - -func testCallCheckResourceBeforeAllocation(t *testing.T) { - var rs *engine.Resources - args := &utils.ArgRSv1ResourceUsage{ - UsageID: "OriginID", - CGREvent: &utils.CGREvent{ - Tenant: "cgrates.org", - ID: "ResourceEvent", - Event: map[string]interface{}{ - utils.Account: "1001", - utils.Subject: "1001", - utils.Destination: "1002"}, - }} - if err := tutorialCallsRpc.Call(utils.ResourceSv1GetResourcesForEvent, args, &rs); err != nil { - t.Fatal(err) - } else if len(*rs) != 1 { - t.Fatalf("Resources: %+v", utils.ToJSON(rs)) - } - for _, r := range *rs { - if r.ID == "ResGroup1" && - (len(r.Usages) != 0 || len(r.TTLIdx) != 0) { - t.Errorf("Unexpected resource: %+v", utils.ToJSON(r)) - } - } -} - -func testCallCheckThreshold1001Before(t *testing.T) { - var td engine.Threshold - eTd := engine.Threshold{Tenant: "cgrates.org", ID: "THD_ACNT_1001", Hits: 0} - if err := tutorialCallsRpc.Call(utils.ThresholdSv1GetThreshold, - &utils.TenantID{Tenant: "cgrates.org", ID: "THD_ACNT_1001"}, &td); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(eTd, td) { - t.Errorf("expecting: %+v, received: %+v", eTd, td) - } -} - -func testCallCheckThreshold1002Before(t *testing.T) { - var td engine.Threshold - eTd := engine.Threshold{Tenant: "cgrates.org", ID: "THD_ACNT_1002", Hits: 0} - if err := tutorialCallsRpc.Call(utils.ThresholdSv1GetThreshold, - &utils.TenantID{Tenant: "cgrates.org", ID: "THD_ACNT_1002"}, &td); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(eTd, td) { - t.Errorf("expecting: %+v, received: %+v", eTd, td) - } -} - -// Start Pjsua as listener and register it to receive calls -func testCallStartPjsuaListener(t *testing.T) { - var err error - acnts := []*engine.PjsuaAccount{ - {Id: "sip:1001@127.0.0.1", - Username: "1001", Password: "CGRateS.org", Realm: "*", Registrar: "sip:127.0.0.1:5080"}, - {Id: "sip:1002@127.0.0.1", - Username: "1002", Password: "CGRateS.org", Realm: "*", Registrar: "sip:127.0.0.1:5080"}, - {Id: "sip:1003@127.0.0.1", - Username: "1003", Password: "CGRateS.org", Realm: "*", Registrar: "sip:127.0.0.1:5080"}, - } - if tutorialCallsPjSuaListener, err = engine.StartPjsuaListener( - acnts, 5070, time.Duration(*waitRater)*time.Millisecond); err != nil { - t.Fatal(err) - } - time.Sleep(1 * time.Second) -} - -// Call from 1001 (prepaid) to 1002 -func testCallCall1001To1002(t *testing.T) { - if err := engine.PjsuaCallUri( - &engine.PjsuaAccount{Id: "sip:1001@127.0.0.1", Username: "1001", Password: "CGRateS.org", Realm: "*"}, - "sip:1002@127.0.0.1", "sip:127.0.0.1:5080", time.Duration(67)*time.Second, 5071); err != nil { - t.Fatal(err) - } - // give time to session to start so we can check it - time.Sleep(time.Second) -} - -// GetActiveSessions -func testCallGetActiveSessions(t *testing.T) { - var reply *[]*sessions.ExternalSession - expected := &[]*sessions.ExternalSession{ - { - RequestType: "*prepaid", - Tenant: "cgrates.org", - Category: "call", - Account: "1001", - Subject: "1001", - Destination: "1002", - }, - } - if err := tutorialCallsRpc.Call(utils.SessionSv1GetActiveSessions, - nil, &reply); err != nil { - t.Error("Got error on SessionSv1.GetActiveSessions: ", err.Error()) - } else { - // compare some fields (eg. CGRId is generated) - if !reflect.DeepEqual((*expected)[0].RequestType, (*reply)[0].RequestType) { - t.Errorf("Expected: %s, received: %s", (*expected)[0].RequestType, (*reply)[0].RequestType) - } else if !reflect.DeepEqual((*expected)[0].Account, (*reply)[0].Account) { - t.Errorf("Expected: %s, received: %s", (*expected)[0].Account, (*reply)[0].Account) - } else if !reflect.DeepEqual((*expected)[0].Destination, (*reply)[0].Destination) { - t.Errorf("Expected: %s, received: %s", (*expected)[0].Destination, (*reply)[0].Destination) - } - } -} - -// Call from 1002 (postpaid) to 1001 -func testCallCall1002To1001(t *testing.T) { - if err := engine.PjsuaCallUri( - &engine.PjsuaAccount{Id: "sip:1002@127.0.0.1", Username: "1002", Password: "CGRateS.org", Realm: "*"}, - "sip:1001@127.0.0.1", "sip:127.0.0.1:5080", time.Duration(65)*time.Second, 5072); err != nil { - t.Fatal(err) - } -} - -// Call from 1001 (prepaid) to 1003 limit to 12 seconds -func testCallCall1001To1003(t *testing.T) { - if err := engine.PjsuaCallUri( - &engine.PjsuaAccount{Id: "sip:1001@127.0.0.1", Username: "1001", Password: "CGRateS.org", Realm: "*"}, - "sip:1003@127.0.0.1", "sip:127.0.0.1:5080", 60*time.Second, 5073); err != nil { - t.Fatal(err) - } -} - -// Call from 1003 (prepaid) to 1001 for 20 seconds -func testCallCall1003To1001(t *testing.T) { - if err := engine.PjsuaCallUri( - &engine.PjsuaAccount{Id: "sip:1003@127.0.0.1", Username: "1003", Password: "CGRateS.org", Realm: "*"}, - "sip:1001@127.0.0.1", "sip:127.0.0.1:5080", 20*time.Second, 5074); err != nil { - t.Fatal(err) - } - // after this call from 1001 to 1003 and call from 1003 to 1001 should be done -} - -// Call from 1003 (prepaid) to 1001 for 15 seconds -func testCallCall1003To1001SecondTime(t *testing.T) { - time.Sleep(22 * time.Second) - if err := engine.PjsuaCallUri( - &engine.PjsuaAccount{Id: "sip:1003@127.0.0.1", Username: "1003", Password: "CGRateS.org", Realm: "*"}, - "sip:1001@127.0.0.1", "sip:127.0.0.1:5080", 15*time.Second, 5075); err != nil { - t.Fatal(err) - } - time.Sleep(time.Second) -} - -// Check if the resource was Allocated -func testCallCheckResourceAllocation(t *testing.T) { - var rs *engine.Resources - args := &utils.ArgRSv1ResourceUsage{ - UsageID: "OriginID1", - CGREvent: &utils.CGREvent{ - Tenant: "cgrates.org", - ID: "ResourceAllocation", - Event: map[string]interface{}{ - utils.Account: "1001", - utils.Subject: "1001", - utils.Destination: "1002"}, - }} - if err := tutorialCallsRpc.Call(utils.ResourceSv1GetResourcesForEvent, args, &rs); err != nil { - t.Fatal(err) - } else if len(*rs) != 1 { - t.Fatalf("Resources: %+v", utils.ToJSON(rs)) - } - for _, r := range *rs { - if r.ID == "ResGroup1" && len(r.Usages) != 3 { - t.Errorf("Unexpected resource: %+v", utils.ToJSON(r)) - } - } - // Allow calls to finish before start querying the results - time.Sleep(time.Duration(50) * time.Second) -} - -// Make sure account was debited properly -func testCallAccount1001(t *testing.T) { - var reply *engine.Account - attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} - if err := tutorialCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error(err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() == 10.0 { // Make sure we debitted - t.Errorf("Expected: 10, received: %+v", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } else if reply.Disabled == true { - t.Error("Account disabled") - } -} - -// Make sure account was debited properly -func testCall1001Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}, Accounts: []string{"1001"}} - if err := tutorialCallsRpc.Call(utils.ApierV2GetCDRs, req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 2 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - for _, cdr := range reply { - if cdr.RequestType != utils.META_PREPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", cdr.RequestType) - } - if cdr.Destination == "1002" { - // in case of Asterisk take the integer part from usage - if optConf == utils.Asterisk { - cdr.Usage = strings.Split(cdr.Usage, ".")[0] + "s" - } - if cdr.Usage != "1m7s" && cdr.Usage != "1m8s" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", cdr.Usage) - } - if cdr.CostSource != utils.MetaSessionS { - t.Errorf("Unexpected CostSource for CDR: %+v", cdr.CostSource) - } - } else if cdr.Destination == "1003" { - // in case of Asterisk take the integer part from usage - if optConf == utils.Asterisk { - cdr.Usage = strings.Split(cdr.Usage, ".")[0] + "s" - } - if cdr.Usage != "12s" && cdr.Usage != "13s" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", cdr.Usage) - } - if cdr.CostSource != utils.MetaSessionS { - t.Errorf("Unexpected CostSource for CDR: %+v", cdr.CostSource) - } - } - } - } -} - -// Make sure account was debited properly -func testCall1002Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}, - Accounts: []string{"1002"}, DestinationPrefixes: []string{"1001"}} - if err := tutorialCallsRpc.Call(utils.ApierV2GetCDRs, req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - if reply[0].RequestType != utils.META_POSTPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0].RequestType) - } - // in case of Asterisk take the integer part from usage - if optConf == utils.Asterisk { - reply[0].Usage = strings.Split(reply[0].Usage, ".")[0] + "s" - } - if reply[0].Usage != "1m5s" && reply[0].Usage != "1m6s" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", reply[0].Usage) - } - if reply[0].CostSource != utils.MetaCDRs { - t.Errorf("Unexpected CostSource for CDR: %+v", reply[0].CostSource) - } - } -} - -// Make sure account was debited properly -func testCall1003Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}, - Accounts: []string{"1003"}, DestinationPrefixes: []string{"1001"}} - if err := tutorialCallsRpc.Call(utils.ApierV2GetCDRs, req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 2 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - for _, cdr := range reply { - if cdr.RequestType != utils.META_PREPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", cdr.RequestType) - } - // in case of Asterisk take the integer part from usage - if optConf == utils.Asterisk { - cdr.Usage = strings.Split(cdr.Usage, ".")[0] + "s" - } - if cdr.Usage != "15s" && cdr.Usage != "16s" && - cdr.Usage != "20s" && cdr.Usage != "21s" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", cdr.Usage) - } - if cdr.CostSource != utils.MetaSessionS { - t.Errorf("Unexpected CostSource for CDR: %+v", cdr.CostSource) - } - - } - } -} - -func testCallStatMetrics(t *testing.T) { - var metrics map[string]string - firstStatMetrics1 := map[string]string{ - utils.MetaTCC: "1.35346", - utils.MetaTCD: "2m27s", - } - firstStatMetrics2 := map[string]string{ - utils.MetaTCC: "1.35009", - utils.MetaTCD: "2m25s", - } - firstStatMetrics3 := map[string]string{ - utils.MetaTCC: "1.34009", - utils.MetaTCD: "2m24s", - } - firstStatMetrics4 := map[string]string{ - utils.MetaTCC: "1.35346", - utils.MetaTCD: "2m24s", - } - secondStatMetrics1 := map[string]string{ - utils.MetaTCC: "0.6", - utils.MetaTCD: "35s", - } - secondStatMetrics2 := map[string]string{ - utils.MetaTCC: "0.6", - utils.MetaTCD: "37s", - } - - if err := tutorialCallsRpc.Call(utils.StatSv1GetQueueStringMetrics, - &utils.TenantID{Tenant: "cgrates.org", ID: "Stats2"}, &metrics); err != nil { - t.Error(err) - } - if optConf == utils.Asterisk { - metrics[utils.MetaTCD] = strings.Split(metrics[utils.MetaTCD], ".")[0] + "s" - } - if !reflect.DeepEqual(firstStatMetrics1, metrics) && - !reflect.DeepEqual(firstStatMetrics2, metrics) && - !reflect.DeepEqual(firstStatMetrics3, metrics) && - !reflect.DeepEqual(firstStatMetrics4, metrics) { - t.Errorf("expecting: %+v, received reply: %s", firstStatMetrics1, metrics) - } - if err := tutorialCallsRpc.Call(utils.StatSv1GetQueueStringMetrics, - &utils.TenantID{Tenant: "cgrates.org", ID: "Stats2_1"}, &metrics); err != nil { - t.Error(err) - } - if optConf == utils.Asterisk { - metrics[utils.MetaTCD] = strings.Split(metrics[utils.MetaTCD], ".")[0] + "s" - } - if !reflect.DeepEqual(secondStatMetrics1, metrics) && - !reflect.DeepEqual(secondStatMetrics2, metrics) { - t.Errorf("expecting: %+v, received reply: %s", secondStatMetrics1, metrics) - } -} - -func testCallCheckResourceRelease(t *testing.T) { - var rs *engine.Resources - args := &utils.ArgRSv1ResourceUsage{ - UsageID: "OriginID2", - CGREvent: &utils.CGREvent{ - Tenant: "cgrates.org", - ID: "ResourceRelease", - Event: map[string]interface{}{ - utils.Account: "1001", - utils.Subject: "1001", - utils.Destination: "1002"}, - }} - if err := tutorialCallsRpc.Call(utils.ResourceSv1GetResourcesForEvent, args, &rs); err != nil { - t.Fatal(err) - } else if len(*rs) != 1 { - t.Fatalf("Resources: %+v", rs) - } - for _, r := range *rs { - if r.ID == "ResGroup1" && len(r.Usages) != 0 { - t.Errorf("Unexpected resource: %+v", utils.ToJSON(r)) - } - } -} - -func testCallCheckThreshold1001After(t *testing.T) { - var td engine.Threshold - if err := tutorialCallsRpc.Call(utils.ThresholdSv1GetThreshold, - &utils.TenantID{Tenant: "cgrates.org", ID: "THD_ACNT_1001"}, &td); err != nil && - err.Error() != utils.ErrNotFound.Error() { - t.Error(err) - } -} - -func testCallCheckThreshold1002After(t *testing.T) { - var td engine.Threshold - eTd := engine.Threshold{Tenant: "cgrates.org", ID: "THD_ACNT_1002", Hits: 4} - if err := tutorialCallsRpc.Call(utils.ThresholdSv1GetThreshold, - &utils.TenantID{Tenant: "cgrates.org", ID: "THD_ACNT_1002"}, &td); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(eTd.Tenant, td.Tenant) { - t.Errorf("expecting: %+v, received: %+v", eTd.Tenant, td.Tenant) - } else if !reflect.DeepEqual(eTd.ID, td.ID) { - t.Errorf("expecting: %+v, received: %+v", eTd.ID, td.ID) - } else if !reflect.DeepEqual(eTd.Hits, td.Hits) { - t.Errorf("expecting: %+v, received: %+v", eTd.Hits, td.Hits) - } -} - -func testCallSyncSessions(t *testing.T) { - var reply *[]*sessions.ExternalSession - // activeSessions shouldn't be active - if err := tutorialCallsRpc.Call(utils.SessionSv1GetActiveSessions, - nil, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { - t.Error("Got error on SessionSv1.GetActiveSessions: ", err) - } - // 1001 call 1002 stop the call after 12 seconds - if err := engine.PjsuaCallUri( - &engine.PjsuaAccount{Id: "sip:1001@127.0.0.1", Username: "1001", Password: "CGRateS.org", Realm: "*"}, - "sip:1002@127.0.0.1", "sip:127.0.0.1:5080", time.Duration(120)*time.Second, 5076); err != nil { - t.Fatal(err) - } - // 1001 call 1003 stop the call after 11 seconds - if err := engine.PjsuaCallUri( - &engine.PjsuaAccount{Id: "sip:1001@127.0.0.1", Username: "1001", Password: "CGRateS.org", Realm: "*"}, - "sip:1003@127.0.0.1", "sip:127.0.0.1:5080", time.Duration(120)*time.Second, 5077); err != nil { - t.Fatal(err) - } - time.Sleep(1 * time.Second) - // get active sessions - if err := tutorialCallsRpc.Call(utils.SessionSv1GetActiveSessions, - nil, &reply); err != nil { - t.Error("Got error on SessionSv1.GetActiveSessions: ", err.Error()) - } else if len(*reply) != 2 { - t.Errorf("expecting 2 active sessions, received: %+v", utils.ToJSON(reply)) - } - //check if resource was allocated for 2 calls(1001->1002;1001->1003) - var rs *engine.Resources - args := &utils.ArgRSv1ResourceUsage{ - UsageID: "OriginID3", - CGREvent: &utils.CGREvent{ - Tenant: "cgrates.org", - ID: "AllocateResource", - Event: map[string]interface{}{ - utils.Account: "1001", - utils.Subject: "1001", - utils.Destination: "1002"}, - }} - if err := tutorialCallsRpc.Call(utils.ResourceSv1GetResourcesForEvent, args, &rs); err != nil { - t.Fatal(err) - } else if len(*rs) != 1 { - t.Fatalf("Resources: %+v", utils.ToJSON(rs)) - } - for _, r := range *rs { - if r.ID == "ResGroup1" && len(r.Usages) != 2 { - t.Errorf("Unexpected resource: %+v", utils.ToJSON(r)) - } - } - - time.Sleep(3 * time.Second) - //stop the FS - switch optConf { - case utils.Freeswitch: - engine.ForceKillProcName(utils.Freeswitch, - int(tutorialCallsCfg.SessionSCfg().ChannelSyncInterval.Nanoseconds()/1e6)) - case utils.Kamailio: - engine.ForceKillProcName(utils.Kamailio, - int(tutorialCallsCfg.SessionSCfg().ChannelSyncInterval.Nanoseconds()/1e6)) - case utils.Opensips: - engine.ForceKillProcName(utils.Opensips, - int(tutorialCallsCfg.SessionSCfg().ChannelSyncInterval.Nanoseconds()/1e6)) - case utils.Asterisk: - engine.ForceKillProcName(utils.Asterisk, - int(tutorialCallsCfg.SessionSCfg().ChannelSyncInterval.Nanoseconds()/1e6)) - default: - t.Errorf("Unsuported format") - } - - time.Sleep(2 * time.Second) - - // activeSessions shouldn't be active - if err := tutorialCallsRpc.Call(utils.SessionSv1GetActiveSessions, - nil, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { - t.Errorf("Got error on SessionSv1.GetActiveSessions: %v and reply: %s", err, utils.ToJSON(reply)) - } - - var sourceForCDR string - var numberOfCDR int - switch optConf { - case utils.Freeswitch: - sourceForCDR = "FS_CHANNEL_ANSWER" - numberOfCDR = 2 - case utils.Kamailio: - sourceForCDR = utils.KamailioAgent - numberOfCDR = 3 - case utils.Asterisk: - sourceForCDR = utils.AsteriskAgent - numberOfCDR = 3 - case utils.Opensips: - sourceForCDR = utils.Opensips - numberOfCDR = 3 - } - // verify cdr - var rplCdrs []*engine.ExternalCDR - req := utils.RPCCDRsFilter{ - Sources: []string{sourceForCDR}, - MaxUsage: "20s", - RunIDs: []string{utils.META_DEFAULT}, - Accounts: []string{"1001"}, - } - if err := tutorialCallsRpc.Call(utils.ApierV2GetCDRs, req, &rplCdrs); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(rplCdrs) != numberOfCDR { // cdr from sync session + cdr from before - t.Fatal("Unexpected number of CDRs returned: ", len(rplCdrs), utils.ToJSON(rplCdrs)) - } else if time1, err := utils.ParseDurationWithSecs(rplCdrs[0].Usage); err != nil { - t.Error(err) - } else if time1 > time.Duration(15*time.Second) { - t.Error("Unexpected time duration : ", time1) - } else if time1, err := utils.ParseDurationWithSecs(rplCdrs[1].Usage); err != nil { - t.Error(err) - } else if time1 > time.Duration(15*time.Second) { - t.Error("Unexpected time duration : ", time1) - } else if numberOfCDR == 3 { - if time1, err := utils.ParseDurationWithSecs(rplCdrs[2].Usage); err != nil { - t.Error(err) - } else if time1 > time.Duration(15*time.Second) { - t.Error("Unexpected time duration : ", time1) - } - } - - //check if resource was released - var rsAfter *engine.Resources - if err := tutorialCallsRpc.Call(utils.ResourceSv1GetResourcesForEvent, args, &rsAfter); err != nil { - t.Fatal(err) - } else if len(*rsAfter) != 1 { - t.Fatalf("Resources: %+v", rsAfter) - } - for _, r := range *rsAfter { - if r.ID == "ResGroup1" && len(r.Usages) != 0 { - t.Errorf("Unexpected resource: %+v", utils.ToJSON(r)) - } - } -} - -func testCallStopPjsuaListener(t *testing.T) { - tutorialCallsPjSuaListener.Write([]byte("q\n")) // Close pjsua - time.Sleep(time.Second) // Allow pjsua to finish it's tasks, eg un-REGISTER -} - -func testCallStopCgrEngine(t *testing.T) { - if err := engine.KillEngine(100); err != nil { - t.Error(err) - } -} - -func testCallStopFS(t *testing.T) { - switch optConf { - case utils.Freeswitch: - engine.ForceKillProcName(utils.Freeswitch, 1000) - case utils.Kamailio: - engine.ForceKillProcName(utils.Kamailio, 1000) - case utils.Opensips: - engine.ForceKillProcName(utils.Opensips, 1000) - case utils.Asterisk: - engine.ForceKillProcName(utils.Asterisk, 1000) - default: - t.Errorf("Unsuported format") - } -} +// +build call + +/* +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 ( + "flag" + "net/rpc" + "net/rpc/jsonrpc" + "os" + "path" + "reflect" + "strings" + "testing" + "time" + + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/sessions" + "github.com/cgrates/cgrates/utils" +) + +var tutorialCallsCfg *config.CGRConfig +var tutorialCallsRpc *rpc.Client +var tutorialCallsPjSuaListener *os.File +var waitRater = flag.Int("wait_rater", 1000, "Number of miliseconds to wait for rater to start and cache") +var dataDir = flag.String("data_dir", "/usr/share/cgrates", "CGR data dir path here") +var fsConfig = flag.String("fsConfig", "/usr/share/cgrates/tutorial_tests/fs_evsock", "FreeSwitch tutorial folder") +var kamConfig = flag.String("kamConfig", "/usr/share/cgrates/tutorial_tests/kamevapi", "Kamailio tutorial folder") +var oSipsConfig = flag.String("osConfig", "/usr/share/cgrates/tutorial_tests/osips", "OpenSips tutorial folder") +var ariConf = flag.String("ariConf", "/usr/share/cgrates/tutorial_tests/asterisk_ari", "Asterisk tutorial folder") +var optConf string + +var sTestsCalls = []func(t *testing.T){ + testCallInitCfg, + testCallResetDataDb, + testCallResetStorDb, + testCallStartFS, + testCallStartEngine, + testCallRestartFS, + testCallRpcConn, + testCallLoadTariffPlanFromFolder, + testCallAccountsBefore, + testCallStatMetricsBefore, + testCallCheckResourceBeforeAllocation, + testCallCheckThreshold1001Before, + testCallCheckThreshold1002Before, + testCallStartPjsuaListener, + testCallCall1001To1002, + testCallGetActiveSessions, + testCallCall1002To1001, + testCallCall1001To1003, + testCallCall1003To1001, + testCallCall1003To1001SecondTime, + testCallCheckResourceAllocation, + testCallAccount1001, + testCall1001Cdrs, + testCall1002Cdrs, + testCall1003Cdrs, + testCallStatMetrics, + testCallCheckResourceRelease, + testCallCheckThreshold1001After, + testCallCheckThreshold1002After, + testCallSyncSessions, + testCallStopPjsuaListener, + testCallStopCgrEngine, + testCallStopFS, +} + +//Test start here +func TestFreeswitchCalls(t *testing.T) { + optConf = utils.Freeswitch + for _, stest := range sTestsCalls { + t.Run("", stest) + } +} + +func TestKamailioCalls(t *testing.T) { + optConf = utils.Kamailio + for _, stest := range sTestsCalls { + t.Run("", stest) + } +} + +func TestOpensipsCalls(t *testing.T) { + optConf = utils.Opensips + for _, stest := range sTestsCalls { + t.Run("", stest) + } +} + +func TestAsteriskCalls(t *testing.T) { + optConf = utils.Asterisk + for _, stest := range sTestsCalls { + t.Run("", stest) + } +} + +func testCallInitCfg(t *testing.T) { + // Init config first + var err error + switch optConf { + case utils.Freeswitch: + tutorialCallsCfg, err = config.NewCGRConfigFromPath(path.Join(*fsConfig, "cgrates", "etc", "cgrates")) + if err != nil { + t.Error(err) + } + case utils.Kamailio: + tutorialCallsCfg, err = config.NewCGRConfigFromPath(path.Join(*kamConfig, "cgrates", "etc", "cgrates")) + if err != nil { + t.Error(err) + } + case utils.Opensips: + tutorialCallsCfg, err = config.NewCGRConfigFromPath(path.Join(*oSipsConfig, "cgrates", "etc", "cgrates")) + if err != nil { + t.Error(err) + } + case utils.Asterisk: + tutorialCallsCfg, err = config.NewCGRConfigFromPath(path.Join(*ariConf, "cgrates", "etc", "cgrates")) + if err != nil { + t.Error(err) + } + default: + t.Error("Invalid option") + } + + tutorialCallsCfg.DataFolderPath = *dataDir // Share DataFolderPath through config towards StoreDb for Flush() + config.SetCgrConfig(tutorialCallsCfg) +} + +// Remove data in both rating and accounting db +func testCallResetDataDb(t *testing.T) { + if err := engine.InitDataDb(tutorialCallsCfg); err != nil { + t.Fatal(err) + } +} + +// Wipe out the cdr database +func testCallResetStorDb(t *testing.T) { + if err := engine.InitStorDb(tutorialCallsCfg); err != nil { + t.Fatal(err) + } +} + +// start FS server +func testCallStartFS(t *testing.T) { + switch optConf { + case utils.Freeswitch: + engine.KillProcName(utils.Freeswitch, 5000) + if err := engine.CallScript(path.Join(*fsConfig, "freeswitch", "etc", "init.d", "freeswitch"), "start", 3000); err != nil { + t.Fatal(err) + } + case utils.Kamailio: + engine.KillProcName(utils.Kamailio, 5000) + if err := engine.CallScript(path.Join(*kamConfig, "kamailio", "etc", "init.d", "kamailio"), "start", 3000); err != nil { + t.Fatal(err) + } + case utils.Opensips: + engine.KillProcName(utils.Kamailio, 5000) + if err := engine.CallScript(path.Join(*oSipsConfig, "opensips", "etc", "init.d", "opensips"), "start", 3000); err != nil { + t.Fatal(err) + } + case utils.Asterisk: + engine.KillProcName(utils.Asterisk, 5000) + if err := engine.CallScript(path.Join(*ariConf, "asterisk", "etc", "init.d", "asterisk"), "start", 3000); err != nil { + t.Fatal(err) + } + default: + t.Error("Invalid option") + } +} + +// Start CGR Engine +func testCallStartEngine(t *testing.T) { + engine.KillProcName("cgr-engine", *waitRater) + switch optConf { + case utils.Freeswitch: + if err := engine.CallScript(path.Join(*fsConfig, "cgrates", "etc", "init.d", "cgrates"), "start", 100); err != nil { + t.Fatal(err) + } + case utils.Kamailio: + if err := engine.CallScript(path.Join(*kamConfig, "cgrates", "etc", "init.d", "cgrates"), "start", 100); err != nil { + t.Fatal(err) + } + case utils.Opensips: + if err := engine.CallScript(path.Join(*oSipsConfig, "cgrates", "etc", "init.d", "cgrates"), "start", 100); err != nil { + t.Fatal(err) + } + case utils.Asterisk: + if err := engine.CallScript(path.Join(*ariConf, "cgrates", "etc", "init.d", "cgrates"), "start", 100); err != nil { + t.Fatal(err) + } + default: + t.Error("invalid option") + } +} + +// Restart FS so we make sure reconnects are working +func testCallRestartFS(t *testing.T) { + switch optConf { + case utils.Freeswitch: + engine.KillProcName(utils.Freeswitch, 5000) + if err := engine.CallScript(path.Join(*fsConfig, "freeswitch", "etc", "init.d", "freeswitch"), "restart", 3000); err != nil { + t.Fatal(err) + } + case utils.Kamailio: + engine.KillProcName(utils.Kamailio, 5000) + if err := engine.CallScript(path.Join(*kamConfig, "kamailio", "etc", "init.d", "kamailio"), "restart", 3000); err != nil { + t.Fatal(err) + } + case utils.Opensips: + engine.KillProcName(utils.Kamailio, 5000) + if err := engine.CallScript(path.Join(*oSipsConfig, "opensips", "etc", "init.d", "opensips"), "restart", 3000); err != nil { + t.Fatal(err) + } + case utils.Asterisk: + engine.KillProcName(utils.Asterisk, 5000) + if err := engine.CallScript(path.Join(*ariConf, "asterisk", "etc", "init.d", "asterisk"), "restart", 3000); err != nil { + t.Fatal(err) + } + default: + t.Error("Invalid option") + } +} + +// Connect rpc client to rater +func testCallRpcConn(t *testing.T) { + var err error + tutorialCallsRpc, err = jsonrpc.Dial("tcp", tutorialCallsCfg.ListenCfg().RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed + if err != nil { + t.Fatal(err) + } +} + +// Load the tariff plan, creating accounts and their balances +func testCallLoadTariffPlanFromFolder(t *testing.T) { + var reply string + attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "tutorial")} + if err := tutorialCallsRpc.Call("ApierV1.LoadTariffPlanFromFolder", attrs, &reply); err != nil { + t.Error(err) + } + time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups +} + +// Make sure account was debited properly +func testCallAccountsBefore(t *testing.T) { + var reply *engine.Account + attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} + if err := tutorialCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { + t.Error("Got error on ApierV2.GetAccount: ", err.Error()) + } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { + t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) + } + var reply2 *engine.Account + attrs2 := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1002"} + if err := tutorialCallsRpc.Call("ApierV2.GetAccount", attrs2, &reply2); err != nil { + t.Error("Got error on ApierV2.GetAccount: ", err.Error()) + } else if reply2.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { + t.Errorf("Calling ApierV1.GetBalance received: %f", reply2.BalanceMap[utils.MONETARY].GetTotalValue()) + } + var reply3 *engine.Account + attrs3 := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1003"} + if err := tutorialCallsRpc.Call("ApierV2.GetAccount", attrs3, &reply3); err != nil { + t.Error("Got error on ApierV2.GetAccount: ", err.Error()) + } else if reply3.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { + t.Errorf("Calling ApierV1.GetBalance received: %f", reply3.BalanceMap[utils.MONETARY].GetTotalValue()) + } +} + +func testCallStatMetricsBefore(t *testing.T) { + var metrics map[string]string + expectedMetrics := map[string]string{ + utils.MetaTCC: utils.NOT_AVAILABLE, + utils.MetaTCD: utils.NOT_AVAILABLE, + } + if err := tutorialCallsRpc.Call(utils.StatSv1GetQueueStringMetrics, + &utils.TenantID{Tenant: "cgrates.org", ID: "Stats2"}, &metrics); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(expectedMetrics, metrics) { + t.Errorf("expecting: %+v, received reply: %s", expectedMetrics, metrics) + } + if err := tutorialCallsRpc.Call(utils.StatSv1GetQueueStringMetrics, + &utils.TenantID{Tenant: "cgrates.org", ID: "Stats2_1"}, &metrics); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(expectedMetrics, metrics) { + t.Errorf("expecting: %+v, received reply: %s", expectedMetrics, metrics) + } +} + +func testCallCheckResourceBeforeAllocation(t *testing.T) { + var rs *engine.Resources + args := &utils.ArgRSv1ResourceUsage{ + UsageID: "OriginID", + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "ResourceEvent", + Event: map[string]interface{}{ + utils.Account: "1001", + utils.Subject: "1001", + utils.Destination: "1002"}, + }} + if err := tutorialCallsRpc.Call(utils.ResourceSv1GetResourcesForEvent, args, &rs); err != nil { + t.Fatal(err) + } else if len(*rs) != 1 { + t.Fatalf("Resources: %+v", utils.ToJSON(rs)) + } + for _, r := range *rs { + if r.ID == "ResGroup1" && + (len(r.Usages) != 0 || len(r.TTLIdx) != 0) { + t.Errorf("Unexpected resource: %+v", utils.ToJSON(r)) + } + } +} + +func testCallCheckThreshold1001Before(t *testing.T) { + var td engine.Threshold + eTd := engine.Threshold{Tenant: "cgrates.org", ID: "THD_ACNT_1001", Hits: 0} + if err := tutorialCallsRpc.Call(utils.ThresholdSv1GetThreshold, + &utils.TenantID{Tenant: "cgrates.org", ID: "THD_ACNT_1001"}, &td); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(eTd, td) { + t.Errorf("expecting: %+v, received: %+v", eTd, td) + } +} + +func testCallCheckThreshold1002Before(t *testing.T) { + var td engine.Threshold + eTd := engine.Threshold{Tenant: "cgrates.org", ID: "THD_ACNT_1002", Hits: 0} + if err := tutorialCallsRpc.Call(utils.ThresholdSv1GetThreshold, + &utils.TenantID{Tenant: "cgrates.org", ID: "THD_ACNT_1002"}, &td); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(eTd, td) { + t.Errorf("expecting: %+v, received: %+v", eTd, td) + } +} + +// Start Pjsua as listener and register it to receive calls +func testCallStartPjsuaListener(t *testing.T) { + var err error + acnts := []*engine.PjsuaAccount{ + {Id: "sip:1001@127.0.0.1", + Username: "1001", Password: "CGRateS.org", Realm: "*", Registrar: "sip:127.0.0.1:5080"}, + {Id: "sip:1002@127.0.0.1", + Username: "1002", Password: "CGRateS.org", Realm: "*", Registrar: "sip:127.0.0.1:5080"}, + {Id: "sip:1003@127.0.0.1", + Username: "1003", Password: "CGRateS.org", Realm: "*", Registrar: "sip:127.0.0.1:5080"}, + } + if tutorialCallsPjSuaListener, err = engine.StartPjsuaListener( + acnts, 5070, time.Duration(*waitRater)*time.Millisecond); err != nil { + t.Fatal(err) + } + time.Sleep(1 * time.Second) +} + +// Call from 1001 (prepaid) to 1002 +func testCallCall1001To1002(t *testing.T) { + if err := engine.PjsuaCallUri( + &engine.PjsuaAccount{Id: "sip:1001@127.0.0.1", Username: "1001", Password: "CGRateS.org", Realm: "*"}, + "sip:1002@127.0.0.1", "sip:127.0.0.1:5080", time.Duration(67)*time.Second, 5071); err != nil { + t.Fatal(err) + } + // give time to session to start so we can check it + time.Sleep(time.Second) +} + +// GetActiveSessions +func testCallGetActiveSessions(t *testing.T) { + var reply *[]*sessions.ExternalSession + expected := &[]*sessions.ExternalSession{ + { + RequestType: "*prepaid", + Tenant: "cgrates.org", + Category: "call", + Account: "1001", + Subject: "1001", + Destination: "1002", + }, + } + if err := tutorialCallsRpc.Call(utils.SessionSv1GetActiveSessions, + nil, &reply); err != nil { + t.Error("Got error on SessionSv1.GetActiveSessions: ", err.Error()) + } else { + // compare some fields (eg. CGRId is generated) + if !reflect.DeepEqual((*expected)[0].RequestType, (*reply)[0].RequestType) { + t.Errorf("Expected: %s, received: %s", (*expected)[0].RequestType, (*reply)[0].RequestType) + } else if !reflect.DeepEqual((*expected)[0].Account, (*reply)[0].Account) { + t.Errorf("Expected: %s, received: %s", (*expected)[0].Account, (*reply)[0].Account) + } else if !reflect.DeepEqual((*expected)[0].Destination, (*reply)[0].Destination) { + t.Errorf("Expected: %s, received: %s", (*expected)[0].Destination, (*reply)[0].Destination) + } + } +} + +// Call from 1002 (postpaid) to 1001 +func testCallCall1002To1001(t *testing.T) { + if err := engine.PjsuaCallUri( + &engine.PjsuaAccount{Id: "sip:1002@127.0.0.1", Username: "1002", Password: "CGRateS.org", Realm: "*"}, + "sip:1001@127.0.0.1", "sip:127.0.0.1:5080", time.Duration(65)*time.Second, 5072); err != nil { + t.Fatal(err) + } +} + +// Call from 1001 (prepaid) to 1003 limit to 12 seconds +func testCallCall1001To1003(t *testing.T) { + if err := engine.PjsuaCallUri( + &engine.PjsuaAccount{Id: "sip:1001@127.0.0.1", Username: "1001", Password: "CGRateS.org", Realm: "*"}, + "sip:1003@127.0.0.1", "sip:127.0.0.1:5080", 60*time.Second, 5073); err != nil { + t.Fatal(err) + } +} + +// Call from 1003 (prepaid) to 1001 for 20 seconds +func testCallCall1003To1001(t *testing.T) { + if err := engine.PjsuaCallUri( + &engine.PjsuaAccount{Id: "sip:1003@127.0.0.1", Username: "1003", Password: "CGRateS.org", Realm: "*"}, + "sip:1001@127.0.0.1", "sip:127.0.0.1:5080", 20*time.Second, 5074); err != nil { + t.Fatal(err) + } + // after this call from 1001 to 1003 and call from 1003 to 1001 should be done +} + +// Call from 1003 (prepaid) to 1001 for 15 seconds +func testCallCall1003To1001SecondTime(t *testing.T) { + time.Sleep(22 * time.Second) + if err := engine.PjsuaCallUri( + &engine.PjsuaAccount{Id: "sip:1003@127.0.0.1", Username: "1003", Password: "CGRateS.org", Realm: "*"}, + "sip:1001@127.0.0.1", "sip:127.0.0.1:5080", 15*time.Second, 5075); err != nil { + t.Fatal(err) + } + time.Sleep(time.Second) +} + +// Check if the resource was Allocated +func testCallCheckResourceAllocation(t *testing.T) { + var rs *engine.Resources + args := &utils.ArgRSv1ResourceUsage{ + UsageID: "OriginID1", + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "ResourceAllocation", + Event: map[string]interface{}{ + utils.Account: "1001", + utils.Subject: "1001", + utils.Destination: "1002"}, + }} + if err := tutorialCallsRpc.Call(utils.ResourceSv1GetResourcesForEvent, args, &rs); err != nil { + t.Fatal(err) + } else if len(*rs) != 1 { + t.Fatalf("Resources: %+v", utils.ToJSON(rs)) + } + for _, r := range *rs { + if r.ID == "ResGroup1" && len(r.Usages) != 3 { + t.Errorf("Unexpected resource: %+v", utils.ToJSON(r)) + } + } + // Allow calls to finish before start querying the results + time.Sleep(time.Duration(50) * time.Second) +} + +// Make sure account was debited properly +func testCallAccount1001(t *testing.T) { + var reply *engine.Account + attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} + if err := tutorialCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { + t.Error(err.Error()) + } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() == 10.0 { // Make sure we debitted + t.Errorf("Expected: 10, received: %+v", reply.BalanceMap[utils.MONETARY].GetTotalValue()) + } else if reply.Disabled == true { + t.Error("Account disabled") + } +} + +// Make sure account was debited properly +func testCall1001Cdrs(t *testing.T) { + var reply []*engine.ExternalCDR + req := utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}, Accounts: []string{"1001"}} + if err := tutorialCallsRpc.Call(utils.ApierV2GetCDRs, req, &reply); err != nil { + t.Error("Unexpected error: ", err.Error()) + } else if len(reply) != 2 { + t.Error("Unexpected number of CDRs returned: ", len(reply)) + } else { + for _, cdr := range reply { + if cdr.RequestType != utils.META_PREPAID { + t.Errorf("Unexpected RequestType for CDR: %+v", cdr.RequestType) + } + if cdr.Destination == "1002" { + // in case of Asterisk take the integer part from usage + if optConf == utils.Asterisk { + cdr.Usage = strings.Split(cdr.Usage, ".")[0] + "s" + } + if cdr.Usage != "1m7s" && cdr.Usage != "1m8s" { // Usage as seconds + t.Errorf("Unexpected Usage for CDR: %+v", cdr.Usage) + } + if cdr.CostSource != utils.MetaSessionS { + t.Errorf("Unexpected CostSource for CDR: %+v", cdr.CostSource) + } + } else if cdr.Destination == "1003" { + // in case of Asterisk take the integer part from usage + if optConf == utils.Asterisk { + cdr.Usage = strings.Split(cdr.Usage, ".")[0] + "s" + } + if cdr.Usage != "12s" && cdr.Usage != "13s" { // Usage as seconds + t.Errorf("Unexpected Usage for CDR: %+v", cdr.Usage) + } + if cdr.CostSource != utils.MetaSessionS { + t.Errorf("Unexpected CostSource for CDR: %+v", cdr.CostSource) + } + } + } + } +} + +// Make sure account was debited properly +func testCall1002Cdrs(t *testing.T) { + var reply []*engine.ExternalCDR + req := utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}, + Accounts: []string{"1002"}, DestinationPrefixes: []string{"1001"}} + if err := tutorialCallsRpc.Call(utils.ApierV2GetCDRs, req, &reply); err != nil { + t.Error("Unexpected error: ", err.Error()) + } else if len(reply) != 1 { + t.Error("Unexpected number of CDRs returned: ", len(reply)) + } else { + if reply[0].RequestType != utils.META_POSTPAID { + t.Errorf("Unexpected RequestType for CDR: %+v", reply[0].RequestType) + } + // in case of Asterisk take the integer part from usage + if optConf == utils.Asterisk { + reply[0].Usage = strings.Split(reply[0].Usage, ".")[0] + "s" + } + if reply[0].Usage != "1m5s" && reply[0].Usage != "1m6s" { // Usage as seconds + t.Errorf("Unexpected Usage for CDR: %+v", reply[0].Usage) + } + if reply[0].CostSource != utils.MetaCDRs { + t.Errorf("Unexpected CostSource for CDR: %+v", reply[0].CostSource) + } + } +} + +// Make sure account was debited properly +func testCall1003Cdrs(t *testing.T) { + var reply []*engine.ExternalCDR + req := utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}, + Accounts: []string{"1003"}, DestinationPrefixes: []string{"1001"}} + if err := tutorialCallsRpc.Call(utils.ApierV2GetCDRs, req, &reply); err != nil { + t.Error("Unexpected error: ", err.Error()) + } else if len(reply) != 2 { + t.Error("Unexpected number of CDRs returned: ", len(reply)) + } else { + for _, cdr := range reply { + if cdr.RequestType != utils.META_PREPAID { + t.Errorf("Unexpected RequestType for CDR: %+v", cdr.RequestType) + } + // in case of Asterisk take the integer part from usage + if optConf == utils.Asterisk { + cdr.Usage = strings.Split(cdr.Usage, ".")[0] + "s" + } + if cdr.Usage != "15s" && cdr.Usage != "16s" && + cdr.Usage != "20s" && cdr.Usage != "21s" { // Usage as seconds + t.Errorf("Unexpected Usage for CDR: %+v", cdr.Usage) + } + if cdr.CostSource != utils.MetaSessionS { + t.Errorf("Unexpected CostSource for CDR: %+v", cdr.CostSource) + } + + } + } +} + +func testCallStatMetrics(t *testing.T) { + var metrics map[string]string + firstStatMetrics1 := map[string]string{ + utils.MetaTCC: "1.35346", + utils.MetaTCD: "2m27s", + } + firstStatMetrics2 := map[string]string{ + utils.MetaTCC: "1.35009", + utils.MetaTCD: "2m25s", + } + firstStatMetrics3 := map[string]string{ + utils.MetaTCC: "1.34009", + utils.MetaTCD: "2m24s", + } + firstStatMetrics4 := map[string]string{ + utils.MetaTCC: "1.35346", + utils.MetaTCD: "2m24s", + } + secondStatMetrics1 := map[string]string{ + utils.MetaTCC: "0.6", + utils.MetaTCD: "35s", + } + secondStatMetrics2 := map[string]string{ + utils.MetaTCC: "0.6", + utils.MetaTCD: "37s", + } + + if err := tutorialCallsRpc.Call(utils.StatSv1GetQueueStringMetrics, + &utils.TenantID{Tenant: "cgrates.org", ID: "Stats2"}, &metrics); err != nil { + t.Error(err) + } + if optConf == utils.Asterisk { + metrics[utils.MetaTCD] = strings.Split(metrics[utils.MetaTCD], ".")[0] + "s" + } + if !reflect.DeepEqual(firstStatMetrics1, metrics) && + !reflect.DeepEqual(firstStatMetrics2, metrics) && + !reflect.DeepEqual(firstStatMetrics3, metrics) && + !reflect.DeepEqual(firstStatMetrics4, metrics) { + t.Errorf("expecting: %+v, received reply: %s", firstStatMetrics1, metrics) + } + if err := tutorialCallsRpc.Call(utils.StatSv1GetQueueStringMetrics, + &utils.TenantID{Tenant: "cgrates.org", ID: "Stats2_1"}, &metrics); err != nil { + t.Error(err) + } + if optConf == utils.Asterisk { + metrics[utils.MetaTCD] = strings.Split(metrics[utils.MetaTCD], ".")[0] + "s" + } + if !reflect.DeepEqual(secondStatMetrics1, metrics) && + !reflect.DeepEqual(secondStatMetrics2, metrics) { + t.Errorf("expecting: %+v, received reply: %s", secondStatMetrics1, metrics) + } +} + +func testCallCheckResourceRelease(t *testing.T) { + var rs *engine.Resources + args := &utils.ArgRSv1ResourceUsage{ + UsageID: "OriginID2", + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "ResourceRelease", + Event: map[string]interface{}{ + utils.Account: "1001", + utils.Subject: "1001", + utils.Destination: "1002"}, + }} + if err := tutorialCallsRpc.Call(utils.ResourceSv1GetResourcesForEvent, args, &rs); err != nil { + t.Fatal(err) + } else if len(*rs) != 1 { + t.Fatalf("Resources: %+v", rs) + } + for _, r := range *rs { + if r.ID == "ResGroup1" && len(r.Usages) != 0 { + t.Errorf("Unexpected resource: %+v", utils.ToJSON(r)) + } + } +} + +func testCallCheckThreshold1001After(t *testing.T) { + var td engine.Threshold + if err := tutorialCallsRpc.Call(utils.ThresholdSv1GetThreshold, + &utils.TenantID{Tenant: "cgrates.org", ID: "THD_ACNT_1001"}, &td); err != nil && + err.Error() != utils.ErrNotFound.Error() { + t.Error(err) + } +} + +func testCallCheckThreshold1002After(t *testing.T) { + var td engine.Threshold + eTd := engine.Threshold{Tenant: "cgrates.org", ID: "THD_ACNT_1002", Hits: 4} + if err := tutorialCallsRpc.Call(utils.ThresholdSv1GetThreshold, + &utils.TenantID{Tenant: "cgrates.org", ID: "THD_ACNT_1002"}, &td); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(eTd.Tenant, td.Tenant) { + t.Errorf("expecting: %+v, received: %+v", eTd.Tenant, td.Tenant) + } else if !reflect.DeepEqual(eTd.ID, td.ID) { + t.Errorf("expecting: %+v, received: %+v", eTd.ID, td.ID) + } else if !reflect.DeepEqual(eTd.Hits, td.Hits) { + t.Errorf("expecting: %+v, received: %+v", eTd.Hits, td.Hits) + } +} + +func testCallSyncSessions(t *testing.T) { + var reply *[]*sessions.ExternalSession + // activeSessions shouldn't be active + if err := tutorialCallsRpc.Call(utils.SessionSv1GetActiveSessions, + nil, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { + t.Error("Got error on SessionSv1.GetActiveSessions: ", err) + } + // 1001 call 1002 stop the call after 12 seconds + if err := engine.PjsuaCallUri( + &engine.PjsuaAccount{Id: "sip:1001@127.0.0.1", Username: "1001", Password: "CGRateS.org", Realm: "*"}, + "sip:1002@127.0.0.1", "sip:127.0.0.1:5080", time.Duration(120)*time.Second, 5076); err != nil { + t.Fatal(err) + } + // 1001 call 1003 stop the call after 11 seconds + if err := engine.PjsuaCallUri( + &engine.PjsuaAccount{Id: "sip:1001@127.0.0.1", Username: "1001", Password: "CGRateS.org", Realm: "*"}, + "sip:1003@127.0.0.1", "sip:127.0.0.1:5080", time.Duration(120)*time.Second, 5077); err != nil { + t.Fatal(err) + } + time.Sleep(1 * time.Second) + // get active sessions + if err := tutorialCallsRpc.Call(utils.SessionSv1GetActiveSessions, + nil, &reply); err != nil { + t.Error("Got error on SessionSv1.GetActiveSessions: ", err.Error()) + } else if len(*reply) != 2 { + t.Errorf("expecting 2 active sessions, received: %+v", utils.ToJSON(reply)) + } + //check if resource was allocated for 2 calls(1001->1002;1001->1003) + var rs *engine.Resources + args := &utils.ArgRSv1ResourceUsage{ + UsageID: "OriginID3", + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "AllocateResource", + Event: map[string]interface{}{ + utils.Account: "1001", + utils.Subject: "1001", + utils.Destination: "1002"}, + }} + if err := tutorialCallsRpc.Call(utils.ResourceSv1GetResourcesForEvent, args, &rs); err != nil { + t.Fatal(err) + } else if len(*rs) != 1 { + t.Fatalf("Resources: %+v", utils.ToJSON(rs)) + } + for _, r := range *rs { + if r.ID == "ResGroup1" && len(r.Usages) != 2 { + t.Errorf("Unexpected resource: %+v", utils.ToJSON(r)) + } + } + + time.Sleep(3 * time.Second) + //stop the FS + switch optConf { + case utils.Freeswitch: + engine.ForceKillProcName(utils.Freeswitch, + int(tutorialCallsCfg.SessionSCfg().ChannelSyncInterval.Nanoseconds()/1e6)) + case utils.Kamailio: + engine.ForceKillProcName(utils.Kamailio, + int(tutorialCallsCfg.SessionSCfg().ChannelSyncInterval.Nanoseconds()/1e6)) + case utils.Opensips: + engine.ForceKillProcName(utils.Opensips, + int(tutorialCallsCfg.SessionSCfg().ChannelSyncInterval.Nanoseconds()/1e6)) + case utils.Asterisk: + engine.ForceKillProcName(utils.Asterisk, + int(tutorialCallsCfg.SessionSCfg().ChannelSyncInterval.Nanoseconds()/1e6)) + default: + t.Errorf("Unsuported format") + } + + time.Sleep(2 * time.Second) + + // activeSessions shouldn't be active + if err := tutorialCallsRpc.Call(utils.SessionSv1GetActiveSessions, + nil, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { + t.Errorf("Got error on SessionSv1.GetActiveSessions: %v and reply: %s", err, utils.ToJSON(reply)) + } + + var sourceForCDR string + var numberOfCDR int + switch optConf { + case utils.Freeswitch: + sourceForCDR = "FS_CHANNEL_ANSWER" + numberOfCDR = 2 + case utils.Kamailio: + sourceForCDR = utils.KamailioAgent + numberOfCDR = 3 + case utils.Asterisk: + sourceForCDR = utils.AsteriskAgent + numberOfCDR = 3 + case utils.Opensips: + sourceForCDR = utils.Opensips + numberOfCDR = 3 + } + // verify cdr + var rplCdrs []*engine.ExternalCDR + req := utils.RPCCDRsFilter{ + Sources: []string{sourceForCDR}, + MaxUsage: "20s", + RunIDs: []string{utils.META_DEFAULT}, + Accounts: []string{"1001"}, + } + if err := tutorialCallsRpc.Call(utils.ApierV2GetCDRs, req, &rplCdrs); err != nil { + t.Error("Unexpected error: ", err.Error()) + } else if len(rplCdrs) != numberOfCDR { // cdr from sync session + cdr from before + t.Fatal("Unexpected number of CDRs returned: ", len(rplCdrs), utils.ToJSON(rplCdrs)) + } else if time1, err := utils.ParseDurationWithSecs(rplCdrs[0].Usage); err != nil { + t.Error(err) + } else if time1 > time.Duration(15*time.Second) { + t.Error("Unexpected time duration : ", time1) + } else if time1, err := utils.ParseDurationWithSecs(rplCdrs[1].Usage); err != nil { + t.Error(err) + } else if time1 > time.Duration(15*time.Second) { + t.Error("Unexpected time duration : ", time1) + } else if numberOfCDR == 3 { + if time1, err := utils.ParseDurationWithSecs(rplCdrs[2].Usage); err != nil { + t.Error(err) + } else if time1 > time.Duration(15*time.Second) { + t.Error("Unexpected time duration : ", time1) + } + } + + //check if resource was released + var rsAfter *engine.Resources + if err := tutorialCallsRpc.Call(utils.ResourceSv1GetResourcesForEvent, args, &rsAfter); err != nil { + t.Fatal(err) + } else if len(*rsAfter) != 1 { + t.Fatalf("Resources: %+v", rsAfter) + } + for _, r := range *rsAfter { + if r.ID == "ResGroup1" && len(r.Usages) != 0 { + t.Errorf("Unexpected resource: %+v", utils.ToJSON(r)) + } + } +} + +func testCallStopPjsuaListener(t *testing.T) { + tutorialCallsPjSuaListener.Write([]byte("q\n")) // Close pjsua + time.Sleep(time.Second) // Allow pjsua to finish it's tasks, eg un-REGISTER +} + +func testCallStopCgrEngine(t *testing.T) { + if err := engine.KillEngine(100); err != nil { + t.Error(err) + } +} + +func testCallStopFS(t *testing.T) { + switch optConf { + case utils.Freeswitch: + engine.ForceKillProcName(utils.Freeswitch, 1000) + case utils.Kamailio: + engine.ForceKillProcName(utils.Kamailio, 1000) + case utils.Opensips: + engine.ForceKillProcName(utils.Opensips, 1000) + case utils.Asterisk: + engine.ForceKillProcName(utils.Asterisk, 1000) + default: + t.Errorf("Unsuported format") + } +} diff --git a/general_tests/tutorial_it_test.go b/general_tests/tutorial_it_test.go index c5b4331e1..351c6d9bb 100644 --- a/general_tests/tutorial_it_test.go +++ b/general_tests/tutorial_it_test.go @@ -1,148 +1,148 @@ -// +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 general_tests - -import ( - "flag" - "net/rpc" - "net/rpc/jsonrpc" - "path" - "testing" - "time" - - v1 "github.com/cgrates/cgrates/apier/v1" - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" -) - -var ( - itTestMongoAtalas = flag.Bool("mongo_atlas", false, "Run the test with mongo atalas connection") - tutorialCfgPath string - tutorialCfg *config.CGRConfig - tutorialRpc *rpc.Client - tutorialConfDIR string //run tests for specific configuration - tutorialDelay int -) - -var sTestsTutorials = []func(t *testing.T){ - testTutorialLoadConfig, - testTutorialResetDB, - testTutorialStartEngine, - testTutorialRpcConn, - testTutorialFromFolder, - testTutorialGetCost, - testTutorialStopEngine, -} - -//Test start here -func TestTutorialMongoAtlas(t *testing.T) { - if !*itTestMongoAtalas { - return - } - tutorialConfDIR = "mongoatlas" - for _, stest := range sTestsTutorials { - t.Run(tutorialConfDIR, stest) - } -} - -func TestTutorialMongo(t *testing.T) { - tutorialConfDIR = "tutmongo" - for _, stest := range sTestsTutorials { - t.Run(tutorialConfDIR, stest) - } -} - -func TestTutorialMySQL(t *testing.T) { - tutorialConfDIR = "tutmysql" - for _, stest := range sTestsTutorials { - t.Run(tutorialConfDIR, stest) - } -} - -func testTutorialLoadConfig(t *testing.T) { - var err error - tutorialCfgPath = path.Join(*dataDir, "conf", "samples", tutorialConfDIR) - if tutorialCfg, err = config.NewCGRConfigFromPath(tutorialCfgPath); err != nil { - t.Error(err) - } - switch tutorialConfDIR { - case "mongoatlas": // Mongo needs more time to reset db - tutorialDelay = 4000 - default: - tutorialDelay = 2000 - } -} - -func testTutorialResetDB(t *testing.T) { - if err := engine.InitDataDb(tutorialCfg); err != nil { - t.Fatal(err) - } - if err := engine.InitStorDb(tutorialCfg); err != nil { - t.Fatal(err) - } -} - -func testTutorialStartEngine(t *testing.T) { - if _, err := engine.StopStartEngine(tutorialCfgPath, tutorialDelay); err != nil { - t.Fatal(err) - } -} - -func testTutorialRpcConn(t *testing.T) { - var err error - tutorialRpc, err = jsonrpc.Dial("tcp", tutorialCfg.ListenCfg().RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed - if err != nil { - t.Fatal("Could not connect to rater: ", err.Error()) - } -} - -func testTutorialFromFolder(t *testing.T) { - var reply string - attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "tutorial")} - if err := tutorialRpc.Call("ApierV1.LoadTariffPlanFromFolder", attrs, &reply); err != nil { - t.Error(err) - } - time.Sleep(500 * time.Millisecond) -} - -func testTutorialGetCost(t *testing.T) { - attrs := v1.AttrGetCost{ - Tenant: "cgrates.org", - Category: "call", - Subject: "1001", - Destination: "1002", - AnswerTime: "*now", - Usage: "2m10s", - } - var rply *engine.EventCost - if err := tutorialRpc.Call("ApierV1.GetCost", attrs, &rply); err != nil { - t.Error("Unexpected nil error received: ", err.Error()) - } else if *rply.Cost != 0.716900 { - t.Errorf("Unexpected cost received: %f", *rply.Cost) - } -} - -func testTutorialStopEngine(t *testing.T) { - if err := engine.KillEngine(tutorialDelay); err != nil { - t.Error(err) - } -} +// +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 general_tests + +import ( + "flag" + "net/rpc" + "net/rpc/jsonrpc" + "path" + "testing" + "time" + + v1 "github.com/cgrates/cgrates/apier/v1" + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" +) + +var ( + itTestMongoAtalas = flag.Bool("mongo_atlas", false, "Run the test with mongo atalas connection") + tutorialCfgPath string + tutorialCfg *config.CGRConfig + tutorialRpc *rpc.Client + tutorialConfDIR string //run tests for specific configuration + tutorialDelay int + + sTestsTutorials = []func(t *testing.T){ + testTutorialLoadConfig, + testTutorialResetDB, + testTutorialStartEngine, + testTutorialRpcConn, + testTutorialFromFolder, + testTutorialGetCost, + testTutorialStopEngine, + } +) + +//Test start here +func TestTutorialMongoAtlas(t *testing.T) { + if !*itTestMongoAtalas { + return + } + tutorialConfDIR = "mongoatlas" + for _, stest := range sTestsTutorials { + t.Run(tutorialConfDIR, stest) + } +} + +func TestTutorialMongo(t *testing.T) { + tutorialConfDIR = "tutmongo" + for _, stest := range sTestsTutorials { + t.Run(tutorialConfDIR, stest) + } +} + +func TestTutorialMySQL(t *testing.T) { + tutorialConfDIR = "tutmysql" + for _, stest := range sTestsTutorials { + t.Run(tutorialConfDIR, stest) + } +} + +func testTutorialLoadConfig(t *testing.T) { + var err error + tutorialCfgPath = path.Join(*dataDir, "conf", "samples", tutorialConfDIR) + if tutorialCfg, err = config.NewCGRConfigFromPath(tutorialCfgPath); err != nil { + t.Error(err) + } + switch tutorialConfDIR { + case "mongoatlas": // Mongo needs more time to reset db + tutorialDelay = 4000 + default: + tutorialDelay = 2000 + } +} + +func testTutorialResetDB(t *testing.T) { + if err := engine.InitDataDb(tutorialCfg); err != nil { + t.Fatal(err) + } + if err := engine.InitStorDb(tutorialCfg); err != nil { + t.Fatal(err) + } +} + +func testTutorialStartEngine(t *testing.T) { + if _, err := engine.StopStartEngine(tutorialCfgPath, tutorialDelay); err != nil { + t.Fatal(err) + } +} + +func testTutorialRpcConn(t *testing.T) { + var err error + tutorialRpc, err = jsonrpc.Dial("tcp", tutorialCfg.ListenCfg().RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed + if err != nil { + t.Fatal("Could not connect to rater: ", err.Error()) + } +} + +func testTutorialFromFolder(t *testing.T) { + var reply string + attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "tutorial")} + if err := tutorialRpc.Call("ApierV1.LoadTariffPlanFromFolder", attrs, &reply); err != nil { + t.Error(err) + } + time.Sleep(500 * time.Millisecond) +} + +func testTutorialGetCost(t *testing.T) { + attrs := v1.AttrGetCost{ + Tenant: "cgrates.org", + Category: "call", + Subject: "1001", + Destination: "1002", + AnswerTime: "*now", + Usage: "2m10s", + } + var rply *engine.EventCost + if err := tutorialRpc.Call("ApierV1.GetCost", attrs, &rply); err != nil { + t.Error("Unexpected nil error received: ", err.Error()) + } else if *rply.Cost != 0.716900 { + t.Errorf("Unexpected cost received: %f", *rply.Cost) + } +} + +func testTutorialStopEngine(t *testing.T) { + if err := engine.KillEngine(tutorialDelay); err != nil { + t.Error(err) + } +}