Add tests to compare calculation of voice with a price

This commit is contained in:
TeoV
2021-02-19 14:28:48 +02:00
committed by Dan Christian Bogos
parent 2f05e64c81
commit 48e60b5bd7
12 changed files with 281 additions and 3 deletions

View File

@@ -58,6 +58,8 @@ func TestAccountSv1IT(t *testing.T) {
testAccountSv1DebitMultipleAccLimited,
testAccountSv1DebitWithAttributeSandRateS,
testAccountSv1DebitWithRateS,
testAccountSv1DebitWithRateS2,
testAccountSv1KillEngine,
}
switch *dbType {
case utils.MetaInternal:
@@ -926,3 +928,114 @@ func testAccountSv1DebitWithRateS(t *testing.T) {
t.Errorf("Expecting : %+v, received: %s", decimal.New(95, 0), reply2.Balances["Balance1"].Units)
}
}
func testAccountSv1DebitWithRateS2(t *testing.T) {
accPrfAPI := &APIAccountProfileWithCache{
APIAccountProfile: &utils.APIAccountProfile{
Tenant: "cgrates.org",
ID: "ACC_WITH_RATES2",
FilterIDs: []string{"*string:~*req.Account:ACC_WITH_RATES2"},
Weights: ";10",
Balances: map[string]*utils.APIBalance{
"Balance1": &utils.APIBalance{
ID: "Balance1",
Weights: ";10",
Type: utils.MetaAbstract,
Units: 100,
CostIncrements: []*utils.APICostIncrement{
{
Increment: utils.Float64Pointer(1),
RecurrentFee: utils.Float64Pointer(-1),
},
},
RateProfileIDs: []string{"RP_Test22"},
},
"Balance2": &utils.APIBalance{
ID: "Balance2",
Weights: ";10",
Type: utils.MetaConcrete,
Units: 100,
},
},
ThresholdIDs: []string{utils.MetaNone},
},
}
var reply string
if err := acntSRPC.Call(utils.APIerSv1SetAccountProfile, accPrfAPI, &reply); err != nil {
t.Error(err)
} else if reply != utils.OK {
t.Error("Unexpected reply returned", reply)
}
var err error
var convAcc *utils.AccountProfile
if convAcc, err = accPrfAPI.AsAccountProfile(); err != nil {
t.Error(err)
}
var reply2 *utils.AccountProfile
if err := acntSRPC.Call(utils.APIerSv1GetAccountProfile, &utils.TenantIDWithOpts{
TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: "ACC_WITH_RATES2"}}, &reply2); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(convAcc, reply2) {
t.Errorf("Expecting : %+v, received: %+v", convAcc, reply2)
}
//set a rate profile to be used in case of debit
apiRPrf := &engine.APIRateProfile{
Tenant: "cgrates.org",
ID: "RP_Test22",
FilterIDs: []string{"*string:~*req.Account:ACC_WITH_RATES2"},
Weights: ";20",
Rates: map[string]*engine.APIRate{
"RT_ALWAYS": {
ID: "RT_ALWAYS",
Weights: ";0",
ActivationTimes: "* * * * *",
IntervalRates: []*engine.APIIntervalRate{
{
IntervalStart: "0",
RecurrentFee: utils.Float64Pointer(0.5),
Increment: utils.Float64Pointer(2),
Unit: utils.Float64Pointer(2),
},
},
},
},
}
if err := acntSRPC.Call(utils.APIerSv1SetRateProfile,
&APIRateProfileWithCache{
APIRateProfileWithOpts: &engine.APIRateProfileWithOpts{
APIRateProfile: apiRPrf},
}, &reply); err != nil {
t.Fatal(err)
} else if reply != utils.OK {
t.Errorf("Expecting: %+v, received: %+v", utils.OK, reply)
}
var eEc *utils.ExtEventCharges
if err := acntSRPC.Call(utils.AccountSv1DebitUsage,
&utils.ArgsAccountsForEvent{CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testAccountSv1DebitWithAttributeS",
Event: map[string]interface{}{
utils.AccountField: "ACC_WITH_RATES2",
utils.Usage: "20",
}}}, &eEc); err != nil {
t.Error(err)
} else if eEc.Usage == nil || *eEc.Usage != 20.0 {
t.Fatalf("received usage: %v", *eEc.Usage)
}
if err := acntSRPC.Call(utils.APIerSv1GetAccountProfile, &utils.TenantIDWithOpts{
TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: "ACC_WITH_RATES2"}}, &reply2); err != nil {
t.Error(err)
} else if reply2.Balances["Balance1"].Units.Cmp(decimal.New(80, 0)) != 0 {
t.Errorf("Expecting : %+v, received: %s", decimal.New(80, 0), reply2.Balances["Balance1"].Units)
}
}
func testAccountSv1KillEngine(t *testing.T) {
if err := engine.KillEngine(100); err != nil {
t.Error(err)
}
}

View File

@@ -0,0 +1,145 @@
/*
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 main
import (
"flag"
"fmt"
"log"
"math/rand"
"net/rpc"
"net/rpc/jsonrpc"
"path"
"sync"
"time"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/utils"
)
var (
dataDir = flag.String("data_dir", "/usr/share/cgrates", "CGR data dir path here")
requests = flag.Int("requests", 10000, "Number of requests")
gorutines = flag.Int("goroutines", 5, "Number of simultaneous goroutines")
)
// How to run:
// 1) Start the engine with the following configuration < cgr-engine -config_path=/usr/share/cgrates/conf/samples/accounts_mysql >
// 2) Load the data with < cgr-loader -config_path=/usr/share/cgrates/conf/samples/accounts_mysql -verbose -path=/usr/share/cgrates/tariffplans/oldaccvsnew >
// 3) Run the program with < go run combined_max_usage.go -requests=10000 -goroutines=5 >
func main() {
flag.Parse()
var err error
var rpc *rpc.Client
var cfgPath string
var cfg *config.CGRConfig
cfgPath = path.Join(*dataDir, "conf", "samples", "accounts_mysql")
if cfg, err = config.NewCGRConfigFromPath(cfgPath); err != nil {
log.Fatal("Got config error: ", err.Error())
}
if rpc, err = jsonrpc.Dial(utils.TCP, cfg.ListenCfg().RPCJSONListen); err != nil {
return
}
s1 := rand.NewSource(time.Now().UnixNano())
r1 := rand.New(s1)
var wgAccountS sync.WaitGroup
var accountSTime time.Duration
var sumAccountS float64
var wgRALs sync.WaitGroup
var ralsTime time.Duration
var sumRALs float64
for i := 0; i < *requests; i++ {
wgAccountS.Add(1)
wgRALs.Add(1)
usage := fmt.Sprintf("%+vm", 1+r1.Intn(59))
go func() {
var eEc *utils.ExtEventCharges
arg := &utils.ArgsAccountsForEvent{CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
ID: utils.UUIDSha1Prefix(),
Event: map[string]interface{}{
utils.AccountField: "1002",
utils.ToR: utils.MetaVoice,
utils.Usage: usage,
}}}
tNow := time.Now()
if err := rpc.Call(utils.AccountSv1MaxUsage,
arg, &eEc); err != nil {
return
}
accountSTime += time.Now().Sub(tNow)
sumAccountS += *eEc.Usage
wgAccountS.Done()
}()
go func() {
tStart := time.Date(2016, 3, 31, 0, 0, 0, 0, time.UTC)
usageDur, _ := utils.ParseDurationWithNanosecs(usage)
cd := &engine.CallDescriptorWithOpts{
CallDescriptor: &engine.CallDescriptor{
Category: "call",
Tenant: "cgrates.org",
Subject: "1002",
Account: "1002",
Destination: "1003",
TimeStart: tStart,
TimeEnd: tStart.Add(usageDur),
},
}
var rply time.Duration
tNow := time.Now()
if err := rpc.Call(utils.ResponderGetMaxSessionTime, cd, &rply); err != nil {
return
}
ralsTime += time.Now().Sub(tNow)
sumRALs += rply.Seconds()
wgRALs.Done()
}()
if i%*gorutines == 0 {
wgAccountS.Wait()
wgRALs.Wait()
}
}
wgAccountS.Wait()
wgRALs.Wait()
fmt.Println("Sum AccountS MaxUsage")
fmt.Println(sumAccountS)
fmt.Println("Average AccountS MaxUsage")
fmt.Println(accountSTime / time.Duration(*requests))
fmt.Println("Total AccountS MaxUsage Time")
fmt.Println(accountSTime)
fmt.Println("Sum RALs GetMaxSessionTime")
fmt.Println(sumRALs)
fmt.Println("Average RALs GetMaxSessionTime")
fmt.Println(ralsTime / time.Duration(*requests))
fmt.Println("Total RALs GetMaxSessionTime Time")
fmt.Println(ralsTime)
}

View File

@@ -1,2 +1,3 @@
#Tenant,Account,ActionPlanId,ActionTriggersId,AllowNegative,Disabled
cgrates.org,1001,AP_PACKAGE_10,,,
cgrates.org,1001,AP_PACKAGE_10,,,
cgrates.org,1002,AP_PACKAGE_11,,,
1 #Tenant Account ActionPlanId ActionTriggersId AllowNegative Disabled
2 cgrates.org 1001 AP_PACKAGE_10
3 cgrates.org 1002 AP_PACKAGE_11

View File

@@ -1,3 +1,4 @@
#Tenant,ID,FilterIDs,ActivationInterval,Weights,Opts,BalanceID,BalanceFilterIDs,BalanceWeights,BalanceType,BalanceUnits,BalanceUnitFactors,BalanceOpts,BalanceCostIncrements,BalanceAttributeIDs,BalanceRateProfileIDs,ThresholdIDs
cgrates.org,1001,*string:~*req.Account:1001,,,,VoiceBalance,,;10,*abstract,3600000000000,,,*string:~*req.ToR:*voice;1000000000;0;0,,,
cgrates.org,1002,*string:~*req.Account:1002,,,,VoiceBalance,,;10,*abstract,3600000000000,,,*string:~*req.ToR:*voice;1000000000;0;-1,,RP_ANY,
cgrates.org,1002,,,,,MonetaryBalance,,;10,*concrete,100,,,,,,
1 #Tenant ID FilterIDs ActivationInterval Weights Opts BalanceID BalanceFilterIDs BalanceWeights BalanceType BalanceUnits BalanceUnitFactors BalanceOpts BalanceCostIncrements BalanceAttributeIDs BalanceRateProfileIDs ThresholdIDs
2 cgrates.org 1001 *string:~*req.Account:1001 VoiceBalance ;10 *abstract 3600000000000 *string:~*req.ToR:*voice;1000000000;0;0
3 cgrates.org 1002 *string:~*req.Account:1002 VoiceBalance ;10 *abstract 3600000000000 *string:~*req.ToR:*voice;1000000000;0;-1 RP_ANY
4 cgrates.org 1002 MonetaryBalance ;10 *concrete 100

View File

@@ -1,2 +1,3 @@
#Id,ActionsId,TimingId,Weight
AP_PACKAGE_10,ACT_TOPUP_RST_10,*asap,10
AP_PACKAGE_10,ACT_TOPUP_RST_10,*asap,10
AP_PACKAGE_11,ACT_TOPUP_RST_11,*asap,10
1 #Id ActionsId TimingId Weight
2 AP_PACKAGE_10 ACT_TOPUP_RST_10 *asap 10
3 AP_PACKAGE_11 ACT_TOPUP_RST_11 *asap 10

View File

@@ -1,2 +1,4 @@
#ActionsId[0],Action[1],ExtraParameters[2],Filter[3],BalanceId[4],BalanceType[5],Categories[6],DestinationIds[7],RatingSubject[8],SharedGroup[9],ExpiryTime[10],TimingIds[11],Units[12],BalanceWeight[13],BalanceBlocker[14],BalanceDisabled[15],Weight[16]
ACT_TOPUP_RST_10,*topup_reset,,,test,*voice,,*any,,,*unlimited,,3600000000000,10,false,false,10
ACT_TOPUP_RST_11,*topup_reset,,,,*voice,,*any,RP_ANY,,*unlimited,,3600000000000,10,false,false,10
ACT_TOPUP_RST_11,*topup_reset,,,,*monetary,,*any,,,*unlimited,,100,10,false,false,10
1 #ActionsId[0] Action[1] ExtraParameters[2] Filter[3] BalanceId[4] BalanceType[5] Categories[6] DestinationIds[7] RatingSubject[8] SharedGroup[9] ExpiryTime[10] TimingIds[11] Units[12] BalanceWeight[13] BalanceBlocker[14] BalanceDisabled[15] Weight[16]
2 ACT_TOPUP_RST_10 *topup_reset test *voice *any *unlimited 3600000000000 10 false false 10
3 ACT_TOPUP_RST_11 *topup_reset *voice *any RP_ANY *unlimited 3600000000000 10 false false 10
4 ACT_TOPUP_RST_11 *topup_reset *monetary *any *unlimited 100 10 false false 10

View File

@@ -0,0 +1,2 @@
#Tenant,ID,FilterIDs,ActivationInterval,RunID,AttributeIDs,Weight
cgrates.org,DEFAULT,,,*default,*none,0
1 #Tenant ID FilterIDs ActivationInterval RunID AttributeIDs Weight
2 cgrates.org DEFAULT *default *none 0

View File

@@ -0,0 +1,2 @@
#Id,DestinationId,RatesTag,RoundingMethod,RoundingDecimals,MaxCost,MaxCostStrategy
DR_ANY,*any,RT_ANY,*up,20,0,
1 #Id DestinationId RatesTag RoundingMethod RoundingDecimals MaxCost MaxCostStrategy
2 DR_ANY *any RT_ANY *up 20 0

View File

@@ -0,0 +1,3 @@
#Tenant,ID,FilterIDs,ActivationInterval,Weight,MinCost,MaxCost,MaxCostStrategy,RateID,RateFilterIDs,RateActivationStart,RateWeight,RateBlocker,RateIntervalStart,RateFixedFee,RateRecurrentFee,RateUnit,RateIncrement
cgrates.org,RP_ANY,,,,,,,RT_ANY,,,,,0s,0,0.2,60s,60s
cgrates.org,RP_ANY,,,,,,,RT_ANY,,,,,60s,0,0.1,60s,1s
1 #Tenant ID FilterIDs ActivationInterval Weight MinCost MaxCost MaxCostStrategy RateID RateFilterIDs RateActivationStart RateWeight RateBlocker RateIntervalStart RateFixedFee RateRecurrentFee RateUnit RateIncrement
2 cgrates.org RP_ANY RT_ANY 0s 0 0.2 60s 60s
3 cgrates.org RP_ANY RT_ANY 60s 0 0.1 60s 1s

View File

@@ -0,0 +1,3 @@
#Id,ConnectFee,Rate,RateUnit,RateIncrement,GroupIntervalStart
RT_ANY,0,0.2,60s,60s,0s
RT_ANY,0,0.1,60s,1s,60s
1 #Id ConnectFee Rate RateUnit RateIncrement GroupIntervalStart
2 RT_ANY 0 0.2 60s 60s 0s
3 RT_ANY 0 0.1 60s 1s 60s

View File

@@ -0,0 +1,2 @@
#Id,DestinationRatesId,TimingTag,Weight
RP_ANY,DR_ANY,*any,10
1 #Id DestinationRatesId TimingTag Weight
2 RP_ANY DR_ANY *any 10

View File

@@ -0,0 +1,3 @@
#Tenant,Category,Subject,ActivationTime,RatingPlanId,RatesFallbackSubject
cgrates.org,call,*any,2014-01-14T00:00:00Z,RP_ANY,
1 #Tenant Category Subject ActivationTime RatingPlanId RatesFallbackSubject
2 cgrates.org call *any 2014-01-14T00:00:00Z RP_ANY