*voice balance format change into nanoseconds from seconds, some test fixes

This commit is contained in:
DanB
2017-11-12 19:26:07 +01:00
parent 3c6a8d52b6
commit e0cdcba030
8 changed files with 71 additions and 37 deletions

View File

@@ -336,7 +336,7 @@ func (self *ApierV2) SetActions(attrs utils.AttrSetActions, reply *string) error
for idx, apiAct := range attrs.Actions {
var vf *utils.ValueFormula
if apiAct.Units != "" {
if x, err := utils.ParseBalanceFilterValue(apiAct.Units); err == nil {
if x, err := utils.ParseBalanceFilterValue(apiAct.BalanceType, apiAct.Units); err == nil {
vf = x
} else {
return err

View File

@@ -393,7 +393,6 @@ func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun boo
for _, balance := range usefulUnitBalances {
//utils.Logger.Info(fmt.Sprintf("Unit balance: %+v", balance))
//utils.Logger.Info(fmt.Sprintf("CD BEFORE UNIT: %+v", cd))
partCC, debitErr := balance.debitUnits(cd, balance.account,
usefulMoneyBalances, count, dryRun, len(cc.Timespans) == 0)
if debitErr != nil {
@@ -441,7 +440,8 @@ func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun boo
for _, balance := range usefulMoneyBalances {
//utils.Logger.Info(fmt.Sprintf("Money balance: %+v", balance))
//utils.Logger.Info(fmt.Sprintf("CD BEFORE MONEY: %+v", cd))
partCC, debitErr := balance.debitMoney(cd, balance.account, usefulMoneyBalances, count, dryRun, len(cc.Timespans) == 0)
partCC, debitErr := balance.debitMoney(cd, balance.account,
usefulMoneyBalances, count, dryRun, len(cc.Timespans) == 0)
if debitErr != nil {
return nil, debitErr
}

View File

@@ -517,7 +517,7 @@ func (b *Balance) debitUnits(cd *CallDescriptor, ub *Account, moneyBalances Bala
}
} else {
inc.paid = false
// delete the rest of the unpiad increments/timespans
// delete the rest of the unpaid increments/timespans
if incIndex == 0 {
// cut the entire current timespan
cc.Timespans = cc.Timespans[:tsIndex]

View File

@@ -265,7 +265,6 @@ func (ec *EventCost) AsCallCost() *CallCost {
ts.TimeEnd = ts.TimeStart.Add(
time.Duration(cIl.Usage().Nanoseconds() * int64(cIl.CompressFactor)))
if cIl.RatingID != "" {
//fmt.Printf("Checking RatingID: <%s>\n", cIl.RatingID)
if ec.Rating[cIl.RatingID].RatingFiltersID != "" {
rfs := ec.RatingFilters[ec.Rating[cIl.RatingID].RatingFiltersID]
ts.MatchedSubject = rfs["Subject"].(string)

View File

@@ -594,7 +594,7 @@ func (tpr *TpReader) LoadActions() (err error) {
}
if tpact.Units != "" && tpact.Units != utils.ANY {
vf, err := utils.ParseBalanceFilterValue(tpact.Units)
vf, err := utils.ParseBalanceFilterValue(tpact.BalanceType, tpact.Units)
if err != nil {
return err
}
@@ -1056,7 +1056,7 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *utils.TPAccountActions)
}
if tpact.Units != "" && tpact.Units != utils.ANY {
vf, err := utils.ParseBalanceFilterValue(tpact.Units)
vf, err := utils.ParseBalanceFilterValue(tpact.BalanceType, tpact.Units)
if err != nil {
return err
}
@@ -1399,7 +1399,7 @@ func (tpr *TpReader) LoadCdrStatsFiltered(tag string, save bool) (err error) {
}
if tpact.Units != "" && tpact.Units != utils.ANY {
vf, err := utils.ParseBalanceFilterValue(tpact.Units)
vf, err := utils.ParseBalanceFilterValue(tpact.BalanceType, tpact.Units)
if err != nil {
return err
}

View File

@@ -29,13 +29,13 @@ import (
var dataDB *engine.DataManager
func TestSetStorage(t *testing.T) {
func TestDZ1SetStorage(t *testing.T) {
data, _ := engine.NewMapStorageJson()
dataDB = engine.NewDataManager(data)
engine.SetDataStorage(dataDB)
}
func TestLoadCsvTp(t *testing.T) {
func TestDZ1LoadCsvTp(t *testing.T) {
timings := `ALWAYS,*any,*any,*any,*any,00:00:00
ASAP,*any,*any,*any,*any,*asap`
destinations := `DST_UK_Mobile_BIG5,447596
@@ -51,7 +51,7 @@ RP_UK,DR_UK_Mobile_BIG5,ALWAYS,10`
sharedGroups := ``
lcrs := ``
actions := `TOPUP10_AC,*topup_reset,,,,*monetary,*out,,*any,,,*unlimited,,10,10,false,false,10
TOPUP10_AC1,*topup_reset,,,,*voice,*out,,DST_UK_Mobile_BIG5,discounted_minutes,,*unlimited,,40,10,false,false,10`
TOPUP10_AC1,*topup_reset,,,,*voice,*out,,DST_UK_Mobile_BIG5,discounted_minutes,,*unlimited,,40000000000,10,false,false,10`
actionPlans := `TOPUP10_AT,TOPUP10_AC,ASAP,10
TOPUP10_AT,TOPUP10_AC1,ASAP,10`
actionTriggers := ``
@@ -64,8 +64,12 @@ TOPUP10_AT,TOPUP10_AC1,ASAP,10`
stats := ``
thresholds := ``
filters := ``
csvr := engine.NewTpReader(dataDB.DataDB(), engine.NewStringCSVStorage(',', destinations, timings, rates, destinationRates, ratingPlans, ratingProfiles,
sharedGroups, lcrs, actions, actionPlans, actionTriggers, accountActions, derivedCharges, cdrStats, users, aliases, resLimits, stats, thresholds, filters), "", "")
csvr := engine.NewTpReader(dataDB.DataDB(),
engine.NewStringCSVStorage(',', destinations, timings, rates,
destinationRates, ratingPlans, ratingProfiles,
sharedGroups, lcrs, actions, actionPlans, actionTriggers,
accountActions, derivedCharges, cdrStats, users, aliases,
resLimits, stats, thresholds, filters), "", "")
if err := csvr.LoadDestinations(); err != nil {
t.Fatal(err)
}
@@ -112,37 +116,41 @@ TOPUP10_AT,TOPUP10_AC1,ASAP,10`
t.Error("No account saved")
}
cache.Flush()
dataDB.LoadDataDBCache(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
/*
dataDB.LoadDataDBCache(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
if cachedDests := cache.CountEntries(utils.DESTINATION_PREFIX); cachedDests != 0 {
t.Error("Wrong number of cached destinations found", cachedDests)
}
if cachedRPlans := cache.CountEntries(utils.RATING_PLAN_PREFIX); cachedRPlans != 2 {
t.Error("Wrong number of cached rating plans found", cachedRPlans)
}
if cachedRProfiles := cache.CountEntries(utils.RATING_PROFILE_PREFIX); cachedRProfiles != 0 {
t.Error("Wrong number of cached rating profiles found", cachedRProfiles)
}
if cachedActions := cache.CountEntries(utils.ACTION_PREFIX); cachedActions != 0 {
t.Error("Wrong number of cached actions found", cachedActions)
}
if cachedDests := cache.CountEntries(utils.DESTINATION_PREFIX); cachedDests != 0 {
t.Error("Wrong number of cached destinations found", cachedDests)
}
if cachedRPlans := cache.CountEntries(utils.RATING_PLAN_PREFIX); cachedRPlans != 2 {
t.Error("Wrong number of cached rating plans found", cachedRPlans)
}
if cachedRProfiles := cache.CountEntries(utils.RATING_PROFILE_PREFIX); cachedRProfiles != 0 {
t.Error("Wrong number of cached rating profiles found", cachedRProfiles)
}
if cachedActions := cache.CountEntries(utils.ACTION_PREFIX); cachedActions != 0 {
t.Error("Wrong number of cached actions found", cachedActions)
}
*/
}
func TestExecuteActions(t *testing.T) {
func TestDZ1ExecuteActions(t *testing.T) {
scheduler.NewScheduler(dataDB).Reload()
time.Sleep(10 * time.Millisecond) // Give time to scheduler to topup the account
if acnt, err := dataDB.DataDB().GetAccount("cgrates.org:12344"); err != nil {
t.Error(err)
} else if len(acnt.BalanceMap) != 2 {
t.Error("Account does not have enough balances: ", acnt.BalanceMap)
} else if acnt.BalanceMap[utils.VOICE][0].Value != 40 {
t.Error("Account does not have enough minutes in balance", acnt.BalanceMap[utils.VOICE][0].Value)
} else if acnt.BalanceMap[utils.VOICE][0].Value != 40000000000 {
t.Error("Account does not have enough minutes in balance",
acnt.BalanceMap[utils.VOICE][0].Value)
} else if acnt.BalanceMap[utils.MONETARY][0].Value != 10 {
t.Error("Account does not have enough monetary balance", acnt.BalanceMap[utils.MONETARY][0].Value)
t.Error("Account does not have enough monetary balance",
acnt.BalanceMap[utils.MONETARY][0].Value)
}
}
func TestDebit(t *testing.T) {
func TestDZ1Debit(t *testing.T) {
cd := &engine.CallDescriptor{
Direction: "*out",
Category: "call",
@@ -162,10 +170,12 @@ func TestDebit(t *testing.T) {
if err != nil {
t.Error(err)
}
if acnt.BalanceMap[utils.VOICE][0].Value != 20 {
t.Error("Account does not have expected minutes in balance", acnt.BalanceMap[utils.VOICE][0].Value)
if acnt.BalanceMap[utils.VOICE][0].Value != 20000000000 {
t.Error("Account does not have expected *voice units in balance",
acnt.BalanceMap[utils.VOICE][0].Value)
}
if acnt.BalanceMap[utils.MONETARY][0].Value != 9.99 {
t.Error("Account does not have expected monetary balance", acnt.BalanceMap[utils.MONETARY][0].Value)
t.Error("Account does not have expected *monetary units in balance",
acnt.BalanceMap[utils.MONETARY][0].Value)
}
}

View File

@@ -33,9 +33,12 @@ type ValueFormula struct {
Static float64
}
func ParseBalanceFilterValue(val string) (*ValueFormula, error) {
u, err := strconv.ParseFloat(val, 64)
if err == nil {
func ParseBalanceFilterValue(tor string, val string) (*ValueFormula, error) {
if tor == VOICE { // VOICE balance is parsed as nanoseconds with support for time duration strings
if d, err := ParseDurationWithNanosecs(val); err == nil {
return &ValueFormula{Static: float64(d.Nanoseconds())}, err
}
} else if u, err := strconv.ParseFloat(val, 64); err == nil {
return &ValueFormula{Static: u}, err
}
var vf ValueFormula

View File

@@ -19,6 +19,7 @@ package utils
import (
"encoding/json"
"reflect"
"testing"
"time"
)
@@ -54,3 +55,24 @@ func TestValueFormulaDayYear(t *testing.T) {
t.Error("error caclulating value using formula: ", x)
}
}
func TestValueFormulaParseBalanceFilterValue(t *testing.T) {
eVF := &ValueFormula{Static: 10000000000.0}
if vf, err := ParseBalanceFilterValue(VOICE, "10s"); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eVF, vf) {
t.Errorf("Expecting: %+v, received: %+v", eVF, vf)
}
eVF = &ValueFormula{Static: 1024.0}
if vf, err := ParseBalanceFilterValue(DATA, "1024"); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eVF, vf) {
t.Errorf("Expecting: %+v, received: %+v", eVF, vf)
}
eVF = &ValueFormula{Static: 10.0}
if vf, err := ParseBalanceFilterValue(MONETARY, "10"); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eVF, vf) {
t.Errorf("Expecting: %+v, received: %+v", eVF, vf)
}
}