mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
all tests pass
This commit is contained in:
@@ -4,4 +4,6 @@ CUSTOMER_1,0,OUT,rif:from:tm,danb,STANDARD,2012-02-28T00:00:00Z
|
||||
CUSTOMER_2,0,OUT,danb:87.139.12.167,danb,STANDARD,2012-01-01T00:00:00Z
|
||||
CUSTOMER_1,0,OUT,danb,,PREMIUM,2012-01-01T00:00:00Z
|
||||
vdf,0,OUT,rif,,EVENING,2012-01-01T00:00:00Z
|
||||
vdf,0,OUT,rif,,EVENING,2012-02-28T00:00:00Z
|
||||
vdf,0,OUT,rif,,EVENING,2012-02-28T00:00:00Z
|
||||
vdf,0,OUT,minu,,EVENING,2012-01-01T00:00:00Z
|
||||
vdf,0,OUT,minu,,EVENING,2012-02-28T00:00:00Z
|
||||
|
@@ -86,7 +86,7 @@ func logAction(ub *UserBalance, a *Action) (err error) {
|
||||
}
|
||||
|
||||
func resetTriggersAction(ub *UserBalance, a *Action) (err error) {
|
||||
ub.ResetActionTriggers()
|
||||
ub.resetActionTriggers()
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -178,7 +178,7 @@ func (cd *CallDescriptor) splitTimeSpan(firstSpan *TimeSpan) (timespans []*TimeS
|
||||
timespans = append(timespans, firstSpan)
|
||||
// split on (free) minute buckets
|
||||
if userBalance, err := cd.getUserBalance(); err == nil && userBalance != nil {
|
||||
_, bucketList := userBalance.getSecondsForPrefix(cd.Destination)
|
||||
_, _, bucketList := userBalance.getSecondsForPrefix(cd.Destination)
|
||||
for _, mb := range bucketList {
|
||||
for i := 0; i < len(timespans); i++ {
|
||||
if timespans[i].MinuteInfo != nil {
|
||||
@@ -296,8 +296,7 @@ func (cd *CallDescriptor) GetMaxSessionTime() (seconds float64, err error) {
|
||||
if userBalance.Type == UB_TYPE_POSTPAID {
|
||||
return -1, nil
|
||||
} else {
|
||||
availableCredit = userBalance.BalanceMap[CREDIT]
|
||||
availableSeconds, _ = userBalance.getSecondsForPrefix(cd.Destination)
|
||||
availableSeconds, availableCredit, _ = userBalance.getSecondsForPrefix(cd.Destination)
|
||||
}
|
||||
} else {
|
||||
return cd.Amount, err
|
||||
@@ -306,10 +305,9 @@ func (cd *CallDescriptor) GetMaxSessionTime() (seconds float64, err error) {
|
||||
if availableCredit == 0 {
|
||||
return availableSeconds, nil
|
||||
}
|
||||
|
||||
maxSessionSeconds := cd.Amount
|
||||
for i := 0; i < 10; i++ {
|
||||
maxDuration, _ := time.ParseDuration(fmt.Sprintf("%vs", maxSessionSeconds))
|
||||
maxDuration, _ := time.ParseDuration(fmt.Sprintf("%vs", maxSessionSeconds-availableSeconds))
|
||||
ts := &TimeSpan{TimeStart: now, TimeEnd: now.Add(maxDuration)}
|
||||
timespans := cd.splitTimeSpan(ts)
|
||||
|
||||
@@ -320,6 +318,7 @@ func (cd *CallDescriptor) GetMaxSessionTime() (seconds float64, err error) {
|
||||
}
|
||||
cost += ts.getCost(cd)
|
||||
}
|
||||
//log.Print(availableCredit, availableSeconds, cost)
|
||||
if cost < availableCredit {
|
||||
return maxSessionSeconds, nil
|
||||
} else { //decrease the period by 10% and try again
|
||||
|
||||
@@ -31,18 +31,27 @@ func init() {
|
||||
}
|
||||
|
||||
func populateDB() {
|
||||
ub := &UserBalance{
|
||||
minu := &UserBalance{
|
||||
Id: "OUT:vdf:minu",
|
||||
Type: UB_TYPE_PREPAID,
|
||||
/*BalanceMap: map[string]float64{
|
||||
BalanceMap: map[string]float64{
|
||||
CREDIT: 21,
|
||||
},*/
|
||||
},
|
||||
MinuteBuckets: []*MinuteBucket{
|
||||
&MinuteBucket{Seconds: 200, DestinationId: "NAT", Weight: 10},
|
||||
&MinuteBucket{Seconds: 100, DestinationId: "RET", Weight: 20},
|
||||
},
|
||||
}
|
||||
storageGetter.SetUserBalance(ub)
|
||||
broker := &UserBalance{
|
||||
Id: "OUT:vdf:broker",
|
||||
Type: UB_TYPE_PREPAID,
|
||||
MinuteBuckets: []*MinuteBucket{
|
||||
&MinuteBucket{Seconds: 20, DestinationId: "NAT", Weight: 10, Price: 1},
|
||||
&MinuteBucket{Seconds: 100, DestinationId: "RET", Weight: 20},
|
||||
},
|
||||
}
|
||||
storageGetter.SetUserBalance(broker)
|
||||
storageGetter.SetUserBalance(minu)
|
||||
}
|
||||
|
||||
func TestSplitSpans(t *testing.T) {
|
||||
@@ -174,7 +183,7 @@ func TestMaxSessionTimeNoUserBalance(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMaxSessionTimeWithUserBalance(t *testing.T) {
|
||||
cd := &CallDescriptor{Direction: "OUT", TOR: "0", Tenant: "vdf", Subject: "minu", Destination: "0723", Amount: 5400}
|
||||
cd := &CallDescriptor{Direction: "OUT", TOR: "0", Tenant: "vdf", Subject: "minu", Destination: "0723", Amount: 1000}
|
||||
result, err := cd.GetMaxSessionTime()
|
||||
expected := 300.0
|
||||
if result != expected || err != nil {
|
||||
|
||||
@@ -33,6 +33,7 @@ type MinuteBucket struct {
|
||||
precision int
|
||||
}
|
||||
|
||||
// Returns the available number of seconds for a specified credit
|
||||
func (mb *MinuteBucket) GetSecondsForCredit(credit float64) (seconds float64) {
|
||||
seconds = mb.Seconds
|
||||
if mb.Price > 0 {
|
||||
@@ -63,9 +64,3 @@ func (bs bucketsorter) Less(j, i int) bool {
|
||||
func (bs bucketsorter) Sort() {
|
||||
sort.Sort(bs)
|
||||
}
|
||||
|
||||
func (ub *UserBalance) ResetActionTriggers() {
|
||||
for _, at := range ub.ActionTriggers {
|
||||
at.executed = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package timespans
|
||||
|
||||
import (
|
||||
// "log"
|
||||
"sort"
|
||||
// "log"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -68,7 +67,7 @@ func (a AmountTooBig) Error() string {
|
||||
/*
|
||||
Returns user's available minutes for the specified destination
|
||||
*/
|
||||
func (ub *UserBalance) getSecondsForPrefix(prefix string) (seconds float64, bucketList bucketsorter) {
|
||||
func (ub *UserBalance) getSecondsForPrefix(prefix string) (seconds, credit float64, bucketList bucketsorter) {
|
||||
if len(ub.MinuteBuckets) == 0 {
|
||||
// log.Print("There are no minute buckets to check for user: ", ub.Id)
|
||||
return
|
||||
@@ -86,8 +85,8 @@ func (ub *UserBalance) getSecondsForPrefix(prefix string) (seconds float64, buck
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Sort(bucketList) // sorts the buckets according to priority, precision or price
|
||||
credit := ub.BalanceMap[CREDIT]
|
||||
bucketList.Sort() // sorts the buckets according to priority, precision or price
|
||||
credit = ub.BalanceMap[CREDIT]
|
||||
for _, mb := range bucketList {
|
||||
s := mb.GetSecondsForCredit(credit)
|
||||
credit -= s * mb.Price
|
||||
@@ -112,7 +111,7 @@ If the amount is bigger than the sum of all seconds in the minute buckets than n
|
||||
debited and an error will be returned.
|
||||
*/
|
||||
func (ub *UserBalance) debitMinutesBalance(amount float64, prefix string) error {
|
||||
avaliableNbSeconds, bucketList := ub.getSecondsForPrefix(prefix)
|
||||
avaliableNbSeconds, _, bucketList := ub.getSecondsForPrefix(prefix)
|
||||
if avaliableNbSeconds < amount {
|
||||
return new(AmountTooBig)
|
||||
}
|
||||
@@ -139,6 +138,7 @@ func (ub *UserBalance) debitMinutesBalance(amount float64, prefix string) error
|
||||
return new(AmountTooBig)
|
||||
}
|
||||
ub.BalanceMap[CREDIT] = credit // credit is > 0
|
||||
|
||||
for _, mb := range bucketList {
|
||||
if mb.Seconds < amount {
|
||||
amount -= mb.Seconds
|
||||
@@ -182,6 +182,7 @@ func (ub *UserBalance) addMinuteBucket(newMb *MinuteBucket) {
|
||||
}
|
||||
}
|
||||
|
||||
// Scans the action trigers and execute the actions for which trigger is met
|
||||
func (ub *UserBalance) executeActionTriggers() {
|
||||
ub.ActionTriggers.Sort()
|
||||
for _, at := range ub.ActionTriggers {
|
||||
@@ -209,6 +210,13 @@ func (ub *UserBalance) executeActionTriggers() {
|
||||
}
|
||||
}
|
||||
|
||||
// Mark all action trigers as ready for execution
|
||||
func (ub *UserBalance) resetActionTriggers() {
|
||||
for _, at := range ub.ActionTriggers {
|
||||
at.executed = false
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Adds the specified amount of seconds.
|
||||
*/
|
||||
|
||||
@@ -49,9 +49,9 @@ func TestGetSecondsForPrefix(t *testing.T) {
|
||||
b1 := &MinuteBucket{Seconds: 10, Weight: 10, DestinationId: "NAT"}
|
||||
b2 := &MinuteBucket{Seconds: 100, Weight: 20, DestinationId: "RET"}
|
||||
ub1 := &UserBalance{Id: "OUT:CUSTOMER_1:rif", MinuteBuckets: []*MinuteBucket{b1, b2}, BalanceMap: map[string]float64{CREDIT: 200}}
|
||||
seconds, bucketList := ub1.getSecondsForPrefix("0723")
|
||||
seconds, credit, bucketList := ub1.getSecondsForPrefix("0723")
|
||||
expected := 110.0
|
||||
if seconds != expected || bucketList[0].Weight < bucketList[1].Weight {
|
||||
if credit != 200 || seconds != expected || bucketList[0].Weight < bucketList[1].Weight {
|
||||
t.Errorf("Expected %v was %v", expected, seconds)
|
||||
}
|
||||
}
|
||||
@@ -61,9 +61,9 @@ func TestGetPricedSeconds(t *testing.T) {
|
||||
b2 := &MinuteBucket{Seconds: 100, Price: 1, Weight: 20, DestinationId: "RET"}
|
||||
|
||||
ub1 := &UserBalance{Id: "OUT:CUSTOMER_1:rif", MinuteBuckets: []*MinuteBucket{b1, b2}, BalanceMap: map[string]float64{CREDIT: 21}}
|
||||
seconds, bucketList := ub1.getSecondsForPrefix("0723")
|
||||
seconds, credit, bucketList := ub1.getSecondsForPrefix("0723")
|
||||
expected := 21.0
|
||||
if seconds != expected || bucketList[0].Weight < bucketList[1].Weight {
|
||||
if credit != 0 || seconds != expected || bucketList[0].Weight < bucketList[1].Weight {
|
||||
t.Errorf("Expected %v was %v", expected, seconds)
|
||||
}
|
||||
}
|
||||
@@ -168,7 +168,6 @@ func TestDebitPriceMinuteBalance(t *testing.T) {
|
||||
rifsBalance := &UserBalance{Id: "other", MinuteBuckets: []*MinuteBucket{b1, b2}, BalanceMap: map[string]float64{CREDIT: 21}}
|
||||
err := rifsBalance.debitMinutesBalance(5, "0723")
|
||||
if b2.Seconds != 95 || b1.Seconds != 10 || err != nil || rifsBalance.BalanceMap[CREDIT] != 16 {
|
||||
t.Log(rifsBalance.BalanceMap[CREDIT])
|
||||
t.Errorf("Expected %v was %v", 16, rifsBalance.BalanceMap[CREDIT])
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user