Merge pull request #1788 from adragusin/master

Updated tests in ConfigSanity
This commit is contained in:
Dan Christian Bogos
2019-11-29 09:55:14 +01:00
committed by GitHub
4 changed files with 1133 additions and 560 deletions

View File

@@ -300,423 +300,6 @@ var posibleLoaderTypes = utils.NewStringSet([]string{utils.MetaAttributes,
var possibleReaderTypes = utils.NewStringSet([]string{utils.MetaFileCSV, utils.MetaKafkajsonMap})
func (cfg *CGRConfig) checkConfigSanity() error {
// Rater checks
if cfg.ralsCfg.Enabled && !cfg.dispatcherSCfg.Enabled {
if !cfg.statsCfg.Enabled {
for _, connCfg := range cfg.ralsCfg.StatSConns {
if connCfg.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but requested by <%s> component.",
utils.StatS, utils.RALService)
}
}
}
if !cfg.thresholdSCfg.Enabled {
for _, connCfg := range cfg.ralsCfg.ThresholdSConns {
if connCfg.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but requested by <%s> component.",
utils.ThresholdS, utils.RALService)
}
}
}
}
// CDRServer checks
if cfg.cdrsCfg.Enabled && !cfg.dispatcherSCfg.Enabled {
if !cfg.chargerSCfg.Enabled {
for _, conn := range cfg.cdrsCfg.ChargerSConns {
if conn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but requested by <%s> component.", utils.Chargers, utils.CDRs)
}
}
}
if !cfg.ralsCfg.Enabled {
for _, cdrsRaterConn := range cfg.cdrsCfg.RaterConns {
if cdrsRaterConn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but requested by <%s> component.", utils.RALService, utils.CDRs)
}
}
}
if !cfg.attributeSCfg.Enabled {
for _, connCfg := range cfg.cdrsCfg.AttributeSConns {
if connCfg.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but requested by <%s> component.", utils.AttributeS, utils.CDRs)
}
}
}
if !cfg.statsCfg.Enabled {
for _, connCfg := range cfg.cdrsCfg.StatSConns {
if connCfg.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but requested by <%s> component.", utils.StatService, utils.CDRs)
}
}
}
for _, cdrePrfl := range cfg.cdrsCfg.OnlineCDRExports {
if _, hasIt := cfg.CdreProfiles[cdrePrfl]; !hasIt {
return fmt.Errorf("<%s> Cannot find CDR export template with ID: <%s>", utils.CDRs, cdrePrfl)
}
}
if !cfg.thresholdSCfg.Enabled {
for _, connCfg := range cfg.cdrsCfg.ThresholdSConns {
if connCfg.Address == utils.MetaInternal {
return fmt.Errorf("%s not enabled but requested by %s component.", utils.ThresholdS, utils.CDRs)
}
}
}
}
// CDRC sanity checks
for _, cdrcCfgs := range cfg.CdrcProfiles {
for _, cdrcInst := range cdrcCfgs {
if !cdrcInst.Enabled {
continue
}
if len(cdrcInst.CdrsConns) == 0 {
return fmt.Errorf("<%s> Instance: %s, %s enabled but no %s defined!", utils.CDRC, cdrcInst.ID, utils.CDRC, utils.CDRs)
}
if !cfg.cdrsCfg.Enabled && !cfg.dispatcherSCfg.Enabled {
for _, conn := range cdrcInst.CdrsConns {
if conn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but referenced from <%s>", utils.CDRs, utils.CDRC)
}
}
}
if len(cdrcInst.ContentFields) == 0 {
return fmt.Errorf("<%s> enabled but no fields to be processed defined!", utils.CDRC)
}
}
}
// Loaders sanity checks
for _, ldrSCfg := range cfg.loaderCfg {
if !ldrSCfg.Enabled {
continue
}
for _, dir := range []string{ldrSCfg.TpInDir, ldrSCfg.TpOutDir} {
if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
return fmt.Errorf("<%s> Nonexistent folder: %s", utils.LoaderS, dir)
}
}
for _, data := range ldrSCfg.Data {
if !posibleLoaderTypes.Has(data.Type) {
return fmt.Errorf("<%s> unsupported data type %s", utils.LoaderS, data.Type)
}
for _, field := range data.Fields {
if field.Type != utils.META_COMPOSED && field.Type != utils.MetaString && field.Type != utils.MetaVariable {
return fmt.Errorf("<%s> invalid field type %s for %s at %s", utils.LoaderS, field.Type, data.Type, field.Tag)
}
}
}
}
// SessionS checks
if cfg.sessionSCfg.Enabled && !cfg.dispatcherSCfg.Enabled {
if cfg.sessionSCfg.TerminateAttempts < 1 {
return fmt.Errorf("<%s> 'terminate_attempts' should be at least 1", utils.SessionS)
}
if !cfg.chargerSCfg.Enabled {
for _, conn := range cfg.sessionSCfg.ChargerSConns {
if conn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> %s not enabled", utils.SessionS, utils.ChargerS)
}
}
}
if !cfg.ralsCfg.Enabled {
for _, smgRALsConn := range cfg.sessionSCfg.RALsConns {
if smgRALsConn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> %s not enabled but requested by SMGeneric component.", utils.SessionS, utils.RALService)
}
}
}
if !cfg.resourceSCfg.Enabled {
for _, conn := range cfg.sessionSCfg.ResSConns {
if conn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> %s not enabled but requested by SMGeneric component.", utils.SessionS, utils.ResourceS)
}
}
}
if !cfg.thresholdSCfg.Enabled {
for _, conn := range cfg.sessionSCfg.ThreshSConns {
if conn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> %s not enabled but requested by SMGeneric component.", utils.SessionS, utils.ThresholdS)
}
}
}
if !cfg.statsCfg.Enabled {
for _, conn := range cfg.sessionSCfg.StatSConns {
if conn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> %s not enabled but requested by SMGeneric component.", utils.SessionS, utils.StatS)
}
}
}
if !cfg.supplierSCfg.Enabled {
for _, conn := range cfg.sessionSCfg.SupplSConns {
if conn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> %s not enabled but requested by SMGeneric component.", utils.SessionS, utils.SupplierS)
}
}
}
if !cfg.attributeSCfg.Enabled {
for _, conn := range cfg.sessionSCfg.AttrSConns {
if conn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> %s not enabled but requested by SMGeneric component.", utils.SessionS, utils.AttributeS)
}
}
}
if !cfg.cdrsCfg.Enabled {
for _, smgCDRSConn := range cfg.sessionSCfg.CDRsConns {
if smgCDRSConn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> CDRS not enabled but referenced by SMGeneric component", utils.SessionS)
}
}
}
if cfg.cacheCfg[utils.CacheClosedSessions].Limit == 0 {
return fmt.Errorf("<%s> %s needs to be != 0, received: %d", utils.CacheS, utils.CacheClosedSessions, cfg.cacheCfg[utils.CacheClosedSessions].Limit)
}
}
// FreeSWITCHAgent checks
if cfg.fsAgentCfg.Enabled {
if len(cfg.fsAgentCfg.SessionSConns) == 0 {
return fmt.Errorf("<%s> no %s connections defined",
utils.FreeSWITCHAgent, utils.SessionS)
}
if !cfg.dispatcherSCfg.Enabled && // if dispatcher is enabled all internal connections are managed by it
!cfg.sessionSCfg.Enabled {
for _, connCfg := range cfg.fsAgentCfg.SessionSConns {
if connCfg.Address == utils.MetaInternal {
return fmt.Errorf("%s not enabled but referenced by %s",
utils.SessionS, utils.FreeSWITCHAgent)
}
}
}
}
// KamailioAgent checks
if cfg.kamAgentCfg.Enabled {
if len(cfg.kamAgentCfg.SessionSConns) == 0 {
return fmt.Errorf("<%s> no %s connections defined",
utils.KamailioAgent, utils.SessionS)
}
if !cfg.dispatcherSCfg.Enabled && // if dispatcher is enabled all internal connections are managed by it
!cfg.sessionSCfg.Enabled {
for _, connCfg := range cfg.kamAgentCfg.SessionSConns {
if connCfg.Address == utils.MetaInternal {
return fmt.Errorf("%s not enabled but referenced by %s",
utils.SessionS, utils.KamailioAgent)
}
}
}
}
// AsteriskAgent checks
if cfg.asteriskAgentCfg.Enabled {
if len(cfg.asteriskAgentCfg.SessionSConns) == 0 {
return fmt.Errorf("<%s> no %s connections defined",
utils.AsteriskAgent, utils.SessionS)
}
if !cfg.dispatcherSCfg.Enabled && // if dispatcher is enabled all internal connections are managed by it
!cfg.sessionSCfg.Enabled {
for _, smAstSMGConn := range cfg.asteriskAgentCfg.SessionSConns {
if smAstSMGConn.Address == utils.MetaInternal {
return fmt.Errorf("%s not enabled but referenced by %s",
utils.SessionS, utils.AsteriskAgent)
}
}
}
}
// DAgent checks
if cfg.diameterAgentCfg.Enabled {
if len(cfg.diameterAgentCfg.SessionSConns) == 0 {
return fmt.Errorf("<%s> no %s connections defined",
utils.DiameterAgent, utils.SessionS)
}
if !cfg.dispatcherSCfg.Enabled && // if dispatcher is enabled all internal connections are managed by it
!cfg.sessionSCfg.Enabled {
for _, daSMGConn := range cfg.diameterAgentCfg.SessionSConns {
if daSMGConn.Address == utils.MetaInternal {
return fmt.Errorf("%s not enabled but referenced by %s",
utils.SessionS, utils.DiameterAgent)
}
}
}
}
if cfg.radiusAgentCfg.Enabled {
if len(cfg.radiusAgentCfg.SessionSConns) == 0 {
return fmt.Errorf("<%s> no %s connections defined",
utils.RadiusAgent, utils.SessionS)
}
if !cfg.dispatcherSCfg.Enabled && // if dispatcher is enabled all internal connections are managed by it
!cfg.sessionSCfg.Enabled {
for _, raSMGConn := range cfg.radiusAgentCfg.SessionSConns {
if raSMGConn.Address == utils.MetaInternal {
return fmt.Errorf("%s not enabled but referenced by %s",
utils.SessionS, utils.RadiusAgent)
}
}
}
}
if cfg.dnsAgentCfg.Enabled {
if len(cfg.dnsAgentCfg.SessionSConns) == 0 {
return fmt.Errorf("<%s> no %s connections defined",
utils.DNSAgent, utils.SessionS)
}
if !cfg.dispatcherSCfg.Enabled && // if dispatcher is enabled all internal connections are managed by it
!cfg.sessionSCfg.Enabled {
for _, sSConn := range cfg.dnsAgentCfg.SessionSConns {
if sSConn.Address == utils.MetaInternal {
return fmt.Errorf("%s not enabled but referenced by %s", utils.SessionS, utils.DNSAgent)
}
}
}
}
// HTTPAgent checks
for _, httpAgentCfg := range cfg.httpAgentCfg {
// httpAgent checks
if !cfg.dispatcherSCfg.Enabled && // if dispatcher is enabled all internal connections are managed by it
cfg.sessionSCfg.Enabled {
for _, sSConn := range httpAgentCfg.SessionSConns {
if sSConn.Address == utils.MetaInternal {
return errors.New("SessionS not enabled but referenced by HttpAgent component")
}
}
}
if !utils.SliceHasMember([]string{utils.MetaUrl, utils.MetaXml}, httpAgentCfg.RequestPayload) {
return fmt.Errorf("<%s> unsupported request payload %s",
utils.HTTPAgent, httpAgentCfg.RequestPayload)
}
if !utils.SliceHasMember([]string{utils.MetaTextPlain, utils.MetaXml}, httpAgentCfg.ReplyPayload) {
return fmt.Errorf("<%s> unsupported reply payload %s",
utils.HTTPAgent, httpAgentCfg.ReplyPayload)
}
}
if cfg.attributeSCfg.Enabled {
if cfg.attributeSCfg.ProcessRuns < 1 {
return fmt.Errorf("<%s> process_runs needs to be bigger than 0", utils.AttributeS)
}
}
if cfg.chargerSCfg.Enabled && !cfg.dispatcherSCfg.Enabled &&
(cfg.attributeSCfg == nil || !cfg.attributeSCfg.Enabled) {
for _, connCfg := range cfg.chargerSCfg.AttributeSConns {
if connCfg.Address == utils.MetaInternal {
return errors.New("AttributeS not enabled but requested by ChargerS component.")
}
}
}
// ResourceLimiter checks
if cfg.resourceSCfg.Enabled && !cfg.thresholdSCfg.Enabled && !cfg.dispatcherSCfg.Enabled {
for _, connCfg := range cfg.resourceSCfg.ThresholdSConns {
if connCfg.Address == utils.MetaInternal {
return errors.New("ThresholdS not enabled but requested by ResourceS component.")
}
}
}
// StatS checks
if cfg.statsCfg.Enabled && !cfg.thresholdSCfg.Enabled && !cfg.dispatcherSCfg.Enabled {
for _, connCfg := range cfg.statsCfg.ThresholdSConns {
if connCfg.Address == utils.MetaInternal {
return errors.New("ThresholdS not enabled but requested by StatS component.")
}
}
}
// SupplierS checks
if cfg.supplierSCfg.Enabled && !cfg.dispatcherSCfg.Enabled {
if !cfg.resourceSCfg.Enabled {
for _, connCfg := range cfg.supplierSCfg.ResourceSConns {
if connCfg.Address == utils.MetaInternal {
return errors.New("ResourceS not enabled but requested by SupplierS component.")
}
}
}
if !cfg.statsCfg.Enabled {
for _, connCfg := range cfg.supplierSCfg.StatSConns {
if connCfg.Address == utils.MetaInternal {
return errors.New("StatS not enabled but requested by SupplierS component.")
}
}
}
if !cfg.attributeSCfg.Enabled {
for _, connCfg := range cfg.supplierSCfg.AttributeSConns {
if connCfg.Address == utils.MetaInternal {
return errors.New("AttributeS not enabled but requested by SupplierS component.")
}
}
}
}
// Scheduler check connection with CDR Server
if !cfg.cdrsCfg.Enabled && !cfg.dispatcherSCfg.Enabled {
for _, connCfg := range cfg.schedulerCfg.CDRsConns {
if connCfg.Address == utils.MetaInternal {
return errors.New("CDR Server not enabled but requested by Scheduler")
}
}
}
// EventReader sanity checks
if cfg.ersCfg.Enabled {
if !cfg.sessionSCfg.Enabled {
for _, connCfg := range cfg.ersCfg.SessionSConns {
if connCfg.Address == utils.MetaInternal {
return errors.New("SessionS not enabled but requested by EventReader component.")
}
}
}
for _, rdr := range cfg.ersCfg.Readers {
if !possibleReaderTypes.Has(rdr.Type) {
return fmt.Errorf("<%s> unsupported data type: %s for reader with ID: %s", utils.ERs, rdr.Type, rdr.ID)
}
if rdr.Type == utils.MetaFileCSV {
for _, dir := range []string{rdr.ProcessedPath, rdr.SourcePath} {
if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
return fmt.Errorf("<%s> Nonexistent folder: %s for reader with ID: %s", utils.ERs, dir, rdr.ID)
}
}
if rdr.FieldSep == utils.EmptyString {
return fmt.Errorf("<%s> empty FieldSep for reader with ID: %s", utils.ERs, rdr.ID)
}
}
if rdr.Type == utils.MetaKafkajsonMap && rdr.RunDelay > 0 {
return fmt.Errorf("<%s> RunDelay field can not be bigger than zero for reader with ID: %s", utils.ERs, rdr.ID)
}
}
}
// StorDB sanity checks
if cfg.storDbCfg.Type == utils.POSTGRES {
if !utils.IsSliceMember([]string{utils.PostgressSSLModeDisable, utils.PostgressSSLModeAllow,
utils.PostgressSSLModePrefer, utils.PostgressSSLModeRequire, utils.PostgressSSLModeVerifyCa,
utils.PostgressSSLModeVerifyFull}, cfg.storDbCfg.SSLMode) {
return fmt.Errorf("<%s> Unsuported sslmode for storDB", utils.StorDB)
}
}
// DataDB sanity checks
if cfg.dataDbCfg.DataDbType == utils.INTERNAL {
for key, config := range cfg.cacheCfg {
if key == utils.CacheDiameterMessages || key == utils.CacheClosedSessions {
if config.Limit == 0 {
return fmt.Errorf("<%s> %s needs to be != 0 when DataBD is *internal, found 0.", utils.CacheS, key)
}
continue
}
if config.Limit != 0 {
return fmt.Errorf("<%s> %s needs to be 0 when DataBD is *internal, received : %d", utils.CacheS, key, config.Limit)
}
}
if cfg.resourceSCfg.Enabled == true && cfg.resourceSCfg.StoreInterval != -1 {
return fmt.Errorf("<%s> StoreInterval needs to be -1 when DataBD is *internal, received : %d", utils.ResourceS, cfg.resourceSCfg.StoreInterval)
}
if cfg.statsCfg.Enabled == true && cfg.statsCfg.StoreInterval != -1 {
return fmt.Errorf("<%s> StoreInterval needs to be -1 when DataBD is *internal, received : %d", utils.StatS, cfg.statsCfg.StoreInterval)
}
if cfg.thresholdSCfg.Enabled == true && cfg.thresholdSCfg.StoreInterval != -1 {
return fmt.Errorf("<%s> StoreInterval needs to be -1 when DataBD is *internal, received : %d", utils.ThresholdS, cfg.thresholdSCfg.StoreInterval)
}
}
for item, val := range cfg.dataDbCfg.Items {
if val.Remote == true && len(cfg.dataDbCfg.RmtConns) == 0 {
return fmt.Errorf("Remote connections required by: <%s>", item)
}
if val.Replicate == true && len(cfg.dataDbCfg.RplConns) == 0 {
return fmt.Errorf("Replicate connections required by: <%s>", item)
}
}
return nil
}
func (cfg *CGRConfig) LazySanityCheck() {
for _, cdrePrfl := range cfg.cdrsCfg.OnlineCDRExports {
if cdreProfile, hasIt := cfg.CdreProfiles[cdrePrfl]; hasIt && (cdreProfile.ExportFormat == utils.MetaS3jsonMap || cdreProfile.ExportFormat == utils.MetaSQSjsonMap) {

View File

@@ -1910,146 +1910,3 @@ func TestCgrCfgEventReaderDefault(t *testing.T) {
}
}
func TestCheckConfigSanity(t *testing.T) {
// Rater checks
cfg, _ := NewDefaultCGRConfig()
cfg.ralsCfg = &RalsCfg{
Enabled: true,
StatSConns: []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
},
}
expected := "<Stats> not enabled but requested by <RALs> component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.statsCfg.Enabled = true
cfg.ralsCfg.ThresholdSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<ThresholdS> not enabled but requested by <RALs> component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.ralsCfg = &RalsCfg{
Enabled: false,
StatSConns: []*RemoteHost{},
ThresholdSConns: []*RemoteHost{},
}
// CDRServer checks
cfg.thresholdSCfg.Enabled = true
cfg.cdrsCfg = &CdrsCfg{
Enabled: true,
ChargerSConns: []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
},
}
expected = "<Chargers> not enabled but requested by <CDRs> component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.chargerSCfg.Enabled = true
cfg.cdrsCfg.RaterConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<RALs> not enabled but requested by <CDRs> component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.ralsCfg.Enabled = true
cfg.cdrsCfg.AttributeSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<AttributeS> not enabled but requested by <CDRs> component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.statsCfg.Enabled = false
cfg.attributeSCfg.Enabled = true
cfg.cdrsCfg.StatSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<StatS> not enabled but requested by <CDRs> component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.statsCfg.Enabled = true
cfg.cdrsCfg.OnlineCDRExports = []string{"stringy"}
cfg.CdreProfiles = map[string]*CdreCfg{"stringx": &CdreCfg{}}
expected = "<CDRs> Cannot find CDR export template with ID: <stringy>"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.thresholdSCfg.Enabled = false
cfg.cdrsCfg.OnlineCDRExports = []string{"stringx"}
cfg.cdrsCfg.ThresholdSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "ThresholdS not enabled but requested by CDRs component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
// CDRC sanity checks
cfg, _ = NewDefaultCGRConfig()
cfg.CdrcProfiles = map[string][]*CdrcCfg{
"test": []*CdrcCfg{
&CdrcCfg{
Enabled: true,
},
},
}
expected = "<cdrc> Instance: , cdrc enabled but no CDRs defined!"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.dispatcherSCfg.Enabled = false
cfg.CdrcProfiles = map[string][]*CdrcCfg{
"test": []*CdrcCfg{
&CdrcCfg{
Enabled: true,
CdrsConns: []*RemoteHost{
&RemoteHost{Address: utils.MetaInternal},
},
},
},
}
expected = "<CDRs> not enabled but referenced from <cdrc>"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.CdrcProfiles = map[string][]*CdrcCfg{
"test": []*CdrcCfg{
&CdrcCfg{
Enabled: true,
CdrsConns: []*RemoteHost{
&RemoteHost{Address: utils.MetaInternal},
},
ContentFields: []*FCTemplate{},
},
},
}
cfg.cdrsCfg = &CdrsCfg{
Enabled: true,
}
expected = "<cdrc> enabled but no fields to be processed defined!"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
}

443
config/configsanity.go Normal file
View File

@@ -0,0 +1,443 @@
/*
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 config
import (
"fmt"
"os"
"github.com/cgrates/cgrates/utils"
)
func (cfg *CGRConfig) checkConfigSanity() error {
// Rater checks
if cfg.ralsCfg.Enabled && !cfg.dispatcherSCfg.Enabled {
if !cfg.statsCfg.Enabled {
for _, connCfg := range cfg.ralsCfg.StatSConns {
if connCfg.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but requested by <%s> component.",
utils.StatS, utils.RALService)
}
}
}
if !cfg.thresholdSCfg.Enabled {
for _, connCfg := range cfg.ralsCfg.ThresholdSConns {
if connCfg.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but requested by <%s> component.",
utils.ThresholdS, utils.RALService)
}
}
}
}
// CDRServer checks
if cfg.cdrsCfg.Enabled && !cfg.dispatcherSCfg.Enabled {
if !cfg.chargerSCfg.Enabled {
for _, conn := range cfg.cdrsCfg.ChargerSConns {
if conn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but requested by <%s> component.", utils.Chargers, utils.CDRs)
}
}
}
if !cfg.ralsCfg.Enabled {
for _, cdrsRaterConn := range cfg.cdrsCfg.RaterConns {
if cdrsRaterConn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but requested by <%s> component.", utils.RALService, utils.CDRs)
}
}
}
if !cfg.attributeSCfg.Enabled {
for _, connCfg := range cfg.cdrsCfg.AttributeSConns {
if connCfg.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but requested by <%s> component.", utils.AttributeS, utils.CDRs)
}
}
}
if !cfg.statsCfg.Enabled {
for _, connCfg := range cfg.cdrsCfg.StatSConns {
if connCfg.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but requested by <%s> component.", utils.StatService, utils.CDRs)
}
}
}
for _, cdrePrfl := range cfg.cdrsCfg.OnlineCDRExports {
if _, hasIt := cfg.CdreProfiles[cdrePrfl]; !hasIt {
return fmt.Errorf("<%s> Cannot find CDR export template with ID: <%s>", utils.CDRs, cdrePrfl)
}
}
if !cfg.thresholdSCfg.Enabled {
for _, connCfg := range cfg.cdrsCfg.ThresholdSConns {
if connCfg.Address == utils.MetaInternal {
return fmt.Errorf("%s not enabled but requested by %s component.", utils.ThresholdS, utils.CDRs)
}
}
}
}
// CDRC sanity checks
for _, cdrcCfgs := range cfg.CdrcProfiles {
for _, cdrcInst := range cdrcCfgs {
if !cdrcInst.Enabled {
continue
}
if len(cdrcInst.CdrsConns) == 0 {
return fmt.Errorf("<%s> Instance: %s, %s enabled but no %s defined!", utils.CDRC, cdrcInst.ID, utils.CDRC, utils.CDRs)
}
if !cfg.cdrsCfg.Enabled && !cfg.dispatcherSCfg.Enabled {
for _, conn := range cdrcInst.CdrsConns {
if conn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but referenced from <%s>", utils.CDRs, utils.CDRC)
}
}
}
if len(cdrcInst.ContentFields) == 0 {
return fmt.Errorf("<%s> enabled but no fields to be processed defined!", utils.CDRC)
}
}
}
// Loaders sanity checks
for _, ldrSCfg := range cfg.loaderCfg {
if !ldrSCfg.Enabled {
continue
}
for _, dir := range []string{ldrSCfg.TpInDir, ldrSCfg.TpOutDir} {
if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
return fmt.Errorf("<%s> Nonexistent folder: %s", utils.LoaderS, dir)
}
}
for _, data := range ldrSCfg.Data {
if !posibleLoaderTypes.Has(data.Type) {
return fmt.Errorf("<%s> unsupported data type %s", utils.LoaderS, data.Type)
}
for _, field := range data.Fields {
if field.Type != utils.META_COMPOSED && field.Type != utils.MetaString && field.Type != utils.MetaVariable {
return fmt.Errorf("<%s> invalid field type %s for %s at %s", utils.LoaderS, field.Type, data.Type, field.Tag)
}
}
}
}
// SessionS checks
if cfg.sessionSCfg.Enabled && !cfg.dispatcherSCfg.Enabled {
if cfg.sessionSCfg.TerminateAttempts < 1 {
return fmt.Errorf("<%s> 'terminate_attempts' should be at least 1", utils.SessionS)
}
if !cfg.chargerSCfg.Enabled {
for _, conn := range cfg.sessionSCfg.ChargerSConns {
if conn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> %s not enabled", utils.SessionS, utils.ChargerS)
}
}
}
if !cfg.ralsCfg.Enabled {
for _, smgRALsConn := range cfg.sessionSCfg.RALsConns {
if smgRALsConn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> %s not enabled but requested by SMGeneric component.", utils.SessionS, utils.RALService)
}
}
}
if !cfg.resourceSCfg.Enabled {
for _, conn := range cfg.sessionSCfg.ResSConns {
if conn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> %s not enabled but requested by SMGeneric component.", utils.SessionS, utils.ResourceS)
}
}
}
if !cfg.thresholdSCfg.Enabled {
for _, conn := range cfg.sessionSCfg.ThreshSConns {
if conn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> %s not enabled but requested by SMGeneric component.", utils.SessionS, utils.ThresholdS)
}
}
}
if !cfg.statsCfg.Enabled {
for _, conn := range cfg.sessionSCfg.StatSConns {
if conn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> %s not enabled but requested by SMGeneric component.", utils.SessionS, utils.StatS)
}
}
}
if !cfg.supplierSCfg.Enabled {
for _, conn := range cfg.sessionSCfg.SupplSConns {
if conn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> %s not enabled but requested by SMGeneric component.", utils.SessionS, utils.SupplierS)
}
}
}
if !cfg.attributeSCfg.Enabled {
for _, conn := range cfg.sessionSCfg.AttrSConns {
if conn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> %s not enabled but requested by SMGeneric component.", utils.SessionS, utils.AttributeS)
}
}
}
if !cfg.cdrsCfg.Enabled {
for _, smgCDRSConn := range cfg.sessionSCfg.CDRsConns {
if smgCDRSConn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> CDRS not enabled but referenced by SMGeneric component.", utils.SessionS)
}
}
}
if cfg.cacheCfg[utils.CacheClosedSessions].Limit == 0 {
return fmt.Errorf("<%s> %s needs to be != 0, received: %d", utils.CacheS, utils.CacheClosedSessions, cfg.cacheCfg[utils.CacheClosedSessions].Limit)
}
}
// FreeSWITCHAgent checks
if cfg.fsAgentCfg.Enabled {
if len(cfg.fsAgentCfg.SessionSConns) == 0 {
return fmt.Errorf("<%s> no %s connections defined",
utils.FreeSWITCHAgent, utils.SessionS)
}
if !cfg.dispatcherSCfg.Enabled && // if dispatcher is enabled all internal connections are managed by it
!cfg.sessionSCfg.Enabled {
for _, connCfg := range cfg.fsAgentCfg.SessionSConns {
if connCfg.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but referenced by <%s>",
utils.SessionS, utils.FreeSWITCHAgent)
}
}
}
}
// KamailioAgent checks
if cfg.kamAgentCfg.Enabled {
if len(cfg.kamAgentCfg.SessionSConns) == 0 {
return fmt.Errorf("<%s> no %s connections defined",
utils.KamailioAgent, utils.SessionS)
}
if !cfg.dispatcherSCfg.Enabled && // if dispatcher is enabled all internal connections are managed by it
!cfg.sessionSCfg.Enabled {
for _, connCfg := range cfg.kamAgentCfg.SessionSConns {
if connCfg.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but referenced by <%s>",
utils.SessionS, utils.KamailioAgent)
}
}
}
}
// AsteriskAgent checks
if cfg.asteriskAgentCfg.Enabled {
if len(cfg.asteriskAgentCfg.SessionSConns) == 0 {
return fmt.Errorf("<%s> no %s connections defined",
utils.AsteriskAgent, utils.SessionS)
}
if !cfg.dispatcherSCfg.Enabled && // if dispatcher is enabled all internal connections are managed by it
!cfg.sessionSCfg.Enabled {
for _, smAstSMGConn := range cfg.asteriskAgentCfg.SessionSConns {
if smAstSMGConn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but referenced by <%s>",
utils.SessionS, utils.AsteriskAgent)
}
}
}
}
// DAgent checks
if cfg.diameterAgentCfg.Enabled {
if len(cfg.diameterAgentCfg.SessionSConns) == 0 {
return fmt.Errorf("<%s> no %s connections defined",
utils.DiameterAgent, utils.SessionS)
}
if !cfg.dispatcherSCfg.Enabled && // if dispatcher is enabled all internal connections are managed by it
!cfg.sessionSCfg.Enabled {
for _, daSMGConn := range cfg.diameterAgentCfg.SessionSConns {
if daSMGConn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but referenced by <%s>",
utils.SessionS, utils.DiameterAgent)
}
}
}
}
//Radius Agent
if cfg.radiusAgentCfg.Enabled {
if len(cfg.radiusAgentCfg.SessionSConns) == 0 {
return fmt.Errorf("<%s> no %s connections defined",
utils.RadiusAgent, utils.SessionS)
}
if !cfg.dispatcherSCfg.Enabled && // if dispatcher is enabled all internal connections are managed by it
!cfg.sessionSCfg.Enabled {
for _, raSMGConn := range cfg.radiusAgentCfg.SessionSConns {
if raSMGConn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but referenced by <%s>",
utils.SessionS, utils.RadiusAgent)
}
}
}
}
//DNS Agent
if cfg.dnsAgentCfg.Enabled {
if len(cfg.dnsAgentCfg.SessionSConns) == 0 {
return fmt.Errorf("<%s> no %s connections defined",
utils.DNSAgent, utils.SessionS)
}
if !cfg.dispatcherSCfg.Enabled && // if dispatcher is enabled all internal connections are managed by it
!cfg.sessionSCfg.Enabled {
for _, sSConn := range cfg.dnsAgentCfg.SessionSConns {
if sSConn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but referenced by <%s>", utils.SessionS, utils.DNSAgent)
}
}
}
}
// HTTPAgent checks
for _, httpAgentCfg := range cfg.httpAgentCfg {
// httpAgent checks
if !cfg.dispatcherSCfg.Enabled && // if dispatcher is enabled all internal connections are managed by it
cfg.sessionSCfg.Enabled {
for _, sSConn := range httpAgentCfg.SessionSConns {
if sSConn.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but referenced by <%s> component", utils.SessionS, utils.HTTPAgent)
}
}
}
if !utils.SliceHasMember([]string{utils.MetaUrl, utils.MetaXml}, httpAgentCfg.RequestPayload) {
return fmt.Errorf("<%s> unsupported request payload %s", utils.HTTPAgent, httpAgentCfg.RequestPayload)
}
if !utils.SliceHasMember([]string{utils.MetaTextPlain, utils.MetaXml}, httpAgentCfg.ReplyPayload) {
return fmt.Errorf("<%s> unsupported reply payload %s", utils.HTTPAgent, httpAgentCfg.ReplyPayload)
}
}
if cfg.attributeSCfg.Enabled {
if cfg.attributeSCfg.ProcessRuns < 1 {
return fmt.Errorf("<%s> process_runs needs to be bigger than 0", utils.AttributeS)
}
}
if cfg.chargerSCfg.Enabled && !cfg.dispatcherSCfg.Enabled &&
(cfg.attributeSCfg == nil || !cfg.attributeSCfg.Enabled) {
for _, connCfg := range cfg.chargerSCfg.AttributeSConns {
if connCfg.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but requested by <%s> component.", utils.AttributeS, utils.ChargerS)
}
}
}
// ResourceLimiter checks
if cfg.resourceSCfg.Enabled && !cfg.thresholdSCfg.Enabled && !cfg.dispatcherSCfg.Enabled {
for _, connCfg := range cfg.resourceSCfg.ThresholdSConns {
if connCfg.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but requested by <%s> component.", utils.ThresholdS, utils.ResourceS)
}
}
}
// StatS checks
if cfg.statsCfg.Enabled && !cfg.thresholdSCfg.Enabled && !cfg.dispatcherSCfg.Enabled {
for _, connCfg := range cfg.statsCfg.ThresholdSConns {
if connCfg.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but requested by <%s> component.", utils.ThresholdS, utils.StatService)
}
}
}
// SupplierS checks
if cfg.supplierSCfg.Enabled && !cfg.dispatcherSCfg.Enabled {
if !cfg.resourceSCfg.Enabled {
for _, connCfg := range cfg.supplierSCfg.ResourceSConns {
if connCfg.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but requested by <%s> component.", utils.ResourceS, utils.SupplierS)
}
}
}
if !cfg.statsCfg.Enabled {
for _, connCfg := range cfg.supplierSCfg.StatSConns {
if connCfg.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but requested by <%s> component.", utils.StatService, utils.SupplierS)
}
}
}
if !cfg.attributeSCfg.Enabled {
for _, connCfg := range cfg.supplierSCfg.AttributeSConns {
if connCfg.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but requested by <%s> component.", utils.AttributeS, utils.SupplierS)
}
}
}
}
// Scheduler check connection with CDR Server
if !cfg.cdrsCfg.Enabled && !cfg.dispatcherSCfg.Enabled {
for _, connCfg := range cfg.schedulerCfg.CDRsConns {
if connCfg.Address == utils.MetaInternal {
return fmt.Errorf("%s Server not enabled but requested by %s", utils.CDR, utils.SchedulerS)
}
}
}
// EventReader sanity checks
if cfg.ersCfg.Enabled {
if !cfg.sessionSCfg.Enabled {
for _, connCfg := range cfg.ersCfg.SessionSConns {
if connCfg.Address == utils.MetaInternal {
return fmt.Errorf("<%s> not enabled but requested by EventReader component.", utils.SessionS)
}
}
}
for _, rdr := range cfg.ersCfg.Readers {
if !possibleReaderTypes.Has(rdr.Type) {
return fmt.Errorf("<%s> unsupported data type: %s for reader with ID: %s", utils.ERs, rdr.Type, rdr.ID)
}
if rdr.Type == utils.MetaFileCSV {
for _, dir := range []string{rdr.ProcessedPath, rdr.SourcePath} {
if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
return fmt.Errorf("<%s> Nonexistent folder: %s for reader with ID: %s", utils.ERs, dir, rdr.ID)
}
}
if rdr.FieldSep == utils.EmptyString {
return fmt.Errorf("<%s> empty FieldSep for reader with ID: %s", utils.ERs, rdr.ID)
}
}
if rdr.Type == utils.MetaKafkajsonMap && rdr.RunDelay > 0 {
return fmt.Errorf("<%s> RunDelay field can not be bigger than zero for reader with ID: %s", utils.ERs, rdr.ID)
}
}
}
// StorDB sanity checks
if cfg.storDbCfg.Type == utils.POSTGRES {
if !utils.IsSliceMember([]string{utils.PostgressSSLModeDisable, utils.PostgressSSLModeAllow,
utils.PostgressSSLModePrefer, utils.PostgressSSLModeRequire, utils.PostgressSSLModeVerifyCa,
utils.PostgressSSLModeVerifyFull}, cfg.storDbCfg.SSLMode) {
return fmt.Errorf("<%s> Unsuported sslmode for storDB", utils.StorDB)
}
}
// DataDB sanity checks
if cfg.dataDbCfg.DataDbType == utils.INTERNAL {
for key, config := range cfg.cacheCfg {
if key == utils.CacheDiameterMessages || key == utils.CacheClosedSessions {
if config.Limit == 0 {
return fmt.Errorf("<%s> %s needs to be != 0 when DataBD is *internal, found 0.", utils.CacheS, key)
}
continue
}
if config.Limit != 0 {
return fmt.Errorf("<%s> %s needs to be 0 when DataBD is *internal, received : %d", utils.CacheS, key, config.Limit)
}
}
if cfg.resourceSCfg.Enabled == true && cfg.resourceSCfg.StoreInterval != -1 {
return fmt.Errorf("<%s> StoreInterval needs to be -1 when DataBD is *internal, received : %d", utils.ResourceS, cfg.resourceSCfg.StoreInterval)
}
if cfg.statsCfg.Enabled == true && cfg.statsCfg.StoreInterval != -1 {
return fmt.Errorf("<%s> StoreInterval needs to be -1 when DataBD is *internal, received : %d", utils.StatS, cfg.statsCfg.StoreInterval)
}
if cfg.thresholdSCfg.Enabled == true && cfg.thresholdSCfg.StoreInterval != -1 {
return fmt.Errorf("<%s> StoreInterval needs to be -1 when DataBD is *internal, received : %d", utils.ThresholdS, cfg.thresholdSCfg.StoreInterval)
}
}
for item, val := range cfg.dataDbCfg.Items {
if val.Remote == true && len(cfg.dataDbCfg.RmtConns) == 0 {
return fmt.Errorf("Remote connections required by: <%s>", item)
}
if val.Replicate == true && len(cfg.dataDbCfg.RplConns) == 0 {
return fmt.Errorf("Replicate connections required by: <%s>", item)
}
}
return nil
}

690
config/configsanity_test.go Normal file
View File

@@ -0,0 +1,690 @@
/*
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 config
import (
"testing"
"github.com/cgrates/cgrates/utils"
)
func TestConfigSanityRater(t *testing.T) {
cfg, _ := NewDefaultCGRConfig()
cfg.ralsCfg = &RalsCfg{
Enabled: true,
StatSConns: []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
},
}
expected := "<Stats> not enabled but requested by <RALs> component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.statsCfg.Enabled = true
cfg.ralsCfg.ThresholdSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<ThresholdS> not enabled but requested by <RALs> component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
}
func TestConfigSanityCDRServer(t *testing.T) {
cfg, _ := NewDefaultCGRConfig()
cfg.cdrsCfg = &CdrsCfg{
Enabled: true,
ChargerSConns: []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
},
}
expected := "<Chargers> not enabled but requested by <CDRs> component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.chargerSCfg.Enabled = true
cfg.cdrsCfg.RaterConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<RALs> not enabled but requested by <CDRs> component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.ralsCfg.Enabled = true
cfg.cdrsCfg.AttributeSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<AttributeS> not enabled but requested by <CDRs> component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.attributeSCfg.Enabled = true
cfg.cdrsCfg.StatSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<StatS> not enabled but requested by <CDRs> component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.statsCfg.Enabled = true
cfg.cdrsCfg.OnlineCDRExports = []string{"stringy"}
cfg.CdreProfiles = map[string]*CdreCfg{"stringx": &CdreCfg{}}
expected = "<CDRs> Cannot find CDR export template with ID: <stringy>"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.cdrsCfg.OnlineCDRExports = []string{"stringx"}
cfg.cdrsCfg.ThresholdSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "ThresholdS not enabled but requested by CDRs component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
}
func TestConfigSanityCDRC(t *testing.T) {
cfg, _ = NewDefaultCGRConfig()
cfg.CdrcProfiles = map[string][]*CdrcCfg{
"test": []*CdrcCfg{
&CdrcCfg{
Enabled: true,
},
},
}
expected := "<cdrc> Instance: , cdrc enabled but no CDRs defined!"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.CdrcProfiles = map[string][]*CdrcCfg{
"test": []*CdrcCfg{
&CdrcCfg{
Enabled: true,
CdrsConns: []*RemoteHost{
&RemoteHost{Address: utils.MetaInternal},
},
},
},
}
expected = "<CDRs> not enabled but referenced from <cdrc>"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.CdrcProfiles = map[string][]*CdrcCfg{
"test": []*CdrcCfg{
&CdrcCfg{
Enabled: true,
CdrsConns: []*RemoteHost{
&RemoteHost{Address: utils.MetaInternal},
},
ContentFields: []*FCTemplate{},
},
},
}
cfg.cdrsCfg.Enabled = true
expected = "<cdrc> enabled but no fields to be processed defined!"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
}
func TestConfigSanityLoaders(t *testing.T) {
cfg, _ = NewDefaultCGRConfig()
cfg.loaderCfg = LoaderSCfgs{
&LoaderSCfg{
Enabled: true,
TpInDir: "/not/exist",
Data: []*LoaderDataType{
&LoaderDataType{
Type: "strsdfing",
},
},
},
}
expected := "<LoaderS> Nonexistent folder: /not/exist"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.loaderCfg = LoaderSCfgs{
&LoaderSCfg{
Enabled: true,
TpInDir: "/",
TpOutDir: "/",
Data: []*LoaderDataType{
&LoaderDataType{
Type: "wrongtype",
},
},
},
}
expected = "<LoaderS> unsupported data type wrongtype"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.loaderCfg = LoaderSCfgs{
&LoaderSCfg{
Enabled: true,
TpInDir: "/",
TpOutDir: "/",
Data: []*LoaderDataType{
&LoaderDataType{
Type: utils.MetaStats,
Fields: []*FCTemplate{
&FCTemplate{
Type: utils.MetaStats,
Tag: "test1",
},
},
},
},
},
}
expected = "<LoaderS> invalid field type *stats for *stats at test1"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
}
func TestConfigSanitySessionS(t *testing.T) {
cfg, _ = NewDefaultCGRConfig()
cfg.sessionSCfg = &SessionSCfg{
Enabled: true,
TerminateAttempts: 0,
}
expected := "<SessionS> 'terminate_attempts' should be at least 1"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.sessionSCfg.TerminateAttempts = 1
cfg.sessionSCfg.ChargerSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<SessionS> ChargerS not enabled"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.chargerSCfg.Enabled = true
cfg.sessionSCfg.RALsConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<SessionS> RALs not enabled but requested by SMGeneric component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.ralsCfg.Enabled = true
cfg.sessionSCfg.ResSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<SessionS> ResourceS not enabled but requested by SMGeneric component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.resourceSCfg.Enabled = true
cfg.sessionSCfg.ThreshSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<SessionS> ThresholdS not enabled but requested by SMGeneric component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.thresholdSCfg.Enabled = true
cfg.sessionSCfg.StatSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<SessionS> Stats not enabled but requested by SMGeneric component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.statsCfg.Enabled = true
cfg.sessionSCfg.SupplSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<SessionS> SupplierS not enabled but requested by SMGeneric component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.supplierSCfg.Enabled = true
cfg.sessionSCfg.AttrSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<SessionS> AttributeS not enabled but requested by SMGeneric component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.attributeSCfg.Enabled = true
cfg.sessionSCfg.CDRsConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<SessionS> CDRS not enabled but referenced by SMGeneric component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.cdrsCfg.Enabled = true
cfg.cacheCfg[utils.CacheClosedSessions].Limit = 0
expected = "<CacheS> *closed_sessions needs to be != 0, received: 0"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
}
func TestConfigSanityFreeSWITCHAgent(t *testing.T) {
cfg, _ = NewDefaultCGRConfig()
cfg.fsAgentCfg = &FsAgentCfg{
Enabled: true,
}
expected := "<FreeSWITCHAgent> no SessionS connections defined"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.fsAgentCfg = &FsAgentCfg{
Enabled: true,
SessionSConns: []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
},
}
expected = "<SessionS> not enabled but referenced by <FreeSWITCHAgent>"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
}
func TestConfigSanityKamailioAgent(t *testing.T) {
cfg, _ = NewDefaultCGRConfig()
cfg.kamAgentCfg = &KamAgentCfg{
Enabled: true,
}
expected := "<KamailioAgent> no SessionS connections defined"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.kamAgentCfg.SessionSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<SessionS> not enabled but referenced by <KamailioAgent>"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
}
func TestConfigSanityAsteriskAgent(t *testing.T) {
cfg, _ = NewDefaultCGRConfig()
cfg.asteriskAgentCfg = &AsteriskAgentCfg{
Enabled: true,
}
expected := "<AsteriskAgent> no SessionS connections defined"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.asteriskAgentCfg.SessionSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<SessionS> not enabled but referenced by <AsteriskAgent>"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
}
func TestConfigSanityDAgent(t *testing.T) {
cfg, _ = NewDefaultCGRConfig()
cfg.diameterAgentCfg = &DiameterAgentCfg{
Enabled: true,
}
expected := "<DiameterAgent> no SessionS connections defined"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.diameterAgentCfg.SessionSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<SessionS> not enabled but referenced by <DiameterAgent>"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
}
func TestConfigSanityRadiusAgent(t *testing.T) {
cfg, _ = NewDefaultCGRConfig()
cfg.radiusAgentCfg = &RadiusAgentCfg{
Enabled: true,
}
expected := "<RadiusAgent> no SessionS connections defined"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.radiusAgentCfg.SessionSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<SessionS> not enabled but referenced by <RadiusAgent>"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
}
func TestConfigSanityDNSAgent(t *testing.T) {
cfg, _ = NewDefaultCGRConfig()
cfg.dnsAgentCfg = &DNSAgentCfg{
Enabled: true,
}
expected := "<DNSAgent> no SessionS connections defined"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.dnsAgentCfg.SessionSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<SessionS> not enabled but referenced by <DNSAgent>"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
}
func TestConfigSanityHTTPAgent(t *testing.T) {
cfg, _ = NewDefaultCGRConfig()
cfg.sessionSCfg.Enabled = true
cfg.httpAgentCfg = HttpAgentCfgs{
&HttpAgentCfg{
SessionSConns: []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
},
},
}
expected := "<SessionS> not enabled but referenced by <HTTPAgent> component"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.sessionSCfg.Enabled = false
cfg.httpAgentCfg = HttpAgentCfgs{
&HttpAgentCfg{
RequestPayload: "test",
},
}
expected = "<HTTPAgent> unsupported request payload test"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.httpAgentCfg = HttpAgentCfgs{
&HttpAgentCfg{
RequestPayload: utils.MetaUrl,
ReplyPayload: "test",
},
}
expected = "<HTTPAgent> unsupported reply payload test"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.httpAgentCfg[0].ReplyPayload = utils.MetaTextPlain
cfg.attributeSCfg = &AttributeSCfg{
Enabled: true,
ProcessRuns: 0,
}
expected = "<AttributeS> process_runs needs to be bigger than 0"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.attributeSCfg = &AttributeSCfg{
ProcessRuns: 1,
Enabled: false,
}
cfg.chargerSCfg.Enabled = true
cfg.chargerSCfg.AttributeSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<AttributeS> not enabled but requested by <ChargerS> component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
}
func TestConfigSanityResourceLimiter(t *testing.T) {
cfg, _ = NewDefaultCGRConfig()
cfg.resourceSCfg = &ResourceSConfig{
Enabled: true,
ThresholdSConns: []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
},
}
expected := "<ThresholdS> not enabled but requested by <ResourceS> component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
}
func TestConfigSanityStatS(t *testing.T) {
cfg, _ = NewDefaultCGRConfig()
cfg.statsCfg = &StatSCfg{
Enabled: true,
ThresholdSConns: []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
},
}
expected := "<ThresholdS> not enabled but requested by <StatS> component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
}
func TestConfigSanitySupplierS(t *testing.T) {
cfg, _ = NewDefaultCGRConfig()
cfg.supplierSCfg.Enabled = true
cfg.supplierSCfg.ResourceSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected := "<ResourceS> not enabled but requested by <SupplierS> component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.resourceSCfg.Enabled = true
cfg.supplierSCfg.StatSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<StatS> not enabled but requested by <SupplierS> component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.statsCfg.Enabled = true
cfg.supplierSCfg.AttributeSConns = []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
}
expected = "<AttributeS> not enabled but requested by <SupplierS> component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
}
func TestConfigSanityScheduler(t *testing.T) {
cfg, _ = NewDefaultCGRConfig()
cfg.schedulerCfg = &SchedulerCfg{
Enabled: true,
CDRsConns: []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
},
}
expected := "CDR Server not enabled but requested by SchedulerS"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
}
func TestConfigSanityEventReader(t *testing.T) {
cfg, _ = NewDefaultCGRConfig()
cfg.ersCfg = &ERsCfg{
Enabled: true,
SessionSConns: []*RemoteHost{
&RemoteHost{
Address: utils.MetaInternal,
},
},
}
expected := "<SessionS> not enabled but requested by EventReader component."
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.sessionSCfg.Enabled = true
cfg.ersCfg.Readers = []*EventReaderCfg{
&EventReaderCfg{
ID: "test",
Type: "wrongtype",
},
}
expected = "<ERs> unsupported data type: wrongtype for reader with ID: test"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.ersCfg.Readers = []*EventReaderCfg{
&EventReaderCfg{
ID: "test2",
Type: utils.MetaFileCSV,
ProcessedPath: "not/a/path",
},
}
expected = "<ERs> Nonexistent folder: not/a/path for reader with ID: test2"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.ersCfg.Readers = []*EventReaderCfg{
&EventReaderCfg{
ID: "test3",
Type: utils.MetaFileCSV,
ProcessedPath: "/",
SourcePath: "/",
FieldSep: "",
},
}
expected = "<ERs> empty FieldSep for reader with ID: test3"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
cfg.ersCfg.Readers[0].FieldSep = utils.InInFieldSep
cfg.ersCfg.Readers[0].ID = "test4"
cfg.ersCfg.Readers[0].Type = utils.MetaKafkajsonMap
cfg.ersCfg.Readers[0].RunDelay = 1
expected = "<ERs> RunDelay field can not be bigger than zero for reader with ID: test4"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
}
func TestConfigSanityStorDB(t *testing.T) {
cfg, _ = NewDefaultCGRConfig()
cfg.storDbCfg = &StorDbCfg{
Type: utils.POSTGRES,
SSLMode: "wrongSSLMode",
}
expected := "<stor_db> Unsuported sslmode for storDB"
if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
}