mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
685 lines
19 KiB
Go
685 lines
19 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 ers
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path"
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/cgrates/birpc/context"
|
|
|
|
"github.com/cgrates/birpc"
|
|
"github.com/cgrates/cgrates/utils"
|
|
|
|
"github.com/cgrates/cgrates/config"
|
|
"github.com/cgrates/cgrates/engine"
|
|
)
|
|
|
|
var (
|
|
xmlCfgPath string
|
|
xmlCfgDIR string
|
|
xmlCfg *config.CGRConfig
|
|
xmlRPC *birpc.Client
|
|
|
|
xmlTests = []func(t *testing.T){
|
|
testCreateDirs,
|
|
testXMLITInitConfig,
|
|
testXMLITInitCdrDb,
|
|
testXMLITResetDataDb,
|
|
testXMLITStartEngine,
|
|
testXMLITRpcConn,
|
|
testXMLITLoadTPFromFolder,
|
|
testXMLITHandleCdr1File,
|
|
testXmlITAnalyseCDRs,
|
|
testXMLITEmptyRootPathCase,
|
|
testXMLITEmptyRootPathCaseCheckCDRs,
|
|
testCleanupFiles,
|
|
testXMLITKillEngine,
|
|
}
|
|
)
|
|
|
|
func TestXMLReadFile(t *testing.T) {
|
|
switch *utils.DBType {
|
|
case utils.MetaInternal:
|
|
xmlCfgDIR = "ers_internal"
|
|
case utils.MetaMySQL:
|
|
xmlCfgDIR = "ers_mysql"
|
|
case utils.MetaMongo:
|
|
xmlCfgDIR = "ers_mongo"
|
|
case utils.MetaPostgres:
|
|
xmlCfgDIR = "ers_postgres"
|
|
default:
|
|
t.Fatal("Unknown Database type")
|
|
}
|
|
for _, test := range xmlTests {
|
|
t.Run(xmlCfgDIR, test)
|
|
}
|
|
}
|
|
|
|
func testXMLITInitConfig(t *testing.T) {
|
|
var err error
|
|
xmlCfgPath = path.Join(*utils.DataDir, "conf", "samples", xmlCfgDIR)
|
|
if xmlCfg, err = config.NewCGRConfigFromPath(xmlCfgPath); err != nil {
|
|
t.Fatal("Got config error: ", err.Error())
|
|
}
|
|
}
|
|
|
|
// InitDb so we can rely on count
|
|
func testXMLITInitCdrDb(t *testing.T) {
|
|
if err := engine.InitStorDb(xmlCfg); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
// Remove data in both rating and accounting db
|
|
func testXMLITResetDataDb(t *testing.T) {
|
|
if err := engine.InitDataDB(xmlCfg); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func testXMLITStartEngine(t *testing.T) {
|
|
if _, err := engine.StopStartEngine(xmlCfgPath, *utils.WaitRater); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
// Connect rpc client to rater
|
|
func testXMLITRpcConn(t *testing.T) {
|
|
var err error
|
|
xmlRPC, err = newRPCClient(xmlCfg.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 testXMLITLoadTPFromFolder(t *testing.T) {
|
|
attrs := &utils.AttrLoadTpFromFolder{
|
|
FolderPath: path.Join(*utils.DataDir, "tariffplans", "testit")}
|
|
var loadInst utils.LoadInstance
|
|
if err := xmlRPC.Call(context.Background(), utils.APIerSv2LoadTariffPlanFromFolder,
|
|
attrs, &loadInst); err != nil {
|
|
t.Error(err)
|
|
}
|
|
time.Sleep(100 * time.Millisecond)
|
|
}
|
|
|
|
var cdrXmlBroadsoft = `<?xml version="1.0" encoding="ISO-8859-1"?>
|
|
<!DOCTYPE broadWorksCDR>
|
|
<broadWorksCDR version="19.0">
|
|
<cdrData>
|
|
<headerModule>
|
|
<recordId>
|
|
<eventCounter>0002183384</eventCounter>
|
|
<systemId>CGRateSaabb</systemId>
|
|
<date>20160419210000.104</date>
|
|
<systemTimeZone>1+020000</systemTimeZone>
|
|
</recordId>
|
|
<type>Start</type>
|
|
</headerModule>
|
|
</cdrData>
|
|
<cdrData>
|
|
<headerModule>
|
|
<recordId>
|
|
<eventCounter>0002183385</eventCounter>
|
|
<systemId>CGRateSaabb</systemId>
|
|
<date>20160419210005.247</date>
|
|
<systemTimeZone>1+020000</systemTimeZone>
|
|
</recordId>
|
|
<serviceProvider>MBC</serviceProvider>
|
|
<type>Normal</type>
|
|
</headerModule>
|
|
<basicModule>
|
|
<userNumber>1001</userNumber>
|
|
<groupNumber>2001</groupNumber>
|
|
<asCallType>Network</asCallType>
|
|
<callingNumber>1001</callingNumber>
|
|
<callingPresentationIndicator>Public</callingPresentationIndicator>
|
|
<calledNumber>+4915117174963</calledNumber>
|
|
<startTime>20160419210005.247</startTime>
|
|
<userTimeZone>1+020000</userTimeZone>
|
|
<localCallId>25160047719:0</localCallId>
|
|
<answerIndicator>Yes</answerIndicator>
|
|
<answerTime>20160419210006.813</answerTime>
|
|
<releaseTime>20160419210020.296</releaseTime>
|
|
<terminationCause>016</terminationCause>
|
|
<chargeIndicator>y</chargeIndicator>
|
|
<releasingParty>local</releasingParty>
|
|
<userId>1001@cgrates.org</userId>
|
|
<clidPermitted>Yes</clidPermitted>
|
|
<namePermitted>Yes</namePermitted>
|
|
</basicModule>
|
|
<centrexModule>
|
|
<group>CGR_GROUP</group>
|
|
<trunkGroupName>CGR_GROUP/CGR_GROUP_TRUNK30</trunkGroupName>
|
|
<trunkGroupInfo>Normal</trunkGroupInfo>
|
|
<locationList>
|
|
<locationInformation>
|
|
<location>1001@cgrates.org</location>
|
|
<locationType>Primary Device</locationType>
|
|
</locationInformation>
|
|
</locationList>
|
|
<locationUsage>31.882</locationUsage>
|
|
</centrexModule>
|
|
<ipModule>
|
|
<route>gw04.cgrates.org</route>
|
|
<networkCallID>74122796919420162305@172.16.1.2</networkCallID>
|
|
<codec>PCMA/8000</codec>
|
|
<accessDeviceAddress>172.16.1.4</accessDeviceAddress>
|
|
<accessCallID>BW2300052501904161738474465@172.16.1.10</accessCallID>
|
|
<codecUsage>31.882</codecUsage>
|
|
<userAgent>OmniPCX Enterprise R11.0.1 k1.520.22.b</userAgent>
|
|
</ipModule>
|
|
</cdrData>
|
|
<cdrData>
|
|
<headerModule>
|
|
<recordId>
|
|
<eventCounter>0002183386</eventCounter>
|
|
<systemId>CGRateSaabb</systemId>
|
|
<date>20160419210006.909</date>
|
|
<systemTimeZone>1+020000</systemTimeZone>
|
|
</recordId>
|
|
<serviceProvider>MBC</serviceProvider>
|
|
<type>Normal</type>
|
|
</headerModule>
|
|
<basicModule>
|
|
<userNumber>1002</userNumber>
|
|
<groupNumber>2001</groupNumber>
|
|
<asCallType>Network</asCallType>
|
|
<callingNumber>+4986517174964</callingNumber>
|
|
<callingPresentationIndicator>Public</callingPresentationIndicator>
|
|
<calledNumber>1001</calledNumber>
|
|
<startTime>20160419210006.909</startTime>
|
|
<userTimeZone>1+020000</userTimeZone>
|
|
<localCallId>27280048121:0</localCallId>
|
|
<answerIndicator>Yes</answerIndicator>
|
|
<answerTime>20160419210007.037</answerTime>
|
|
<releaseTime>20160419210030.322</releaseTime>
|
|
<terminationCause>016</terminationCause>
|
|
<chargeIndicator>y</chargeIndicator>
|
|
<releasingParty>local</releasingParty>
|
|
<userId>314028947650@cgrates.org</userId>
|
|
<clidPermitted>Yes</clidPermitted>
|
|
<namePermitted>Yes</namePermitted>
|
|
</basicModule>
|
|
<centrexModule>
|
|
<group>CGR_GROUP</group>
|
|
<trunkGroupName>CGR_GROUP/CGR_GROUP_TRUNK65</trunkGroupName>
|
|
<trunkGroupInfo>Normal</trunkGroupInfo>
|
|
<locationList>
|
|
<locationInformation>
|
|
<location>31403456100@cgrates.org</location>
|
|
<locationType>Primary Device</locationType>
|
|
</locationInformation>
|
|
</locationList>
|
|
<locationUsage>26.244</locationUsage>
|
|
</centrexModule>
|
|
<ipModule>
|
|
<route>gw01.cgrates.org</route>
|
|
<networkCallID>108352493719420162306@172.31.250.150</networkCallID>
|
|
<codec>PCMA/8000</codec>
|
|
<accessDeviceAddress>172.16.1.4</accessDeviceAddress>
|
|
<accessCallID>2345300069121904161716512907@172.16.1.10</accessCallID>
|
|
<codecUsage>26.244</codecUsage>
|
|
<userAgent>Altitude vBox</userAgent>
|
|
</ipModule>
|
|
</cdrData>
|
|
<cdrData>
|
|
<headerModule>
|
|
<recordId>
|
|
<eventCounter>0002183486</eventCounter>
|
|
<systemId>CGRateSaabb</systemId>
|
|
<date>20160419211500.104</date>
|
|
<systemTimeZone>1+020000</systemTimeZone>
|
|
</recordId>
|
|
<type>End</type>
|
|
</headerModule>
|
|
</cdrData>
|
|
</broadWorksCDR>`
|
|
|
|
// The default scenario, out of ers defined in .cfg file
|
|
func testXMLITHandleCdr1File(t *testing.T) {
|
|
fileName := "file1.xml"
|
|
tmpFilePath := path.Join("/tmp", fileName)
|
|
if err := os.WriteFile(tmpFilePath, []byte(cdrXmlBroadsoft), 0644); err != nil {
|
|
t.Fatal(err.Error())
|
|
}
|
|
if err := os.Rename(tmpFilePath, path.Join("/tmp/xmlErs/in", fileName)); err != nil {
|
|
t.Fatal("Error moving file to processing directory: ", err)
|
|
}
|
|
time.Sleep(200 * time.Millisecond)
|
|
}
|
|
|
|
func testXmlITAnalyseCDRs(t *testing.T) {
|
|
var reply []*engine.ExternalCDR
|
|
if err := xmlRPC.Call(context.Background(), utils.APIerSv2GetCDRs, &utils.RPCCDRsFilter{}, &reply); err != nil {
|
|
t.Error("Unexpected error: ", err.Error())
|
|
} else if len(reply) != 6 {
|
|
t.Error("Unexpected number of CDRs returned: ", len(reply))
|
|
}
|
|
for _, cdr := range reply {
|
|
if cdr.ExtraFields["ReaderID"] != "XmlDryRun" {
|
|
t.Errorf("Expected <%v>, received <%v>", "XmlDryRun", cdr.ExtraFields["ReaderID"])
|
|
}
|
|
}
|
|
if err := xmlRPC.Call(context.Background(), utils.APIerSv2GetCDRs, &utils.RPCCDRsFilter{DestinationPrefixes: []string{"+4915117174963"}}, &reply); err != nil {
|
|
t.Error("Unexpected error: ", err.Error())
|
|
} else if len(reply) != 3 {
|
|
t.Error("Unexpected number of CDRs returned: ", len(reply))
|
|
}
|
|
}
|
|
|
|
var xmlPartialCDR = `<?xml version="1.0" encoding="ISO-8859-1"?>
|
|
<root>
|
|
<partial_cdr>
|
|
<ID>1</ID>
|
|
<Account>1001</Account>
|
|
<Destination>1002</Destination>
|
|
<Tenant>cgrates.org</Tenant>
|
|
<ReleaseTime>20231011125833.158</ReleaseTime>
|
|
</partial_cdr>
|
|
<partial_cdr>
|
|
<ID>2</ID>
|
|
<RequestType>*postpaid</RequestType>
|
|
<ToR>*voice</ToR>
|
|
</partial_cdr>
|
|
<partial_cdr>
|
|
<TestCase>EmptyRootCDR</TestCase>
|
|
<ID>3</ID>
|
|
<Tenant>ignored</Tenant>
|
|
<SetupTime>20231011125800</SetupTime>
|
|
<AnswerTime>20231011125801</AnswerTime>
|
|
</partial_cdr>
|
|
</root>`
|
|
|
|
func testXMLITEmptyRootPathCase(t *testing.T) {
|
|
fileName := "partial-cdr.xml"
|
|
tmpFilePath := path.Join("/tmp", fileName)
|
|
if err := os.WriteFile(tmpFilePath, []byte(xmlPartialCDR), 0644); err != nil {
|
|
t.Fatal(err.Error())
|
|
}
|
|
if err := os.Rename(tmpFilePath, path.Join("/tmp/xmlErs2/in", fileName)); err != nil {
|
|
t.Fatal("Error moving file to processing directory: ", err)
|
|
}
|
|
time.Sleep(100 * time.Millisecond)
|
|
}
|
|
|
|
func testXMLITEmptyRootPathCaseCheckCDRs(t *testing.T) {
|
|
var reply []*engine.ExternalCDR
|
|
if err := xmlRPC.Call(
|
|
context.Background(),
|
|
utils.APIerSv2GetCDRs,
|
|
utils.RPCCDRsFilter{OriginIDs: []string{"EmptyRootCDR_2"}},
|
|
&reply); err != nil {
|
|
t.Error("Unexpected error: ", err.Error())
|
|
} else if len(reply) != 3 {
|
|
t.Error("Unexpected number of CDRs returned:", len(reply))
|
|
}
|
|
}
|
|
|
|
func testXMLITKillEngine(t *testing.T) {
|
|
if err := engine.KillEngine(*utils.WaitRater); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestNewXMLFileER(t *testing.T) {
|
|
cfg := config.NewDefaultCGRConfig()
|
|
cfg.ERsCfg().Readers[0].SourcePath = "/tmp/xmlErs/out/"
|
|
cfg.ERsCfg().Readers[0].ConcurrentReqs = 1
|
|
fltrs := &engine.FilterS{}
|
|
expEr := &XMLFileER{
|
|
cgrCfg: cfg,
|
|
cfgIdx: 0,
|
|
fltrS: fltrs,
|
|
sourceDir: "/tmp/xmlErs/out",
|
|
rdrEvents: nil,
|
|
rdrError: nil,
|
|
rdrExit: nil,
|
|
conReqs: make(chan struct{}, 1),
|
|
}
|
|
|
|
eR, err := NewXMLFileER(cfg, 0, nil, nil, nil, fltrs, nil)
|
|
|
|
expEr.conReqs = nil
|
|
eR.(*XMLFileER).conReqs = nil
|
|
if err != nil {
|
|
t.Error(err)
|
|
} else if !reflect.DeepEqual(eR.(*XMLFileER), expEr) {
|
|
t.Errorf("Expected %v but received %v", expEr.conReqs, eR.(*XMLFileER).conReqs)
|
|
}
|
|
}
|
|
|
|
func TestFileXMLProcessEvent(t *testing.T) {
|
|
cfg := config.NewDefaultCGRConfig()
|
|
cfg.ERsCfg().Readers[0].ProcessedPath = ""
|
|
fltrs := &engine.FilterS{}
|
|
filePath := "/tmp/TestFileXMLProcessEvent/"
|
|
if err := os.MkdirAll(filePath, 0777); err != nil {
|
|
t.Error(err)
|
|
}
|
|
file, err := os.Create(path.Join(filePath, "file1.xml"))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
xmlData := `<?xml version="1.0" encoding="ISO-8859-1"?>
|
|
<!DOCTYPE broadWorksCDR>
|
|
<broadWorksCDR version="19.0">
|
|
<cdrData>
|
|
<basicModule>
|
|
<localCallId>
|
|
<localCallId>25160047719:0</localCallId>
|
|
</localCallId>
|
|
</basicModule>
|
|
</cdrData>
|
|
</broadWorksCDR>
|
|
`
|
|
file.Write([]byte(xmlData))
|
|
file.Close()
|
|
eR := &XMLFileER{
|
|
cgrCfg: cfg,
|
|
cfgIdx: 0,
|
|
fltrS: fltrs,
|
|
sourceDir: filePath,
|
|
rdrEvents: make(chan *erEvent, 1),
|
|
rdrError: make(chan error, 1),
|
|
rdrExit: make(chan struct{}),
|
|
conReqs: make(chan struct{}, 1),
|
|
}
|
|
|
|
//or set the default Fields of cfg.ERsCfg().Readers[0].Fields
|
|
eR.Config().Fields = []*config.FCTemplate{
|
|
{
|
|
Tag: "OriginID",
|
|
Type: utils.MetaConstant,
|
|
Path: "*cgreq.OriginID",
|
|
Value: config.NewRSRParsersMustCompile("25160047719:0", utils.InfieldSep),
|
|
Mandatory: true,
|
|
},
|
|
}
|
|
|
|
eR.Config().Fields[0].ComputePath()
|
|
|
|
fileName := "file1.xml"
|
|
if err := eR.processFile(fileName); err != nil {
|
|
t.Error(err)
|
|
}
|
|
expEvent := &utils.CGREvent{
|
|
Tenant: "cgrates.org",
|
|
Event: map[string]any{
|
|
"OriginID": "25160047719:0",
|
|
},
|
|
APIOpts: make(map[string]any),
|
|
}
|
|
select {
|
|
case data := <-eR.rdrEvents:
|
|
expEvent.ID = data.cgrEvent.ID
|
|
expEvent.Time = data.cgrEvent.Time
|
|
if !reflect.DeepEqual(data.cgrEvent, expEvent) {
|
|
t.Errorf("Expected %v but received %v", utils.ToJSON(expEvent), utils.ToJSON(data.cgrEvent))
|
|
}
|
|
case <-time.After(50 * time.Millisecond):
|
|
t.Error("Time limit exceeded")
|
|
}
|
|
if err := os.RemoveAll(filePath); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFileXMLProcessEventError1(t *testing.T) {
|
|
cfg := config.NewDefaultCGRConfig()
|
|
fltrs := &engine.FilterS{}
|
|
filePath := "/tmp/TestFileXMLProcessEvent/"
|
|
fname := "file1.xml"
|
|
eR := &XMLFileER{
|
|
cgrCfg: cfg,
|
|
cfgIdx: 0,
|
|
fltrS: fltrs,
|
|
sourceDir: filePath,
|
|
rdrEvents: make(chan *erEvent, 1),
|
|
rdrError: make(chan error, 1),
|
|
rdrExit: make(chan struct{}),
|
|
conReqs: make(chan struct{}, 1),
|
|
}
|
|
errExpect := "open /tmp/TestFileXMLProcessEvent/file1.xml: no such file or directory"
|
|
if err := eR.processFile(fname); err == nil || err.Error() != errExpect {
|
|
t.Errorf("Expected %v but received %v", errExpect, err)
|
|
}
|
|
}
|
|
|
|
func TestFileXMLProcessEVentError2(t *testing.T) {
|
|
cfg := config.NewDefaultCGRConfig()
|
|
cfg.ERsCfg().Readers[0].Fields = []*config.FCTemplate{}
|
|
data, err := engine.NewInternalDB(nil, nil, true, nil, cfg.DataDbCfg().Items)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
dm := engine.NewDataManager(data, cfg.CacheCfg(), nil)
|
|
fltrs := engine.NewFilterS(cfg, nil, dm)
|
|
filePath := "/tmp/TestFileXMLProcessEvent/"
|
|
fname := "file1.xml"
|
|
if err := os.MkdirAll(filePath, 0777); err != nil {
|
|
t.Error(err)
|
|
}
|
|
file, err := os.Create(path.Join(filePath, "file1.xml"))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
xmlData := `<?xml version="1.0" encoding="ISO-8859-1"?>
|
|
<!DOCTYPE broadWorksCDR>
|
|
<broadWorksCDR version="19.0">
|
|
<cdrData>
|
|
<basicModule>
|
|
<localCallId>
|
|
<localCallId>25160047719:0</localCallId>
|
|
</localCallId>
|
|
</basicModule>
|
|
</cdrData>
|
|
</broadWorksCDR>
|
|
`
|
|
file.Write([]byte(xmlData))
|
|
file.Close()
|
|
eR := &XMLFileER{
|
|
cgrCfg: cfg,
|
|
cfgIdx: 0,
|
|
fltrS: fltrs,
|
|
sourceDir: filePath,
|
|
rdrEvents: make(chan *erEvent, 1),
|
|
rdrError: make(chan error, 1),
|
|
rdrExit: make(chan struct{}),
|
|
conReqs: make(chan struct{}, 1),
|
|
}
|
|
|
|
eR.Config().Tenant = config.RSRParsers{
|
|
{
|
|
Rules: "test",
|
|
},
|
|
}
|
|
|
|
//
|
|
eR.Config().Filters = []string{"Filter1"}
|
|
errExpect := "NOT_FOUND:Filter1"
|
|
if err := eR.processFile(fname); err == nil || err.Error() != errExpect {
|
|
t.Errorf("Expected %v but received %v", errExpect, err)
|
|
}
|
|
|
|
//
|
|
eR.Config().Filters = []string{"*exists:~*req..Account:"}
|
|
errExpect = "rename /tmp/TestFileXMLProcessEvent/file1.xml /var/spool/cgrates/ers/out/file1.xml: no such file or directory"
|
|
if err := eR.processFile(fname); err == nil || err.Error() != errExpect {
|
|
t.Errorf("Expected %v but received %v", errExpect, err)
|
|
}
|
|
if err := os.RemoveAll(filePath); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFileXMLProcessEventParseError(t *testing.T) {
|
|
cfg := config.NewDefaultCGRConfig()
|
|
cfg.ERsCfg().Readers[0].ProcessedPath = ""
|
|
fltrs := &engine.FilterS{}
|
|
filePath := "/tmp/TestFileXMLProcessEvent/"
|
|
if err := os.MkdirAll(filePath, 0777); err != nil {
|
|
t.Error(err)
|
|
}
|
|
file, err := os.Create(path.Join(filePath, "file1.xml"))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
file.Write([]byte(`
|
|
<XMLField>test/XMLField>`))
|
|
file.Close()
|
|
eR := &XMLFileER{
|
|
cgrCfg: cfg,
|
|
cfgIdx: 0,
|
|
fltrS: fltrs,
|
|
sourceDir: filePath,
|
|
rdrEvents: make(chan *erEvent, 1),
|
|
rdrError: make(chan error, 1),
|
|
rdrExit: make(chan struct{}),
|
|
conReqs: make(chan struct{}, 1),
|
|
}
|
|
|
|
fileName := "file1.xml"
|
|
errExpect := "XML syntax error on line 2: unexpected EOF"
|
|
if err := eR.processFile(fileName); err == nil || err.Error() != errExpect {
|
|
t.Errorf("Expected %v but received %v", errExpect, err)
|
|
}
|
|
if err := os.RemoveAll(filePath); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFileXML(t *testing.T) {
|
|
cfg := config.NewDefaultCGRConfig()
|
|
fltrs := &engine.FilterS{}
|
|
eR := &XMLFileER{
|
|
cgrCfg: cfg,
|
|
cfgIdx: 0,
|
|
fltrS: fltrs,
|
|
sourceDir: "/tmp/xmlErs/out",
|
|
rdrEvents: make(chan *erEvent, 1),
|
|
rdrError: make(chan error, 1),
|
|
rdrExit: make(chan struct{}),
|
|
}
|
|
err := os.MkdirAll(eR.sourceDir, 0777)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
eR.Config().Fields = []*config.FCTemplate{
|
|
{
|
|
Tag: "OriginID",
|
|
Type: utils.MetaConstant,
|
|
Path: "*cgreq.OriginID",
|
|
Value: config.NewRSRParsersMustCompile("25160047719:0", utils.InfieldSep),
|
|
Mandatory: true,
|
|
},
|
|
}
|
|
|
|
eR.Config().Fields[0].ComputePath()
|
|
|
|
for i := 1; i < 4; i++ {
|
|
if _, err := os.Create(path.Join(eR.sourceDir, fmt.Sprintf("file%d.xml", i))); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
eR.Config().RunDelay = time.Duration(-1)
|
|
if err := eR.Serve(); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
eR.Config().RunDelay = 1 * time.Millisecond
|
|
if err := eR.Serve(); err != nil {
|
|
t.Error(err)
|
|
}
|
|
os.Create(path.Join(eR.sourceDir, "file1.txt"))
|
|
eR.Config().RunDelay = 1 * time.Millisecond
|
|
if err := eR.Serve(); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFileXMLError(t *testing.T) {
|
|
cfg := config.NewDefaultCGRConfig()
|
|
fltrs := &engine.FilterS{}
|
|
eR := &XMLFileER{
|
|
cgrCfg: cfg,
|
|
cfgIdx: 0,
|
|
fltrS: fltrs,
|
|
sourceDir: "/tmp/xmlErsError/out",
|
|
rdrEvents: make(chan *erEvent, 1),
|
|
rdrError: make(chan error, 1),
|
|
rdrExit: make(chan struct{}),
|
|
}
|
|
err := os.MkdirAll(eR.sourceDir, 0777)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
eR.Config().Fields = []*config.FCTemplate{
|
|
{
|
|
Tag: "OriginID",
|
|
Type: utils.MetaConstant,
|
|
Path: "*cgreq.OriginID",
|
|
Value: config.NewRSRParsersMustCompile("25160047719:0", utils.InfieldSep),
|
|
Mandatory: true,
|
|
},
|
|
}
|
|
|
|
eR.Config().Fields[0].ComputePath()
|
|
|
|
for i := 1; i < 4; i++ {
|
|
if _, err := os.Create(path.Join(eR.sourceDir, fmt.Sprintf("file%d.xml", i))); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
os.Create(path.Join(eR.sourceDir, "file1.txt"))
|
|
eR.Config().RunDelay = 1 * time.Millisecond
|
|
if err := eR.Serve(); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFileXMLExit(t *testing.T) {
|
|
cfg := config.NewDefaultCGRConfig()
|
|
fltrs := &engine.FilterS{}
|
|
eR := &XMLFileER{
|
|
cgrCfg: cfg,
|
|
cfgIdx: 0,
|
|
fltrS: fltrs,
|
|
sourceDir: "/tmp/xmlErs/out",
|
|
rdrEvents: make(chan *erEvent, 1),
|
|
rdrError: make(chan error, 1),
|
|
rdrExit: make(chan struct{}),
|
|
}
|
|
eR.Config().RunDelay = 1 * time.Millisecond
|
|
if err := eR.Serve(); err != nil {
|
|
t.Error(err)
|
|
}
|
|
eR.rdrExit <- struct{}{}
|
|
}
|