more tests

This commit is contained in:
Radu Ioan Fericean
2012-02-03 16:17:37 +02:00
parent efbad7a6ef
commit 66721ba8c0
9 changed files with 246 additions and 195 deletions

View File

@@ -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 := &timespans.CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256"}
ap1 := &timespans.ActivationPeriod{ActivationTime: t1}
ap1 := &timespans.ActivationPeriod{ActivationTime: t1}
ap1.AddInterval(&timespans.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(&timespans.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(&timespans.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!")
}

View File

@@ -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
}

View File

@@ -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))
}
}

View File

@@ -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)
}
}

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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
}

View File

@@ -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
}
}

View File

@@ -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")
}
}