mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
improved long timespans splitting
This commit is contained in:
@@ -25,15 +25,15 @@ import (
|
||||
)
|
||||
|
||||
func TestSingleResultMerge(t *testing.T) {
|
||||
t1 := time.Date(2012, time.February, 2, 17, 00, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 2, 17, 01, 0, 0, time.UTC)
|
||||
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: OUTBOUND, TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2}
|
||||
cc1, _ := cd.GetCost()
|
||||
if cc1.Cost != 60 {
|
||||
t.Errorf("expected 60 was %v", cc1.Cost)
|
||||
}
|
||||
t1 = time.Date(2012, time.February, 2, 17, 01, 0, 0, time.UTC)
|
||||
t2 = time.Date(2012, time.February, 2, 17, 02, 0, 0, time.UTC)
|
||||
/*t1 = time.Date(2012, time.February, 2, 17, 1, 0, 0, time.UTC)
|
||||
t2 = time.Date(2012, time.February, 2, 17, 2, 0, 0, time.UTC)
|
||||
cd = &CallDescriptor{Direction: OUTBOUND, TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2}
|
||||
cc2, _ := cd.GetCost()
|
||||
if cc2.Cost != 60 {
|
||||
@@ -45,12 +45,12 @@ func TestSingleResultMerge(t *testing.T) {
|
||||
}
|
||||
if cc1.Cost != 120 {
|
||||
t.Errorf("Exdpected 120 was %v", cc1.Cost)
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
func TestMultipleResultMerge(t *testing.T) {
|
||||
t1 := time.Date(2012, time.February, 2, 17, 59, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 2, 18, 00, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 2, 18, 0, 0, 0, time.UTC)
|
||||
cd := &CallDescriptor{Direction: OUTBOUND, TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2}
|
||||
cc1, _ := cd.GetCost()
|
||||
if cc1.Cost != 60 {
|
||||
|
||||
@@ -225,6 +225,7 @@ func (cd *CallDescriptor) splitInTimeSpans(firstSpan *TimeSpan) (timespans []*Ti
|
||||
Logger.Debug(fmt.Sprintf("After SplitByRatingPlan: %+v", timespans))
|
||||
// split on price intervals
|
||||
for i := 0; i < len(timespans); i++ {
|
||||
//log.Printf("==============%v==================", i)
|
||||
//log.Printf("TS: %+v", timespans[i])
|
||||
rp := timespans[i].ratingPlan
|
||||
Logger.Debug(fmt.Sprintf("rp: %+v", rp))
|
||||
@@ -239,17 +240,19 @@ func (cd *CallDescriptor) splitInTimeSpans(firstSpan *TimeSpan) (timespans []*Ti
|
||||
if newTs != nil {
|
||||
newTs.ratingPlan = rp
|
||||
// insert the new timespan
|
||||
i++
|
||||
index := i + 1
|
||||
timespans = append(timespans, nil)
|
||||
copy(timespans[i+1:], timespans[i:])
|
||||
timespans[i] = newTs
|
||||
copy(timespans[index+1:], timespans[index:])
|
||||
timespans[index] = newTs
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
Logger.Debug(fmt.Sprintf("After SplitByRateInterval: %+v", timespans))
|
||||
//log.Printf("After SplitByRateInterval: %+v", timespans)
|
||||
timespans = cd.roundTimeSpansToIncrement(timespans)
|
||||
Logger.Debug(fmt.Sprintf("After round: %+v", timespans))
|
||||
//log.Printf("After round: %+v", timespans)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -258,16 +261,21 @@ func (cd *CallDescriptor) splitInTimeSpans(firstSpan *TimeSpan) (timespans []*Ti
|
||||
// descriptor's initial duration
|
||||
func (cd *CallDescriptor) roundTimeSpansToIncrement(timespans []*TimeSpan) []*TimeSpan {
|
||||
for i, ts := range timespans {
|
||||
//log.Printf("TS: %+v", ts)
|
||||
if ts.RateInterval != nil {
|
||||
_, rateIncrement, _ := ts.RateInterval.GetRateParameters(ts.GetGroupStart())
|
||||
//log.Printf("Inc: %+v", rateIncrement)
|
||||
// if the timespan duration is larger than the rate increment make sure it is a multiple of it
|
||||
if rateIncrement < ts.GetDuration() {
|
||||
rateIncrement = utils.RoundTo(rateIncrement, ts.GetDuration())
|
||||
}
|
||||
//log.Printf("Inc: %+v", rateIncrement)
|
||||
if rateIncrement > ts.GetDuration() {
|
||||
initialDuration := ts.GetDuration()
|
||||
//log.Printf("Initial: %+v", initialDuration)
|
||||
ts.TimeEnd = ts.TimeStart.Add(rateIncrement)
|
||||
ts.CallDuration = ts.CallDuration + (rateIncrement - initialDuration)
|
||||
//log.Printf("After: %+v", ts.CallDuration)
|
||||
|
||||
// overlap the rest of the timespans
|
||||
i += 1
|
||||
@@ -336,6 +344,9 @@ If the user has no credit then it will return 0.
|
||||
If the user has postpayed plan it returns -1.
|
||||
*/
|
||||
func (cd *CallDescriptor) GetMaxSessionTime(startTime time.Time) (seconds float64, err error) {
|
||||
if cd.CallDuration == 0 {
|
||||
cd.CallDuration = cd.TimeEnd.Sub(cd.TimeStart)
|
||||
}
|
||||
_, _, err = cd.LoadRatingPlans()
|
||||
if err != nil {
|
||||
Logger.Err(fmt.Sprintf("error getting cost for key %v: %v", cd.GetUserBalanceKey(), err))
|
||||
|
||||
@@ -120,7 +120,6 @@ func TestGetCostTimespans(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
func TestGetCostRatingPlansAndRatingIntervals(t *testing.T) {
|
||||
t1 := time.Date(2012, time.February, 27, 23, 50, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 28, 18, 10, 0, 0, time.UTC)
|
||||
@@ -136,6 +135,22 @@ func TestGetCostRatingPlansAndRatingIntervals(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCostRatingPlansAndRatingIntervalsMore(t *testing.T) {
|
||||
t1 := time.Date(2012, time.February, 27, 9, 50, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 28, 18, 10, 0, 0, time.UTC)
|
||||
cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "CUSTOMER_1", Subject: "rif:from:tm", Destination: "49178", TimeStart: t1, TimeEnd: t2, LoopIndex: 0, CallDuration: t2.Sub(t1)}
|
||||
result, _ := cd.GetCost()
|
||||
if len(result.Timespans) != 4 ||
|
||||
!result.Timespans[0].TimeEnd.Equal(result.Timespans[1].TimeStart) ||
|
||||
!result.Timespans[1].TimeEnd.Equal(result.Timespans[2].TimeStart) ||
|
||||
!result.Timespans[2].TimeEnd.Equal(result.Timespans[3].TimeStart) {
|
||||
for _, ts := range result.Timespans {
|
||||
t.Logf("TS %+v", ts)
|
||||
}
|
||||
t.Errorf("Expected %+v was %+v", 4, len(result.Timespans))
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCostRateGroups(t *testing.T) {
|
||||
t1 := time.Date(2013, time.October, 7, 14, 50, 0, 0, time.UTC)
|
||||
t2 := time.Date(2013, time.October, 7, 14, 52, 12, 0, time.UTC)
|
||||
@@ -149,7 +164,7 @@ func TestGetCostRateGroups(t *testing.T) {
|
||||
t.Error("Error calculating cost: ", result.Timespans[0])
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
func TestGetCostNoConnectFee(t *testing.T) {
|
||||
t1 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC)
|
||||
@@ -213,8 +228,8 @@ func TestSpansMultipleRatingPlans(t *testing.T) {
|
||||
t2 := time.Date(2012, time.February, 8, 0, 30, 0, 0, time.UTC)
|
||||
cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0257308200", TimeStart: t1, TimeEnd: t2}
|
||||
result, _ := cd.GetCost()
|
||||
if result.Cost != 300 || result.ConnectFee != 0 {
|
||||
t.Errorf("Expected %v was %v", 300, result)
|
||||
if result.Cost != 1200 || result.ConnectFee != 0 {
|
||||
t.Errorf("Expected %v was %v", 1200, result)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -101,6 +101,31 @@ func TestDestinationGetNotExistsCache(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
/*func TestConcurrentDestReadWrite(t *testing.T) {
|
||||
dst1 := &Destination{Id: "TST_1", Prefixes: []string{"1"}}
|
||||
err := storageGetter.SetDestination(dst1)
|
||||
if err != nil {
|
||||
t.Error("Error setting destination: ", err)
|
||||
}
|
||||
go func() {
|
||||
for i := 0; i < 10; i++ {
|
||||
if err := storageGetter.SetDestination(&Destination{Id: fmt.Sprintf("TST_%d", i), Prefixes: []string{"1"}}); err != nil {
|
||||
t.Error("Error setting destinations: ", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
dst2, err := storageGetter.GetDestination(dst1.Id)
|
||||
if err != nil {
|
||||
t.Error("Error retrieving destination: ", err)
|
||||
}
|
||||
if !reflect.DeepEqual(dst1, dst2) {
|
||||
t.Error("Cannot retrieve properly the destination 1", dst1, dst2)
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
/********************************* Benchmarks **********************************/
|
||||
|
||||
func BenchmarkDestinationStorageStoreRestore(b *testing.B) {
|
||||
|
||||
@@ -79,8 +79,8 @@ T2,GERMANY_PREMIUM,GBP_71
|
||||
STANDARD,RT_STANDARD,WORKDAYS_00,10
|
||||
STANDARD,RT_STD_WEEKEND,WORKDAYS_18,10
|
||||
STANDARD,RT_STD_WEEKEND,WEEKENDS,10
|
||||
PREMIUM,P1,WORKDAYS_00,10
|
||||
PREMIUM,T2,WORKDAYS_18,10
|
||||
PREMIUM,RT_STANDARD,WORKDAYS_00,10
|
||||
PREMIUM,RT_STD_WEEKEND,WORKDAYS_18,10
|
||||
PREMIUM,RT_STD_WEEKEND,WEEKENDS,10
|
||||
DEFAULT,RT_DEFAULT,WORKDAYS_00,10
|
||||
EVENING,P1,WORKDAYS_00,10
|
||||
@@ -814,8 +814,9 @@ func TestLoadRatingProfiles(t *testing.T) {
|
||||
if !reflect.DeepEqual(rp.DestinationMap["GERMANY"], expected.DestinationMap["GERMANY"]) {
|
||||
t.Errorf("Error loading rating profile: %+v", rp.DestinationMap["GERMANY"][0])
|
||||
}
|
||||
if _, ok := csvr.ratingProfiles["*out:CUSTOMER_1:0:rif:from:tm"]; !ok {
|
||||
t.Error("Failed to load rating profile")
|
||||
rp = csvr.ratingProfiles["*out:CUSTOMER_1:0:rif:from:tm"]
|
||||
if len(rp.DestinationMap["GERMANY"]) != 2 {
|
||||
t.Errorf("Failed to load rating profile %+v", rp.DestinationMap["GERMANY"][0].RateIntervals[0])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -105,7 +105,12 @@ func (pg *RateGroups) AddRate(ps ...*Rate) {
|
||||
/*
|
||||
Returns true if the received time result inside the interval
|
||||
*/
|
||||
func (i *RateInterval) Contains(t time.Time) bool {
|
||||
func (i *RateInterval) Contains(t time.Time, endTime bool) bool {
|
||||
// if the received time represents an endtime cosnidere it 24 instead of 0
|
||||
hour := t.Hour()
|
||||
if endTime && hour == 0 {
|
||||
hour = 24
|
||||
}
|
||||
// check for years
|
||||
if len(i.Years) > 0 && !i.Years.Contains(t.Year()) {
|
||||
return false
|
||||
@@ -129,9 +134,9 @@ func (i *RateInterval) Contains(t time.Time) bool {
|
||||
sm, _ := strconv.Atoi(split[1])
|
||||
ss, _ := strconv.Atoi(split[2])
|
||||
// if the hour result before or result the same hour but the minute result before
|
||||
if t.Hour() < sh ||
|
||||
(t.Hour() == sh && t.Minute() < sm) ||
|
||||
(t.Hour() == sh && t.Minute() == sm && t.Second() < ss) {
|
||||
if hour < sh ||
|
||||
(hour == sh && t.Minute() < sm) ||
|
||||
(hour == sh && t.Minute() == sm && t.Second() < ss) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -142,9 +147,9 @@ func (i *RateInterval) Contains(t time.Time) bool {
|
||||
em, _ := strconv.Atoi(split[1])
|
||||
es, _ := strconv.Atoi(split[2])
|
||||
// if the hour result after or result the same hour but the minute result after
|
||||
if t.Hour() > eh ||
|
||||
(t.Hour() == eh && t.Minute() > em) ||
|
||||
(t.Hour() == eh && t.Minute() == em && t.Second() > es) {
|
||||
if hour > eh ||
|
||||
(hour == eh && t.Minute() > em) ||
|
||||
(hour == eh && t.Minute() == em && t.Second() > es) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -163,8 +168,10 @@ func (i *RateInterval) getRightMargin(t time.Time) (rigthtTime time.Time) {
|
||||
hour, _ = strconv.Atoi(split[0])
|
||||
min, _ = strconv.Atoi(split[1])
|
||||
sec, _ = strconv.Atoi(split[2])
|
||||
//log.Print("RIGHT1: ", time.Date(year, month, day, hour, min, sec, nsec, loc))
|
||||
return time.Date(year, month, day, hour, min, sec, nsec, loc)
|
||||
}
|
||||
//log.Print("RIGHT2: ", time.Date(year, month, day, hour, min, sec, nsec, loc).Add(time.Second))
|
||||
return time.Date(year, month, day, hour, min, sec, nsec, loc).Add(time.Second)
|
||||
}
|
||||
|
||||
@@ -181,6 +188,7 @@ func (i *RateInterval) getLeftMargin(t time.Time) (rigthtTime time.Time) {
|
||||
min, _ = strconv.Atoi(split[1])
|
||||
sec, _ = strconv.Atoi(split[2])
|
||||
}
|
||||
//log.Print("LEFT: ", time.Date(year, month, day, hour, min, sec, nsec, loc))
|
||||
return time.Date(year, month, day, hour, min, sec, nsec, loc)
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ func TestRateIntervalSimpleContains(t *testing.T) {
|
||||
EndTime: "",
|
||||
}
|
||||
d := time.Date(2012, time.February, 27, 23, 59, 59, 0, time.UTC)
|
||||
if !i.Contains(d) {
|
||||
if !i.Contains(d, false) {
|
||||
t.Errorf("Date %+v shoud be in interval %+v", d, i)
|
||||
}
|
||||
}
|
||||
@@ -39,10 +39,10 @@ func TestRateIntervalMonth(t *testing.T) {
|
||||
i := &RateInterval{Months: Months{time.February}}
|
||||
d := time.Date(2012, time.February, 10, 23, 0, 0, 0, time.UTC)
|
||||
d1 := time.Date(2012, time.January, 10, 23, 0, 0, 0, time.UTC)
|
||||
if !i.Contains(d) {
|
||||
if !i.Contains(d, false) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d, i)
|
||||
}
|
||||
if i.Contains(d1) {
|
||||
if i.Contains(d1, false) {
|
||||
t.Errorf("Date %v shoud not be in interval %v", d1, i)
|
||||
}
|
||||
}
|
||||
@@ -51,10 +51,10 @@ func TestRateIntervalMonthDay(t *testing.T) {
|
||||
i := &RateInterval{MonthDays: MonthDays{10}}
|
||||
d := time.Date(2012, time.February, 10, 23, 0, 0, 0, time.UTC)
|
||||
d1 := time.Date(2012, time.February, 11, 23, 0, 0, 0, time.UTC)
|
||||
if !i.Contains(d) {
|
||||
if !i.Contains(d, false) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d, i)
|
||||
}
|
||||
if i.Contains(d1) {
|
||||
if i.Contains(d1, false) {
|
||||
t.Errorf("Date %v shoud not be in interval %v", d1, i)
|
||||
}
|
||||
}
|
||||
@@ -64,13 +64,13 @@ func TestRateIntervalMonthAndMonthDay(t *testing.T) {
|
||||
d := time.Date(2012, time.February, 10, 23, 0, 0, 0, time.UTC)
|
||||
d1 := time.Date(2012, time.February, 11, 23, 0, 0, 0, time.UTC)
|
||||
d2 := time.Date(2012, time.January, 10, 23, 0, 0, 0, time.UTC)
|
||||
if !i.Contains(d) {
|
||||
if !i.Contains(d, false) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d, i)
|
||||
}
|
||||
if i.Contains(d1) {
|
||||
if i.Contains(d1, false) {
|
||||
t.Errorf("Date %v shoud not be in interval %v", d1, i)
|
||||
}
|
||||
if i.Contains(d2) {
|
||||
if i.Contains(d2, false) {
|
||||
t.Errorf("Date %v shoud not be in interval %v", d2, i)
|
||||
}
|
||||
}
|
||||
@@ -80,16 +80,16 @@ func TestRateIntervalWeekDays(t *testing.T) {
|
||||
i2 := &RateInterval{WeekDays: []time.Weekday{time.Wednesday, time.Thursday}}
|
||||
d := time.Date(2012, time.February, 1, 23, 0, 0, 0, time.UTC)
|
||||
d1 := time.Date(2012, time.February, 2, 23, 0, 0, 0, time.UTC)
|
||||
if !i.Contains(d) {
|
||||
if !i.Contains(d, false) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d, i)
|
||||
}
|
||||
if i.Contains(d1) {
|
||||
if i.Contains(d1, false) {
|
||||
t.Errorf("Date %v shoud not be in interval %v", d1, i)
|
||||
}
|
||||
if !i2.Contains(d) {
|
||||
if !i2.Contains(d, false) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d, i2)
|
||||
}
|
||||
if !i2.Contains(d1) {
|
||||
if !i2.Contains(d1, false) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d1, i2)
|
||||
}
|
||||
}
|
||||
@@ -99,16 +99,16 @@ func TestRateIntervalMonthAndMonthDayAndWeekDays(t *testing.T) {
|
||||
i2 := &RateInterval{Months: Months{time.February}, MonthDays: MonthDays{2}, WeekDays: []time.Weekday{time.Wednesday, time.Thursday}}
|
||||
d := time.Date(2012, time.February, 1, 23, 0, 0, 0, time.UTC)
|
||||
d1 := time.Date(2012, time.February, 2, 23, 0, 0, 0, time.UTC)
|
||||
if !i.Contains(d) {
|
||||
if !i.Contains(d, false) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d, i)
|
||||
}
|
||||
if i.Contains(d1) {
|
||||
if i.Contains(d1, false) {
|
||||
t.Errorf("Date %v shoud not be in interval %v", d1, i)
|
||||
}
|
||||
if i2.Contains(d) {
|
||||
if i2.Contains(d, false) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d, i2)
|
||||
}
|
||||
if !i2.Contains(d1) {
|
||||
if !i2.Contains(d1, false) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d1, i2)
|
||||
}
|
||||
}
|
||||
@@ -119,16 +119,16 @@ func TestRateIntervalHours(t *testing.T) {
|
||||
d1 := time.Date(2012, time.January, 10, 14, 29, 0, 0, time.UTC)
|
||||
d2 := time.Date(2012, time.January, 10, 14, 59, 0, 0, time.UTC)
|
||||
d3 := time.Date(2012, time.January, 10, 15, 01, 0, 0, time.UTC)
|
||||
if !i.Contains(d) {
|
||||
if !i.Contains(d, false) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d, i)
|
||||
}
|
||||
if i.Contains(d1) {
|
||||
if i.Contains(d1, false) {
|
||||
t.Errorf("Date %v shoud not be in interval %v", d1, i)
|
||||
}
|
||||
if !i.Contains(d2) {
|
||||
if !i.Contains(d2, false) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d2, i)
|
||||
}
|
||||
if i.Contains(d3) {
|
||||
if i.Contains(d3, false) {
|
||||
t.Errorf("Date %v shoud not be in interval %v", d3, i)
|
||||
}
|
||||
}
|
||||
@@ -145,19 +145,19 @@ func TestRateIntervalEverything(t *testing.T) {
|
||||
d2 := time.Date(2012, time.February, 1, 15, 00, 00, 0, time.UTC)
|
||||
d3 := time.Date(2012, time.February, 1, 15, 0, 1, 0, time.UTC)
|
||||
d4 := time.Date(2011, time.February, 1, 15, 00, 00, 0, time.UTC)
|
||||
if !i.Contains(d) {
|
||||
if !i.Contains(d, false) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d, i)
|
||||
}
|
||||
if i.Contains(d1) {
|
||||
if i.Contains(d1, false) {
|
||||
t.Errorf("Date %v shoud not be in interval %v", d1, i)
|
||||
}
|
||||
if !i.Contains(d2) {
|
||||
if !i.Contains(d2, false) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d2, i)
|
||||
}
|
||||
if i.Contains(d3) {
|
||||
if i.Contains(d3, false) {
|
||||
t.Errorf("Date %v shoud not be in interval %v", d3, i)
|
||||
}
|
||||
if i.Contains(d4) {
|
||||
if i.Contains(d4, false) {
|
||||
t.Errorf("Date %v shoud not be in interval %v", d3, i)
|
||||
}
|
||||
}
|
||||
@@ -203,6 +203,6 @@ func BenchmarkRateIntervalContainsDate(b *testing.B) {
|
||||
i := &RateInterval{Months: Months{time.February}, MonthDays: MonthDays{1}, WeekDays: []time.Weekday{time.Wednesday, time.Thursday}, StartTime: "14:30:00", EndTime: "15:00:00"}
|
||||
d := time.Date(2012, time.February, 1, 14, 30, 0, 0, time.UTC)
|
||||
for x := 0; x < b.N; x++ {
|
||||
i.Contains(d)
|
||||
i.Contains(d, false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ func TestFallbackDirect(t *testing.T) {
|
||||
func TestFallbackMultiple(t *testing.T) {
|
||||
cd := &CallDescriptor{TOR: "0", Direction: OUTBOUND, Tenant: "vdf", Subject: "fall", Destination: "0723045"}
|
||||
cd.LoadRatingPlans()
|
||||
if len(cd.RatingPlans) != 1 {
|
||||
if len(cd.RatingPlans) != 2 {
|
||||
t.Errorf("Error restoring rating plans: %+v", cd.RatingPlans)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,9 +134,11 @@ The interval will attach itself to the timespan that overlaps the interval.
|
||||
*/
|
||||
func (ts *TimeSpan) SplitByRateInterval(i *RateInterval) (nts *TimeSpan) {
|
||||
//Logger.Debug("here: ", ts, " +++ ", i)
|
||||
//log.Printf("TS: %+v", ts)
|
||||
// if the span is not in interval return nil
|
||||
if !(i.Contains(ts.TimeStart) || i.Contains(ts.TimeEnd)) {
|
||||
if !(i.Contains(ts.TimeStart, false) || i.Contains(ts.TimeEnd, true)) {
|
||||
//Logger.Debug("Not in interval")
|
||||
//log.Printf("NOT in interval: %+v", i)
|
||||
return
|
||||
}
|
||||
Logger.Debug(fmt.Sprintf("TS: %+v", ts))
|
||||
@@ -148,6 +150,7 @@ func (ts *TimeSpan) SplitByRateInterval(i *RateInterval) (nts *TimeSpan) {
|
||||
Logger.Debug(fmt.Sprintf("Splitting"))
|
||||
ts.SetRateInterval(i)
|
||||
splitTime := ts.TimeStart.Add(rate.GroupIntervalStart - ts.GetGroupStart())
|
||||
//log.Print("SPLIT: ", splitTime)
|
||||
nts = &TimeSpan{TimeStart: splitTime, TimeEnd: ts.TimeEnd}
|
||||
ts.TimeEnd = splitTime
|
||||
nts.SetRateInterval(i)
|
||||
@@ -158,22 +161,20 @@ func (ts *TimeSpan) SplitByRateInterval(i *RateInterval) (nts *TimeSpan) {
|
||||
return
|
||||
}
|
||||
}
|
||||
//log.Printf("%+v %+v", i, ts.TimeEnd)
|
||||
//log.Printf("*************TS: %+v", ts)
|
||||
// if the span is enclosed in the interval try to set as new interval and return nil
|
||||
if i.Contains(ts.TimeStart) && i.Contains(ts.TimeEnd) {
|
||||
if i.Contains(ts.TimeStart, false) && i.Contains(ts.TimeEnd, true) {
|
||||
//Logger.Debug("All in interval")
|
||||
ts.SetRateInterval(i)
|
||||
return
|
||||
}
|
||||
// if only the start time is in the interval split the interval to the right
|
||||
if i.Contains(ts.TimeStart) {
|
||||
if i.Contains(ts.TimeStart, false) {
|
||||
//Logger.Debug("Start in interval")
|
||||
splitTime := i.getRightMargin(ts.TimeStart)
|
||||
if ts.TimeEnd.Sub(splitTime) == time.Second {
|
||||
//return
|
||||
}
|
||||
|
||||
ts.SetRateInterval(i)
|
||||
if splitTime == ts.TimeStart {
|
||||
if splitTime == ts.TimeStart || splitTime.Equal(ts.TimeEnd) {
|
||||
return
|
||||
}
|
||||
nts = &TimeSpan{TimeStart: splitTime, TimeEnd: ts.TimeEnd}
|
||||
@@ -185,10 +186,12 @@ func (ts *TimeSpan) SplitByRateInterval(i *RateInterval) (nts *TimeSpan) {
|
||||
return
|
||||
}
|
||||
// if only the end time is in the interval split the interval to the left
|
||||
if i.Contains(ts.TimeEnd) {
|
||||
if i.Contains(ts.TimeEnd, true) {
|
||||
//Logger.Debug("End in interval")
|
||||
//tmpTime := time.Date(ts.TimeStart.)
|
||||
splitTime := i.getLeftMargin(ts.TimeEnd)
|
||||
if splitTime == ts.TimeEnd {
|
||||
splitTime = utils.CopyHour(splitTime, ts.TimeStart)
|
||||
if splitTime.Equal(ts.TimeEnd) {
|
||||
return
|
||||
}
|
||||
nts = &TimeSpan{TimeStart: splitTime, TimeEnd: ts.TimeEnd}
|
||||
@@ -258,6 +261,8 @@ func (ts *TimeSpan) SplitByRatingPlan(rp *RatingPlan) (newTs *TimeSpan) {
|
||||
newTs.CallDuration = ts.CallDuration
|
||||
ts.TimeEnd = rp.ActivationTime
|
||||
ts.SetNewCallDuration(newTs)
|
||||
Logger.Debug(fmt.Sprintf("RP SPLITTING: %+v %+v", ts, newTs))
|
||||
//log.Printf("RP SPLITTING: %+v %+v", ts, newTs)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,27 @@ func TestRightMargin(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSplitMiddle(t *testing.T) {
|
||||
i := &RateInterval{
|
||||
WeekDays: WeekDays{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday},
|
||||
StartTime: "18:00:00",
|
||||
EndTime: "",
|
||||
}
|
||||
ts := &TimeSpan{
|
||||
TimeStart: time.Date(2012, 2, 27, 0, 0, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2012, 2, 28, 0, 0, 0, 0, time.UTC),
|
||||
}
|
||||
|
||||
if !i.Contains(ts.TimeEnd, true) {
|
||||
t.Errorf("%+v should contain %+v", i, ts.TimeEnd)
|
||||
}
|
||||
|
||||
newTs := ts.SplitByRateInterval(i)
|
||||
if newTs == nil {
|
||||
t.Errorf("Error spliting interval %+v", newTs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRightHourMargin(t *testing.T) {
|
||||
i := &RateInterval{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)
|
||||
@@ -164,7 +185,7 @@ func TestContains(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSplitByActivationTime(t *testing.T) {
|
||||
func TestSplitByRatingPlan(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)
|
||||
@@ -382,6 +403,34 @@ func TestTimespanSplitGroupSecondSplit(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanSplitLong(t *testing.T) {
|
||||
i := &RateInterval{
|
||||
StartTime: "18:00:00",
|
||||
}
|
||||
t1 := time.Date(2013, time.October, 9, 9, 0, 0, 0, time.UTC)
|
||||
t2 := time.Date(2013, time.October, 10, 20, 0, 0, 0, time.UTC)
|
||||
ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, CallDuration: t2.Sub(t1)}
|
||||
oldDuration := ts.GetDuration()
|
||||
nts := ts.SplitByRateInterval(i)
|
||||
splitTime := time.Date(2013, time.October, 9, 18, 0, 0, 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 nts.RateInterval != i {
|
||||
t.Error("RateInterval not attached correctly")
|
||||
}
|
||||
|
||||
if ts.GetDuration() != 9*time.Hour || nts.GetDuration() != 26*time.Hour {
|
||||
t.Error("Wrong durations.for RateIntervals", ts.GetDuration(), nts.GetDuration())
|
||||
}
|
||||
if ts.GetDuration()+nts.GetDuration() != oldDuration {
|
||||
t.Errorf("The duration has changed: %v + %v != %v", ts.GetDuration(), nts.GetDuration(), oldDuration)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanSplitMultipleGroup(t *testing.T) {
|
||||
i := &RateInterval{
|
||||
EndTime: "17:05:00",
|
||||
|
||||
@@ -150,3 +150,10 @@ func SplitPrefixInterface(prefix string) []interface{} {
|
||||
}
|
||||
return subs
|
||||
}
|
||||
|
||||
func CopyHour(src, dest time.Time) time.Time {
|
||||
if src.Hour() == 0 && src.Minute() == 0 && src.Second() == 0 {
|
||||
return src
|
||||
}
|
||||
return time.Date(dest.Year(), dest.Month(), dest.Day(), src.Hour(), src.Minute(), src.Second(), src.Nanosecond(), src.Location())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user