From 5e1dce7377bc92c294ddc1eb331850295022e718 Mon Sep 17 00:00:00 2001 From: edwardro22 Date: Mon, 5 Feb 2018 18:05:16 +0200 Subject: [PATCH] Added test for stats --- engine/stats_test.go | 382 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 338 insertions(+), 44 deletions(-) diff --git a/engine/stats_test.go b/engine/stats_test.go index 1d5311385..37ea9e80f 100644 --- a/engine/stats_test.go +++ b/engine/stats_test.go @@ -1,3 +1,5 @@ +// +build integr + /* Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments Copyright (C) ITsysCOM GmbH @@ -17,8 +19,8 @@ along with this program. If not, see */ package engine -/* import ( + "reflect" "testing" "time" @@ -26,53 +28,345 @@ import ( "github.com/cgrates/cgrates/utils" ) -func TestFilterPassStatS(t *testing.T) { - if cgrCfg := config.CgrConfig(); cgrCfg == nil { - cgrCfg, _ = config.NewDefaultCGRConfig() - config.SetCgrConfig(cgrCfg) +var ( + cloneExpTimeStats time.Time + expTimeStats = time.Now().Add(time.Duration(20 * time.Minute)) + + stsserv StatService + dmSTS *DataManager + + sqps = []*StatQueueProfile{ + &StatQueueProfile{ + Tenant: "cgrates.org", + ID: "statsprofile1", + FilterIDs: []string{"filter7"}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + }, + QueueLength: 10, + TTL: time.Duration(10) * time.Second, + Metrics: []*utils.MetricWithParams{ + &utils.MetricWithParams{ + MetricID: utils.MetaSum, + Parameters: utils.Usage, + }, + }, + ThresholdIDs: []string{}, + Blocker: true, + Stored: true, + Weight: 20, + MinItems: 1, + }, + &StatQueueProfile{ + Tenant: "cgrates.org", + ID: "statsprofile2", + FilterIDs: []string{"filter8"}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + }, + QueueLength: 10, + TTL: time.Duration(10) * time.Second, + Metrics: []*utils.MetricWithParams{ + &utils.MetricWithParams{ + MetricID: utils.MetaSum, + Parameters: utils.Usage, + }, + }, + ThresholdIDs: []string{}, + Blocker: true, + Stored: true, + Weight: 20, + MinItems: 1, + }, + &StatQueueProfile{ + Tenant: "cgrates.org", + ID: "statsprofile3", + FilterIDs: []string{"preffilter4"}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + }, + QueueLength: 10, + TTL: time.Duration(10) * time.Second, + Metrics: []*utils.MetricWithParams{ + &utils.MetricWithParams{ + MetricID: utils.MetaSum, + Parameters: utils.Usage, + }, + }, + ThresholdIDs: []string{}, + Blocker: true, + Stored: true, + Weight: 20, + MinItems: 1, + }, + &StatQueueProfile{ + Tenant: "cgrates.org", + ID: "statsprofile4", + FilterIDs: []string{"defaultf4"}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + }, + QueueLength: 10, + TTL: time.Duration(10) * time.Second, + Metrics: []*utils.MetricWithParams{ + &utils.MetricWithParams{ + MetricID: utils.MetaSum, + Parameters: utils.Usage, + }, + }, + ThresholdIDs: []string{}, + Blocker: true, + Stored: true, + Weight: 20, + MinItems: 1, + }, } - dataStorage, _ := engine.NewMapStorage() - dataStorage.SetStatsConfig( - &engine.StatsConfig{ID: "CDRST1", - Filters: []*engine.RequestFilter{ - &engine.RequestFilter{Type: engine.MetaString, FieldName: "Tenant", - Values: []string{"cgrates.org"}}}, - Metrics: []string{utils.MetaASR}}) - statS, err := NewStatService(dataStorage, dataStorage.Marshaler(), 0) + + stqs = []*StatQueue{ + &StatQueue{Tenant: "cgrates.org", ID: "statsprofile1", sqPrfl: sqps[0]}, + &StatQueue{Tenant: "cgrates.org", ID: "statsprofile2", sqPrfl: sqps[1]}, + &StatQueue{Tenant: "cgrates.org", ID: "statsprofile3", sqPrfl: sqps[2]}, + &StatQueue{Tenant: "cgrates.org", ID: "statsprofile4", sqPrfl: sqps[3]}, + } + + evs = []*utils.CGREvent{ + &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "event1", + Event: map[string]interface{}{ + "Stats": "StatsProfile1", + utils.AnswerTime: time.Date(2014, 7, 14, 14, 30, 0, 0, time.UTC), + "UsageInterval": "1s", + "PddInterval": "1s", + "Weight": "20.0", + utils.Usage: time.Duration(135 * time.Second), + utils.COST: 123.0, + }}, + &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "event2", + Event: map[string]interface{}{ + "Stats": "StatsProfile2", + utils.AnswerTime: time.Date(2014, 7, 14, 14, 30, 0, 0, time.UTC), + "UsageInterval": "1s", + "PddInterval": "1s", + "Weight": "21.0", + utils.Usage: time.Duration(45 * time.Second), + }}, + &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "event3", + Event: map[string]interface{}{ + "Stats": "StatsProfilePrefix", + utils.Usage: time.Duration(30 * time.Second), + }}, + &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "event3", + Event: map[string]interface{}{ + "Weight": "200.0", + utils.Usage: time.Duration(65 * time.Second), + }}, + } +) + +func TestStatsPopulateStatsService(t *testing.T) { + data, _ := NewMapStorage() + dmSTS = NewDataManager(data) + var filters1 []*FilterRule + var filters2 []*FilterRule + var preffilter []*FilterRule + var defaultf []*FilterRule + second := 1 * time.Second + stsserv = StatService{ + dm: dmSTS, + filterS: &FilterS{dm: dmSTS}, + } + ref := NewFilterIndexer(dmSTS, utils.StatQueueProfilePrefix, "cgrates.org") + + //filter1 + x, err := NewFilterRule(MetaString, "Stats", []string{"StatsProfile1"}) if err != nil { - t.Fatal(err) + t.Errorf("Error: %+v", err) } - var replyStr string - if err := statS.Call("StatSV1.LoadQueues", ArgsLoadQueues{}, - &replyStr); err != nil { - t.Error(err) - } else if replyStr != utils.OK { - t.Errorf("reply received: %s", replyStr) - } - cdr := &engine.CDR{ - Tenant: "cgrates.org", - Category: "call", - AnswerTime: time.Now(), - SetupTime: time.Now(), - Usage: 10 * time.Second, - Cost: 10, - Supplier: "suppl1", - DisconnectCause: "NORMAL_CLEARNING", - } - cdrMp, _ := cdr.AsMapStringIface() - cdrMp[utils.ID] = "event1" - if err := statS.processEvent(cdrMp); err != nil { - t.Error(err) - } - rf, err := engine.NewRequestFilter(engine.MetaStatS, "", - []string{"CDRST1:*min_asr:20"}) + filters1 = append(filters1, x) + x, err = NewFilterRule(MetaGreaterOrEqual, "UsageInterval", []string{second.String()}) if err != nil { - t.Fatal(err) + t.Errorf("Error: %+v", err) } - if passes, err := rf.Pass(cdr, "", statS); err != nil { - t.Error(err) - } else if !passes { - t.Error("Not passing") + filters1 = append(filters1, x) + x, err = NewFilterRule(MetaGreaterOrEqual, utils.Usage, []string{second.String()}) + if err != nil { + t.Errorf("Error: %+v", err) + } + filters1 = append(filters1, x) + x, err = NewFilterRule(MetaGreaterOrEqual, "Weight", []string{"9.0"}) + if err != nil { + t.Errorf("Error: %+v", err) + } + filters1 = append(filters1, x) + filter7 := &Filter{Tenant: config.CgrConfig().DefaultTenant, ID: "filter7", Rules: filters1} + dmSTS.SetFilter(filter7) + ref.IndexTPFilter(FilterToTPFilter(filter7), "statsprofile1") + + //filter2 + x, err = NewFilterRule(MetaString, "Stats", []string{"StatsProfile2"}) + if err != nil { + t.Errorf("Error: %+v", err) + } + filters2 = append(filters2, x) + x, err = NewFilterRule(MetaGreaterOrEqual, "PddInterval", []string{second.String()}) + if err != nil { + t.Errorf("Error: %+v", err) + } + filters2 = append(filters2, x) + x, err = NewFilterRule(MetaGreaterOrEqual, utils.Usage, []string{second.String()}) + if err != nil { + t.Errorf("Error: %+v", err) + } + filters2 = append(filters2, x) + x, err = NewFilterRule(MetaGreaterOrEqual, "Weight", []string{"15.0"}) + if err != nil { + t.Errorf("Error: %+v", err) + } + filters2 = append(filters2, x) + filter8 := &Filter{Tenant: config.CgrConfig().DefaultTenant, ID: "filter8", Rules: filters2} + dmSTS.SetFilter(filter8) + ref.IndexTPFilter(FilterToTPFilter(filter8), "statsprofile2") + + //prefix filter + x, err = NewFilterRule(MetaPrefix, "Stats", []string{"StatsProfilePrefix"}) + if err != nil { + t.Errorf("Error: %+v", err) + } + preffilter = append(preffilter, x) + x, err = NewFilterRule(MetaGreaterOrEqual, utils.Usage, []string{second.String()}) + if err != nil { + t.Errorf("Error: %+v", err) + } + preffilter = append(preffilter, x) + preffilter4 := &Filter{Tenant: config.CgrConfig().DefaultTenant, ID: "preffilter4", Rules: preffilter} + dmSTS.SetFilter(preffilter4) + ref.IndexTPFilter(FilterToTPFilter(preffilter4), "statsprofile3") + + //default filter + x, err = NewFilterRule(MetaGreaterOrEqual, "Weight", []string{"200.00"}) + if err != nil { + t.Errorf("Error: %+v", err) + } + defaultf = append(defaultf, x) + x, err = NewFilterRule(MetaGreaterOrEqual, utils.Usage, []string{second.String()}) + if err != nil { + t.Errorf("Error: %+v", err) + } + defaultf = append(defaultf, x) + defaultf4 := &Filter{Tenant: config.CgrConfig().DefaultTenant, ID: "defaultf4", Rules: defaultf} + dmSTS.SetFilter(defaultf4) + ref.IndexTPFilter(FilterToTPFilter(defaultf4), "statsprofile4") + + for _, stq := range stqs { + dmSTS.SetStatQueue(stq) + } + + for _, sqp := range sqps { + dmSTS.SetStatQueueProfile(sqp, false) + } + + err = ref.StoreIndexes() + if err != nil { + t.Errorf("Error: %+v", err) + } +} + +func TestStatsmatchingStatQueuesForEvent(t *testing.T) { + msq, err := stsserv.matchingStatQueuesForEvent(evs[0]) + if err != nil { + t.Errorf("Error: %+v", err) + } + if !reflect.DeepEqual(stqs[0].Tenant, msq[0].Tenant) { + t.Errorf("Expecting: %+v, received: %+v", stqs[0].Tenant, msq[0].Tenant) + } else if !reflect.DeepEqual(stqs[0].ID, msq[0].ID) { + t.Errorf("Expecting: %+v, received: %+v", stqs[0].ID, msq[0].ID) + } else if !reflect.DeepEqual(stqs[0].sqPrfl, msq[0].sqPrfl) { + t.Errorf("Expecting: %+v, received: %+v", stqs[0].sqPrfl, msq[0].sqPrfl) + } + msq, err = stsserv.matchingStatQueuesForEvent(evs[1]) + if err != nil { + t.Errorf("Error: %+v", err) + } + if !reflect.DeepEqual(stqs[1].Tenant, msq[0].Tenant) { + t.Errorf("Expecting: %+v, received: %+v", stqs[1].Tenant, msq[0].Tenant) + } else if !reflect.DeepEqual(stqs[1].ID, msq[0].ID) { + t.Errorf("Expecting: %+v, received: %+v", stqs[1].ID, msq[0].ID) + } else if !reflect.DeepEqual(stqs[1].sqPrfl, msq[0].sqPrfl) { + t.Errorf("Expecting: %+v, received: %+v", stqs[1].sqPrfl, msq[0].sqPrfl) + } + msq, err = stsserv.matchingStatQueuesForEvent(evs[2]) + if err != nil { + t.Errorf("Error: %+v", err) + } + if !reflect.DeepEqual(stqs[2].Tenant, msq[0].Tenant) { + t.Errorf("Expecting: %+v, received: %+v", stqs[2].Tenant, msq[0].Tenant) + } else if !reflect.DeepEqual(stqs[2].ID, msq[0].ID) { + t.Errorf("Expecting: %+v, received: %+v", stqs[2].ID, msq[0].ID) + } else if !reflect.DeepEqual(stqs[2].sqPrfl, msq[0].sqPrfl) { + t.Errorf("Expecting: %+v, received: %+v", stqs[2].sqPrfl, msq[0].sqPrfl) + } + msq, err = stsserv.matchingStatQueuesForEvent(evs[3]) + if err != nil { + t.Errorf("Error: %+v", err) + } + if !reflect.DeepEqual(stqs[3].Tenant, msq[0].Tenant) { + t.Errorf("Expecting: %+v, received: %+v", stqs[3].Tenant, msq[0].Tenant) + } else if !reflect.DeepEqual(stqs[3].ID, msq[0].ID) { + t.Errorf("Expecting: %+v, received: %+v", stqs[3].ID, msq[0].ID) + } else if !reflect.DeepEqual(stqs[3].sqPrfl, msq[0].sqPrfl) { + t.Errorf("Expecting: %+v, received: %+v", stqs[3].sqPrfl, msq[0].sqPrfl) + } +} + +//to be updated after thresholds gets fixed +func TestStatSprocessEvent(t *testing.T) { + stq := map[string]string{} + reply := "" + err := stsserv.V1ProcessEvent(evs[0], &reply) + if err != nil { + t.Errorf("Error: %+v", err) + } else if reply != utils.OK { + t.Errorf("received reply: %s", reply) + } + err = stsserv.V1GetQueueStringMetrics(&utils.TenantID{Tenant: stqs[0].Tenant, ID: stqs[0].ID}, &stq) + if err != nil { + t.Errorf("Error: %+v", err) + } + err = stsserv.V1ProcessEvent(evs[1], &reply) + if err != nil { + t.Errorf("Error: %+v", err) + } else if reply != utils.OK { + t.Errorf("received reply: %s", reply) + } + err = stsserv.V1GetQueueStringMetrics(&utils.TenantID{Tenant: stqs[1].Tenant, ID: stqs[1].ID}, &stq) + if err != nil { + t.Errorf("Error: %+v", err) + } + err = stsserv.V1ProcessEvent(evs[2], &reply) + if err != nil { + t.Errorf("Error: %+v", err) + } else if reply != utils.OK { + t.Errorf("received reply: %s", reply) + } + err = stsserv.V1GetQueueStringMetrics(&utils.TenantID{Tenant: stqs[2].Tenant, ID: stqs[2].ID}, &stq) + if err != nil { + t.Errorf("Error: %+v", err) + } + err = stsserv.V1ProcessEvent(evs[3], &reply) + if err != nil { + t.Errorf("Error: %+v", err) + } else if reply != utils.OK { + t.Errorf("received reply: %s", reply) + } + err = stsserv.V1GetQueueStringMetrics(&utils.TenantID{Tenant: stqs[3].Tenant, ID: stqs[3].ID}, &stq) + if err != nil { + t.Errorf("Error: %+v", err) } } -*/