Integration and unit tests in loaders for coverage

This commit is contained in:
porosnicuadrian
2020-12-17 17:57:46 +02:00
committed by Dan Christian Bogos
parent 1ccd14d18a
commit 2fc6c62c6c
3 changed files with 351 additions and 0 deletions

View File

@@ -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)
}
}

View File

@@ -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)
}
}

View File

@@ -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)
}
}