Merge branch 'master' into hapool

This commit is contained in:
DanB
2016-01-10 16:55:01 +01:00
11 changed files with 343 additions and 87 deletions

View File

@@ -766,6 +766,7 @@ func (cd *CallDescriptor) RefundIncrements() (left float64, err error) {
// all must be locked in order to use cache
accMap := make(map[string]struct{})
var accountIDs []string
cd.Increments.Decompress()
for _, increment := range cd.Increments {
accMap[increment.BalanceInfo.AccountId] = struct{}{}
}

View File

@@ -301,6 +301,12 @@ func (i *RateInterval) String_DISABLED() string {
}
func (i *RateInterval) Equal(o *RateInterval) bool {
if i == nil && o == nil {
return true
}
if i.Weight != o.Weight {
return false
}
if i.Timing == nil && o.Timing == nil {
return true
}

View File

@@ -191,6 +191,14 @@ func TestRateIntervalEqual(t *testing.T) {
}
}
func TestRateIntervalEqualWeight(t *testing.T) {
i1 := &RateInterval{Weight: 1}
i2 := &RateInterval{Weight: 2}
if i1.Equal(i2) {
t.Errorf("%v and %v should not be equal", i1, i2)
}
}
func TestRateIntervalNotEqual(t *testing.T) {
i1 := &RateInterval{
Timing: &RITiming{

View File

@@ -450,6 +450,7 @@ func (rs *Responder) GetSessionRuns(ev *CDR, sRuns *[]*SessionRun) error {
}
cd := &CallDescriptor{
CgrId: ev.GetCgrId(rs.Timezone),
TOR: ev.ToR,
Direction: ev.GetDirection(dc.DirectionField),
Tenant: ev.GetTenant(dc.TenantField),
Category: ev.GetCategory(dc.CategoryField),

View File

@@ -153,15 +153,15 @@ func TestResponderGetSessionRuns(t *testing.T) {
&SessionRun{DerivedCharger: extra1DC,
CallDescriptor: &CallDescriptor{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), Direction: "*out", Category: "0",
Tenant: "vdf", Subject: "rif", Account: "minitsboy", Destination: "0256", TimeStart: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC),
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}}},
TOR: utils.VOICE, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}}},
&SessionRun{DerivedCharger: extra2DC,
CallDescriptor: &CallDescriptor{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), Direction: "*out", Category: "call",
Tenant: "vdf", Subject: "ivo", Account: "ivo", Destination: "1002", TimeStart: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC),
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}}},
TOR: utils.VOICE, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}}},
&SessionRun{DerivedCharger: dfDC,
CallDescriptor: &CallDescriptor{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), Direction: "*out", Category: "call",
Tenant: "vdf", Subject: "dan2", Account: "dan2", Destination: "1002", TimeStart: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC),
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}}}}
TOR: utils.VOICE, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}}}}
if err := rsponder.GetSessionRuns(cdr, &sesRuns); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eSRuns, sesRuns) {

View File

@@ -38,6 +38,7 @@ type TimeSpan struct {
DurationIndex time.Duration // the call duration so far till TimeEnd
Increments Increments
MatchedSubject, MatchedPrefix, MatchedDestId, RatingPlanId string
CompressFactor int
}
type Increment struct {
@@ -60,7 +61,8 @@ type UnitInfo struct {
func (mi *UnitInfo) Equal(other *UnitInfo) bool {
return mi.DestinationId == other.DestinationId &&
mi.Quantity == other.Quantity
mi.Quantity == other.Quantity &&
mi.TOR == other.TOR
}
// Holds information about the balance that made a specific payment
@@ -162,31 +164,51 @@ func (timespans *TimeSpans) OverlapWithTimeSpans(paidTs TimeSpans, newTs *TimeSp
return false
}
func (tss TimeSpans) Compress() {
for _, ts := range tss {
var cIncrs Increments
for _, incr := range ts.Increments {
if len(cIncrs) == 0 || !cIncrs[len(cIncrs)-1].Equal(incr) {
incr.GetCompressFactor() // sideefect
cIncrs = append(cIncrs, incr)
} else {
cIncrs[len(cIncrs)-1].CompressFactor++
}
}
ts.Increments = cIncrs
func (tss *TimeSpans) Compress() { // must be pointer receiver
for _, ts := range *tss {
ts.Increments.Compress()
}
var cTss TimeSpans
for _, ts := range *tss {
if len(cTss) == 0 || !cTss[len(cTss)-1].Equal(ts) {
ts.GetCompressFactor() // sideefect
cTss = append(cTss, ts)
} else {
cTs := cTss[len(cTss)-1]
cTs.CompressFactor++
cTs.Cost += ts.Cost
cTs.TimeEnd = ts.TimeEnd
cTs.DurationIndex = ts.DurationIndex
}
}
*tss = cTss
}
func (tss TimeSpans) Decompress() {
for _, ts := range tss {
var incrs Increments
for _, cIncr := range ts.Increments {
for i := 0; i < cIncr.GetCompressFactor(); i++ {
incrs = append(incrs, cIncr.Clone())
}
}
ts.Increments = incrs
func (tss *TimeSpans) Decompress() { // must be pointer receiver
for _, ts := range *tss {
ts.Increments.Decompress()
}
var cTss TimeSpans
for _, cTs := range *tss {
var duration time.Duration
if cTs.GetCompressFactor() > 1 {
duration = cTs.GetUnitDuration()
}
for i := cTs.GetCompressFactor(); i > 1; i-- {
uTs := &TimeSpan{}
*uTs = *cTs // cloned by copy
uTs.TimeEnd = cTs.TimeStart.Add(duration)
uTs.DurationIndex = cTs.DurationIndex - time.Duration((i-1)*int(duration))
uTs.CompressFactor = 1
uTs.Cost = cTs.Cost / float64(cTs.GetCompressFactor())
cTs.TimeStart = uTs.TimeEnd
cTss = append(cTss, uTs)
}
cTs.Cost = cTs.GetUnitCost()
cTs.CompressFactor = 1
cTss = append(cTss, cTs)
}
*tss = cTss
}
func (incr *Increment) Clone() *Increment {
@@ -215,12 +237,48 @@ func (incr *Increment) GetCompressFactor() int {
return incr.CompressFactor
}
func (incr *Increment) GetCost() float64 {
return float64(incr.GetCompressFactor()) * incr.Cost
}
type Increments []*Increment
func (incs Increments) Equal(other Increments) bool {
for index, i := range incs {
if !i.Equal(other[index]) || i.GetCompressFactor() != other[index].GetCompressFactor() {
return false
}
}
return true
}
func (incs *Increments) Compress() { // must be pointer receiver
var cIncrs Increments
for _, incr := range *incs {
if len(cIncrs) == 0 || !cIncrs[len(cIncrs)-1].Equal(incr) {
incr.GetCompressFactor() // sideefect
cIncrs = append(cIncrs, incr)
} else {
cIncrs[len(cIncrs)-1].CompressFactor++
}
}
*incs = cIncrs
}
func (incs *Increments) Decompress() { // must be pointer receiver
var cIncrs Increments
for _, cIncr := range *incs {
for i := 0; i < cIncr.GetCompressFactor(); i++ {
cIncrs = append(cIncrs, cIncr.Clone())
}
}
*incs = cIncrs
}
func (incs Increments) GetTotalCost() float64 {
cost := 0.0
for _, increment := range incs {
cost += (float64(increment.GetCompressFactor()) * increment.Cost)
cost += increment.GetCost()
}
return cost
}
@@ -237,6 +295,15 @@ func (ts *TimeSpan) GetDuration() time.Duration {
return ts.TimeEnd.Sub(ts.TimeStart)
}
//Returns the duration of a unitary timespan in a compressed set
func (ts *TimeSpan) GetUnitDuration() time.Duration {
return time.Duration(int(ts.TimeEnd.Sub(ts.TimeStart)) / ts.GetCompressFactor())
}
func (ts *TimeSpan) GetUnitCost() float64 {
return ts.Cost / float64(ts.GetCompressFactor())
}
// Returns true if the given time is inside timespan range.
func (ts *TimeSpan) Contains(t time.Time) bool {
return t.After(ts.TimeStart) && t.Before(ts.TimeEnd)
@@ -573,3 +640,21 @@ func (ts *TimeSpan) hasBetterRateIntervalThan(interval *RateInterval) bool {
}
return true
}
func (ts *TimeSpan) Equal(other *TimeSpan) bool {
return ts.Increments.Equal(other.Increments) &&
ts.RateInterval.Equal(other.RateInterval) &&
ts.GetUnitCost() == other.GetUnitCost() &&
ts.GetUnitDuration() == other.GetUnitDuration() &&
ts.MatchedSubject == other.MatchedSubject &&
ts.MatchedPrefix == other.MatchedPrefix &&
ts.MatchedDestId == other.MatchedDestId &&
ts.RatingPlanId == other.RatingPlanId
}
func (ts *TimeSpan) GetCompressFactor() int {
if ts.CompressFactor == 0 {
ts.CompressFactor = 1
}
return ts.CompressFactor
}

View File

@@ -25,7 +25,7 @@ import (
"github.com/cgrates/cgrates/utils"
)
func TestRightMargin(t *testing.T) {
func TestTSRightMargin(t *testing.T) {
i := &RateInterval{
Timing: &RITiming{WeekDays: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday}}}
t1 := time.Date(2012, time.February, 3, 23, 45, 0, 0, time.UTC)
@@ -52,7 +52,7 @@ func TestRightMargin(t *testing.T) {
}
}
func TestSplitMiddle(t *testing.T) {
func TestTSSplitMiddle(t *testing.T) {
i := &RateInterval{
Timing: &RITiming{
WeekDays: utils.WeekDays{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday},
@@ -75,7 +75,7 @@ func TestSplitMiddle(t *testing.T) {
}
}
func TestRightHourMargin(t *testing.T) {
func TestTSRightHourMargin(t *testing.T) {
i := &RateInterval{Timing: &RITiming{WeekDays: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday}, EndTime: "17:59:00"}}
t1 := time.Date(2012, time.February, 3, 17, 30, 0, 0, time.UTC)
t2 := time.Date(2012, time.February, 3, 18, 00, 0, 0, time.UTC)
@@ -100,7 +100,7 @@ func TestRightHourMargin(t *testing.T) {
}
}
func TestLeftMargin(t *testing.T) {
func TestTSLeftMargin(t *testing.T) {
i := &RateInterval{Timing: &RITiming{WeekDays: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday}}}
t1 := time.Date(2012, time.February, 5, 23, 45, 0, 0, time.UTC)
t2 := time.Date(2012, time.February, 6, 0, 10, 0, 0, time.UTC)
@@ -124,7 +124,7 @@ func TestLeftMargin(t *testing.T) {
}
}
func TestLeftHourMargin(t *testing.T) {
func TestTSLeftHourMargin(t *testing.T) {
i := &RateInterval{Timing: &RITiming{Months: utils.Months{time.December}, MonthDays: utils.MonthDays{1}, StartTime: "09:00:00"}}
t1 := time.Date(2012, time.December, 1, 8, 45, 0, 0, time.UTC)
t2 := time.Date(2012, time.December, 1, 9, 20, 0, 0, time.UTC)
@@ -148,7 +148,7 @@ func TestLeftHourMargin(t *testing.T) {
}
}
func TestEnclosingMargin(t *testing.T) {
func TestTSEnclosingMargin(t *testing.T) {
i := &RateInterval{Timing: &RITiming{WeekDays: []time.Weekday{time.Sunday}}}
t1 := time.Date(2012, time.February, 5, 17, 45, 0, 0, time.UTC)
t2 := time.Date(2012, time.February, 5, 18, 10, 0, 0, time.UTC)
@@ -162,7 +162,7 @@ func TestEnclosingMargin(t *testing.T) {
}
}
func TestOutsideMargin(t *testing.T) {
func TestTSOutsideMargin(t *testing.T) {
i := &RateInterval{Timing: &RITiming{WeekDays: []time.Weekday{time.Monday}}}
t1 := time.Date(2012, time.February, 5, 17, 45, 0, 0, time.UTC)
t2 := time.Date(2012, time.February, 5, 18, 10, 0, 0, time.UTC)
@@ -173,7 +173,7 @@ func TestOutsideMargin(t *testing.T) {
}
}
func TestContains(t *testing.T) {
func TestTSContains(t *testing.T) {
t1 := time.Date(2012, time.February, 5, 17, 45, 0, 0, time.UTC)
t2 := time.Date(2012, time.February, 5, 17, 55, 0, 0, time.UTC)
t3 := time.Date(2012, time.February, 5, 17, 50, 0, 0, time.UTC)
@@ -189,7 +189,7 @@ func TestContains(t *testing.T) {
}
}
func TestSplitByRatingPlan(t *testing.T) {
func TestTSSplitByRatingPlan(t *testing.T) {
t1 := time.Date(2012, time.February, 5, 17, 45, 0, 0, time.UTC)
t2 := time.Date(2012, time.February, 5, 17, 55, 0, 0, time.UTC)
t3 := time.Date(2012, time.February, 5, 17, 50, 0, 0, time.UTC)
@@ -210,7 +210,7 @@ func TestSplitByRatingPlan(t *testing.T) {
}
}
func TestTimespanGetCost(t *testing.T) {
func TestTSTimespanGetCost(t *testing.T) {
t1 := time.Date(2012, time.February, 5, 17, 45, 0, 0, time.UTC)
t2 := time.Date(2012, time.February, 5, 17, 55, 0, 0, time.UTC)
ts1 := TimeSpan{TimeStart: t1, TimeEnd: t2}
@@ -233,7 +233,7 @@ func TestTimespanGetCost(t *testing.T) {
}
}
func TestTimespanGetCostIntervals(t *testing.T) {
func TestTSTimespanGetCostIntervals(t *testing.T) {
ts := &TimeSpan{}
ts.Increments = make(Increments, 11)
for i := 0; i < 11; i++ {
@@ -244,7 +244,7 @@ func TestTimespanGetCostIntervals(t *testing.T) {
}
}
func TestSetRateInterval(t *testing.T) {
func TestTSSetRateInterval(t *testing.T) {
i1 := &RateInterval{
Timing: &RITiming{},
Rating: &RIRate{Rates: RateGroups{&Rate{0, 1.0, 1 * time.Second, 1 * time.Second}}},
@@ -267,7 +267,7 @@ func TestSetRateInterval(t *testing.T) {
}
}
func TestTimespanSplitGroupedRates(t *testing.T) {
func TestTSTimespanSplitGroupedRates(t *testing.T) {
i := &RateInterval{
Timing: &RITiming{
EndTime: "17:59:00",
@@ -305,7 +305,7 @@ func TestTimespanSplitGroupedRates(t *testing.T) {
}
}
func TestTimespanSplitGroupedRatesIncrements(t *testing.T) {
func TestTSTimespanSplitGroupedRatesIncrements(t *testing.T) {
i := &RateInterval{
Timing: &RITiming{
EndTime: "17:59:00",
@@ -361,7 +361,7 @@ func TestTimespanSplitGroupedRatesIncrements(t *testing.T) {
}
}
func TestTimespanSplitRightHourMarginBeforeGroup(t *testing.T) {
func TestTSTimespanSplitRightHourMarginBeforeGroup(t *testing.T) {
i := &RateInterval{
Timing: &RITiming{
EndTime: "17:00:30",
@@ -398,7 +398,7 @@ func TestTimespanSplitRightHourMarginBeforeGroup(t *testing.T) {
}
}
func TestTimespanSplitGroupSecondSplit(t *testing.T) {
func TestTSTimespanSplitGroupSecondSplit(t *testing.T) {
i := &RateInterval{
Timing: &RITiming{
EndTime: "17:03:30",
@@ -445,7 +445,7 @@ func TestTimespanSplitGroupSecondSplit(t *testing.T) {
}
}
func TestTimespanSplitLong(t *testing.T) {
func TestTSTimespanSplitLong(t *testing.T) {
i := &RateInterval{
Timing: &RITiming{
StartTime: "18:00:00",
@@ -475,7 +475,7 @@ func TestTimespanSplitLong(t *testing.T) {
}
}
func TestTimespanSplitMultipleGroup(t *testing.T) {
func TestTSTimespanSplitMultipleGroup(t *testing.T) {
i := &RateInterval{
Timing: &RITiming{
EndTime: "17:05:00",
@@ -522,7 +522,7 @@ func TestTimespanSplitMultipleGroup(t *testing.T) {
}
}
func TestTimespanExpandingPastEnd(t *testing.T) {
func TestTSTimespanExpandingPastEnd(t *testing.T) {
timespans := []*TimeSpan{
&TimeSpan{
TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
@@ -546,7 +546,7 @@ func TestTimespanExpandingPastEnd(t *testing.T) {
}
}
func TestTimespanExpandingDurationIndex(t *testing.T) {
func TestTSTimespanExpandingDurationIndex(t *testing.T) {
timespans := []*TimeSpan{
&TimeSpan{
TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
@@ -568,7 +568,7 @@ func TestTimespanExpandingDurationIndex(t *testing.T) {
}
}
func TestTimespanExpandingRoundingPastEnd(t *testing.T) {
func TestTSTimespanExpandingRoundingPastEnd(t *testing.T) {
timespans := []*TimeSpan{
&TimeSpan{
TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
@@ -592,7 +592,7 @@ func TestTimespanExpandingRoundingPastEnd(t *testing.T) {
}
}
func TestTimespanExpandingPastEndMultiple(t *testing.T) {
func TestTSTimespanExpandingPastEndMultiple(t *testing.T) {
timespans := []*TimeSpan{
&TimeSpan{
TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
@@ -620,7 +620,7 @@ func TestTimespanExpandingPastEndMultiple(t *testing.T) {
}
}
func TestTimespanExpandingPastEndMultipleEqual(t *testing.T) {
func TestTSTimespanExpandingPastEndMultipleEqual(t *testing.T) {
timespans := []*TimeSpan{
&TimeSpan{
TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
@@ -648,7 +648,7 @@ func TestTimespanExpandingPastEndMultipleEqual(t *testing.T) {
}
}
func TestTimespanExpandingBeforeEnd(t *testing.T) {
func TestTSTimespanExpandingBeforeEnd(t *testing.T) {
timespans := []*TimeSpan{
&TimeSpan{
TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
@@ -674,7 +674,7 @@ func TestTimespanExpandingBeforeEnd(t *testing.T) {
}
}
func TestTimespanExpandingBeforeEndMultiple(t *testing.T) {
func TestTSTimespanExpandingBeforeEndMultiple(t *testing.T) {
timespans := []*TimeSpan{
&TimeSpan{
TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
@@ -704,7 +704,7 @@ func TestTimespanExpandingBeforeEndMultiple(t *testing.T) {
}
}
func TestTimespanCreateSecondsSlice(t *testing.T) {
func TestTSTimespanCreateSecondsSlice(t *testing.T) {
ts := &TimeSpan{
TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
TimeEnd: time.Date(2013, 9, 10, 14, 30, 30, 0, time.UTC),
@@ -721,7 +721,7 @@ func TestTimespanCreateSecondsSlice(t *testing.T) {
}
}
func TestTimespanCreateIncrements(t *testing.T) {
func TestTSTimespanCreateIncrements(t *testing.T) {
ts := &TimeSpan{
TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
TimeEnd: time.Date(2013, 9, 10, 14, 30, 30, 100000000, time.UTC),
@@ -747,7 +747,7 @@ func TestTimespanCreateIncrements(t *testing.T) {
}
}
func TestTimespanSplitByIncrement(t *testing.T) {
func TestTSTimespanSplitByIncrement(t *testing.T) {
ts := &TimeSpan{
TimeStart: time.Date(2013, 9, 19, 18, 30, 0, 0, time.UTC),
TimeEnd: time.Date(2013, 9, 19, 18, 31, 00, 0, time.UTC),
@@ -782,7 +782,7 @@ func TestTimespanSplitByIncrement(t *testing.T) {
}
}
func TestTimespanSplitByIncrementStart(t *testing.T) {
func TestTSTimespanSplitByIncrementStart(t *testing.T) {
ts := &TimeSpan{
TimeStart: time.Date(2013, 9, 19, 18, 30, 0, 0, time.UTC),
TimeEnd: time.Date(2013, 9, 19, 18, 31, 00, 0, time.UTC),
@@ -816,7 +816,7 @@ func TestTimespanSplitByIncrementStart(t *testing.T) {
}
}
func TestTimespanSplitByIncrementEnd(t *testing.T) {
func TestTSTimespanSplitByIncrementEnd(t *testing.T) {
ts := &TimeSpan{
TimeStart: time.Date(2013, 9, 19, 18, 30, 0, 0, time.UTC),
TimeEnd: time.Date(2013, 9, 19, 18, 31, 00, 0, time.UTC),
@@ -850,7 +850,7 @@ func TestTimespanSplitByIncrementEnd(t *testing.T) {
}
}
func TestTimespanSplitByDuration(t *testing.T) {
func TestTSTimespanSplitByDuration(t *testing.T) {
ts := &TimeSpan{
TimeStart: time.Date(2013, 9, 19, 18, 30, 0, 0, time.UTC),
TimeEnd: time.Date(2013, 9, 19, 18, 31, 00, 0, time.UTC),
@@ -888,7 +888,7 @@ func TestTimespanSplitByDuration(t *testing.T) {
}
}
func TestRemoveOverlapedFromIndexMiddle(t *testing.T) {
func TestTSRemoveOverlapedFromIndexMiddle(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
@@ -919,7 +919,7 @@ func TestRemoveOverlapedFromIndexMiddle(t *testing.T) {
}
}
func TestRemoveOverlapedFromIndexMiddleNonBounds(t *testing.T) {
func TestTSRemoveOverlapedFromIndexMiddleNonBounds(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
@@ -952,7 +952,7 @@ func TestRemoveOverlapedFromIndexMiddleNonBounds(t *testing.T) {
}
}
func TestRemoveOverlapedFromIndexMiddleNonBoundsOver(t *testing.T) {
func TestTSRemoveOverlapedFromIndexMiddleNonBoundsOver(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
@@ -984,7 +984,7 @@ func TestRemoveOverlapedFromIndexMiddleNonBoundsOver(t *testing.T) {
}
}
func TestRemoveOverlapedFromIndexEnd(t *testing.T) {
func TestTSRemoveOverlapedFromIndexEnd(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
@@ -1014,7 +1014,7 @@ func TestRemoveOverlapedFromIndexEnd(t *testing.T) {
}
}
func TestRemoveOverlapedFromIndexEndPast(t *testing.T) {
func TestTSRemoveOverlapedFromIndexEndPast(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
@@ -1044,7 +1044,7 @@ func TestRemoveOverlapedFromIndexEndPast(t *testing.T) {
}
}
func TestRemoveOverlapedFromIndexAll(t *testing.T) {
func TestTSRemoveOverlapedFromIndexAll(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
@@ -1073,7 +1073,7 @@ func TestRemoveOverlapedFromIndexAll(t *testing.T) {
}
}
func TestRemoveOverlapedFromIndexNone(t *testing.T) {
func TestTSRemoveOverlapedFromIndexNone(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
@@ -1105,7 +1105,7 @@ func TestRemoveOverlapedFromIndexNone(t *testing.T) {
}
}
func TestRemoveOverlapedFromIndexOne(t *testing.T) {
func TestTSRemoveOverlapedFromIndexOne(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
@@ -1122,7 +1122,7 @@ func TestRemoveOverlapedFromIndexOne(t *testing.T) {
}
}
func TestRemoveOverlapedFromIndexTwo(t *testing.T) {
func TestTSRemoveOverlapedFromIndexTwo(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
@@ -1143,7 +1143,7 @@ func TestRemoveOverlapedFromIndexTwo(t *testing.T) {
}
}
func TestOverlapWithTimeSpansMiddleLong(t *testing.T) {
func TestTSOverlapWithTimeSpansMiddleLong(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
@@ -1180,7 +1180,7 @@ func TestOverlapWithTimeSpansMiddleLong(t *testing.T) {
}
}
func TestOverlapWithTimeSpansMiddleMedium(t *testing.T) {
func TestTSOverlapWithTimeSpansMiddleMedium(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
@@ -1218,7 +1218,7 @@ func TestOverlapWithTimeSpansMiddleMedium(t *testing.T) {
}
}
func TestOverlapWithTimeSpansMiddleShort(t *testing.T) {
func TestTSOverlapWithTimeSpansMiddleShort(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
@@ -1257,7 +1257,7 @@ func TestOverlapWithTimeSpansMiddleShort(t *testing.T) {
}
}
func TestOverlapWithTimeSpansStart(t *testing.T) {
func TestTSOverlapWithTimeSpansStart(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
@@ -1294,7 +1294,7 @@ func TestOverlapWithTimeSpansStart(t *testing.T) {
}
}
func TestOverlapWithTimeSpansAlmostEnd(t *testing.T) {
func TestTSOverlapWithTimeSpansAlmostEnd(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
@@ -1333,7 +1333,7 @@ func TestOverlapWithTimeSpansAlmostEnd(t *testing.T) {
}
}
func TestOverlapWithTimeSpansEnd(t *testing.T) {
func TestTSOverlapWithTimeSpansEnd(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
@@ -1371,7 +1371,7 @@ func TestOverlapWithTimeSpansEnd(t *testing.T) {
}
}
func TestOverlapWithTimeSpansPastEnd(t *testing.T) {
func TestTSOverlapWithTimeSpansPastEnd(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
@@ -1409,7 +1409,7 @@ func TestOverlapWithTimeSpansPastEnd(t *testing.T) {
}
}
func TestOverlapWithTimeSpansAll(t *testing.T) {
func TestTSOverlapWithTimeSpansAll(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
@@ -1445,7 +1445,7 @@ func TestOverlapWithTimeSpansAll(t *testing.T) {
}
}
func TestOverlapWithTimeSpansAllPast(t *testing.T) {
func TestTSOverlapWithTimeSpansAllPast(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
@@ -1481,7 +1481,7 @@ func TestOverlapWithTimeSpansAllPast(t *testing.T) {
}
}
func TestOverlapWithTimeSpansOne(t *testing.T) {
func TestTSOverlapWithTimeSpansOne(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
@@ -1505,7 +1505,7 @@ func TestOverlapWithTimeSpansOne(t *testing.T) {
}
}
func TestTSCompressDecompress(t *testing.T) {
func TestTSIncrementsCompressDecompress(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
Increments: Increments{
@@ -1557,7 +1557,7 @@ func TestTSCompressDecompress(t *testing.T) {
}
}
func TestTSMultipleCompressDecompress(t *testing.T) {
func TestTSMultipleIncrementsCompressDecompress(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
Increments: Increments{
@@ -1694,3 +1694,150 @@ func TestTSBetterIntervalAgainAfter(t *testing.T) {
t.Error("Wrong better rate interval!")
}
}
func TestTSCompressDecompress(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
TimeStart: time.Date(2015, 1, 9, 16, 18, 0, 0, time.UTC),
TimeEnd: time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC),
Cost: 1.2,
DurationIndex: 1 * time.Minute,
},
&TimeSpan{
TimeStart: time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC),
TimeEnd: time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC),
Cost: 1.2,
DurationIndex: 2 * time.Minute,
},
&TimeSpan{
TimeStart: time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC),
TimeEnd: time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC),
Cost: 1.2,
DurationIndex: 3 * time.Minute,
},
&TimeSpan{
TimeStart: time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC),
TimeEnd: time.Date(2015, 1, 9, 16, 22, 0, 0, time.UTC),
Cost: 1.2,
DurationIndex: 4 * time.Minute,
},
}
tss.Compress()
if len(tss) != 1 ||
!tss[0].TimeStart.Equal(time.Date(2015, 1, 9, 16, 18, 0, 0, time.UTC)) ||
!tss[0].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 22, 0, 0, time.UTC)) ||
tss[0].DurationIndex != 4*time.Minute ||
tss[0].Cost != 4.8 ||
tss[0].CompressFactor != 4 {
for _, ts := range tss {
t.Logf("TS: %+v", ts)
}
t.Error("Error compressing timespans: ", tss)
}
tss.Decompress()
if len(tss) != 4 ||
!tss[0].TimeStart.Equal(time.Date(2015, 1, 9, 16, 18, 0, 0, time.UTC)) ||
!tss[0].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC)) ||
tss[0].DurationIndex != 1*time.Minute ||
tss[0].CompressFactor != 1 ||
tss[0].Cost != 1.2 ||
!tss[1].TimeStart.Equal(time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC)) ||
!tss[1].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC)) ||
tss[1].DurationIndex != 2*time.Minute ||
tss[1].CompressFactor != 1 ||
tss[1].Cost != 1.2 ||
!tss[2].TimeStart.Equal(time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC)) ||
!tss[2].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC)) ||
tss[2].DurationIndex != 3*time.Minute ||
tss[2].CompressFactor != 1 ||
tss[2].Cost != 1.2 ||
!tss[3].TimeStart.Equal(time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC)) ||
!tss[3].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 22, 0, 0, time.UTC)) ||
tss[3].DurationIndex != 4*time.Minute ||
tss[3].CompressFactor != 1 ||
tss[3].Cost != 1.2 {
for i, ts := range tss {
t.Logf("TS(%d): %+v", i, ts)
}
t.Error("Error decompressing timespans: ", tss)
}
}
func TestTSDifferentCompressDecompress(t *testing.T) {
tss := TimeSpans{
&TimeSpan{
TimeStart: time.Date(2015, 1, 9, 16, 18, 0, 0, time.UTC),
TimeEnd: time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC),
RateInterval: &RateInterval{Weight: 1},
Cost: 1.2,
DurationIndex: 1 * time.Minute,
},
&TimeSpan{
TimeStart: time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC),
TimeEnd: time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC),
RateInterval: &RateInterval{Weight: 2},
Cost: 1.2,
DurationIndex: 2 * time.Minute,
},
&TimeSpan{
TimeStart: time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC),
TimeEnd: time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC),
RateInterval: &RateInterval{Weight: 1},
Cost: 1.2,
DurationIndex: 3 * time.Minute,
},
&TimeSpan{
TimeStart: time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC),
TimeEnd: time.Date(2015, 1, 9, 16, 22, 0, 0, time.UTC),
RateInterval: &RateInterval{Weight: 1},
Cost: 1.2,
DurationIndex: 4 * time.Minute,
},
}
tss.Compress()
if len(tss) != 3 ||
!tss[0].TimeStart.Equal(time.Date(2015, 1, 9, 16, 18, 0, 0, time.UTC)) ||
!tss[0].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC)) ||
tss[0].DurationIndex != 1*time.Minute ||
tss[0].Cost != 1.2 ||
!tss[1].TimeStart.Equal(time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC)) ||
!tss[1].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC)) ||
tss[1].DurationIndex != 2*time.Minute ||
tss[1].Cost != 1.2 ||
!tss[2].TimeStart.Equal(time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC)) ||
!tss[2].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 22, 0, 0, time.UTC)) ||
tss[2].DurationIndex != 4*time.Minute ||
tss[2].Cost != 2.4 {
for _, ts := range tss {
t.Logf("TS: %+v", ts)
}
t.Error("Error compressing timespans: ", tss)
}
tss.Decompress()
if len(tss) != 4 ||
!tss[0].TimeStart.Equal(time.Date(2015, 1, 9, 16, 18, 0, 0, time.UTC)) ||
!tss[0].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC)) ||
tss[0].DurationIndex != 1*time.Minute ||
tss[0].CompressFactor != 1 ||
tss[0].Cost != 1.2 ||
!tss[1].TimeStart.Equal(time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC)) ||
!tss[1].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC)) ||
tss[1].DurationIndex != 2*time.Minute ||
tss[1].CompressFactor != 1 ||
tss[1].Cost != 1.2 ||
!tss[2].TimeStart.Equal(time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC)) ||
!tss[2].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC)) ||
tss[2].DurationIndex != 3*time.Minute ||
tss[2].CompressFactor != 1 ||
tss[2].Cost != 1.2 ||
!tss[3].TimeStart.Equal(time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC)) ||
!tss[3].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 22, 0, 0, time.UTC)) ||
tss[3].DurationIndex != 4*time.Minute ||
tss[3].CompressFactor != 1 ||
tss[3].Cost != 1.2 {
for i, ts := range tss {
t.Logf("TS(%d): %+v", i, ts)
}
t.Error("Error decompressing timespans: ", tss)
}
}

View File

@@ -205,6 +205,8 @@ func (s *Session) Refund(lastCC *engine.CallCost, hangupTime time.Time) error {
TOR: lastCC.TOR,
Increments: refundIncrements,
}
cd.Increments.Compress()
utils.Logger.Info(fmt.Sprintf("Refunding duration %v with cd: %+v", refundDuration, cd))
var response float64
err := s.sessionManager.Rater().Call("Responder.RefundIncrements", cd, &response)
if err != nil {
@@ -233,6 +235,7 @@ func (s *Session) SaveOperations() {
for _, cc := range sr.CallCosts[1:] {
firstCC.Merge(cc)
}
firstCC.Timespans.Compress()
var reply string
err := s.sessionManager.CdrSrv().Call("CdrServer.LogCallCost", &engine.CallCostLog{

View File

@@ -105,7 +105,7 @@ func TestSessionRefund(t *testing.T) {
cc := &engine.CallCost{Timespans: engine.TimeSpans{ts}}
hangupTime := time.Date(2015, 6, 10, 14, 7, 20, 0, time.UTC)
s.Refund(cc, hangupTime)
if len(mc.refundCd.Increments) != 10 || len(cc.Timespans) != 1 || cc.Timespans[0].TimeEnd != hangupTime {
if len(mc.refundCd.Increments) != 1 || mc.refundCd.Increments[0].GetCompressFactor() != 10 || len(cc.Timespans) != 1 || cc.Timespans[0].TimeEnd != hangupTime {
t.Errorf("Error refunding: %+v, %+v", mc.refundCd.Increments, cc.Timespans[0])
}
}
@@ -125,7 +125,7 @@ func TestSessionRefundAll(t *testing.T) {
cc := &engine.CallCost{Timespans: engine.TimeSpans{ts}}
hangupTime := time.Date(2015, 6, 10, 14, 7, 0, 0, time.UTC)
s.Refund(cc, hangupTime)
if len(mc.refundCd.Increments) != 30 || len(cc.Timespans) != 0 {
if len(mc.refundCd.Increments) != 1 || mc.refundCd.Increments[0].GetCompressFactor() != 30 || len(cc.Timespans) != 0 {
t.Errorf("Error refunding: %+v, %+v", len(mc.refundCd.Increments), cc.Timespans)
}
}
@@ -154,7 +154,7 @@ func TestSessionRefundManyAll(t *testing.T) {
cc := &engine.CallCost{Timespans: engine.TimeSpans{ts1, ts2}}
hangupTime := time.Date(2015, 6, 10, 14, 07, 0, 0, time.UTC)
s.Refund(cc, hangupTime)
if len(mc.refundCd.Increments) != 60 || len(cc.Timespans) != 0 {
if len(mc.refundCd.Increments) != 1 || mc.refundCd.Increments[0].GetCompressFactor() != 60 || len(cc.Timespans) != 0 {
t.Errorf("Error refunding: %+v, %+v", len(mc.refundCd.Increments), cc.Timespans)
}
}

View File

@@ -129,7 +129,7 @@ func TestSMGenericEventParseFields(t *testing.T) {
func TestSMGenericEventAsStoredCdr(t *testing.T) {
smGev := SMGenericEvent{}
smGev[utils.EVENT_NAME] = "TEST_EVENT"
smGev[utils.TOR] = utils.VOICE
smGev[utils.TOR] = utils.SMS
smGev[utils.ACCID] = "12345"
smGev[utils.DIRECTION] = utils.OUT
smGev[utils.ACCOUNT] = "account1"
@@ -148,7 +148,7 @@ func TestSMGenericEventAsStoredCdr(t *testing.T) {
smGev["Extra1"] = "Value1"
smGev["Extra2"] = 5
eStoredCdr := &engine.CDR{CGRID: "0711eaa78e53937f1593dabc08c83ea04a915f2e",
ToR: utils.VOICE, OriginID: "12345", OriginHost: "10.0.3.15", Source: "SMG_TEST_EVENT", RequestType: utils.META_PREPAID,
ToR: utils.SMS, OriginID: "12345", OriginHost: "10.0.3.15", Source: "SMG_TEST_EVENT", RequestType: utils.META_PREPAID,
Direction: utils.OUT, Tenant: "cgrates.org", Category: "call", Account: "account1", Subject: "subject1",
Destination: "+4986517174963", SetupTime: time.Date(2015, 11, 9, 14, 21, 24, 0, time.UTC), AnswerTime: time.Date(2015, 11, 9, 14, 22, 2, 0, time.UTC),
Usage: time.Duration(83) * time.Second, PDD: time.Duration(300) * time.Millisecond, Supplier: "supplier1", DisconnectCause: "NORMAL_DISCONNECT",

View File

@@ -156,6 +156,8 @@ func (self *SMGSession) refund(refundDuration time.Duration) error {
TOR: lastCC.TOR,
Increments: refundIncrements,
}
cd.Increments.Compress()
utils.Logger.Info(fmt.Sprintf("Refunding duration %v with cd: %+v", refundDuration, cd))
var response float64
err := self.rater.Call("Responder.RefundIncrements", cd, &response)
if err != nil {
@@ -170,10 +172,12 @@ func (self *SMGSession) refund(refundDuration time.Duration) error {
// Session has ended, check debits and refund the extra charged duration
func (self *SMGSession) close(endTime time.Time) error {
lastCC := self.callCosts[len(self.callCosts)-1]
end := lastCC.GetEndTime()
refundDuration := end.Sub(endTime)
self.refund(refundDuration)
if len(self.callCosts) != 0 { // We have had at least one cost calculation
lastCC := self.callCosts[len(self.callCosts)-1]
end := lastCC.GetEndTime()
refundDuration := end.Sub(endTime)
self.refund(refundDuration)
}
return nil
}
@@ -205,6 +209,7 @@ func (self *SMGSession) saveOperations() error {
for _, cc := range self.callCosts[1:] {
firstCC.Merge(cc)
}
firstCC.Timespans.Compress()
var reply string
err := self.cdrsrv.Call("CdrServer.LogCallCost", &engine.CallCostLog{
CgrId: self.eventStart.GetCgrId(self.timezone),