mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Integration and unit tests in loaders for coverage
This commit is contained in:
committed by
Dan Christian Bogos
parent
1ccd14d18a
commit
2fc6c62c6c
@@ -19,12 +19,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package loaders
|
||||
|
||||
import (
|
||||
"encoding/csv"
|
||||
"errors"
|
||||
"flag"
|
||||
"io/ioutil"
|
||||
"net/rpc"
|
||||
"net/rpc/jsonrpc"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/cgrates/rpcclient"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
@@ -49,3 +56,91 @@ func newRPCClient(cfg *config.ListenCfg) (c *rpc.Client, err error) {
|
||||
return nil, errors.New("UNSUPPORTED_RPC")
|
||||
}
|
||||
}
|
||||
|
||||
type testMockCacheConn struct {
|
||||
calls map[string]func(arg interface{}, rply interface{}) error
|
||||
}
|
||||
|
||||
func (s *testMockCacheConn) Call(method string, arg interface{}, rply interface{}) error {
|
||||
if call, has := s.calls[method]; !has {
|
||||
return rpcclient.ErrUnsupporteServiceMethod
|
||||
} else {
|
||||
return call(arg, rply)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessContentCalls(t *testing.T) {
|
||||
sMock := &testMockCacheConn{
|
||||
calls: map[string]func(arg interface{}, rply interface{}) error{
|
||||
utils.CacheSv1ReloadCache: func(arg interface{}, rply interface{}) error {
|
||||
prply, can := rply.(*string)
|
||||
if !can {
|
||||
t.Errorf("Wrong argument type : %T", rply)
|
||||
return nil
|
||||
}
|
||||
*prply = utils.OK
|
||||
return nil
|
||||
},
|
||||
utils.CacheSv1Clear: func(arg interface{}, rply interface{}) error {
|
||||
prply, can := rply.(*string)
|
||||
if !can {
|
||||
t.Errorf("Wrong argument type : %T", rply)
|
||||
return nil
|
||||
}
|
||||
*prply = utils.OK
|
||||
return nil
|
||||
},
|
||||
},
|
||||
}
|
||||
data := engine.NewInternalDB(nil, nil, true)
|
||||
|
||||
internalCacheSChan := make(chan rpcclient.ClientConnector, 1)
|
||||
internalCacheSChan <- sMock
|
||||
ldr := &Loader{
|
||||
ldrID: "TestProcessContentCalls",
|
||||
bufLoaderData: make(map[string][]LoaderData),
|
||||
connMgr: engine.NewConnManager(config.CgrConfig(), map[string]chan rpcclient.ClientConnector{
|
||||
utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches): internalCacheSChan,
|
||||
}),
|
||||
dm: engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil),
|
||||
cacheConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches)},
|
||||
timezone: "UTC",
|
||||
}
|
||||
ldr.dataTpls = map[string][]*config.FCTemplate{
|
||||
utils.MetaRateProfiles: {
|
||||
{Tag: "TenantID",
|
||||
Path: "Tenant",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~*req.0", utils.INFIELD_SEP),
|
||||
Mandatory: true},
|
||||
{Tag: "ProfileID",
|
||||
Path: "ID",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~*req.1", utils.INFIELD_SEP),
|
||||
Mandatory: true},
|
||||
{Tag: "Weight",
|
||||
Path: "Weight",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~*req.2", utils.INFIELD_SEP)},
|
||||
},
|
||||
}
|
||||
thresholdsCsv := `
|
||||
#Tenant[0],ID[1],Weight[2]
|
||||
cgrates.org,MOCK_RELOAD_ID,20
|
||||
`
|
||||
rdr := ioutil.NopCloser(strings.NewReader(thresholdsCsv))
|
||||
rdrCsv := csv.NewReader(rdr)
|
||||
rdrCsv.Comment = '#'
|
||||
ldr.rdrs = map[string]map[string]*openedCSVFile{
|
||||
utils.MetaRateProfiles: {
|
||||
utils.RateProfilesCsv: &openedCSVFile{
|
||||
fileName: utils.RateProfilesCsv,
|
||||
rdr: rdr,
|
||||
csvRdr: rdrCsv,
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := ldr.processContent(utils.MetaRateProfiles, utils.MetaReload); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,12 +20,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package loaders
|
||||
|
||||
import (
|
||||
"encoding/csv"
|
||||
"io/ioutil"
|
||||
"net/rpc"
|
||||
"os"
|
||||
"path"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -48,6 +50,9 @@ var (
|
||||
testLoaderStartEngine,
|
||||
testLoaderRPCConn,
|
||||
testLoaderPopulateData,
|
||||
testLoadFromFilesCsvActionProfile,
|
||||
testLoadFromFilesCsvActionProfileOpenError,
|
||||
testLoadFromFilesCsvActionProfileLockFolderError,
|
||||
testLoaderLoadAttributes,
|
||||
testLoaderVerifyOutDir,
|
||||
testLoaderCheckAttributes,
|
||||
@@ -399,3 +404,150 @@ func testLoaderVerifyOutDirForCustomSep(t *testing.T) {
|
||||
t.Errorf("Expecting: %q, received: %q", customAttributes, string(outContent1))
|
||||
}
|
||||
}
|
||||
|
||||
func testLoadFromFilesCsvActionProfile(t *testing.T) {
|
||||
flPath := "/tmp/TestLoadFromFilesCsvActionProfile"
|
||||
if err := os.MkdirAll(flPath, 0777); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
newFile, err := os.Create(path.Join(flPath, "ActionProfiles.csv"))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
newFile.Write([]byte(`
|
||||
#Tenant[0],ID[1]
|
||||
cgrates.org,SET_ACTPROFILE_3
|
||||
`))
|
||||
content, err := ioutil.ReadFile(path.Join(flPath, "ActionProfiles.csv"))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
newFile.Close()
|
||||
|
||||
data := engine.NewInternalDB(nil, nil, true)
|
||||
ldr := &Loader{
|
||||
ldrID: "TestRemoveActionProfileContent",
|
||||
bufLoaderData: make(map[string][]LoaderData),
|
||||
dm: engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil),
|
||||
tpInDir: flPath,
|
||||
tpOutDir: utils.EmptyString,
|
||||
lockFilename: "ActionProfiles.csv",
|
||||
fieldSep: ",",
|
||||
timezone: "UTC",
|
||||
}
|
||||
ldr.dataTpls = map[string][]*config.FCTemplate{
|
||||
utils.MetaActionProfiles: {
|
||||
{Tag: "TenantID",
|
||||
Path: "Tenant",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~*req.0", utils.INFIELD_SEP),
|
||||
Mandatory: true},
|
||||
{Tag: "ProfileID",
|
||||
Path: "ID",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~*req.1", utils.INFIELD_SEP),
|
||||
Mandatory: true},
|
||||
},
|
||||
}
|
||||
|
||||
rdr := ioutil.NopCloser(strings.NewReader(string(content)))
|
||||
csvRdr := csv.NewReader(rdr)
|
||||
csvRdr.Comment = '#'
|
||||
ldr.rdrs = map[string]map[string]*openedCSVFile{
|
||||
utils.MetaActionProfiles: {
|
||||
utils.ActionProfilesCsv: &openedCSVFile{
|
||||
fileName: utils.ActionProfilesCsv,
|
||||
rdr: rdr,
|
||||
csvRdr: csvRdr,
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := ldr.ProcessFolder(utils.EmptyString, utils.MetaStore, true); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
expACtPrf := &engine.ActionProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "SET_ACTPROFILE_3",
|
||||
FilterIDs: []string{},
|
||||
Targets: map[string]utils.StringSet{},
|
||||
Actions: []*engine.APAction{},
|
||||
}
|
||||
if rcv, err := ldr.dm.GetActionProfile(expACtPrf.Tenant, expACtPrf.ID,
|
||||
true, true, utils.NonTransactional); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(expACtPrf, rcv) {
|
||||
t.Errorf("Expected %+v, received %+v", utils.ToJSON(expACtPrf), utils.ToJSON(rcv))
|
||||
}
|
||||
|
||||
//checking the error by adding a caching method
|
||||
ldr.connMgr = engine.NewConnManager(config.NewDefaultCGRConfig(), nil)
|
||||
ldr.cacheConns = []string{utils.MetaInternal}
|
||||
rdr = ioutil.NopCloser(strings.NewReader(string(content)))
|
||||
csvRdr = csv.NewReader(rdr)
|
||||
csvRdr.Comment = '#'
|
||||
ldr.rdrs = map[string]map[string]*openedCSVFile{
|
||||
utils.MetaActionProfiles: {
|
||||
utils.ActionProfilesCsv: &openedCSVFile{
|
||||
fileName: utils.ActionProfilesCsv,
|
||||
rdr: rdr,
|
||||
csvRdr: csvRdr,
|
||||
},
|
||||
},
|
||||
}
|
||||
expected := "UNSUPPORTED_SERVICE_METHOD"
|
||||
if err := ldr.ProcessFolder(utils.MetaReload, utils.MetaStore, true); err == nil || err.Error() != expected {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if err = os.RemoveAll(flPath); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func testLoadFromFilesCsvActionProfileOpenError(t *testing.T) {
|
||||
data := engine.NewInternalDB(nil, nil, true)
|
||||
ldr := &Loader{
|
||||
ldrID: "TestRemoveActionProfileContent",
|
||||
bufLoaderData: make(map[string][]LoaderData),
|
||||
dm: engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil),
|
||||
tpInDir: "/tmp/testLoadFromFilesCsvActionProfileOpenError",
|
||||
timezone: "UTC",
|
||||
}
|
||||
ldr.rdrs = map[string]map[string]*openedCSVFile{
|
||||
utils.MetaActionProfiles: {
|
||||
utils.ActionProfilesCsv: &openedCSVFile{
|
||||
fileName: utils.ActionProfilesCsv,
|
||||
},
|
||||
},
|
||||
}
|
||||
expectedErr := "open /tmp/testLoadFromFilesCsvActionProfileOpenError/ActionProfiles.csv: not a directory"
|
||||
if err := ldr.ProcessFolder(utils.EmptyString, utils.MetaStore, true); err == nil || err.Error() != expectedErr {
|
||||
t.Errorf("Expected %+v, received %+v", expectedErr, err)
|
||||
}
|
||||
|
||||
//if stopOnError is on true, the error is avoided,but instead will get a logger.warning message
|
||||
if err := ldr.ProcessFolder(utils.EmptyString, utils.MetaStore, false); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func testLoadFromFilesCsvActionProfileLockFolderError(t *testing.T) {
|
||||
data := engine.NewInternalDB(nil, nil, true)
|
||||
ldr := &Loader{
|
||||
ldrID: "TestRemoveActionProfileContent",
|
||||
bufLoaderData: make(map[string][]LoaderData),
|
||||
dm: engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil),
|
||||
timezone: "UTC",
|
||||
}
|
||||
ldr.rdrs = map[string]map[string]*openedCSVFile{
|
||||
utils.MetaActionProfiles: {
|
||||
utils.ActionProfilesCsv: &openedCSVFile{
|
||||
fileName: utils.ActionProfilesCsv,
|
||||
},
|
||||
},
|
||||
}
|
||||
expectedErr := "open : no such file or directory"
|
||||
if err := ldr.ProcessFolder(utils.EmptyString, utils.MetaStore, true); err == nil || err.Error() != expectedErr {
|
||||
t.Errorf("Expected %+v, received %+v", expectedErr, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4088,3 +4088,107 @@ cgrates.org,REM_ACTPROFILE_1
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveContentError1(t *testing.T) {
|
||||
//use actionProfile to generate an error by giving a wrong csv
|
||||
data := engine.NewInternalDB(nil, nil, true)
|
||||
ldr := &Loader{
|
||||
ldrID: "TestRemoveActionProfileContent",
|
||||
bufLoaderData: make(map[string][]LoaderData),
|
||||
dm: engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil),
|
||||
timezone: "UTC",
|
||||
}
|
||||
ldr.dataTpls = map[string][]*config.FCTemplate{
|
||||
utils.MetaActionProfiles: {
|
||||
{Tag: "TenantID",
|
||||
Path: "Tenant",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~*req.0", utils.INFIELD_SEP),
|
||||
Mandatory: true},
|
||||
{Tag: "ProfileID",
|
||||
Path: "ID",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~*req.1", utils.INFIELD_SEP),
|
||||
Mandatory: true},
|
||||
},
|
||||
}
|
||||
//wrong start at the beginning of csv
|
||||
actPrfCsv := `
|
||||
//Tenant[0]
|
||||
cgrates.org,REM_ACTPROFILE_s
|
||||
`
|
||||
rdr := ioutil.NopCloser(strings.NewReader(actPrfCsv))
|
||||
csvRdr := csv.NewReader(rdr)
|
||||
csvRdr.Comment = '#'
|
||||
ldr.rdrs = map[string]map[string]*openedCSVFile{
|
||||
utils.MetaActionProfiles: {
|
||||
utils.ActionProfilesCsv: &openedCSVFile{
|
||||
fileName: utils.ActionProfilesCsv,
|
||||
rdr: rdr,
|
||||
csvRdr: csvRdr,
|
||||
},
|
||||
},
|
||||
}
|
||||
actRtPrf := &engine.ActionProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "REM_ACTPROFILE_s",
|
||||
}
|
||||
expectedErr := "NOT_FOUND"
|
||||
if err := ldr.dm.SetActionProfile(actRtPrf, true); err != nil {
|
||||
t.Error(err)
|
||||
} else if err := ldr.removeContent(utils.MetaActionProfiles, utils.EmptyString); err == nil || err.Error() != expectedErr {
|
||||
t.Errorf("Expected %+v, received %+v", expectedErr, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveContentError2(t *testing.T) {
|
||||
//use actionProfile to generate an error by giving a wrong csv
|
||||
data := engine.NewInternalDB(nil, nil, true)
|
||||
ldr := &Loader{
|
||||
ldrID: "TestRemoveActionProfileContent",
|
||||
bufLoaderData: make(map[string][]LoaderData),
|
||||
dm: engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil),
|
||||
timezone: "UTC",
|
||||
}
|
||||
ldr.dataTpls = map[string][]*config.FCTemplate{
|
||||
utils.MetaActionProfiles: {
|
||||
{Tag: "TenantID",
|
||||
Path: "Tenant",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~*req.0", utils.INFIELD_SEP),
|
||||
Mandatory: true},
|
||||
{Tag: "ProfileID",
|
||||
Path: "ID",
|
||||
Type: utils.META_COMPOSED,
|
||||
Value: config.NewRSRParsersMustCompile("~*req.1", utils.INFIELD_SEP),
|
||||
Mandatory: true},
|
||||
},
|
||||
}
|
||||
//wrong start at the beginning of csv
|
||||
actPrfCsv := `
|
||||
Tenant[0],ID[1]
|
||||
cgrates.org,REM_ACTPROFILE_s
|
||||
`
|
||||
rdr := ioutil.NopCloser(strings.NewReader(actPrfCsv))
|
||||
csvRdr := csv.NewReader(rdr)
|
||||
csvRdr.Comment = '#'
|
||||
ldr.rdrs = map[string]map[string]*openedCSVFile{
|
||||
utils.MetaActionProfiles: {
|
||||
utils.ActionProfilesCsv: &openedCSVFile{
|
||||
fileName: utils.ActionProfilesCsv,
|
||||
rdr: rdr,
|
||||
csvRdr: csvRdr,
|
||||
},
|
||||
},
|
||||
}
|
||||
actRtPrf := &engine.ActionProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "REM_ACTPROFILE_s",
|
||||
}
|
||||
expectedErr := "NOT_FOUND"
|
||||
if err := ldr.dm.SetActionProfile(actRtPrf, true); err != nil {
|
||||
t.Error(err)
|
||||
} else if err := ldr.removeContent(utils.MetaActionProfiles, utils.EmptyString); err == nil || err.Error() != expectedErr {
|
||||
t.Errorf("Expected %+v, received %+v", expectedErr, err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user