From 946a496a4660a299b76575fdcb6cb1063a5f60a3 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Wed, 24 Jul 2013 19:08:51 +0300 Subject: [PATCH] more tests for splitting --- engine/timespans.go | 20 ++++--- engine/timespans_test.go | 120 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 128 insertions(+), 12 deletions(-) diff --git a/engine/timespans.go b/engine/timespans.go index 23c968721..d0381bad9 100644 --- a/engine/timespans.go +++ b/engine/timespans.go @@ -20,6 +20,7 @@ package engine import ( "fmt" + "math" "time" ) @@ -114,10 +115,11 @@ func (ts *TimeSpan) SplitByInterval(i *Interval) (nts *TimeSpan) { ts.SetInterval(i) splitTime := ts.TimeStart.Add(time.Duration(price.StartSecond-ts.GetGroupStart()) * time.Second) nts = &TimeSpan{TimeStart: splitTime, TimeEnd: ts.TimeEnd} + ts.TimeEnd = splitTime nts.SetInterval(i) nts.CallDuration = ts.CallDuration - ts.CallDuration = ts.CallDuration - nts.GetDuration().Seconds() - ts.TimeEnd = splitTime + ts.CallDuration = math.Max(0, ts.CallDuration-nts.GetDuration().Seconds()) + return } } @@ -128,7 +130,7 @@ func (ts *TimeSpan) SplitByInterval(i *Interval) (nts *TimeSpan) { ts.SetInterval(i) return } - // if only the start time is in the interval split the interval + // if only the start time is in the interval split the interval to the right if i.Contains(ts.TimeStart) { //Logger.Debug("Start in interval") splitTime := i.getRightMargin(ts.TimeStart) @@ -138,10 +140,12 @@ func (ts *TimeSpan) SplitByInterval(i *Interval) (nts *TimeSpan) { } nts = &TimeSpan{TimeStart: splitTime, TimeEnd: ts.TimeEnd} ts.TimeEnd = splitTime + nts.CallDuration = ts.CallDuration + ts.CallDuration = math.Max(0, ts.CallDuration-nts.GetDuration().Seconds()) return } - // if only the end time is in the interval split the interval + // if only the end time is in the interval split the interval to the left if i.Contains(ts.TimeEnd) { //Logger.Debug("End in interval") splitTime := i.getLeftMargin(ts.TimeEnd) @@ -152,6 +156,9 @@ func (ts *TimeSpan) SplitByInterval(i *Interval) (nts *TimeSpan) { ts.TimeEnd = splitTime nts.SetInterval(i) + nts.CallDuration = ts.CallDuration + ts.CallDuration = math.Max(0, ts.CallDuration-nts.GetDuration().Seconds()) + return } return @@ -203,10 +210,7 @@ func (ts *TimeSpan) SplitByMinuteBucket(mb *MinuteBucket) (newTs *TimeSpan) { } func (ts *TimeSpan) GetGroupStart() float64 { - if ts.CallDuration == 0 { - return 0 - } - return ts.CallDuration - ts.GetDuration().Seconds() + return math.Max(0, ts.CallDuration-ts.GetDuration().Seconds()) } func (ts *TimeSpan) GetGroupEnd() float64 { diff --git a/engine/timespans_test.go b/engine/timespans_test.go index af229d9c1..a3c8db967 100644 --- a/engine/timespans_test.go +++ b/engine/timespans_test.go @@ -332,17 +332,18 @@ func TestTimespanSplitByMinuteBucketScarceExpiringDifferentScarceFirst(t *testin func TestTimespanSplitGroupedRates(t *testing.T) { i := &Interval{ EndTime: "17:59:00", - Prices: PriceGroups{&Price{0, 1, 1}, &Price{900, 2, 1}}, + Prices: PriceGroups{&Price{0, 2, 1}, &Price{900, 1, 1}}, } 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) ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, CallDuration: 1800} oldDuration := ts.GetDuration() nts := ts.SplitByInterval(i) - if ts.TimeStart != t1 || ts.TimeEnd != time.Date(2012, time.February, 3, 17, 45, 00, 0, time.UTC) { + splitTime := time.Date(2012, time.February, 3, 17, 45, 00, 0, time.UTC) + if ts.TimeStart != t1 || ts.TimeEnd != splitTime { t.Error("Incorrect first half", ts) } - if nts.TimeStart != time.Date(2012, time.February, 3, 17, 45, 00, 0, time.UTC) || nts.TimeEnd != t2 { + if nts.TimeStart != splitTime || nts.TimeEnd != t2 { t.Error("Incorrect second half", nts) } if ts.Interval != i { @@ -350,7 +351,7 @@ func TestTimespanSplitGroupedRates(t *testing.T) { } c1 := ts.Interval.GetCost(ts.GetDuration().Seconds(), ts.GetGroupStart()) c2 := nts.Interval.GetCost(nts.GetDuration().Seconds(), nts.GetGroupStart()) - if c1 != 900 || c2 != 1800 { + if c1 != 1800 || c2 != 900 { t.Error("Wrong costs: ", c1, c2) } @@ -361,3 +362,114 @@ func TestTimespanSplitGroupedRates(t *testing.T) { t.Errorf("The duration has changed: %v + %v != %v", ts.GetDuration().Seconds(), nts.GetDuration().Seconds(), oldDuration.Seconds()) } } + +func TestTimespanSplitGroupedRatesIncrements(t *testing.T) { + i := &Interval{ + EndTime: "17:59:00", + Prices: PriceGroups{&Price{0, 2, 1}, &Price{30, 1, 60}}, + } + t1 := time.Date(2012, time.February, 3, 17, 30, 0, 0, time.UTC) + t2 := time.Date(2012, time.February, 3, 17, 31, 0, 0, time.UTC) + ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, CallDuration: 60} + oldDuration := ts.GetDuration() + nts := ts.SplitByInterval(i) + splitTime := time.Date(2012, time.February, 3, 17, 30, 30, 0, time.UTC) + if ts.TimeStart != t1 || ts.TimeEnd != splitTime { + t.Error("Incorrect first half", ts) + } + if nts.TimeStart != splitTime || nts.TimeEnd != t2 { + t.Error("Incorrect second half", nts) + } + if ts.Interval != i { + t.Error("Interval not attached correctly") + } + c1 := ts.Interval.GetCost(ts.GetDuration().Seconds(), ts.GetGroupStart()) + c2 := nts.Interval.GetCost(nts.GetDuration().Seconds(), nts.GetGroupStart()) + if c1 != 60 || c2 != 60 { + t.Error("Wrong costs: ", c1, c2) + } + + if ts.GetDuration().Seconds() != 0.5*60 || nts.GetDuration().Seconds() != 0.5*60 { + t.Error("Wrong durations.for Intervals", ts.GetDuration().Seconds(), nts.GetDuration().Seconds()) + } + if ts.GetDuration().Seconds()+nts.GetDuration().Seconds() != oldDuration.Seconds() { + t.Errorf("The duration has changed: %v + %v != %v", ts.GetDuration().Seconds(), nts.GetDuration().Seconds(), oldDuration.Seconds()) + } +} + +func TestTimespanSplitRightHourMarginBeforeGroup(t *testing.T) { + i := &Interval{ + EndTime: "17:00:30", + Prices: PriceGroups{&Price{0, 2, 1}, &Price{60, 1, 60}}, + } + t1 := time.Date(2012, time.February, 3, 17, 00, 0, 0, time.UTC) + t2 := time.Date(2012, time.February, 3, 17, 01, 0, 0, time.UTC) + ts := &TimeSpan{TimeStart: t1, TimeEnd: t2} + oldDuration := ts.GetDuration() + nts := ts.SplitByInterval(i) + splitTime := time.Date(2012, time.February, 3, 17, 00, 30, 0, time.UTC) + if ts.TimeStart != t1 || ts.TimeEnd != splitTime { + t.Error("Incorrect first half", ts) + } + if nts.TimeStart != splitTime || nts.TimeEnd != t2 { + t.Error("Incorrect second half", nts) + } + if ts.Interval != i { + t.Error("Interval not attached correctly") + } + + if ts.GetDuration().Seconds() != 30 || nts.GetDuration().Seconds() != 30 { + t.Error("Wrong durations.for Intervals", ts.GetDuration().Seconds(), nts.GetDuration().Seconds()) + } + if ts.GetDuration().Seconds()+nts.GetDuration().Seconds() != oldDuration.Seconds() { + t.Errorf("The duration has changed: %v + %v != %v", ts.GetDuration().Seconds(), nts.GetDuration().Seconds(), oldDuration.Seconds()) + } + nnts := nts.SplitByInterval(i) + if nnts != nil { + t.Error("Bad new split", nnts) + } +} + +func TestTimespanSplitGroupSecondSplit(t *testing.T) { + i := &Interval{ + EndTime: "17:03:30", + Prices: PriceGroups{&Price{0, 2, 1}, &Price{60, 1, 1}}, + } + t1 := time.Date(2012, time.February, 3, 17, 00, 0, 0, time.UTC) + t2 := time.Date(2012, time.February, 3, 17, 04, 0, 0, time.UTC) + ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, CallDuration: 240} + oldDuration := ts.GetDuration() + nts := ts.SplitByInterval(i) + splitTime := time.Date(2012, time.February, 3, 17, 01, 00, 0, time.UTC) + if ts.TimeStart != t1 || ts.TimeEnd != splitTime { + t.Error("Incorrect first half", nts) + } + if nts.TimeStart != splitTime || nts.TimeEnd != t2 { + t.Error("Incorrect second half", nts) + } + if ts.Interval != i { + t.Error("Interval not attached correctly") + } + + if ts.GetDuration().Seconds() != 60 || nts.GetDuration().Seconds() != 180 { + t.Error("Wrong durations.for Intervals", ts.GetDuration().Seconds(), nts.GetDuration().Seconds()) + } + if ts.GetDuration().Seconds()+nts.GetDuration().Seconds() != oldDuration.Seconds() { + t.Errorf("The duration has changed: %v + %v != %v", ts.GetDuration().Seconds(), nts.GetDuration().Seconds(), oldDuration.Seconds()) + } + nnts := nts.SplitByInterval(i) + nsplitTime := time.Date(2012, time.February, 3, 17, 03, 30, 0, time.UTC) + if nts.TimeStart != splitTime || nts.TimeEnd != nsplitTime { + t.Error("Incorrect first half", nts) + } + if nnts.TimeStart != nsplitTime || nnts.TimeEnd != t2 { + t.Error("Incorrect second half", nnts) + } + if nts.Interval != i { + t.Error("Interval not attached correctly") + } + + if nts.GetDuration().Seconds() != 150 || nnts.GetDuration().Seconds() != 30 { + t.Error("Wrong durations.for Intervals", nts.GetDuration().Seconds(), nnts.GetDuration().Seconds()) + } +}