From ceb3522ec0941b57226d8e73e851b52535b8c9f9 Mon Sep 17 00:00:00 2001 From: TeoV Date: Mon, 16 Dec 2019 11:02:13 -0500 Subject: [PATCH 1/3] Add test for GOCS functionality --- data/conf/samples/gocs/au_site/cgrates.json | 93 ++++ data/conf/samples/gocs/dsp_site/cgrates.json | 50 ++ data/conf/samples/gocs/us_site/cgrates.json | 104 ++++ data/tariffplans/gocs/au_site/Chargers.csv | 2 + .../gocs/au_site/DestinationRates.csv | 4 + .../tariffplans/gocs/au_site/Destinations.csv | 3 + data/tariffplans/gocs/au_site/Rates.csv | 5 + data/tariffplans/gocs/au_site/RatingPlans.csv | 3 + .../gocs/au_site/RatingProfiles.csv | 3 + .../gocs/dsp_site/DispatcherHosts.csv | 4 + .../gocs/dsp_site/DispatcherProfiles.csv | 4 + .../gocs/us_site/AccountActions.csv | 3 + data/tariffplans/gocs/us_site/ActionPlans.csv | 2 + data/tariffplans/gocs/us_site/Actions.csv | 3 + data/tariffplans/gocs/us_site/Chargers.csv | 2 + .../gocs/us_site/DestinationRates.csv | 4 + .../tariffplans/gocs/us_site/Destinations.csv | 3 + data/tariffplans/gocs/us_site/Rates.csv | 5 + data/tariffplans/gocs/us_site/RatingPlans.csv | 3 + .../gocs/us_site/RatingProfiles.csv | 3 + general_tests/gocs_it_test.go | 497 ++++++++++++++++++ services/datadb.go | 4 +- 22 files changed, 802 insertions(+), 2 deletions(-) create mode 100644 data/conf/samples/gocs/au_site/cgrates.json create mode 100644 data/conf/samples/gocs/dsp_site/cgrates.json create mode 100644 data/conf/samples/gocs/us_site/cgrates.json create mode 100644 data/tariffplans/gocs/au_site/Chargers.csv create mode 100644 data/tariffplans/gocs/au_site/DestinationRates.csv create mode 100644 data/tariffplans/gocs/au_site/Destinations.csv create mode 100644 data/tariffplans/gocs/au_site/Rates.csv create mode 100644 data/tariffplans/gocs/au_site/RatingPlans.csv create mode 100644 data/tariffplans/gocs/au_site/RatingProfiles.csv create mode 100644 data/tariffplans/gocs/dsp_site/DispatcherHosts.csv create mode 100644 data/tariffplans/gocs/dsp_site/DispatcherProfiles.csv create mode 100644 data/tariffplans/gocs/us_site/AccountActions.csv create mode 100644 data/tariffplans/gocs/us_site/ActionPlans.csv create mode 100644 data/tariffplans/gocs/us_site/Actions.csv create mode 100644 data/tariffplans/gocs/us_site/Chargers.csv create mode 100644 data/tariffplans/gocs/us_site/DestinationRates.csv create mode 100644 data/tariffplans/gocs/us_site/Destinations.csv create mode 100644 data/tariffplans/gocs/us_site/Rates.csv create mode 100644 data/tariffplans/gocs/us_site/RatingPlans.csv create mode 100644 data/tariffplans/gocs/us_site/RatingProfiles.csv create mode 100644 general_tests/gocs_it_test.go diff --git a/data/conf/samples/gocs/au_site/cgrates.json b/data/conf/samples/gocs/au_site/cgrates.json new file mode 100644 index 000000000..d38edd172 --- /dev/null +++ b/data/conf/samples/gocs/au_site/cgrates.json @@ -0,0 +1,93 @@ +{ + + "general": { + "log_level": 7, + "node_id": "AU_SITE", + }, + + "listen": { + "rpc_json": ":3012", + "rpc_gob": ":3013", + "http": ":3080", + }, + + + "rpc_conns": { + "conn1": { + "strategy": "*first", + "conns": [{"address": "127.0.0.1:3012", "transport":"*json"}], + }, + "*internal": { + "strategy": "*first", + "conns": [{"address": "*internal"}], + } + }, + + + "data_db": { + "db_type": "*internal", + "remote_conns": [ + {"address": "127.0.0.1:4012", "transport":"*json"} + ], + "items":{ + "*accounts":{"remote":true}, + "*reverse_destinations": {"remote":true}, + "*destinations": {"remote":true}, + "*rating_plans": {"remote":true}, + "*rating_profiles":{"remote":true}, + "*actions":{"remote":true}, + "*action_plans": {"remote":true}, + "*account_action_plans":{"remote":true}, + "*action_triggers":{"remote":true}, + "*shared_groups":{"remote":true}, + "*timings": {"remote":true}, + "*filters": {"remote":true}, + "*supplier_profiles":{"remote":true}, + "*attribute_profiles":{"remote":true}, + "*charger_profiles": {"remote":true}, + "*dispatcher_profiles":{"remote":true}, + "*dispatcher_hosts":{"remote":true}, + "*filter_indexes" :{"remote":true}, + "*load_ids":{"remote":true} + } + }, + + "stor_db": { + "db_password": "CGRateS.org", + }, + + + "rals": { + "enabled": true, + "max_increments":3000000, + }, + + + "scheduler": { + "enabled": true, + "cdrs_conns": ["*internal"], + }, + + + "cdrs": { + "enabled": true, + "chargers_conns":["*internal"], + }, + + + "chargers": { + "enabled": true, + }, + + "sessions": { + "enabled": true, + "rals_conns": ["*internal"], + "cdrs_conns": ["*internal"], + "chargers_conns": ["*internal"], + }, + + "apier": { + "caches_conns":["conn1"], + "scheduler_conns": ["conn1"], + } +} diff --git a/data/conf/samples/gocs/dsp_site/cgrates.json b/data/conf/samples/gocs/dsp_site/cgrates.json new file mode 100644 index 000000000..1a1e57b54 --- /dev/null +++ b/data/conf/samples/gocs/dsp_site/cgrates.json @@ -0,0 +1,50 @@ +{ + + "general": { + "log_level": 7, + "node_id": "DISPATCH_SITE", + "reconnects": 2, + "reply_timeout": "5s", + }, + + + "listen": { + "rpc_json": ":2012", + "rpc_gob": ":2013", + "http": ":2080" + }, + + "data_db": { + "db_type": "*redis", + "db_port": 6379, + "db_name": "13" + }, + + "cache":{ + "*dispatcher_routes": {"limit": -1, "ttl": "2s"} + }, + + "stor_db": { + "db_password": "CGRateS.org" + }, + + + "rals": { + "enabled": true + }, + + + "scheduler": { + "enabled": true + }, + + "dispatchers":{ + "enabled": true + }, + + "apier": { + "scheduler_conns": ["*internal"] + } + + +} diff --git a/data/conf/samples/gocs/us_site/cgrates.json b/data/conf/samples/gocs/us_site/cgrates.json new file mode 100644 index 000000000..d66d8b058 --- /dev/null +++ b/data/conf/samples/gocs/us_site/cgrates.json @@ -0,0 +1,104 @@ +{ + + "general": { + "log_level": 7, + "node_id": "US_SITE", + }, + + "listen": { + "rpc_json": ":4012", + "rpc_gob": ":4013", + "http": ":4080", + }, + + "rpc_conns": { + "conn1": { + "strategy": "*first", + "conns": [{"address": "127.0.0.1:4012", "transport":"*json"}], + }, + "*internal": { + "strategy": "*first", + "conns": [{"address": "*internal"}], + } + }, + + "data_db": { + "db_type": "*redis", + "db_port": 6379, + "db_name": "11", + "replication_conns": [ + {"address": "127.0.0.1:3012", "transport":"*json"} + ], + "items":{ + "*accounts":{"replicate":true}, + "*reverse_destinations": {"replicate":false}, + "*destinations": {"replicate":false}, + "*rating_plans": {"replicate":false}, + "*rating_profiles":{"replicate":false}, + "*actions":{"replicate":false}, + "*action_plans": {"replicate":false}, + "*account_action_plans":{"replicate":false}, + "*action_triggers":{"replicate":false}, + "*shared_groups":{"replicate":false}, + "*timings": {"replicate":false}, + "*resource_profiles":{"replicate":false}, + "*resources":{"replicate":false}, + "*statqueue_profiles": {"replicate":false}, + "*statqueues": {"replicate":false}, + "*threshold_profiles": {"replicate":false}, + "*thresholds": {"replicate":false}, + "*filters": {"replicate":false}, + "*supplier_profiles":{"replicate":false}, + "*attribute_profiles":{"replicate":false}, + "*charger_profiles": {"replicate":false}, + "*dispatcher_profiles":{"replicate":false}, + "*dispatcher_hosts":{"replicate":false}, + "*filter_indexes" :{"replicate":false}, + "*load_ids":{"replicate":false} + } + }, + + "stor_db": { + "db_password": "CGRateS.org", + }, + + + "rals": { + "enabled": true, + "max_increments":3000000, + }, + + + "scheduler": { + "enabled": true, + "cdrs_conns": ["conn1"], + }, + + + "cdrs": { + "enabled": true, + "chargers_conns":["conn1"], + }, + + + "chargers": { + "enabled": true, + }, + + + "sessions": { + "enabled": true, + "listen_bijson": ":4014", + "rals_conns": ["*internal"], + "cdrs_conns": ["*internal"], + "chargers_conns": ["*internal"], + }, + + + "apier": { + "caches_conns":["conn1"], + "scheduler_conns": ["conn1"], + }, + + +} diff --git a/data/tariffplans/gocs/au_site/Chargers.csv b/data/tariffplans/gocs/au_site/Chargers.csv new file mode 100644 index 000000000..c270b5867 --- /dev/null +++ b/data/tariffplans/gocs/au_site/Chargers.csv @@ -0,0 +1,2 @@ +#Tenant,ID,FilterIDs,ActivationInterval,RunID,AttributeIDs,Weight +cgrates.org,DEFAULT,,,*default,*none,0 \ No newline at end of file diff --git a/data/tariffplans/gocs/au_site/DestinationRates.csv b/data/tariffplans/gocs/au_site/DestinationRates.csv new file mode 100644 index 000000000..ec0002962 --- /dev/null +++ b/data/tariffplans/gocs/au_site/DestinationRates.csv @@ -0,0 +1,4 @@ +#Id,DestinationId,RatesTag,RoundingMethod,RoundingDecimals,MaxCost,MaxCostStrategy +DR_1002_20CNT,DST_1002,RT_20CNT,*up,4,0, +DR_1001_10CNT,DST_1001,RT_10CNT,*up,4,0, + diff --git a/data/tariffplans/gocs/au_site/Destinations.csv b/data/tariffplans/gocs/au_site/Destinations.csv new file mode 100644 index 000000000..27b629107 --- /dev/null +++ b/data/tariffplans/gocs/au_site/Destinations.csv @@ -0,0 +1,3 @@ +#Id,Prefix +DST_1002,1002 +DST_1001,1001 \ No newline at end of file diff --git a/data/tariffplans/gocs/au_site/Rates.csv b/data/tariffplans/gocs/au_site/Rates.csv new file mode 100644 index 000000000..0924201a6 --- /dev/null +++ b/data/tariffplans/gocs/au_site/Rates.csv @@ -0,0 +1,5 @@ +#Id,ConnectFee,Rate,RateUnit,RateIncrement,GroupIntervalStart +RT_10CNT,0.2,0.1,60s,60s,0s +RT_10CNT,0,0.05,60s,1s,60s +RT_20CNT,0.4,0.2,60s,60s,0s +RT_20CNT,0,0.1,60s,1s,60s \ No newline at end of file diff --git a/data/tariffplans/gocs/au_site/RatingPlans.csv b/data/tariffplans/gocs/au_site/RatingPlans.csv new file mode 100644 index 000000000..391fa1234 --- /dev/null +++ b/data/tariffplans/gocs/au_site/RatingPlans.csv @@ -0,0 +1,3 @@ +#Id,DestinationRatesId,TimingTag,Weight +RP_1001,DR_1002_20CNT,*any,10 +RP_1002,DR_1001_10CNT,*any,10 \ No newline at end of file diff --git a/data/tariffplans/gocs/au_site/RatingProfiles.csv b/data/tariffplans/gocs/au_site/RatingProfiles.csv new file mode 100644 index 000000000..267aaa2c8 --- /dev/null +++ b/data/tariffplans/gocs/au_site/RatingProfiles.csv @@ -0,0 +1,3 @@ +#Tenant,Category,Subject,ActivationTime,RatingPlanId,RatesFallbackSubject +cgrates.org,call,1001,2014-01-14T00:00:00Z,RP_1001, +cgrates.org,call,1002,2014-01-14T00:00:00Z,RP_1002, \ No newline at end of file diff --git a/data/tariffplans/gocs/dsp_site/DispatcherHosts.csv b/data/tariffplans/gocs/dsp_site/DispatcherHosts.csv new file mode 100644 index 000000000..d3b8a6be5 --- /dev/null +++ b/data/tariffplans/gocs/dsp_site/DispatcherHosts.csv @@ -0,0 +1,4 @@ +#Tenant[0],ID[1],Address[2],Transport[3],TLS[4] +cgrates.org,AU_SITE,127.0.0.1:3012,*json,false +cgrates.org,US_SITE,127.0.0.1:4012,*json,false +cgrates.org,SELF,*internal,, \ No newline at end of file diff --git a/data/tariffplans/gocs/dsp_site/DispatcherProfiles.csv b/data/tariffplans/gocs/dsp_site/DispatcherProfiles.csv new file mode 100644 index 000000000..da1647dee --- /dev/null +++ b/data/tariffplans/gocs/dsp_site/DispatcherProfiles.csv @@ -0,0 +1,4 @@ +#Tenant,ID,Subsystems,FilterIDs,ActivationInterval,Strategy,StrategyParameters,ConnID,ConnFilterIDs,ConnWeight,ConnBlocker,ConnParameters,Weight +cgrates.org,BROADCAST,*sessions,,,*broadcast,,AU_SITE,,20,false,,30 +cgrates.org,BROADCAST,,,,,,US_SITE,,20,,, +cgrates.org,SELF,*any,,,*weight,,SELF,,20,false,,10 \ No newline at end of file diff --git a/data/tariffplans/gocs/us_site/AccountActions.csv b/data/tariffplans/gocs/us_site/AccountActions.csv new file mode 100644 index 000000000..68e8a5ea1 --- /dev/null +++ b/data/tariffplans/gocs/us_site/AccountActions.csv @@ -0,0 +1,3 @@ +#Tenant,Account,ActionPlanId,ActionTriggersId,AllowNegative,Disabled +cgrates.org,1001,AP_PACKAGE_10,,, +cgrates.org,1002,AP_PACKAGE_10,,, \ No newline at end of file diff --git a/data/tariffplans/gocs/us_site/ActionPlans.csv b/data/tariffplans/gocs/us_site/ActionPlans.csv new file mode 100644 index 000000000..b10e827b5 --- /dev/null +++ b/data/tariffplans/gocs/us_site/ActionPlans.csv @@ -0,0 +1,2 @@ +#Id,ActionsId,TimingId,Weight +AP_PACKAGE_10,ACT_TOPUP_RST_10,*asap,10 \ No newline at end of file diff --git a/data/tariffplans/gocs/us_site/Actions.csv b/data/tariffplans/gocs/us_site/Actions.csv new file mode 100644 index 000000000..256e83424 --- /dev/null +++ b/data/tariffplans/gocs/us_site/Actions.csv @@ -0,0 +1,3 @@ +#ActionsId[0],Action[1],ExtraParameters[2],Filter[3],BalanceId[4],BalanceType[5],Categories[6],DestinationIds[7],RatingSubject[8],SharedGroup[9],ExpiryTime[10],TimingIds[11],Units[12],BalanceWeight[13],BalanceBlocker[14],BalanceDisabled[15],Weight[16] +ACT_TOPUP_RST_10,*topup_reset,,,test,*monetary,,*any,,,*unlimited,,10,10,false,false,10 +ACT_LOG_WARNING,*log,,,,,,,,,,,,,false,false,10 \ No newline at end of file diff --git a/data/tariffplans/gocs/us_site/Chargers.csv b/data/tariffplans/gocs/us_site/Chargers.csv new file mode 100644 index 000000000..c270b5867 --- /dev/null +++ b/data/tariffplans/gocs/us_site/Chargers.csv @@ -0,0 +1,2 @@ +#Tenant,ID,FilterIDs,ActivationInterval,RunID,AttributeIDs,Weight +cgrates.org,DEFAULT,,,*default,*none,0 \ No newline at end of file diff --git a/data/tariffplans/gocs/us_site/DestinationRates.csv b/data/tariffplans/gocs/us_site/DestinationRates.csv new file mode 100644 index 000000000..ec0002962 --- /dev/null +++ b/data/tariffplans/gocs/us_site/DestinationRates.csv @@ -0,0 +1,4 @@ +#Id,DestinationId,RatesTag,RoundingMethod,RoundingDecimals,MaxCost,MaxCostStrategy +DR_1002_20CNT,DST_1002,RT_20CNT,*up,4,0, +DR_1001_10CNT,DST_1001,RT_10CNT,*up,4,0, + diff --git a/data/tariffplans/gocs/us_site/Destinations.csv b/data/tariffplans/gocs/us_site/Destinations.csv new file mode 100644 index 000000000..27b629107 --- /dev/null +++ b/data/tariffplans/gocs/us_site/Destinations.csv @@ -0,0 +1,3 @@ +#Id,Prefix +DST_1002,1002 +DST_1001,1001 \ No newline at end of file diff --git a/data/tariffplans/gocs/us_site/Rates.csv b/data/tariffplans/gocs/us_site/Rates.csv new file mode 100644 index 000000000..0924201a6 --- /dev/null +++ b/data/tariffplans/gocs/us_site/Rates.csv @@ -0,0 +1,5 @@ +#Id,ConnectFee,Rate,RateUnit,RateIncrement,GroupIntervalStart +RT_10CNT,0.2,0.1,60s,60s,0s +RT_10CNT,0,0.05,60s,1s,60s +RT_20CNT,0.4,0.2,60s,60s,0s +RT_20CNT,0,0.1,60s,1s,60s \ No newline at end of file diff --git a/data/tariffplans/gocs/us_site/RatingPlans.csv b/data/tariffplans/gocs/us_site/RatingPlans.csv new file mode 100644 index 000000000..391fa1234 --- /dev/null +++ b/data/tariffplans/gocs/us_site/RatingPlans.csv @@ -0,0 +1,3 @@ +#Id,DestinationRatesId,TimingTag,Weight +RP_1001,DR_1002_20CNT,*any,10 +RP_1002,DR_1001_10CNT,*any,10 \ No newline at end of file diff --git a/data/tariffplans/gocs/us_site/RatingProfiles.csv b/data/tariffplans/gocs/us_site/RatingProfiles.csv new file mode 100644 index 000000000..267aaa2c8 --- /dev/null +++ b/data/tariffplans/gocs/us_site/RatingProfiles.csv @@ -0,0 +1,3 @@ +#Tenant,Category,Subject,ActivationTime,RatingPlanId,RatesFallbackSubject +cgrates.org,call,1001,2014-01-14T00:00:00Z,RP_1001, +cgrates.org,call,1002,2014-01-14T00:00:00Z,RP_1002, \ No newline at end of file diff --git a/general_tests/gocs_it_test.go b/general_tests/gocs_it_test.go new file mode 100644 index 000000000..03444b648 --- /dev/null +++ b/general_tests/gocs_it_test.go @@ -0,0 +1,497 @@ +// +build integration + +/* +Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package general_tests + +import ( + "net/rpc" + "os/exec" + "path" + "testing" + "time" + + "github.com/cgrates/cgrates/sessions" + + "github.com/cgrates/cgrates/utils" + + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" +) + +var ( + auCfgPath, usCfgPath, dspCfgPath string + auCfg, usCfg, dspCfg *config.CGRConfig + auRPC, usRPC, dspRPC *rpc.Client + auEngine, usEngine, dspEngine *exec.Cmd + sTestsGOCS = []func(t *testing.T){ + testGOCSInitCfg, + testGOCSResetDB, + testGOCSStartEngine, + testGOCSApierRpcConn, + testGOCSLoadData, + testGOCSAuthSession, + testGOCSInitSession, + testGOCSKillUSEngine, + testGOCSUpdateSession, + testGOCSStartUSEngine, + testGOCSUpdateSession2, + testGOCSTerminateSession, + testGOCSProcessCDR, + testGOCSStopCgrEngine, + } +) + +// Test start here +func TestGOCSIT(t *testing.T) { + for _, stest := range sTestsGOCS { + t.Run("TestGOCSIT", stest) + } +} + +//Init Config +func testGOCSInitCfg(t *testing.T) { + auCfgPath = path.Join(*dataDir, "conf", "samples", "gocs", "au_site") + if auCfg, err = config.NewCGRConfigFromPath(auCfgPath); err != nil { + t.Fatal(err) + } + auCfg.DataFolderPath = *dataDir + config.SetCgrConfig(auCfg) + usCfgPath = path.Join(*dataDir, "conf", "samples", "gocs", "us_site") + if usCfg, err = config.NewCGRConfigFromPath(usCfgPath); err != nil { + t.Fatal(err) + } + dspCfgPath = path.Join(*dataDir, "conf", "samples", "gocs", "dsp_site") + if dspCfg, err = config.NewCGRConfigFromPath(dspCfgPath); err != nil { + t.Fatal(err) + } +} + +// Remove data in both rating and accounting db +func testGOCSResetDB(t *testing.T) { + if err := engine.InitDataDb(auCfg); err != nil { + t.Fatal(err) + } + if err := engine.InitDataDb(usCfg); err != nil { + t.Fatal(err) + } + if err := engine.InitDataDb(dspCfg); err != nil { + t.Fatal(err) + } +} + +// Start CGR Engine +func testGOCSStartEngine(t *testing.T) { + if usEngine, err = engine.StopStartEngine(usCfgPath, *waitRater); err != nil { + t.Fatal(err) + } + if auEngine, err = engine.StartEngine(auCfgPath, *waitRater); err != nil { + t.Fatal(err) + } + if dspEngine, err = engine.StartEngine(dspCfgPath, *waitRater); err != nil { + t.Fatal(err) + } + time.Sleep(10 * time.Millisecond) + +} + +// Connect rpc client to rater +func testGOCSApierRpcConn(t *testing.T) { + if auRPC, err = newRPCClient(auCfg.ListenCfg()); err != nil { + t.Fatal(err) + } + if usRPC, err = newRPCClient(usCfg.ListenCfg()); err != nil { + t.Fatal(err) + } + if dspRPC, err = newRPCClient(dspCfg.ListenCfg()); err != nil { + t.Fatal(err) + } +} + +func testGOCSLoadData(t *testing.T) { + attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "gocs", "us_site")} + var loadInst utils.LoadInstance + if err := usRPC.Call(utils.ApierV2LoadTariffPlanFromFolder, attrs, &loadInst); err != nil { + t.Error(err) + } + attrs = &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "gocs", "au_site")} + if err := auRPC.Call(utils.ApierV2LoadTariffPlanFromFolder, attrs, &loadInst); err != nil { + t.Error(err) + } + time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups on au_site + attrs = &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "gocs", "dsp_site")} + wchan := make(chan struct{}, 1) + go func() { + loaderPath, err := exec.LookPath("cgr-loader") + if err != nil { + t.Error(err) + } + loader := exec.Command(loaderPath, "-config_path", dspCfgPath, "-path", attrs.FolderPath) + + if err := loader.Start(); err != nil { + t.Error(err) + } + loader.Wait() + wchan <- struct{}{} + }() + select { + case <-wchan: + case <-time.After(1 * time.Second): + t.Errorf("cgr-loader failed: ") + } +} + +func testGOCSAuthSession(t *testing.T) { + authUsage := 5 * time.Minute + args := &sessions.V1AuthorizeArgs{ + GetMaxUsage: true, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSSv1ItAuth", + Event: map[string]interface{}{ + utils.Tenant: "cgrates.org", + utils.ToR: utils.VOICE, + utils.OriginID: "TestSSv1It1", + utils.Category: "call", + utils.RequestType: utils.META_PREPAID, + utils.Account: "1001", + utils.Subject: "1001", + utils.Destination: "1002", + utils.SetupTime: time.Date(2018, time.January, 7, 16, 60, 0, 0, time.UTC), + utils.Usage: authUsage, + }, + }, + } + var rply sessions.V1AuthorizeReply + if err := dspRPC.Call(utils.SessionSv1AuthorizeEvent, args, &rply); err != nil { + t.Fatal(err) + } + if rply.MaxUsage != authUsage { + t.Errorf("Unexpected MaxUsage: %v", rply.MaxUsage) + } +} + +func testGOCSInitSession(t *testing.T) { + initUsage := 5 * time.Minute + args := &sessions.V1InitSessionArgs{ + InitSession: true, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSSv1ItInitiateSession", + Event: map[string]interface{}{ + utils.Tenant: "cgrates.org", + utils.ToR: utils.VOICE, + utils.OriginID: "TestSSv1It1", + utils.Category: "call", + utils.RequestType: utils.META_PREPAID, + utils.Account: "1001", + utils.Subject: "1001", + 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.V1InitSessionReply + if err := dspRPC.Call(utils.SessionSv1InitiateSession, + args, &rply); err != nil { + t.Fatal(err) + } + if rply.MaxUsage != initUsage { + t.Errorf("Unexpected MaxUsage: %v", rply.MaxUsage) + } + // give a bit of time to session to be replicate + time.Sleep(10 * time.Millisecond) + + aSessions := make([]*sessions.ExternalSession, 0) + if err := auRPC.Call(utils.SessionSv1GetActiveSessions, new(utils.SessionFilter), &aSessions); err != nil { + t.Error(err) + } else if len(aSessions) != 1 { + t.Errorf("wrong active sessions: %s \n , and len(aSessions) %+v", utils.ToJSON(aSessions), len(aSessions)) + } else if aSessions[0].NodeID != "AU_SITE" { + t.Errorf("Expecting : %+v, received: %+v", "AU_SITE", aSessions[0].NodeID) + } else if aSessions[0].MaxCostSoFar != 1.0008 { + t.Errorf("Expecting : %+v, received: %+v", 1.0008, aSessions[0].MaxCostSoFar) + } else if aSessions[0].Usage != time.Duration(5*time.Minute) { + t.Errorf("Expecting : %+v, received: %+v", time.Duration(5*time.Minute), aSessions[0].MaxCostSoFar) + } + + aSessions = make([]*sessions.ExternalSession, 0) + if err := usRPC.Call(utils.SessionSv1GetActiveSessions, new(utils.SessionFilter), &aSessions); err != nil { + t.Error(err) + } else if len(aSessions) != 1 { + t.Errorf("wrong active sessions: %s \n , and len(aSessions) %+v", utils.ToJSON(aSessions), len(aSessions)) + } else if aSessions[0].NodeID != "US_SITE" { + t.Errorf("Expecting : %+v, received: %+v", "US_SITE", aSessions[0].NodeID) + } else if aSessions[0].MaxCostSoFar != 1.0008 { + t.Errorf("Expecting : %+v, received: %+v", 1.0008, aSessions[0].MaxCostSoFar) + } else if aSessions[0].Usage != time.Duration(5*time.Minute) { + t.Errorf("Expecting : %+v, received: %+v", time.Duration(5*time.Minute), aSessions[0].Usage) + } + + var acnt *engine.Account + attrAcc := &utils.AttrGetAccount{ + Tenant: "cgrates.org", + Account: "1001", + } + + // 10 - 1.0008 = 8.9992 + if err := auRPC.Call(utils.ApierV2GetAccount, attrAcc, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MONETARY].GetTotalValue() != 8.9992 { + t.Errorf("Expecting : %+v, received: %+v", 8.9992, acnt.BalanceMap[utils.MONETARY].GetTotalValue()) + } + + if err := usRPC.Call(utils.ApierV2GetAccount, attrAcc, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MONETARY].GetTotalValue() != 8.9992 { + t.Errorf("Expecting : %+v, received: %+v", 8.9992, acnt.BalanceMap[utils.MONETARY].GetTotalValue()) + } + +} + +func testGOCSKillUSEngine(t *testing.T) { + if err := usEngine.Process.Kill(); err != nil { + t.Error(err) + } + time.Sleep(10 * time.Millisecond) +} + +func testGOCSUpdateSession(t *testing.T) { + reqUsage := 5 * time.Minute + args := &sessions.V1UpdateSessionArgs{ + UpdateSession: true, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSSv1ItUpdateSession", + Event: map[string]interface{}{ + utils.Tenant: "cgrates.org", + utils.ToR: utils.VOICE, + utils.OriginID: "TestSSv1It1", + utils.Category: "call", + utils.RequestType: utils.META_PREPAID, + utils.Account: "1001", + utils.Subject: "1001", + 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: reqUsage, + }, + }, + } + var rply sessions.V1UpdateSessionReply + + // right now dispatcher receive utils.ErrPartiallyExecuted + // in case of of engines fails + if err := dspRPC.Call(utils.SessionSv1UpdateSession, args, &rply); err == nil || err.Error() != utils.ErrPartiallyExecuted.Error() { + t.Errorf("Expecting : %+v, received: %+v", utils.ErrPartiallyExecuted, err) + } + + aSessions := make([]*sessions.ExternalSession, 0) + if err := auRPC.Call(utils.SessionSv1GetActiveSessions, nil, &aSessions); err != nil { + t.Error(err) + } else if len(aSessions) != 1 { + t.Errorf("wrong active sessions: %s", utils.ToJSON(aSessions)) + } else if aSessions[0].NodeID != "AU_SITE" { + t.Errorf("Expecting : %+v, received: %+v", "AU_SITE", aSessions[0].NodeID) + } else if aSessions[0].MaxCostSoFar != 1.5017999999999998 { + t.Errorf("Expecting : %+v, received: %+v", 1.5017999999999998, aSessions[0].MaxCostSoFar) + } else if aSessions[0].Usage != time.Duration(10*time.Minute) { + t.Errorf("Expecting : %+v, received: %+v", time.Duration(5*time.Minute), aSessions[0].Usage) + } + + var acnt *engine.Account + attrAcc := &utils.AttrGetAccount{ + Tenant: "cgrates.org", + Account: "1001", + } + + // balanced changed in AU_SITE + if err := auRPC.Call(utils.ApierV2GetAccount, attrAcc, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MONETARY].GetTotalValue() != 8.4982 { + t.Errorf("Expecting : %+v, received: %+v", 8.4982, acnt.BalanceMap[utils.MONETARY].GetTotalValue()) + } + +} + +func testGOCSStartUSEngine(t *testing.T) { + if usEngine, err = engine.StartEngine(usCfgPath, *waitRater); err != nil { + t.Fatal(err) + } + if usRPC, err = newRPCClient(usCfg.ListenCfg()); err != nil { + t.Fatal(err) + } +} + +func testGOCSUpdateSession2(t *testing.T) { + reqUsage := 5 * time.Minute + args := &sessions.V1UpdateSessionArgs{ + UpdateSession: true, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSSv1ItUpdateSession2", + Event: map[string]interface{}{ + utils.Tenant: "cgrates.org", + utils.ToR: utils.VOICE, + utils.OriginID: "TestSSv1It1", + utils.Category: "call", + utils.RequestType: utils.META_PREPAID, + utils.Account: "1001", + utils.Subject: "1001", + 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: reqUsage, + }, + }, + } + var rply sessions.V1UpdateSessionReply + + if err := dspRPC.Call(utils.SessionSv1UpdateSession, args, &rply); err != nil { + t.Errorf("Expecting : %+v, received: %+v", nil, err) + } else if rply.MaxUsage != reqUsage { + t.Errorf("Unexpected MaxUsage: %v", rply.MaxUsage) + } + + aSessions := make([]*sessions.ExternalSession, 0) + if err := auRPC.Call(utils.SessionSv1GetActiveSessions, nil, &aSessions); err != nil { + t.Error(err) + } else if len(aSessions) != 1 { + t.Errorf("wrong active sessions: %s", utils.ToJSON(aSessions)) + } else if aSessions[0].NodeID != "AU_SITE" { + t.Errorf("Expecting : %+v, received: %+v", "AU_SITE", aSessions[0].NodeID) + } else if aSessions[0].MaxCostSoFar != 2.0027999999999997 { + t.Errorf("Expecting : %+v, received: %+v", 2.0027999999999997, aSessions[0].MaxCostSoFar) + } else if aSessions[0].Usage != time.Duration(15*time.Minute) { + t.Errorf("Expecting : %+v, received: %+v", time.Duration(15*time.Minute), aSessions[0].Usage) + } + + aSessions = make([]*sessions.ExternalSession, 0) + if err := usRPC.Call(utils.SessionSv1GetActiveSessions, new(utils.SessionFilter), &aSessions); err != nil { + t.Error(err) + } else if len(aSessions) != 1 { + t.Errorf("wrong active sessions: %s \n , and len(aSessions) %+v", utils.ToJSON(aSessions), len(aSessions)) + } else if aSessions[0].NodeID != "US_SITE" { + t.Errorf("Expecting : %+v, received: %+v", "US_SITE", aSessions[0].NodeID) + } else if aSessions[0].MaxCostSoFar != 1.0008 { + t.Errorf("Expecting : %+v, received: %+v", 1.0008, aSessions[0].MaxCostSoFar) + } else if aSessions[0].Usage != time.Duration(5*time.Minute) { + t.Errorf("Expecting : %+v, received: %+v", time.Duration(5*time.Minute), aSessions[0].Usage) + } + + var acnt *engine.Account + attrAcc := &utils.AttrGetAccount{ + Tenant: "cgrates.org", + Account: "1001", + } + + // because the session don't exist on US_SITE + // this update behaves as an init + // 8.9992 - 1.0008 = 7.9984 + if err := auRPC.Call(utils.ApierV2GetAccount, attrAcc, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MONETARY].GetTotalValue() != 7.9984 { + t.Errorf("Expecting : %+v, received: %+v", 7.9984, acnt.BalanceMap[utils.MONETARY].GetTotalValue()) + } + + if err := usRPC.Call(utils.ApierV2GetAccount, attrAcc, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MONETARY].GetTotalValue() != 7.9984 { + t.Errorf("Expecting : %+v, received: %+v", 7.9984, acnt.BalanceMap[utils.MONETARY].GetTotalValue()) + } +} + +func testGOCSTerminateSession(t *testing.T) { + args := &sessions.V1TerminateSessionArgs{ + TerminateSession: true, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "testGOCSTerminateSession", + Event: map[string]interface{}{ + utils.Tenant: "cgrates.org", + utils.ToR: utils.VOICE, + utils.OriginID: "TestSSv1It1", + utils.Category: "call", + utils.RequestType: utils.META_PREPAID, + utils.Account: "1001", + utils.Subject: "1001", + 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: 15 * time.Minute, + }, + }, + } + var rply string + if err := dspRPC.Call(utils.SessionSv1TerminateSession, + args, &rply); err != nil { + t.Error(err) + } + if rply != utils.OK { + t.Errorf("Unexpected reply: %s", rply) + } + aSessions := make([]*sessions.ExternalSession, 0) + if err := auRPC.Call(utils.SessionSv1GetActiveSessions, nil, &aSessions); err == nil || + err.Error() != utils.ErrNotFound.Error() { + t.Errorf("Expected error %s received error %v and reply %s", utils.ErrNotFound, err, utils.ToJSON(aSessions)) + } + if err := usRPC.Call(utils.SessionSv1GetActiveSessions, nil, &aSessions); err == nil || + err.Error() != utils.ErrNotFound.Error() { + t.Errorf("Expected error %s received error %v and reply %s", utils.ErrNotFound, err, utils.ToJSON(aSessions)) + } +} + +func testGOCSProcessCDR(t *testing.T) { + args := &utils.CGREventWithArgDispatcher{ + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSSv1ItProcessCDR", + Event: map[string]interface{}{ + utils.Tenant: "cgrates.org", + utils.ToR: utils.VOICE, + utils.OriginID: "TestSSv1It1", + utils.Category: "call", + utils.RequestType: utils.META_PREPAID, + utils.Account: "1001", + utils.Subject: "1001", + 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: 10 * time.Minute, + }, + }, + } + var rply string + if err := usRPC.Call(utils.SessionSv1ProcessCDR, + args, &rply); err != nil { + t.Error(err) + } + if rply != utils.OK { + t.Errorf("Unexpected reply: %s", rply) + } + time.Sleep(100 * time.Millisecond) +} + +func testGOCSStopCgrEngine(t *testing.T) { + if err := engine.KillEngine(100); err != nil { + t.Error(err) + } +} diff --git a/services/datadb.go b/services/datadb.go index c9492405f..80180774a 100644 --- a/services/datadb.go +++ b/services/datadb.go @@ -76,7 +76,7 @@ func (db *DataDBService) Start() (err error) { db.cfg.TlsCfg().ClientCerificate, db.cfg.TlsCfg().CaCertificate, db.cfg.GeneralCfg().ConnectAttempts, db.cfg.GeneralCfg().Reconnects, db.cfg.GeneralCfg().ConnectTimeout, db.cfg.GeneralCfg().ReplyTimeout, - db.cfg.DataDbCfg().RmtConns, nil, false) + db.cfg.DataDbCfg().RmtConns, nil, true) if err != nil { log.Fatalf("Coud not confignure dataDB remote connections: %s", err.Error()) } @@ -87,7 +87,7 @@ func (db *DataDBService) Start() (err error) { db.cfg.TlsCfg().ClientCerificate, db.cfg.TlsCfg().CaCertificate, db.cfg.GeneralCfg().ConnectAttempts, db.cfg.GeneralCfg().Reconnects, db.cfg.GeneralCfg().ConnectTimeout, db.cfg.GeneralCfg().ReplyTimeout, - db.cfg.DataDbCfg().RplConns, nil, false) + db.cfg.DataDbCfg().RplConns, nil, true) if err != nil { log.Fatalf("Coud not confignure dataDB replication connections: %s", err.Error()) } From 183c2d5a00fdc5946622b69bf9557c7f8a953bab Mon Sep 17 00:00:00 2001 From: TeoV Date: Tue, 17 Dec 2019 03:46:45 -0500 Subject: [PATCH 2/3] Update GOCS tests with voice balance for account --- data/conf/samples/gocs/au_site/cgrates.json | 8 - data/conf/samples/gocs/us_site/cgrates.json | 1 + .../gocs/us_site/AccountActions.csv | 3 - data/tariffplans/gocs/us_site/ActionPlans.csv | 2 - data/tariffplans/gocs/us_site/Actions.csv | 3 - general_tests/gocs_it_test.go | 151 ++++++++++++++---- 6 files changed, 120 insertions(+), 48 deletions(-) delete mode 100644 data/tariffplans/gocs/us_site/AccountActions.csv delete mode 100644 data/tariffplans/gocs/us_site/ActionPlans.csv delete mode 100644 data/tariffplans/gocs/us_site/Actions.csv diff --git a/data/conf/samples/gocs/au_site/cgrates.json b/data/conf/samples/gocs/au_site/cgrates.json index d38edd172..9afd5bcc5 100644 --- a/data/conf/samples/gocs/au_site/cgrates.json +++ b/data/conf/samples/gocs/au_site/cgrates.json @@ -65,13 +65,6 @@ "scheduler": { "enabled": true, - "cdrs_conns": ["*internal"], - }, - - - "cdrs": { - "enabled": true, - "chargers_conns":["*internal"], }, @@ -82,7 +75,6 @@ "sessions": { "enabled": true, "rals_conns": ["*internal"], - "cdrs_conns": ["*internal"], "chargers_conns": ["*internal"], }, diff --git a/data/conf/samples/gocs/us_site/cgrates.json b/data/conf/samples/gocs/us_site/cgrates.json index d66d8b058..6d8fa20b2 100644 --- a/data/conf/samples/gocs/us_site/cgrates.json +++ b/data/conf/samples/gocs/us_site/cgrates.json @@ -78,6 +78,7 @@ "cdrs": { "enabled": true, "chargers_conns":["conn1"], + "rals_conns": ["*internal"], }, diff --git a/data/tariffplans/gocs/us_site/AccountActions.csv b/data/tariffplans/gocs/us_site/AccountActions.csv deleted file mode 100644 index 68e8a5ea1..000000000 --- a/data/tariffplans/gocs/us_site/AccountActions.csv +++ /dev/null @@ -1,3 +0,0 @@ -#Tenant,Account,ActionPlanId,ActionTriggersId,AllowNegative,Disabled -cgrates.org,1001,AP_PACKAGE_10,,, -cgrates.org,1002,AP_PACKAGE_10,,, \ No newline at end of file diff --git a/data/tariffplans/gocs/us_site/ActionPlans.csv b/data/tariffplans/gocs/us_site/ActionPlans.csv deleted file mode 100644 index b10e827b5..000000000 --- a/data/tariffplans/gocs/us_site/ActionPlans.csv +++ /dev/null @@ -1,2 +0,0 @@ -#Id,ActionsId,TimingId,Weight -AP_PACKAGE_10,ACT_TOPUP_RST_10,*asap,10 \ No newline at end of file diff --git a/data/tariffplans/gocs/us_site/Actions.csv b/data/tariffplans/gocs/us_site/Actions.csv deleted file mode 100644 index 256e83424..000000000 --- a/data/tariffplans/gocs/us_site/Actions.csv +++ /dev/null @@ -1,3 +0,0 @@ -#ActionsId[0],Action[1],ExtraParameters[2],Filter[3],BalanceId[4],BalanceType[5],Categories[6],DestinationIds[7],RatingSubject[8],SharedGroup[9],ExpiryTime[10],TimingIds[11],Units[12],BalanceWeight[13],BalanceBlocker[14],BalanceDisabled[15],Weight[16] -ACT_TOPUP_RST_10,*topup_reset,,,test,*monetary,,*any,,,*unlimited,,10,10,false,false,10 -ACT_LOG_WARNING,*log,,,,,,,,,,,,,false,false,10 \ No newline at end of file diff --git a/general_tests/gocs_it_test.go b/general_tests/gocs_it_test.go index 03444b648..83f78c604 100644 --- a/general_tests/gocs_it_test.go +++ b/general_tests/gocs_it_test.go @@ -51,6 +51,7 @@ var ( testGOCSKillUSEngine, testGOCSUpdateSession, testGOCSStartUSEngine, + testGOCSVerifyAccountsAfterStart, testGOCSUpdateSession2, testGOCSTerminateSession, testGOCSProcessCDR, @@ -94,6 +95,17 @@ func testGOCSResetDB(t *testing.T) { if err := engine.InitDataDb(dspCfg); err != nil { t.Fatal(err) } + if err := engine.InitStorDb(auCfg); err != nil { + t.Fatal(err) + } + if err := engine.InitStorDb(usCfg); err != nil { + t.Fatal(err) + } + if err := engine.InitStorDb(dspCfg); err != nil { + t.Fatal(err) + } + // give some time to flush DataDB and StorDB for all 3 engines + time.Sleep(100 * time.Millisecond) } // Start CGR Engine @@ -155,6 +167,33 @@ func testGOCSLoadData(t *testing.T) { case <-time.After(1 * time.Second): t.Errorf("cgr-loader failed: ") } + var acnt *engine.Account + acntAttrs := &utils.AttrGetAccount{ + Tenant: "cgrates.org", + Account: "1001"} + attrSetBalance := utils.AttrSetBalance{ + Tenant: acntAttrs.Tenant, + Account: acntAttrs.Account, + BalanceType: utils.VOICE, + Balance: map[string]interface{}{ + utils.ID: "BALANCE1", + utils.Value: 3540000000000, + utils.Weight: 20, + }, + } + // add a voice balance of 59 minutes + var reply string + if err := usRPC.Call(utils.ApierV1SetBalance, attrSetBalance, &reply); err != nil { + t.Error(err) + } else if reply != utils.OK { + t.Errorf("received: %s", reply) + } + expectedVoice := 3540000000000.0 + if err := usRPC.Call(utils.ApierV2GetAccount, acntAttrs, &acnt); err != nil { + t.Error(err) + } else if rply := acnt.BalanceMap[utils.VOICE].GetTotalValue(); rply != expectedVoice { + t.Errorf("Expecting: %v, received: %v", expectedVoice, rply) + } } func testGOCSAuthSession(t *testing.T) { @@ -167,7 +206,7 @@ func testGOCSAuthSession(t *testing.T) { Event: map[string]interface{}{ utils.Tenant: "cgrates.org", utils.ToR: utils.VOICE, - utils.OriginID: "TestSSv1It1", + utils.OriginID: "testGOCS", utils.Category: "call", utils.RequestType: utils.META_PREPAID, utils.Account: "1001", @@ -197,7 +236,7 @@ func testGOCSInitSession(t *testing.T) { Event: map[string]interface{}{ utils.Tenant: "cgrates.org", utils.ToR: utils.VOICE, - utils.OriginID: "TestSSv1It1", + utils.OriginID: "testGOCS", utils.Category: "call", utils.RequestType: utils.META_PREPAID, utils.Account: "1001", @@ -227,8 +266,6 @@ func testGOCSInitSession(t *testing.T) { t.Errorf("wrong active sessions: %s \n , and len(aSessions) %+v", utils.ToJSON(aSessions), len(aSessions)) } else if aSessions[0].NodeID != "AU_SITE" { t.Errorf("Expecting : %+v, received: %+v", "AU_SITE", aSessions[0].NodeID) - } else if aSessions[0].MaxCostSoFar != 1.0008 { - t.Errorf("Expecting : %+v, received: %+v", 1.0008, aSessions[0].MaxCostSoFar) } else if aSessions[0].Usage != time.Duration(5*time.Minute) { t.Errorf("Expecting : %+v, received: %+v", time.Duration(5*time.Minute), aSessions[0].MaxCostSoFar) } @@ -240,8 +277,6 @@ func testGOCSInitSession(t *testing.T) { t.Errorf("wrong active sessions: %s \n , and len(aSessions) %+v", utils.ToJSON(aSessions), len(aSessions)) } else if aSessions[0].NodeID != "US_SITE" { t.Errorf("Expecting : %+v, received: %+v", "US_SITE", aSessions[0].NodeID) - } else if aSessions[0].MaxCostSoFar != 1.0008 { - t.Errorf("Expecting : %+v, received: %+v", 1.0008, aSessions[0].MaxCostSoFar) } else if aSessions[0].Usage != time.Duration(5*time.Minute) { t.Errorf("Expecting : %+v, received: %+v", time.Duration(5*time.Minute), aSessions[0].Usage) } @@ -252,17 +287,17 @@ func testGOCSInitSession(t *testing.T) { Account: "1001", } - // 10 - 1.0008 = 8.9992 + // 59 mins - 5 mins = 54 mins if err := auRPC.Call(utils.ApierV2GetAccount, attrAcc, &acnt); err != nil { t.Error(err) - } else if acnt.BalanceMap[utils.MONETARY].GetTotalValue() != 8.9992 { - t.Errorf("Expecting : %+v, received: %+v", 8.9992, acnt.BalanceMap[utils.MONETARY].GetTotalValue()) + } else if acnt.BalanceMap[utils.VOICE].GetTotalValue() != 3240000000000.0 { + t.Errorf("Expecting : %+v, received: %+v", 3240000000000.0, acnt.BalanceMap[utils.VOICE].GetTotalValue()) } if err := usRPC.Call(utils.ApierV2GetAccount, attrAcc, &acnt); err != nil { t.Error(err) - } else if acnt.BalanceMap[utils.MONETARY].GetTotalValue() != 8.9992 { - t.Errorf("Expecting : %+v, received: %+v", 8.9992, acnt.BalanceMap[utils.MONETARY].GetTotalValue()) + } else if acnt.BalanceMap[utils.VOICE].GetTotalValue() != 3240000000000.0 { + t.Errorf("Expecting : %+v, received: %+v", 3240000000000.0, acnt.BalanceMap[utils.VOICE].GetTotalValue()) } } @@ -284,7 +319,7 @@ func testGOCSUpdateSession(t *testing.T) { Event: map[string]interface{}{ utils.Tenant: "cgrates.org", utils.ToR: utils.VOICE, - utils.OriginID: "TestSSv1It1", + utils.OriginID: "testGOCS", utils.Category: "call", utils.RequestType: utils.META_PREPAID, utils.Account: "1001", @@ -311,8 +346,6 @@ func testGOCSUpdateSession(t *testing.T) { t.Errorf("wrong active sessions: %s", utils.ToJSON(aSessions)) } else if aSessions[0].NodeID != "AU_SITE" { t.Errorf("Expecting : %+v, received: %+v", "AU_SITE", aSessions[0].NodeID) - } else if aSessions[0].MaxCostSoFar != 1.5017999999999998 { - t.Errorf("Expecting : %+v, received: %+v", 1.5017999999999998, aSessions[0].MaxCostSoFar) } else if aSessions[0].Usage != time.Duration(10*time.Minute) { t.Errorf("Expecting : %+v, received: %+v", time.Duration(5*time.Minute), aSessions[0].Usage) } @@ -324,10 +357,11 @@ func testGOCSUpdateSession(t *testing.T) { } // balanced changed in AU_SITE + // 54 min - 5 mins = 49 min if err := auRPC.Call(utils.ApierV2GetAccount, attrAcc, &acnt); err != nil { t.Error(err) - } else if acnt.BalanceMap[utils.MONETARY].GetTotalValue() != 8.4982 { - t.Errorf("Expecting : %+v, received: %+v", 8.4982, acnt.BalanceMap[utils.MONETARY].GetTotalValue()) + } else if acnt.BalanceMap[utils.VOICE].GetTotalValue() != 2940000000000.0 { + t.Errorf("Expecting : %+v, received: %+v", 2940000000000.0, acnt.BalanceMap[utils.VOICE].GetTotalValue()) } } @@ -341,6 +375,26 @@ func testGOCSStartUSEngine(t *testing.T) { } } +func testGOCSVerifyAccountsAfterStart(t *testing.T) { + var acnt *engine.Account + attrAcc := &utils.AttrGetAccount{ + Tenant: "cgrates.org", + Account: "1001", + } + // because US_SITE was down we should notice a difference between balance from accounts from US_SITE and AU_SITE + if err := auRPC.Call(utils.ApierV2GetAccount, attrAcc, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.VOICE].GetTotalValue() != 2940000000000.0 { + t.Errorf("Expecting : %+v, received: %+v", 2940000000000.0, acnt.BalanceMap[utils.VOICE].GetTotalValue()) + } + + if err := usRPC.Call(utils.ApierV2GetAccount, attrAcc, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.VOICE].GetTotalValue() != 3240000000000.0 { + t.Errorf("Expecting : %+v, received: %+v", 3240000000000.0, acnt.BalanceMap[utils.VOICE].GetTotalValue()) + } +} + func testGOCSUpdateSession2(t *testing.T) { reqUsage := 5 * time.Minute args := &sessions.V1UpdateSessionArgs{ @@ -351,7 +405,7 @@ func testGOCSUpdateSession2(t *testing.T) { Event: map[string]interface{}{ utils.Tenant: "cgrates.org", utils.ToR: utils.VOICE, - utils.OriginID: "TestSSv1It1", + utils.OriginID: "testGOCS", utils.Category: "call", utils.RequestType: utils.META_PREPAID, utils.Account: "1001", @@ -364,7 +418,8 @@ func testGOCSUpdateSession2(t *testing.T) { }, } var rply sessions.V1UpdateSessionReply - + // Update the session on both US_SITE and AU_SITE + // With this update the account should be replicate from US_SITE to AU_SITE and forgot about the update than happens on AU_SITE if err := dspRPC.Call(utils.SessionSv1UpdateSession, args, &rply); err != nil { t.Errorf("Expecting : %+v, received: %+v", nil, err) } else if rply.MaxUsage != reqUsage { @@ -378,8 +433,6 @@ func testGOCSUpdateSession2(t *testing.T) { t.Errorf("wrong active sessions: %s", utils.ToJSON(aSessions)) } else if aSessions[0].NodeID != "AU_SITE" { t.Errorf("Expecting : %+v, received: %+v", "AU_SITE", aSessions[0].NodeID) - } else if aSessions[0].MaxCostSoFar != 2.0027999999999997 { - t.Errorf("Expecting : %+v, received: %+v", 2.0027999999999997, aSessions[0].MaxCostSoFar) } else if aSessions[0].Usage != time.Duration(15*time.Minute) { t.Errorf("Expecting : %+v, received: %+v", time.Duration(15*time.Minute), aSessions[0].Usage) } @@ -391,8 +444,6 @@ func testGOCSUpdateSession2(t *testing.T) { t.Errorf("wrong active sessions: %s \n , and len(aSessions) %+v", utils.ToJSON(aSessions), len(aSessions)) } else if aSessions[0].NodeID != "US_SITE" { t.Errorf("Expecting : %+v, received: %+v", "US_SITE", aSessions[0].NodeID) - } else if aSessions[0].MaxCostSoFar != 1.0008 { - t.Errorf("Expecting : %+v, received: %+v", 1.0008, aSessions[0].MaxCostSoFar) } else if aSessions[0].Usage != time.Duration(5*time.Minute) { t.Errorf("Expecting : %+v, received: %+v", time.Duration(5*time.Minute), aSessions[0].Usage) } @@ -403,19 +454,16 @@ func testGOCSUpdateSession2(t *testing.T) { Account: "1001", } - // because the session don't exist on US_SITE - // this update behaves as an init - // 8.9992 - 1.0008 = 7.9984 if err := auRPC.Call(utils.ApierV2GetAccount, attrAcc, &acnt); err != nil { t.Error(err) - } else if acnt.BalanceMap[utils.MONETARY].GetTotalValue() != 7.9984 { - t.Errorf("Expecting : %+v, received: %+v", 7.9984, acnt.BalanceMap[utils.MONETARY].GetTotalValue()) + } else if acnt.BalanceMap[utils.VOICE].GetTotalValue() != 2940000000000.0 { + t.Errorf("Expecting : %+v, received: %+v", 2940000000000.0, acnt.BalanceMap[utils.VOICE].GetTotalValue()) } if err := usRPC.Call(utils.ApierV2GetAccount, attrAcc, &acnt); err != nil { t.Error(err) - } else if acnt.BalanceMap[utils.MONETARY].GetTotalValue() != 7.9984 { - t.Errorf("Expecting : %+v, received: %+v", 7.9984, acnt.BalanceMap[utils.MONETARY].GetTotalValue()) + } else if acnt.BalanceMap[utils.VOICE].GetTotalValue() != 2940000000000.0 { + t.Errorf("Expecting : %+v, received: %+v", 2940000000000.0, acnt.BalanceMap[utils.VOICE].GetTotalValue()) } } @@ -428,7 +476,7 @@ func testGOCSTerminateSession(t *testing.T) { Event: map[string]interface{}{ utils.Tenant: "cgrates.org", utils.ToR: utils.VOICE, - utils.OriginID: "TestSSv1It1", + utils.OriginID: "testGOCS", utils.Category: "call", utils.RequestType: utils.META_PREPAID, utils.Account: "1001", @@ -441,6 +489,8 @@ func testGOCSTerminateSession(t *testing.T) { }, } var rply string + // we send terminate session with the correct usage, but because the US_SITE was down + // this lost the previous session operations and will debit more if err := dspRPC.Call(utils.SessionSv1TerminateSession, args, &rply); err != nil { t.Error(err) @@ -457,6 +507,24 @@ func testGOCSTerminateSession(t *testing.T) { err.Error() != utils.ErrNotFound.Error() { t.Errorf("Expected error %s received error %v and reply %s", utils.ErrNotFound, err, utils.ToJSON(aSessions)) } + + var acnt *engine.Account + attrAcc := &utils.AttrGetAccount{ + Tenant: "cgrates.org", + Account: "1001", + } + + if err := auRPC.Call(utils.ApierV2GetAccount, attrAcc, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.VOICE].GetTotalValue() != 2340000000000.0 { + t.Errorf("Expecting : %+v, received: %+v", 2340000000000.0, acnt.BalanceMap[utils.VOICE].GetTotalValue()) + } + + if err := usRPC.Call(utils.ApierV2GetAccount, attrAcc, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.VOICE].GetTotalValue() != 2340000000000.0 { + t.Errorf("Expecting : %+v, received: %+v", 2340000000000.0, acnt.BalanceMap[utils.VOICE].GetTotalValue()) + } } func testGOCSProcessCDR(t *testing.T) { @@ -467,7 +535,7 @@ func testGOCSProcessCDR(t *testing.T) { Event: map[string]interface{}{ utils.Tenant: "cgrates.org", utils.ToR: utils.VOICE, - utils.OriginID: "TestSSv1It1", + utils.OriginID: "testGOCS", utils.Category: "call", utils.RequestType: utils.META_PREPAID, utils.Account: "1001", @@ -475,11 +543,13 @@ func testGOCSProcessCDR(t *testing.T) { 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: 10 * time.Minute, + utils.Usage: 15 * time.Minute, }, }, } var rply string + // process cdr should apply the correction because terminate was debited to much + // 59 - 15 = 44 minutes if err := usRPC.Call(utils.SessionSv1ProcessCDR, args, &rply); err != nil { t.Error(err) @@ -488,6 +558,23 @@ func testGOCSProcessCDR(t *testing.T) { t.Errorf("Unexpected reply: %s", rply) } time.Sleep(100 * time.Millisecond) + var acnt *engine.Account + attrAcc := &utils.AttrGetAccount{ + Tenant: "cgrates.org", + Account: "1001", + } + + if err := auRPC.Call(utils.ApierV2GetAccount, attrAcc, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.VOICE].GetTotalValue() != 2640000000000.0 { + t.Errorf("Expecting : %+v, received: %+v", 2640000000000.0, acnt.BalanceMap[utils.VOICE].GetTotalValue()) + } + + if err := usRPC.Call(utils.ApierV2GetAccount, attrAcc, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.VOICE].GetTotalValue() != 2640000000000.0 { + t.Errorf("Expecting : %+v, received: %+v", 2640000000000.0, acnt.BalanceMap[utils.VOICE].GetTotalValue()) + } } func testGOCSStopCgrEngine(t *testing.T) { From fc54558e14c5d7a32c8c43054b9f28d2454a5b26 Mon Sep 17 00:00:00 2001 From: TeoV Date: Tue, 17 Dec 2019 04:06:52 -0500 Subject: [PATCH 3/3] Remove tariffPlans for GOCS tests --- data/tariffplans/gocs/au_site/Chargers.csv | 2 - .../gocs/au_site/DestinationRates.csv | 4 -- .../tariffplans/gocs/au_site/Destinations.csv | 3 -- data/tariffplans/gocs/au_site/Rates.csv | 5 --- data/tariffplans/gocs/au_site/RatingPlans.csv | 3 -- .../gocs/au_site/RatingProfiles.csv | 3 -- data/tariffplans/gocs/us_site/Chargers.csv | 2 - .../gocs/us_site/DestinationRates.csv | 4 -- .../tariffplans/gocs/us_site/Destinations.csv | 3 -- data/tariffplans/gocs/us_site/Rates.csv | 5 --- data/tariffplans/gocs/us_site/RatingPlans.csv | 3 -- .../gocs/us_site/RatingProfiles.csv | 3 -- general_tests/gocs_it_test.go | 45 +++++++++++++++---- 13 files changed, 36 insertions(+), 49 deletions(-) delete mode 100644 data/tariffplans/gocs/au_site/Chargers.csv delete mode 100644 data/tariffplans/gocs/au_site/DestinationRates.csv delete mode 100644 data/tariffplans/gocs/au_site/Destinations.csv delete mode 100644 data/tariffplans/gocs/au_site/Rates.csv delete mode 100644 data/tariffplans/gocs/au_site/RatingPlans.csv delete mode 100644 data/tariffplans/gocs/au_site/RatingProfiles.csv delete mode 100644 data/tariffplans/gocs/us_site/Chargers.csv delete mode 100644 data/tariffplans/gocs/us_site/DestinationRates.csv delete mode 100644 data/tariffplans/gocs/us_site/Destinations.csv delete mode 100644 data/tariffplans/gocs/us_site/Rates.csv delete mode 100644 data/tariffplans/gocs/us_site/RatingPlans.csv delete mode 100644 data/tariffplans/gocs/us_site/RatingProfiles.csv diff --git a/data/tariffplans/gocs/au_site/Chargers.csv b/data/tariffplans/gocs/au_site/Chargers.csv deleted file mode 100644 index c270b5867..000000000 --- a/data/tariffplans/gocs/au_site/Chargers.csv +++ /dev/null @@ -1,2 +0,0 @@ -#Tenant,ID,FilterIDs,ActivationInterval,RunID,AttributeIDs,Weight -cgrates.org,DEFAULT,,,*default,*none,0 \ No newline at end of file diff --git a/data/tariffplans/gocs/au_site/DestinationRates.csv b/data/tariffplans/gocs/au_site/DestinationRates.csv deleted file mode 100644 index ec0002962..000000000 --- a/data/tariffplans/gocs/au_site/DestinationRates.csv +++ /dev/null @@ -1,4 +0,0 @@ -#Id,DestinationId,RatesTag,RoundingMethod,RoundingDecimals,MaxCost,MaxCostStrategy -DR_1002_20CNT,DST_1002,RT_20CNT,*up,4,0, -DR_1001_10CNT,DST_1001,RT_10CNT,*up,4,0, - diff --git a/data/tariffplans/gocs/au_site/Destinations.csv b/data/tariffplans/gocs/au_site/Destinations.csv deleted file mode 100644 index 27b629107..000000000 --- a/data/tariffplans/gocs/au_site/Destinations.csv +++ /dev/null @@ -1,3 +0,0 @@ -#Id,Prefix -DST_1002,1002 -DST_1001,1001 \ No newline at end of file diff --git a/data/tariffplans/gocs/au_site/Rates.csv b/data/tariffplans/gocs/au_site/Rates.csv deleted file mode 100644 index 0924201a6..000000000 --- a/data/tariffplans/gocs/au_site/Rates.csv +++ /dev/null @@ -1,5 +0,0 @@ -#Id,ConnectFee,Rate,RateUnit,RateIncrement,GroupIntervalStart -RT_10CNT,0.2,0.1,60s,60s,0s -RT_10CNT,0,0.05,60s,1s,60s -RT_20CNT,0.4,0.2,60s,60s,0s -RT_20CNT,0,0.1,60s,1s,60s \ No newline at end of file diff --git a/data/tariffplans/gocs/au_site/RatingPlans.csv b/data/tariffplans/gocs/au_site/RatingPlans.csv deleted file mode 100644 index 391fa1234..000000000 --- a/data/tariffplans/gocs/au_site/RatingPlans.csv +++ /dev/null @@ -1,3 +0,0 @@ -#Id,DestinationRatesId,TimingTag,Weight -RP_1001,DR_1002_20CNT,*any,10 -RP_1002,DR_1001_10CNT,*any,10 \ No newline at end of file diff --git a/data/tariffplans/gocs/au_site/RatingProfiles.csv b/data/tariffplans/gocs/au_site/RatingProfiles.csv deleted file mode 100644 index 267aaa2c8..000000000 --- a/data/tariffplans/gocs/au_site/RatingProfiles.csv +++ /dev/null @@ -1,3 +0,0 @@ -#Tenant,Category,Subject,ActivationTime,RatingPlanId,RatesFallbackSubject -cgrates.org,call,1001,2014-01-14T00:00:00Z,RP_1001, -cgrates.org,call,1002,2014-01-14T00:00:00Z,RP_1002, \ No newline at end of file diff --git a/data/tariffplans/gocs/us_site/Chargers.csv b/data/tariffplans/gocs/us_site/Chargers.csv deleted file mode 100644 index c270b5867..000000000 --- a/data/tariffplans/gocs/us_site/Chargers.csv +++ /dev/null @@ -1,2 +0,0 @@ -#Tenant,ID,FilterIDs,ActivationInterval,RunID,AttributeIDs,Weight -cgrates.org,DEFAULT,,,*default,*none,0 \ No newline at end of file diff --git a/data/tariffplans/gocs/us_site/DestinationRates.csv b/data/tariffplans/gocs/us_site/DestinationRates.csv deleted file mode 100644 index ec0002962..000000000 --- a/data/tariffplans/gocs/us_site/DestinationRates.csv +++ /dev/null @@ -1,4 +0,0 @@ -#Id,DestinationId,RatesTag,RoundingMethod,RoundingDecimals,MaxCost,MaxCostStrategy -DR_1002_20CNT,DST_1002,RT_20CNT,*up,4,0, -DR_1001_10CNT,DST_1001,RT_10CNT,*up,4,0, - diff --git a/data/tariffplans/gocs/us_site/Destinations.csv b/data/tariffplans/gocs/us_site/Destinations.csv deleted file mode 100644 index 27b629107..000000000 --- a/data/tariffplans/gocs/us_site/Destinations.csv +++ /dev/null @@ -1,3 +0,0 @@ -#Id,Prefix -DST_1002,1002 -DST_1001,1001 \ No newline at end of file diff --git a/data/tariffplans/gocs/us_site/Rates.csv b/data/tariffplans/gocs/us_site/Rates.csv deleted file mode 100644 index 0924201a6..000000000 --- a/data/tariffplans/gocs/us_site/Rates.csv +++ /dev/null @@ -1,5 +0,0 @@ -#Id,ConnectFee,Rate,RateUnit,RateIncrement,GroupIntervalStart -RT_10CNT,0.2,0.1,60s,60s,0s -RT_10CNT,0,0.05,60s,1s,60s -RT_20CNT,0.4,0.2,60s,60s,0s -RT_20CNT,0,0.1,60s,1s,60s \ No newline at end of file diff --git a/data/tariffplans/gocs/us_site/RatingPlans.csv b/data/tariffplans/gocs/us_site/RatingPlans.csv deleted file mode 100644 index 391fa1234..000000000 --- a/data/tariffplans/gocs/us_site/RatingPlans.csv +++ /dev/null @@ -1,3 +0,0 @@ -#Id,DestinationRatesId,TimingTag,Weight -RP_1001,DR_1002_20CNT,*any,10 -RP_1002,DR_1001_10CNT,*any,10 \ No newline at end of file diff --git a/data/tariffplans/gocs/us_site/RatingProfiles.csv b/data/tariffplans/gocs/us_site/RatingProfiles.csv deleted file mode 100644 index 267aaa2c8..000000000 --- a/data/tariffplans/gocs/us_site/RatingProfiles.csv +++ /dev/null @@ -1,3 +0,0 @@ -#Tenant,Category,Subject,ActivationTime,RatingPlanId,RatesFallbackSubject -cgrates.org,call,1001,2014-01-14T00:00:00Z,RP_1001, -cgrates.org,call,1002,2014-01-14T00:00:00Z,RP_1002, \ No newline at end of file diff --git a/general_tests/gocs_it_test.go b/general_tests/gocs_it_test.go index 83f78c604..2b1e03c2f 100644 --- a/general_tests/gocs_it_test.go +++ b/general_tests/gocs_it_test.go @@ -24,9 +24,12 @@ import ( "net/rpc" "os/exec" "path" + "reflect" "testing" "time" + v1 "github.com/cgrates/cgrates/apier/v1" + "github.com/cgrates/cgrates/sessions" "github.com/cgrates/cgrates/utils" @@ -137,24 +140,47 @@ func testGOCSApierRpcConn(t *testing.T) { } func testGOCSLoadData(t *testing.T) { - attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "gocs", "us_site")} - var loadInst utils.LoadInstance - if err := usRPC.Call(utils.ApierV2LoadTariffPlanFromFolder, attrs, &loadInst); err != nil { - t.Error(err) + chargerProfile := &v1.ChargerWithCache{ + ChargerProfile: &engine.ChargerProfile{ + Tenant: "cgrates.org", + ID: "DEFAULT", + RunID: utils.MetaDefault, + AttributeIDs: []string{utils.META_NONE}, + Weight: 10, + }, } - attrs = &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "gocs", "au_site")} - if err := auRPC.Call(utils.ApierV2LoadTariffPlanFromFolder, attrs, &loadInst); err != nil { + var result string + if err := usRPC.Call(utils.ApierV1SetChargerProfile, chargerProfile, &result); err != nil { t.Error(err) + } else if result != utils.OK { + t.Error("Unexpected reply returned", result) } - time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups on au_site - attrs = &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "gocs", "dsp_site")} + var rpl *engine.ChargerProfile + if err := usRPC.Call(utils.ApierV1GetChargerProfile, + &utils.TenantID{Tenant: "cgrates.org", ID: "DEFAULT"}, &rpl); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(chargerProfile.ChargerProfile, rpl) { + t.Errorf("Expecting : %+v, received: %+v", chargerProfile.ChargerProfile, rpl) + } + if err := usRPC.Call(utils.ApierV1SetChargerProfile, chargerProfile, &result); err != nil { + t.Error(err) + } else if result != utils.OK { + t.Error("Unexpected reply returned", result) + } + if err := usRPC.Call(utils.ApierV1GetChargerProfile, + &utils.TenantID{Tenant: "cgrates.org", ID: "DEFAULT"}, &rpl); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(chargerProfile.ChargerProfile, rpl) { + t.Errorf("Expecting : %+v, received: %+v", chargerProfile.ChargerProfile, rpl) + } + wchan := make(chan struct{}, 1) go func() { loaderPath, err := exec.LookPath("cgr-loader") if err != nil { t.Error(err) } - loader := exec.Command(loaderPath, "-config_path", dspCfgPath, "-path", attrs.FolderPath) + loader := exec.Command(loaderPath, "-config_path", dspCfgPath, "-path", path.Join(*dataDir, "tariffplans", "gocs", "dsp_site")) if err := loader.Start(); err != nil { t.Error(err) @@ -194,6 +220,7 @@ func testGOCSLoadData(t *testing.T) { } else if rply := acnt.BalanceMap[utils.VOICE].GetTotalValue(); rply != expectedVoice { t.Errorf("Expecting: %v, received: %v", expectedVoice, rply) } + time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups on au_site } func testGOCSAuthSession(t *testing.T) {