diff --git a/engine/action_timing.go b/engine/action_timing.go
index 552432e7f..3892399c6 100644
--- a/engine/action_timing.go
+++ b/engine/action_timing.go
@@ -241,11 +241,6 @@ func (at *ActionTiming) Execute() (err error) {
} else if ub.Disabled {
return 0, fmt.Errorf("User %s is disabled", ubId)
}
- if err != nil {
- Logger.Warning(fmt.Sprintf("Could not get user balances for this id: %s. Skipping!", ubId))
- return 0, err
- }
-
Logger.Info(fmt.Sprintf("Executing %v on %v", a.ActionType, ub.Id))
err = actionFunction(ub, a)
accountingStorage.SetAccount(ub)
diff --git a/general_tests/ddazmbl1_test.go b/general_tests/ddazmbl1_test.go
index 9622c96a0..fb2824f3e 100644
--- a/general_tests/ddazmbl1_test.go
+++ b/general_tests/ddazmbl1_test.go
@@ -30,7 +30,7 @@ import (
var ratingDb engine.RatingStorage
var acntDb engine.AccountingStorage
-func init() {
+func TestSetStorage(t *testing.T) {
ratingDb, _ = engine.NewMapStorageJson()
engine.SetRatingStorage(ratingDb)
acntDb, _ = engine.NewMapStorageJson()
@@ -115,7 +115,7 @@ TOPUP10_AT,TOPUP10_AC1,ASAP,10`
func TestExecuteActions(t *testing.T) {
scheduler.NewScheduler().LoadActionTimings(acntDb)
- time.Sleep(time.Duration(10000) * time.Microsecond) // Give time to scheduler to topup the account
+ time.Sleep(time.Duration(10) * time.Millisecond) // Give time to scheduler to topup the account
if acnt, err := acntDb.GetAccount("*out:cgrates.org:12345"); err != nil {
t.Error(err)
} else if len(acnt.BalanceMap) != 2 {
diff --git a/general_tests/ddazmbl2_test.go b/general_tests/ddazmbl2_test.go
new file mode 100644
index 000000000..46c7caefe
--- /dev/null
+++ b/general_tests/ddazmbl2_test.go
@@ -0,0 +1,159 @@
+/*
+Rating system designed to be used in VoIP Carriers World
+Copyright (C) 2012-2014 ITsysCOM GmbH
+
+This program is free software: you can Storagetribute 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 WITH*out 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
+*/
+
+package general_tests
+
+import (
+ "testing"
+ "time"
+
+ "github.com/cgrates/cgrates/cache2go"
+ "github.com/cgrates/cgrates/engine"
+ "github.com/cgrates/cgrates/scheduler"
+)
+
+var ratingDb2 engine.RatingStorage
+var acntDb2 engine.AccountingStorage
+
+func TestSetStorage2(t *testing.T) {
+ ratingDb2, _ = engine.NewMapStorageJson()
+ engine.SetRatingStorage(ratingDb2)
+ acntDb2, _ = engine.NewMapStorageJson()
+ engine.SetAccountingStorage(acntDb2)
+}
+
+func TestLoadCsvTp2(t *testing.T) {
+ timings := `ALWAYS,*any,*any,*any,*any,00:00:00
+ASAP,*any,*any,*any,*any,*asap`
+ destinations := `DST_UK_Mobile_BIG5,447596
+DST_UK_Mobile_BIG5,447956`
+ rates := `RT_UK_Mobile_BIG5_PKG,0.01,0,20s,20s,0s,*up,8
+RT_UK_Mobile_BIG5,0.01,0.10,1s,1s,0s,*up,8`
+ destinationRates := `DR_UK_Mobile_BIG5_PKG,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5_PKG
+DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5`
+ ratingPlans := `RP_UK_Mobile_BIG5_PKG,DR_UK_Mobile_BIG5_PKG,ALWAYS,10
+RP_UK,DR_UK_Mobile_BIG5,ALWAYS,10`
+ ratingProfiles := `cgrates.org,call,*out,*any,2013-01-06T00:00:00Z,RP_UK,
+cgrates.org,call,*out,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_PKG,`
+ sharedGroups := ``
+ actions := `TOPUP10_AC,*topup_reset,*monetary,*out,0,*unlimited,*any,,10,,,10
+TOPUP10_AC1,*topup_reset,*minutes,*out,40,*unlimited,DST_UK_Mobile_BIG5,discounted_minutes,10,,,10`
+ actionPlans := `TOPUP10_AT,TOPUP10_AC,ASAP,10
+TOPUP10_AT,TOPUP10_AC1,ASAP,10`
+ actionTriggers := ``
+ accountActions := `cgrates.org,12345,*out,TOPUP10_AT,`
+ csvr := engine.NewStringCSVReader(ratingDb2, acntDb2, ',', destinations, timings, rates, destinationRates, ratingPlans, ratingProfiles, sharedGroups, actions, actionPlans, actionTriggers, accountActions)
+ if err := csvr.LoadDestinations(); err != nil {
+ t.Fatal(err)
+ }
+ if err := csvr.LoadTimings(); err != nil {
+ t.Fatal(err)
+ }
+ if err := csvr.LoadRates(); err != nil {
+ t.Fatal(err)
+ }
+ if err := csvr.LoadDestinationRates(); err != nil {
+ t.Fatal(err)
+ }
+ if err := csvr.LoadRatingPlans(); err != nil {
+ t.Fatal(err)
+ }
+ if err := csvr.LoadRatingProfiles(); err != nil {
+ t.Fatal(err)
+ }
+ if err := csvr.LoadSharedGroups(); err != nil {
+ t.Fatal(err)
+ }
+ if err := csvr.LoadActions(); err != nil {
+ t.Fatal(err)
+ }
+ if err := csvr.LoadActionTimings(); err != nil {
+ t.Fatal(err)
+ }
+ if err := csvr.LoadActionTriggers(); err != nil {
+ t.Fatal(err)
+ }
+ if err := csvr.LoadAccountActions(); err != nil {
+ t.Fatal(err)
+ }
+ csvr.WriteToDatabase(false, false)
+ if acnt, err := acntDb2.GetAccount("*out:cgrates.org:12345"); err != nil {
+ t.Error(err)
+ } else if acnt == nil {
+ t.Error("No account saved")
+ }
+ ratingDb2.CacheRating(nil, nil, nil, nil)
+ acntDb2.CacheAccounting(nil, nil, nil)
+ if cachedDests := cache2go.CountEntries(engine.DESTINATION_PREFIX); cachedDests != 2 {
+ t.Error("Wrong number of cached destinations found", cachedDests)
+ }
+ if cachedRPlans := cache2go.CountEntries(engine.RATING_PLAN_PREFIX); cachedRPlans != 2 {
+ t.Error("Wrong number of cached rating plans found", cachedRPlans)
+ }
+ if cachedRProfiles := cache2go.CountEntries(engine.RATING_PROFILE_PREFIX); cachedRProfiles != 2 {
+ t.Error("Wrong number of cached rating profiles found", cachedRProfiles)
+ }
+ if cachedActions := cache2go.CountEntries(engine.ACTION_PREFIX); cachedActions != 2 {
+ t.Error("Wrong number of cached actions found", cachedActions)
+ }
+}
+
+func TestExecuteActions2(t *testing.T) {
+ scheduler.NewScheduler().LoadActionTimings(acntDb2)
+ time.Sleep(time.Duration(10) * time.Millisecond) // Give time to scheduler to topup the account
+ if acnt, err := acntDb2.GetAccount("*out:cgrates.org:12345"); 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[engine.MINUTES+engine.OUTBOUND][0].Value != 40 {
+ t.Errorf("Account does not have enough minutes in balance", acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value)
+ } else if acnt.BalanceMap[engine.CREDIT+engine.OUTBOUND][0].Value != 0 {
+ t.Error("Account does not have enough monetary balance", acnt.BalanceMap[engine.CREDIT+engine.OUTBOUND][0].Value)
+ }
+}
+
+func TestDebit2(t *testing.T) {
+ cd := &engine.CallDescriptor{
+ Direction: "*out",
+ TOR: "call",
+ Tenant: "cgrates.org",
+ Subject: "12345",
+ Account: "12345",
+ Destination: "447956933443",
+ TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC),
+ TimeEnd: time.Date(2014, 3, 4, 6, 0, 10, 0, time.UTC),
+ }
+ if cc, err := cd.Debit(); err != nil {
+ t.Error(err)
+ } else if cc.Cost != 0.01 {
+ t.Error("Wrong cost returned: ", cc.Cost)
+ }
+ acnt, err := acntDb2.GetAccount("*out:cgrates.org:12345")
+ if err != nil {
+ t.Error(err)
+ }
+ if len(acnt.BalanceMap) != 2 {
+ t.Error("Wrong number of user balances found", acnt.BalanceMap)
+ }
+ if acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value != 20 {
+ t.Error("Account does not have expected minutes in balance", acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value)
+ }
+ if acnt.BalanceMap[engine.CREDIT+engine.OUTBOUND][0].Value != -0.01 {
+ t.Error("Account does not have expected monetary balance", acnt.BalanceMap[engine.CREDIT+engine.OUTBOUND][0].Value)
+ }
+}
diff --git a/general_tests/ddazmbl3_test.go b/general_tests/ddazmbl3_test.go
new file mode 100644
index 000000000..b2c435a3c
--- /dev/null
+++ b/general_tests/ddazmbl3_test.go
@@ -0,0 +1,155 @@
+/*
+Rating system designed to be used in VoIP Carriers World
+Copyright (C) 2012-2014 ITsysCOM GmbH
+
+This program is free software: you can Storagetribute 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 WITH*out 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
+*/
+
+package general_tests
+
+import (
+ "testing"
+ "time"
+
+ "github.com/cgrates/cgrates/cache2go"
+ "github.com/cgrates/cgrates/engine"
+ "github.com/cgrates/cgrates/scheduler"
+)
+
+var ratingDb3 engine.RatingStorage
+var acntDb3 engine.AccountingStorage
+
+func TestSetStorage3(t *testing.T) {
+ ratingDb3, _ = engine.NewMapStorageJson()
+ engine.SetRatingStorage(ratingDb3)
+ acntDb3, _ = engine.NewMapStorageJson()
+ engine.SetAccountingStorage(acntDb3)
+}
+
+func TestLoadCsvTp3(t *testing.T) {
+ timings := `ALWAYS,*any,*any,*any,*any,00:00:00
+ASAP,*any,*any,*any,*any,*asap`
+ destinations := `DST_UK_Mobile_BIG5,447596
+DST_UK_Mobile_BIG5,447956`
+ rates := `RT_UK_Mobile_BIG5_PKG,0.01,0,20s,20s,0s,*up,8
+RT_UK_Mobile_BIG5,0.01,0.10,1s,1s,0s,*up,8`
+ destinationRates := `DR_UK_Mobile_BIG5_PKG,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5_PKG
+DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5`
+ ratingPlans := `RP_UK_Mobile_BIG5_PKG,DR_UK_Mobile_BIG5_PKG,ALWAYS,10
+RP_UK,DR_UK_Mobile_BIG5,ALWAYS,10`
+ ratingProfiles := `cgrates.org,call,*out,*any,2013-01-06T00:00:00Z,RP_UK,
+cgrates.org,call,*out,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_PKG,`
+ sharedGroups := ``
+ actions := `TOPUP10_AC1,*topup_reset,*minutes,*out,40,*unlimited,DST_UK_Mobile_BIG5,discounted_minutes,10,,,10`
+ actionPlans := `TOPUP10_AT,TOPUP10_AC1,ASAP,10`
+ actionTriggers := ``
+ accountActions := `cgrates.org,12345,*out,TOPUP10_AT,`
+ csvr := engine.NewStringCSVReader(ratingDb3, acntDb3, ',', destinations, timings, rates, destinationRates, ratingPlans, ratingProfiles, sharedGroups, actions, actionPlans, actionTriggers, accountActions)
+ if err := csvr.LoadDestinations(); err != nil {
+ t.Fatal(err)
+ }
+ if err := csvr.LoadTimings(); err != nil {
+ t.Fatal(err)
+ }
+ if err := csvr.LoadRates(); err != nil {
+ t.Fatal(err)
+ }
+ if err := csvr.LoadDestinationRates(); err != nil {
+ t.Fatal(err)
+ }
+ if err := csvr.LoadRatingPlans(); err != nil {
+ t.Fatal(err)
+ }
+ if err := csvr.LoadRatingProfiles(); err != nil {
+ t.Fatal(err)
+ }
+ if err := csvr.LoadSharedGroups(); err != nil {
+ t.Fatal(err)
+ }
+ if err := csvr.LoadActions(); err != nil {
+ t.Fatal(err)
+ }
+ if err := csvr.LoadActionTimings(); err != nil {
+ t.Fatal(err)
+ }
+ if err := csvr.LoadActionTriggers(); err != nil {
+ t.Fatal(err)
+ }
+ if err := csvr.LoadAccountActions(); err != nil {
+ t.Fatal(err)
+ }
+ csvr.WriteToDatabase(false, false)
+ if acnt, err := acntDb3.GetAccount("*out:cgrates.org:12345"); err != nil {
+ t.Error(err)
+ } else if acnt == nil {
+ t.Error("No account saved")
+ }
+ ratingDb3.CacheRating(nil, nil, nil, nil)
+ acntDb3.CacheAccounting(nil, nil, nil)
+ if cachedDests := cache2go.CountEntries(engine.DESTINATION_PREFIX); cachedDests != 2 {
+ t.Error("Wrong number of cached destinations found", cachedDests)
+ }
+ if cachedRPlans := cache2go.CountEntries(engine.RATING_PLAN_PREFIX); cachedRPlans != 2 {
+ t.Error("Wrong number of cached rating plans found", cachedRPlans)
+ }
+ if cachedRProfiles := cache2go.CountEntries(engine.RATING_PROFILE_PREFIX); cachedRProfiles != 2 {
+ t.Error("Wrong number of cached rating profiles found", cachedRProfiles)
+ }
+ if cachedActions := cache2go.CountEntries(engine.ACTION_PREFIX); cachedActions != 1 {
+ t.Error("Wrong number of cached actions found", cachedActions)
+ }
+}
+
+func TestExecuteActions3(t *testing.T) {
+ scheduler.NewScheduler().LoadActionTimings(acntDb3)
+ time.Sleep(time.Duration(10) * time.Millisecond) // Give time to scheduler to topup the account
+ if acnt, err := acntDb3.GetAccount("*out:cgrates.org:12345"); err != nil {
+ t.Error(err)
+ } else if len(acnt.BalanceMap) != 1 {
+ t.Error("Account does not have enough balances: ", acnt.BalanceMap)
+ } else if acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value != 40 {
+ t.Errorf("Account does not have enough minutes in balance", acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value)
+ }
+}
+
+func TestDebit3(t *testing.T) {
+ cd := &engine.CallDescriptor{
+ Direction: "*out",
+ TOR: "call",
+ Tenant: "cgrates.org",
+ Subject: "12345",
+ Account: "12345",
+ Destination: "447956933443",
+ TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC),
+ TimeEnd: time.Date(2014, 3, 4, 6, 0, 10, 0, time.UTC),
+ }
+ if cc, err := cd.Debit(); err != nil {
+ t.Error(err)
+ } else if cc.Cost != 0.01 {
+ t.Error("Wrong cost returned: ", cc.Cost)
+ }
+ acnt, err := acntDb3.GetAccount("*out:cgrates.org:12345")
+ if err != nil {
+ t.Error(err)
+ }
+ if len(acnt.BalanceMap) != 2 {
+ t.Error("Wrong number of user balances found", acnt.BalanceMap)
+ }
+ if acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value != 20 {
+ t.Error("Account does not have expected minutes in balance", acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value)
+ }
+ if acnt.BalanceMap[engine.CREDIT+engine.OUTBOUND][0].Value != -0.01 {
+ t.Error("Account does not have expected monetary balance", acnt.BalanceMap[engine.CREDIT+engine.OUTBOUND][0].Value)
+ }
+}