From 092ff2d459886d05468696dcf81330dff520c73e Mon Sep 17 00:00:00 2001 From: ionutboangiu Date: Fri, 7 May 2021 08:18:14 +0300 Subject: [PATCH] Move tests from resources_test.go to z_resources_test.go in engine --- engine/resources_test.go | 291 ------------------------------------ engine/z_resources_test.go | 299 +++++++++++++++++++++++++++++++------ 2 files changed, 255 insertions(+), 335 deletions(-) delete mode 100644 engine/resources_test.go diff --git a/engine/resources_test.go b/engine/resources_test.go deleted file mode 100644 index 555ea77fe..000000000 --- a/engine/resources_test.go +++ /dev/null @@ -1,291 +0,0 @@ -/* -Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments -Copyright (C) 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 -*/ - -package engine - -import ( - "bytes" - "fmt" - "log" - "os" - "reflect" - "strings" - "testing" - "time" - - "github.com/cgrates/cgrates/utils" -) - -func TestResourcesRemoveExpiredUnitsResetTotalUsage(t *testing.T) { - utils.Logger.SetLogLevel(4) - utils.Logger.SetSyslog(nil) - - var buf bytes.Buffer - log.SetOutput(&buf) - defer func() { - log.SetOutput(os.Stderr) - }() - - r := &Resource{ - TTLIdx: []string{"ResGroup1", "ResGroup2", "ResGroup3"}, - Usages: map[string]*ResourceUsage{ - "ResGroup2": { - Tenant: "cgrates.org", - ID: "RU_2", - Units: 11, - ExpiryTime: time.Date(2021, 5, 3, 13, 0, 0, 0, time.UTC), - }, - "ResGroup3": { - Tenant: "cgrates.org", - ID: "RU_3", - }, - }, - tUsage: utils.Float64Pointer(10), - } - - exp := &Resource{ - TTLIdx: []string{"ResGroup3"}, - Usages: map[string]*ResourceUsage{ - "ResGroup3": { - Tenant: "cgrates.org", - ID: "RU_3", - }, - }, - } - - explog := "CGRateS <> [WARNING] resetting total usage for resourceID: , usage smaller than 0: -1.000000\n" - r.removeExpiredUnits() - - if !reflect.DeepEqual(r, exp) { - t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", exp, r) - } - - rcvlog := buf.String()[20:] - if rcvlog != explog { - t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", explog, rcvlog) - } - - utils.Logger.SetLogLevel(0) -} - -func TestResourcesAvailable(t *testing.T) { - r := ResourceWithConfig{ - Resource: &Resource{ - Usages: map[string]*ResourceUsage{ - "RU_1": { - Units: 4, - }, - "RU_2": { - Units: 7, - }, - }, - }, - Config: &ResourceProfile{ - Limit: 10, - }, - } - - exp := -1.0 - rcv := r.Available() - - if rcv != exp { - t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", exp, rcv) - } -} - -func TestResourcesRecordUsageZeroTTL(t *testing.T) { - r := &Resource{ - Usages: map[string]*ResourceUsage{ - "RU_1": { - Tenant: "cgrates.org", - ID: "RU_1", - }, - }, - ttl: utils.DurationPointer(0), - } - ru := &ResourceUsage{ - ID: "RU_2", - } - - err := r.recordUsage(ru) - - if err != nil { - t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) - } -} - -func TestResourcesRecordUsageGtZeroTTL(t *testing.T) { - r := &Resource{ - Usages: map[string]*ResourceUsage{ - "RU_1": { - Tenant: "cgrates.org", - ID: "RU_1", - }, - }, - TTLIdx: []string{"RU_1"}, - ttl: utils.DurationPointer(1 * time.Second), - } - ru := &ResourceUsage{ - Tenant: "cgrates.org", - ID: "RU_2", - } - - exp := &Resource{ - Usages: map[string]*ResourceUsage{ - "RU_1": { - Tenant: "cgrates.org", - ID: "RU_1", - }, - "RU_2": { - Tenant: "cgrates.org", - ID: "RU_2", - }, - }, - TTLIdx: []string{"RU_1", "RU_2"}, - ttl: utils.DurationPointer(1 * time.Second), - } - err := r.recordUsage(ru) - exp.Usages[ru.ID].ExpiryTime = r.Usages[ru.ID].ExpiryTime - - if err != nil { - t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) - } - - if !reflect.DeepEqual(r, exp) { - t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", utils.ToJSON(exp), utils.ToJSON(r)) - } -} - -type mockWriter struct { - WriteF func(p []byte) (n int, err error) -} - -func (mW *mockWriter) Write(p []byte) (n int, err error) { - if mW.WriteF != nil { - return mW.WriteF(p) - } - return 0, nil -} - -func TestResourcesRecordUsageClearErr(t *testing.T) { - utils.Logger.SetLogLevel(4) - utils.Logger.SetSyslog(nil) - - var buf bytes.Buffer - - rs := Resources{ - { - Usages: map[string]*ResourceUsage{ - "RU_1": { - Tenant: "cgrates.org", - ID: "RU_1", - }, - "RU_2": { - Tenant: "cgrates.org", - ID: "RU_2", - }, - }, - TTLIdx: []string{"RU_1", "RU_2"}, - ttl: utils.DurationPointer(1 * time.Second), - }, - { - Usages: map[string]*ResourceUsage{ - "RU_3": { - Tenant: "cgrates.org", - ID: "RU_3", - }, - "RU_4": { - Tenant: "cgrates.org", - ID: "RU_4", - }, - }, - TTLIdx: []string{"RU_3"}, - ttl: utils.DurationPointer(2 * time.Second), - }, - } - - ru := &ResourceUsage{ - Tenant: "cgrates.org", - ID: "RU_4", - } - - exp := Resources{ - { - Usages: map[string]*ResourceUsage{ - "RU_1": { - Tenant: "cgrates.org", - ID: "RU_1", - }, - "RU_2": { - Tenant: "cgrates.org", - ID: "RU_2", - }, - }, - TTLIdx: []string{"RU_1", "RU_2", "RU_4"}, - ttl: utils.DurationPointer(1 * time.Second), - }, - { - Usages: map[string]*ResourceUsage{ - "RU_3": { - Tenant: "cgrates.org", - ID: "RU_3", - }, - "RU_4": { - Tenant: "cgrates.org", - ID: "RU_4", - }, - }, - TTLIdx: []string{"RU_3"}, - ttl: utils.DurationPointer(2 * time.Second), - }, - } - - explog := []string{ - fmt.Sprintf("CGRateS <> [WARNING] <%s>cannot record usage, err: duplicate resource usage with id: %s:%s", utils.ResourceS, ru.Tenant, ru.ID), - fmt.Sprintf("CGRateS <> [WARNING] <%s> cannot clear usage, err: cannot find usage record with id: %s", utils.ResourceS, ru.ID), - } - experr := fmt.Sprintf("duplicate resource usage with id: %s", "cgrates.org:"+ru.ID) - - defer log.SetOutput(os.Stderr) - log.SetOutput(&mockWriter{ - WriteF: func(p []byte) (n int, err error) { - delete(rs[0].Usages, "RU_4") - return buf.Write(p) - }, - }) - - err := rs.recordUsage(ru) - - if err == nil || err.Error() != experr { - t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", experr, err) - } - - if !reflect.DeepEqual(rs, exp) { - t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", utils.ToJSON(exp), utils.ToJSON(rs)) - } - - rcv := strings.Split(buf.String(), "\n") - for idx, exp := range explog { - rcv[idx] = rcv[idx][20:] - if rcv[idx] != exp { - t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", exp, rcv[idx]) - } - } - - utils.Logger.SetLogLevel(0) -} diff --git a/engine/z_resources_test.go b/engine/z_resources_test.go index 8dc1b741c..e7f52c7d8 100644 --- a/engine/z_resources_test.go +++ b/engine/z_resources_test.go @@ -18,7 +18,12 @@ along with this program. If not, see package engine import ( + "bytes" + "fmt" + "log" + "os" "reflect" + "strings" "testing" "time" @@ -2821,55 +2826,261 @@ func TestResourceCaching(t *testing.T) { } } -func TestResourceAllocateResourceOtherDB(t *testing.T) { - rProf := &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RL_DB", - FilterIDs: []string{"*string:~*opts.Resource:RL_DB"}, - Weight: 100, - Limit: 2, - ThresholdIDs: []string{utils.MetaNone}, - UsageTTL: -time.Nanosecond, - } +func TestResourcesRemoveExpiredUnitsResetTotalUsage(t *testing.T) { + utils.Logger.SetLogLevel(4) + utils.Logger.SetSyslog(nil) - Cache.Clear(nil) - cfg := config.NewDefaultCGRConfig() - dm := NewDataManager(NewInternalDB(nil, nil, true), cfg.CacheCfg(), nil) - fltS := NewFilterS(cfg, nil, dm) - rs := NewResourceService(dm, cfg, fltS, nil) - if err := dm.SetResourceProfile(rProf, true); err != nil { - t.Fatal(err) - } - if err := dm.SetResource(&Resource{ - Tenant: "cgrates.org", - ID: "RL_DB", + var buf bytes.Buffer + log.SetOutput(&buf) + defer func() { + log.SetOutput(os.Stderr) + }() + + r := &Resource{ + TTLIdx: []string{"ResGroup1", "ResGroup2", "ResGroup3"}, Usages: map[string]*ResourceUsage{ - "RU1": { // the resource in DB is expired (should be cleaned when the next allocate is called) + "ResGroup2": { Tenant: "cgrates.org", - ID: "RU1", - ExpiryTime: time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC), - Units: 1, + ID: "RU_2", + Units: 11, + ExpiryTime: time.Date(2021, 5, 3, 13, 0, 0, 0, time.UTC), + }, + "ResGroup3": { + Tenant: "cgrates.org", + ID: "RU_3", }, }, - TTLIdx: []string{"RU1"}, - }, nil, 2, true); err != nil { // simulate how the resource is stored in redis or mongo(non-exported fields are not populated) - t.Fatal(err) - } - var reply string - exp := rProf.ID - if err := rs.V1AllocateResources(utils.ArgRSv1ResourceUsage{ - CGREvent: &utils.CGREvent{ - Tenant: "cgrates.org", - ID: "ef0f554", - Event: map[string]interface{}{"": ""}, - APIOpts: map[string]interface{}{"Resource": "RL_DB"}, - }, - UsageID: "56156434-2e44-4f16-a766-086f10b413cd", - Units: 1, - }, &reply); err != nil { - t.Fatal(err) - } else if reply != exp { - t.Errorf("Expected: %q, received: %q", exp, reply) + tUsage: utils.Float64Pointer(10), } + exp := &Resource{ + TTLIdx: []string{"ResGroup3"}, + Usages: map[string]*ResourceUsage{ + "ResGroup3": { + Tenant: "cgrates.org", + ID: "RU_3", + }, + }, + } + + explog := "CGRateS <> [WARNING] resetting total usage for resourceID: , usage smaller than 0: -1.000000\n" + r.removeExpiredUnits() + + if !reflect.DeepEqual(r, exp) { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", exp, r) + } + + rcvlog := buf.String()[20:] + if rcvlog != explog { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", explog, rcvlog) + } + + utils.Logger.SetLogLevel(0) +} + +func TestResourcesAvailable(t *testing.T) { + r := ResourceWithConfig{ + Resource: &Resource{ + Usages: map[string]*ResourceUsage{ + "RU_1": { + Units: 4, + }, + "RU_2": { + Units: 7, + }, + }, + }, + Config: &ResourceProfile{ + Limit: 10, + }, + } + + exp := -1.0 + rcv := r.Available() + + if rcv != exp { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", exp, rcv) + } +} + +func TestResourcesRecordUsageZeroTTL(t *testing.T) { + r := &Resource{ + Usages: map[string]*ResourceUsage{ + "RU_1": { + Tenant: "cgrates.org", + ID: "RU_1", + }, + }, + ttl: utils.DurationPointer(0), + } + ru := &ResourceUsage{ + ID: "RU_2", + } + + err := r.recordUsage(ru) + + if err != nil { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) + } +} + +func TestResourcesRecordUsageGtZeroTTL(t *testing.T) { + r := &Resource{ + Usages: map[string]*ResourceUsage{ + "RU_1": { + Tenant: "cgrates.org", + ID: "RU_1", + }, + }, + TTLIdx: []string{"RU_1"}, + ttl: utils.DurationPointer(1 * time.Second), + } + ru := &ResourceUsage{ + Tenant: "cgrates.org", + ID: "RU_2", + } + + exp := &Resource{ + Usages: map[string]*ResourceUsage{ + "RU_1": { + Tenant: "cgrates.org", + ID: "RU_1", + }, + "RU_2": { + Tenant: "cgrates.org", + ID: "RU_2", + }, + }, + TTLIdx: []string{"RU_1", "RU_2"}, + ttl: utils.DurationPointer(1 * time.Second), + } + err := r.recordUsage(ru) + exp.Usages[ru.ID].ExpiryTime = r.Usages[ru.ID].ExpiryTime + + if err != nil { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) + } + + if !reflect.DeepEqual(r, exp) { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", utils.ToJSON(exp), utils.ToJSON(r)) + } +} + +type mockWriter struct { + WriteF func(p []byte) (n int, err error) +} + +func (mW *mockWriter) Write(p []byte) (n int, err error) { + if mW.WriteF != nil { + return mW.WriteF(p) + } + return 0, nil +} + +func TestResourcesRecordUsageClearErr(t *testing.T) { + utils.Logger.SetLogLevel(4) + utils.Logger.SetSyslog(nil) + + var buf bytes.Buffer + + rs := Resources{ + { + Usages: map[string]*ResourceUsage{ + "RU_1": { + Tenant: "cgrates.org", + ID: "RU_1", + }, + "RU_2": { + Tenant: "cgrates.org", + ID: "RU_2", + }, + }, + TTLIdx: []string{"RU_1", "RU_2"}, + ttl: utils.DurationPointer(1 * time.Second), + }, + { + Usages: map[string]*ResourceUsage{ + "RU_3": { + Tenant: "cgrates.org", + ID: "RU_3", + }, + "RU_4": { + Tenant: "cgrates.org", + ID: "RU_4", + }, + }, + TTLIdx: []string{"RU_3"}, + ttl: utils.DurationPointer(2 * time.Second), + }, + } + + ru := &ResourceUsage{ + Tenant: "cgrates.org", + ID: "RU_4", + } + + exp := Resources{ + { + Usages: map[string]*ResourceUsage{ + "RU_1": { + Tenant: "cgrates.org", + ID: "RU_1", + }, + "RU_2": { + Tenant: "cgrates.org", + ID: "RU_2", + }, + }, + TTLIdx: []string{"RU_1", "RU_2", "RU_4"}, + ttl: utils.DurationPointer(1 * time.Second), + }, + { + Usages: map[string]*ResourceUsage{ + "RU_3": { + Tenant: "cgrates.org", + ID: "RU_3", + }, + "RU_4": { + Tenant: "cgrates.org", + ID: "RU_4", + }, + }, + TTLIdx: []string{"RU_3"}, + ttl: utils.DurationPointer(2 * time.Second), + }, + } + + explog := []string{ + fmt.Sprintf("CGRateS <> [WARNING] <%s>cannot record usage, err: duplicate resource usage with id: %s:%s", utils.ResourceS, ru.Tenant, ru.ID), + fmt.Sprintf("CGRateS <> [WARNING] <%s> cannot clear usage, err: cannot find usage record with id: %s", utils.ResourceS, ru.ID), + } + experr := fmt.Sprintf("duplicate resource usage with id: %s", "cgrates.org:"+ru.ID) + + defer log.SetOutput(os.Stderr) + log.SetOutput(&mockWriter{ + WriteF: func(p []byte) (n int, err error) { + delete(rs[0].Usages, "RU_4") + return buf.Write(p) + }, + }) + + err := rs.recordUsage(ru) + + if err == nil || err.Error() != experr { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", experr, err) + } + + if !reflect.DeepEqual(rs, exp) { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", utils.ToJSON(exp), utils.ToJSON(rs)) + } + + rcv := strings.Split(buf.String(), "\n") + for idx, exp := range explog { + rcv[idx] = rcv[idx][20:] + if rcv[idx] != exp { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", exp, rcv[idx]) + } + } + + utils.Logger.SetLogLevel(0) }