Make go vet pass

The rpcclient constructor could not see the centralized
Encoding flag because it didn't have the necessary build
constraints. Added the constraints in lib_test.go files
where it wasn't alone. In all the other cases, it was
moved to the first file where it was needed.

Moved resources cache tests relying on DBType flag value
to a separate integration test file. Before it was getting
skipped for *internal anyway.
This commit is contained in:
ionutboangiu
2024-05-16 18:24:39 +03:00
committed by Dan Christian Bogos
parent 6d3d7b3b23
commit c0b665a015
10 changed files with 267 additions and 178 deletions

View File

@@ -22,9 +22,11 @@ package agents
import (
"crypto/rand"
"errors"
"fmt"
"math/big"
"net/rpc"
"net/rpc/jsonrpc"
"os"
"path"
"path/filepath"
@@ -177,8 +179,7 @@ func testRAHitInitCfg(t *testing.T) {
}
`
var folderNameSuffix *big.Int
folderNameSuffix, err = rand.Int(rand.Reader, big.NewInt(10000))
folderNameSuffix, err := rand.Int(rand.Reader, big.NewInt(10000))
if err != nil {
t.Fatalf("could not generate random number for folder name suffix, err: %s", err.Error())
}
@@ -225,7 +226,14 @@ func testRAHitStartEngine(t *testing.T) {
// Connect rpc client to rater
func testRAHitApierRpcConn(t *testing.T) {
var err error
raHRPC, err = newRPCClient(raHCfg.ListenCfg()) // We connect over JSON so we can also troubleshoot if needed
switch *utils.Encoding {
case utils.MetaJSON:
raHRPC, err = jsonrpc.Dial(utils.TCP, raHCfg.ListenCfg().RPCJSONListen)
case utils.MetaGOB:
raHRPC, err = rpc.Dial(utils.TCP, raHCfg.ListenCfg().RPCGOBListen)
default:
err = errors.New("UNSUPPORTED_RPC")
}
if err != nil {
t.Fatal(err)
}
@@ -271,6 +279,7 @@ cgrates.org,ATTR_RAD,*any,*string:~*req.RadUserName:10011;*prefix:~*req.RadPassw
}
func testRAHitEmptyValueHandling(t *testing.T) {
var err error
if raHAuthClnt, err = radigo.NewClient("udp", "127.0.0.1:1812", "CGRateS.org", dictRad, 1, nil); err != nil {
t.Fatal(err)
}

View File

@@ -1,3 +1,5 @@
//go:build integration || flaky
/*
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
Copyright (C) ITsysCOM GmbH

145
engine/resources_it_test.go Normal file
View File

@@ -0,0 +1,145 @@
//go:build integration
// +build integration
/*
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 <http://www.gnu.org/licenses/>
*/
package engine
import (
"reflect"
"testing"
"time"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/utils"
)
// TestRSCacheSetGet assurace the presence of private params in cached resource
func TestRSCacheSetGet(t *testing.T) {
if *utils.DBType == utils.MetaInternal {
t.SkipNow()
}
r := &Resource{
Tenant: "cgrates.org",
ID: "RL",
rPrf: &ResourceProfile{
Tenant: "cgrates.org",
ID: "RL",
FilterIDs: []string{"FLTR_RES_RL"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC),
ExpiryTime: time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC),
},
AllocationMessage: "ALLOC_RL",
Weight: 50,
Limit: 2,
ThresholdIDs: []string{"TEST_ACTIONS"},
UsageTTL: time.Duration(1 * time.Millisecond),
},
Usages: map[string]*ResourceUsage{
"RU2": {
Tenant: "cgrates.org",
ID: "RU2",
ExpiryTime: time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC),
Units: 2,
},
},
tUsage: utils.Float64Pointer(2),
dirty: utils.BoolPointer(true),
}
Cache.Set(utils.CacheResources, r.TenantID(), r, nil, true, "")
if x, ok := Cache.Get(utils.CacheResources, r.TenantID()); !ok {
t.Error("not in cache")
} else if x == nil {
t.Error("nil resource")
} else if !reflect.DeepEqual(r, x.(*Resource)) {
t.Errorf("Expecting: %+v, received: %+v", r, x)
}
}
func TestResourceCaching(t *testing.T) {
if *utils.DBType == utils.MetaInternal {
t.SkipNow()
}
//clear the cache
Cache.Clear(nil)
// start fresh with new dataManager
defaultCfg, _ := config.NewDefaultCGRConfig()
data := NewInternalDB(nil, nil, true, defaultCfg.DataDbCfg().Items)
dmRES = NewDataManager(data, config.CgrConfig().CacheCfg(), nil)
defaultCfg.ResourceSCfg().StoreInterval = 1
defaultCfg.ResourceSCfg().StringIndexedFields = nil
defaultCfg.ResourceSCfg().PrefixIndexedFields = nil
resService, err = NewResourceService(dmRES, defaultCfg,
&FilterS{dm: dmRES, cfg: defaultCfg}, nil)
if err != nil {
t.Errorf("Error: %+v", err)
}
resProf := &ResourceProfile{
Tenant: "cgrates.org",
ID: "ResourceProfileCached",
FilterIDs: []string{"*string:~*req.Account:1001"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
},
UsageTTL: time.Duration(-1),
Limit: 10.00,
AllocationMessage: "AllocationMessage",
Weight: 20.00,
ThresholdIDs: []string{utils.META_NONE},
}
Cache.Set(utils.CacheResourceProfiles, "cgrates.org:ResourceProfileCached",
resProf, nil, cacheCommit(utils.EmptyString), utils.EmptyString)
res := &Resource{Tenant: resProf.Tenant,
ID: resProf.ID,
Usages: make(map[string]*ResourceUsage)}
Cache.Set(utils.CacheResources, "cgrates.org:ResourceProfileCached",
res, nil, cacheCommit(utils.EmptyString), utils.EmptyString)
resources := Resources{res}
Cache.Set(utils.CacheEventResources, "TestResourceCaching", resources.resIDsMp(), nil, true, "")
ev := &utils.CGREvent{
Tenant: "cgrates.org",
ID: utils.UUIDSha1Prefix(),
Event: map[string]any{
"Account": "1001",
"Destination": "3002"},
}
mres, err := resService.matchingResourcesForEvent(ev,
"TestResourceCaching", nil)
if err != nil {
t.Errorf("Error: %+v", err)
}
mres.unlock()
if !reflect.DeepEqual(resources[0].Tenant, mres[0].Tenant) {
t.Errorf("Expecting: %+v, received: %+v", resources[0].Tenant, mres[0].Tenant)
} else if !reflect.DeepEqual(resources[0].ID, mres[0].ID) {
t.Errorf("Expecting: %+v, received: %+v", resources[0].ID, mres[0].ID)
} else if !reflect.DeepEqual(resources[0].rPrf, mres[0].rPrf) {
t.Errorf("Expecting: %+v, received: %+v", resources[0].rPrf, mres[0].rPrf)
} else if !reflect.DeepEqual(resources[0].ttl, mres[0].ttl) {
t.Errorf("Expecting: %+v, received: %+v", resources[0].ttl, mres[0].ttl)
}
}

View File

@@ -325,49 +325,6 @@ func TestResourceAllocateResource(t *testing.T) {
}
}
// TestRSCacheSetGet assurace the presence of private params in cached resource
func TestRSCacheSetGet(t *testing.T) {
if *utils.DBType == utils.MetaInternal {
t.SkipNow()
}
r := &Resource{
Tenant: "cgrates.org",
ID: "RL",
rPrf: &ResourceProfile{
Tenant: "cgrates.org",
ID: "RL",
FilterIDs: []string{"FLTR_RES_RL"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC),
ExpiryTime: time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC),
},
AllocationMessage: "ALLOC_RL",
Weight: 50,
Limit: 2,
ThresholdIDs: []string{"TEST_ACTIONS"},
UsageTTL: time.Duration(1 * time.Millisecond),
},
Usages: map[string]*ResourceUsage{
"RU2": {
Tenant: "cgrates.org",
ID: "RU2",
ExpiryTime: time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC),
Units: 2,
},
},
tUsage: utils.Float64Pointer(2),
dirty: utils.BoolPointer(true),
}
Cache.Set(utils.CacheResources, r.TenantID(), r, nil, true, "")
if x, ok := Cache.Get(utils.CacheResources, r.TenantID()); !ok {
t.Error("not in cache")
} else if x == nil {
t.Error("nil resource")
} else if !reflect.DeepEqual(r, x.(*Resource)) {
t.Errorf("Expecting: %+v, received: %+v", r, x)
}
}
func TestResourcePopulateResourceService(t *testing.T) {
defaultCfg, _ := config.NewDefaultCGRConfig()
data := NewInternalDB(nil, nil, true, defaultCfg.DataDbCfg().Items)
@@ -734,78 +691,6 @@ func TestResourceIDs(t *testing.T) {
}
}
func TestResourceCaching(t *testing.T) {
if *utils.DBType == utils.MetaInternal {
t.SkipNow()
}
//clear the cache
Cache.Clear(nil)
// start fresh with new dataManager
defaultCfg, _ := config.NewDefaultCGRConfig()
data := NewInternalDB(nil, nil, true, defaultCfg.DataDbCfg().Items)
dmRES = NewDataManager(data, config.CgrConfig().CacheCfg(), nil)
defaultCfg.ResourceSCfg().StoreInterval = 1
defaultCfg.ResourceSCfg().StringIndexedFields = nil
defaultCfg.ResourceSCfg().PrefixIndexedFields = nil
resService, err = NewResourceService(dmRES, defaultCfg,
&FilterS{dm: dmRES, cfg: defaultCfg}, nil)
if err != nil {
t.Errorf("Error: %+v", err)
}
resProf := &ResourceProfile{
Tenant: "cgrates.org",
ID: "ResourceProfileCached",
FilterIDs: []string{"*string:~*req.Account:1001"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
},
UsageTTL: time.Duration(-1),
Limit: 10.00,
AllocationMessage: "AllocationMessage",
Weight: 20.00,
ThresholdIDs: []string{utils.META_NONE},
}
Cache.Set(utils.CacheResourceProfiles, "cgrates.org:ResourceProfileCached",
resProf, nil, cacheCommit(utils.EmptyString), utils.EmptyString)
res := &Resource{Tenant: resProf.Tenant,
ID: resProf.ID,
Usages: make(map[string]*ResourceUsage)}
Cache.Set(utils.CacheResources, "cgrates.org:ResourceProfileCached",
res, nil, cacheCommit(utils.EmptyString), utils.EmptyString)
resources := Resources{res}
Cache.Set(utils.CacheEventResources, "TestResourceCaching", resources.resIDsMp(), nil, true, "")
ev := &utils.CGREvent{
Tenant: "cgrates.org",
ID: utils.UUIDSha1Prefix(),
Event: map[string]any{
"Account": "1001",
"Destination": "3002"},
}
mres, err := resService.matchingResourcesForEvent(ev,
"TestResourceCaching", nil)
if err != nil {
t.Errorf("Error: %+v", err)
}
mres.unlock()
if !reflect.DeepEqual(resources[0].Tenant, mres[0].Tenant) {
t.Errorf("Expecting: %+v, received: %+v", resources[0].Tenant, mres[0].Tenant)
} else if !reflect.DeepEqual(resources[0].ID, mres[0].ID) {
t.Errorf("Expecting: %+v, received: %+v", resources[0].ID, mres[0].ID)
} else if !reflect.DeepEqual(resources[0].rPrf, mres[0].rPrf) {
t.Errorf("Expecting: %+v, received: %+v", resources[0].rPrf, mres[0].rPrf)
} else if !reflect.DeepEqual(resources[0].ttl, mres[0].ttl) {
t.Errorf("Expecting: %+v, received: %+v", resources[0].ttl, mres[0].ttl)
}
}
func TestResourcesStoreResourceError(t *testing.T) {
Cache.Clear(nil)
cfg, _ := config.NewDefaultCGRConfig()

View File

@@ -37,9 +37,9 @@ import (
)
var (
rdrEvents chan *erEvent
rdrErr chan error
rdrExit chan struct{}
kfkEvents chan *erEvent
kfkErr chan error
kfkExit chan struct{}
kfk EventReader
)
@@ -99,12 +99,12 @@ func TestKafkaER(t *testing.T) {
t.Fatal(err)
}
rdrEvents = make(chan *erEvent, 1)
rdrErr = make(chan error, 1)
rdrExit = make(chan struct{}, 1)
kfkEvents = make(chan *erEvent, 1)
kfkErr = make(chan error, 1)
kfkExit = make(chan struct{}, 1)
if kfk, err = NewKafkaER(cfg, 1, rdrEvents,
rdrErr, new(engine.FilterS), rdrExit); err != nil {
if kfk, err = NewKafkaER(cfg, 1, kfkEvents,
kfkErr, new(engine.FilterS), kfkExit); err != nil {
t.Fatal(err)
}
kfk.Serve()
@@ -131,9 +131,9 @@ func TestKafkaER(t *testing.T) {
}(randomCGRID)
select {
case err = <-rdrErr:
case err = <-kfkErr:
t.Error(err)
case ev := <-rdrEvents:
case ev := <-kfkEvents:
if ev.rdrCfg.ID != "kafka" {
t.Errorf("Expected 'kakfa' received `%s`", ev.rdrCfg.ID)
}
@@ -151,7 +151,7 @@ func TestKafkaER(t *testing.T) {
case <-time.After(10 * time.Second):
t.Fatal("Timeout")
}
rdrExit <- struct{}{}
kfkExit <- struct{}{}
// Delete kafka topic

View File

@@ -1,3 +1,5 @@
//go:build integration || flaky
/*
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
Copyright (C) ITsysCOM GmbH

View File

@@ -168,20 +168,26 @@ func testSQLInitDB(t *testing.T) {
tx.Commit()
}
var (
sqlEvents chan *erEvent
sqlErr chan error
sqlExit chan struct{}
)
func testSQLReader(t *testing.T) {
rdrEvents = make(chan *erEvent, 1)
rdrErr = make(chan error, 1)
rdrExit = make(chan struct{}, 1)
sqlER, err := NewEventReader(sqlCfg, 1, rdrEvents, rdrErr, new(engine.FilterS), rdrExit)
sqlEvents = make(chan *erEvent, 1)
sqlErr = make(chan error, 1)
sqlExit = make(chan struct{}, 1)
sqlER, err := NewEventReader(sqlCfg, 1, sqlEvents, sqlErr, new(engine.FilterS), sqlExit)
if err != nil {
t.Fatal(err)
}
sqlER.Serve()
select {
case err = <-rdrErr:
case err = <-sqlErr:
t.Error(err)
case ev := <-rdrEvents:
case ev := <-sqlEvents:
if ev.rdrCfg.ID != "mysql" {
t.Errorf("Expected 'mysql' received `%s`", ev.rdrCfg.ID)
}
@@ -230,9 +236,9 @@ func testSQLEmptyTable(t *testing.T) {
func testSQLReader2(t *testing.T) {
select {
case err := <-rdrErr:
case err := <-sqlErr:
t.Error(err)
case ev := <-rdrEvents:
case ev := <-sqlEvents:
if ev.rdrCfg.ID != "mysql" {
t.Errorf("Expected 'mysql' received `%s`", ev.rdrCfg.ID)
}
@@ -282,7 +288,7 @@ func testSQLPoster(t *testing.T) {
}
func testSQLStop(t *testing.T) {
rdrExit <- struct{}{}
sqlExit <- struct{}{}
db = db.DropTable("cdrs2")
if err := db.Close(); err != nil {
t.Error(err)

View File

@@ -22,10 +22,8 @@ package general_tests
import (
"encoding/json"
"errors"
"fmt"
"net/rpc"
"net/rpc/jsonrpc"
"path"
"sync"
"testing"
@@ -412,14 +410,3 @@ func testA1itStopCgrEngine(t *testing.T) {
t.Error(err)
}
}
func newRPCClient(cfg *config.ListenCfg) (c *rpc.Client, err error) {
switch *utils.Encoding {
case utils.MetaJSON:
return jsonrpc.Dial(utils.TCP, cfg.RPCJSONListen)
case utils.MetaGOB:
return rpc.Dial(utils.TCP, cfg.RPCGOBListen)
default:
return nil, errors.New("UNSUPPORTED_RPC")
}
}

View File

@@ -1,4 +1,5 @@
//go:build flaky
//go:build integration
// +build integration
/*
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
@@ -21,6 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package general_tests
import (
"net/rpc"
"path"
"testing"
"time"
@@ -33,65 +35,70 @@ import (
// Start test wth combines rating plan
// destination for 1002 cost 1CNT and *any cost 10CNT
var (
destCombCfgPath string
destCombCfg *config.CGRConfig
destCombRPC *rpc.Client
destCombConfDIR string
destCombDelay int
var sTestsTutorials2 = []func(t *testing.T){
testDestinationLoadConfig,
testDestinationResetDB,
testDestinationStartEngine,
testDestinationRpcConn,
testDestinationFromFolder,
testDestinationGetCostFor1002,
testDestinationGetCostFor1003,
testTutorialStopEngine,
}
sTestsDestComb = []func(t *testing.T){
testDestinationLoadConfig,
testDestinationResetDB,
testDestinationStartEngine,
testDestinationRpcConn,
testDestinationFromFolder,
testDestinationGetCostFor1002,
testDestinationGetCostFor1003,
testDestinationStopEngine,
}
)
func TestDestinationCombines(t *testing.T) {
switch *utils.DBType {
case utils.MetaInternal:
tutorialConfDIR = "tutinternal"
destCombConfDIR = "tutinternal"
case utils.MetaMySQL:
tutorialConfDIR = "tutmysql"
destCombConfDIR = "tutmysql"
case utils.MetaMongo:
tutorialConfDIR = "tutmongo"
destCombConfDIR = "tutmongo"
case utils.MetaPostgres:
t.SkipNow()
default:
t.Fatal("Unknown Database type")
}
for _, stest := range sTestsTutorials2 {
t.Run(tutorialConfDIR, stest)
for _, stest := range sTestsDestComb {
t.Run(destCombConfDIR, stest)
}
}
func testDestinationLoadConfig(t *testing.T) {
var err error
tutorialCfgPath = path.Join(*utils.DataDir, "conf", "samples", tutorialConfDIR)
if tutorialCfg, err = config.NewCGRConfigFromPath(tutorialCfgPath); err != nil {
destCombCfgPath = path.Join(*utils.DataDir, "conf", "samples", destCombConfDIR)
if destCombCfg, err = config.NewCGRConfigFromPath(destCombCfgPath); err != nil {
t.Error(err)
}
tutorialDelay = 2000
}
func testDestinationResetDB(t *testing.T) {
if err := engine.InitDataDb(tutorialCfg); err != nil {
if err := engine.InitDataDb(destCombCfg); err != nil {
t.Fatal(err)
}
if err := engine.InitStorDb(tutorialCfg); err != nil {
if err := engine.InitStorDb(destCombCfg); err != nil {
t.Fatal(err)
}
}
func testDestinationStartEngine(t *testing.T) {
if _, err := engine.StopStartEngine(tutorialCfgPath, tutorialDelay); err != nil {
if _, err := engine.StopStartEngine(destCombCfgPath, 2000); err != nil {
t.Fatal(err)
}
}
func testDestinationRpcConn(t *testing.T) {
var err error
tutorialRpc, err = newRPCClient(tutorialCfg.ListenCfg()) // We connect over JSON so we can also troubleshoot if needed
destCombRPC, err = newRPCClient(destCombCfg.ListenCfg()) // We connect over JSON so we can also troubleshoot if needed
if err != nil {
t.Fatal("Could not connect to rater: ", err.Error())
}
@@ -100,7 +107,7 @@ func testDestinationRpcConn(t *testing.T) {
func testDestinationFromFolder(t *testing.T) {
var reply string
attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*utils.DataDir, "tariffplans", "tp_destination_with_any")}
if err := tutorialRpc.Call(utils.APIerSv1LoadTariffPlanFromFolder, attrs, &reply); err != nil {
if err := destCombRPC.Call(utils.APIerSv1LoadTariffPlanFromFolder, attrs, &reply); err != nil {
t.Error(err)
}
time.Sleep(500 * time.Millisecond)
@@ -116,7 +123,7 @@ func testDestinationGetCostFor1002(t *testing.T) {
Usage: "1m",
}
var rply *engine.EventCost
if err := tutorialRpc.Call(utils.APIerSv1GetCost, attrs, &rply); err != nil {
if err := destCombRPC.Call(utils.APIerSv1GetCost, attrs, &rply); err != nil {
t.Error("Unexpected nil error received: ", err.Error())
} else if *rply.Cost != 0.01 {
t.Errorf("Unexpected cost received: %f", *rply.Cost)
@@ -133,9 +140,15 @@ func testDestinationGetCostFor1003(t *testing.T) {
Usage: "1m",
}
var rply *engine.EventCost
if err := tutorialRpc.Call(utils.APIerSv1GetCost, attrs, &rply); err != nil {
if err := destCombRPC.Call(utils.APIerSv1GetCost, attrs, &rply); err != nil {
t.Error("Unexpected nil error received: ", err.Error())
} else if *rply.Cost != 0.3 {
t.Errorf("Unexpected cost received: %f", *rply.Cost)
}
}
func testDestinationStopEngine(t *testing.T) {
if err := engine.KillEngine(2000); err != nil {
t.Error(err)
}
}

40
general_tests/lib_test.go Normal file
View File

@@ -0,0 +1,40 @@
//go:build integration || flaky
/*
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 <http://www.gnu.org/licenses/>
*/
package general_tests
import (
"errors"
"net/rpc"
"net/rpc/jsonrpc"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/utils"
)
func newRPCClient(cfg *config.ListenCfg) (c *rpc.Client, err error) {
switch *utils.Encoding {
case utils.MetaJSON:
return jsonrpc.Dial(utils.TCP, cfg.RPCJSONListen)
case utils.MetaGOB:
return rpc.Dial(utils.TCP, cfg.RPCGOBListen)
default:
return nil, errors.New("UNSUPPORTED_RPC")
}
}