mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
395 lines
15 KiB
Go
395 lines
15 KiB
Go
/*
|
|
Real-time Charging System for Telecom & ISP environments
|
|
Copyright (C) 2012-2014 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"
|
|
"reflect"
|
|
"regexp"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/cgrates/cgrates/utils"
|
|
)
|
|
|
|
func TestConfigSharing(t *testing.T) {
|
|
cfg, _ := NewDefaultCGRConfig()
|
|
SetCgrConfig(cfg)
|
|
cfgReturn := CgrConfig()
|
|
if !reflect.DeepEqual(cfgReturn, cfg) {
|
|
t.Errorf("Retrieved %v, Expected %v", cfgReturn, cfg)
|
|
}
|
|
}
|
|
|
|
// Make sure defaults did not change by mistake
|
|
func TestDefaults(t *testing.T) {
|
|
cfg := &CGRConfig{}
|
|
errSet := cfg.setDefaults()
|
|
if errSet != nil {
|
|
t.Log(fmt.Sprintf("Coud not set defaults: %s!", errSet.Error()))
|
|
t.FailNow()
|
|
}
|
|
eCfg := &CGRConfig{}
|
|
eCfg.RatingDBType = REDIS
|
|
eCfg.RatingDBHost = "127.0.0.1"
|
|
eCfg.RatingDBPort = "6379"
|
|
eCfg.RatingDBName = "10"
|
|
eCfg.RatingDBUser = ""
|
|
eCfg.RatingDBPass = ""
|
|
eCfg.AccountDBType = REDIS
|
|
eCfg.AccountDBHost = "127.0.0.1"
|
|
eCfg.AccountDBPort = "6379"
|
|
eCfg.AccountDBName = "11"
|
|
eCfg.AccountDBUser = ""
|
|
eCfg.AccountDBPass = ""
|
|
eCfg.StorDBType = utils.MYSQL
|
|
eCfg.StorDBHost = "localhost"
|
|
eCfg.StorDBPort = "3306"
|
|
eCfg.StorDBName = "cgrates"
|
|
eCfg.StorDBUser = "cgrates"
|
|
eCfg.StorDBPass = "CGRateS.org"
|
|
eCfg.DBDataEncoding = utils.MSGPACK
|
|
eCfg.RPCJSONListen = "127.0.0.1:2012"
|
|
eCfg.RPCGOBListen = "127.0.0.1:2013"
|
|
eCfg.HTTPListen = "127.0.0.1:2080"
|
|
eCfg.DefaultReqType = utils.RATED
|
|
eCfg.DefaultCategory = "call"
|
|
eCfg.DefaultTenant = "cgrates.org"
|
|
eCfg.DefaultSubject = "cgrates"
|
|
eCfg.RoundingDecimals = 10
|
|
eCfg.HttpSkipTlsVerify = false
|
|
eCfg.XmlCfgDocument = nil
|
|
eCfg.RaterEnabled = false
|
|
eCfg.RaterBalancer = ""
|
|
eCfg.BalancerEnabled = false
|
|
eCfg.SchedulerEnabled = false
|
|
eCfg.CdreDefaultInstance, _ = NewDefaultCdreConfig()
|
|
eCfg.CDRSEnabled = false
|
|
eCfg.CDRSExtraFields = []*utils.RSRField{}
|
|
eCfg.CDRSMediator = ""
|
|
eCfg.CDRSStats = ""
|
|
eCfg.CDRSStoreDisable = false
|
|
eCfg.CDRStatsEnabled = false
|
|
eCfg.CDRStatConfig = &CdrStatsConfig{Id: utils.META_DEFAULT, QueueLength: 50, TimeWindow: time.Duration(1) * time.Hour, Metrics: []string{"ASR", "ACD", "ACC"}}
|
|
eCfg.CdrcEnabled = false
|
|
eCfg.CdrcCdrs = utils.INTERNAL
|
|
eCfg.CdrcRunDelay = time.Duration(0)
|
|
eCfg.CdrcCdrType = "csv"
|
|
eCfg.CdrcCsvSep = string(utils.CSV_SEP)
|
|
eCfg.CdrcCdrInDir = "/var/log/cgrates/cdrc/in"
|
|
eCfg.CdrcCdrOutDir = "/var/log/cgrates/cdrc/out"
|
|
eCfg.CdrcSourceId = "csv"
|
|
eCfg.CdrcCdrFields = map[string][]*utils.RSRField{
|
|
utils.TOR: []*utils.RSRField{&utils.RSRField{Id: "2"}},
|
|
utils.ACCID: []*utils.RSRField{&utils.RSRField{Id: "3"}},
|
|
utils.REQTYPE: []*utils.RSRField{&utils.RSRField{Id: "4"}},
|
|
utils.DIRECTION: []*utils.RSRField{&utils.RSRField{Id: "5"}},
|
|
utils.TENANT: []*utils.RSRField{&utils.RSRField{Id: "6"}},
|
|
utils.CATEGORY: []*utils.RSRField{&utils.RSRField{Id: "7"}},
|
|
utils.ACCOUNT: []*utils.RSRField{&utils.RSRField{Id: "8"}},
|
|
utils.SUBJECT: []*utils.RSRField{&utils.RSRField{Id: "9"}},
|
|
utils.DESTINATION: []*utils.RSRField{&utils.RSRField{Id: "10"}},
|
|
utils.SETUP_TIME: []*utils.RSRField{&utils.RSRField{Id: "11"}},
|
|
utils.ANSWER_TIME: []*utils.RSRField{&utils.RSRField{Id: "12"}},
|
|
utils.USAGE: []*utils.RSRField{&utils.RSRField{Id: "13"}},
|
|
}
|
|
eCfg.MediatorEnabled = false
|
|
eCfg.MediatorRater = utils.INTERNAL
|
|
eCfg.MediatorReconnects = 3
|
|
eCfg.MediatorStats = utils.INTERNAL
|
|
eCfg.MediatorStoreDisable = false
|
|
eCfg.SMEnabled = false
|
|
eCfg.SMSwitchType = FS
|
|
eCfg.SMRater = utils.INTERNAL
|
|
eCfg.SMCdrS = ""
|
|
eCfg.SMReconnects = 3
|
|
eCfg.SMDebitInterval = 10
|
|
eCfg.SMMinCallDuration = time.Duration(0)
|
|
eCfg.SMMaxCallDuration = time.Duration(3) * time.Hour
|
|
eCfg.FreeswitchServer = "127.0.0.1:8021"
|
|
eCfg.FreeswitchPass = "ClueCon"
|
|
eCfg.FreeswitchReconnects = 5
|
|
eCfg.FSMinDurLowBalance = time.Duration(5) * time.Second
|
|
eCfg.FSLowBalanceAnnFile = ""
|
|
eCfg.FSEmptyBalanceContext = ""
|
|
eCfg.FSEmptyBalanceAnnFile = ""
|
|
eCfg.FSCdrExtraFields = []*utils.RSRField{}
|
|
eCfg.OsipsListenUdp = "127.0.0.1:2020"
|
|
eCfg.OsipsMiAddr = "127.0.0.1:8020"
|
|
eCfg.OsipsEvSubscInterval = time.Duration(60) * time.Second
|
|
eCfg.OsipsReconnects = 3
|
|
eCfg.DerivedChargers = make(utils.DerivedChargers, 0)
|
|
eCfg.CombinedDerivedChargers = true
|
|
eCfg.HistoryAgentEnabled = false
|
|
eCfg.HistoryServer = utils.INTERNAL
|
|
eCfg.HistoryServerEnabled = false
|
|
eCfg.HistoryDir = "/var/log/cgrates/history"
|
|
eCfg.HistorySaveInterval = time.Duration(1) * time.Second
|
|
eCfg.MailerServer = "localhost:25"
|
|
eCfg.MailerAuthUser = "cgrates"
|
|
eCfg.MailerAuthPass = "CGRateS.org"
|
|
eCfg.MailerFromAddr = "cgr-mailer@localhost.localdomain"
|
|
eCfg.DataFolderPath = "/usr/share/cgrates/"
|
|
if !reflect.DeepEqual(cfg, eCfg) {
|
|
t.Log(eCfg)
|
|
t.Log(cfg)
|
|
t.Error("Defaults different than expected!")
|
|
}
|
|
|
|
}
|
|
|
|
func TestSanityCheck(t *testing.T) {
|
|
cfg := &CGRConfig{}
|
|
errSet := cfg.setDefaults()
|
|
if errSet != nil {
|
|
t.Error("Coud not set defaults: ", errSet.Error())
|
|
}
|
|
if err := cfg.checkConfigSanity(); err != nil {
|
|
t.Error("Invalid defaults: ", err)
|
|
}
|
|
cfg = &CGRConfig{}
|
|
cfg.CdrcEnabled = true
|
|
if err := cfg.checkConfigSanity(); err == nil {
|
|
t.Error("Failed to detect missing CDR fields definition")
|
|
}
|
|
cfg.CdrcCdrType = utils.CSV
|
|
cfg.CdrcCdrFields = map[string][]*utils.RSRField{utils.ACCID: []*utils.RSRField{&utils.RSRField{Id: "test"}}}
|
|
if err := cfg.checkConfigSanity(); err == nil {
|
|
t.Error("Failed to detect improper use of CDR field names")
|
|
}
|
|
cfg.CdrcCdrFields = map[string][]*utils.RSRField{"extra1": []*utils.RSRField{&utils.RSRField{Id: "test"}}}
|
|
if err := cfg.checkConfigSanity(); err == nil {
|
|
t.Error("Failed to detect improper use of CDR field names")
|
|
}
|
|
}
|
|
|
|
// Load config from file and make sure we have all set
|
|
func TestConfigFromFile(t *testing.T) {
|
|
cfgPth := "test_data.txt"
|
|
cfg, err := NewCGRConfigFromFile(&cfgPth)
|
|
if err != nil {
|
|
t.Log(fmt.Sprintf("Could not parse config: %s!", err))
|
|
t.FailNow()
|
|
}
|
|
eCfg := &CGRConfig{} // Instance we expect to get out after reading config file
|
|
eCfg.setDefaults()
|
|
eCfg.RatingDBType = "test"
|
|
eCfg.RatingDBHost = "test"
|
|
eCfg.RatingDBPort = "test"
|
|
eCfg.RatingDBName = "test"
|
|
eCfg.RatingDBUser = "test"
|
|
eCfg.RatingDBPass = "test"
|
|
eCfg.AccountDBType = "test"
|
|
eCfg.AccountDBHost = "test"
|
|
eCfg.AccountDBPort = "test"
|
|
eCfg.AccountDBName = "test"
|
|
eCfg.AccountDBUser = "test"
|
|
eCfg.AccountDBPass = "test"
|
|
eCfg.StorDBType = "test"
|
|
eCfg.StorDBHost = "test"
|
|
eCfg.StorDBPort = "test"
|
|
eCfg.StorDBName = "test"
|
|
eCfg.StorDBUser = "test"
|
|
eCfg.StorDBPass = "test"
|
|
eCfg.DBDataEncoding = "test"
|
|
eCfg.RPCJSONListen = "test"
|
|
eCfg.RPCGOBListen = "test"
|
|
eCfg.HTTPListen = "test"
|
|
eCfg.DefaultReqType = "test"
|
|
eCfg.DefaultCategory = "test"
|
|
eCfg.DefaultTenant = "test"
|
|
eCfg.DefaultSubject = "test"
|
|
eCfg.RoundingDecimals = 99
|
|
eCfg.HttpSkipTlsVerify = true
|
|
eCfg.RaterEnabled = true
|
|
eCfg.RaterBalancer = "test"
|
|
eCfg.BalancerEnabled = true
|
|
eCfg.SchedulerEnabled = true
|
|
eCfg.CDRSEnabled = true
|
|
eCfg.CDRSExtraFields = []*utils.RSRField{&utils.RSRField{Id: "test"}}
|
|
eCfg.CDRSMediator = "test"
|
|
eCfg.CDRSStats = "test"
|
|
eCfg.CDRSStoreDisable = true
|
|
eCfg.CDRStatsEnabled = true
|
|
eCfg.CDRStatConfig = &CdrStatsConfig{Id: utils.META_DEFAULT, QueueLength: 99, TimeWindow: time.Duration(99) * time.Second,
|
|
Metrics: []string{"test"}, TORs: []string{"test"}, CdrHosts: []string{"test"}, CdrSources: []string{"test"}, ReqTypes: []string{"test"}, Directions: []string{"test"},
|
|
Tenants: []string{"test"}, Categories: []string{"test"}, Accounts: []string{"test"}, Subjects: []string{"test"}, DestinationPrefixes: []string{"test"},
|
|
UsageInterval: []time.Duration{time.Duration(99) * time.Second},
|
|
MediationRunIds: []string{"test"}, RatedAccounts: []string{"test"}, RatedSubjects: []string{"test"}, CostInterval: []float64{99.0}}
|
|
eCfg.CDRSStats = "test"
|
|
eCfg.CdreDefaultInstance = &CdreConfig{
|
|
CdrFormat: "test",
|
|
FieldSeparator: utils.CSV_SEP,
|
|
DataUsageMultiplyFactor: 99.0,
|
|
CostMultiplyFactor: 99.0,
|
|
CostRoundingDecimals: 99,
|
|
CostShiftDigits: 99,
|
|
MaskDestId: "test",
|
|
MaskLength: 99,
|
|
ExportDir: "test"}
|
|
eCfg.CdreDefaultInstance.ContentFields, _ = NewCdreCdrFieldsFromIds(false, "test")
|
|
eCfg.CdrcEnabled = true
|
|
eCfg.CdrcCdrs = "test"
|
|
eCfg.CdrcRunDelay = time.Duration(99) * time.Second
|
|
eCfg.CdrcCdrType = "test"
|
|
eCfg.CdrcCsvSep = ";"
|
|
eCfg.CdrcCdrInDir = "test"
|
|
eCfg.CdrcCdrOutDir = "test"
|
|
eCfg.CdrcSourceId = "test"
|
|
eCfg.CdrcCdrFields = map[string][]*utils.RSRField{
|
|
utils.TOR: []*utils.RSRField{&utils.RSRField{Id: "test"}},
|
|
utils.ACCID: []*utils.RSRField{&utils.RSRField{Id: "test"}},
|
|
utils.REQTYPE: []*utils.RSRField{&utils.RSRField{Id: "test"}},
|
|
utils.DIRECTION: []*utils.RSRField{&utils.RSRField{Id: "test"}},
|
|
utils.TENANT: []*utils.RSRField{&utils.RSRField{Id: "test"}},
|
|
utils.CATEGORY: []*utils.RSRField{&utils.RSRField{Id: "test"}},
|
|
utils.ACCOUNT: []*utils.RSRField{&utils.RSRField{Id: "test"}},
|
|
utils.SUBJECT: []*utils.RSRField{&utils.RSRField{Id: "test"}},
|
|
utils.DESTINATION: []*utils.RSRField{&utils.RSRField{Id: "test"}},
|
|
utils.SETUP_TIME: []*utils.RSRField{&utils.RSRField{Id: "test"}},
|
|
utils.ANSWER_TIME: []*utils.RSRField{&utils.RSRField{Id: "test"}},
|
|
utils.USAGE: []*utils.RSRField{&utils.RSRField{Id: "test"}},
|
|
"test": []*utils.RSRField{&utils.RSRField{Id: "test"}},
|
|
}
|
|
eCfg.MediatorEnabled = true
|
|
eCfg.MediatorRater = "test"
|
|
eCfg.MediatorReconnects = 99
|
|
eCfg.MediatorStats = "test"
|
|
eCfg.MediatorStoreDisable = true
|
|
eCfg.SMEnabled = true
|
|
eCfg.SMSwitchType = "test"
|
|
eCfg.SMRater = "test"
|
|
eCfg.SMCdrS = "test"
|
|
eCfg.SMReconnects = 99
|
|
eCfg.SMDebitInterval = 99
|
|
eCfg.SMMinCallDuration = time.Duration(98) * time.Second
|
|
eCfg.SMMaxCallDuration = time.Duration(99) * time.Second
|
|
eCfg.FreeswitchServer = "test"
|
|
eCfg.FreeswitchPass = "test"
|
|
eCfg.FreeswitchReconnects = 99
|
|
eCfg.FSMinDurLowBalance = time.Duration(99) * time.Second
|
|
eCfg.FSLowBalanceAnnFile = "test"
|
|
eCfg.FSEmptyBalanceContext = "test"
|
|
eCfg.FSEmptyBalanceAnnFile = "test"
|
|
eCfg.FSCdrExtraFields = []*utils.RSRField{&utils.RSRField{Id: "test"}}
|
|
eCfg.OsipsListenUdp = "test"
|
|
eCfg.OsipsMiAddr = "test"
|
|
eCfg.OsipsEvSubscInterval = time.Duration(99) * time.Second
|
|
eCfg.OsipsReconnects = 99
|
|
eCfg.DerivedChargers = utils.DerivedChargers{&utils.DerivedCharger{RunId: "test", RunFilters: "", ReqTypeField: "test", DirectionField: "test", TenantField: "test",
|
|
CategoryField: "test", AccountField: "test", SubjectField: "test", DestinationField: "test", SetupTimeField: "test", AnswerTimeField: "test", UsageField: "test"}}
|
|
eCfg.CombinedDerivedChargers = true
|
|
eCfg.HistoryAgentEnabled = true
|
|
eCfg.HistoryServer = "test"
|
|
eCfg.HistoryServerEnabled = true
|
|
eCfg.HistoryDir = "test"
|
|
eCfg.HistorySaveInterval = time.Duration(99) * time.Second
|
|
eCfg.MailerServer = "test"
|
|
eCfg.MailerAuthUser = "test"
|
|
eCfg.MailerAuthPass = "test"
|
|
eCfg.MailerFromAddr = "test"
|
|
eCfg.DataFolderPath = "/usr/share/cgrates/"
|
|
if !reflect.DeepEqual(cfg, eCfg) {
|
|
t.Log(eCfg)
|
|
t.Log(cfg)
|
|
t.Error("Loading of configuration from file failed!")
|
|
}
|
|
}
|
|
|
|
func TestCdrsExtraFields(t *testing.T) {
|
|
eFieldsCfg := []byte(`[cdrs]
|
|
extra_fields = extr1,extr2
|
|
`)
|
|
if cfg, err := NewCGRConfigFromBytes(eFieldsCfg); err != nil {
|
|
t.Error("Could not parse the config", err.Error())
|
|
} else if !reflect.DeepEqual(cfg.CDRSExtraFields, []*utils.RSRField{&utils.RSRField{Id: "extr1"}, &utils.RSRField{Id: "extr2"}}) {
|
|
t.Errorf("Unexpected value for CdrsExtraFields: %v", cfg.CDRSExtraFields)
|
|
}
|
|
eFieldsCfg = []byte(`[cdrs]
|
|
extra_fields = ~effective_caller_id_number:s/(\d+)/+$1/
|
|
`)
|
|
if cfg, err := NewCGRConfigFromBytes(eFieldsCfg); err != nil {
|
|
t.Error("Could not parse the config", err.Error())
|
|
} else if !reflect.DeepEqual(cfg.CDRSExtraFields, []*utils.RSRField{&utils.RSRField{Id: "effective_caller_id_number",
|
|
RSRules: []*utils.ReSearchReplace{&utils.ReSearchReplace{SearchRegexp: regexp.MustCompile(`(\d+)`), ReplaceTemplate: "+$1"}}}}) {
|
|
t.Errorf("Unexpected value for config CdrsExtraFields: %v", cfg.CDRSExtraFields)
|
|
}
|
|
eFieldsCfg = []byte(`[cdrs]
|
|
extra_fields = extr1,~extr2:s/x.+/
|
|
`)
|
|
if _, err := NewCGRConfigFromBytes(eFieldsCfg); err == nil {
|
|
t.Error("Failed to detect failed RSRParsing")
|
|
}
|
|
|
|
}
|
|
|
|
func TestCdreExtraFields(t *testing.T) {
|
|
eFieldsCfg := []byte(`[cdre]
|
|
cdr_format = csv
|
|
export_template = cgrid,mediation_runid,accid
|
|
`)
|
|
expectedFlds := []*CdreCdrField{
|
|
&CdreCdrField{Name: "cgrid", Type: utils.CDRFIELD, Value: "cgrid", valueAsRsrField: &utils.RSRField{Id: "cgrid"}, Mandatory: true},
|
|
&CdreCdrField{Name: "mediation_runid", Type: utils.CDRFIELD, Value: "mediation_runid", valueAsRsrField: &utils.RSRField{Id: "mediation_runid"},
|
|
Mandatory: true},
|
|
&CdreCdrField{Name: "accid", Type: utils.CDRFIELD, Value: "accid", valueAsRsrField: &utils.RSRField{Id: "accid"},
|
|
Mandatory: true},
|
|
}
|
|
expCdreCfg := &CdreConfig{CdrFormat: utils.CSV, FieldSeparator: utils.CSV_SEP, CostRoundingDecimals: -1, ExportDir: "/var/log/cgrates/cdre", ContentFields: expectedFlds}
|
|
if cfg, err := NewCGRConfigFromBytes(eFieldsCfg); err != nil {
|
|
t.Error("Could not parse the config", err.Error())
|
|
} else if !reflect.DeepEqual(cfg.CdreDefaultInstance, expCdreCfg) {
|
|
t.Errorf("Expecting: %v, received: %v", expCdreCfg, cfg.CdreDefaultInstance)
|
|
}
|
|
eFieldsCfg = []byte(`[cdre]
|
|
cdr_format = csv
|
|
export_template = cgrid,~effective_caller_id_number:s/(\d+)/+$1/
|
|
`)
|
|
rsrField, _ := utils.NewRSRField(`~effective_caller_id_number:s/(\d+)/+$1/`)
|
|
expectedFlds = []*CdreCdrField{
|
|
&CdreCdrField{Name: "cgrid", Type: utils.CDRFIELD, Value: "cgrid", valueAsRsrField: &utils.RSRField{Id: "cgrid"}, Mandatory: true},
|
|
&CdreCdrField{Name: `~effective_caller_id_number:s/(\d+)/+$1/`, Type: utils.CDRFIELD, Value: `~effective_caller_id_number:s/(\d+)/+$1/`,
|
|
valueAsRsrField: rsrField, Mandatory: false}}
|
|
expCdreCfg.ContentFields = expectedFlds
|
|
if cfg, err := NewCGRConfigFromBytes(eFieldsCfg); err != nil {
|
|
t.Error("Could not parse the config", err.Error())
|
|
} else if !reflect.DeepEqual(cfg.CdreDefaultInstance, expCdreCfg) {
|
|
t.Errorf("Expecting: %v, received: %v", expCdreCfg, cfg.CdreDefaultInstance)
|
|
}
|
|
eFieldsCfg = []byte(`[cdre]
|
|
cdr_format = csv
|
|
export_template = cgrid,~accid:s/(\d)/$1,runid
|
|
`)
|
|
if _, err := NewCGRConfigFromBytes(eFieldsCfg); err == nil {
|
|
t.Error("Failed to detect failed RSRParsing")
|
|
}
|
|
}
|
|
|
|
func TestCdrcCdrDefaultFields(t *testing.T) {
|
|
cdrcCfg := []byte(`[cdrc]
|
|
enabled = true
|
|
`)
|
|
cfgDefault, _ := NewDefaultCGRConfig()
|
|
if cfg, err := NewCGRConfigFromBytes(cdrcCfg); err != nil {
|
|
t.Error("Could not parse the config", err.Error())
|
|
} else if !reflect.DeepEqual(cfg.CdrcCdrFields, cfgDefault.CdrcCdrFields) {
|
|
t.Errorf("Unexpected value for CdrcCdrFields: %v", cfg.CdrcCdrFields)
|
|
}
|
|
}
|