mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
test for cdr stats csv load
This commit is contained in:
@@ -1,4 +1,9 @@
|
||||
#Tag,BalanceType,Direction,ThresholdType,ThresholdValue,Recurrent,DestinationTag,ActionsTag,Weight
|
||||
STANDARD_TRIGGERS,*monetary,*out,*min_balance,2,false,,LOG_BALANCE,10
|
||||
STANDARD_TRIGGERS,*monetary,*out,*max_balance,20,false,,LOG_BALANCE,10
|
||||
STANDARD_TRIGGERS,*monetary,*out,*max_counter,15,false,FS_USERS,LOG_BALANCE,10
|
||||
#Tag,BalanceTag,Direction,ThresholdType,ThresholdValue,Recurrent,MinSleep,BalanceDestinationTag,BalanceWeight,BalanceExpiryTime,BalanceRatingSubject,BalanceSharedGroup,StatsMinQueuedItems,ActionsTag,Weight
|
||||
STANDARD_TRIGGERS,*monetary,*out,*min_balance,2,false,0,,,,,,,LOG_BALANCE,10
|
||||
STANDARD_TRIGGERS,*monetary,*out,*max_balance,20,false,0,,,,,,,LOG_BALANCE,10
|
||||
STANDARD_TRIGGERS,*monetary,*out,*max_counter,15,false,0,FS_USERS,,,,,,LOG_BALANCE,10
|
||||
CDRST1_WARN_ASR,,,*min_asr,45,true,1h,,,,,,3,CDRST_WARN_HTTP,10
|
||||
CDRST1_WARN_ACD,,,*min_acd,10,true,1h,,,,,,5,CDRST_WARN_HTTP,10
|
||||
CDRST1_WARN_ACC,,,*max_acc,10,true,10m,,,,,,5,CDRST_WARN_HTTP,10
|
||||
CDRST2_WARN_ASR,,,*min_asr,30,true,,,,,,,5,CDRST_WARN_HTTP,10
|
||||
CDRST2_WARN_ACD,,,*min_acd,3,true,,,,,,,5,CDRST_WARN_HTTP,10
|
||||
|
||||
|
@@ -2,3 +2,4 @@
|
||||
PREPAID_10,*topup_reset,*monetary,*out,10,*unlimited,*any,,10,,,10
|
||||
BONUS_1,*topup,*monetary,*out,1,*unlimited,*any,,10,,,10
|
||||
LOG_BALANCE,*log,,,,,,,,,,10
|
||||
CDRST_WARN_HTTP,*call_url,,,,,,,,,http://localhost:8080,10
|
||||
|
6
data/tariffplans/prepaid1centpsec/CdrStats.csv
Normal file
6
data/tariffplans/prepaid1centpsec/CdrStats.csv
Normal file
@@ -0,0 +1,6 @@
|
||||
#Id,QueueLength,TimeWindow,Metrics,SetupInterval,TOR,CdrHost,CdrSource,ReqType,Direction,Tenant,Category,Account,Subject,DestinationPrefix,UsageInterval,MediationRunIds,RatedAccount,RatedSubject,CostInterval,Triggers
|
||||
CDRST1,5,60m,ASR,2014-07-29T15:00:00Z;2014-07-29T16:00:00Z,*voice,87.139.12.167,FS_JSON,rated,*out,cgrates.org,call,dan,dan,49,5m;10m,default,rif,rif,0;2,CDRST1_WARN_ASR
|
||||
CDRST1,,,ACD,,,,,,,,,,,,,,,,,CDRST1_WARN_ACD
|
||||
CDRST1,,,ACC,,,,,,,,,,,,,,,,,CDRST1_WARN_ACC
|
||||
CDRST2,10,10m,ASR,,,,,,,cgrates.org,call,,,,,,,,,CDRST2_WARN_ASR
|
||||
CDRST2,,,ACD,,,,,,,,,,,,,,,,,CDRST2_WARN_ACD
|
||||
|
@@ -914,7 +914,7 @@ func (csvr *CSVReader) LoadDerivedChargers() (err error) {
|
||||
}
|
||||
|
||||
func (csvr *CSVReader) LoadCdrStats() (err error) {
|
||||
csvReader, fp, err := csvr.readerFunc(csvr.timingsFn, csvr.sep, utils.TIMINGS_NRCOLS)
|
||||
csvReader, fp, err := csvr.readerFunc(csvr.cdrStatsFn, csvr.sep, utils.CDR_STATS_NRCOLS)
|
||||
if err != nil {
|
||||
log.Print("Could not load cdr stats file: ", err)
|
||||
// allow writing of the other values
|
||||
@@ -925,18 +925,16 @@ func (csvr *CSVReader) LoadCdrStats() (err error) {
|
||||
}
|
||||
for record, err := csvReader.Read(); err == nil; record, err = csvReader.Read() {
|
||||
tag := record[0]
|
||||
if _, exists := csvr.cdrStats[tag]; exists {
|
||||
log.Print("Warning: duplicate cdr stats found: ", tag)
|
||||
}
|
||||
var cs *CdrStats
|
||||
var exists bool
|
||||
if cs, exists = csvr.cdrStats[tag]; !exists {
|
||||
cs = &CdrStats{}
|
||||
}
|
||||
triggers, exists := csvr.actionsTriggers[record[18]]
|
||||
if record[18] != "" && !exists {
|
||||
triggerTag := record[20]
|
||||
triggers, exists := csvr.actionsTriggers[triggerTag]
|
||||
if triggerTag != "" && !exists {
|
||||
// only return error if there was something there for the tag
|
||||
return fmt.Errorf("Could not get action triggers for cdr stats id %s: %s", cs.Id, record[18])
|
||||
return fmt.Errorf("Could not get action triggers for cdr stats id %s: %s", cs.Id, triggerTag)
|
||||
}
|
||||
UpdateCdrStats(cs, triggers, record...)
|
||||
csvr.cdrStats[tag] = cs
|
||||
|
||||
@@ -183,6 +183,12 @@ vdf,emptyY,*out,TOPUP_EMPTY_AT,
|
||||
*out,cgrates.org,call,dan,*any,extra1,,,,,,rif2,rif2,,,,
|
||||
`
|
||||
cdrStats = `
|
||||
#Id,QueueLength,TimeWindow,Metrics,SetupInterval,TOR,CdrHost,CdrSource,ReqType,Direction,Tenant,Category,Account,Subject,DestinationPrefix,UsageInterval,MediationRunIds,RatedAccount,RatedSubject,CostInterval,Triggers
|
||||
CDRST1,5,60m,ASR,2014-07-29T15:00:00Z;2014-07-29T16:00:00Z,*voice,87.139.12.167,FS_JSON,rated,*out,cgrates.org,call,dan,dan,49,5m;10m,default,rif,rif,0;2,STANDARD_TRIGGERS
|
||||
CDRST1,,,ACD,,,,,,,,,,,,,,,,,STANDARD_TRIGGER
|
||||
CDRST1,,,ACC,,,,,,,,,,,,,,,,,
|
||||
CDRST2,10,10m,ASR,,,,,,,cgrates.org,call,,,,,,,,,
|
||||
CDRST2,,,ACD,,,,,,,,,,,,,,,,,
|
||||
`
|
||||
)
|
||||
|
||||
@@ -204,6 +210,7 @@ func init() {
|
||||
csvr.LoadActionTriggers()
|
||||
csvr.LoadAccountActions()
|
||||
csvr.LoadDerivedChargers()
|
||||
csvr.LoadCdrStats()
|
||||
csvr.WriteToDatabase(false, false)
|
||||
dataStorage.CacheRating(nil, nil, nil, nil, nil)
|
||||
accountingStorage.CacheAccounting(nil, nil, nil, nil)
|
||||
@@ -770,19 +777,19 @@ func TestLoadSharedGroups(t *testing.T) {
|
||||
t.Error("Error loading shared group: ", sg2.AccountParameters)
|
||||
}
|
||||
/*sg, _ := accountingStorage.GetSharedGroup("SG1", false)
|
||||
if len(sg.Members) != 0 {
|
||||
t.Errorf("Memebers should be empty: %+v", sg)
|
||||
}
|
||||
if len(sg.Members) != 0 {
|
||||
t.Errorf("Memebers should be empty: %+v", sg)
|
||||
}
|
||||
|
||||
// execute action timings to fill memebers
|
||||
atm := csvr.actionsTimings["MORE_MINUTES"][1]
|
||||
atm.Execute()
|
||||
atm.actions, atm.stCache = nil, time.Time{}
|
||||
// execute action timings to fill memebers
|
||||
atm := csvr.actionsTimings["MORE_MINUTES"][1]
|
||||
atm.Execute()
|
||||
atm.actions, atm.stCache = nil, time.Time{}
|
||||
|
||||
sg, _ = accountingStorage.GetSharedGroup("SG1", false)
|
||||
if len(sg.Members) != 1 {
|
||||
t.Errorf("Memebers should not be empty: %+v", sg)
|
||||
}*/
|
||||
sg, _ = accountingStorage.GetSharedGroup("SG1", false)
|
||||
if len(sg.Members) != 1 {
|
||||
t.Errorf("Memebers should not be empty: %+v", sg)
|
||||
}*/
|
||||
}
|
||||
|
||||
func TestLoadLCRs(t *testing.T) {
|
||||
@@ -945,3 +952,38 @@ func TestLoadDerivedChargers(t *testing.T) {
|
||||
t.Error("Unexpected charger", csvr.derivedChargers[keyCharger1])
|
||||
}
|
||||
}
|
||||
func TestLoadCdrStats(t *testing.T) {
|
||||
if len(csvr.cdrStats) != 2 {
|
||||
t.Error("Failed to load cdr stats: ", csvr.cdrStats)
|
||||
}
|
||||
cdrStats1 := &CdrStats{
|
||||
Id: "CDRST1",
|
||||
QueueLength: 5,
|
||||
TimeWindow: 60 * time.Minute,
|
||||
Metrics: []string{"ASR", "ACD", "ACC"},
|
||||
SetupInterval: []time.Time{
|
||||
time.Date(2014, 7, 29, 15, 0, 0, 0, time.UTC),
|
||||
time.Date(2014, 7, 29, 16, 0, 0, 0, time.UTC),
|
||||
},
|
||||
TOR: []string{utils.VOICE},
|
||||
CdrHost: []string{"87.139.12.167"},
|
||||
CdrSource: []string{"FS_JSON"},
|
||||
ReqType: []string{"rated"},
|
||||
Direction: []string{utils.OUT},
|
||||
Tenant: []string{"cgrates.org"},
|
||||
Category: []string{"call"},
|
||||
Account: []string{"dan"},
|
||||
Subject: []string{"dan"},
|
||||
DestinationPrefix: []string{"49"},
|
||||
UsageInterval: []time.Duration{5 * time.Minute, 10 * time.Minute},
|
||||
MediationRunIds: []string{"default"},
|
||||
RatedAccount: []string{"rif"},
|
||||
RatedSubject: []string{"rif"},
|
||||
CostInterval: []float64{0, 2},
|
||||
}
|
||||
cdrStats1.Triggers = append(cdrStats1.Triggers, csvr.actionsTriggers["STANDARD_TRIGGERS"]...)
|
||||
cdrStats1.Triggers = append(cdrStats1.Triggers, csvr.actionsTriggers["STANDARD_TRIGGER"]...)
|
||||
if !reflect.DeepEqual(csvr.cdrStats[cdrStats1.Id], cdrStats1) {
|
||||
t.Error("Unexpected stats", csvr.cdrStats[cdrStats1.Id])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,13 +97,12 @@ func NewTiming(timingInfo ...string) (rt *utils.TPTiming) {
|
||||
}
|
||||
|
||||
func UpdateCdrStats(cs *CdrStats, triggers ActionTriggerPriotityList, record ...string) {
|
||||
cs = &CdrStats{}
|
||||
cs.Id = record[0]
|
||||
if record[1] != "" {
|
||||
if qi, err := strconv.Atoi(record[1]); err == nil {
|
||||
cs.QueueLength = qi
|
||||
} else {
|
||||
log.Printf("Error parsing QueuedItems %v for cdrs stats %v", record[1], cs.Id)
|
||||
log.Printf("Error parsing QueuedLength %v for cdrs stats %v", record[1], cs.Id)
|
||||
}
|
||||
}
|
||||
if record[2] != "" {
|
||||
@@ -200,7 +199,13 @@ func UpdateCdrStats(cs *CdrStats, triggers ActionTriggerPriotityList, record ...
|
||||
cs.MediationRunIds = append(cs.MediationRunIds, record[16])
|
||||
}
|
||||
if record[17] != "" {
|
||||
costs := strings.Split(record[17], utils.INFIELD_SEP)
|
||||
cs.RatedAccount = append(cs.RatedAccount, record[17])
|
||||
}
|
||||
if record[18] != "" {
|
||||
cs.RatedSubject = append(cs.RatedSubject, record[18])
|
||||
}
|
||||
if record[19] != "" {
|
||||
costs := strings.Split(record[19], utils.INFIELD_SEP)
|
||||
if len(costs) > 0 {
|
||||
if sCost, err := strconv.ParseFloat(costs[0], 64); err == nil {
|
||||
if len(cs.CostInterval) < 1 {
|
||||
@@ -209,7 +214,7 @@ func UpdateCdrStats(cs *CdrStats, triggers ActionTriggerPriotityList, record ...
|
||||
cs.CostInterval[0] = sCost
|
||||
}
|
||||
} else {
|
||||
log.Printf("Error parsing CostInterval %v for cdrs stats %v", record[17], cs.Id)
|
||||
log.Printf("Error parsing CostInterval %v for cdrs stats %v", record[19], cs.Id)
|
||||
}
|
||||
}
|
||||
if len(costs) > 1 {
|
||||
@@ -220,13 +225,12 @@ func UpdateCdrStats(cs *CdrStats, triggers ActionTriggerPriotityList, record ...
|
||||
cs.CostInterval[1] = eCost
|
||||
}
|
||||
} else {
|
||||
log.Printf("Error parsing CostInterval %v for cdrs stats %v", record[17], cs.Id)
|
||||
log.Printf("Error parsing CostInterval %v for cdrs stats %v", record[19], cs.Id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if triggers != nil {
|
||||
cs.Triggers = triggers
|
||||
cs.Triggers = append(cs.Triggers, triggers...)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,7 +341,7 @@ var FileValidators = map[string]*FileLineRegexValidator{
|
||||
regexp.MustCompile(`(?:\w+\s*,\s*){3}(?:\d+\.?\d*){1}`),
|
||||
"Tag([0-9A-Za-z_]),ActionsTag([0-9A-Za-z_]),TimingTag([0-9A-Za-z_]),Weight([0-9.])"},
|
||||
utils.ACTION_TRIGGERS_CSV: &FileLineRegexValidator{utils.ACTION_TRIGGERS_NRCOLS,
|
||||
regexp.MustCompile(`(?:\w+),(?:\*\w+),(?:\*out),(?:\*\w+),(?:\d+\.?\d*),(?:true|false)?,(?:\w+|\*any)?,(?:\w+),(?:\d+\.?\d*)$`),
|
||||
regexp.MustCompile(`(?:\w+),(?:\*\w+),(?:\*out),(?:\*\w+),(?:\d+\.?\d*),(?:true|false)?,(?:\d+),(?:\w+|\*any)?,(?:\d+\.?\d*)?,(?:\*\w+\s*|\+\d+[smh]\s*|\d+\s*)?,(?:\w+|\*any)?,(?:\w+|\*any)?,(?:\d+),(?:\w+),(?:\d+\.?\d*)$`),
|
||||
"Tag([0-9A-Za-z_]),BalanceType(*[a-z_]),Direction(*out),ThresholdType(*[a-z_]),ThresholdValue([0-9]+),Recurrent(true|false),DestinationTag([0-9A-Za-z_]|*all),ActionsTag([0-9A-Za-z_]),Weight([0-9]+)"},
|
||||
utils.ACCOUNT_ACTIONS_CSV: &FileLineRegexValidator{utils.ACCOUNT_ACTIONS_NRCOLS,
|
||||
regexp.MustCompile(`(?:\w+\s*),(?:(\w+;?)+\s*),(?:\*out\s*),(?:\w+\s*),(?:\w+\s*)$`),
|
||||
|
||||
@@ -50,7 +50,7 @@ const (
|
||||
ACTION_TRIGGERS_CSV = "ActionTriggers.csv"
|
||||
ACCOUNT_ACTIONS_CSV = "AccountActions.csv"
|
||||
DERIVED_CHARGERS_CSV = "DerivedChargers.csv"
|
||||
CDR_STATS_CSV = "CdrStats.csv"
|
||||
CDR_STATS_CSV = "CdrStats.csv"
|
||||
TIMINGS_NRCOLS = 6
|
||||
DESTINATIONS_NRCOLS = 2
|
||||
RATES_NRCOLS = 6
|
||||
@@ -64,7 +64,7 @@ const (
|
||||
ACTION_TRIGGERS_NRCOLS = 15
|
||||
ACCOUNT_ACTIONS_NRCOLS = 5
|
||||
DERIVED_CHARGERS_NRCOLS = 17
|
||||
CDR_STATS_NRCOLS = 19
|
||||
CDR_STATS_NRCOLS = 21
|
||||
ROUNDING_UP = "*up"
|
||||
ROUNDING_MIDDLE = "*middle"
|
||||
ROUNDING_DOWN = "*down"
|
||||
|
||||
Reference in New Issue
Block a user