Improved stats + tests

This commit is contained in:
porosnicuadrian
2022-04-08 16:28:02 +03:00
committed by Dan Christian Bogos
parent d8289fa9d6
commit bb41017266
7 changed files with 711 additions and 734 deletions

View File

@@ -597,6 +597,7 @@ func TestStatsAPIs(t *testing.T) {
utils.StatID: "sq2",
},
APIOpts: map[string]interface{}{
utils.MetaUsage: 3000,
utils.MetaEventType: utils.StatUpdate,
utils.OptsThresholdsProfileIDs: []string{"thdID"},
utils.OptsStatsProfileIDs: []string{"sq1", "sq2"},
@@ -754,9 +755,10 @@ func TestStatsAPIs(t *testing.T) {
ID: "StatsEventTest",
Event: map[string]interface{}{
utils.AccountField: "1002",
utils.Usage: 3000,
//utils.Usage: 3000,
},
APIOpts: map[string]interface{}{
utils.MetaUsage: 3000,
utils.OptsStatsProfileIDs: []string{"sq1", "sq2"},
},
}

View File

@@ -84,13 +84,13 @@ func TestStatRemEventWithID(t *testing.T) {
t.Errorf("unexpected Events in asrMetric: %+v", asrMetric.Events)
}
sq.remEventWithID("cgrates.org:TestRemEventWithID_2")
if asr := asrMetric.GetValue(); asr.Compare(utils.NewDecimal(-1, 0)) != 0 {
if asr := asrMetric.GetValue(); asr.Compare(utils.DecimalNaN) != 0 {
t.Errorf("received asrMetric: %v", asrMetric)
} else if len(asrMetric.Events) != 0 {
t.Errorf("unexpected Events in asrMetric: %+v", asrMetric.Events)
}
sq.remEventWithID("cgrates.org:TestRemEventWithID_2")
if asr := asrMetric.GetValue(); asr.Compare(utils.NewDecimal(-1, 0)) != 0 {
if asr := asrMetric.GetValue(); asr.Compare(utils.DecimalNaN) != 0 {
t.Errorf("received asrMetric: %v", asrMetric)
} else if len(asrMetric.Events) != 0 {
t.Errorf("unexpected Events in asrMetric: %+v", asrMetric.Events)
@@ -131,13 +131,13 @@ func TestStatRemEventWithID2(t *testing.T) {
}
sq.remEventWithID("cgrates.org:TestRemEventWithID_2")
sq.remEventWithID("cgrates.org:TestRemEventWithID_1")
if asr := asrMetric.GetValue(); asr.Compare(utils.NewDecimal(-1, 0)) != 0 {
if asr := asrMetric.GetValue(); asr.Compare(utils.DecimalNaN) != 0 {
t.Errorf("received asrMetric: %v", asrMetric)
} else if len(asrMetric.Events) != 0 {
t.Errorf("unexpected Events in asrMetric: %+v", asrMetric.Events)
}
sq.remEventWithID("cgrates.org:TestRemEventWithID_2")
if asr := asrMetric.GetValue(); asr.Compare(utils.NewDecimal(-1, 0)) != 0 {
if asr := asrMetric.GetValue(); asr.Compare(utils.DecimalNaN) != 0 {
t.Errorf("received asrMetric: %v", asrMetric)
} else if len(asrMetric.Events) != 0 {
t.Errorf("unexpected Events in asrMetric: %+v", asrMetric.Events)
@@ -234,15 +234,19 @@ func TestStatAddStatEvent(t *testing.T) {
t.Errorf("received ASR: %v", asr)
}
ev1 := &utils.CGREvent{Tenant: "cgrates.org", ID: "TestStatAddStatEvent_1"}
sq.addStatEvent(context.Background(), ev1.Tenant, ev1.ID, nil, utils.MapStorage{utils.MetaReq: ev1.Event})
sq.addStatEvent(context.Background(), ev1.Tenant, ev1.ID, nil, utils.MapStorage{utils.MetaOpts: ev1.Event})
if asr := asrMetric.GetValue(); asr.Compare(utils.NewDecimalFromFloat64(50)) != 0 {
t.Errorf("received ASR: %v", asr)
} else if asrMetric.Value.Compare(utils.NewDecimal(1, 0)) != 0 || asrMetric.Count != 2 {
t.Errorf("ASR: %v", asrMetric)
}
ev1.Event = map[string]interface{}{
utils.AnswerTime: time.Now()}
sq.addStatEvent(context.Background(), ev1.Tenant, ev1.ID, nil, utils.MapStorage{utils.MetaReq: ev1.Event})
/*
ev1.Event = map[string]interface{}{
utils.AnswerTime: time.Now()}
*/
ev1.APIOpts = map[string]interface{}{
utils.MetaStartTime: time.Now()}
sq.addStatEvent(context.Background(), ev1.Tenant, ev1.ID, nil, utils.MapStorage{utils.MetaOpts: ev1.APIOpts})
if asr := asrMetric.GetValue(); asr.Compare(utils.NewDecimalFromFloat64(66.66666666666667)) != 0 {
t.Errorf("received ASR: %v", asr)
} else if asrMetric.Value.Compare(utils.NewDecimal(2, 0)) != 0 || asrMetric.Count != 3 {

View File

@@ -99,22 +99,15 @@ func (asr *StatASR) GetValue() (val *utils.Decimal) {
func (asr *StatASR) AddEvent(evID string, ev utils.DataProvider) (err error) {
var answered int
var val interface{}
if val, err = ev.FieldAsInterface([]string{utils.MetaReq, utils.AnswerTime}); err != nil {
if err == utils.ErrNotFound {
if val, err = ev.FieldAsInterface([]string{utils.MetaOpts, utils.MetaStartTime}); err != nil {
if err != utils.ErrNotFound {
return utils.ErrPrefix(err, utils.MetaStartTime)
}
}
}
}
if val != nil {
if at, err := utils.IfaceAsTime(val,
config.CgrConfig().GeneralCfg().DefaultTimezone); err != nil {
if val, err = ev.FieldAsInterface([]string{utils.MetaOpts, utils.MetaStartTime}); err != nil {
if err != utils.ErrNotFound {
return err
} else if !at.IsZero() {
answered = 1
}
} else if at, err := utils.IfaceAsTime(val,
config.CgrConfig().GeneralCfg().DefaultTimezone); err != nil {
return err
} else if !at.IsZero() {
answered = 1
}
return asr.addEvent(evID, answered)
}
@@ -171,18 +164,12 @@ func (acd *StatACD) GetValue() *utils.Decimal {
}
func (acd *StatACD) AddEvent(evID string, ev utils.DataProvider) (err error) {
var ival interface{}
if ival, err = ev.FieldAsInterface([]string{utils.MetaReq, utils.Usage}); err != nil {
ival, err := ev.FieldAsInterface([]string{utils.MetaOpts, utils.MetaUsage})
if err != nil {
if err == utils.ErrNotFound {
if ival, err = ev.FieldAsInterface([]string{utils.MetaOpts, utils.MetaUsage}); err != nil {
if err == utils.ErrNotFound {
return utils.ErrPrefix(err, utils.MetaUsage)
}
return err
}
} else {
return err
err = utils.ErrPrefix(err, utils.MetaUsage)
}
return err
}
return acd.addEvent(evID, ival)
}
@@ -211,18 +198,12 @@ func (sum *StatTCD) GetStringValue(rounding int) string {
}
func (sum *StatTCD) AddEvent(evID string, ev utils.DataProvider) (err error) {
var ival interface{}
if ival, err = ev.FieldAsInterface([]string{utils.MetaReq, utils.Usage}); err != nil {
ival, err := ev.FieldAsInterface([]string{utils.MetaOpts, utils.MetaUsage})
if err != nil {
if err == utils.ErrNotFound {
if ival, err = ev.FieldAsInterface([]string{utils.MetaOpts, utils.MetaUsage}); err != nil {
if err == utils.ErrNotFound {
return utils.ErrPrefix(err, utils.MetaUsage)
}
return err
}
} else {
return err
err = utils.ErrPrefix(err, utils.MetaUsage)
}
return err
}
return sum.addEvent(evID, ival)
}
@@ -250,26 +231,20 @@ func (acc *StatACC) GetValue() *utils.Decimal {
return acc.getAvgValue()
}
func (acc *StatACC) AddEvent(evID string, ev utils.DataProvider) (err error) {
var ival interface{}
if ival, err = ev.FieldAsInterface([]string{utils.MetaReq, utils.Cost}); err != nil {
func (acc *StatACC) AddEvent(evID string, ev utils.DataProvider) error {
ival, err := ev.FieldAsInterface([]string{utils.MetaOpts, utils.MetaCost})
if err != nil {
if err == utils.ErrNotFound {
if ival, err = ev.FieldAsInterface([]string{utils.MetaOpts, utils.MetaCost}); err != nil {
if err == utils.ErrNotFound {
return utils.ErrPrefix(err, utils.MetaUsage)
}
return err
}
} else {
return err
err = utils.ErrPrefix(err, utils.MetaCost)
}
return err
}
val, err := utils.IfaceAsBig(ival)
if err != nil {
return err
}
if val.Cmp(decimal.New(0, 0)) < 0 {
return utils.ErrPrefix(utils.ErrNegative, utils.Cost)
return utils.ErrPrefix(utils.ErrNegative, utils.MetaCost)
}
return acc.addEvent(evID, val)
}
@@ -289,26 +264,20 @@ type StatTCC struct {
*Metric
}
func (tcc *StatTCC) AddEvent(evID string, ev utils.DataProvider) (err error) {
var ival interface{}
if ival, err = ev.FieldAsInterface([]string{utils.MetaReq, utils.Cost}); err != nil {
func (tcc *StatTCC) AddEvent(evID string, ev utils.DataProvider) error {
ival, err := ev.FieldAsInterface([]string{utils.MetaOpts, utils.MetaCost})
if err != nil {
if err == utils.ErrNotFound {
if ival, err = ev.FieldAsInterface([]string{utils.MetaOpts, utils.MetaCost}); err != nil {
if err == utils.ErrNotFound {
return utils.ErrPrefix(err, utils.MetaUsage)
}
return err
}
} else {
return err
err = utils.ErrPrefix(err, utils.MetaCost)
}
return err
}
val, err := utils.IfaceAsBig(ival)
if err != nil {
return err
}
if val.Cmp(decimal.New(0, 0)) < 0 {
return utils.ErrPrefix(utils.ErrNegative, utils.Cost)
return utils.ErrPrefix(utils.ErrNegative, utils.MetaCost)
}
return tcc.addEvent(evID, val)
}
@@ -767,8 +736,8 @@ func (dst *StatDistinct) GetValue() *utils.Decimal {
func (dst *StatDistinct) AddEvent(evID string, ev utils.DataProvider) (err error) {
var fieldValue string
// simply remove the ~*req. prefix and do normal process
if !strings.HasPrefix(dst.FieldName, utils.DynamicDataPrefix+utils.MetaReq+utils.NestingSep) {
// simply remove the ~*req./~*opts. prefix and do normal process
if !strings.HasPrefix(dst.FieldName, utils.DynamicDataPrefix+utils.MetaReq+utils.NestingSep) && !strings.HasPrefix(dst.FieldName, utils.DynamicDataPrefix+utils.MetaOpts+utils.NestingSep) {
return fmt.Errorf("Invalid format for field <%s>", dst.FieldName)
}

File diff suppressed because it is too large Load Diff

View File

@@ -483,7 +483,7 @@ func TestStatQueuesUpdateStatQueue(t *testing.T) {
Metrics: []*MetricWithFilters{{MetricID: utils.MetaTCC}},
}
sqm := NewTCC(0, utils.EmptyString, nil)
if err = sqm.AddEvent("ev1", utils.MapStorage{utils.MetaReq: utils.MapStorage{utils.Cost: 10}}); err != nil {
if err = sqm.AddEvent("ev1", utils.MapStorage{utils.MetaOpts: utils.MapStorage{utils.MetaCost: 10}}); err != nil {
t.Fatal(err)
}
sq := &StatQueue{

View File

@@ -132,10 +132,9 @@ func testV1RtStatsProcessStatsValid(t *testing.T) {
utils.Destination: "1021",
utils.Category: "call",
utils.Usage: "1m20s",
//utils.AnswerTime: "2022-04-01T05:00:00Z",
utils.Cost: 1.8,
},
APIOpts: map[string]interface{}{
utils.MetaCost: 1.8,
utils.MetaStartTime: "2022-04-01T05:00:00Z",
utils.MetaUsage: "1m20s",
},
@@ -162,9 +161,9 @@ func testV1RtStatsProcessStatsNotAnswered(t *testing.T) {
utils.AccountField: "1010",
utils.Destination: "1021",
utils.Usage: "26s",
utils.Cost: 1.8,
},
APIOpts: map[string]interface{}{
utils.MetaCost: 1.8,
utils.MetaUsage: "1m20s",
},
}
@@ -197,12 +196,11 @@ func testV1RtStatsProcessStatsNotAnswered(t *testing.T) {
Event: map[string]interface{}{
utils.AccountField: "1010",
utils.Category: "call",
utils.Usage: "50s",
utils.AnswerTime: "2022-04-01T05:00:00Z",
utils.Cost: 1.8,
},
APIOpts: map[string]interface{}{
utils.MetaUsage: "1m20s",
utils.MetaCost: 1.8,
utils.MetaUsage: "1m20s",
utils.MetaStartTime: "2022-04-01T05:00:00Z",
},
}
expected = []string{"STATS_TCC1", "STATS_TOP1", "STATS_TOP3"}

View File

@@ -50,7 +50,6 @@ var (
testV1RtsCaseFromFolder,
testV1RtsCaseGetRoutesAfterLoading,
testV1RtsCasesSortingRoutesWeightAccountValue,
testV1RtsCasesSortingRoutesWeightAllRoutes,
testV1RtsCasesSortingRoutesWeightNotMatchingValue,
// testV1RtsCasesSortingRoutesLowestCost,
@@ -670,7 +669,9 @@ func testV1RtsCasesSortingRoutesLowestCostDefaultUsage(t *testing.T) {
utils.AccountField: "1002",
utils.Destination: "1003",
utils.SetupTime: "2013-06-01T00:00:00Z",
utils.AnswerTime: "2013-06-01T05:00:00Z",
},
APIOpts: map[string]interface{}{
utils.MetaStartTime: "2013-06-01T05:00:00Z",
},
}
expSrtdRoutes := &engine.SortedRoutesList{
@@ -746,11 +747,11 @@ func testV1RtsCasesSortingRoutesLCSetStatsAndResForMatching(t *testing.T) {
utils.Usage: "2m30s",
utils.AccountField: "1004",
utils.Category: "vendor2",
utils.AnswerTime: "2013-06-01T05:00:00Z",
utils.Cost: 1.0,
},
APIOpts: map[string]interface{}{
utils.MetaUsage: "2m30s",
utils.MetaStartTime: "2013-06-01T05:00:00Z",
utils.MetaCost: 1.0,
utils.MetaUsage: "2m30s",
},
}
if err := rtsCaseSv1BiRpc.Call(context.Background(), utils.StatSv1ProcessEvent, ev1, &result); err != nil {
@@ -773,11 +774,10 @@ func testV1RtsCasesSortingRoutesLowestCostStats(t *testing.T) {
utils.AccountField: "1002",
utils.Destination: "1003",
utils.SetupTime: "2013-06-01T00:00:00Z",
utils.AnswerTime: "2013-06-01T05:00:00Z",
utils.Usage: "2m30s",
},
APIOpts: map[string]interface{}{
utils.MetaUsage: "2m30s",
utils.MetaStartTime: "2013-06-01T05:00:00Z",
utils.MetaUsage: "2m30s",
},
}
expSrtdRoutes := &engine.SortedRoutesList{
@@ -850,10 +850,10 @@ func testV1RtsCasesSortingRoutesLowestCosMatchingAllRoutes(t *testing.T) {
utils.AccountField: "1002",
utils.Destination: "1003",
utils.SetupTime: "2013-06-01T00:00:00Z",
utils.AnswerTime: "2013-06-01T05:00:00Z",
},
APIOpts: map[string]interface{}{
utils.MetaUsage: "2m30s",
utils.MetaStartTime: "2013-06-01T05:00:00Z",
utils.MetaUsage: "2m30s",
},
}
expSrtdRoutes := &engine.SortedRoutesList{
@@ -913,10 +913,9 @@ func testV1RtsCasesSortingRoutesLowestCosMaxCost(t *testing.T) {
utils.AccountField: "1002",
utils.Destination: "1003",
utils.SetupTime: "2013-06-01T00:00:00Z",
utils.AnswerTime: "2013-06-01T05:00:00Z",
utils.Usage: "2m30s",
},
APIOpts: map[string]interface{}{
utils.MetaStartTime: "2013-06-01T05:00:00Z",
utils.OptsRoutesMaxCost: "0.35",
utils.MetaUsage: "2m30s",
},
@@ -971,9 +970,9 @@ func testV1RtsCasesSortingRoutesLowestCosMaxCostNotMatch(t *testing.T) {
utils.AccountField: "1002",
utils.Destination: "1003",
utils.SetupTime: "2013-06-01T00:00:00Z",
utils.AnswerTime: "2013-06-01T05:00:00Z",
},
APIOpts: map[string]interface{}{
utils.MetaStartTime: "2013-06-01T05:00:00Z",
utils.OptsRoutesMaxCost: "0.05",
utils.MetaUsage: "2m30s",
},
@@ -996,11 +995,11 @@ func testV1RtsCasesSortingRoutesProcessMetrics(t *testing.T) {
utils.Usage: "2m30s",
utils.AccountField: "1004",
utils.Category: "vendor2",
utils.AnswerTime: "2013-06-01T05:00:00Z",
utils.Cost: 1.0,
},
APIOpts: map[string]interface{}{
utils.MetaUsage: "2m30s",
utils.MetaStartTime: "2013-06-01T05:00:00Z",
utils.MetaCost: 1.0,
utils.MetaUsage: "2m30s",
},
}
var result []string
@@ -1032,11 +1031,11 @@ func testV1RtsCasesSortingRoutesProcessMetrics(t *testing.T) {
utils.Usage: "2m30s",
utils.AccountField: "1004",
utils.Category: "vendor1",
utils.AnswerTime: "2013-06-01T05:00:00Z",
utils.Cost: 1.0,
},
APIOpts: map[string]interface{}{
utils.MetaUsage: "2m30s",
utils.MetaStartTime: "2013-06-01T05:00:00Z",
utils.MetaCost: 1.0,
utils.MetaUsage: "2m30s",
},
}
if err := rtsCaseSv1BiRpc.Call(context.Background(), utils.StatSv1ProcessEvent, ev1, &result); err != nil {
@@ -1069,10 +1068,10 @@ func testV1RtsCasesSortingRoutesQOS(t *testing.T) {
utils.AccountField: "1003",
utils.Destination: "1007",
utils.SetupTime: "2013-06-01T00:00:00Z",
utils.AnswerTime: "2013-06-01T05:00:00Z",
},
APIOpts: map[string]interface{}{
utils.MetaUsage: "50s",
utils.MetaStartTime: "2013-06-01T05:00:00Z",
utils.MetaUsage: "50s",
},
}
expSrtdRoutes := &engine.SortedRoutesList{
@@ -1124,11 +1123,11 @@ func testV1RtsCasesSortingRoutesQOSAllRoutes(t *testing.T) {
utils.Usage: "2m30s",
utils.AccountField: "1004",
utils.Category: "vendor1",
utils.AnswerTime: "2013-06-01T05:00:00Z",
utils.Cost: 10.0,
},
APIOpts: map[string]interface{}{
utils.MetaUsage: "2m30s",
utils.MetaStartTime: "2013-06-01T05:00:00Z",
utils.MetaCost: 10.0,
utils.MetaUsage: "2m30s",
},
}
var result []string
@@ -1145,10 +1144,10 @@ func testV1RtsCasesSortingRoutesQOSAllRoutes(t *testing.T) {
utils.AccountField: "1003",
utils.Destination: "1007",
utils.SetupTime: "2013-06-01T00:00:00Z",
utils.AnswerTime: "2013-06-01T05:00:00Z",
},
APIOpts: map[string]interface{}{
utils.MetaUsage: "50s",
utils.MetaStartTime: "2013-06-01T05:00:00Z",
utils.MetaUsage: "50s",
},
}
expSrtdRoutes := &engine.SortedRoutesList{
@@ -1211,10 +1210,10 @@ func testV1RtsCasesSortingRoutesQOSNotFound(t *testing.T) {
utils.AccountField: "1008",
utils.Destination: "1007",
utils.SetupTime: "2013-06-01T00:00:00Z",
utils.AnswerTime: "2013-06-01T05:00:00Z",
},
APIOpts: map[string]interface{}{
utils.MetaUsage: "50s",
utils.MetaStartTime: "2013-06-01T05:00:00Z",
utils.MetaUsage: "50s",
},
}
var reply *engine.SortedRoutesList
@@ -1378,13 +1377,13 @@ func testV1RtsCasesRoutesProcessStatsForLoadRtsSorting(t *testing.T) {
ID: "event1",
Event: map[string]interface{}{
//utils.AccountField: "1004",
utils.Usage: "1m20s",
utils.Category: "vendor1",
utils.AnswerTime: "2013-06-01T05:00:00Z",
utils.Cost: 1.8,
utils.Usage: "1m20s",
utils.Category: "vendor1",
},
APIOpts: map[string]interface{}{
utils.MetaUsage: "1m20s",
utils.MetaStartTime: "2013-06-01T05:00:00Z",
utils.MetaCost: 1.8,
utils.MetaUsage: "1m20s",
},
}
if err := rtsCaseSv1BiRpc.Call(context.Background(), utils.StatSv1ProcessEvent, ev1, &reply); err != nil {
@@ -1404,13 +1403,13 @@ func testV1RtsCasesRoutesProcessStatsForLoadRtsSorting(t *testing.T) {
ID: "event1",
Event: map[string]interface{}{
//utils.AccountField: "1004",
utils.Usage: "20s",
utils.Category: "vendor1",
utils.AnswerTime: "2013-06-01T05:00:00Z",
utils.Cost: 1.8,
utils.Usage: "20s",
utils.Category: "vendor1",
},
APIOpts: map[string]interface{}{
utils.MetaUsage: "20s",
utils.MetaUsage: "20s",
utils.MetaStartTime: "2013-06-01T05:00:00Z",
utils.MetaCost: 1.8,
},
}
if err := rtsCaseSv1BiRpc.Call(context.Background(), utils.StatSv1ProcessEvent, ev1, &reply); err != nil {
@@ -1432,13 +1431,13 @@ func testV1RtsCasesRoutesProcessStatsForLoadRtsSorting(t *testing.T) {
ID: "event1",
Event: map[string]interface{}{
//utils.AccountField: "1004",
utils.Usage: "30s",
utils.Category: "vendor2",
utils.AnswerTime: "2013-06-01T05:00:00Z",
utils.Cost: 0.77,
utils.Usage: "30s",
utils.Category: "vendor2",
},
APIOpts: map[string]interface{}{
utils.MetaUsage: "30s",
utils.MetaStartTime: "2013-06-01T05:00:00Z",
utils.MetaCost: 0.77,
utils.MetaUsage: "30s",
},
}
if err := rtsCaseSv1BiRpc.Call(context.Background(), utils.StatSv1ProcessEvent, ev1, &reply); err != nil {
@@ -1507,7 +1506,6 @@ func testV1RtsCasesSortRoutesHigherCostV2V3(t *testing.T) {
ID: "LC_SORT",
Tenant: "cgrates.org",
Event: map[string]interface{}{
utils.Usage: "3m25s",
utils.AccountField: "1008",
utils.Destination: "1007",
utils.SetupTime: "2013-06-01T00:00:00Z",
@@ -1632,7 +1630,6 @@ func testV1RtsCasesSortRoutesHigherCostV1V3(t *testing.T) {
ID: "LC_SORT",
Tenant: "cgrates.org",
Event: map[string]interface{}{
utils.Usage: "3m25s",
utils.AccountField: "1008",
utils.Destination: "1007",
utils.SetupTime: "2013-06-01T00:00:00Z",