mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
226 lines
6.4 KiB
Go
226 lines
6.4 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 Affero 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 Affero General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>
|
|
*/
|
|
|
|
package general_tests
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/json"
|
|
"fmt"
|
|
"math/big"
|
|
"net/rpc"
|
|
"os"
|
|
"path/filepath"
|
|
"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 (
|
|
cdRFCfgPath string
|
|
cdRFCfg *config.CGRConfig
|
|
cdRFRPC *rpc.Client
|
|
cdRFDelay int
|
|
|
|
sTestsCDReplaceField = []func(t *testing.T){
|
|
testCDReplaceFieldLoadConfig,
|
|
testCDReplaceFieldInitDataDb,
|
|
testCDReplaceFieldResetStorDb,
|
|
testCDReplaceFieldStartEngine,
|
|
testCDReplaceFieldRpcConn,
|
|
|
|
testCDReplaceFieldStoreCDR,
|
|
testCDReplaceFieldExportCDR,
|
|
|
|
testCDReplaceFieldStopEngine,
|
|
}
|
|
)
|
|
|
|
func TestCDReplaceFieldIT(t *testing.T) {
|
|
for _, stest := range sTestsCDReplaceField {
|
|
t.Run("cost details replace field", stest)
|
|
}
|
|
}
|
|
|
|
func testCDReplaceFieldLoadConfig(t *testing.T) {
|
|
content := `{
|
|
"general": {
|
|
"log_level": 7,
|
|
"node_id": "cd_replace_field",
|
|
},
|
|
"data_db": {
|
|
"db_type": "*internal"
|
|
},
|
|
"stor_db": {
|
|
"db_type": "*internal"
|
|
},
|
|
"cdrs": {
|
|
"enabled": true,
|
|
},
|
|
"apiers": {
|
|
"enabled": true
|
|
},
|
|
"cdre": {
|
|
"csv_exporter": {
|
|
"export_format": "*file_csv",
|
|
"export_path": "/tmp/",
|
|
"fields": [
|
|
{"path": "*exp.CGRID", "type": "*composed", "value": "~*req.CGRID"},
|
|
// {
|
|
// "path": "*exp.TariffClass",
|
|
// "type": "*composed",
|
|
// "value": "~*req.CostDetails"
|
|
// },
|
|
{
|
|
"path": "*exp.TariffClass",
|
|
"type": "*composed",
|
|
"filters": [
|
|
"*rsr::~*req.CostDetails(~^.+\"DestinationID\":\"\\w+_(\\w{5})\".+$)"
|
|
],
|
|
"value": "~*req.CostDetails:s/^.+\"DestinationID\":\"\\w+_(\\w{5})\".+$/${1}/:s/\"DestinationID\":\"INTERNAL\"/ON010/"
|
|
},
|
|
],
|
|
},
|
|
},
|
|
}`
|
|
folderNameSuffix, err := rand.Int(rand.Reader, big.NewInt(10000))
|
|
if err != nil {
|
|
t.Fatalf("could not generate random number for folder name suffix, err: %s", err.Error())
|
|
}
|
|
cdRFCfgPath = fmt.Sprintf("/tmp/config%d", folderNameSuffix)
|
|
err = os.MkdirAll(cdRFCfgPath, 0755)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
filePath := filepath.Join(cdRFCfgPath, "cgrates.json")
|
|
err = os.WriteFile(filePath, []byte(content), 0644)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if cdRFCfg, err = config.NewCGRConfigFromPath(cdRFCfgPath); err != nil {
|
|
t.Error(err)
|
|
}
|
|
cdRFDelay = 100
|
|
}
|
|
|
|
func testCDReplaceFieldInitDataDb(t *testing.T) {
|
|
if err := engine.InitDataDb(cdRFCfg); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func testCDReplaceFieldResetStorDb(t *testing.T) {
|
|
if err := engine.InitStorDb(cdRFCfg); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func testCDReplaceFieldStartEngine(t *testing.T) {
|
|
if _, err := engine.StopStartEngine(cdRFCfgPath, cdRFDelay); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func testCDReplaceFieldRpcConn(t *testing.T) {
|
|
var err error
|
|
cdRFRPC, err = newRPCClient(cdRFCfg.ListenCfg())
|
|
if err != nil {
|
|
t.Fatal("Could not connect to engine: ", err.Error())
|
|
}
|
|
}
|
|
|
|
func testCDReplaceFieldStoreCDR(t *testing.T) {
|
|
sampleCD := &engine.EventCost{}
|
|
err := json.Unmarshal(
|
|
[]byte(`{"CGRID":"31ee543fdc15e011332e0a0952c0b37b161e3a59","RunID":"*default","StartTime":"2023-06-19T11:15:46-04:00","Usage":10000000000,"Cost":0.1,"Charges":[{"RatingID":"efd715b","Increments":[{"Usage":1000000000,"Cost":0.01,"AccountingID":"c946243","CompressFactor":5}],"CompressFactor":2}],"AccountSummary":{"Tenant":"cgrates.org","ID":"1001","BalanceSummaries":[{"UUID":"e4bf588f-583b-44d9-9b5d-cd12d9b7331c","ID":"test","Type":"*monetary","Value":8.5682,"Disabled":false}],"AllowNegative":false,"Disabled":false},"Rating":{"efd715b":{"ConnectFee":0,"RoundingMethod":"*up","RoundingDecimals":4,"MaxCost":0.12,"MaxCostStrategy":"*disconnect","TimingID":"240ecf8","RatesID":"8042384","RatingFiltersID":"ef07765"}},"Accounting":{"c946243":{"AccountID":"cgrates.org:1001","BalanceUUID":"e4bf588f-583b-44d9-9b5d-cd12d9b7331c","RatingID":"","Units":0.01,"ExtraChargeID":""}},"RatingFilters":{"ef07765":{"DestinationID":"CST_316_NL002","DestinationPrefix":"1003","RatingPlanID":"RP_1001","Subject":"*out:cgrates.org:call:1001"}},"Rates":{"8042384":[{"GroupIntervalStart":0,"Value":0.01,"RateIncrement":1000000000,"RateUnit":1000000000}]},"Timings":{"240ecf8":{"Years":[],"Months":[],"MonthDays":[],"WeekDays":[],"StartTime":"00:00:00"}}}`),
|
|
sampleCD)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
setupTime := time.Now()
|
|
cdr := &engine.CDR{
|
|
CGRID: "CDR_1",
|
|
OrderID: 123,
|
|
ToR: utils.VOICE,
|
|
OriginID: "1",
|
|
OriginHost: "192.168.1.1",
|
|
Source: "test",
|
|
RequestType: utils.META_PREPAID,
|
|
Tenant: "cgrates.org",
|
|
Category: "call",
|
|
Account: "1001",
|
|
Subject: "1001",
|
|
Destination: "+4986517174963",
|
|
SetupTime: setupTime,
|
|
AnswerTime: setupTime.Add(2 * time.Second),
|
|
RunID: utils.MetaDefault,
|
|
Usage: 30 * time.Second,
|
|
Cost: 1.01,
|
|
CostDetails: sampleCD,
|
|
}
|
|
|
|
var reply string
|
|
if err := cdRFRPC.Call(utils.CDRsV1ProcessCDR, &engine.CDRWithArgDispatcher{CDR: cdr}, &reply); err != nil {
|
|
t.Error("Unexpected error: ", err.Error())
|
|
} else if reply != utils.OK {
|
|
t.Error("Unexpected reply received: ", reply)
|
|
}
|
|
time.Sleep(100 * time.Millisecond)
|
|
}
|
|
|
|
func testCDReplaceFieldExportCDR(t *testing.T) {
|
|
attr := v1.ArgExportCDRs{
|
|
ExportArgs: map[string]any{
|
|
utils.ExportTemplate: "csv_exporter",
|
|
},
|
|
Verbose: true,
|
|
}
|
|
var reply *v1.RplExportedCDRs
|
|
err := cdRFRPC.Call(utils.APIerSv1ExportCDRs, attr, &reply)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
exportedCDR, err := os.ReadFile(reply.ExportedPath)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
exp := "CDR_1,NL002\n"
|
|
if rcv := string(exportedCDR); rcv != exp {
|
|
t.Errorf("expected <%s>, received <%s>", exp, rcv)
|
|
}
|
|
|
|
}
|
|
|
|
func testCDReplaceFieldStopEngine(t *testing.T) {
|
|
err := engine.KillEngine(cdRFDelay)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = os.RemoveAll(cdRFCfgPath)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|