mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
more tests
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/fsouza/gokabinet/kc"
|
||||
"flag"
|
||||
"time"
|
||||
"github.com/rif/cgrates/timespans"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -15,33 +15,33 @@ var (
|
||||
func main() {
|
||||
flag.Parse()
|
||||
db, _ := kc.Open(*filename, kc.WRITE)
|
||||
defer db.Close()
|
||||
defer db.Close()
|
||||
|
||||
t1 := time.Date(2012, time.January, 1, 0, 0, 0, 0, time.UTC)
|
||||
cd1 := ×pans.CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256"}
|
||||
ap1 := ×pans.ActivationPeriod{ActivationTime: t1}
|
||||
ap1 := ×pans.ActivationPeriod{ActivationTime: t1}
|
||||
ap1.AddInterval(×pans.Interval{
|
||||
WeekDays: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday},
|
||||
EndTime:"18:00:00",
|
||||
ConnectFee: 0,
|
||||
Price: 0.2,
|
||||
WeekDays: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday},
|
||||
EndTime: "18:00:00",
|
||||
ConnectFee: 0,
|
||||
Price: 0.2,
|
||||
BillingUnit: 1.0})
|
||||
ap1.AddInterval(×pans.Interval{
|
||||
WeekDays: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday},
|
||||
StartTime:"18:00:00",
|
||||
ConnectFee: 0,
|
||||
Price: 0.1,
|
||||
BillingUnit: 1.0})
|
||||
WeekDays: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday},
|
||||
StartTime: "18:00:00",
|
||||
ConnectFee: 0,
|
||||
Price: 0.1,
|
||||
BillingUnit: 1.0})
|
||||
ap1.AddInterval(×pans.Interval{
|
||||
WeekDays: []time.Weekday{time.Saturday, time.Sunday},
|
||||
ConnectFee: 0,
|
||||
Price: 0.1,
|
||||
WeekDays: []time.Weekday{time.Saturday, time.Sunday},
|
||||
ConnectFee: 0,
|
||||
Price: 0.1,
|
||||
BillingUnit: 1.0})
|
||||
cd1.AddActivationPeriod(ap1)
|
||||
key := cd1.GetKey()
|
||||
key := cd1.GetKey()
|
||||
|
||||
value := cd1.EncodeValues()
|
||||
|
||||
db.Set(key, string(value))
|
||||
fmt.Println("Done!")
|
||||
|
||||
db.Set(key, string(value))
|
||||
fmt.Println("Done!")
|
||||
}
|
||||
|
||||
@@ -1,42 +1,50 @@
|
||||
package timespans
|
||||
|
||||
import ("time"; "encoding/json"; "fmt"; "log")
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
/*
|
||||
The output structure that will be returned with the call cost information.
|
||||
*/
|
||||
type CallCost struct {
|
||||
TOR int
|
||||
TOR int
|
||||
CstmId, Subject, DestinationPrefix string
|
||||
Cost, ConnectFee float64
|
||||
// ratesInfo *RatingProfile
|
||||
Cost, ConnectFee float64
|
||||
// ratesInfo *RatingProfile
|
||||
}
|
||||
|
||||
/*
|
||||
The struture that is saved to storage.
|
||||
*/
|
||||
type ActivationPeriod struct {
|
||||
ActivationTime time.Time
|
||||
Intervals []*Interval
|
||||
Intervals []*Interval
|
||||
}
|
||||
|
||||
func (ap *ActivationPeriod) AddInterval( is ...*Interval) {
|
||||
func (ap *ActivationPeriod) AddInterval(is ...*Interval) {
|
||||
for _, i := range is {
|
||||
ap.Intervals = append(ap.Intervals, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
The input stucture that contains call information.
|
||||
*/
|
||||
type CallDescriptor struct {
|
||||
TOR int
|
||||
TOR int
|
||||
CstmId, Subject, DestinationPrefix string
|
||||
TimeStart, TimeEnd time.Time
|
||||
ActivationPeriods []*ActivationPeriod
|
||||
TimeStart, TimeEnd time.Time
|
||||
ActivationPeriods []*ActivationPeriod
|
||||
}
|
||||
|
||||
func (cd *CallDescriptor) AddActivationPeriod(aps ...*ActivationPeriod) {
|
||||
func (cd *CallDescriptor) AddActivationPeriod(aps ...*ActivationPeriod) {
|
||||
for _, ap := range aps {
|
||||
cd.ActivationPeriods = append(cd.ActivationPeriods, ap)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (cd *CallDescriptor) EncodeValues() []byte {
|
||||
@@ -55,50 +63,50 @@ func (cd *CallDescriptor) decodeValues(v []byte) {
|
||||
err := json.Unmarshal(v, &cd.ActivationPeriods)
|
||||
if err != nil {
|
||||
log.Print("Cannot decode intervals: ", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (cd *CallDescriptor) getActiveIntervals() (is []*Interval) {
|
||||
func (cd *CallDescriptor) getActiveIntervals() (is []*Interval) {
|
||||
now := time.Now()
|
||||
// add a second in the future to be able to pick the active timestamp
|
||||
// from the very second it becomes active
|
||||
sec,_ := time.ParseDuration("1s")
|
||||
now.Add(sec)
|
||||
sec, _ := time.ParseDuration("1s")
|
||||
now.Add(sec)
|
||||
bestTime := time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)
|
||||
for _, ap := range cd.ActivationPeriods {
|
||||
t := ap.ActivationTime
|
||||
if t.After(bestTime) && t.Before(now) {
|
||||
bestTime = t
|
||||
is = ap.Intervals
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
func (cd *CallDescriptor) splitInTimeSpans(intervals []*Interval) (timespans []*TimeSpan) {
|
||||
ts1 := &TimeSpan{TimeStart: cd.TimeStart, TimeEnd: cd.TimeEnd}
|
||||
timespans = append(timespans, ts1)
|
||||
timespans = append(timespans, ts1)
|
||||
for _, interval := range intervals {
|
||||
for _, ts := range timespans {
|
||||
newTs := interval.Split(ts)
|
||||
if newTs != nil {
|
||||
for _, ts := range timespans {
|
||||
newTs := interval.Split(ts)
|
||||
if newTs != nil {
|
||||
timespans = append(timespans, newTs)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
func (cd *CallDescriptor) GetCost(sg StorageGetter) (result *CallCost, err error) {
|
||||
|
||||
*/
|
||||
func (cd *CallDescriptor) GetCost(sg StorageGetter) (result *CallCost, err error) {
|
||||
|
||||
key := cd.GetKey()
|
||||
values, err := sg.Get(key)
|
||||
|
||||
|
||||
cd.decodeValues([]byte(values))
|
||||
|
||||
|
||||
intervals := cd.getActiveIntervals()
|
||||
timespans := cd.splitInTimeSpans(intervals)
|
||||
|
||||
@@ -107,11 +115,10 @@ func (cd *CallDescriptor) GetCost(sg StorageGetter) (result *CallCost, err error
|
||||
cost += ts.GetCost()
|
||||
}
|
||||
cc := &CallCost{TOR: cd.TOR,
|
||||
CstmId: cd.CstmId,
|
||||
Subject: cd.Subject,
|
||||
DestinationPrefix: cd.DestinationPrefix,
|
||||
Cost: cost,
|
||||
ConnectFee: timespans[0].Interval.ConnectFee}
|
||||
CstmId: cd.CstmId,
|
||||
Subject: cd.Subject,
|
||||
DestinationPrefix: cd.DestinationPrefix,
|
||||
Cost: cost,
|
||||
ConnectFee: timespans[0].Interval.ConnectFee}
|
||||
return cc, err
|
||||
}
|
||||
|
||||
|
||||
@@ -1,53 +1,68 @@
|
||||
package timespans
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestSplitSpans(t *testing.T){
|
||||
func TestSplitSpans(t *testing.T) {
|
||||
getter, _ := NewKyotoStorage("test.kch")
|
||||
defer getter.Close()
|
||||
|
||||
|
||||
t1 := time.Date(2012, time.February, 02, 17, 30, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 02, 18, 30, 0, 0, time.UTC)
|
||||
cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", TimeStart: t1, TimeEnd: t2}
|
||||
key := cd.GetKey()
|
||||
values, _ := getter.Get(key)
|
||||
|
||||
|
||||
cd.decodeValues([]byte(values))
|
||||
|
||||
|
||||
intervals := cd.getActiveIntervals()
|
||||
timespans := cd.splitInTimeSpans(intervals)
|
||||
if len(timespans) != 2 {
|
||||
t.Error("Wrong number of timespans: ", len(timespans))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ATestGetCost(t *testing.T){
|
||||
func ATestGetCost(t *testing.T) {
|
||||
getter, _ := NewKyotoStorage("test.kch")
|
||||
defer getter.Close()
|
||||
|
||||
|
||||
t1 := time.Date(2012, time.February, 02, 17, 30, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 02, 18, 30, 0, 0, time.UTC)
|
||||
cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", TimeStart: t1, TimeEnd: t2}
|
||||
result,_ := cd.GetCost(getter)
|
||||
result, _ := cd.GetCost(getter)
|
||||
expected := &CallCost{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", Cost: 360, ConnectFee: 0}
|
||||
if *result != *expected {
|
||||
t.Errorf("Expected %v was %v", expected, result)
|
||||
}
|
||||
t.Errorf("Expected %v was %v", expected, result)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetCost(b *testing.B) {
|
||||
func BenchmarkGetCost(b *testing.B) {
|
||||
b.StopTimer()
|
||||
getter, _ := NewKyotoStorage("test.kch")
|
||||
defer getter.Close()
|
||||
|
||||
|
||||
t1 := time.Date(2012, time.February, 02, 17, 30, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 02, 18, 30, 0, 0, time.UTC)
|
||||
cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", TimeStart: t1, TimeEnd: t2}
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
cd.GetCost(getter)
|
||||
}
|
||||
for i := 0; i < b.N; i++ {
|
||||
cd.GetCost(getter)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecoding(b *testing.B) {
|
||||
b.StopTimer()
|
||||
getter, _ := NewKyotoStorage("test.kch")
|
||||
defer getter.Close()
|
||||
|
||||
cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256"}
|
||||
key := cd.GetKey()
|
||||
values, _ := getter.Get(key)
|
||||
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
cd.decodeValues([]byte(values))
|
||||
}
|
||||
}
|
||||
@@ -1,89 +1,89 @@
|
||||
package timespans
|
||||
|
||||
import (
|
||||
"time"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestMonth(t *testing.T){
|
||||
func TestMonth(t *testing.T) {
|
||||
i := &Interval{Month: 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) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d, i)
|
||||
}
|
||||
}
|
||||
if i.Contains(d1) {
|
||||
t.Errorf("Date %v shoud not be in interval %v", d1, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMonthDay(t *testing.T){
|
||||
func TestMonthDay(t *testing.T) {
|
||||
i := &Interval{MonthDay: 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) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d, i)
|
||||
}
|
||||
}
|
||||
if i.Contains(d1) {
|
||||
t.Errorf("Date %v shoud not be in interval %v", d1, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMonthAndMonthDay(t *testing.T){
|
||||
func TestMonthAndMonthDay(t *testing.T) {
|
||||
i := &Interval{Month: time.February, MonthDay: 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)
|
||||
d2 := time.Date(2012, time.January, 10, 23, 0, 0, 0, time.UTC)
|
||||
if !i.Contains(d) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d, i)
|
||||
}
|
||||
}
|
||||
if i.Contains(d1) {
|
||||
t.Errorf("Date %v shoud not be in interval %v", d1, i)
|
||||
}
|
||||
}
|
||||
if i.Contains(d2) {
|
||||
t.Errorf("Date %v shoud not be in interval %v", d2, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWeekDays(t *testing.T){
|
||||
func TestWeekDays(t *testing.T) {
|
||||
i := &Interval{WeekDays: []time.Weekday{time.Wednesday}}
|
||||
i2 := &Interval{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) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d, i)
|
||||
}
|
||||
}
|
||||
if i.Contains(d1) {
|
||||
t.Errorf("Date %v shoud not be in interval %v", d1, i)
|
||||
}
|
||||
}
|
||||
if !i2.Contains(d) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d, i2)
|
||||
}
|
||||
}
|
||||
if !i2.Contains(d1) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d1, i2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMonthAndMonthDayAndWeekDays(t *testing.T){
|
||||
func TestMonthAndMonthDayAndWeekDays(t *testing.T) {
|
||||
i := &Interval{Month: time.February, MonthDay: 1, WeekDays: []time.Weekday{time.Wednesday}}
|
||||
i2 := &Interval{Month: time.February, MonthDay: 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) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d, i)
|
||||
}
|
||||
}
|
||||
if i.Contains(d1) {
|
||||
t.Errorf("Date %v shoud not be in interval %v", d1, i)
|
||||
}
|
||||
}
|
||||
if i2.Contains(d) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d, i2)
|
||||
}
|
||||
}
|
||||
if !i2.Contains(d1) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d1, i2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHours(t *testing.T){
|
||||
func TestHours(t *testing.T) {
|
||||
i := &Interval{StartTime: "14:30:00", EndTime: "15:00:00"}
|
||||
d := time.Date(2012, time.February, 10, 14, 30, 1, 0, time.UTC)
|
||||
d1 := time.Date(2012, time.January, 10, 14, 29, 0, 0, time.UTC)
|
||||
@@ -91,43 +91,43 @@ func TestHours(t *testing.T){
|
||||
d3 := time.Date(2012, time.January, 10, 15, 01, 0, 0, time.UTC)
|
||||
if !i.Contains(d) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d, i)
|
||||
}
|
||||
}
|
||||
if i.Contains(d1) {
|
||||
t.Errorf("Date %v shoud not be in interval %v", d1, i)
|
||||
}
|
||||
}
|
||||
if !i.Contains(d2) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d2, i)
|
||||
}
|
||||
}
|
||||
if i.Contains(d3) {
|
||||
t.Errorf("Date %v shoud not be in interval %v", d3, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEverything(t *testing.T){
|
||||
func TestEverything(t *testing.T) {
|
||||
i := &Interval{Month: time.February,
|
||||
MonthDay: 1,
|
||||
WeekDays: []time.Weekday{time.Wednesday, time.Thursday},
|
||||
StartTime: "14:30:00",
|
||||
EndTime: "15:00:00"}
|
||||
MonthDay: 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, 1, 0, time.UTC)
|
||||
d1 := time.Date(2012, time.February, 1, 14, 29, 1, 0, time.UTC)
|
||||
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)
|
||||
if !i.Contains(d) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d, i)
|
||||
}
|
||||
}
|
||||
if i.Contains(d1) {
|
||||
t.Errorf("Date %v shoud not be in interval %v", d1, i)
|
||||
}
|
||||
}
|
||||
if !i.Contains(d2) {
|
||||
t.Errorf("Date %v shoud be in interval %v", d2, i)
|
||||
}
|
||||
}
|
||||
if i.Contains(d3) {
|
||||
t.Errorf("Date %v shoud not be in interval %v", d3, i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRightMargin(t *testing.T){
|
||||
func TestRightMargin(t *testing.T) {
|
||||
i := &Interval{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)
|
||||
t2 := time.Date(2012, time.February, 4, 0, 10, 0, 0, time.UTC)
|
||||
@@ -144,22 +144,22 @@ func TestRightMargin(t *testing.T){
|
||||
t.Error("Interval not attached correctly")
|
||||
}
|
||||
|
||||
if ts.GetDuration().Seconds() != 15 * 60 - 1 || nts.GetDuration().Seconds() != 10 * 60 + 1 {
|
||||
if ts.GetDuration().Seconds() != 15*60-1 || nts.GetDuration().Seconds() != 10*60+1 {
|
||||
t.Error("Wrong durations.for Intervals", ts.GetDuration().Seconds(), ts.GetDuration().Seconds())
|
||||
}
|
||||
|
||||
if ts.GetDuration().Seconds() + nts.GetDuration().Seconds() != oldDuration.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 TestRightHourMargin(t *testing.T){
|
||||
func TestRightHourMargin(t *testing.T) {
|
||||
i := &Interval{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)
|
||||
ts := &TimeSpan{TimeStart: t1, TimeEnd: t2}
|
||||
oldDuration := ts.GetDuration()
|
||||
nts := i.Split(ts)
|
||||
nts := i.Split(ts)
|
||||
if ts.TimeStart != t1 || ts.TimeEnd != time.Date(2012, time.February, 3, 17, 59, 00, 0, time.UTC) {
|
||||
t.Error("Incorrect first half", ts)
|
||||
}
|
||||
@@ -170,21 +170,21 @@ func TestRightHourMargin(t *testing.T){
|
||||
t.Error("Interval not attached correctly")
|
||||
}
|
||||
|
||||
if ts.GetDuration().Seconds() != 29 * 60 || nts.GetDuration().Seconds() != 1 * 60 {
|
||||
if ts.GetDuration().Seconds() != 29*60 || nts.GetDuration().Seconds() != 1*60 {
|
||||
t.Error("Wrong durations.for Intervals", ts.GetDuration().Seconds(), nts.GetDuration().Seconds())
|
||||
}
|
||||
if ts.GetDuration().Seconds() + nts.GetDuration().Seconds() != oldDuration.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 TestLeftMargin(t *testing.T){
|
||||
func TestLeftMargin(t *testing.T) {
|
||||
i := &Interval{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)
|
||||
ts := &TimeSpan{TimeStart: t1, TimeEnd: t2}
|
||||
oldDuration := ts.GetDuration()
|
||||
nts := i.Split(ts)
|
||||
nts := i.Split(ts)
|
||||
if ts.TimeStart != t1 || ts.TimeEnd != time.Date(2012, time.February, 6, 0, 0, 0, 0, time.UTC) {
|
||||
t.Error("Incorrect first half", ts)
|
||||
}
|
||||
@@ -194,21 +194,21 @@ func TestLeftMargin(t *testing.T){
|
||||
if nts.Interval != i {
|
||||
t.Error("Interval not attached correctly")
|
||||
}
|
||||
if ts.GetDuration().Seconds() != 15 * 60 || nts.GetDuration().Seconds() != 10 * 60 {
|
||||
if ts.GetDuration().Seconds() != 15*60 || nts.GetDuration().Seconds() != 10*60 {
|
||||
t.Error("Wrong durations.for Intervals", ts.GetDuration().Seconds(), nts.GetDuration().Seconds())
|
||||
}
|
||||
if ts.GetDuration().Seconds() + nts.GetDuration().Seconds() != oldDuration.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 TestLeftHourMargin(t *testing.T){
|
||||
func TestLeftHourMargin(t *testing.T) {
|
||||
i := &Interval{Month: time.December, MonthDay: 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)
|
||||
ts := &TimeSpan{TimeStart: t1, TimeEnd: t2}
|
||||
oldDuration := ts.GetDuration()
|
||||
nts := i.Split(ts)
|
||||
nts := i.Split(ts)
|
||||
if ts.TimeStart != t1 || ts.TimeEnd != time.Date(2012, time.December, 1, 9, 0, 0, 0, time.UTC) {
|
||||
t.Error("Incorrect first half", ts)
|
||||
}
|
||||
@@ -218,43 +218,43 @@ func TestLeftHourMargin(t *testing.T){
|
||||
if nts.Interval != i {
|
||||
t.Error("Interval not attached correctly")
|
||||
}
|
||||
if ts.GetDuration().Seconds() != 15 * 60 || nts.GetDuration().Seconds() != 20 * 60 {
|
||||
if ts.GetDuration().Seconds() != 15*60 || nts.GetDuration().Seconds() != 20*60 {
|
||||
t.Error("Wrong durations.for Intervals", ts.GetDuration().Seconds(), nts.GetDuration().Seconds())
|
||||
}
|
||||
if ts.GetDuration().Seconds() + nts.GetDuration().Seconds() != oldDuration.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 TestEnclosingMargin(t *testing.T){
|
||||
func TestEnclosingMargin(t *testing.T) {
|
||||
i := &Interval{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)
|
||||
ts := &TimeSpan{TimeStart: t1, TimeEnd: t2}
|
||||
nts := i.Split(ts)
|
||||
if ts.TimeStart != t1 || ts.TimeEnd != t2 || nts != nil{
|
||||
nts := i.Split(ts)
|
||||
if ts.TimeStart != t1 || ts.TimeEnd != t2 || nts != nil {
|
||||
t.Error("Incorrect enclosing", ts)
|
||||
}
|
||||
}
|
||||
if ts.Interval != i {
|
||||
t.Error("Interval not attached correctly")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOutsideMargin(t *testing.T){
|
||||
func TestOutsideMargin(t *testing.T) {
|
||||
i := &Interval{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)
|
||||
ts := &TimeSpan{TimeStart: t1, TimeEnd: t2}
|
||||
result := i.Split(ts)
|
||||
result := i.Split(ts)
|
||||
if result != nil {
|
||||
t.Error("Interval not split correctly")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIntervalFull(b *testing.B) {
|
||||
i := &Interval{Month: time.February, MonthDay: 1, WeekDays: []time.Weekday{time.Wednesday, time.Thursday}, StartTime: "14:30:00", EndTime: "15:00"}
|
||||
i := &Interval{Month: time.February, MonthDay: 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)
|
||||
}
|
||||
}
|
||||
for x := 0; x < b.N; x++ {
|
||||
i.Contains(d)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
package timespans
|
||||
|
||||
import (
|
||||
"time"
|
||||
"strings"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
/*
|
||||
Defines a time interval for which a certain set of prices will apply
|
||||
*/
|
||||
type Interval struct {
|
||||
Month time.Month
|
||||
MonthDay int
|
||||
WeekDays []time.Weekday
|
||||
StartTime, EndTime string // ##:##:## format
|
||||
Month time.Month
|
||||
MonthDay int
|
||||
WeekDays []time.Weekday
|
||||
StartTime, EndTime string // ##:##:## format
|
||||
Ponder, ConnectFee, Price, BillingUnit float64
|
||||
}
|
||||
|
||||
@@ -22,33 +22,33 @@ Returns true if the received time is inside the interval
|
||||
*/
|
||||
func (i *Interval) Contains(t time.Time) bool {
|
||||
// chec for month
|
||||
if i.Month > 0 && t.Month() != i.Month {
|
||||
if i.Month > 0 && t.Month() != i.Month {
|
||||
return false
|
||||
}
|
||||
}
|
||||
// check for month day
|
||||
if i.MonthDay > 0 && t.Day() != i.MonthDay {
|
||||
if i.MonthDay > 0 && t.Day() != i.MonthDay {
|
||||
return false
|
||||
}
|
||||
// check for weekdays
|
||||
found := false
|
||||
for _,wd := range i.WeekDays {
|
||||
for _, wd := range i.WeekDays {
|
||||
if t.Weekday() == wd {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(i.WeekDays) > 0 && !found {
|
||||
return false
|
||||
return false
|
||||
}
|
||||
// check for start hour
|
||||
if i.StartTime != "" {
|
||||
split:= strings.Split(i.StartTime, ":")
|
||||
split := strings.Split(i.StartTime, ":")
|
||||
sh, _ := strconv.Atoi(split[0])
|
||||
sm, _ := strconv.Atoi(split[1])
|
||||
ss, _ := strconv.Atoi(split[2])
|
||||
// if the hour is before or is the same hour but the minute is before
|
||||
if t.Hour() < sh ||
|
||||
(t.Hour() == sh && t.Minute() < sm) ||
|
||||
(t.Hour() == sh && t.Minute() == sm && t.Second() < ss) {
|
||||
(t.Hour() == sh && t.Minute() == sm && t.Second() < ss) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -60,9 +60,9 @@ func (i *Interval) Contains(t time.Time) bool {
|
||||
es, _ := strconv.Atoi(split[2])
|
||||
// if the hour is after or is the same hour but the minute is after
|
||||
if t.Hour() > eh ||
|
||||
(t.Hour() == eh && t.Minute() > em) ||
|
||||
(t.Hour() == eh && t.Minute() == em && t.Second() > es) {
|
||||
return false
|
||||
(t.Hour() == eh && t.Minute() > em) ||
|
||||
(t.Hour() == eh && t.Minute() == em && t.Second() > es) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
@@ -78,24 +78,28 @@ func (i *Interval) ContainsSpan(t *TimeSpan) bool {
|
||||
/*
|
||||
Returns true if the timespan is fully enclosed in the interval
|
||||
*/
|
||||
func (i *Interval) ContainsFullSpan(ts *TimeSpan) bool {
|
||||
func (i *Interval) ContainsFullSpan(ts *TimeSpan) bool {
|
||||
return i.Contains(ts.TimeStart) && i.Contains(ts.TimeEnd)
|
||||
}
|
||||
|
||||
/*
|
||||
Returns a time object that represents the end of the interval realtive to the received time
|
||||
*/
|
||||
func (i *Interval) getRightMargin(t time.Time) (rigthtTime time.Time){
|
||||
year, month, day := t.Year(), t.Month(), t.Day()
|
||||
hour, min, sec, nsec := 23,59,59,0
|
||||
loc := t.Location()
|
||||
if i.Month > 0 { month = i.Month }
|
||||
if i.MonthDay > 0 { day = i.MonthDay }
|
||||
func (i *Interval) getRightMargin(t time.Time) (rigthtTime time.Time) {
|
||||
year, month, day := t.Year(), t.Month(), t.Day()
|
||||
hour, min, sec, nsec := 23, 59, 59, 0
|
||||
loc := t.Location()
|
||||
if i.Month > 0 {
|
||||
month = i.Month
|
||||
}
|
||||
if i.MonthDay > 0 {
|
||||
day = i.MonthDay
|
||||
}
|
||||
if i.EndTime != "" {
|
||||
split := strings.Split(i.EndTime, ":")
|
||||
hour, _ = strconv.Atoi(split[0])
|
||||
min, _ = strconv.Atoi(split[1])
|
||||
sec,_ = strconv.Atoi(split[2])
|
||||
sec, _ = strconv.Atoi(split[2])
|
||||
}
|
||||
return time.Date(year, month, day, hour, min, sec, nsec, loc)
|
||||
}
|
||||
@@ -103,12 +107,16 @@ func (i *Interval) getRightMargin(t time.Time) (rigthtTime time.Time){
|
||||
/*
|
||||
Returns a time object that represents the start of the interval realtive to the received time
|
||||
*/
|
||||
func (i *Interval) getLeftMargin(t time.Time) (rigthtTime time.Time){
|
||||
year, month, day := t.Year(), t.Month(), t.Day()
|
||||
hour, min, sec, nsec := 0,0,0,0
|
||||
loc := t.Location()
|
||||
if i.Month > 0 { month = i.Month }
|
||||
if i.MonthDay > 0 { day = i.MonthDay }
|
||||
func (i *Interval) getLeftMargin(t time.Time) (rigthtTime time.Time) {
|
||||
year, month, day := t.Year(), t.Month(), t.Day()
|
||||
hour, min, sec, nsec := 0, 0, 0, 0
|
||||
loc := t.Location()
|
||||
if i.Month > 0 {
|
||||
month = i.Month
|
||||
}
|
||||
if i.MonthDay > 0 {
|
||||
day = i.MonthDay
|
||||
}
|
||||
if i.StartTime != "" {
|
||||
split := strings.Split(i.StartTime, ":")
|
||||
hour, _ = strconv.Atoi(split[0])
|
||||
@@ -126,41 +134,40 @@ The interval will attach itself to the timespan that overlaps the interval.
|
||||
*/
|
||||
func (i *Interval) Split(ts *TimeSpan) (nts *TimeSpan) {
|
||||
// if the span is not in interval return nil
|
||||
if !i.ContainsSpan(ts) {
|
||||
if !i.ContainsSpan(ts) {
|
||||
return
|
||||
}
|
||||
// if the span is enclosed in the interval try to set as new interval and return nil
|
||||
if i.ContainsFullSpan(ts){
|
||||
ts.SetInterval(i)
|
||||
if i.ContainsFullSpan(ts) {
|
||||
ts.SetInterval(i)
|
||||
return
|
||||
}
|
||||
// if only the start time is in the interval split he interval
|
||||
if i.Contains(ts.TimeStart){
|
||||
splitTime := i.getRightMargin(ts.TimeStart)
|
||||
ts.SetInterval(i)
|
||||
if splitTime == ts.TimeEnd {
|
||||
if i.Contains(ts.TimeStart) {
|
||||
splitTime := i.getRightMargin(ts.TimeStart)
|
||||
ts.SetInterval(i)
|
||||
if splitTime == ts.TimeStart {
|
||||
return
|
||||
}
|
||||
oldTimeEnd := ts.TimeEnd
|
||||
ts.TimeEnd = splitTime
|
||||
|
||||
nts = &TimeSpan{TimeStart: splitTime, TimeEnd: oldTimeEnd}
|
||||
ts.TimeEnd = splitTime
|
||||
|
||||
nts = &TimeSpan{TimeStart: splitTime, TimeEnd: oldTimeEnd}
|
||||
return
|
||||
}
|
||||
// if only the end time is in the interval split the interval
|
||||
if i.Contains(ts.TimeEnd){
|
||||
splitTime := i.getLeftMargin(ts.TimeEnd)
|
||||
if splitTime == ts.TimeEnd {
|
||||
if i.Contains(ts.TimeEnd) {
|
||||
splitTime := i.getLeftMargin(ts.TimeEnd)
|
||||
if splitTime == ts.TimeEnd {
|
||||
ts.SetInterval(i)
|
||||
return
|
||||
return
|
||||
}
|
||||
oldTimeEnd := ts.TimeEnd
|
||||
ts.TimeEnd = splitTime
|
||||
ts.TimeEnd = splitTime
|
||||
|
||||
nts = &TimeSpan{TimeStart: splitTime, TimeEnd: oldTimeEnd}
|
||||
nts = &TimeSpan{TimeStart: splitTime, TimeEnd: oldTimeEnd}
|
||||
nts.SetInterval(i)
|
||||
return
|
||||
}
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -12,10 +12,9 @@ type KyotoStorage struct {
|
||||
func NewKyotoStorage(filaName string) (*KyotoStorage, error) {
|
||||
ndb, err := kc.Open(filaName, kc.READ)
|
||||
//log.Print("Starting kyoto storage")
|
||||
return &KyotoStorage{db: ndb}, err
|
||||
return &KyotoStorage{db: ndb}, err
|
||||
}
|
||||
|
||||
|
||||
func (ks *KyotoStorage) Close() {
|
||||
//log.Print("Closing kyoto storage")
|
||||
ks.db.Close()
|
||||
@@ -24,4 +23,3 @@ func (ks *KyotoStorage) Close() {
|
||||
func (ks *KyotoStorage) Get(key string) (value string, err error) {
|
||||
return ks.db.Get(key)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package timespans
|
||||
|
||||
import (
|
||||
"github.com/simonz05/godis"
|
||||
"log"
|
||||
"github.com/simonz05/godis"
|
||||
)
|
||||
|
||||
type RedisStorage struct {
|
||||
@@ -10,12 +10,11 @@ type RedisStorage struct {
|
||||
}
|
||||
|
||||
func NewRedisStorage(address string) (*RedisStorage, error) {
|
||||
ndb:= godis.New(address, 10, "")
|
||||
ndb := godis.New(address, 10, "")
|
||||
log.Print("Starting redis storage")
|
||||
return &RedisStorage{db: ndb}, nil
|
||||
}
|
||||
|
||||
|
||||
func (rs *RedisStorage) Close() {
|
||||
log.Print("Closing redis storage")
|
||||
rs.db.Quit()
|
||||
@@ -25,4 +24,3 @@ func (rs *RedisStorage) Get(key string) (string, error) {
|
||||
elem, err := rs.db.Get(key)
|
||||
return elem.String(), err
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package timespans
|
||||
|
||||
import (
|
||||
"time"
|
||||
"time"
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -9,7 +9,7 @@ A unit in which a call will be split that has a specific price related interval
|
||||
*/
|
||||
type TimeSpan struct {
|
||||
TimeStart, TimeEnd time.Time
|
||||
Interval *Interval
|
||||
Interval *Interval
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -46,3 +46,5 @@ func (ts *TimeSpan) SetInterval(i *Interval) {
|
||||
ts.Interval = i
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,14 +1,38 @@
|
||||
package timespans
|
||||
|
||||
import (
|
||||
//"time"
|
||||
"time"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStorageEncoding(t *testing.T){
|
||||
func TestGetCost(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}
|
||||
if ts1.GetCost() != 0 {
|
||||
t.Error("No interval and still kicking")
|
||||
}
|
||||
ts1.Interval = &Interval{Price: 1}
|
||||
if ts1.GetCost() != 600 {
|
||||
t.Error("Expected 10 got ", ts1.GetCost())
|
||||
}
|
||||
ts1.Interval.BillingUnit = .1
|
||||
if ts1.GetCost() != 6000 {
|
||||
t.Error("Expected 6000 got ", ts1.GetCost())
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecoding(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
}
|
||||
func TestSetInterval(t *testing.T) {
|
||||
i1 := &Interval{Price: 1}
|
||||
ts1 := TimeSpan{Interval: i1}
|
||||
i2 := &Interval{Price: 2}
|
||||
ts1.SetInterval(i2)
|
||||
if ts1.Interval != i1 {
|
||||
t.Error("Smaller price interval should win")
|
||||
}
|
||||
i2.Ponder = 1
|
||||
ts1.SetInterval(i2)
|
||||
if ts1.Interval != i2 {
|
||||
t.Error("Bigger ponder interval should win")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user