From 6d4e968b685dca52cb25ccdfe92981daa51be852 Mon Sep 17 00:00:00 2001 From: porosnicuadrian Date: Thu, 11 Feb 2021 10:14:54 +0200 Subject: [PATCH] Coverage tests in accounts --- accounts/abstractbalance_test.go | 165 +++++++++++++++++++++++++++++++ accounts/libaccounts_test.go | 130 ++++++++++++++++++++++++ 2 files changed, 295 insertions(+) create mode 100644 accounts/libaccounts_test.go diff --git a/accounts/abstractbalance_test.go b/accounts/abstractbalance_test.go index 57020ff80..9a1cdadf5 100644 --- a/accounts/abstractbalance_test.go +++ b/accounts/abstractbalance_test.go @@ -22,6 +22,7 @@ import ( "testing" "time" + "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" "github.com/ericlagergren/decimal" @@ -533,3 +534,167 @@ func TestABCost0WithLimitExceedWithConcrete(t *testing.T) { t.Errorf("Unexpected units in concrete balance: %s", aB.cncrtBlncs[0].blnCfg.Units) } } + +func TestDebitUsageFiltersError(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + filters := engine.NewFilterS(cfg, nil, nil) + aB := &abstractBalance{ + blnCfg: &utils.Balance{ + ID: "ID_TEST", + Type: utils.MetaAbstract, + FilterIDs: []string{"*string:*~req.Usage:10s"}, + CostIncrements: []*utils.CostIncrement{ + { + Increment: utils.NewDecimal(int64(1*time.Second), 0), + RecurrentFee: utils.NewDecimal(2, 0), + }, + }, + Units: utils.NewDecimal(int64(50*time.Second), 0), + }, + fltrS: filters, + } + + cgrEv := &utils.CGREvent{ + Tenant: "cgrates.org", + Event: map[string]interface{}{ + utils.Usage: "10s", + }, + } + _, err := aB.debitUsage(utils.NewDecimal(int64(40*time.Second), 0), + cgrEv) + if err == nil || err != utils.ErrFilterNotPassingNoCaps { + t.Errorf("Expected %+v, received %+v", utils.ErrFilterNotPassingNoCaps, err) + } + + aB.blnCfg.FilterIDs = []string{"invalid_filter_format"} + _, err = aB.debitUsage(utils.NewDecimal(int64(40*time.Second), 0), + cgrEv) + if err == nil || err != utils.ErrNoDatabaseConn { + t.Errorf("Expected %+v, received %+v", utils.ErrNoDatabaseConn, err) + } +} + +func TestDebitUsageBalanceLimitErrors(t *testing.T) { + aB := &abstractBalance{ + blnCfg: &utils.Balance{ + ID: "ID_TEST", + Type: utils.MetaAbstract, + Opts: map[string]interface{}{ + utils.MetaBalanceLimit: "not_FLOAT64", + }, + CostIncrements: []*utils.CostIncrement{ + { + Increment: utils.NewDecimal(int64(1*time.Second), 0), + RecurrentFee: utils.NewDecimal(2, 0), + }, + }, + Units: utils.NewDecimal(int64(60*time.Second), 0), + }, + fltrS: new(engine.FilterS), + } + + cgrEv := &utils.CGREvent{ + Tenant: "cgrates.org", + Event: map[string]interface{}{ + utils.Usage: "10s", + }, + } + + expectedErr := "unsupported *balanceLimit format" + _, err := aB.debitUsage(utils.NewDecimal(int64(40*time.Second), 0), + cgrEv) + if err == nil || err.Error() != expectedErr { + t.Errorf("Expected %+v, received %+v", expectedErr, err) + } + + aB.blnCfg.Opts[utils.MetaBalanceLimit] = float64(16 * time.Second) + if _, err = aB.debitUsage(utils.NewDecimal(int64(40*time.Second), 0), + cgrEv); err != nil { + t.Error(err) + } + if aB.blnCfg.Units.Compare(utils.NewDecimal(int64(60*time.Second), 0)) != 0 { + t.Errorf("Expected %+v, received %+v", aB.blnCfg.Units.Big, utils.NewDecimal(int64(50*time.Second), 0)) + } +} + +func TestDebitUsageUnitFactorsErrors(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + filters := engine.NewFilterS(cfg, nil, nil) + aB := &abstractBalance{ + blnCfg: &utils.Balance{ + ID: "ID_TEST", + Type: utils.MetaAbstract, + UnitFactors: []*utils.UnitFactor{ + { + FilterIDs: []string{"invalid_filter_fromat"}, + Factor: utils.NewDecimal(2, 0), + }, + }, + CostIncrements: []*utils.CostIncrement{ + { + Increment: utils.NewDecimal(int64(1*time.Second), 0), + RecurrentFee: utils.NewDecimal(2, 0), + }, + }, + Units: utils.NewDecimal(int64(60*time.Second), 0), + }, + fltrS: filters, + } + + cgrEv := &utils.CGREvent{ + Tenant: "cgrates.org", + Event: map[string]interface{}{ + utils.Usage: "10s", + }, + } + + if _, err := aB.debitUsage(utils.NewDecimal(int64(20*time.Second), 0), cgrEv); err == nil || err != utils.ErrNoDatabaseConn { + t.Errorf("Expected %+v, received %+v", utils.ErrNoDatabaseConn, err) + } + + aB.blnCfg.UnitFactors[0].FilterIDs = []string{"*string:*~req.Usage:10s"} + if ec, err := aB.debitUsage(utils.NewDecimal(int64(20*time.Second), 0), cgrEv); err != nil { + t.Error(err) + } else if ec.Usage.Cmp(decimal.New(0, 0)) != 0 { + t.Error(err) + } +} + +func TestDebitUsageCostIncrementError(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + filters := engine.NewFilterS(cfg, nil, nil) + aB := &abstractBalance{ + blnCfg: &utils.Balance{ + ID: "ID_TEST", + Type: utils.MetaAbstract, + CostIncrements: []*utils.CostIncrement{ + { + FilterIDs: []string{"INVALID_FILTER_FORMAT"}, + Increment: utils.NewDecimal(int64(1*time.Second), 0), + RecurrentFee: utils.NewDecimal(2, 0), + }, + }, + Units: utils.NewDecimal(int64(60*time.Second), 0), + }, + fltrS: filters, + } + cgrEv := &utils.CGREvent{ + Tenant: "cgrates.org", + Event: map[string]interface{}{ + utils.Usage: "10s", + }, + } + + if _, err := aB.debitUsage(utils.NewDecimal(int64(20*time.Second), 0), cgrEv); err == nil || err != utils.ErrNoDatabaseConn { + t.Errorf("Expected %+v, received %+v", utils.ErrNoDatabaseConn, err) + } + + //Will check the error by making the event charge + //the cost is unknown, will use attributes to query from rates + aB.blnCfg.CostIncrements = nil + aB.blnCfg.AttributeIDs = []string{"attr11"} + expected := "NOT_CONNECTED: AttributeS" + if _, err := aB.debitUsage(utils.NewDecimal(int64(20*time.Second), 0), cgrEv); err == nil || err.Error() != expected { + t.Errorf("Expected %+v, received %+v", expected, err) + } +} diff --git a/accounts/libaccounts_test.go b/accounts/libaccounts_test.go new file mode 100644 index 000000000..85acb82db --- /dev/null +++ b/accounts/libaccounts_test.go @@ -0,0 +1,130 @@ +/* +Real-time Online/Offline Charging System (OerS) 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 accounts + +import ( + "reflect" + "testing" + "time" + + "github.com/cgrates/cgrates/config" + + "github.com/cgrates/rpcclient" + + "github.com/cgrates/cgrates/engine" + + "github.com/cgrates/cgrates/utils" +) + +func TestNewAccountBalanceOperators(t *testing.T) { + acntPrf := &utils.AccountProfile{ + ID: "TEST_ID", + Tenant: "cgrates.org", + Balances: map[string]*utils.Balance{ + "BL0": { + ID: "BALANCE1", + Type: utils.MetaAbstract, + }, + "BL1": { + ID: "BALANCE1", + Type: utils.MetaConcrete, + CostIncrements: []*utils.CostIncrement{ + { + Increment: utils.NewDecimal(int64(time.Second), 0), + }, + }, + }, + }, + } + config := config.NewDefaultCGRConfig() + filters := engine.NewFilterS(config, nil, nil) + + concrete, err := newBalanceOperator(acntPrf.Balances["BL1"], nil, filters, nil, nil, nil) + if err != nil { + t.Error(err) + } + var cncrtBlncs []*concreteBalance + cncrtBlncs = append(cncrtBlncs, concrete.(*concreteBalance)) + + expected := &abstractBalance{ + blnCfg: acntPrf.Balances["BL0"], + fltrS: filters, + cncrtBlncs: cncrtBlncs, + } + + if blcOp, err := newAccountBalanceOperators(acntPrf, filters, nil, + nil, nil); err != nil { + t.Error(err) + } else { + rcv := blcOp[0].(*abstractBalance) + if !reflect.DeepEqual(expected, rcv) { + t.Errorf("Expected %+v, received %+v", expected, rcv) + } + } + + acntPrf.Balances["BL1"].Type = "INVALID_TYPE" + expectedErr := "unsupported balance type: " + if _, err := newAccountBalanceOperators(acntPrf, filters, nil, + nil, nil); err == nil || err.Error() != expectedErr { + t.Errorf("Expected %+v, received %+v", expectedErr, err) + } +} + +type testMockCall struct { + calls map[string]func(args interface{}, reply interface{}) error +} + +func (tS *testMockCall) Call(method string, args interface{}, rply interface{}) error { + if call, has := tS.calls[method]; !has { + return rpcclient.ErrUnsupporteServiceMethod + } else { + return call(args, rply) + } +} + +func TestProcessAttributeS(t *testing.T) { + engine.Cache.Clear(nil) + + config := config.NewDefaultCGRConfig() + sTestMock := &testMockCall{ + calls: map[string]func(args interface{}, reply interface{}) error{ + utils.AttributeSv1ProcessEvent: func(args interface{}, reply interface{}) error { + return utils.ErrNotImplemented + }, + }, + } + chanInternal := make(chan rpcclient.ClientConnector, 1) + chanInternal <- sTestMock + connMgr := engine.NewConnManager(config, map[string]chan rpcclient.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes): chanInternal, + }) + cgrEvent := &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TEST_ID1", + Opts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: "20", + }, + } + + attrsConns := []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes)} + + if _, err := processAttributeS(connMgr, cgrEvent, attrsConns, nil); err == nil || err != utils.ErrNotImplemented { + t.Errorf("Expected %+v, received %+v", utils.ErrNotImplemented, err) + } +}