mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
762 lines
21 KiB
Go
762 lines
21 KiB
Go
//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 Affero 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 Affero General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>
|
|
*/
|
|
package general_tests
|
|
|
|
import (
|
|
"io/fs"
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
"sort"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/cgrates/birpc/context"
|
|
"github.com/cgrates/cgrates/apis"
|
|
"github.com/cgrates/cgrates/engine"
|
|
"github.com/cgrates/cgrates/loaders"
|
|
"github.com/cgrates/cgrates/utils"
|
|
)
|
|
|
|
func TestMultipleDBs(t *testing.T) {
|
|
if err := os.MkdirAll("/tmp/internal_db/db", 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(func() {
|
|
if err := os.RemoveAll("/tmp/internal_db"); err != nil {
|
|
t.Error(err)
|
|
}
|
|
})
|
|
ng := engine.TestEngine{
|
|
ConfigPath: filepath.Join(*utils.DataDir, "conf", "samples", "multiple_dbs"),
|
|
GracefulShutdown: true,
|
|
Encoding: *utils.Encoding,
|
|
}
|
|
client, cfg := ng.Run(t)
|
|
t.Run("LoadTariffPlans", func(t *testing.T) {
|
|
var reply string
|
|
if err := client.Call(context.Background(), utils.LoaderSv1Run,
|
|
&loaders.ArgsProcessFolder{
|
|
APIOpts: map[string]any{
|
|
utils.MetaCache: utils.MetaNone,
|
|
},
|
|
}, &reply); err != nil {
|
|
t.Error(err)
|
|
} else if reply != utils.OK {
|
|
t.Error("Unexpected reply returned:", reply)
|
|
}
|
|
time.Sleep(100 * time.Millisecond)
|
|
})
|
|
|
|
t.Run("CheckChargers", func(t *testing.T) { // stored in redis2
|
|
var chrgrs []*utils.ChargerProfile
|
|
if err := client.Call(context.Background(), utils.AdminSv1GetChargerProfiles,
|
|
&utils.ArgsItemIDs{
|
|
Tenant: "cgrates.org",
|
|
}, &chrgrs); err != nil {
|
|
t.Errorf("AdminSv1GetChargerProfiles failed unexpectedly: %v", err)
|
|
}
|
|
if len(chrgrs) != 3 {
|
|
t.Fatalf("AdminSv1GetChargerProfiles len(chrgrs)=%v, want 3", len(chrgrs))
|
|
}
|
|
sort.Slice(chrgrs, func(i, j int) bool {
|
|
return chrgrs[i].ID > chrgrs[j].ID
|
|
})
|
|
exp := []*utils.ChargerProfile{
|
|
{
|
|
ID: "SupplierCharges",
|
|
Tenant: "cgrates.org",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 10,
|
|
},
|
|
},
|
|
RunID: "SupplierCharges",
|
|
AttributeIDs: []string{"ATTR_SUPPLIER1"},
|
|
},
|
|
{
|
|
ID: "Raw",
|
|
Tenant: "cgrates.org",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 20,
|
|
},
|
|
},
|
|
RunID: "raw",
|
|
AttributeIDs: []string{"*constant:*req.RequestType:*none"},
|
|
},
|
|
{
|
|
ID: "CustomerCharges",
|
|
Tenant: "cgrates.org",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 20,
|
|
},
|
|
},
|
|
RunID: "CustomerCharges",
|
|
AttributeIDs: []string{"*none"},
|
|
},
|
|
}
|
|
if !reflect.DeepEqual(exp, chrgrs) {
|
|
t.Errorf("Expected <%+v>,\n received <%+v>", exp, chrgrs)
|
|
}
|
|
})
|
|
|
|
t.Run("CheckChargerFilterIndexes", func(t *testing.T) { // stored in internal
|
|
var replyIdx []string
|
|
expectedIDx := []string{"*none:*any:*any:CustomerCharges", "*none:*any:*any:Raw",
|
|
"*none:*any:*any:SupplierCharges"}
|
|
if err := client.Call(context.Background(), utils.AdminSv1GetFilterIndexes,
|
|
&apis.AttrGetFilterIndexes{
|
|
Tenant: utils.CGRateSorg,
|
|
ItemType: utils.MetaChargers,
|
|
},
|
|
&replyIdx); err != nil {
|
|
t.Error(err)
|
|
} else {
|
|
sort.Strings(replyIdx)
|
|
sort.Strings(expectedIDx)
|
|
if !reflect.DeepEqual(expectedIDx, replyIdx) {
|
|
t.Errorf("Expected %+v, \nreceived %+v", utils.ToJSON(expectedIDx), utils.ToJSON(replyIdx))
|
|
}
|
|
}
|
|
})
|
|
|
|
t.Run("CheckAccounts", func(t *testing.T) { // stored in *default (redis in this case)
|
|
var acnts []*utils.Account
|
|
if err := client.Call(context.Background(), utils.AdminSv1GetAccounts,
|
|
&utils.ArgsItemIDs{
|
|
Tenant: "cgrates.org",
|
|
}, &acnts); err != nil {
|
|
t.Errorf("AdminSv2GetAccounts failed unexpectedly: %v", err)
|
|
}
|
|
if len(acnts) != 2 {
|
|
t.Fatalf("AdminSv2GetAccounts len(acnts)=%v, want 2", len(acnts))
|
|
}
|
|
sort.Slice(acnts, func(i, j int) bool {
|
|
return acnts[i].ID > acnts[j].ID
|
|
})
|
|
exp := []*utils.Account{
|
|
{
|
|
Tenant: "cgrates.org",
|
|
ID: "ACC_PRF_1",
|
|
Opts: map[string]any{},
|
|
Balances: map[string]*utils.Balance{
|
|
"MonetaryBalance": {
|
|
ID: "MonetaryBalance",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 10,
|
|
},
|
|
},
|
|
Type: "*monetary",
|
|
Opts: map[string]any{},
|
|
Units: utils.NewDecimal(14, 0),
|
|
UnitFactors: []*utils.UnitFactor{
|
|
{
|
|
FilterIDs: []string{"fltr1", "fltr2"},
|
|
Factor: utils.NewDecimal(100, 0),
|
|
},
|
|
{
|
|
FilterIDs: []string{"fltr3"},
|
|
Factor: utils.NewDecimal(200, 0),
|
|
},
|
|
},
|
|
CostIncrements: []*utils.CostIncrement{
|
|
{
|
|
FilterIDs: []string{"fltr1", "fltr2"},
|
|
Increment: utils.NewDecimal(13, 1),
|
|
FixedFee: utils.NewDecimal(23, 1),
|
|
RecurrentFee: utils.NewDecimal(33, 1),
|
|
},
|
|
},
|
|
AttributeIDs: []string{"attr1", "attr2"},
|
|
},
|
|
},
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 20,
|
|
},
|
|
},
|
|
ThresholdIDs: []string{utils.MetaNone},
|
|
},
|
|
{
|
|
Tenant: "cgrates.org",
|
|
ID: "1001",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 20,
|
|
},
|
|
},
|
|
Opts: map[string]any{},
|
|
Balances: map[string]*utils.Balance{
|
|
"MonetaryBalance": {
|
|
ID: "MonetaryBalance",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 10,
|
|
},
|
|
},
|
|
Type: "*monetary",
|
|
Opts: map[string]any{},
|
|
Units: utils.NewDecimal(14, 0),
|
|
UnitFactors: []*utils.UnitFactor{
|
|
{
|
|
FilterIDs: []string{"fltr1", "fltr2"},
|
|
Factor: utils.NewDecimal(100, 0),
|
|
},
|
|
{
|
|
FilterIDs: []string{"fltr3"},
|
|
Factor: utils.NewDecimal(200, 0),
|
|
},
|
|
},
|
|
CostIncrements: []*utils.CostIncrement{
|
|
{
|
|
FilterIDs: []string{"fltr1", "fltr2"},
|
|
Increment: utils.NewDecimal(13, 1),
|
|
FixedFee: utils.NewDecimal(23, 1),
|
|
RecurrentFee: utils.NewDecimal(33, 1),
|
|
},
|
|
},
|
|
AttributeIDs: []string{"attr1", "attr2"},
|
|
},
|
|
"VoiceBalance": {
|
|
ID: "VoiceBalance",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 10,
|
|
},
|
|
{
|
|
Weight: 10,
|
|
},
|
|
},
|
|
Blockers: utils.DynamicBlockers{
|
|
{
|
|
FilterIDs: []string{"*string:~*req.Destination:1002"},
|
|
Blocker: true,
|
|
},
|
|
{
|
|
Blocker: false,
|
|
},
|
|
},
|
|
Type: "*voice",
|
|
Opts: map[string]any{},
|
|
Units: utils.NewDecimalFromUsageIgnoreErr("1h"),
|
|
},
|
|
},
|
|
ThresholdIDs: []string{utils.MetaNone},
|
|
},
|
|
}
|
|
if !reflect.DeepEqual(exp, acnts) {
|
|
t.Errorf("Expected <%+v>,\n received <%+v>", exp, acnts)
|
|
}
|
|
})
|
|
|
|
t.Run("CheckCdrs", func(t *testing.T) { // stored in mysql
|
|
var cdrs []*utils.CDR
|
|
if err := client.Call(context.Background(), utils.AdminSv1GetCDRs, &utils.CDRFilters{Tenant: "cgrates.org"}, &cdrs); err == nil || err.Error() != "retrieving CDRs failed: NOT_FOUND" {
|
|
t.Errorf("Expecting error <%v>, received: <%v>", "retrieving CDRs failed: NOT_FOUND", err)
|
|
}
|
|
ev := &utils.CGREvent{
|
|
Tenant: "cgrates.org",
|
|
ID: "TestEv1",
|
|
Event: map[string]any{
|
|
utils.ToR: utils.MetaVoice,
|
|
utils.OriginID: "TestEv1",
|
|
utils.RequestType: utils.MetaPrepaid,
|
|
utils.AccountField: "1001",
|
|
utils.Subject: "1001",
|
|
utils.Destination: "1002",
|
|
utils.Usage: time.Minute,
|
|
},
|
|
APIOpts: map[string]any{
|
|
utils.MetaRates: true,
|
|
utils.MetaAccounts: false,
|
|
},
|
|
}
|
|
var rply string
|
|
client.Call(context.Background(), utils.CDRsV1ProcessEvent, ev, &rply)
|
|
if err := client.Call(context.Background(), utils.AdminSv1GetCDRs, &utils.CDRFilters{Tenant: "cgrates.org"}, &cdrs); err != nil {
|
|
t.Error(err)
|
|
}
|
|
if len(cdrs) != 1 {
|
|
t.Errorf("unexpected number of cdrs found: %v", len(cdrs))
|
|
}
|
|
exp := &utils.CDR{
|
|
Tenant: utils.CGRateSorg,
|
|
Opts: map[string]any{
|
|
utils.MetaCDRID: cdrs[0].Opts[utils.MetaCDRID],
|
|
utils.MetaRates: true,
|
|
utils.MetaAccounts: false,
|
|
utils.MetaCost: 0.4,
|
|
utils.MetaRateSCost: map[string]any{
|
|
"Altered": nil,
|
|
utils.Cost: 0.4,
|
|
"CostIntervals": []any{
|
|
map[string]any{
|
|
"CompressFactor": 1,
|
|
"Increments": []any{
|
|
map[string]any{
|
|
"CompressFactor": 2,
|
|
"RateID": cdrs[0].Opts[utils.MetaRateSCost].(map[string]any)["CostIntervals"].([]any)[0].(map[string]any)["Increments"].([]any)[0].(map[string]any)["RateID"],
|
|
"RateIntervalIndex": 0,
|
|
"Usage": 6e+10,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"ID": "RT_RETAIL1",
|
|
"MaxCost": 0,
|
|
"MaxCostStrategy": "",
|
|
"MinCost": 0,
|
|
"Rates": cdrs[0].Opts[utils.MetaRateSCost].(map[string]any)["Rates"],
|
|
},
|
|
},
|
|
Event: map[string]any{
|
|
utils.AccountField: "1001",
|
|
utils.Destination: "1002",
|
|
utils.OriginID: "TestEv1",
|
|
utils.RequestType: utils.MetaPrepaid,
|
|
utils.Subject: "1001",
|
|
utils.ToR: utils.MetaVoice,
|
|
utils.Usage: 6e+10,
|
|
},
|
|
CreatedAt: cdrs[0].CreatedAt,
|
|
UpdatedAt: cdrs[0].UpdatedAt,
|
|
}
|
|
if !reflect.DeepEqual(utils.ToJSON(exp), utils.ToJSON(cdrs[0])) {
|
|
t.Errorf("Expecting <%#v>, \nreceived <%#v>", exp, cdrs[0])
|
|
}
|
|
})
|
|
t.Run("EngineShutdown", func(t *testing.T) {
|
|
if err := engine.KillEngine(100); err != nil {
|
|
t.Error(err)
|
|
}
|
|
})
|
|
|
|
t.Run("CountDBFiles", func(t *testing.T) {
|
|
var dirs, files int
|
|
if err := filepath.WalkDir(cfg.DbCfg().DBConns["intrnl"].Opts.InternalDBDumpPath, func(root string, info fs.DirEntry, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if info.IsDir() {
|
|
dirs++
|
|
} else {
|
|
if !strings.HasPrefix(root, "/tmp/internal_db/db/*charger_filter_indexes") &&
|
|
!strings.HasPrefix(root, "/tmp/internal_db/db/*versions") {
|
|
t.Fatalf("got unexpected folder <%s>", root)
|
|
}
|
|
files++
|
|
}
|
|
return nil
|
|
}); err != nil {
|
|
t.Error(err)
|
|
} else if dirs != 36 {
|
|
t.Errorf("expected <%d> directories, received <%d>", 36, dirs)
|
|
} else if files != 2 {
|
|
t.Errorf("expected <%d> files, received <%d>", 2, files)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestMultipleDBsMongo(t *testing.T) {
|
|
if err := os.MkdirAll("/tmp/internal_db/db", 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(func() {
|
|
if err := os.RemoveAll("/tmp/internal_db"); err != nil {
|
|
t.Error(err)
|
|
}
|
|
})
|
|
ng := engine.TestEngine{
|
|
ConfigPath: filepath.Join(*utils.DataDir, "conf", "samples", "multiple_dbs_mongo"),
|
|
GracefulShutdown: true,
|
|
Encoding: *utils.Encoding,
|
|
}
|
|
client, cfg := ng.Run(t)
|
|
t.Run("LoadTariffPlans", func(t *testing.T) {
|
|
var reply string
|
|
if err := client.Call(context.Background(), utils.LoaderSv1Run,
|
|
&loaders.ArgsProcessFolder{
|
|
APIOpts: map[string]any{
|
|
utils.MetaCache: utils.MetaNone,
|
|
},
|
|
}, &reply); err != nil {
|
|
t.Error(err)
|
|
} else if reply != utils.OK {
|
|
t.Error("Unexpected reply returned:", reply)
|
|
}
|
|
time.Sleep(100 * time.Millisecond)
|
|
})
|
|
|
|
t.Run("CheckChargers", func(t *testing.T) { // stored in mongo
|
|
var chrgrs []*utils.ChargerProfile
|
|
if err := client.Call(context.Background(), utils.AdminSv1GetChargerProfiles,
|
|
&utils.ArgsItemIDs{
|
|
Tenant: "cgrates.org",
|
|
}, &chrgrs); err != nil {
|
|
t.Errorf("AdminSv1GetChargerProfiles failed unexpectedly: %v", err)
|
|
}
|
|
if len(chrgrs) != 3 {
|
|
t.Fatalf("AdminSv1GetChargerProfiles len(chrgrs)=%v, want 3", len(chrgrs))
|
|
}
|
|
sort.Slice(chrgrs, func(i, j int) bool {
|
|
return chrgrs[i].ID > chrgrs[j].ID
|
|
})
|
|
exp := []*utils.ChargerProfile{
|
|
{
|
|
ID: "SupplierCharges",
|
|
Tenant: "cgrates.org",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 10,
|
|
},
|
|
},
|
|
RunID: "SupplierCharges",
|
|
AttributeIDs: []string{"ATTR_SUPPLIER1"},
|
|
},
|
|
{
|
|
ID: "Raw",
|
|
Tenant: "cgrates.org",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 20,
|
|
},
|
|
},
|
|
RunID: "raw",
|
|
AttributeIDs: []string{"*constant:*req.RequestType:*none"},
|
|
},
|
|
{
|
|
ID: "CustomerCharges",
|
|
Tenant: "cgrates.org",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 20,
|
|
},
|
|
},
|
|
RunID: "CustomerCharges",
|
|
AttributeIDs: []string{"*none"},
|
|
},
|
|
}
|
|
if !reflect.DeepEqual(exp, chrgrs) {
|
|
t.Errorf("Expected <%+v>,\n received <%+v>", exp, chrgrs)
|
|
}
|
|
})
|
|
|
|
t.Run("CheckChargerFilterIndexes", func(t *testing.T) { // stored in internal
|
|
var replyIdx []string
|
|
expectedIDx := []string{"*none:*any:*any:CustomerCharges", "*none:*any:*any:Raw",
|
|
"*none:*any:*any:SupplierCharges"}
|
|
if err := client.Call(context.Background(), utils.AdminSv1GetFilterIndexes,
|
|
&apis.AttrGetFilterIndexes{
|
|
Tenant: utils.CGRateSorg,
|
|
ItemType: utils.MetaChargers,
|
|
},
|
|
&replyIdx); err != nil {
|
|
t.Error(err)
|
|
} else {
|
|
sort.Strings(replyIdx)
|
|
sort.Strings(expectedIDx)
|
|
if !reflect.DeepEqual(expectedIDx, replyIdx) {
|
|
t.Errorf("Expected %+v, \nreceived %+v", utils.ToJSON(expectedIDx), utils.ToJSON(replyIdx))
|
|
}
|
|
}
|
|
})
|
|
|
|
t.Run("CheckAccounts", func(t *testing.T) { // stored in *default (redis in this case)
|
|
var acnts []*utils.Account
|
|
if err := client.Call(context.Background(), utils.AdminSv1GetAccounts,
|
|
&utils.ArgsItemIDs{
|
|
Tenant: "cgrates.org",
|
|
}, &acnts); err != nil {
|
|
t.Errorf("AdminSv2GetAccounts failed unexpectedly: %v", err)
|
|
}
|
|
if len(acnts) != 2 {
|
|
t.Fatalf("AdminSv2GetAccounts len(acnts)=%v, want 2", len(acnts))
|
|
}
|
|
sort.Slice(acnts, func(i, j int) bool {
|
|
return acnts[i].ID > acnts[j].ID
|
|
})
|
|
exp := []*utils.Account{
|
|
{
|
|
Tenant: "cgrates.org",
|
|
ID: "ACC_PRF_1",
|
|
Opts: map[string]any{},
|
|
Balances: map[string]*utils.Balance{
|
|
"MonetaryBalance": {
|
|
ID: "MonetaryBalance",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 10,
|
|
},
|
|
},
|
|
Type: "*monetary",
|
|
Opts: map[string]any{},
|
|
Units: utils.NewDecimal(14, 0),
|
|
UnitFactors: []*utils.UnitFactor{
|
|
{
|
|
FilterIDs: []string{"fltr1", "fltr2"},
|
|
Factor: utils.NewDecimal(100, 0),
|
|
},
|
|
{
|
|
FilterIDs: []string{"fltr3"},
|
|
Factor: utils.NewDecimal(200, 0),
|
|
},
|
|
},
|
|
CostIncrements: []*utils.CostIncrement{
|
|
{
|
|
FilterIDs: []string{"fltr1", "fltr2"},
|
|
Increment: utils.NewDecimal(13, 1),
|
|
FixedFee: utils.NewDecimal(23, 1),
|
|
RecurrentFee: utils.NewDecimal(33, 1),
|
|
},
|
|
},
|
|
AttributeIDs: []string{"attr1", "attr2"},
|
|
},
|
|
},
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 20,
|
|
},
|
|
},
|
|
ThresholdIDs: []string{utils.MetaNone},
|
|
},
|
|
{
|
|
Tenant: "cgrates.org",
|
|
ID: "1001",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 20,
|
|
},
|
|
},
|
|
Opts: map[string]any{},
|
|
Balances: map[string]*utils.Balance{
|
|
"MonetaryBalance": {
|
|
ID: "MonetaryBalance",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 10,
|
|
},
|
|
},
|
|
Type: "*monetary",
|
|
Opts: map[string]any{},
|
|
Units: utils.NewDecimal(14, 0),
|
|
UnitFactors: []*utils.UnitFactor{
|
|
{
|
|
FilterIDs: []string{"fltr1", "fltr2"},
|
|
Factor: utils.NewDecimal(100, 0),
|
|
},
|
|
{
|
|
FilterIDs: []string{"fltr3"},
|
|
Factor: utils.NewDecimal(200, 0),
|
|
},
|
|
},
|
|
CostIncrements: []*utils.CostIncrement{
|
|
{
|
|
FilterIDs: []string{"fltr1", "fltr2"},
|
|
Increment: utils.NewDecimal(13, 1),
|
|
FixedFee: utils.NewDecimal(23, 1),
|
|
RecurrentFee: utils.NewDecimal(33, 1),
|
|
},
|
|
},
|
|
AttributeIDs: []string{"attr1", "attr2"},
|
|
},
|
|
"VoiceBalance": {
|
|
ID: "VoiceBalance",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 10,
|
|
},
|
|
{
|
|
Weight: 10,
|
|
},
|
|
},
|
|
Blockers: utils.DynamicBlockers{
|
|
{
|
|
FilterIDs: []string{"*string:~*req.Destination:1002"},
|
|
Blocker: true,
|
|
},
|
|
{
|
|
Blocker: false,
|
|
},
|
|
},
|
|
Type: "*voice",
|
|
Opts: map[string]any{},
|
|
Units: utils.NewDecimalFromUsageIgnoreErr("1h"),
|
|
},
|
|
},
|
|
ThresholdIDs: []string{utils.MetaNone},
|
|
},
|
|
}
|
|
if !reflect.DeepEqual(exp, acnts) {
|
|
t.Errorf("Expected <%+v>,\n received <%+v>", exp, acnts)
|
|
}
|
|
})
|
|
|
|
t.Run("CheckCdrs", func(t *testing.T) { // stored in mongo
|
|
var cdrs []*utils.CDR
|
|
if err := client.Call(context.Background(), utils.AdminSv1GetCDRs, &utils.CDRFilters{Tenant: "cgrates.org"}, &cdrs); err == nil || err.Error() != "retrieving CDRs failed: NOT_FOUND" {
|
|
t.Errorf("Expecting error <%v>, received: <%v>", "retrieving CDRs failed: NOT_FOUND", err)
|
|
}
|
|
ev := &utils.CGREvent{
|
|
Tenant: "cgrates.org",
|
|
ID: "TestEv1",
|
|
Event: map[string]any{
|
|
utils.ToR: utils.MetaVoice,
|
|
utils.OriginID: "TestEv1",
|
|
utils.RequestType: utils.MetaPrepaid,
|
|
utils.AccountField: "1001",
|
|
utils.Subject: "1001",
|
|
utils.Destination: "1002",
|
|
utils.Usage: time.Minute,
|
|
},
|
|
APIOpts: map[string]any{
|
|
utils.MetaRates: true,
|
|
utils.MetaAccounts: false,
|
|
},
|
|
}
|
|
var rply string
|
|
client.Call(context.Background(), utils.CDRsV1ProcessEvent, ev, &rply)
|
|
if err := client.Call(context.Background(), utils.AdminSv1GetCDRs, &utils.CDRFilters{Tenant: "cgrates.org"}, &cdrs); err != nil {
|
|
t.Error(err)
|
|
}
|
|
if len(cdrs) != 1 {
|
|
t.Errorf("unexpected number of cdrs found: %v", len(cdrs))
|
|
}
|
|
exp := &utils.CDR{
|
|
Tenant: utils.CGRateSorg,
|
|
Opts: map[string]any{
|
|
utils.MetaCDRID: cdrs[0].Opts[utils.MetaCDRID],
|
|
utils.MetaRates: true,
|
|
utils.MetaAccounts: false,
|
|
utils.MetaCost: 0.4,
|
|
utils.MetaRateSCost: map[string]any{
|
|
"altered": nil,
|
|
"cost": 0.4,
|
|
"costintervals": []any{
|
|
map[string]any{
|
|
"compressfactor": 1,
|
|
"increments": []any{
|
|
map[string]any{
|
|
"compressfactor": 2,
|
|
"rateid": cdrs[0].Opts[utils.MetaRateSCost].(map[string]any)["costintervals"].([]any)[0].(map[string]any)["increments"].([]any)[0].(map[string]any)["rateid"],
|
|
"rateintervalindex": 0,
|
|
"usage": 6e+10,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"id": "RT_RETAIL1",
|
|
"maxcost": 0,
|
|
"maxcoststrategy": "",
|
|
"mincost": 0,
|
|
"rates": cdrs[0].Opts[utils.MetaRateSCost].(map[string]any)["rates"],
|
|
},
|
|
},
|
|
Event: map[string]any{
|
|
utils.AccountField: "1001",
|
|
utils.Destination: "1002",
|
|
utils.OriginID: "TestEv1",
|
|
utils.RequestType: utils.MetaPrepaid,
|
|
utils.Subject: "1001",
|
|
utils.ToR: utils.MetaVoice,
|
|
utils.Usage: 6e+10,
|
|
},
|
|
CreatedAt: cdrs[0].CreatedAt,
|
|
UpdatedAt: cdrs[0].UpdatedAt,
|
|
}
|
|
if !reflect.DeepEqual(utils.ToJSON(exp), utils.ToJSON(cdrs[0])) {
|
|
t.Errorf("Expecting <%#v>, \nreceived <%#v>", exp, cdrs[0])
|
|
}
|
|
})
|
|
t.Run("EngineShutdown", func(t *testing.T) {
|
|
if err := engine.KillEngine(100); err != nil {
|
|
t.Error(err)
|
|
}
|
|
})
|
|
|
|
t.Run("CountDBFiles", func(t *testing.T) {
|
|
var dirs, files int
|
|
if err := filepath.WalkDir(cfg.DbCfg().DBConns["internalDBConn"].Opts.InternalDBDumpPath, func(root string, info fs.DirEntry, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if info.IsDir() {
|
|
dirs++
|
|
} else {
|
|
if !strings.HasPrefix(root, "/tmp/internal_db/db/*charger_filter_indexes") &&
|
|
!strings.HasPrefix(root, "/tmp/internal_db/db/*versions") {
|
|
t.Fatalf("got unexpected folder <%s>", root)
|
|
}
|
|
files++
|
|
}
|
|
return nil
|
|
}); err != nil {
|
|
t.Error(err)
|
|
} else if dirs != 36 {
|
|
t.Errorf("expected <%d> directories, received <%d>", 36, dirs)
|
|
} else if files != 2 {
|
|
t.Errorf("expected <%d> files, received <%d>", 2, files)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestMultipleDBsInternalFail(t *testing.T) {
|
|
if err := os.MkdirAll("/tmp/internal_db/db", 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(func() {
|
|
if err := os.RemoveAll("/tmp/internal_db"); err != nil {
|
|
t.Error(err)
|
|
}
|
|
})
|
|
cfgJSON := `{
|
|
"logger": {
|
|
"level": 7
|
|
},
|
|
|
|
"db": {
|
|
"db_conns": {
|
|
"intrnl": {
|
|
"db_type": "*internal"
|
|
},
|
|
},
|
|
"items":{
|
|
"*charger_profiles": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "intrnl"},
|
|
},
|
|
"opts": {
|
|
"internalDBDumpPath": "/tmp/internal_db/db",
|
|
"internalDBRewriteInterval": "0s"
|
|
}
|
|
},
|
|
|
|
}
|
|
`
|
|
expErr := `/001: <db> There can only be 1 internal DB`
|
|
if _, err := engine.StartEngineFromString(cfgJSON, 200, t); err == nil ||
|
|
!strings.Contains(err.Error(), expErr) {
|
|
t.Errorf("expected error <%v>, received <%v>", expErr, err)
|
|
}
|
|
|
|
}
|