mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
tests passing on get max session time
This commit is contained in:
@@ -51,12 +51,12 @@ func (self *ApierV1) SetTPActions(attrs utils.TPActions, reply *string) error {
|
||||
BalanceId: act.BalanceType,
|
||||
Direction: act.Direction,
|
||||
ExpirationString: act.ExpiryTime,
|
||||
ExtraParameters: act.ExtraParameters,
|
||||
Balance: &engine.Balance{
|
||||
Value: act.Units,
|
||||
DestinationId: act.DestinationId,
|
||||
SpecialPriceType: act.RateType,
|
||||
SpecialPrice: act.Rate,
|
||||
Weight: act.MinutesWeight,
|
||||
Value: act.Units,
|
||||
DestinationId: act.DestinationId,
|
||||
RateSubject: act.RateSubject,
|
||||
Weight: act.BalanceWeight,
|
||||
},
|
||||
Weight: act.Weight,
|
||||
}
|
||||
|
||||
@@ -64,22 +64,30 @@ func (b *Balance) Clone() *Balance {
|
||||
// Returns the available number of seconds for a specified credit
|
||||
func (b *Balance) GetSecondsForCredit(cd *CallDescriptor, credit float64) (seconds float64) {
|
||||
seconds = b.Value
|
||||
// TODO: fix this
|
||||
cc, err := b.GetCost(cd)
|
||||
if err != nil {
|
||||
Logger.Err(fmt.Sprintf("Error getting new cost for balance subject: %v", err))
|
||||
return 0
|
||||
}
|
||||
if cc.Cost > 0 {
|
||||
seconds = math.Min(credit/cc.Cost, b.Value)
|
||||
secondCost := cc.Cost / cc.GetDuration().Seconds()
|
||||
// TODO: this is not very accurate
|
||||
// we should iterate timespans and increment to get exact number of minutes for
|
||||
// available credit
|
||||
seconds = math.Min(credit/secondCost, b.Value)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (b *Balance) GetCost(cd *CallDescriptor) (*CallCost, error) {
|
||||
cd.Subject = b.RateSubject
|
||||
cd.Account = cd.Subject
|
||||
return cd.GetCost()
|
||||
if b.RateSubject != "" {
|
||||
cd.Subject = b.RateSubject
|
||||
cd.Account = cd.Subject
|
||||
return cd.GetCost()
|
||||
}
|
||||
cc := cd.CreateCallCost()
|
||||
cc.Cost = 0
|
||||
return cc, nil
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -67,7 +67,7 @@ func (cc *CallCost) GetStartTime() time.Time {
|
||||
return cc.Timespans[0].TimeStart
|
||||
}
|
||||
|
||||
func (cc *CallCost) GetTotalDuration() (td time.Duration) {
|
||||
func (cc *CallCost) GetDuration() (td time.Duration) {
|
||||
for _, ts := range cc.Timespans {
|
||||
td += ts.GetDuration()
|
||||
}
|
||||
|
||||
@@ -128,8 +128,8 @@ func TestMultipleInputRightMerge(t *testing.T) {
|
||||
|
||||
func TestCallCostGetDurationZero(t *testing.T) {
|
||||
cc := &CallCost{}
|
||||
if cc.GetTotalDuration().Seconds() != 0 {
|
||||
t.Error("Wrong call cost duration for zero timespans: ", cc.GetTotalDuration())
|
||||
if cc.GetDuration().Seconds() != 0 {
|
||||
t.Error("Wrong call cost duration for zero timespans: ", cc.GetDuration())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ func TestCallCostGetDuration(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
if cc.GetTotalDuration().Seconds() != 90 {
|
||||
t.Error("Wrong call cost duration: ", cc.GetTotalDuration())
|
||||
if cc.GetDuration().Seconds() != 90 {
|
||||
t.Error("Wrong call cost duration: ", cc.GetDuration())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ func populateDB() {
|
||||
Type: UB_TYPE_PREPAID,
|
||||
BalanceMap: map[string]BalanceChain{
|
||||
MINUTES + OUTBOUND: BalanceChain{
|
||||
&Balance{Value: 20, DestinationId: "NAT", Weight: 10},
|
||||
&Balance{Value: 20, DestinationId: "NAT", Weight: 10, RateSubject: "rif"},
|
||||
&Balance{Value: 100, DestinationId: "RET", Weight: 20},
|
||||
}},
|
||||
}
|
||||
|
||||
@@ -561,12 +561,12 @@ func (self *SQLStorage) GetTPActions(tpid, actsId string) (*utils.TPActions, err
|
||||
i := 0
|
||||
for rows.Next() {
|
||||
i++ //Keep here a reference so we know we got at least one result
|
||||
var action, balanceId, dir, destId, rateType, expTime string
|
||||
var units, rate, minutesWeight, weight float64
|
||||
if err = rows.Scan(&action, &balanceId, &dir, &units, &expTime, &destId, &rateType, &rate, &minutesWeight, &weight); err != nil {
|
||||
var action, balanceId, dir, destId, rateSubject, expTime, extraParameters string
|
||||
var units, balanceWeight, weight float64
|
||||
if err = rows.Scan(&action, &balanceId, &dir, &units, &expTime, &destId, &rateSubject, &balanceWeight, &extraParameters, &weight); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
acts.Actions = append(acts.Actions, utils.Action{action, balanceId, dir, units, expTime, destId, rateType, rate, minutesWeight, weight})
|
||||
acts.Actions = append(acts.Actions, utils.Action{action, balanceId, dir, units, expTime, destId, rateSubject, balanceWeight, extraParameters, weight})
|
||||
}
|
||||
if i == 0 {
|
||||
return nil, nil
|
||||
|
||||
@@ -65,35 +65,15 @@ type UserBalance struct {
|
||||
BalanceMap map[string]BalanceChain
|
||||
UnitCounters []*UnitsCounter
|
||||
ActionTriggers ActionTriggerPriotityList
|
||||
|
||||
Groups GroupLinks // user info about groups
|
||||
Groups GroupLinks // user info about groups
|
||||
// group information
|
||||
UserIds []string // group info about users
|
||||
}
|
||||
|
||||
// Returns user's available minutes for the specified destination
|
||||
func (ub *UserBalance) getSecondsForPrefix(cd *CallDescriptor) (seconds, credit float64, balances BalanceChain) {
|
||||
credit = ub.getBalanceForPrefix(cd.Destination, ub.BalanceMap[CREDIT+cd.Direction]).GetTotalValue()
|
||||
if len(ub.BalanceMap[MINUTES+cd.Direction]) == 0 {
|
||||
// Logger.Debug("There are no minute buckets to check for user: ", ub.Id)
|
||||
return
|
||||
}
|
||||
for _, b := range ub.BalanceMap[MINUTES+cd.Direction] {
|
||||
if b.IsExpired() {
|
||||
continue
|
||||
}
|
||||
precision, err := storageGetter.DestinationContainsPrefix(b.DestinationId, cd.Destination)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if precision > 0 {
|
||||
b.precision = precision
|
||||
if b.Value > 0 {
|
||||
balances = append(balances, b)
|
||||
}
|
||||
}
|
||||
}
|
||||
balances.Sort() // sorts the buckets according to priority, precision or price
|
||||
credit = ub.getBalancesForPrefix(cd.Destination, ub.BalanceMap[CREDIT+cd.Direction]).GetTotalValue()
|
||||
balances = ub.getBalancesForPrefix(cd.Destination, ub.BalanceMap[MINUTES+cd.Direction])
|
||||
for _, b := range balances {
|
||||
s := b.GetSecondsForCredit(cd, credit)
|
||||
cc, err := b.GetCost(cd)
|
||||
@@ -101,7 +81,11 @@ func (ub *UserBalance) getSecondsForPrefix(cd *CallDescriptor) (seconds, credit
|
||||
Logger.Err(fmt.Sprintf("Error getting new cost for balance subject: %v", err))
|
||||
continue
|
||||
}
|
||||
credit -= s * cc.Cost
|
||||
if cc.Cost > 0 && cc.GetDuration() > 0 {
|
||||
// TODO: fix this
|
||||
secondCost := cc.Cost / cc.GetDuration().Seconds()
|
||||
credit -= s * secondCost
|
||||
}
|
||||
seconds += s
|
||||
}
|
||||
return
|
||||
@@ -140,7 +124,7 @@ func (ub *UserBalance) debitBalanceAction(a *Action) error {
|
||||
return nil //ub.BalanceMap[id].GetTotalValue()
|
||||
}
|
||||
|
||||
func (ub *UserBalance) getBalanceForPrefix(prefix string, balances BalanceChain) BalanceChain {
|
||||
func (ub *UserBalance) getBalancesForPrefix(prefix string, balances BalanceChain) BalanceChain {
|
||||
var usefulBalances BalanceChain
|
||||
for _, b := range balances {
|
||||
if b.IsExpired() || (ub.Type != UB_TYPE_POSTPAID && b.Value <= 0) {
|
||||
@@ -170,8 +154,8 @@ This method is the core of userbalance debiting: don't panic just follow the bra
|
||||
func (ub *UserBalance) debitCreditBalance(cc *CallCost, count bool) error {
|
||||
minuteBalances := ub.BalanceMap[MINUTES+cc.Direction]
|
||||
moneyBalances := ub.BalanceMap[CREDIT+cc.Direction]
|
||||
usefulMinuteBalances := ub.getBalanceForPrefix(cc.Destination, minuteBalances)
|
||||
usefulMoneyBalances := ub.getBalanceForPrefix(cc.Destination, moneyBalances)
|
||||
usefulMinuteBalances := ub.getBalancesForPrefix(cc.Destination, minuteBalances)
|
||||
usefulMoneyBalances := ub.getBalancesForPrefix(cc.Destination, moneyBalances)
|
||||
// debit connect fee
|
||||
if cc.ConnectFee > 0 {
|
||||
amount := cc.ConnectFee
|
||||
|
||||
@@ -112,26 +112,42 @@ func TestGetSecondsForPrefix(t *testing.T) {
|
||||
b2 := &Balance{Value: 100, Weight: 20, DestinationId: "RET"}
|
||||
ub1 := &UserBalance{Id: "OUT:CUSTOMER_1:rif", BalanceMap: map[string]BalanceChain{MINUTES + OUTBOUND: BalanceChain{b1, b2}, CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 200}}}}
|
||||
cd := &CallDescriptor{
|
||||
Destination: "0723",
|
||||
TOR: "0",
|
||||
Tenant: "vdf",
|
||||
TimeStart: time.Date(2013, 10, 4, 15, 46, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2013, 10, 4, 15, 46, 10, 0, time.UTC),
|
||||
LoopIndex: 0,
|
||||
CallDuration: 10 * time.Second,
|
||||
Direction: OUTBOUND,
|
||||
Destination: "0723",
|
||||
}
|
||||
seconds, credit, bucketList := ub1.getSecondsForPrefix(cd)
|
||||
expected := 110.0
|
||||
if credit != 200 || seconds != expected || bucketList[0].Weight < bucketList[1].Weight {
|
||||
t.Log(seconds, credit, bucketList)
|
||||
t.Errorf("Expected %v was %v", expected, seconds)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSpecialPricedSeconds(t *testing.T) {
|
||||
b1 := &Balance{Value: 10, Weight: 10, DestinationId: "NAT"}
|
||||
b2 := &Balance{Value: 100, Weight: 20, DestinationId: "RET"}
|
||||
b1 := &Balance{Value: 10, Weight: 10, DestinationId: "NAT", RateSubject: "minu"}
|
||||
b2 := &Balance{Value: 100, Weight: 20, DestinationId: "RET", RateSubject: "minu"}
|
||||
|
||||
ub1 := &UserBalance{Id: "OUT:CUSTOMER_1:rif", BalanceMap: map[string]BalanceChain{MINUTES + OUTBOUND: BalanceChain{b1, b2}, CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 21}}}}
|
||||
cd := &CallDescriptor{
|
||||
Destination: "0723",
|
||||
TOR: "0",
|
||||
Tenant: "vdf",
|
||||
TimeStart: time.Date(2013, 10, 4, 15, 46, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2013, 10, 4, 15, 46, 10, 0, time.UTC),
|
||||
LoopIndex: 0,
|
||||
CallDuration: 10 * time.Second,
|
||||
Direction: OUTBOUND,
|
||||
Destination: "0723",
|
||||
}
|
||||
seconds, credit, bucketList := ub1.getSecondsForPrefix(cd)
|
||||
expected := 21.0
|
||||
if credit != 0 || seconds != expected || len(bucketList) < 2 || bucketList[0].Weight < bucketList[1].Weight {
|
||||
t.Log(seconds, credit, bucketList)
|
||||
t.Errorf("Expected %v was %v", expected, seconds)
|
||||
}
|
||||
}
|
||||
@@ -510,7 +526,7 @@ func TestDebitCreditNoConectFeeCredit(t *testing.T) {
|
||||
t.Error("Error debiting balance: ", err)
|
||||
}
|
||||
|
||||
if len(cc.Timespans) != 0 || cc.GetTotalDuration() != 0 {
|
||||
if len(cc.Timespans) != 0 || cc.GetDuration() != 0 {
|
||||
t.Error("Error cutting at no connect fee: ", cc.Timespans)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,7 +307,7 @@ func (sm *FSSessionManager) LoopAction(s *Session, cd *engine.CallDescriptor, in
|
||||
s.sessionManager.DisconnectSession(s, SYSTEM_ERROR)
|
||||
}
|
||||
engine.Logger.Debug(fmt.Sprintf("Result of MaxDebit call: %v", cc))
|
||||
if cc.GetTotalDuration() == 0 || err != nil {
|
||||
if cc.GetDuration() == 0 || err != nil {
|
||||
engine.Logger.Info(fmt.Sprintf("No credit left: Disconnect %v", s))
|
||||
sm.DisconnectSession(s, INSUFFICIENT_FUNDS)
|
||||
return
|
||||
|
||||
@@ -87,7 +87,7 @@ func (s *Session) startDebitLoop() {
|
||||
}
|
||||
nextCd.TimeEnd = nextCd.TimeStart.Add(s.sessionManager.GetDebitPeriod())
|
||||
cc := s.sessionManager.LoopAction(s, &nextCd, index)
|
||||
time.Sleep(cc.GetTotalDuration())
|
||||
time.Sleep(cc.GetDuration())
|
||||
index++
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,16 +91,16 @@ type TPActions struct {
|
||||
}
|
||||
|
||||
type Action struct {
|
||||
Identifier string // Identifier mapped in the code
|
||||
BalanceType string // Type of balance the action will operate on
|
||||
Direction string // Balance direction
|
||||
Units float64 // Number of units to add/deduct
|
||||
ExpiryTime string // Time when the units will expire
|
||||
DestinationId string // Destination profile id
|
||||
RateType string // Type of rate <*absolute|*percent>
|
||||
Rate float64 // Price value
|
||||
MinutesWeight float64 // Minutes weight
|
||||
Weight float64 // Action's weight
|
||||
Identifier string // Identifier mapped in the code
|
||||
BalanceType string // Type of balance the action will operate on
|
||||
Direction string // Balance direction
|
||||
Units float64 // Number of units to add/deduct
|
||||
ExpiryTime string // Time when the units will expire
|
||||
DestinationId string // Destination profile id
|
||||
RateSubject string // Type of rate <*absolute|*percent>
|
||||
BalanceWeight float64 // Balance weight
|
||||
ExtraParameters string
|
||||
Weight float64 // Action's weight
|
||||
}
|
||||
|
||||
type ApiTPActionTimings struct {
|
||||
|
||||
Reference in New Issue
Block a user