mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-22 23:58:44 +05:00
The time it takes to register RPC methods is quite long and sometimes it is causing errors when methods that are not yet registered are being called. Therefore, the 'waitRater' default value has been increased from 100ms to 500ms. For 'cdrs_onlexp_it_test.go': - 2 functions have been added that create and delete the kafka topic relevant to the test. This ensures that the topic exists before export and also that it is deleted to avoid the data from within to influence subsequent tests; - the maximum duration that we are waiting for the amqp messages to be consumed has been increased. Since it usually takes anywhere between 300ms and 1.9s to read a message, it has been increased to 2 seconds; - amqp queues are now deleted once we are done verifying the exports. For 'cdrs_post_failover_it_test.go', we now make sure that the failed posts directories exist and are empty before starting the engine. For 'cdrs_processevent_it_test.go': - some of the stat queue items were expiring too quickly, causing the test for fail sometimes. In order to solve the issue, I had to modify increase the TTL, but since the 'testit' tariff plan is also used by other tests, I decided to create the .csv files within the test, taking from 'testit' only the relevant information; - same issue as in the previous test was occuring here. Was fixed in the same way; - removed some useless calls.
221 lines
7.1 KiB
Go
221 lines
7.1 KiB
Go
//go:build integration
|
|
// +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"
|
|
"os"
|
|
"path"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/cgrates/cgrates/config"
|
|
"github.com/cgrates/cgrates/engine"
|
|
"github.com/cgrates/cgrates/utils"
|
|
)
|
|
|
|
var (
|
|
cdrsPostFailCfgPath string
|
|
cdrsPostFailCfg *config.CGRConfig
|
|
cdrsPostFailRpc *rpc.Client
|
|
cdrsPostFailConfDIR string // run the tests for specific configuration
|
|
|
|
// subtests to be executed for each confDIR
|
|
sTestsCDRsPostFailIT = []func(t *testing.T){
|
|
testCDRsPostFailoverInitConfig,
|
|
testCDRsPostFailoverInitDataDb,
|
|
testCDRsPostFailoverInitCdrDb,
|
|
testCDRsPostFailoverStartEngine,
|
|
testCDRsPostFailoverRpcConn,
|
|
testCDRsPostFailoverLoadTariffPlanFromFolder,
|
|
testCDRsPostFailoverProcessCDR,
|
|
testCDRsPostFailoverToFile,
|
|
testCDRsPostFailoverKillEngine,
|
|
}
|
|
)
|
|
|
|
// Tests starting here
|
|
func TestCDRsPostFailoverIT(t *testing.T) {
|
|
switch *dbType {
|
|
case utils.MetaInternal:
|
|
cdrsPostFailConfDIR = "cdrsv_failover_internal"
|
|
case utils.MetaMySQL:
|
|
cdrsPostFailConfDIR = "cdrsv_failover_mysql"
|
|
case utils.MetaMongo:
|
|
cdrsPostFailConfDIR = "cdrsv_failover_mongo"
|
|
case utils.MetaPostgres:
|
|
t.SkipNow()
|
|
default:
|
|
t.Fatal("Unknown Database type")
|
|
}
|
|
|
|
for _, stest := range sTestsCDRsPostFailIT {
|
|
t.Run(cdrsPostFailConfDIR, stest)
|
|
}
|
|
}
|
|
|
|
func testCDRsPostFailoverInitConfig(t *testing.T) {
|
|
var err error
|
|
cdrsPostFailCfgPath = path.Join(*dataDir, "conf", "samples", cdrsPostFailConfDIR)
|
|
if cdrsPostFailCfg, err = config.NewCGRConfigFromPath(cdrsPostFailCfgPath); err != nil {
|
|
t.Fatal("Got config error: ", err.Error())
|
|
}
|
|
}
|
|
|
|
func testCDRsPostFailoverInitDataDb(t *testing.T) {
|
|
if err := engine.InitDataDb(cdrsPostFailCfg); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
// InitDb so we can rely on count
|
|
func testCDRsPostFailoverInitCdrDb(t *testing.T) {
|
|
if err := engine.InitStorDb(cdrsPostFailCfg); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func testCDRsPostFailoverStartEngine(t *testing.T) {
|
|
// before starting the engine, create the directories needed for failed posts or
|
|
// clear their contents if they exist already
|
|
if err := os.RemoveAll(cdrsPostFailCfg.GeneralCfg().FailedPostsDir); err != nil {
|
|
t.Fatal("Error removing folder: ", cdrsPostFailCfg.GeneralCfg().FailedPostsDir, err)
|
|
}
|
|
if err := os.MkdirAll(cdrsPostFailCfg.GeneralCfg().FailedPostsDir, 0755); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
if _, err := engine.StopStartEngine(cdrsPostFailCfgPath, *waitRater); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
// Connect rpc client to rater
|
|
func testCDRsPostFailoverRpcConn(t *testing.T) {
|
|
cdrsPostFailRpc, err = newRPCClient(cdrsPostFailCfg.ListenCfg()) // We connect over JSON so we can also troubleshoot if needed
|
|
if err != nil {
|
|
t.Fatal("Could not connect to rater: ", err.Error())
|
|
}
|
|
}
|
|
|
|
func testCDRsPostFailoverLoadTariffPlanFromFolder(t *testing.T) {
|
|
var loadInst utils.LoadInstance
|
|
if err := cdrsPostFailRpc.Call(utils.APIerSv2LoadTariffPlanFromFolder,
|
|
&utils.AttrLoadTpFromFolder{FolderPath: path.Join(
|
|
*dataDir, "tariffplans", "testit")}, &loadInst); err != nil {
|
|
t.Error(err)
|
|
}
|
|
time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups
|
|
var resp string
|
|
if err := cdrsPostFailRpc.Call(utils.APIerSv1RemoveChargerProfile,
|
|
&utils.TenantID{Tenant: "cgrates.org", ID: "SupplierCharges"}, &resp); err != nil {
|
|
t.Error(err)
|
|
} else if resp != utils.OK {
|
|
t.Error("Unexpected reply returned", resp)
|
|
}
|
|
var reply *engine.ChargerProfile
|
|
if err := cdrsPostFailRpc.Call(utils.APIerSv1GetChargerProfile,
|
|
&utils.TenantID{Tenant: "cgrates.org", ID: "SupplierCharges"},
|
|
&reply); err == nil || err.Error() != utils.ErrNotFound.Error() {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func testCDRsPostFailoverProcessCDR(t *testing.T) {
|
|
args := &engine.ArgV1ProcessEvent{
|
|
Flags: []string{utils.MetaExport, "*attributes:false", "*rals:false", "*chargers:*false",
|
|
"*store:false", "*thresholds:false", "*stats:false"}, // only export the CDR
|
|
CGREvent: utils.CGREvent{
|
|
ID: "1",
|
|
Tenant: "cgrates.org",
|
|
Event: map[string]interface{}{
|
|
utils.OriginID: "testCDRsPostFailoverProcessCDR",
|
|
utils.OriginHost: "192.168.1.1",
|
|
utils.Source: "testCDRsPostFailoverProcessCDR",
|
|
utils.RequestType: utils.META_RATED,
|
|
utils.Category: "call",
|
|
utils.Account: "testCDRsPostFailoverProcessCDR",
|
|
utils.Subject: "ANY2CNT",
|
|
utils.Destination: "+4986517174963",
|
|
utils.AnswerTime: time.Date(2018, 8, 24, 16, 00, 26, 0, time.UTC),
|
|
utils.Usage: time.Duration(1) * time.Minute,
|
|
"field_extr1": "val_extr1",
|
|
"fieldextr2": "valextr2",
|
|
},
|
|
},
|
|
}
|
|
|
|
var reply string
|
|
if err := cdrsPostFailRpc.Call(utils.CDRsV1ProcessEvent, args, &reply); err != nil {
|
|
t.Error("Unexpected error: ", err.Error())
|
|
} else if reply != utils.OK {
|
|
t.Error("Unexpected reply received: ", reply)
|
|
}
|
|
args.ID = "2"
|
|
args.Event[utils.OriginID] = "2"
|
|
if err := cdrsPostFailRpc.Call(utils.CDRsV1ProcessEvent, args, &reply); err != nil {
|
|
t.Error("Unexpected error: ", err.Error())
|
|
} else if reply != utils.OK {
|
|
t.Error("Unexpected reply received: ", reply)
|
|
}
|
|
args.ID = "3"
|
|
args.Event[utils.OriginID] = "3"
|
|
if err := cdrsPostFailRpc.Call(utils.CDRsV1ProcessEvent, args, &reply); err != nil {
|
|
t.Error("Unexpected error: ", err.Error())
|
|
} else if reply != utils.OK {
|
|
t.Error("Unexpected reply received: ", reply)
|
|
}
|
|
}
|
|
|
|
func testCDRsPostFailoverToFile(t *testing.T) {
|
|
time.Sleep(time.Duration(2 * time.Second))
|
|
filesInDir, _ := os.ReadDir(cdrsPostFailCfg.GeneralCfg().FailedPostsDir)
|
|
if len(filesInDir) == 0 {
|
|
t.Fatalf("No files in directory: %s", cdrsPostFailCfg.GeneralCfg().FailedPostsDir)
|
|
}
|
|
for _, file := range filesInDir { // First file in directory is the one we need, harder to find it's name out of config
|
|
fileName := file.Name()
|
|
filePath := path.Join(cdrsPostFailCfg.GeneralCfg().FailedPostsDir, fileName)
|
|
|
|
ev, err := engine.NewExportEventsFromFile(filePath)
|
|
if err != nil {
|
|
t.Errorf("<%s> for file <%s>", err, fileName)
|
|
continue
|
|
} else if len(ev.Events) == 0 {
|
|
t.Error("Expected at least one event")
|
|
continue
|
|
}
|
|
if ev.Format != utils.MetaS3jsonMap {
|
|
t.Errorf("Expected event to use %q received: %q", utils.MetaS3jsonMap, ev.Format)
|
|
}
|
|
if len(ev.Events) != 3 {
|
|
t.Errorf("Expected all the events to be saved in the same file, ony %v saved in this file.", len(ev.Events))
|
|
}
|
|
}
|
|
}
|
|
|
|
func testCDRsPostFailoverKillEngine(t *testing.T) {
|
|
if err := engine.KillEngine(*waitRater); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|