diff --git a/engine/account_test.go b/engine/account_test.go index eda9563e2..a97e04c98 100644 --- a/engine/account_test.go +++ b/engine/account_test.go @@ -31,7 +31,8 @@ var ( ) func TestBalanceStoreRestore(t *testing.T) { - b := &Balance{Value: 14, Weight: 1, Uuid: "test", ExpirationDate: time.Date(2013, time.July, 15, 17, 48, 0, 0, time.UTC)} + b := &Balance{Value: 14, Weight: 1, Uuid: "test", + ExpirationDate: time.Date(2013, time.July, 15, 17, 48, 0, 0, time.UTC)} marsh := NewCodecMsgpackMarshaler() output, err := marsh.Marshal(b) if err != nil { @@ -154,7 +155,10 @@ func TestAccountStorageStore(t *testing.T) { } b1 := &Balance{Value: 10, Weight: 10, DestinationIDs: utils.StringMap{"NAT": true}} b2 := &Balance{Value: 100, Weight: 20, DestinationIDs: utils.StringMap{"RET": true}} - rifsBalance := &Account{ID: "other", BalanceMap: map[string]Balances{utils.VOICE: Balances{b1, b2}, utils.MONETARY: Balances{&Balance{Value: 21}}}} + rifsBalance := &Account{ID: "other", + BalanceMap: map[string]Balances{ + utils.VOICE: Balances{b1, b2}, + utils.MONETARY: Balances{&Balance{Value: 21}}}} dm.DataDB().SetAccount(rifsBalance) result, err := dm.DataDB().GetAccount(rifsBalance.ID) if err != nil || rifsBalance.ID != result.ID || @@ -167,7 +171,10 @@ func TestAccountStorageStore(t *testing.T) { } func TestDebitCreditZeroSecond(t *testing.T) { - b1 := &Balance{Uuid: "testb", Value: 10, Weight: 10, DestinationIDs: utils.StringMap{"NAT": true}, RatingSubject: "*zero1s"} + b1 := &Balance{ + Uuid: "testb", Value: 10 * float64(time.Second), Weight: 10, + DestinationIDs: utils.StringMap{"NAT": true}, + RatingSubject: "*zero1s"} cc := &CallCost{ Direction: utils.OUT, Destination: "0723045326", @@ -289,7 +296,9 @@ func TestDebitFreeEmpty(t *testing.T) { } func TestDebitCreditZeroMinute(t *testing.T) { - b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationIDs: utils.StringMap{"NAT": true}, RatingSubject: "*zero1m"} + b1 := &Balance{Uuid: "testb", Value: 70 * float64(time.Second), + Weight: 10, DestinationIDs: utils.StringMap{"NAT": true}, + RatingSubject: "*zero1m"} cc := &CallCost{ Direction: utils.OUT, Destination: "0723045326", @@ -298,7 +307,11 @@ func TestDebitCreditZeroMinute(t *testing.T) { TimeStart: time.Date(2013, 9, 24, 10, 48, 0, 0, time.UTC), TimeEnd: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), DurationIndex: 0, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + RateInterval: &RateInterval{ + Rating: &RIRate{Rates: RateGroups{ + &Rate{GroupIntervalStart: 0, Value: 100, + RateIncrement: 10 * time.Second, + RateUnit: time.Second}}}}, }, }, TOR: utils.VOICE, @@ -312,10 +325,12 @@ func TestDebitCreditZeroMinute(t *testing.T) { TOR: utils.VOICE, testCallcost: cc, } - rifsBalance := &Account{ID: "other", BalanceMap: map[string]Balances{ - utils.VOICE: Balances{b1}, - utils.MONETARY: Balances{&Balance{Value: 21}}, - }} + rifsBalance := &Account{ + ID: "other", + BalanceMap: map[string]Balances{ + utils.VOICE: Balances{b1}, + utils.MONETARY: Balances{&Balance{Value: 21}}, + }} var err error cc, err = rifsBalance.debitCreditBalance(cd, false, false, true) if err != nil { @@ -324,18 +339,23 @@ func TestDebitCreditZeroMinute(t *testing.T) { //t.Logf("%+v", cc.Timespans) if cc.Timespans[0].Increments[0].BalanceInfo.Unit.UUID != "testb" || cc.Timespans[0].Increments[0].Duration != time.Minute { - t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0]) + t.Errorf("Error setting balance id to increment: %s", + utils.ToJSON(cc)) } - if rifsBalance.BalanceMap[utils.VOICE][0].GetValue() != 10 || + if rifsBalance.BalanceMap[utils.VOICE][0].GetValue() != 10*float64(time.Second) || rifsBalance.BalanceMap[utils.MONETARY][0].GetValue() != 21 { - t.Error("Error extracting minutes from balance: ", - rifsBalance.BalanceMap[utils.VOICE][0]) + t.Errorf("Error extracting minutes from balance: %s", + utils.ToJSON(rifsBalance.BalanceMap[utils.VOICE][0])) } } func TestDebitCreditZeroMixedMinute(t *testing.T) { - b1 := &Balance{Uuid: "testm", Value: 70, Weight: 5, DestinationIDs: utils.StringMap{"NAT": true}, RatingSubject: "*zero1m"} - b2 := &Balance{Uuid: "tests", Value: 10, Weight: 10, DestinationIDs: utils.StringMap{"NAT": true}, RatingSubject: "*zero1s"} + b1 := &Balance{ + Uuid: "testm", Value: 70 * float64(time.Second), + DestinationIDs: utils.StringMap{"NAT": true}, + RatingSubject: "*zero1m", Weight: 5} + b2 := &Balance{Uuid: "tests", Value: 10 * float64(time.Second), Weight: 10, + DestinationIDs: utils.StringMap{"NAT": true}, RatingSubject: "*zero1s"} cc := &CallCost{ Direction: utils.OUT, Destination: "0723045326", @@ -373,7 +393,7 @@ func TestDebitCreditZeroMixedMinute(t *testing.T) { t.Error("Error setting balance id to increment: ", cc.Timespans) } if rifsBalance.BalanceMap[utils.VOICE][1].GetValue() != 0 || - rifsBalance.BalanceMap[utils.VOICE][0].GetValue() != 10 || + rifsBalance.BalanceMap[utils.VOICE][0].GetValue() != 10*float64(time.Second) || rifsBalance.BalanceMap[utils.MONETARY][0].GetValue() != 21 { t.Logf("TS0: %+v", cc.Timespans[0]) t.Logf("TS1: %+v", cc.Timespans[1]) @@ -382,7 +402,9 @@ func TestDebitCreditZeroMixedMinute(t *testing.T) { } func TestDebitCreditNoCredit(t *testing.T) { - b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationIDs: utils.StringMap{"NAT": true}, RatingSubject: "*zero1m"} + b1 := &Balance{Uuid: "testb", Value: 70 * float64(time.Second), + DestinationIDs: utils.StringMap{"NAT": true}, + RatingSubject: "*zero1m", Weight: 10} cc := &CallCost{ Direction: utils.OUT, Destination: "0723045326", @@ -391,13 +413,23 @@ func TestDebitCreditNoCredit(t *testing.T) { TimeStart: time.Date(2013, 9, 24, 10, 48, 0, 0, time.UTC), TimeEnd: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), DurationIndex: 0, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + RateInterval: &RateInterval{ + Rating: &RIRate{ + Rates: RateGroups{ + &Rate{GroupIntervalStart: 0, Value: 100, + RateIncrement: 10 * time.Second, + RateUnit: time.Second}}}}, }, &TimeSpan{ TimeStart: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), TimeEnd: time.Date(2013, 9, 24, 10, 49, 20, 0, time.UTC), DurationIndex: 10 * time.Second, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + RateInterval: &RateInterval{ + Rating: &RIRate{ + Rates: RateGroups{ + &Rate{GroupIntervalStart: 0, Value: 100, + RateIncrement: 10 * time.Second, + RateUnit: time.Second}}}}, }, }, TOR: utils.VOICE, @@ -411,9 +443,10 @@ func TestDebitCreditNoCredit(t *testing.T) { DurationIndex: cc.GetDuration(), testCallcost: cc, } - rifsBalance := &Account{ID: "other", BalanceMap: map[string]Balances{ - utils.VOICE: Balances{b1}, - }} + rifsBalance := &Account{ID: "other", + BalanceMap: map[string]Balances{ + utils.VOICE: Balances{b1}, + }} var err error cc, err = rifsBalance.debitCreditBalance(cd, false, false, true) if err == nil { @@ -423,7 +456,7 @@ func TestDebitCreditNoCredit(t *testing.T) { cc.Timespans[0].Increments[0].Duration != time.Minute { t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0]) } - if rifsBalance.BalanceMap[utils.VOICE][0].GetValue() != 10 { + if rifsBalance.BalanceMap[utils.VOICE][0].GetValue() != 10*float64(time.Second) { t.Error("Error extracting minutes from balance: ", rifsBalance.BalanceMap[utils.VOICE][0]) } @@ -433,7 +466,9 @@ func TestDebitCreditNoCredit(t *testing.T) { } func TestDebitCreditHasCredit(t *testing.T) { - b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationIDs: utils.StringMap{"NAT": true}, RatingSubject: "*zero1m"} + b1 := &Balance{Uuid: "testb", Value: 70 * float64(time.Second), + DestinationIDs: utils.StringMap{"NAT": true}, + Weight: 10, RatingSubject: "*zero1m"} cc := &CallCost{ Direction: utils.OUT, Destination: "0723045326", @@ -475,10 +510,11 @@ func TestDebitCreditHasCredit(t *testing.T) { cc.Timespans[0].Increments[0].Duration != time.Minute { t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0]) } - if rifsBalance.BalanceMap[utils.VOICE][0].GetValue() != 10 || + if rifsBalance.BalanceMap[utils.VOICE][0].GetValue() != 10*float64(time.Second) || rifsBalance.BalanceMap[utils.MONETARY][0].GetValue() != 30 { t.Errorf("Error extracting minutes from balance: %+v, %+v", - rifsBalance.BalanceMap[utils.VOICE][0].GetValue(), rifsBalance.BalanceMap[utils.MONETARY][0].GetValue()) + rifsBalance.BalanceMap[utils.VOICE][0].GetValue(), + rifsBalance.BalanceMap[utils.MONETARY][0].GetValue()) } if len(cc.Timespans) != 3 || cc.Timespans[0].GetDuration() != time.Minute { t.Error("Error truncating extra timespans: ", cc.Timespans) @@ -486,7 +522,9 @@ func TestDebitCreditHasCredit(t *testing.T) { } func TestDebitCreditSplitMinutesMoney(t *testing.T) { - b1 := &Balance{Uuid: "testb", Value: 10, Weight: 10, DestinationIDs: utils.StringMap{"NAT": true}, RatingSubject: "*zero1s"} + b1 := &Balance{Uuid: "testb", Value: 10 * float64(time.Second), + DestinationIDs: utils.StringMap{"NAT": true}, + Weight: 10, RatingSubject: "*zero1s"} cc := &CallCost{ Direction: utils.OUT, Destination: "0723045326", @@ -496,7 +534,12 @@ func TestDebitCreditSplitMinutesMoney(t *testing.T) { TimeEnd: time.Date(2013, 9, 24, 10, 48, 20, 0, time.UTC), DurationIndex: 0, ratingInfo: &RatingInfo{}, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + RateInterval: &RateInterval{ + Rating: &RIRate{ + Rates: RateGroups{ + &Rate{GroupIntervalStart: 0, Value: 1, + RateIncrement: 10 * time.Second, + RateUnit: time.Second}}}}, }, }, TOR: utils.VOICE, @@ -534,7 +577,9 @@ func TestDebitCreditSplitMinutesMoney(t *testing.T) { } func TestDebitCreditMoreTimespans(t *testing.T) { - b1 := &Balance{Uuid: "testb", Value: 150, Weight: 10, DestinationIDs: utils.StringMap{"NAT": true}, RatingSubject: "*zero1m"} + b1 := &Balance{Uuid: "testb", Value: 150 * float64(time.Second), + DestinationIDs: utils.StringMap{"NAT": true}, + Weight: 10, RatingSubject: "*zero1m"} cc := &CallCost{ Direction: utils.OUT, Destination: "0723045326", @@ -543,13 +588,22 @@ func TestDebitCreditMoreTimespans(t *testing.T) { TimeStart: time.Date(2013, 9, 24, 10, 48, 0, 0, time.UTC), TimeEnd: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), DurationIndex: 0, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + RateInterval: &RateInterval{ + Rating: &RIRate{ + Rates: RateGroups{ + &Rate{GroupIntervalStart: 0, Value: 100, + RateIncrement: 10 * time.Second, + RateUnit: time.Second}}}}, }, &TimeSpan{ TimeStart: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), TimeEnd: time.Date(2013, 9, 24, 10, 49, 20, 0, time.UTC), DurationIndex: 10 * time.Second, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + RateInterval: &RateInterval{ + Rating: &RIRate{Rates: RateGroups{ + &Rate{GroupIntervalStart: 0, Value: 100, + RateIncrement: 10 * time.Second, + RateUnit: time.Second}}}}, }, }, TOR: utils.VOICE, @@ -575,15 +629,19 @@ func TestDebitCreditMoreTimespans(t *testing.T) { cc.Timespans[0].Increments[0].Duration != time.Minute { t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0]) } - if rifsBalance.BalanceMap[utils.VOICE][0].GetValue() != 30 { + if rifsBalance.BalanceMap[utils.VOICE][0].GetValue() != 30*float64(time.Second) { t.Error("Error extracting minutes from balance: ", rifsBalance.BalanceMap[utils.VOICE][0]) } } func TestDebitCreditMoreTimespansMixed(t *testing.T) { - b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationIDs: utils.StringMap{"NAT": true}, RatingSubject: "*zero1m"} - b2 := &Balance{Uuid: "testa", Value: 150, Weight: 5, DestinationIDs: utils.StringMap{"NAT": true}, RatingSubject: "*zero1s"} + b1 := &Balance{Uuid: "testb", Value: 70 * float64(time.Second), + DestinationIDs: utils.StringMap{"NAT": true}, + Weight: 10, RatingSubject: "*zero1m"} + b2 := &Balance{Uuid: "testa", Value: 150 * float64(time.Second), + DestinationIDs: utils.StringMap{"NAT": true}, + Weight: 5, RatingSubject: "*zero1s"} cc := &CallCost{ Direction: utils.OUT, Destination: "0723045326", @@ -624,15 +682,17 @@ func TestDebitCreditMoreTimespansMixed(t *testing.T) { cc.Timespans[0].Increments[0].Duration != time.Minute { t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0]) } - if rifsBalance.BalanceMap[utils.VOICE][0].GetValue() != 10 || - rifsBalance.BalanceMap[utils.VOICE][1].GetValue() != 130 { + if rifsBalance.BalanceMap[utils.VOICE][0].GetValue() != 10*float64(time.Second) || + rifsBalance.BalanceMap[utils.VOICE][1].GetValue() != 130*float64(time.Second) { t.Error("Error extracting minutes from balance: ", rifsBalance.BalanceMap[utils.VOICE][1], cc.Timespans[1]) } } func TestDebitCreditNoConectFeeCredit(t *testing.T) { - b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationIDs: utils.StringMap{"NAT": true}, RatingSubject: "*zero1m"} + b1 := &Balance{Uuid: "testb", Value: 70 * float64(time.Second), + DestinationIDs: utils.StringMap{"NAT": true}, + Weight: 10, RatingSubject: "*zero1m"} cc := &CallCost{ Direction: utils.OUT, Destination: "0723045326", @@ -731,7 +791,11 @@ func TestDebitCreditMoneyOnly(t *testing.T) { } func TestDebitCreditSubjectMinutes(t *testing.T) { - b1 := &Balance{Uuid: "testb", Categories: utils.NewStringMap("0"), Value: 250, Weight: 10, DestinationIDs: utils.StringMap{"NAT": true}, RatingSubject: "minu"} + b1 := &Balance{Uuid: "testb", + Categories: utils.NewStringMap("0"), + Value: 250 * float64(time.Second), + Weight: 10, DestinationIDs: utils.StringMap{"NAT": true}, + RatingSubject: "minu"} cc := &CallCost{ Tenant: "vdf", Category: "0", @@ -773,10 +837,11 @@ func TestDebitCreditSubjectMinutes(t *testing.T) { cc.Timespans[0].Increments[0].Duration != 10*time.Second { t.Errorf("Error setting balance id to increment: %+v", cc.Timespans[0].Increments[0]) } - if rifsBalance.BalanceMap[utils.VOICE][0].GetValue() != 180 || + if rifsBalance.BalanceMap[utils.VOICE][0].GetValue() != 180*float64(time.Second) || rifsBalance.BalanceMap[utils.MONETARY][0].GetValue() != 280 { t.Errorf("Error extracting minutes from balance: %+v, %+v", - rifsBalance.BalanceMap[utils.VOICE][0].GetValue(), rifsBalance.BalanceMap[utils.MONETARY][0].GetValue()) + rifsBalance.BalanceMap[utils.VOICE][0].GetValue(), + rifsBalance.BalanceMap[utils.MONETARY][0].GetValue()) } if len(cc.Timespans) != 1 || cc.Timespans[0].GetDuration() != 70*time.Second { for _, ts := range cc.Timespans { @@ -1004,53 +1069,128 @@ func TestAccountAddMinutBucketEmpty(t *testing.T) { func TestAccountExecuteTriggeredActions(t *testing.T) { ub := &Account{ - ID: "TEST_UB", - BalanceMap: map[string]Balances{utils.MONETARY: Balances{&Balance{Directions: utils.NewStringMap(utils.OUT), Value: 100}}, utils.VOICE: Balances{&Balance{Value: 10, Weight: 20, DestinationIDs: utils.StringMap{"NAT": true}, Directions: utils.StringMap{utils.OUT: true}}, &Balance{Weight: 10, DestinationIDs: utils.StringMap{"RET": true}}}}, - UnitCounters: UnitCounters{utils.MONETARY: []*UnitCounter{&UnitCounter{Counters: CounterFilters{&CounterFilter{Value: 1, Filter: &BalanceFilter{Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.StringMap{utils.OUT: true})}}}}}}, - ActionTriggers: ActionTriggers{&ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, ThresholdValue: 2, ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER, ActionsID: "TEST_ACTIONS"}}, + ID: "TEST_UB", + BalanceMap: map[string]Balances{ + utils.MONETARY: Balances{ + &Balance{Directions: utils.NewStringMap(utils.OUT), Value: 100}}, + utils.VOICE: Balances{ + &Balance{Value: 10 * float64(time.Second), + Weight: 20, + DestinationIDs: utils.StringMap{"NAT": true}, + Directions: utils.StringMap{utils.OUT: true}}, + &Balance{Weight: 10, + DestinationIDs: utils.StringMap{"RET": true}}}}, + UnitCounters: UnitCounters{ + utils.MONETARY: []*UnitCounter{ + &UnitCounter{Counters: CounterFilters{ + &CounterFilter{Value: 1, + Filter: &BalanceFilter{ + Type: utils.StringPointer(utils.MONETARY), + Directions: utils.StringMapPointer(utils.StringMap{utils.OUT: true})}}}}}}, + ActionTriggers: ActionTriggers{ + &ActionTrigger{ + Balance: &BalanceFilter{ + Type: utils.StringPointer(utils.MONETARY), + Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, + ThresholdValue: 2, ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER, + ActionsID: "TEST_ACTIONS"}}, } ub.countUnits(1, utils.MONETARY, &CallCost{Direction: utils.OUT}, nil) - if ub.BalanceMap[utils.MONETARY][0].GetValue() != 110 || ub.BalanceMap[utils.VOICE][0].GetValue() != 20 { - t.Error("Error executing triggered actions", ub.BalanceMap[utils.MONETARY][0].GetValue(), ub.BalanceMap[utils.VOICE][0].GetValue()) + if ub.BalanceMap[utils.MONETARY][0].GetValue() != 110 || + ub.BalanceMap[utils.VOICE][0].GetValue() != 20*float64(time.Second) { + t.Error("Error executing triggered actions", + ub.BalanceMap[utils.MONETARY][0].GetValue(), ub.BalanceMap[utils.VOICE][0].GetValue()) } // are set to executed ub.countUnits(1, utils.MONETARY, nil, nil) - if ub.BalanceMap[utils.MONETARY][0].GetValue() != 110 || ub.BalanceMap[utils.VOICE][0].GetValue() != 20 { - t.Error("Error executing triggered actions", ub.BalanceMap[utils.MONETARY][0].GetValue(), ub.BalanceMap[utils.VOICE][0].GetValue()) + if ub.BalanceMap[utils.MONETARY][0].GetValue() != 110 || + ub.BalanceMap[utils.VOICE][0].GetValue() != 20*float64(time.Second) { + t.Error("Error executing triggered actions", + ub.BalanceMap[utils.MONETARY][0].GetValue(), ub.BalanceMap[utils.VOICE][0].GetValue()) } // we can reset them ub.ResetActionTriggers(nil) ub.countUnits(10, utils.MONETARY, nil, nil) - if ub.BalanceMap[utils.MONETARY][0].GetValue() != 120 || ub.BalanceMap[utils.VOICE][0].GetValue() != 30 { - t.Error("Error executing triggered actions", ub.BalanceMap[utils.MONETARY][0].GetValue(), ub.BalanceMap[utils.VOICE][0].GetValue()) + if ub.BalanceMap[utils.MONETARY][0].GetValue() != 120 || + ub.BalanceMap[utils.VOICE][0].GetValue() != 30*float64(time.Second) { + t.Error("Error executing triggered actions", + ub.BalanceMap[utils.MONETARY][0].GetValue(), + ub.BalanceMap[utils.VOICE][0].GetValue()) } } func TestAccountExecuteTriggeredActionsBalance(t *testing.T) { ub := &Account{ - ID: "TEST_UB", - BalanceMap: map[string]Balances{utils.MONETARY: Balances{&Balance{Directions: utils.NewStringMap(utils.OUT), Value: 100}}, utils.VOICE: Balances{&Balance{Directions: utils.NewStringMap(utils.OUT), Value: 10, Weight: 20, DestinationIDs: utils.StringMap{"NAT": true}}, &Balance{Directions: utils.NewStringMap(utils.OUT), Weight: 10, DestinationIDs: utils.StringMap{"RET": true}}}}, - UnitCounters: UnitCounters{utils.MONETARY: []*UnitCounter{&UnitCounter{Counters: CounterFilters{&CounterFilter{Filter: &BalanceFilter{Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, Value: 1.0}}}}}, - ActionTriggers: ActionTriggers{&ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, ThresholdValue: 100, ThresholdType: utils.TRIGGER_MIN_EVENT_COUNTER, ActionsID: "TEST_ACTIONS"}}, + ID: "TEST_UB", + BalanceMap: map[string]Balances{ + utils.MONETARY: Balances{ + &Balance{ + Directions: utils.NewStringMap(utils.OUT), + Value: 100}}, + utils.VOICE: Balances{ + &Balance{ + Directions: utils.NewStringMap(utils.OUT), + Value: 10 * float64(time.Second), + Weight: 20, + DestinationIDs: utils.StringMap{"NAT": true}}, + &Balance{ + Directions: utils.NewStringMap(utils.OUT), + Weight: 10, + DestinationIDs: utils.StringMap{"RET": true}}}}, + UnitCounters: UnitCounters{ + utils.MONETARY: []*UnitCounter{ + &UnitCounter{Counters: CounterFilters{ + &CounterFilter{Filter: &BalanceFilter{ + Type: utils.StringPointer(utils.MONETARY), + Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, + Value: 1.0}}}}}, + ActionTriggers: ActionTriggers{ + &ActionTrigger{ + Balance: &BalanceFilter{ + Type: utils.StringPointer(utils.MONETARY), + Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, + ThresholdValue: 100, + ThresholdType: utils.TRIGGER_MIN_EVENT_COUNTER, + ActionsID: "TEST_ACTIONS"}}, } ub.countUnits(1, utils.MONETARY, nil, nil) - if ub.BalanceMap[utils.MONETARY][0].GetValue() != 110 || ub.BalanceMap[utils.VOICE][0].GetValue() != 20 { - t.Error("Error executing triggered actions", ub.BalanceMap[utils.MONETARY][0].GetValue(), ub.BalanceMap[utils.VOICE][0].GetValue(), len(ub.BalanceMap[utils.MONETARY])) + if ub.BalanceMap[utils.MONETARY][0].GetValue() != 110 || + ub.BalanceMap[utils.VOICE][0].GetValue() != 20*float64(time.Second) { + t.Error("Error executing triggered actions", + ub.BalanceMap[utils.MONETARY][0].GetValue(), + ub.BalanceMap[utils.VOICE][0].GetValue(), + len(ub.BalanceMap[utils.MONETARY])) } } func TestAccountExecuteTriggeredActionsOrder(t *testing.T) { ub := &Account{ - ID: "TEST_UB_OREDER", - BalanceMap: map[string]Balances{utils.MONETARY: Balances{&Balance{Directions: utils.NewStringMap(utils.OUT), Value: 100}}}, - UnitCounters: UnitCounters{utils.MONETARY: []*UnitCounter{&UnitCounter{Counters: CounterFilters{&CounterFilter{Value: 1, Filter: &BalanceFilter{Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)), Type: utils.StringPointer(utils.MONETARY)}}}}}}, - ActionTriggers: ActionTriggers{&ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, ThresholdValue: 2, ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER, ActionsID: "TEST_ACTIONS_ORDER"}}, + ID: "TEST_UB_OREDER", + BalanceMap: map[string]Balances{ + utils.MONETARY: Balances{ + &Balance{Directions: utils.NewStringMap(utils.OUT), + Value: 100}}}, + UnitCounters: UnitCounters{ + utils.MONETARY: []*UnitCounter{ + &UnitCounter{Counters: CounterFilters{ + &CounterFilter{Value: 1, Filter: &BalanceFilter{ + Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)), + Type: utils.StringPointer(utils.MONETARY)}}}}}}, + ActionTriggers: ActionTriggers{ + &ActionTrigger{Balance: &BalanceFilter{ + Type: utils.StringPointer(utils.MONETARY), + Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, + ThresholdValue: 2, + ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER, + ActionsID: "TEST_ACTIONS_ORDER"}}, } ub.countUnits(1, utils.MONETARY, &CallCost{Direction: utils.OUT}, nil) - if len(ub.BalanceMap[utils.MONETARY]) != 1 || ub.BalanceMap[utils.MONETARY][0].GetValue() != 10 { + if len(ub.BalanceMap[utils.MONETARY]) != 1 || + ub.BalanceMap[utils.MONETARY][0].GetValue() != 10 { - t.Errorf("Error executing triggered actions in order %v", ub.BalanceMap[utils.MONETARY][0].GetValue()) + t.Errorf("Error executing triggered actions in order %v", + ub.BalanceMap[utils.MONETARY][0].GetValue()) } } @@ -1084,19 +1224,35 @@ func TestAccountExecuteTriggeredDayWeek(t *testing.T) { func TestAccountExpActionTrigger(t *testing.T) { ub := &Account{ - ID: "TEST_UB", - BalanceMap: map[string]Balances{utils.MONETARY: Balances{&Balance{Directions: utils.NewStringMap(utils.OUT), Value: 100, ExpirationDate: time.Date(2015, time.November, 9, 9, 48, 0, 0, time.UTC)}}, utils.VOICE: Balances{&Balance{Value: 10, Weight: 20, DestinationIDs: utils.StringMap{"NAT": true}, Directions: utils.StringMap{utils.OUT: true}}, &Balance{Weight: 10, DestinationIDs: utils.StringMap{"RET": true}}}}, + ID: "TEST_UB", + BalanceMap: map[string]Balances{ + utils.MONETARY: Balances{ + &Balance{Directions: utils.NewStringMap(utils.OUT), Value: 100, + ExpirationDate: time.Date(2015, time.November, 9, 9, 48, 0, 0, time.UTC)}}, + utils.VOICE: Balances{ + &Balance{Value: 10 * float64(time.Second), Weight: 20, + DestinationIDs: utils.StringMap{"NAT": true}, + Directions: utils.StringMap{utils.OUT: true}}, + &Balance{Weight: 10 * float64(time.Second), + DestinationIDs: utils.StringMap{"RET": true}}}}, ActionTriggers: ActionTriggers{ - &ActionTrigger{ID: "check expired balances", Balance: &BalanceFilter{Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, ThresholdValue: 10, ThresholdType: utils.TRIGGER_BALANCE_EXPIRED, ActionsID: "TEST_ACTIONS"}, + &ActionTrigger{ID: "check expired balances", Balance: &BalanceFilter{ + Type: utils.StringPointer(utils.MONETARY), + Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, + ThresholdValue: 10, ThresholdType: utils.TRIGGER_BALANCE_EXPIRED, + ActionsID: "TEST_ACTIONS"}, }, } ub.ExecuteActionTriggers(nil) if ub.BalanceMap[utils.MONETARY][0].IsExpired() || ub.BalanceMap[utils.MONETARY][0].GetValue() != 10 || // expired was cleaned - ub.BalanceMap[utils.VOICE][0].GetValue() != 20 || + ub.BalanceMap[utils.VOICE][0].GetValue() != 20*float64(time.Second) || ub.ActionTriggers[0].Executed != true { t.Log(ub.BalanceMap[utils.MONETARY][0].IsExpired()) - t.Error("Error executing triggered actions", ub.BalanceMap[utils.MONETARY][0].GetValue(), ub.BalanceMap[utils.VOICE][0].GetValue(), len(ub.BalanceMap[utils.MONETARY])) + t.Error("Error executing triggered actions", + ub.BalanceMap[utils.MONETARY][0].GetValue(), + ub.BalanceMap[utils.VOICE][0].GetValue(), + len(ub.BalanceMap[utils.MONETARY])) } } @@ -1168,13 +1324,17 @@ func TestCleanExpired(t *testing.T) { } func TestAccountUnitCounting(t *testing.T) { - ub := &Account{UnitCounters: UnitCounters{utils.MONETARY: []*UnitCounter{&UnitCounter{Counters: CounterFilters{&CounterFilter{Value: 0}}}}}} + ub := &Account{UnitCounters: UnitCounters{ + utils.MONETARY: []*UnitCounter{&UnitCounter{ + Counters: CounterFilters{&CounterFilter{Value: 0}}}}}} ub.countUnits(10, utils.MONETARY, &CallCost{}, nil) - if len(ub.UnitCounters[utils.MONETARY]) != 1 || ub.UnitCounters[utils.MONETARY][0].Counters[0].Value != 10 { + if len(ub.UnitCounters[utils.MONETARY]) != 1 || + ub.UnitCounters[utils.MONETARY][0].Counters[0].Value != 10 { t.Error("Error counting units") } ub.countUnits(10, utils.MONETARY, &CallCost{}, nil) - if len(ub.UnitCounters[utils.MONETARY]) != 1 || ub.UnitCounters[utils.MONETARY][0].Counters[0].Value != 20 { + if len(ub.UnitCounters[utils.MONETARY]) != 1 || + ub.UnitCounters[utils.MONETARY][0].Counters[0].Value != 20 { t.Error("Error counting units") } } @@ -1362,10 +1522,16 @@ func TestDebitSMS(t *testing.T) { Timespans: []*TimeSpan{ &TimeSpan{ TimeStart: time.Date(2013, 9, 24, 10, 48, 0, 0, time.UTC), - TimeEnd: time.Date(2013, 9, 24, 10, 48, 1, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 48, 0, 1, time.UTC), ratingInfo: &RatingInfo{}, DurationIndex: 0, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 1 * time.Second, RateUnit: time.Second}}}}, + RateInterval: &RateInterval{ + Rating: &RIRate{ + Rates: RateGroups{ + &Rate{GroupIntervalStart: 0, + Value: 100, + RateIncrement: 1, + RateUnit: time.Nanosecond}}}}, }, }, TOR: utils.SMS, @@ -1379,10 +1545,15 @@ func TestDebitSMS(t *testing.T) { DurationIndex: cc.GetDuration(), testCallcost: cc, } - rifsBalance := &Account{ID: "other", BalanceMap: map[string]Balances{ - utils.SMS: Balances{&Balance{Uuid: "testm", Value: 100, Weight: 5, DestinationIDs: utils.StringMap{"NAT": true}}}, - utils.MONETARY: Balances{&Balance{Value: 21}}, - }} + rifsBalance := &Account{ID: "other", + BalanceMap: map[string]Balances{ + utils.SMS: Balances{ + &Balance{Uuid: "testm", + Value: 100, Weight: 5, + DestinationIDs: utils.StringMap{"NAT": true}}}, + utils.MONETARY: Balances{ + &Balance{Value: 21}}, + }} var err error cc, err = rifsBalance.debitCreditBalance(cd, false, false, true) if err != nil { @@ -1394,7 +1565,9 @@ func TestDebitSMS(t *testing.T) { if rifsBalance.BalanceMap[utils.SMS][0].GetValue() != 99 || rifsBalance.BalanceMap[utils.MONETARY][0].GetValue() != 21 { t.Log(cc.Timespans[0].Increments) - t.Error("Error extracting minutes from balance: ", rifsBalance.BalanceMap[utils.SMS][0].GetValue(), rifsBalance.BalanceMap[utils.MONETARY][0].GetValue()) + t.Error("Error extracting minutes from balance: ", + rifsBalance.BalanceMap[utils.SMS][0].GetValue(), + rifsBalance.BalanceMap[utils.MONETARY][0].GetValue()) } } @@ -1405,10 +1578,15 @@ func TestDebitGeneric(t *testing.T) { Timespans: []*TimeSpan{ &TimeSpan{ TimeStart: time.Date(2013, 9, 24, 10, 48, 0, 0, time.UTC), - TimeEnd: time.Date(2013, 9, 24, 10, 48, 1, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 48, 0, 1, time.UTC), ratingInfo: &RatingInfo{}, DurationIndex: 0, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 1 * time.Second, RateUnit: time.Second}}}}, + RateInterval: &RateInterval{ + Rating: &RIRate{ + Rates: RateGroups{ + &Rate{GroupIntervalStart: 0, Value: 100, + RateIncrement: 1, + RateUnit: time.Nanosecond}}}}, }, }, TOR: utils.GENERIC, @@ -1422,10 +1600,13 @@ func TestDebitGeneric(t *testing.T) { DurationIndex: cc.GetDuration(), testCallcost: cc, } - rifsBalance := &Account{ID: "other", BalanceMap: map[string]Balances{ - utils.GENERIC: Balances{&Balance{Uuid: "testm", Value: 100, Weight: 5, DestinationIDs: utils.StringMap{"NAT": true}}}, - utils.MONETARY: Balances{&Balance{Value: 21}}, - }} + rifsBalance := &Account{ID: "other", + BalanceMap: map[string]Balances{ + utils.GENERIC: Balances{ + &Balance{Uuid: "testm", Value: 100, Weight: 5, + DestinationIDs: utils.StringMap{"NAT": true}}}, + utils.MONETARY: Balances{&Balance{Value: 21}}, + }} var err error cc, err = rifsBalance.debitCreditBalance(cd, false, false, true) if err != nil { @@ -1451,7 +1632,13 @@ func TestDebitGenericBalance(t *testing.T) { TimeEnd: time.Date(2013, 9, 24, 10, 48, 30, 0, time.UTC), ratingInfo: &RatingInfo{}, DurationIndex: 0, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 1 * time.Second, RateUnit: time.Second}}}}, + RateInterval: &RateInterval{ + Rating: &RIRate{ + Rates: RateGroups{ + &Rate{GroupIntervalStart: 0, + Value: 100, + RateIncrement: 1 * time.Second, + RateUnit: time.Second}}}}, }, }, TOR: utils.VOICE, @@ -1465,10 +1652,14 @@ func TestDebitGenericBalance(t *testing.T) { DurationIndex: cc.GetDuration(), testCallcost: cc, } - rifsBalance := &Account{ID: "other", BalanceMap: map[string]Balances{ - utils.GENERIC: Balances{&Balance{Uuid: "testm", Value: 100, Weight: 5, DestinationIDs: utils.StringMap{"NAT": true}, Factor: ValueFactor{utils.VOICE: 60.0}}}, - utils.MONETARY: Balances{&Balance{Value: 21}}, - }} + rifsBalance := &Account{ + ID: "other", BalanceMap: map[string]Balances{ + utils.GENERIC: Balances{ + &Balance{Uuid: "testm", Value: 100, Weight: 5, + DestinationIDs: utils.StringMap{"NAT": true}, + Factor: ValueFactor{utils.VOICE: 60 * float64(time.Second)}}}, + utils.MONETARY: Balances{&Balance{Value: 21}}, + }} var err error cc, err = rifsBalance.debitCreditBalance(cd, false, false, true) if err != nil { @@ -1480,7 +1671,9 @@ func TestDebitGenericBalance(t *testing.T) { if rifsBalance.BalanceMap[utils.GENERIC][0].GetValue() != 99.49999 || rifsBalance.BalanceMap[utils.MONETARY][0].GetValue() != 21 { t.Logf("%+v", cc.Timespans[0].Increments[0]) - t.Error("Error extracting minutes from balance: ", rifsBalance.BalanceMap[utils.GENERIC][0].GetValue(), rifsBalance.BalanceMap[utils.MONETARY][0].GetValue()) + t.Error("Error extracting minutes from balance: ", + rifsBalance.BalanceMap[utils.GENERIC][0].GetValue(), + rifsBalance.BalanceMap[utils.MONETARY][0].GetValue()) } } @@ -1494,7 +1687,12 @@ func TestDebitGenericBalanceWithRatingSubject(t *testing.T) { TimeEnd: time.Date(2013, 9, 24, 10, 48, 30, 0, time.UTC), ratingInfo: &RatingInfo{}, DurationIndex: 0, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 0, RateIncrement: time.Second, RateUnit: time.Second}}}}, + RateInterval: &RateInterval{ + Rating: &RIRate{ + Rates: RateGroups{ + &Rate{GroupIntervalStart: 0, Value: 0, + RateIncrement: time.Second, + RateUnit: time.Second}}}}, }, }, TOR: utils.VOICE, @@ -1508,10 +1706,15 @@ func TestDebitGenericBalanceWithRatingSubject(t *testing.T) { DurationIndex: cc.GetDuration(), testCallcost: cc, } - rifsBalance := &Account{ID: "other", BalanceMap: map[string]Balances{ - utils.GENERIC: Balances{&Balance{Uuid: "testm", Value: 100, Weight: 5, DestinationIDs: utils.StringMap{"NAT": true}, Factor: ValueFactor{utils.VOICE: 60.0}, RatingSubject: "free"}}, - utils.MONETARY: Balances{&Balance{Value: 21}}, - }} + rifsBalance := &Account{ID: "other", + BalanceMap: map[string]Balances{ + utils.GENERIC: Balances{ + &Balance{Uuid: "testm", Value: 100, + Weight: 5, DestinationIDs: utils.StringMap{"NAT": true}, + Factor: ValueFactor{utils.VOICE: 60 * float64(time.Second)}, + RatingSubject: "free"}}, + utils.MONETARY: Balances{&Balance{Value: 21}}, + }} var err error cc, err = rifsBalance.debitCreditBalance(cd, false, false, true) if err != nil { @@ -1523,7 +1726,9 @@ func TestDebitGenericBalanceWithRatingSubject(t *testing.T) { if rifsBalance.BalanceMap[utils.GENERIC][0].GetValue() != 99.49999 || rifsBalance.BalanceMap[utils.MONETARY][0].GetValue() != 21 { t.Logf("%+v", cc.Timespans[0].Increments[0]) - t.Error("Error extracting minutes from balance: ", rifsBalance.BalanceMap[utils.GENERIC][0].GetValue(), rifsBalance.BalanceMap[utils.MONETARY][0].GetValue()) + t.Error("Error extracting minutes from balance: ", + rifsBalance.BalanceMap[utils.GENERIC][0].GetValue(), + rifsBalance.BalanceMap[utils.MONETARY][0].GetValue()) } } @@ -1534,14 +1739,19 @@ func TestDebitDataUnits(t *testing.T) { Timespans: []*TimeSpan{ &TimeSpan{ TimeStart: time.Date(2013, 9, 24, 10, 48, 0, 0, time.UTC), - TimeEnd: time.Date(2013, 9, 24, 10, 49, 20, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 48, 0, 80, time.UTC), ratingInfo: &RatingInfo{}, DurationIndex: 0, RateInterval: &RateInterval{ Rating: &RIRate{ Rates: RateGroups{ - &Rate{GroupIntervalStart: 0, Value: 2, RateIncrement: 1 * time.Second, RateUnit: time.Minute}, - &Rate{GroupIntervalStart: 60, Value: 1, RateIncrement: 1 * time.Second, RateUnit: time.Second}, + &Rate{GroupIntervalStart: 0, + Value: 2, RateIncrement: 1, + RateUnit: 1}, + &Rate{GroupIntervalStart: 60, + Value: 1, + RateIncrement: 1, + RateUnit: 1}, }, }, }, @@ -1558,15 +1768,20 @@ func TestDebitDataUnits(t *testing.T) { DurationIndex: cc.GetDuration(), testCallcost: cc, } - rifsBalance := &Account{ID: "other", BalanceMap: map[string]Balances{ - utils.DATA: Balances{&Balance{Uuid: "testm", Value: 100, Weight: 5, DestinationIDs: utils.StringMap{"NAT": true}}}, - utils.MONETARY: Balances{&Balance{Value: 21}}, - }} + rifsBalance := &Account{ID: "other", + BalanceMap: map[string]Balances{ + utils.DATA: Balances{ + &Balance{Uuid: "testm", Value: 100, + Weight: 5, + DestinationIDs: utils.StringMap{"NAT": true}}}, + utils.MONETARY: Balances{&Balance{Value: 21}}, + }} var err error cc, err = rifsBalance.debitCreditBalance(cd, false, false, true) // test rating information ts := cc.Timespans[0] - if ts.MatchedSubject != "testm" || ts.MatchedPrefix != "0723" || ts.MatchedDestId != "NAT" || ts.RatingPlanId != utils.META_NONE { + if ts.MatchedSubject != "testm" || ts.MatchedPrefix != "0723" || + ts.MatchedDestId != "NAT" || ts.RatingPlanId != utils.META_NONE { t.Errorf("Error setting rating info: %+v", ts.ratingInfo) } if err != nil { @@ -1578,7 +1793,9 @@ func TestDebitDataUnits(t *testing.T) { if rifsBalance.BalanceMap[utils.DATA][0].GetValue() != 20 || rifsBalance.BalanceMap[utils.MONETARY][0].GetValue() != 21 { t.Log(ts.Increments) - t.Error("Error extracting minutes from balance: ", rifsBalance.BalanceMap[utils.DATA][0].GetValue(), rifsBalance.BalanceMap[utils.MONETARY][0].GetValue()) + t.Error("Error extracting minutes from balance: ", + rifsBalance.BalanceMap[utils.DATA][0].GetValue(), + rifsBalance.BalanceMap[utils.MONETARY][0].GetValue()) } } diff --git a/engine/callcost_test.go b/engine/callcost_test.go index 4f87cd25a..6ec384f94 100644 --- a/engine/callcost_test.go +++ b/engine/callcost_test.go @@ -27,7 +27,9 @@ import ( func TestSingleResultMerge(t *testing.T) { t1 := time.Date(2012, time.February, 2, 17, 0, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 2, 17, 1, 0, 0, time.UTC) - cd := &CallDescriptor{Direction: utils.OUT, Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} + cd := &CallDescriptor{Direction: utils.OUT, Category: "0", + Tenant: "vdf", Subject: "rif", + Destination: "0256", TimeStart: t1, TimeEnd: t2} cc1, _ := cd.getCost() if cc1.Cost != 61 { t.Errorf("expected 61 was %v", cc1.Cost) @@ -50,7 +52,7 @@ func TestSingleResultMerge(t *testing.T) { t.Errorf("Exdpected 120 was %v", cc1.Cost) } d := cc1.UpdateRatedUsage() - if d != 2*time.Minute || cc1.RatedUsage != 120.0 { + if d != 2*time.Minute || cc1.RatedUsage != 120.0*float64(time.Second) { t.Errorf("error updating rating usage: %v, %v", d, cc1.RatedUsage) } } diff --git a/engine/calldesc_test.go b/engine/calldesc_test.go index 5068eadfa..df0cafe9e 100644 --- a/engine/calldesc_test.go +++ b/engine/calldesc_test.go @@ -39,12 +39,21 @@ func init() { func populateDB() { ats := []*Action{ - &Action{ActionType: "*topup", Balance: &BalanceFilter{Type: utils.StringPointer(utils.MONETARY), Value: &utils.ValueFormula{Static: 10}}}, - &Action{ActionType: "*topup", Balance: &BalanceFilter{Type: utils.StringPointer(utils.VOICE), Weight: utils.Float64Pointer(20), Value: &utils.ValueFormula{Static: 10}, DestinationIDs: utils.StringMapPointer(utils.NewStringMap("NAT"))}}, + &Action{ActionType: "*topup", + Balance: &BalanceFilter{Type: utils.StringPointer(utils.MONETARY), + Value: &utils.ValueFormula{Static: 10}}}, + &Action{ActionType: "*topup", + Balance: &BalanceFilter{Type: utils.StringPointer(utils.VOICE), + Weight: utils.Float64Pointer(20), + Value: &utils.ValueFormula{Static: 10 * float64(time.Second)}, + DestinationIDs: utils.StringMapPointer(utils.NewStringMap("NAT"))}}, } ats1 := []*Action{ - &Action{ActionType: "*topup", Balance: &BalanceFilter{Type: utils.StringPointer(utils.MONETARY), Value: &utils.ValueFormula{Static: 10}}, Weight: 10}, + &Action{ActionType: "*topup", + Balance: &BalanceFilter{ + Type: utils.StringPointer(utils.MONETARY), + Value: &utils.ValueFormula{Static: 10}}, Weight: 10}, &Action{ActionType: "*reset_account", Weight: 20}, } @@ -53,16 +62,21 @@ func populateDB() { BalanceMap: map[string]Balances{ utils.MONETARY: Balances{&Balance{Value: 50}}, utils.VOICE: Balances{ - &Balance{Value: 200, DestinationIDs: utils.NewStringMap("NAT"), Weight: 10}, - &Balance{Value: 100, DestinationIDs: utils.NewStringMap("RET"), Weight: 20}, + &Balance{Value: 200 * float64(time.Second), + DestinationIDs: utils.NewStringMap("NAT"), Weight: 10}, + &Balance{Value: 100 * float64(time.Second), + DestinationIDs: utils.NewStringMap("RET"), Weight: 20}, }}, } broker := &Account{ ID: "vdf:broker", BalanceMap: map[string]Balances{ utils.VOICE: Balances{ - &Balance{Value: 20, DestinationIDs: utils.NewStringMap("NAT"), Weight: 10, RatingSubject: "rif"}, - &Balance{Value: 100, DestinationIDs: utils.NewStringMap("RET"), Weight: 20}, + &Balance{Value: 20 * float64(time.Second), + DestinationIDs: utils.NewStringMap("NAT"), + Weight: 10, RatingSubject: "rif"}, + &Balance{Value: 100 * float64(time.Second), + DestinationIDs: utils.NewStringMap("RET"), Weight: 20}, }}, } luna := &Account{ @@ -77,8 +91,11 @@ func populateDB() { ID: "vdf:minitsboy", BalanceMap: map[string]Balances{ utils.VOICE: Balances{ - &Balance{Value: 20, DestinationIDs: utils.NewStringMap("NAT"), Weight: 10, RatingSubject: "rif"}, - &Balance{Value: 100, DestinationIDs: utils.NewStringMap("RET"), Weight: 20}, + &Balance{Value: 20 * float64(time.Second), + DestinationIDs: utils.NewStringMap("NAT"), + Weight: 10, RatingSubject: "rif"}, + &Balance{Value: 100 * float64(time.Second), + DestinationIDs: utils.NewStringMap("RET"), Weight: 20}, }, utils.MONETARY: Balances{ &Balance{Value: 100, Weight: 10}, @@ -116,7 +133,9 @@ func populateDB() { func debitTest(t *testing.T, wg *sync.WaitGroup) { t1 := time.Date(2017, time.February, 2, 17, 30, 0, 0, time.UTC) t2 := time.Date(2017, time.February, 2, 17, 30, 59, 0, time.UTC) - cd := &CallDescriptor{Direction: "*out", Category: "call", Tenant: "cgrates.org", Account: "moneyp", Subject: "nt", Destination: "49", TimeStart: t1, TimeEnd: t2, LoopIndex: 0} + cd := &CallDescriptor{Direction: "*out", Category: "call", + Tenant: "cgrates.org", Account: "moneyp", Subject: "nt", + Destination: "49", TimeStart: t1, TimeEnd: t2, LoopIndex: 0} if _, err := cd.Debit(); err != nil { t.Errorf("Error debiting balance: %s", err) } @@ -144,7 +163,9 @@ func TestSerialDebit(t *testing.T) { wg.Wait() t1 := time.Date(2017, time.February, 2, 17, 30, 0, 0, time.UTC) t2 := time.Date(2017, time.February, 2, 17, 30, 59, 0, time.UTC) - cd := &CallDescriptor{Direction: "*out", Category: "call", Tenant: "cgrates.org", Account: "moneyp", Subject: "nt", Destination: "49", TimeStart: t1, TimeEnd: t2, LoopIndex: 0} + cd := &CallDescriptor{Direction: "*out", Category: "call", + Tenant: "cgrates.org", Account: "moneyp", Subject: "nt", + Destination: "49", TimeStart: t1, TimeEnd: t2, LoopIndex: 0} acc, err := cd.getAccount() if err != nil { @@ -152,14 +173,9 @@ func TestSerialDebit(t *testing.T) { } expBalance := initialBalance - float64(debitsToDo*60) if acc.BalanceMap[utils.MONETARY][0].GetValue() != expBalance { - t.Errorf("Balance does not match: %f, expected %f", acc.BalanceMap[utils.MONETARY][0].GetValue(), expBalance) + t.Errorf("Balance does not match: %f, expected %f", + acc.BalanceMap[utils.MONETARY][0].GetValue(), expBalance) } - /* - out, err := json.Marshal(acc) - if err == nil { - t.Log("Account: %s", string(out)) - } - */ } @@ -1308,9 +1324,11 @@ func TestDebitAndMaxDebit(t *testing.T) { if err1 != nil || err2 != nil { t.Error("Error debiting and/or maxdebiting: ", err1, err2) } - if cc1.Timespans[0].Increments[0].BalanceInfo.Unit.Value != 90 || - cc2.Timespans[0].Increments[0].BalanceInfo.Unit.Value != 80 { - t.Error("Error setting the Unit.Value: ", cc1.Timespans[0].Increments[0].BalanceInfo.Unit.Value, cc2.Timespans[0].Increments[0].BalanceInfo.Unit.Value) + if cc1.Timespans[0].Increments[0].BalanceInfo.Unit.Value != 90*float64(time.Second) || + cc2.Timespans[0].Increments[0].BalanceInfo.Unit.Value != 80*float64(time.Second) { + t.Error("Error setting the Unit.Value: ", + cc1.Timespans[0].Increments[0].BalanceInfo.Unit.Value, + cc2.Timespans[0].Increments[0].BalanceInfo.Unit.Value) } // make Unit.Values have the same value cc1.Timespans[0].Increments[0].BalanceInfo.Unit.Value = 0 @@ -1595,8 +1613,9 @@ func TestMaxDebitConsumesMinutes(t *testing.T) { LoopIndex: 0, DurationIndex: 0} cd1.MaxDebit() - if cd1.account.BalanceMap[utils.VOICE][0].GetValue() != 20 { - t.Error("Error using minutes: ", cd1.account.BalanceMap[utils.VOICE][0].GetValue()) + if cd1.account.BalanceMap[utils.VOICE][0].GetValue() != 20*float64(time.Second) { + t.Error("Error using minutes: ", + cd1.account.BalanceMap[utils.VOICE][0].GetValue()) } } @@ -1662,23 +1681,32 @@ func TestCDRefundIncrements(t *testing.T) { &Balance{Uuid: "moneya", Value: 100}, }, utils.VOICE: Balances{ - &Balance{Uuid: "minutea", Value: 10, Weight: 20, DestinationIDs: utils.StringMap{"NAT": true}}, - &Balance{Uuid: "minuteb", Value: 10, DestinationIDs: utils.StringMap{"RET": true}}, + &Balance{Uuid: "minutea", + Value: 10 * float64(time.Second), + Weight: 20, + DestinationIDs: utils.StringMap{"NAT": true}}, + &Balance{Uuid: "minuteb", + Value: 10 * float64(time.Second), + DestinationIDs: utils.StringMap{"RET": true}}, }, }, } dm.DataDB().SetAccount(ub) increments := Increments{ - &Increment{Cost: 2, BalanceInfo: &DebitInfo{Monetary: &MonetaryInfo{UUID: "moneya"}, AccountID: ub.ID}}, - &Increment{Cost: 2, Duration: 3 * time.Second, BalanceInfo: &DebitInfo{Unit: &UnitInfo{UUID: "minutea"}, Monetary: &MonetaryInfo{UUID: "moneya"}, AccountID: ub.ID}}, - &Increment{Duration: 4 * time.Second, BalanceInfo: &DebitInfo{Unit: &UnitInfo{UUID: "minuteb"}, AccountID: ub.ID}}, + &Increment{Cost: 2, BalanceInfo: &DebitInfo{ + Monetary: &MonetaryInfo{UUID: "moneya"}, AccountID: ub.ID}}, + &Increment{Cost: 2, Duration: 3 * time.Second, BalanceInfo: &DebitInfo{ + Unit: &UnitInfo{UUID: "minutea"}, + Monetary: &MonetaryInfo{UUID: "moneya"}, AccountID: ub.ID}}, + &Increment{Duration: 4 * time.Second, BalanceInfo: &DebitInfo{ + Unit: &UnitInfo{UUID: "minuteb"}, AccountID: ub.ID}}, } cd := &CallDescriptor{TOR: utils.VOICE, Increments: increments} cd.RefundIncrements() ub, _ = dm.DataDB().GetAccount(ub.ID) if ub.BalanceMap[utils.MONETARY][0].GetValue() != 104 || - ub.BalanceMap[utils.VOICE][0].GetValue() != 13 || - ub.BalanceMap[utils.VOICE][1].GetValue() != 14 { + ub.BalanceMap[utils.VOICE][0].GetValue() != 13*float64(time.Second) || + ub.BalanceMap[utils.VOICE][1].GetValue() != 14*float64(time.Second) { t.Error("Error refunding money: ", utils.ToIJSON(ub.BalanceMap)) } } @@ -1717,7 +1745,8 @@ func TestCDDebitBalanceSubjectWithFallback(t *testing.T) { ID: "TCDDBSWF:account1", BalanceMap: map[string]Balances{ utils.VOICE: Balances{ - &Balance{ID: "voice1", Value: 60, RatingSubject: "SubjTCDDBSWF"}, + &Balance{ID: "voice1", Value: 60 * float64(time.Second), + RatingSubject: "SubjTCDDBSWF"}, }}, } dm.DataDB().SetAccount(acnt) diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index 069307102..7469a892e 100755 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -67,7 +67,7 @@ LANDLINE_OFFPEAK,0,1,1s,60s,0s LANDLINE_OFFPEAK,0,1,1s,1s,60s GBP_71,0.000000,5.55555,1s,1s,0s GBP_72,0.000000,7.77777,1s,1s,0s -GBP_70,0.000000,1,1,1s,0s +GBP_70,0.000000,1,1s,1s,0s RT_UK_Mobile_BIG5_PKG,0.01,0,20s,20s,0s RT_UK_Mobile_BIG5,0.01,0.10,1s,1s,0s R_URG,0,0,1s,1s,0s @@ -163,10 +163,10 @@ SG3,*any,*lowest, ` actions = ` MINI,*topup_reset,,,,*monetary,*out,,,,,*unlimited,,10,10,false,false,10 -MINI,*topup,,,,*voice,*out,,NAT,test,,*unlimited,,100,10,false,false,10 +MINI,*topup,,,,*voice,*out,,NAT,test,,*unlimited,,100s,10,false,false,10 SHARED,*topup,,,,*monetary,*out,,,,SG1,*unlimited,,100,10,false,false,10 TOPUP10_AC,*topup_reset,,,,*monetary,*out,,*any,,,*unlimited,,1,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,,40s,10,false,false,10 SE0,*topup_reset,,,,*monetary,*out,,,,SG2,*unlimited,,0,10,false,false,10 SE10,*topup_reset,,,,*monetary,*out,,,,SG2,*unlimited,,10,5,false,false,10 SE10,*topup,,,,*monetary,*out,,,,,*unlimited,,10,10,false,false,10 @@ -179,8 +179,8 @@ BLOCK,*topup,,,bfree,*monetary,*out,,,,,*unlimited,,20,10,false,false,10 BLOCK_EMPTY,*topup,,,bblocker,*monetary,*out,,NAT,,,*unlimited,,0,20,true,false,20 BLOCK_EMPTY,*topup,,,bfree,*monetary,*out,,,,,*unlimited,,20,10,false,false,10 FILTER,*topup,,"{""*and"":[{""Value"":{""*lt"":0}},{""Id"":{""*eq"":""*default""}}]}",bfree,*monetary,*out,,,,,*unlimited,,20,10,false,false,10 -EXP,*topup,,,,*voice,*out,,,,,*monthly,*any,300,10,false,false,10 -NOEXP,*topup,,,,*voice,*out,,,,,*unlimited,*any,50,10,false,false,10 +EXP,*topup,,,,*voice,*out,,,,,*monthly,*any,300s,10,false,false,10 +NOEXP,*topup,,,,*voice,*out,,,,,*unlimited,*any,50s,10,false,false,10 VF,*debit,,,,*monetary,*out,,,,,*unlimited,*any,"{""Method"":""*incremental"",""Params"":{""Units"":10, ""Interval"":""month"", ""Increment"":""day""}}",10,false,false,10 TOPUP_RST_GNR_1000,*topup_reset,"{""*voice"": 60.0,""*data"":1024.0,""*sms"":1.0}",,,*generic,*out,,*any,,,*unlimited,,1000,20,false,false,10 ` @@ -934,7 +934,7 @@ func TestLoadActions(t *testing.T) { Type: utils.StringPointer(utils.VOICE), Uuid: as1[1].Balance.Uuid, Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)), - Value: &utils.ValueFormula{Static: 100}, + Value: &utils.ValueFormula{Static: 100 * float64(time.Second)}, Weight: utils.Float64Pointer(10), RatingSubject: utils.StringPointer("test"), DestinationIDs: utils.StringMapPointer(utils.NewStringMap("NAT")), diff --git a/engine/rateinterval.go b/engine/rateinterval.go index eec12cf68..c84a586c8 100644 --- a/engine/rateinterval.go +++ b/engine/rateinterval.go @@ -351,7 +351,7 @@ func (i *RateInterval) GetCost(duration, startSecond time.Duration) float64 { price, _, rateUnit := i.GetRateParameters(startSecond) price /= float64(rateUnit.Nanoseconds()) d := float64(duration.Nanoseconds()) - return d * price + return utils.Round(d*price, globalRoundingDecimals, utils.ROUNDING_MIDDLE) } // Gets the price for a the provided start second diff --git a/engine/responder_test.go b/engine/responder_test.go index e367761fe..5eb31fd53 100644 --- a/engine/responder_test.go +++ b/engine/responder_test.go @@ -69,17 +69,21 @@ func TestResponderGetDerivedMaxSessionTime(t *testing.T) { } else if maxSessionTime != -1 { t.Error("Unexpected maxSessionTime received: ", maxSessionTime) } - deTMobile := &Destination{Id: "DE_TMOBILE", Prefixes: []string{"+49151", "+49160", "+49170", "+49171", "+49175"}} + deTMobile := &Destination{Id: "DE_TMOBILE", + Prefixes: []string{"+49151", "+49160", "+49170", "+49171", "+49175"}} if err := dm.DataDB().SetDestination(deTMobile, utils.NonTransactional); err != nil { t.Error(err) } if err := dm.DataDB().SetReverseDestination(deTMobile, utils.NonTransactional); err != nil { t.Error(err) } - b10 := &Balance{Value: 10, Weight: 10, DestinationIDs: utils.NewStringMap("DE_TMOBILE")} - b20 := &Balance{Value: 20, Weight: 10, DestinationIDs: utils.NewStringMap("DE_TMOBILE")} + b10 := &Balance{Value: 10 * float64(time.Second), + Weight: 10, DestinationIDs: utils.NewStringMap("DE_TMOBILE")} + b20 := &Balance{Value: 20 * float64(time.Second), + Weight: 10, DestinationIDs: utils.NewStringMap("DE_TMOBILE")} rifsAccount := &Account{ID: utils.ConcatenatedKey(testTenant, "rif"), - BalanceMap: map[string]Balances{utils.VOICE: Balances{b10}}} + BalanceMap: map[string]Balances{ + utils.VOICE: Balances{b10}}} dansAccount := &Account{ID: utils.ConcatenatedKey(testTenant, "dan"), BalanceMap: map[string]Balances{utils.VOICE: Balances{b20}}} if err := dm.DataDB().SetAccount(rifsAccount); err != nil { @@ -438,10 +442,18 @@ func TestResponderGetLCR(t *testing.T) { } else if !reflect.DeepEqual(eLcLcr.SupplierCosts, lcrLc.SupplierCosts) { t.Errorf("Expecting: %+v, received: %+v", eLcLcr.SupplierCosts, lcrLc.SupplierCosts) } - bRif12 := &Balance{Value: 40, Weight: 10, DestinationIDs: utils.NewStringMap(dstDe.Id)} - bIvo12 := &Balance{Value: 60, Weight: 10, DestinationIDs: utils.NewStringMap(dstDe.Id)} - rif12sAccount := &Account{ID: utils.ConcatenatedKey("tenant12", "rif12"), BalanceMap: map[string]Balances{utils.VOICE: Balances{bRif12}}, AllowNegative: true} - ivo12sAccount := &Account{ID: utils.ConcatenatedKey("tenant12", "ivo12"), BalanceMap: map[string]Balances{utils.VOICE: Balances{bIvo12}}, AllowNegative: true} + bRif12 := &Balance{Value: 40 * float64(time.Second), + Weight: 10, DestinationIDs: utils.NewStringMap(dstDe.Id)} + bIvo12 := &Balance{Value: 60 * float64(time.Second), + Weight: 10, DestinationIDs: utils.NewStringMap(dstDe.Id)} + rif12sAccount := &Account{ + ID: utils.ConcatenatedKey("tenant12", "rif12"), + BalanceMap: map[string]Balances{ + utils.VOICE: Balances{bRif12}}, AllowNegative: true} + ivo12sAccount := &Account{ + ID: utils.ConcatenatedKey("tenant12", "ivo12"), + BalanceMap: map[string]Balances{ + utils.VOICE: Balances{bIvo12}}, AllowNegative: true} for _, acnt := range []*Account{rif12sAccount, ivo12sAccount} { if err := dm.DataDB().SetAccount(acnt); err != nil { t.Error(err) @@ -461,7 +473,7 @@ func TestResponderGetLCR(t *testing.T) { t.Errorf("Expecting: %+v, received: %+v", eLcLcr.Entry, lcrLc.Entry) } else if !reflect.DeepEqual(eLcLcr.SupplierCosts, lcrLc.SupplierCosts) { - t.Errorf("Expecting: %+v, received: %+v", eLcLcr.SupplierCosts, lcrLc.SupplierCosts) + t.Errorf("Expecting: %s\n, received: %+v", utils.ToJSON(eLcLcr.SupplierCosts), utils.ToJSON(lcrLc.SupplierCosts)) } /* // Test *qos_threshold strategy here, diff --git a/general_tests/ddazmbl2_test.go b/general_tests/ddazmbl2_test.go index 910e6325f..24fa3d005 100644 --- a/general_tests/ddazmbl2_test.go +++ b/general_tests/ddazmbl2_test.go @@ -51,7 +51,7 @@ RP_UK,DR_UK_Mobile_BIG5,ALWAYS,10` sharedGroups := `` lcrs := `` actions := `TOPUP10_AC,*topup_reset,,,,*monetary,*out,,*any,,,*unlimited,,0,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,,40s,10,false,false,10` actionPlans := `TOPUP10_AT,TOPUP10_AC,ASAP,10 TOPUP10_AT,TOPUP10_AC1,ASAP,10` actionTriggers := `` @@ -135,7 +135,7 @@ func TestExecuteActions2(t *testing.T) { 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 { + } else if acnt.BalanceMap[utils.VOICE][0].Value != 40*float64(time.Second) { t.Error("Account does not have enough minutes in balance", acnt.BalanceMap[utils.VOICE][0].Value) } else if acnt.BalanceMap[utils.MONETARY][0].Value != 0 { t.Error("Account does not have enough monetary balance", acnt.BalanceMap[utils.MONETARY][0].Value) @@ -165,7 +165,7 @@ func TestDebit2(t *testing.T) { if len(acnt.BalanceMap) != 2 { t.Error("Wrong number of user balances found", acnt.BalanceMap) } - if acnt.BalanceMap[utils.VOICE][0].Value != 20 { + if acnt.BalanceMap[utils.VOICE][0].Value != 20*float64(time.Second) { t.Error("Account does not have expected minutes in balance", acnt.BalanceMap[utils.VOICE][0].Value) } for _, blnc := range acnt.BalanceMap[utils.MONETARY] { // Test negative balance for default one diff --git a/general_tests/ddazmbl3_test.go b/general_tests/ddazmbl3_test.go index 4230688cf..39f0fe81b 100644 --- a/general_tests/ddazmbl3_test.go +++ b/general_tests/ddazmbl3_test.go @@ -50,7 +50,7 @@ RP_UK,DR_UK_Mobile_BIG5,ALWAYS,10` *out,cgrates.org,call,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_PKG,,` sharedGroups := `` lcrs := `` - actions := `TOPUP10_AC1,*topup_reset,,,,*voice,*out,,DST_UK_Mobile_BIG5,discounted_minutes,,*unlimited,,40,10,false,false,10` + actions := `TOPUP10_AC1,*topup_reset,,,,*voice,*out,,DST_UK_Mobile_BIG5,discounted_minutes,,*unlimited,,40s,10,false,false,10` actionPlans := `TOPUP10_AT,TOPUP10_AC1,ASAP,10` actionTriggers := `` accountActions := `cgrates.org,12346,TOPUP10_AT,,,` @@ -133,7 +133,7 @@ func TestExecuteActions3(t *testing.T) { t.Error(err) } else if len(acnt.BalanceMap) != 1 { t.Error("Account does not have enough balances: ", acnt.BalanceMap) - } else if acnt.BalanceMap[utils.VOICE][0].Value != 40 { + } else if acnt.BalanceMap[utils.VOICE][0].Value != 40*float64(time.Second) { t.Error("Account does not have enough minutes in balance", acnt.BalanceMap[utils.VOICE][0].Value) } } @@ -161,7 +161,7 @@ func TestDebit3(t *testing.T) { if len(acnt.BalanceMap) != 2 { t.Error("Wrong number of user balances found", acnt.BalanceMap) } - if acnt.BalanceMap[utils.VOICE][0].Value != 20 { + if acnt.BalanceMap[utils.VOICE][0].Value != 20*float64(time.Second) { t.Error("Account does not have expected minutes in balance", acnt.BalanceMap[utils.VOICE][0].Value) } if acnt.BalanceMap[utils.MONETARY][0].Value != -0.01 {