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) + } +}