Updated general tests with sub-tests

This commit is contained in:
adragusin
2019-10-25 16:31:58 +03:00
committed by Dan Christian Bogos
parent 7e884a4058
commit 519a11cebb
21 changed files with 2255 additions and 2043 deletions

View File

@@ -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) {

View File

@@ -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"

View File

@@ -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) {

View File

@@ -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)
}

View File

@@ -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) {

View File

@@ -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)
}

View File

@@ -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) {

View File

@@ -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 <mysql>")
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 <mysql>")
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)
}

View File

@@ -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)
}

View File

@@ -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 <http://www.gnu.org/licenses/>
*/
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 <http://www.gnu.org/licenses/>
*/
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)
}
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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) {

View File

@@ -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)
}

View File

@@ -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 <http://www.gnu.org/licenses/>
*/
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 <http://www.gnu.org/licenses/>
*/
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)
}
}

View File

@@ -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)
}

View File

@@ -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")

View File

@@ -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 <http://www.gnu.org/licenses/>
*/
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 <http://www.gnu.org/licenses/>
*/
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)
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -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 <http://www.gnu.org/licenses/>
*/
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 <http://www.gnu.org/licenses/>
*/
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)
}
}