mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
initial user budgets for test
This commit is contained in:
@@ -76,6 +76,7 @@ var (
|
||||
"TOPUP_RESET": topupResetAction,
|
||||
"TOPUP": topupAction,
|
||||
"DEBIT": debitAction,
|
||||
"RESET_COUNTERS": resetCountersAction,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -130,6 +131,11 @@ func debitAction(ub *UserBalance, a *Action) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func resetCountersAction(ub *UserBalance, a *Action) (err error) {
|
||||
//ub.UnitsCounters
|
||||
return
|
||||
}
|
||||
|
||||
type ActionTrigger struct {
|
||||
BalanceId string
|
||||
ThresholdValue float64
|
||||
|
||||
@@ -24,13 +24,25 @@ import (
|
||||
//"log"
|
||||
)
|
||||
|
||||
var (
|
||||
getter StorageGetter
|
||||
)
|
||||
|
||||
func init() {
|
||||
getter, _ = NewRedisStorage("tcp:127.0.0.1:6379", 10)
|
||||
SetStorageGetter(getter)
|
||||
storageGetter, _ = NewRedisStorage("tcp:127.0.0.1:6379", 10)
|
||||
SetStorageGetter(storageGetter)
|
||||
populateDB()
|
||||
}
|
||||
|
||||
func populateDB() {
|
||||
ub := &UserBalance{
|
||||
Id: "OUT:vdf:minu",
|
||||
Type: UB_TYPE_PREPAID,
|
||||
/*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)
|
||||
}
|
||||
|
||||
func TestSplitSpans(t *testing.T) {
|
||||
@@ -162,9 +174,9 @@ func TestMaxSessionTimeNoUserBalance(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMaxSessionTimeWithUserBalance(t *testing.T) {
|
||||
cd := &CallDescriptor{Direction: "OUT", TOR: "0", Tenant: "vdf", Subject: "minitsboy", Destination: "0723", Amount: 5400}
|
||||
cd := &CallDescriptor{Direction: "OUT", TOR: "0", Tenant: "vdf", Subject: "minu", Destination: "0723", Amount: 5400}
|
||||
result, err := cd.GetMaxSessionTime()
|
||||
expected := 200.0
|
||||
expected := 300.0
|
||||
if result != expected || err != nil {
|
||||
t.Errorf("Expected %v was %v", expected, result)
|
||||
}
|
||||
@@ -179,8 +191,8 @@ func TestMaxSessionTimeNoCredit(t *testing.T) {
|
||||
}
|
||||
|
||||
/*func TestGetCostWithVolumeDiscount(t *testing.T) {
|
||||
getter, _ := NewRedisStorage("tcp:127.0.0.1:6379", 10)
|
||||
defer getter.Close()
|
||||
storageGetter, _ := NewRedisStorage("tcp:127.0.0.1:6379", 10)
|
||||
defer storageGetter.Close()
|
||||
vd1 := &VolumeDiscount{100, 10}
|
||||
vd2 := &VolumeDiscount{500, 20}
|
||||
seara := &TariffPlan{Id: "seara", SmsCredit: 100, VolumeDiscountThresholds: []*VolumeDiscount{vd1, vd2}}
|
||||
@@ -219,7 +231,7 @@ func BenchmarkRedisGetting(b *testing.B) {
|
||||
cd := &CallDescriptor{Direction: "OUT", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2}
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
getter.GetActivationPeriodsOrFallback(cd.GetKey())
|
||||
storageGetter.GetActivationPeriodsOrFallback(cd.GetKey())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,17 @@ var (
|
||||
DestinationCacheMap = make(destinationCacheMap)
|
||||
)
|
||||
|
||||
func GetDestination(dId string) (d *Destination, err error) {
|
||||
d, exists := DestinationCacheMap[dId]
|
||||
if !exists {
|
||||
d, err = storageGetter.GetDestination(dId)
|
||||
if err == nil && d != nil {
|
||||
DestinationCacheMap[dId] = d
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
De-serializes the destination for the storage. Used for key-value storages.
|
||||
*/
|
||||
|
||||
@@ -58,6 +58,34 @@ func TestDestinationContainsPrefix(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestDestinationGetExists(t *testing.T) {
|
||||
d, err := GetDestination("NAT")
|
||||
if err != nil || d == nil {
|
||||
t.Error("Could not get destination: ", d)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDestinationGetExistsCache(t *testing.T) {
|
||||
GetDestination("NAT")
|
||||
if _, exists := DestinationCacheMap["NAT"]; !exists {
|
||||
t.Error("Destination not cached!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDestinationGetNotExists(t *testing.T) {
|
||||
d, err := GetDestination("not existing")
|
||||
if d != nil {
|
||||
t.Error("Got false destination: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDestinationGetNotExistsCache(t *testing.T) {
|
||||
GetDestination("not existing")
|
||||
if _, exists := DestinationCacheMap["not existing"]; exists {
|
||||
t.Error("Bad destination cached")
|
||||
}
|
||||
}
|
||||
|
||||
/********************************* Benchmarks **********************************/
|
||||
|
||||
func BenchmarkDestinationRedisStoreRestore(b *testing.B) {
|
||||
|
||||
@@ -20,6 +20,7 @@ package timespans
|
||||
|
||||
import (
|
||||
// "log"
|
||||
"sort"
|
||||
"math"
|
||||
)
|
||||
|
||||
@@ -39,3 +40,32 @@ func (mb *MinuteBucket) GetSecondsForCredit(credit float64) (seconds float64) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
Structure to store minute buckets according to weight, precision or price.
|
||||
*/
|
||||
type bucketsorter []*MinuteBucket
|
||||
|
||||
func (bs bucketsorter) Len() int {
|
||||
return len(bs)
|
||||
}
|
||||
|
||||
func (bs bucketsorter) Swap(i, j int) {
|
||||
bs[i], bs[j] = bs[j], bs[i]
|
||||
}
|
||||
|
||||
func (bs bucketsorter) Less(j, i int) bool {
|
||||
return bs[i].Weight < bs[j].Weight ||
|
||||
bs[i].precision < bs[j].precision ||
|
||||
bs[i].Price > bs[j].Price
|
||||
}
|
||||
|
||||
func (bs bucketsorter) Sort() {
|
||||
sort.Sort(bs)
|
||||
}
|
||||
|
||||
func (ub *UserBalance) ResetActionTriggers() {
|
||||
for _, at := range ub.ActionTriggers {
|
||||
at.executed = false
|
||||
}
|
||||
}
|
||||
|
||||
56
timespans/minute_buckets_test.go
Normal file
56
timespans/minute_buckets_test.go
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
Rating system designed to be used in VoIP Carriers World
|
||||
Copyright (C) 2012 Radu Ioan Fericean
|
||||
|
||||
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 timespans
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMinutBucketSortWeight(t *testing.T) {
|
||||
mb1 := &MinuteBucket{Weight: 1, precision: 2, Price: 2}
|
||||
mb2 := &MinuteBucket{Weight: 2, precision: 1, Price: 1}
|
||||
var bs bucketsorter
|
||||
bs = append(bs, mb2, mb1)
|
||||
bs.Sort()
|
||||
if bs[0] != mb1 || bs[1] != mb2 {
|
||||
t.Error("Buckets not sorted by weight!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMinutBucketSortPrecision(t *testing.T) {
|
||||
mb1 := &MinuteBucket{Weight: 1, precision: 2, Price: 2}
|
||||
mb2 := &MinuteBucket{Weight: 1, precision: 1, Price: 1}
|
||||
var bs bucketsorter
|
||||
bs = append(bs, mb2, mb1)
|
||||
bs.Sort()
|
||||
if bs[0] != mb1 || bs[1] != mb2 {
|
||||
t.Error("Buckets not sorted by precision!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMinutBucketSortPrice(t *testing.T) {
|
||||
mb1 := &MinuteBucket{Weight: 1, precision: 1, Price: 1}
|
||||
mb2 := &MinuteBucket{Weight: 1, precision: 1, Price: 2}
|
||||
var bs bucketsorter
|
||||
bs = append(bs, mb2, mb1)
|
||||
bs.Sort()
|
||||
if bs[0] != mb1 || bs[1] != mb2 {
|
||||
t.Error("Buckets not sorted by price!")
|
||||
}
|
||||
}
|
||||
@@ -65,31 +65,6 @@ func (a AmountTooBig) Error() string {
|
||||
return "Amount excedes balance!"
|
||||
}
|
||||
|
||||
/*
|
||||
Structure to store minute buckets according to weight, precision or price.
|
||||
*/
|
||||
type bucketsorter []*MinuteBucket
|
||||
|
||||
func (bs bucketsorter) Len() int {
|
||||
return len(bs)
|
||||
}
|
||||
|
||||
func (bs bucketsorter) Swap(i, j int) {
|
||||
bs[i], bs[j] = bs[j], bs[i]
|
||||
}
|
||||
|
||||
func (bs bucketsorter) Less(j, i int) bool {
|
||||
return bs[i].Weight < bs[j].Weight ||
|
||||
bs[i].precision < bs[j].precision ||
|
||||
bs[i].Price > bs[j].Price
|
||||
}
|
||||
|
||||
func (ub *UserBalance) ResetActionTriggers() {
|
||||
for _, at := range ub.ActionTriggers {
|
||||
at.executed = false
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Returns user's available minutes for the specified destination
|
||||
*/
|
||||
@@ -99,8 +74,8 @@ func (ub *UserBalance) getSecondsForPrefix(prefix string) (seconds float64, buck
|
||||
return
|
||||
}
|
||||
for _, mb := range ub.MinuteBuckets {
|
||||
d, exists := DestinationCacheMap[mb.DestinationId]
|
||||
if !exists {
|
||||
d, err := GetDestination(mb.DestinationId)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
contains, precision := d.containsPrefix(prefix)
|
||||
@@ -207,7 +182,7 @@ func (ub *UserBalance) addMinuteBucket(newMb *MinuteBucket) {
|
||||
}
|
||||
}
|
||||
|
||||
func (ub *UserBalance) ExecuteActionTriggers() {
|
||||
func (ub *UserBalance) executeActionTriggers() {
|
||||
ub.ActionTriggers.Sort()
|
||||
for _, at := range ub.ActionTriggers {
|
||||
if at.executed {
|
||||
|
||||
@@ -30,16 +30,16 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
getter, _ = NewRedisStorage("tcp:127.0.0.1:6379", 10)
|
||||
SetStorageGetter(getter)
|
||||
storageGetter, _ = NewRedisStorage("tcp:127.0.0.1:6379", 10)
|
||||
SetStorageGetter(storageGetter)
|
||||
}
|
||||
|
||||
func TestUserBalanceStoreRestore(t *testing.T) {
|
||||
b1 := &MinuteBucket{Seconds: 10, Weight: 10, Price: 0.01, DestinationId: "NAT"}
|
||||
b2 := &MinuteBucket{Seconds: 100, Weight: 20, Price: 0.0, DestinationId: "RET"}
|
||||
rifsBalance := &UserBalance{Id: "other", MinuteBuckets: []*MinuteBucket{b1, b2}, BalanceMap: map[string]float64{CREDIT: 21}}
|
||||
getter.SetUserBalance(rifsBalance)
|
||||
ub1, err := getter.GetUserBalance("other")
|
||||
storageGetter.SetUserBalance(rifsBalance)
|
||||
ub1, err := storageGetter.GetUserBalance("other")
|
||||
if err != nil || ub1.BalanceMap[CREDIT] != rifsBalance.BalanceMap[CREDIT] {
|
||||
t.Errorf("Expected %v was %v", rifsBalance.BalanceMap[CREDIT], ub1.BalanceMap[CREDIT])
|
||||
}
|
||||
@@ -72,8 +72,8 @@ func TestUserBalanceRedisStore(t *testing.T) {
|
||||
b1 := &MinuteBucket{Seconds: 10, Weight: 10, Price: 0.01, DestinationId: "NAT"}
|
||||
b2 := &MinuteBucket{Seconds: 100, Weight: 20, Price: 0.0, DestinationId: "RET"}
|
||||
rifsBalance := &UserBalance{Id: "other", MinuteBuckets: []*MinuteBucket{b1, b2}, BalanceMap: map[string]float64{CREDIT: 21}}
|
||||
getter.SetUserBalance(rifsBalance)
|
||||
result, _ := getter.GetUserBalance(rifsBalance.Id)
|
||||
storageGetter.SetUserBalance(rifsBalance)
|
||||
result, _ := storageGetter.GetUserBalance(rifsBalance.Id)
|
||||
if !reflect.DeepEqual(rifsBalance, result) {
|
||||
t.Errorf("Expected %v was %v", rifsBalance, result)
|
||||
}
|
||||
@@ -261,7 +261,7 @@ func TestDebitNegativeSMSBalance(t *testing.T) {
|
||||
b2 := &MinuteBucket{Seconds: 100, Weight: 20, Price: 0.0, DestinationId: "RET"}
|
||||
rifsBalance := &UserBalance{Id: "other", MinuteBuckets: []*MinuteBucket{b1, b2}, BalanceMap: map[string]float64{CREDIT: 21}}
|
||||
rifsBalance.MinuteBuckets[0].Seconds, rifsBalance.MinuteBuckets[1].Seconds = 0.0, 0.0
|
||||
err := rifsBalance.resetUserBalance(getter)
|
||||
err := rifsBalance.resetUserBalance(storageGetter)
|
||||
if err != nil ||
|
||||
rifsBalance.MinuteBuckets[0] == b1 ||
|
||||
rifsBalance.BalanceMap[SMS] != seara.SmsCredit {
|
||||
@@ -307,7 +307,7 @@ func TestGetVolumeDiscountSteps(t *testing.T) {
|
||||
|
||||
func TestRecivedCallsBonus(t *testing.T) {
|
||||
_ := NewKyotoStorage("../data/test.kch")
|
||||
defer getter.Close()
|
||||
defer storageGetter.Close()
|
||||
rcb := &RecivedCallBonus{Credit: 100}
|
||||
seara := &TariffPlan{Id: "seara_voo", SmsCredit: 100, ReceivedCallSecondsLimit: 10, RecivedCallBonus: rcb}
|
||||
rifsBalance := &UserBalance{Id: "other", BalanceMap: map[string]float64{CREDIT: 21}, tariffPlan: seara, ReceivedCallSeconds: 1}
|
||||
@@ -355,8 +355,8 @@ func BenchmarkUserBalanceRedisStoreRestore(b *testing.B) {
|
||||
b2 := &MinuteBucket{Seconds: 100, Weight: 20, Price: 0.0, DestinationId: "RET"}
|
||||
rifsBalance := &UserBalance{Id: "other", MinuteBuckets: []*MinuteBucket{b1, b2}, BalanceMap: map[string]float64{CREDIT: 21}}
|
||||
for i := 0; i < b.N; i++ {
|
||||
getter.SetUserBalance(rifsBalance)
|
||||
getter.GetUserBalance(rifsBalance.Id)
|
||||
storageGetter.SetUserBalance(rifsBalance)
|
||||
storageGetter.GetUserBalance(rifsBalance.Id)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user