test for cdr stats csv load

This commit is contained in:
Radu Ioan Fericean
2014-07-30 14:23:31 +03:00
parent 8342a00fcb
commit b012922272
7 changed files with 88 additions and 32 deletions

View File

@@ -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
1 #Tag BalanceType BalanceTag Direction ThresholdType ThresholdValue Recurrent DestinationTag MinSleep BalanceDestinationTag BalanceWeight BalanceExpiryTime BalanceRatingSubject BalanceSharedGroup StatsMinQueuedItems ActionsTag Weight
2 STANDARD_TRIGGERS *monetary *monetary *out *min_balance 2 false 0 LOG_BALANCE 10
3 STANDARD_TRIGGERS *monetary *monetary *out *max_balance 20 false 0 LOG_BALANCE 10
4 STANDARD_TRIGGERS *monetary *monetary *out *max_counter 15 false FS_USERS 0 FS_USERS LOG_BALANCE 10
5 CDRST1_WARN_ASR *min_asr 45 true 1h 3 CDRST_WARN_HTTP 10
6 CDRST1_WARN_ACD *min_acd 10 true 1h 5 CDRST_WARN_HTTP 10
7 CDRST1_WARN_ACC *max_acc 10 true 10m 5 CDRST_WARN_HTTP 10
8 CDRST2_WARN_ASR *min_asr 30 true 5 CDRST_WARN_HTTP 10
9 CDRST2_WARN_ACD *min_acd 3 true 5 CDRST_WARN_HTTP 10

View File

@@ -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
1 #ActionsTag Action BalanceType Direction Units ExpiryTime DestinationTag RatingSubject BalanceWeight SharedGroup ExtraParameters Weight
2 PREPAID_10 *topup_reset *monetary *out 10 *unlimited *any 10 10
3 BONUS_1 *topup *monetary *out 1 *unlimited *any 10 10
4 LOG_BALANCE *log 10
5 CDRST_WARN_HTTP *call_url http://localhost:8080 10

View 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
1 #Id QueueLength TimeWindow Metrics SetupInterval TOR CdrHost CdrSource ReqType Direction Tenant Category Account Subject DestinationPrefix UsageInterval MediationRunIds RatedAccount RatedSubject CostInterval Triggers
2 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
3 CDRST1 ACD CDRST1_WARN_ACD
4 CDRST1 ACC CDRST1_WARN_ACC
5 CDRST2 10 10m ASR cgrates.org call CDRST2_WARN_ASR
6 CDRST2 ACD CDRST2_WARN_ACD

View File

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

View File

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

View File

@@ -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*)$`),

View File

@@ -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"