mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-13 11:06:25 +05:00
1409 lines
48 KiB
Go
1409 lines
48 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 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 apis
|
|
|
|
import (
|
|
"archive/zip"
|
|
"bytes"
|
|
"encoding/csv"
|
|
"path"
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/cgrates/birpc"
|
|
"github.com/cgrates/birpc/context"
|
|
"github.com/cgrates/cgrates/config"
|
|
"github.com/cgrates/cgrates/engine"
|
|
"github.com/cgrates/cgrates/tpes"
|
|
"github.com/cgrates/cgrates/utils"
|
|
)
|
|
|
|
var (
|
|
tpesCfgPath string
|
|
tpesCfg *config.CGRConfig
|
|
tpeSRPC *birpc.Client
|
|
tpeSConfigDIR string //run tests for specific configuration
|
|
|
|
sTestTpes = []func(t *testing.T){
|
|
testTPeSInitCfg,
|
|
testTPeSInitDataDb,
|
|
testTPeSStartEngine,
|
|
testTPeSRPCConn,
|
|
testTPeSPing,
|
|
testTPeSSetAttributeProfile,
|
|
testTPeSSetResourceProfile,
|
|
testTPeSetFilters,
|
|
testTPeSetRateProfiles,
|
|
testTPeSetChargerProfiles,
|
|
testTPeSetRouteProfiles,
|
|
testTPeSetAccount,
|
|
testTPeSetStatQueueProfile,
|
|
testTPeSetActions,
|
|
testTPeSetThresholds,
|
|
testTPeSetDispatcherProfiles,
|
|
testSeTPeSetDispatcherHosts,
|
|
testTPeSExportTariffPlanHalfTariffPlan,
|
|
testTPeSExportTariffPlanAllTariffPlan,
|
|
// export again after we will flush the database
|
|
testTPeSInitDataDb,
|
|
testTPeSKillEngine,
|
|
testTPeSInitCfg,
|
|
testTPeSStartEngine,
|
|
testTPeSRPCConn,
|
|
testTPeSExportAfterFlush,
|
|
testTPeSKillEngine,
|
|
}
|
|
)
|
|
|
|
func TestTPeSIT(t *testing.T) {
|
|
switch *dbType {
|
|
case utils.MetaInternal:
|
|
tpeSConfigDIR = "tpe_internal"
|
|
case utils.MetaMongo:
|
|
tpeSConfigDIR = "tutmongo"
|
|
case utils.MetaMySQL:
|
|
tpeSConfigDIR = "tutmysql"
|
|
case utils.MetaPostgres:
|
|
t.SkipNow()
|
|
default:
|
|
t.Fatal("Unknown Database type")
|
|
}
|
|
for _, stest := range sTestTpes {
|
|
t.Run(tpeSConfigDIR, stest)
|
|
}
|
|
}
|
|
|
|
func testTPeSInitCfg(t *testing.T) {
|
|
var err error
|
|
tpesCfgPath = path.Join(*dataDir, "conf", "samples", tpeSConfigDIR)
|
|
tpesCfg, err = config.NewCGRConfigFromPath(context.Background(), tpesCfgPath)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func testTPeSInitDataDb(t *testing.T) {
|
|
if err := engine.InitDataDB(tpesCfg); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
// Start CGR Engine
|
|
func testTPeSStartEngine(t *testing.T) {
|
|
if _, err := engine.StopStartEngine(tpesCfgPath, *waitRater); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func testTPeSRPCConn(t *testing.T) {
|
|
var err error
|
|
tpeSRPC, err = newRPCClient(tpesCfg.ListenCfg()) // We connect over JSON so we can also troubleshoot if needed
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func testTPeSPing(t *testing.T) {
|
|
var reply string
|
|
if err := tpeSRPC.Call(context.Background(), utils.TPeSv1Ping, &utils.CGREvent{}, &reply); err != nil {
|
|
t.Error(err)
|
|
} else if reply != utils.Pong {
|
|
t.Errorf("Unexpected reply returned: %s", reply)
|
|
}
|
|
}
|
|
|
|
func testTPeSSetAttributeProfile(t *testing.T) {
|
|
attrPrf := &engine.APIAttributeProfileWithAPIOpts{
|
|
APIAttributeProfile: &engine.APIAttributeProfile{
|
|
Tenant: utils.CGRateSorg,
|
|
ID: "TEST_ATTRIBUTES_IT_TEST",
|
|
FilterIDs: []string{"*string:~*req.Account:1002", "*exists:~*opts.*usage:"},
|
|
Attributes: []*engine.ExternalAttribute{
|
|
{
|
|
Blockers: utils.DynamicBlockers{
|
|
{
|
|
FilterIDs: []string{"*string:~*req.Account:1002"},
|
|
Blocker: true,
|
|
},
|
|
{
|
|
Blocker: false,
|
|
},
|
|
},
|
|
Path: utils.AccountField,
|
|
Type: utils.MetaConstant,
|
|
Value: "1002",
|
|
},
|
|
{
|
|
Path: "*tenant",
|
|
Type: utils.MetaConstant,
|
|
Value: "cgrates.itsyscom",
|
|
},
|
|
},
|
|
Blockers: utils.DynamicBlockers{
|
|
{
|
|
Blocker: true,
|
|
},
|
|
},
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 20,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
var reply string
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetAttributeProfile,
|
|
attrPrf, &reply); err != nil {
|
|
t.Error(err)
|
|
} else if reply != utils.OK {
|
|
t.Error(err)
|
|
}
|
|
|
|
attrPrf1 := &engine.APIAttributeProfileWithAPIOpts{
|
|
APIAttributeProfile: &engine.APIAttributeProfile{
|
|
Tenant: utils.CGRateSorg,
|
|
ID: "TEST_ATTRIBUTES_IT_TEST_SECOND",
|
|
FilterIDs: []string{"*string:~*opts.*context:*sessions", "*exists:~*opts.*usage:"},
|
|
Attributes: []*engine.ExternalAttribute{
|
|
{
|
|
Path: "*tenant",
|
|
Type: utils.MetaConstant,
|
|
Value: "cgrates.itsyscom",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
var reply1 string
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetAttributeProfile,
|
|
attrPrf1, &reply1); err != nil {
|
|
t.Error(err)
|
|
} else if reply1 != utils.OK {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func testTPeSSetResourceProfile(t *testing.T) {
|
|
rsPrf1 := &engine.ResourceProfileWithAPIOpts{
|
|
ResourceProfile: &engine.ResourceProfile{
|
|
Tenant: "cgrates.org",
|
|
ID: "ResGroup1",
|
|
FilterIDs: []string{"*string:~*req.Account:1001"},
|
|
Limit: 10,
|
|
AllocationMessage: "Approved",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 20,
|
|
}},
|
|
ThresholdIDs: []string{utils.MetaNone},
|
|
},
|
|
}
|
|
|
|
var replystr string
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetResourceProfile,
|
|
rsPrf1, &replystr); err != nil {
|
|
t.Error(err)
|
|
} else if replystr != utils.OK {
|
|
t.Error("Unexpected reply returned", replystr)
|
|
}
|
|
|
|
rsPrf2 := &engine.ResourceProfileWithAPIOpts{
|
|
ResourceProfile: &engine.ResourceProfile{
|
|
Tenant: "cgrates.org",
|
|
ID: "ResGroup2",
|
|
FilterIDs: []string{"*string:~*req.Account:1002"},
|
|
Limit: 5,
|
|
AllocationMessage: "Declined",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 10,
|
|
}},
|
|
ThresholdIDs: []string{utils.MetaNone},
|
|
},
|
|
}
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetResourceProfile,
|
|
rsPrf2, &replystr); err != nil {
|
|
t.Error(err)
|
|
} else if replystr != utils.OK {
|
|
t.Error("Unexpected reply returned", replystr)
|
|
}
|
|
}
|
|
|
|
func testTPeSetFilters(t *testing.T) {
|
|
fltr1 := &engine.FilterWithAPIOpts{
|
|
Filter: &engine.Filter{
|
|
Tenant: utils.CGRateSorg,
|
|
ID: "fltr_for_prf",
|
|
Rules: []*engine.FilterRule{
|
|
{
|
|
Type: utils.MetaString,
|
|
Element: "~*req.Subject",
|
|
Values: []string{"1004", "6774", "22312"},
|
|
},
|
|
{
|
|
Type: utils.MetaString,
|
|
Element: "~*opts.Subsystems",
|
|
Values: []string{"*attributes"},
|
|
},
|
|
{
|
|
Type: utils.MetaPrefix,
|
|
Element: "~*req.Destinations",
|
|
Values: []string{"+0775", "+442"},
|
|
},
|
|
{
|
|
Type: utils.MetaExists,
|
|
Element: "~*req.NumberOfEvents",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
fltr2 := &engine.FilterWithAPIOpts{
|
|
Filter: &engine.Filter{
|
|
Tenant: utils.CGRateSorg,
|
|
ID: "fltr_changed2",
|
|
Rules: []*engine.FilterRule{
|
|
{
|
|
Type: utils.MetaString,
|
|
Element: "~*opts.*originID",
|
|
Values: []string{"QWEASDZXC", "IOPJKLBNM"},
|
|
},
|
|
{
|
|
Type: utils.MetaString,
|
|
Element: "~*opts.Subsystems",
|
|
Values: []string{"*attributes"},
|
|
},
|
|
{
|
|
Type: utils.MetaNotExists,
|
|
Element: "~*opts.*rates",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
var reply string
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetFilter,
|
|
fltr1, &reply); err != nil {
|
|
t.Error(err)
|
|
} else if reply != utils.OK {
|
|
t.Error("Unexpected reply result", reply)
|
|
}
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetFilter,
|
|
fltr2, &reply); err != nil {
|
|
t.Error(err)
|
|
} else if reply != utils.OK {
|
|
t.Error("Unexpected reply result", reply)
|
|
}
|
|
}
|
|
|
|
func testTPeSetRateProfiles(t *testing.T) {
|
|
ratePrf := &utils.APIRateProfile{
|
|
RateProfile: &utils.RateProfile{
|
|
Tenant: utils.CGRateSorg,
|
|
ID: "TEST_RATE_IT_TEST",
|
|
FilterIDs: []string{"*string:~*req.Account:dan"},
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 10,
|
|
},
|
|
},
|
|
MaxCostStrategy: "*free",
|
|
Rates: map[string]*utils.Rate{
|
|
"RT_WEEK": {
|
|
ID: "RT_WEEK",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 0,
|
|
},
|
|
},
|
|
ActivationTimes: "* * * * 1-5",
|
|
IntervalRates: []*utils.IntervalRate{
|
|
{
|
|
IntervalStart: utils.NewDecimal(0, 0),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
var reply string
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetRateProfile,
|
|
ratePrf, &reply); err != nil {
|
|
t.Error(err)
|
|
} else if reply != utils.OK {
|
|
t.Error(err)
|
|
}
|
|
ratePrf2 := &utils.APIRateProfile{
|
|
RateProfile: &utils.RateProfile{
|
|
Tenant: utils.CGRateSorg,
|
|
ID: "MultipleRates",
|
|
FilterIDs: []string{"*exists:~*req.CGRID:", "*prefix:~*req.Destination:12354"},
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 20,
|
|
},
|
|
},
|
|
MinCost: utils.NewDecimal(2, 1),
|
|
MaxCost: utils.NewDecimal(20244, 3),
|
|
MaxCostStrategy: "*free",
|
|
Rates: map[string]*utils.Rate{
|
|
"RT_MONDAY": {
|
|
ID: "RT_MONDAY",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 50,
|
|
},
|
|
},
|
|
ActivationTimes: "* * * * 0",
|
|
IntervalRates: []*utils.IntervalRate{
|
|
{
|
|
IntervalStart: utils.NewDecimal(0, 0),
|
|
FixedFee: utils.NewDecimal(33, 2),
|
|
Increment: utils.NewDecimal(int64(time.Second), 0),
|
|
RecurrentFee: utils.NewDecimal(int64(time.Second), 0),
|
|
Unit: utils.NewDecimal(int64(time.Minute), 0),
|
|
},
|
|
{
|
|
IntervalStart: utils.NewDecimal(int64(60*time.Second), 0),
|
|
FixedFee: utils.NewDecimal(1, 1),
|
|
Increment: utils.NewDecimal(int64(time.Minute), 0),
|
|
RecurrentFee: utils.NewDecimal(int64(time.Second), 0),
|
|
Unit: utils.NewDecimal(int64(time.Minute), 0),
|
|
},
|
|
},
|
|
},
|
|
"RT_THUESDAY": {
|
|
ID: "RT_THUESDAY",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 40,
|
|
},
|
|
},
|
|
FilterIDs: []string{"*string:~*opts.*rates:true"},
|
|
ActivationTimes: "* * * * 1",
|
|
IntervalRates: []*utils.IntervalRate{
|
|
{
|
|
IntervalStart: utils.NewDecimal(0, 0),
|
|
FixedFee: utils.NewDecimal(20, 2),
|
|
Increment: utils.NewDecimal(int64(time.Second), 0),
|
|
RecurrentFee: utils.NewDecimal(int64(time.Second), 0),
|
|
Unit: utils.NewDecimal(int64(time.Minute), 0),
|
|
},
|
|
{
|
|
IntervalStart: utils.NewDecimal(int64(45*time.Second), 0),
|
|
FixedFee: utils.NewDecimal(0, 0),
|
|
Increment: utils.NewDecimal(int64(time.Minute), 0),
|
|
RecurrentFee: utils.NewDecimal(int64(time.Second), 0),
|
|
Unit: utils.NewDecimal(int64(time.Minute), 0),
|
|
},
|
|
},
|
|
},
|
|
"RT_WEDNESDAY": {
|
|
ID: "RT_WEDNESDAY",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 30,
|
|
},
|
|
},
|
|
ActivationTimes: "* * * * 2",
|
|
IntervalRates: []*utils.IntervalRate{
|
|
{
|
|
IntervalStart: utils.NewDecimal(0, 0),
|
|
FixedFee: utils.NewDecimal(1, 1),
|
|
Increment: utils.NewDecimal(int64(time.Second), 0),
|
|
RecurrentFee: utils.NewDecimal(int64(time.Second), 0),
|
|
Unit: utils.NewDecimal(int64(time.Minute), 0),
|
|
},
|
|
{
|
|
IntervalStart: utils.NewDecimal(int64(45*time.Second), 0),
|
|
FixedFee: utils.NewDecimal(2, 3),
|
|
Increment: utils.NewDecimal(int64(time.Minute), 0),
|
|
RecurrentFee: utils.NewDecimal(int64(time.Second), 0),
|
|
Unit: utils.NewDecimal(int64(time.Minute), 0),
|
|
},
|
|
},
|
|
},
|
|
"RT_THURSDAY": {
|
|
ID: "RT_THURSDAY",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 20,
|
|
},
|
|
},
|
|
ActivationTimes: "* * * * 3",
|
|
IntervalRates: []*utils.IntervalRate{
|
|
{
|
|
IntervalStart: utils.NewDecimal(0, 0),
|
|
FixedFee: utils.NewDecimal(2, 1),
|
|
Increment: utils.NewDecimal(int64(time.Second), 0),
|
|
RecurrentFee: utils.NewDecimal(int64(time.Second), 0),
|
|
Unit: utils.NewDecimal(int64(time.Minute), 0),
|
|
},
|
|
{
|
|
IntervalStart: utils.NewDecimal(int64(time.Minute), 0),
|
|
FixedFee: utils.NewDecimal(1, 3),
|
|
Increment: utils.NewDecimal(int64(time.Minute), 0),
|
|
RecurrentFee: utils.NewDecimal(int64(time.Second), 0),
|
|
Unit: utils.NewDecimal(int64(time.Minute), 0),
|
|
},
|
|
},
|
|
},
|
|
"RT_FRIDAY": {
|
|
ID: "RT_FRIDAY",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 10,
|
|
},
|
|
},
|
|
ActivationTimes: "* * * * 4",
|
|
IntervalRates: []*utils.IntervalRate{
|
|
{
|
|
IntervalStart: utils.NewDecimal(0, 0),
|
|
FixedFee: utils.NewDecimal(5, 1),
|
|
Increment: utils.NewDecimal(int64(time.Second), 0),
|
|
RecurrentFee: utils.NewDecimal(int64(time.Second), 0),
|
|
Unit: utils.NewDecimal(int64(time.Minute), 0),
|
|
},
|
|
{
|
|
IntervalStart: utils.NewDecimal(int64(time.Minute+30*time.Second), 0),
|
|
FixedFee: utils.NewDecimal(21, 3),
|
|
Increment: utils.NewDecimal(int64(time.Minute), 0),
|
|
RecurrentFee: utils.NewDecimal(int64(time.Second), 0),
|
|
Unit: utils.NewDecimal(int64(time.Minute), 0),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetRateProfile,
|
|
ratePrf2, &reply); err != nil {
|
|
t.Error(err)
|
|
} else if reply != utils.OK {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func testTPeSetChargerProfiles(t *testing.T) {
|
|
chgrsPrf := &ChargerWithAPIOpts{
|
|
ChargerProfile: &engine.ChargerProfile{
|
|
Tenant: "cgrates.org",
|
|
ID: "Chargers1",
|
|
RunID: utils.MetaDefault,
|
|
AttributeIDs: []string{"*none"},
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 20,
|
|
},
|
|
},
|
|
},
|
|
APIOpts: nil,
|
|
}
|
|
var reply string
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetChargerProfile,
|
|
chgrsPrf, &reply); err != nil {
|
|
t.Error(err)
|
|
} else if reply != utils.OK {
|
|
t.Error(err)
|
|
}
|
|
chgrsPrf2 := &ChargerWithAPIOpts{
|
|
ChargerProfile: &engine.ChargerProfile{
|
|
Tenant: "cgrates.org",
|
|
ID: "DifferentCharger",
|
|
RunID: "Raw",
|
|
AttributeIDs: []string{"ATTR1"},
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 0,
|
|
},
|
|
},
|
|
},
|
|
APIOpts: nil,
|
|
}
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetChargerProfile,
|
|
chgrsPrf2, &reply); err != nil {
|
|
t.Error(err)
|
|
} else if reply != utils.OK {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func testTPeSetRouteProfiles(t *testing.T) {
|
|
prf := &engine.RouteProfileWithAPIOpts{
|
|
RouteProfile: &engine.RouteProfile{
|
|
ID: "ROUTE_2003",
|
|
Tenant: "cgrates.org",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 10,
|
|
},
|
|
},
|
|
Sorting: utils.MetaWeight,
|
|
SortingParameters: []string{},
|
|
Routes: []*engine.Route{
|
|
{
|
|
ID: "route1",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 20,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
var reply string
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetRouteProfile,
|
|
prf, &reply); err != nil {
|
|
t.Error(err)
|
|
} else if reply != utils.OK {
|
|
t.Error(err)
|
|
}
|
|
rt2 := &engine.RouteProfileWithAPIOpts{
|
|
RouteProfile: &engine.RouteProfile{
|
|
ID: "ROUTE_ACNT_1001",
|
|
Tenant: "cgrates.org",
|
|
FilterIDs: []string{"*string:~*req.Account:1001"},
|
|
Sorting: "*weight",
|
|
Routes: []*engine.Route{
|
|
{
|
|
ID: "vendor1",
|
|
FilterIDs: []string{"FLTR_DEST_1003"},
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 10,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
ID: "vendor2",
|
|
FilterIDs: []string{"*gte:~*accounts.1001.Balance[Concrete1].Units:10"},
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 20,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
ID: "vendor3",
|
|
FilterIDs: []string{"FLTR_DEST_1003", "*prefix:~*req.Account:10"},
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 40,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
ID: "vendor4",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 35,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetRouteProfile,
|
|
rt2, &reply); err != nil {
|
|
t.Error(err)
|
|
} else if reply != utils.OK {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func testTPeSetAccount(t *testing.T) {
|
|
args := &utils.AccountWithAPIOpts{
|
|
Account: &utils.Account{
|
|
Tenant: "cgrates.org",
|
|
ID: "Account_simple",
|
|
Opts: map[string]interface{}{},
|
|
Balances: map[string]*utils.Balance{
|
|
"VoiceBalance": {
|
|
ID: "VoiceBalance",
|
|
FilterIDs: []string{"*string:~*req.Account:1001"},
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 12,
|
|
},
|
|
},
|
|
Blockers: utils.DynamicBlockers{
|
|
{
|
|
FilterIDs: []string{"*prefix:~*req.Destination:+443"},
|
|
Blocker: true,
|
|
},
|
|
{
|
|
Blocker: false,
|
|
},
|
|
},
|
|
Type: "*abstract",
|
|
Opts: map[string]interface{}{
|
|
"Destination": "10",
|
|
},
|
|
Units: utils.NewDecimal(0, 0),
|
|
},
|
|
},
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 10,
|
|
},
|
|
},
|
|
},
|
|
APIOpts: nil,
|
|
}
|
|
var reply string
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetAccount,
|
|
args, &reply); err != nil {
|
|
t.Error(err)
|
|
} else if reply != utils.OK {
|
|
t.Error(err)
|
|
}
|
|
acnt1 := &utils.AccountWithAPIOpts{
|
|
Account: &utils.Account{
|
|
Tenant: utils.CGRateSorg,
|
|
ID: "Account_balances",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 10,
|
|
},
|
|
},
|
|
Blockers: utils.DynamicBlockers{
|
|
{
|
|
FilterIDs: []string{"*string:~*req.Destination:1002"},
|
|
Blocker: true,
|
|
},
|
|
{
|
|
Blocker: false,
|
|
},
|
|
},
|
|
Balances: map[string]*utils.Balance{
|
|
"AB1": {
|
|
ID: "AB1",
|
|
Type: utils.MetaAbstract,
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 40,
|
|
},
|
|
},
|
|
Blockers: utils.DynamicBlockers{
|
|
{
|
|
Blocker: false,
|
|
},
|
|
},
|
|
CostIncrements: []*utils.CostIncrement{
|
|
{
|
|
Increment: utils.NewDecimal(int64(time.Minute), 0),
|
|
FixedFee: utils.NewDecimal(4, 1), // 0.4
|
|
RecurrentFee: utils.NewDecimal(2, 1), // 0.2 per minute
|
|
},
|
|
},
|
|
Units: utils.NewDecimal(int64(130*time.Second), 0),
|
|
},
|
|
"CB1": {
|
|
ID: "CB1",
|
|
Type: utils.MetaConcrete,
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 30,
|
|
},
|
|
},
|
|
Opts: map[string]interface{}{
|
|
utils.MetaBalanceLimit: -200.0,
|
|
},
|
|
CostIncrements: []*utils.CostIncrement{
|
|
{
|
|
Increment: utils.NewDecimal(int64(time.Second), 0),
|
|
RecurrentFee: utils.NewDecimal(1, 1), // 0.1 per second
|
|
},
|
|
},
|
|
UnitFactors: []*utils.UnitFactor{
|
|
{
|
|
Factor: utils.NewDecimal(100, 0), // EuroCents
|
|
},
|
|
},
|
|
Units: utils.NewDecimal(80, 0),
|
|
},
|
|
"ab2": {
|
|
ID: "ab2",
|
|
Type: utils.MetaAbstract,
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 20,
|
|
},
|
|
},
|
|
CostIncrements: []*utils.CostIncrement{
|
|
{
|
|
Increment: utils.NewDecimal(int64(time.Second), 0),
|
|
RecurrentFee: utils.NewDecimal(0, 0)},
|
|
},
|
|
Units: utils.NewDecimal(int64(1*time.Minute), 0), // 1 Minute,
|
|
},
|
|
"ab3": {
|
|
ID: "ab3",
|
|
Type: utils.MetaAbstract,
|
|
FilterIDs: []string{"*string:*~req.Account:AnotherAccount"},
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 10,
|
|
},
|
|
},
|
|
CostIncrements: []*utils.CostIncrement{
|
|
{
|
|
Increment: utils.NewDecimal(int64(time.Second), 0),
|
|
RecurrentFee: utils.NewDecimal(1, 0)},
|
|
},
|
|
Units: utils.NewDecimal(int64(60*time.Second), 0), // 1 Minute
|
|
},
|
|
"cb2": {
|
|
ID: "cb2",
|
|
Type: utils.MetaConcrete,
|
|
CostIncrements: []*utils.CostIncrement{
|
|
{
|
|
Increment: utils.NewDecimal(int64(time.Second), 0),
|
|
},
|
|
},
|
|
AttributeIDs: []string{utils.MetaNone},
|
|
Units: utils.NewDecimal(125, 2), // 1.25
|
|
},
|
|
},
|
|
},
|
|
}
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetAccount,
|
|
acnt1, &reply); err != nil {
|
|
t.Error(err)
|
|
} else if reply != utils.OK {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func testTPeSetStatQueueProfile(t *testing.T) {
|
|
sqPrf := &engine.StatQueueProfileWithAPIOpts{
|
|
StatQueueProfile: &engine.StatQueueProfile{
|
|
Tenant: "cgrates.org",
|
|
ID: "SQ_2",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 20,
|
|
},
|
|
},
|
|
QueueLength: 14,
|
|
ThresholdIDs: []string{utils.MetaNone},
|
|
Blockers: utils.DynamicBlockers{{Blocker: false}},
|
|
Metrics: []*engine.MetricWithFilters{
|
|
{
|
|
MetricID: utils.MetaASR,
|
|
},
|
|
{
|
|
MetricID: utils.MetaTCD,
|
|
},
|
|
{
|
|
MetricID: utils.MetaPDD,
|
|
},
|
|
{
|
|
MetricID: utils.MetaTCC,
|
|
},
|
|
{
|
|
MetricID: utils.MetaTCD,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
var reply string
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetStatQueueProfile,
|
|
sqPrf, &reply); err != nil {
|
|
t.Error(err)
|
|
} else if reply != utils.OK {
|
|
t.Error("Unexpected reply returned:", reply)
|
|
}
|
|
|
|
sqPrf2 := &engine.StatQueueProfileWithAPIOpts{
|
|
StatQueueProfile: &engine.StatQueueProfile{
|
|
Tenant: "cgrates.org",
|
|
ID: "SQ_basic",
|
|
TTL: 0,
|
|
Blockers: utils.DynamicBlockers{{Blocker: true}},
|
|
MinItems: 3,
|
|
Stored: true,
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 10,
|
|
},
|
|
},
|
|
Metrics: []*engine.MetricWithFilters{
|
|
{
|
|
MetricID: utils.MetaTCD,
|
|
},
|
|
},
|
|
ThresholdIDs: []string{utils.MetaNone},
|
|
},
|
|
}
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetStatQueueProfile,
|
|
sqPrf2, &reply); err != nil {
|
|
t.Error(err)
|
|
} else if reply != utils.OK {
|
|
t.Error("Unexpected reply returned:", reply)
|
|
}
|
|
}
|
|
|
|
func testTPeSetActions(t *testing.T) {
|
|
actPrf := &engine.ActionProfileWithAPIOpts{
|
|
ActionProfile: &engine.ActionProfile{
|
|
Tenant: "cgrates.org",
|
|
ID: "SET_BAL",
|
|
FilterIDs: []string{
|
|
"*string:~*req.Account:1001"},
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 10,
|
|
},
|
|
},
|
|
Targets: map[string]utils.StringSet{utils.MetaAccounts: {"1001": {}}},
|
|
Schedule: utils.MetaASAP,
|
|
Actions: []*engine.APAction{
|
|
{
|
|
ID: "SET_BAL",
|
|
Type: utils.MetaSetBalance,
|
|
Diktats: []*engine.APDiktat{
|
|
{
|
|
Path: "MONETARY",
|
|
Value: "10",
|
|
}},
|
|
},
|
|
},
|
|
},
|
|
APIOpts: map[string]interface{}{},
|
|
}
|
|
var reply string
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetActionProfile,
|
|
actPrf, &reply); err != nil {
|
|
t.Error(err)
|
|
} else if reply != utils.OK {
|
|
t.Error(err)
|
|
}
|
|
actPrf2 := &engine.ActionProfileWithAPIOpts{
|
|
ActionProfile: &engine.ActionProfile{
|
|
Tenant: "cgrates.org",
|
|
ID: "Execute_thd",
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 20,
|
|
},
|
|
},
|
|
Actions: []*engine.APAction{
|
|
{
|
|
ID: "actID",
|
|
Type: utils.MetaResetThreshold,
|
|
},
|
|
},
|
|
Targets: map[string]utils.StringSet{
|
|
utils.MetaThresholds: {
|
|
"THD_1": struct{}{},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetActionProfile,
|
|
actPrf2, &reply); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func testTPeSetThresholds(t *testing.T) {
|
|
thPrf2 := &engine.ThresholdProfileWithAPIOpts{
|
|
ThresholdProfile: &engine.ThresholdProfile{
|
|
Tenant: "cgrates.org",
|
|
ID: "THD_2",
|
|
FilterIDs: []string{"*string:~*req.Account:1001"},
|
|
ActionProfileIDs: []string{"actPrfID"},
|
|
MaxHits: 7,
|
|
MinHits: 0,
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 20,
|
|
},
|
|
},
|
|
Async: true,
|
|
},
|
|
}
|
|
|
|
var reply string
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetThresholdProfile,
|
|
thPrf2, &reply); err != nil {
|
|
t.Error(err)
|
|
} else if reply != utils.OK {
|
|
t.Error("Unexpected reply returned:", reply)
|
|
}
|
|
tPrfl := &engine.ThresholdProfileWithAPIOpts{
|
|
ThresholdProfile: &engine.ThresholdProfile{
|
|
Tenant: "cgrates.org",
|
|
ID: "TH_Stats1",
|
|
FilterIDs: []string{"*string:~*req.Account:1010", "*ai:~*req.AnswerTime:2014-07-14T14:35:00Z|2014-07-14T14:36:00Z", "*string:~*req.Destination:1011"},
|
|
MaxHits: -1,
|
|
MinSleep: time.Millisecond,
|
|
Weights: utils.DynamicWeights{
|
|
{
|
|
Weight: 10,
|
|
},
|
|
},
|
|
ActionProfileIDs: []string{"LOG"},
|
|
Async: true,
|
|
},
|
|
}
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetThresholdProfile, tPrfl, &reply); err != nil {
|
|
t.Error(err)
|
|
} else if reply != utils.OK {
|
|
t.Error("Unexpected reply returned", reply)
|
|
}
|
|
}
|
|
|
|
func testTPeSetDispatcherProfiles(t *testing.T) {
|
|
dspPrf := &DispatcherWithAPIOpts{
|
|
DispatcherProfile: &engine.DispatcherProfile{
|
|
Tenant: "cgrates.org",
|
|
ID: "Dsp1",
|
|
FilterIDs: []string{"*string:~*req.Account:1001", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"},
|
|
Strategy: utils.MetaFirst,
|
|
StrategyParams: map[string]interface{}{
|
|
utils.MetaDefaultRatio: "false",
|
|
},
|
|
Weight: 20,
|
|
Hosts: engine.DispatcherHostProfiles{
|
|
{
|
|
ID: "C1",
|
|
FilterIDs: []string{},
|
|
Weight: 10,
|
|
Params: map[string]interface{}{"0": "192.168.54.203"},
|
|
Blocker: false,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
var result string
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetDispatcherProfile, dspPrf, &result); err != nil {
|
|
t.Fatal(err)
|
|
} else if result != utils.OK {
|
|
t.Error("Unexpected reply returned", result)
|
|
}
|
|
|
|
dspPrf2 := &DispatcherWithAPIOpts{
|
|
DispatcherProfile: &engine.DispatcherProfile{
|
|
Tenant: "cgrates.org",
|
|
ID: "Dsp2",
|
|
FilterIDs: []string{"*string:~*opts.EventType:LoadDispatcher"},
|
|
Strategy: utils.MetaWeight,
|
|
Weight: 10,
|
|
Hosts: engine.DispatcherHostProfiles{
|
|
{
|
|
ID: "Conn2",
|
|
FilterIDs: []string{"*suffix:~*opts.*answerTime:45T"},
|
|
Params: map[string]interface{}{utils.MetaRatio: 1},
|
|
Blocker: false,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetDispatcherProfile, dspPrf2, &result); err != nil {
|
|
t.Fatal(err)
|
|
} else if result != utils.OK {
|
|
t.Error("Unexpected reply returned", result)
|
|
}
|
|
}
|
|
|
|
func testSeTPeSetDispatcherHosts(t *testing.T) {
|
|
dspPrf := &engine.DispatcherHostWithAPIOpts{
|
|
DispatcherHost: &engine.DispatcherHost{
|
|
Tenant: "cgrates.org",
|
|
RemoteHost: &config.RemoteHost{
|
|
ID: "DSH1",
|
|
Address: "*internal",
|
|
ConnectAttempts: 1,
|
|
Reconnects: 3,
|
|
MaxReconnectInterval: 5 * time.Minute,
|
|
ConnectTimeout: time.Minute,
|
|
ReplyTimeout: 2 * time.Minute,
|
|
},
|
|
},
|
|
}
|
|
var result string
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetDispatcherHost, dspPrf, &result); err != nil {
|
|
t.Fatal(err)
|
|
} else if result != utils.OK {
|
|
t.Error("Unexpected reply returned", result)
|
|
}
|
|
|
|
dspPrf2 := &engine.DispatcherHostWithAPIOpts{
|
|
DispatcherHost: &engine.DispatcherHost{
|
|
Tenant: "cgrates.org",
|
|
RemoteHost: &config.RemoteHost{
|
|
ID: "DSH2",
|
|
Address: "127.0.0.1:6012",
|
|
Transport: utils.MetaJSON,
|
|
ConnectAttempts: 1,
|
|
Reconnects: 3,
|
|
ConnectTimeout: time.Minute,
|
|
ReplyTimeout: 2 * time.Minute,
|
|
},
|
|
},
|
|
}
|
|
if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetDispatcherHost, dspPrf2, &result); err != nil {
|
|
t.Fatal(err)
|
|
} else if result != utils.OK {
|
|
t.Error("Unexpected reply returned", result)
|
|
}
|
|
}
|
|
|
|
func testTPeSExportTariffPlanHalfTariffPlan(t *testing.T) {
|
|
var replyBts []byte
|
|
// we will get only the wantes tariff plans in the csv format
|
|
if err := tpeSRPC.Call(context.Background(), utils.TPeSv1ExportTariffPlan, &tpes.ArgsExportTP{
|
|
Tenant: "cgrates.org",
|
|
ExportItems: map[string][]string{
|
|
utils.MetaAttributes: {"TEST_ATTRIBUTES_IT_TEST"},
|
|
utils.MetaResources: {"ResGroup1"},
|
|
utils.MetaFilters: {"fltr_for_prf"},
|
|
utils.MetaRates: {"MultipleRates"},
|
|
utils.MetaChargers: {"Chargers1"},
|
|
utils.MetaRoutes: {"ROUTE_2003"},
|
|
utils.MetaAccounts: {"Account_balances"},
|
|
utils.MetaStats: {"SQ_basic"},
|
|
utils.MetaActions: {"Execute_thd"},
|
|
utils.MetaThresholds: {"TH_Stats1"},
|
|
utils.MetaDispatchers: {"Dsp1"},
|
|
utils.MetaDispatcherHosts: {"DSH1"},
|
|
},
|
|
}, &replyBts); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
rdr, err := zip.NewReader(bytes.NewReader(replyBts), int64(len(replyBts)))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
csvRply := make(map[string][][]string)
|
|
for _, f := range rdr.File {
|
|
rc, err := f.Open()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
info := csv.NewReader(rc)
|
|
//info.FieldsPerRecord = -1
|
|
csvFile, err := info.ReadAll()
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
csvRply[f.Name] = append(csvRply[f.Name], csvFile...)
|
|
rc.Close()
|
|
}
|
|
|
|
expected := map[string][][]string{
|
|
utils.AttributesCsv: {
|
|
{"#Tenant", "ID", "FilterIDs", "Weights", "Blockers", "AttributeFilterIDs", "AttributeBlockers", "Path", "Type", "Value"},
|
|
{"cgrates.org", "TEST_ATTRIBUTES_IT_TEST", "*string:~*req.Account:1002;*exists:~*opts.*usage:", ";20", ";true", "", "*string:~*req.Account:1002;true;;false", "Account", "*constant", "1002"},
|
|
{"cgrates.org", "TEST_ATTRIBUTES_IT_TEST", "", "", "", "", "", "*tenant", "*constant", "cgrates.itsyscom"},
|
|
},
|
|
utils.ResourcesCsv: {
|
|
{"#Tenant", "ID", "FIlterIDs", "Weights", "TTL", "Limit", "AlocationMessage", "Blocker", "Stored", "ThresholdIDs"},
|
|
{"cgrates.org", "ResGroup1", "*string:~*req.Account:1001", ";20", "", "10", "Approved", "false", "false", "*none"},
|
|
},
|
|
utils.FiltersCsv: {
|
|
{"#Tenant", "ID", "Type", "Path", "Values"},
|
|
{"cgrates.org", "fltr_for_prf", "*string", "~*req.Subject", "1004;6774;22312"},
|
|
{"cgrates.org", "fltr_for_prf", "*string", "~*opts.Subsystems", "*attributes"},
|
|
{"cgrates.org", "fltr_for_prf", "*prefix", "~*req.Destinations", "+0775;+442"},
|
|
{"cgrates.org", "fltr_for_prf", "*exists", "~*req.NumberOfEvents", ""},
|
|
},
|
|
utils.RatesCsv: {
|
|
{"#Tenant", "ID", "FilterIDs", "Weights", "MinCost", "MaxCost", "MaxCostStrategy", "RateID", "RateFilterIDs", "RateActivationStart", "RateWeights", "RateBlocker", "RateIntervalStart", "RateFixedFee", "RateRecurrentFee", "RateUnit", "RateIncrement"},
|
|
{"cgrates.org", "MultipleRates", "*exists:~*req.CGRID:;*prefix:~*req.Destination:12354", ";20", "0.2", "20.244", "*free", "RT_MONDAY", "", "* * * * 0", ";50", "false", "0", "0.33", "1000000000", "60000000000", "1000000000"},
|
|
{"cgrates.org", "MultipleRates", "", "", "0", "0", "", "RT_MONDAY", "", "", "", "false", "60000000000", "0.1", "1000000000", "60000000000", "60000000000"},
|
|
{"cgrates.org", "MultipleRates", "", "", "0", "0", "", "RT_THUESDAY", "*string:~*opts.*rates:true", "* * * * 1", ";40", "false", "0", "0.2", "1000000000", "60000000000", "1000000000"},
|
|
{"cgrates.org", "MultipleRates", "", "", "0", "0", "", "RT_THUESDAY", "", "", "", "false", "45000000000", "0", "1000000000", "60000000000", "60000000000"},
|
|
{"cgrates.org", "MultipleRates", "", "", "0", "0", "", "RT_THURSDAY", "", "* * * * 3", ";20", "false", "0", "0.2", "1000000000", "60000000000", "1000000000"},
|
|
{"cgrates.org", "MultipleRates", "", "", "0", "0", "", "RT_THURSDAY", "", "", "", "false", "60000000000", "0.001", "1000000000", "60000000000", "60000000000"},
|
|
{"cgrates.org", "MultipleRates", "", "", "0", "0", "", "RT_WEDNESDAY", "", "* * * * 2", ";30", "false", "0", "0.1", "1000000000", "60000000000", "1000000000"},
|
|
{"cgrates.org", "MultipleRates", "", "", "0", "0", "", "RT_WEDNESDAY", "", "", "", "false", "45000000000", "0.002", "1000000000", "60000000000", "60000000000"},
|
|
{"cgrates.org", "MultipleRates", "", "", "0", "0", "", "RT_FRIDAY", "", "* * * * 4", ";10", "false", "0", "0.5", "1000000000", "60000000000", "1000000000"},
|
|
{"cgrates.org", "MultipleRates", "", "", "0", "0", "", "RT_FRIDAY", "", "", "", "false", "90000000000", "0.021", "1000000000", "60000000000", "60000000000"},
|
|
},
|
|
utils.ChargersCsv: {
|
|
{"#Tenant", "ID", "FilterIDs", "Weights", "Blockers", "RunID", "AttributeIDs"},
|
|
{"cgrates.org", "Chargers1", "", ";20", "", "*default", "*none"},
|
|
},
|
|
utils.RoutesCsv: {
|
|
{"#Tenant", "ID", "FilterIDs", "Weights", "Blockers", "Sorting", "SortingParameters", "RouteID", "RouteFilterIDs", "RouteAccountIDs", "RouteRateProfileIDs", "RouteResourceIDs", "RouteStatIDs", "RouteWeights", "RouteBlockers", "RouteParameters"},
|
|
{"cgrates.org", "ROUTE_2003", "", ";10", "", "*weight", "", "route1", "", "", "", "", "", ";20", "", ""},
|
|
},
|
|
utils.AccountsCsv: {
|
|
{"#Tenant", "ID", "FilterIDs", "Weights", "Opts", "BalanceID", "BalanceFilterIDs", "BalanceWeights", "BalanceBlockers", "BalanceType", "BalanceUnits", "BalanceUnitFactors", "BalanceOpts", "BalanceCostIncrements", "BalanceAttributeIDs", "BalanceRateProfileIDs", "ThresholdIDs"},
|
|
{"cgrates.org", "Account_balances", "", ";10", "", "ab2", "", ";20", "", "*abstract", "60000000000", "", "", ";1000000000;;0", "", "", ""},
|
|
{"cgrates.org", "Account_balances", "", "", "", "ab3", "*string:*~req.Account:AnotherAccount", ";10", "", "*abstract", "60000000000", "", "", ";1000000000;;1", "", "", ""},
|
|
{"cgrates.org", "Account_balances", "", "", "", "cb2", "", "", "", "*concrete", "1.25", "", "", ";1000000000;;", "*none", "", ""},
|
|
{"cgrates.org", "Account_balances", "", "", "", "AB1", "", ";40", ";false", "*abstract", "130000000000", "", "", ";60000000000;0.4;0.2", "", "", ""},
|
|
{"cgrates.org", "Account_balances", "", "", "", "CB1", "", ";30", "", "*concrete", "80", ";100", "*balanceLimit:-200", ";1000000000;;0.1", "", "", ""},
|
|
},
|
|
utils.StatsCsv: {
|
|
{"#Tenant", "ID", "FilterIDs", "Weights", "Blockers", "QueueLength", "TTL", "MinItems", "Stored", "ThresholdIDs", "MetricIDs", "MetricFilterIDs", "MetricBlockers"},
|
|
{"cgrates.org", "SQ_basic", "", ";10", ";true", "0", "", "3", "true", "*none", "*tcd", "", ""},
|
|
},
|
|
utils.ActionsCsv: {
|
|
{"#Tenant", "ID", "FilterIDs", "Weights", "Blockers", "Schedule", "TargetType", "TargetIDs", "ActionID", "ActionFilterIDs", "ActionTTL", "ActionType", "ActionOpts", "ActionPath", "ActionValue"},
|
|
{"cgrates.org", "Execute_thd", "", ";20", "", "", "*thresholds", "THD_1", "actID", "", "0s", "*reset_threshold", "", "", ""},
|
|
},
|
|
utils.ThresholdsCsv: {
|
|
{"#Tenant", "ID", "FilterIDs", "Weights", "MaxHits", "MinHits", "MinSleep", "Blocker", "ActionProfileIDs", "Async"},
|
|
{"cgrates.org", "TH_Stats1", "*string:~*req.Account:1010", ";10", "-1", "0", "1ms", "false", "LOG", "true"},
|
|
{"cgrates.org", "TH_Stats1", "*ai:~*req.AnswerTime:2014-07-14T14:35:00Z|2014-07-14T14:36:00Z", "", "0", "0", "", "false", "", "false"},
|
|
{"cgrates.org", "TH_Stats1", "*string:~*req.Destination:1011", "", "0", "0", "", "false", "", "false"},
|
|
},
|
|
utils.DispatcherProfilesCsv: {
|
|
{"#Tenant", "ID", "FilterIDs", "Weight", "Strategy", "StrategyParameters", "ConnID", "ConnFilterIDs", "ConnWeight", "ConnBlocker", "ConnParameters"},
|
|
{"cgrates.org", "Dsp1", "*string:~*req.Account:1001;*ai:~*req.AnswerTime:2014-07-14T14:25:00Z", "20", "*first", "false", "C1", "", "10", "false", "192.168.54.203"},
|
|
},
|
|
utils.DispatcherHostsCsv: {
|
|
{"#Tenant", "ID", "Address", "Transport", "ConnectAttempts", "Reconnects", "MaxReconnectInterval", "ConnectTimeout", "ReplyTimeout", "Tls", "ClientKey", "ClientCertificate", "CaCertificate"},
|
|
{"cgrates.org", "DSH1", "*internal", "", "1", "3", "5m0s", "1m0s", "2m0s", "false", "", "", ""},
|
|
},
|
|
}
|
|
// we do this copy of the value one xpected because there are some values in a slice that are hard to concatenate as sorted
|
|
expected[utils.RatesCsv] = csvRply[utils.RatesCsv]
|
|
expected[utils.AccountsCsv] = csvRply[utils.AccountsCsv]
|
|
|
|
if !reflect.DeepEqual(expected, csvRply) {
|
|
t.Errorf("Expected %+v \n received %+v", utils.ToJSON(expected), utils.ToJSON(csvRply))
|
|
}
|
|
}
|
|
|
|
func testTPeSExportTariffPlanAllTariffPlan(t *testing.T) {
|
|
var replyBts []byte
|
|
// we will get all the tariffplans from the database
|
|
if err := tpeSRPC.Call(context.Background(), utils.TPeSv1ExportTariffPlan, &tpes.ArgsExportTP{
|
|
Tenant: "cgrates.org",
|
|
ExportItems: map[string][]string{
|
|
utils.MetaAttributes: {"TEST_ATTRIBUTES_IT_TEST", "TEST_ATTRIBUTES_IT_TEST_SECOND"},
|
|
utils.MetaResources: {"ResGroup1", "ResGroup2"},
|
|
utils.MetaFilters: {"fltr_for_prf", "fltr_changed2"},
|
|
utils.MetaRates: {"MultipleRates", "TEST_RATE_IT_TEST"},
|
|
utils.MetaChargers: {"Chargers1", "DifferentCharger"},
|
|
utils.MetaRoutes: {"ROUTE_2003", "ROUTE_ACNT_1001"},
|
|
utils.MetaAccounts: {"Account_balances", "Account_simple"},
|
|
utils.MetaStats: {"SQ_basic", "SQ_2"},
|
|
utils.MetaActions: {"Execute_thd", "SET_BAL"},
|
|
utils.MetaThresholds: {"TH_Stats1", "THD_2"},
|
|
utils.MetaDispatchers: {"Dsp1", "Dsp2"},
|
|
utils.MetaDispatcherHosts: {"DSH1", "DSH2"},
|
|
},
|
|
}, &replyBts); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
rdr, err := zip.NewReader(bytes.NewReader(replyBts), int64(len(replyBts)))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
csvRply := make(map[string][][]string)
|
|
for _, f := range rdr.File {
|
|
rc, err := f.Open()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
info := csv.NewReader(rc)
|
|
//info.FieldsPerRecord = -1
|
|
csvFile, err := info.ReadAll()
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
csvRply[f.Name] = append(csvRply[f.Name], csvFile...)
|
|
rc.Close()
|
|
}
|
|
|
|
expected := map[string][][]string{
|
|
utils.AttributesCsv: {
|
|
{"#Tenant", "ID", "FilterIDs", "Weights", "Blockers", "AttributeFilterIDs", "AttributeBlockers", "Path", "Type", "Value"},
|
|
{"cgrates.org", "TEST_ATTRIBUTES_IT_TEST", "*string:~*req.Account:1002;*exists:~*opts.*usage:", ";20", ";true", "", "*string:~*req.Account:1002;true;;false", "Account", "*constant", "1002"},
|
|
{"cgrates.org", "TEST_ATTRIBUTES_IT_TEST", "", "", "", "", "", "*tenant", "*constant", "cgrates.itsyscom"},
|
|
{"cgrates.org", "TEST_ATTRIBUTES_IT_TEST_SECOND", "*string:~*opts.*context:*sessions;*exists:~*opts.*usage:", "", "", "", "", "*tenant", "*constant", "cgrates.itsyscom"},
|
|
},
|
|
utils.ResourcesCsv: {
|
|
{"#Tenant", "ID", "FIlterIDs", "Weights", "TTL", "Limit", "AlocationMessage", "Blocker", "Stored", "ThresholdIDs"},
|
|
{"cgrates.org", "ResGroup1", "*string:~*req.Account:1001", ";20", "", "10", "Approved", "false", "false", "*none"},
|
|
{"cgrates.org", "ResGroup2", "*string:~*req.Account:1002", ";10", "", "5", "Declined", "false", "false", "*none"},
|
|
},
|
|
utils.FiltersCsv: {
|
|
{"#Tenant", "ID", "Type", "Path", "Values"},
|
|
{"cgrates.org", "fltr_for_prf", "*string", "~*req.Subject", "1004;6774;22312"},
|
|
{"cgrates.org", "fltr_for_prf", "*string", "~*opts.Subsystems", "*attributes"},
|
|
{"cgrates.org", "fltr_for_prf", "*prefix", "~*req.Destinations", "+0775;+442"},
|
|
{"cgrates.org", "fltr_for_prf", "*exists", "~*req.NumberOfEvents", ""},
|
|
{"cgrates.org", "fltr_changed2", "*string", "~*opts.*originID", "QWEASDZXC;IOPJKLBNM"},
|
|
{"cgrates.org", "fltr_changed2", "*string", "~*opts.Subsystems", "*attributes"},
|
|
{"cgrates.org", "fltr_changed2", "*notexists", "~*opts.*rates", ""},
|
|
},
|
|
utils.RatesCsv: {
|
|
{"#Tenant", "ID", "FilterIDs", "Weights", "MinCost", "MaxCost", "MaxCostStrategy", "RateID", "RateFilterIDs", "RateActivationStart", "RateWeights", "RateBlocker", "RateIntervalStart", "RateFixedFee", "RateRecurrentFee", "RateUnit", "RateIncrement"},
|
|
{"cgrates.org", "MultipleRates", "*exists:~*req.CGRID:;*prefix:~*req.Destination:12354", ";20", "0.2", "20.244", "*free", "RT_MONDAY", "", "* * * * 0", ";50", "false", "0", "0.33", "1000000000", "60000000000", "1000000000"},
|
|
{"cgrates.org", "MultipleRates", "", "", "0", "0", "", "RT_MONDAY", "", "", "", "false", "60000000000", "0.1", "1000000000", "60000000000", "60000000000"},
|
|
{"cgrates.org", "MultipleRates", "", "", "0", "0", "", "RT_THUESDAY", "*string:~*opts.*rates:true", "* * * * 1", ";40", "false", "0", "0.2", "1000000000", "60000000000", "1000000000"},
|
|
{"cgrates.org", "MultipleRates", "", "", "0", "0", "", "RT_THUESDAY", "", "", "", "false", "45000000000", "0", "1000000000", "60000000000", "60000000000"},
|
|
{"cgrates.org", "MultipleRates", "", "", "0", "0", "", "RT_THURSDAY", "", "* * * * 3", ";20", "false", "0", "0.2", "1000000000", "60000000000", "1000000000"},
|
|
{"cgrates.org", "MultipleRates", "", "", "0", "0", "", "RT_THURSDAY", "", "", "", "false", "60000000000", "0.001", "1000000000", "60000000000", "60000000000"},
|
|
{"cgrates.org", "MultipleRates", "", "", "0", "0", "", "RT_WEDNESDAY", "", "* * * * 2", ";30", "false", "0", "0.1", "1000000000", "60000000000", "1000000000"},
|
|
{"cgrates.org", "MultipleRates", "", "", "0", "0", "", "RT_WEDNESDAY", "", "", "", "false", "45000000000", "0.002", "1000000000", "60000000000", "60000000000"},
|
|
{"cgrates.org", "MultipleRates", "", "", "0", "0", "", "RT_FRIDAY", "", "* * * * 4", ";10", "false", "0", "0.5", "1000000000", "60000000000", "1000000000"},
|
|
{"cgrates.org", "MultipleRates", "", "", "0", "0", "", "RT_FRIDAY", "", "", "", "false", "90000000000", "0.021", "1000000000", "60000000000", "60000000000"},
|
|
{"cgrates.org", "TEST_RATE_IT_TEST", "*string:~*req.Account:dan", ";10", "0", "0", "*free", "RT_WEEK", "", "* * * * 1-5", ";0", "false", "0", "0", "0", "", ""},
|
|
},
|
|
utils.ChargersCsv: {
|
|
{"#Tenant", "ID", "FilterIDs", "Weights", "Blockers", "RunID", "AttributeIDs"},
|
|
{"cgrates.org", "Chargers1", "", ";20", "", "*default", "*none"},
|
|
{"cgrates.org", "DifferentCharger", "", ";0", "", "Raw", "ATTR1"},
|
|
},
|
|
utils.RoutesCsv: {
|
|
{"#Tenant", "ID", "FilterIDs", "Weights", "Blockers", "Sorting", "SortingParameters", "RouteID", "RouteFilterIDs", "RouteAccountIDs", "RouteRateProfileIDs", "RouteResourceIDs", "RouteStatIDs", "RouteWeights", "RouteBlockers", "RouteParameters"},
|
|
{"cgrates.org", "ROUTE_2003", "", ";10", "", "*weight", "", "route1", "", "", "", "", "", ";20", "", ""},
|
|
{"cgrates.org", "ROUTE_ACNT_1001", "*string:~*req.Account:1001", "", "", "*weight", "", "vendor1", "FLTR_DEST_1003", "", "", "", "", ";10", "", ""},
|
|
{"cgrates.org", "ROUTE_ACNT_1001", "", "", "", "", "", "vendor2", "*gte:~*accounts.1001.Balance[Concrete1].Units:10", "", "", "", "", ";20", "", ""},
|
|
{"cgrates.org", "ROUTE_ACNT_1001", "", "", "", "", "", "vendor3", "FLTR_DEST_1003;*prefix:~*req.Account:10", "", "", "", "", ";40", "", ""},
|
|
{"cgrates.org", "ROUTE_ACNT_1001", "", "", "", "", "", "vendor4", "", "", "", "", "", ";35", "", ""},
|
|
},
|
|
utils.AccountsCsv: {
|
|
{"#Tenant", "ID", "FilterIDs", "Weights", "Blockers", "Opts", "BalanceID", "BalanceFilterIDs", "BalanceWeights", "BalanceBlockers", "BalanceType", "BalanceUnits", "BalanceUnitFactors", "BalanceOpts", "BalanceCostIncrements", "BalanceAttributeIDs", "BalanceRateProfileIDs", "ThresholdIDs"},
|
|
{"cgrates.org", "Account_balances", "", ";10", "*string:~*req.Destination:1002;true;;false", "", "ab2", "", ";20", "", "*abstract", "60000000000", "", "", ";1000000000;;0", "", "", ""},
|
|
{"cgrates.org", "Account_balances", "", "", "", "", "ab3", "*string:*~req.Account:AnotherAccount", ";10", "", "*abstract", "60000000000", "", "", ";1000000000;;1", "", "", ""},
|
|
{"cgrates.org", "Account_balances", "", "", "", "", "cb2", "", "", "", "*concrete", "1.25", "", "", ";1000000000;;", "*none", "", ""},
|
|
{"cgrates.org", "Account_balances", "", "", "", "", "AB1", "", ";40", ";false", "*abstract", "130000000000", "", "", ";60000000000;0.4;0.2", "", "", ""},
|
|
{"cgrates.org", "Account_balances", "", "", "", "", "CB1", "", ";30", "", "*concrete", "80", ";100", "*balanceLimit:-200", ";1000000000;;0.1", "", "", ""},
|
|
{"cgrates.org", "Account_simple", "", ";10", "", "", "VoiceBalance", "*string:~*req.Account:1001", ";12", "*prefix:~*req.Destination:+443;true;;false", "*abstract", "0", "", "Destination:10", "", "", "", ""},
|
|
},
|
|
utils.StatsCsv: {
|
|
{"#Tenant", "ID", "FilterIDs", "Weights", "Blockers", "QueueLength", "TTL", "MinItems", "Stored", "ThresholdIDs", "MetricIDs", "MetricFilterIDs", "MetricBlockers"},
|
|
{"cgrates.org", "SQ_basic", "", ";10", ";true", "0", "", "3", "true", "*none", "*tcd", "", ""},
|
|
{"cgrates.org", "SQ_2", "", ";20", ";false", "14", "", "0", "false", "*none", "*asr", "", ""},
|
|
{"cgrates.org", "SQ_2", "", "", "", "0", "", "0", "false", "", "*tcd", "", ""},
|
|
{"cgrates.org", "SQ_2", "", "", "", "0", "", "0", "false", "", "*pdd", "", ""},
|
|
{"cgrates.org", "SQ_2", "", "", "", "0", "", "0", "false", "", "*tcc", "", ""},
|
|
{"cgrates.org", "SQ_2", "", "", "", "0", "", "0", "false", "", "*tcd", "", ""},
|
|
},
|
|
utils.ActionsCsv: {
|
|
{"#Tenant", "ID", "FilterIDs", "Weights", "Blockers", "Schedule", "TargetType", "TargetIDs", "ActionID", "ActionFilterIDs", "ActionTTL", "ActionType", "ActionOpts", "ActionPath", "ActionValue"},
|
|
{"cgrates.org", "Execute_thd", "", ";20", "", "", "*thresholds", "THD_1", "actID", "", "0s", "*reset_threshold", "", "", ""},
|
|
{"cgrates.org", "SET_BAL", "*string:~*req.Account:1001", ";10", "", "*asap", "*accounts", "1001", "SET_BAL", "", "0s", "*set_balance", "", "MONETARY", "10"},
|
|
},
|
|
utils.ThresholdsCsv: {
|
|
{"#Tenant", "ID", "FilterIDs", "Weights", "MaxHits", "MinHits", "MinSleep", "Blocker", "ActionProfileIDs", "Async"},
|
|
{"cgrates.org", "TH_Stats1", "*string:~*req.Account:1010", ";10", "-1", "0", "1ms", "false", "LOG", "true"},
|
|
{"cgrates.org", "TH_Stats1", "*ai:~*req.AnswerTime:2014-07-14T14:35:00Z|2014-07-14T14:36:00Z", "", "0", "0", "", "false", "", "false"},
|
|
{"cgrates.org", "TH_Stats1", "*string:~*req.Destination:1011", "", "0", "0", "", "false", "", "false"},
|
|
{"cgrates.org", "THD_2", "*string:~*req.Account:1001", ";20", "7", "0", "", "false", "actPrfID", "true"},
|
|
},
|
|
utils.DispatcherProfilesCsv: {
|
|
{"#Tenant", "ID", "FilterIDs", "Weight", "Strategy", "StrategyParameters", "ConnID", "ConnFilterIDs", "ConnWeight", "ConnBlocker", "ConnParameters"},
|
|
{"cgrates.org", "Dsp1", "*string:~*req.Account:1001;*ai:~*req.AnswerTime:2014-07-14T14:25:00Z", "20", "*first", "false", "C1", "", "10", "false", "192.168.54.203"},
|
|
{"cgrates.org", "Dsp2", "*string:~*opts.EventType:LoadDispatcher", "10", "*weight", "", "Conn2", "*suffix:~*opts.*answerTime:45T", "0", "false", "*ratio:1"},
|
|
},
|
|
utils.DispatcherHostsCsv: {
|
|
{"#Tenant", "ID", "Address", "Transport", "ConnectAttempts", "Reconnects", "MaxReconnectInterval", "ConnectTimeout", "ReplyTimeout", "Tls", "ClientKey", "ClientCertificate", "CaCertificate"},
|
|
{"cgrates.org", "DSH1", "*internal", "", "1", "3", "5m0s", "1m0s", "2m0s", "false", "", "", ""},
|
|
{"cgrates.org", "DSH2", "127.0.0.1:6012", "*json", "1", "3", "0s", "1m0s", "2m0s", "false", "", "", ""},
|
|
},
|
|
}
|
|
expected[utils.RatesCsv] = csvRply[utils.RatesCsv]
|
|
expected[utils.AccountsCsv] = csvRply[utils.AccountsCsv]
|
|
|
|
if !reflect.DeepEqual(expected, csvRply) {
|
|
t.Errorf("Expected %+v \n received %+v", utils.ToJSON(expected), utils.ToJSON(csvRply))
|
|
}
|
|
|
|
// by giving an empty list of exportItems, this will do the same, it will get all the tariffplan in CSV format
|
|
var replyBts2 []byte
|
|
if err := tpeSRPC.Call(context.Background(), utils.TPeSv1ExportTariffPlan, &tpes.ArgsExportTP{
|
|
Tenant: "cgrates.org",
|
|
ExportItems: map[string][]string{},
|
|
}, &replyBts2); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
rdr, err = zip.NewReader(bytes.NewReader(replyBts), int64(len(replyBts)))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
csvRply = make(map[string][][]string)
|
|
for _, f := range rdr.File {
|
|
rc, err := f.Open()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
info := csv.NewReader(rc)
|
|
info.FieldsPerRecord = -1
|
|
csvFile, err := info.ReadAll()
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
csvRply[f.Name] = append(csvRply[f.Name], csvFile...)
|
|
rc.Close()
|
|
}
|
|
// expected will remain the same
|
|
if !reflect.DeepEqual(expected, csvRply) {
|
|
t.Errorf("Expected %+v \n received %+v", utils.ToJSON(expected), utils.ToJSON(csvRply))
|
|
}
|
|
}
|
|
|
|
func testTPeSExportAfterFlush(t *testing.T) {
|
|
var replyBts []byte
|
|
// we will get all the tariffplans from the database
|
|
if err := tpeSRPC.Call(context.Background(), utils.TPeSv1ExportTariffPlan, &tpes.ArgsExportTP{
|
|
Tenant: "cgrates.org",
|
|
}, &replyBts); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
rdr, err := zip.NewReader(bytes.NewReader(replyBts), int64(len(replyBts)))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
csvRply := make(map[string][][]string)
|
|
for _, f := range rdr.File {
|
|
rc, err := f.Open()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
info := csv.NewReader(rc)
|
|
csvFile, err := info.ReadAll()
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
csvRply[f.Name] = append(csvRply[f.Name], csvFile...)
|
|
rc.Close()
|
|
}
|
|
// empty exporters, nothing in database to export
|
|
if len(csvRply) != 0 {
|
|
t.Errorf("Unexpected length, expected to be 0, no exports were nedeed and got zip containing: \n %v", utils.ToJSON(csvRply))
|
|
}
|
|
}
|
|
|
|
// Kill the engine when it is about to be finished
|
|
func testTPeSKillEngine(t *testing.T) {
|
|
if err := engine.KillEngine(100); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|