diff --git a/cmd/stresstest/stresstest.py b/cmd/stresstest/stresstest.py index b4632425d..67bdb192a 100644 --- a/cmd/stresstest/stresstest.py +++ b/cmd/stresstest/stresstest.py @@ -52,6 +52,6 @@ print s.recv(4096) i = 0 result = "" -for i in xrange(5 * int(1e4) + 1): +for i in xrange(int(1e4) + 1): result = rpc.call("Responder.Get", cd) print i, result diff --git a/cmd/tsstress/tsstress.go b/cmd/tsstress/tsstress.go index e2eeae84b..36b2d6be7 100644 --- a/cmd/tsstress/tsstress.go +++ b/cmd/tsstress/tsstress.go @@ -1,40 +1,40 @@ package main import ( - "time" - "log" "flag" + "github.com/rif/cgrates/timespans" + "log" "os" "runtime/pprof" - "github.com/rif/cgrates/timespans" + "time" ) var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file") func main() { flag.Parse() - + if *cpuprofile != "" { - f, err := os.Create(*cpuprofile) - if err != nil { - log.Fatal(err) - } - pprof.StartCPUProfile(f) - defer pprof.StopCPUProfile() - } - + f, err := os.Create(*cpuprofile) + if err != nil { + log.Fatal(err) + } + pprof.StartCPUProfile(f) + defer pprof.StopCPUProfile() + } + 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 := timespans.CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", TimeStart: t1, TimeEnd: t2} - i:= 0 + i := 0 result := ×pans.CallCost{} - getter, _ := timespans.NewKyotoStorage("storage.kch") + getter, _ := timespans.NewRedisStorage("", 10) defer getter.Close() - - for ; i < 1e5; i++ { - + + for ; i < 1e4; i++ { + result, _ = cd.GetCost(getter) } log.Print(result) diff --git a/timespans/calldesc.go b/timespans/calldesc.go index a15ceebf9..403d4b090 100644 --- a/timespans/calldesc.go +++ b/timespans/calldesc.go @@ -50,12 +50,11 @@ Finds the activation periods applicable to the call descriptior. */ func (cd *CallDescriptor) getActivePeriods() (is []*ActivationPeriod) { if len(cd.ActivationPeriods) == 0{ - log.Print("No activation periods available!", cd) + log.Print("No activation periods available! ", cd) return } bestTime := cd.ActivationPeriods[0].ActivationTime is = append(is, cd.ActivationPeriods[0]) - for _, ap := range cd.ActivationPeriods { if ap.ActivationTime.After(bestTime) && ap.ActivationTime.Before(cd.TimeStart) { bestTime = ap.ActivationTime @@ -73,7 +72,7 @@ Splits the call timespan into sub time spans accordin to the activation periods */ func (cd *CallDescriptor) splitInTimeSpans(aps []*ActivationPeriod) (timespans []*TimeSpan) { if len(aps) == 0 { - log.Print("Nothing to split, move along...") + log.Print("Nothing to split, move along... ", cd) return } ts1 := &TimeSpan{TimeStart: cd.TimeStart, TimeEnd: cd.TimeEnd} @@ -132,18 +131,22 @@ Creates a CallCost structure with the cost nformation calculated for the receive func (cd *CallDescriptor) GetCost(sg StorageGetter) (result *CallCost, err error) { destPrefix, err := cd.RestoreFromStorage(sg) timespans := cd.splitInTimeSpans(cd.getActivePeriods()) - + cost := 0.0 for _, ts := range timespans { cost += ts.GetCost() } - + + connectionFee := 0.0 + if len(timespans) > 0 { + connectionFee = timespans[0].Interval.ConnectFee + } cc := &CallCost{TOR: cd.TOR, CstmId: cd.CstmId, Subject: cd.Subject, DestinationPrefix: destPrefix, Cost: cost, - ConnectFee: timespans[0].Interval.ConnectFee} + ConnectFee: connectionFee} return cc, err } diff --git a/timespans/calldesc_test.go b/timespans/calldesc_test.go index 541b73e49..3eb643910 100644 --- a/timespans/calldesc_test.go +++ b/timespans/calldesc_test.go @@ -10,8 +10,8 @@ func TestKyotoSplitSpans(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) + 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) cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", TimeStart: t1, TimeEnd: t2} cd.RestoreFromStorage(getter) @@ -27,8 +27,8 @@ func TestRedisSplitSpans(t *testing.T) { getter, _ := NewRedisStorage("tcp:127.0.0.1:6379", 10) 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) + 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) cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0257", TimeStart: t1, TimeEnd: t2} cd.RestoreFromStorage(getter) @@ -43,8 +43,8 @@ func TestKyotoGetCost(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) + 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) cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", TimeStart: t1, TimeEnd: t2} result, _ := cd.GetCost(getter) expected := &CallCost{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", Cost: 540, ConnectFee: 0} @@ -63,8 +63,8 @@ func TestRedisGetCost(t *testing.T) { getter, _ := NewRedisStorage("tcp:127.0.0.1:6379", 10) 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) + 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) cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", TimeStart: t1, TimeEnd: t2} result, _ := cd.GetCost(getter) expected := &CallCost{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", Cost: 540, ConnectFee: 0} @@ -77,8 +77,8 @@ func TestFullDestNotFound(t *testing.T) { getter, _ := NewRedisStorage("tcp:127.0.0.1:6379", 10) 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) + 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) cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256308200", TimeStart: t1, TimeEnd: t2} result, _ := cd.GetCost(getter) expected := &CallCost{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", Cost: 540, ConnectFee: 0} @@ -87,13 +87,56 @@ func TestFullDestNotFound(t *testing.T) { } } +func TestMultipleActivationPeriods(t *testing.T) { + getter, _ := NewRedisStorage("tcp:127.0.0.1:6379", 10) + defer getter.Close() + + t1 := time.Date(2012, time.February, 8, 17, 30, 0, 0, time.UTC) + t2 := time.Date(2012, time.February, 8, 18, 30, 0, 0, time.UTC) + cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0257308200", TimeStart: t1, TimeEnd: t2} + result, _ := cd.GetCost(getter) + expected := &CallCost{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0257", Cost: 330, ConnectFee: 0} + if *result != *expected { + t.Errorf("Expected %v was %v", expected, result) + } +} + +func TestSpansMultipleActivationPeriods(t *testing.T) { + getter, _ := NewRedisStorage("tcp:127.0.0.1:6379", 10) + defer getter.Close() + + t1 := time.Date(2012, time.February, 7, 23, 50, 0, 0, time.UTC) + t2 := time.Date(2012, time.February, 8, 0, 30, 0, 0, time.UTC) + cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0257308200", TimeStart: t1, TimeEnd: t2} + result, _ := cd.GetCost(getter) + expected := &CallCost{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0257", Cost: 360, ConnectFee: 0} + if *result != *expected { + t.Errorf("Expected %v was %v", expected, result) + } +} + +func TestLessThanAMinute(t *testing.T) { + getter, _ := NewRedisStorage("tcp:127.0.0.1:6379", 10) + defer getter.Close() + + t1 := time.Date(2012, time.February, 8, 23, 50, 0, 0, time.UTC) + t2 := time.Date(2012, time.February, 8, 23, 50, 30, 0, time.UTC) + cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0257308200", TimeStart: t1, TimeEnd: t2} + result, _ := cd.GetCost(getter) + expected := &CallCost{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0257", Cost: 0.5, ConnectFee: 0} + if *result != *expected { + t.Errorf("Expected %v was %v", expected, result) + } +} + +/*********************************** BENCHMARKS ***************************************/ func BenchmarkRedisGetting(b *testing.B) { b.StopTimer() getter, _ := NewRedisStorage("", 10) 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) + 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) cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", TimeStart: t1, TimeEnd: t2} b.StartTimer() for i := 0; i < b.N; i++ { @@ -106,8 +149,8 @@ func BenchmarkRedisGetCost(b *testing.B) { getter, _ := NewRedisStorage("", 10) 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) + 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) cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", TimeStart: t1, TimeEnd: t2} b.StartTimer() for i := 0; i < b.N; i++ { @@ -120,8 +163,8 @@ func BenchmarkKyotoGetting(b *testing.B) { 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) + 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) cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", TimeStart: t1, TimeEnd: t2} b.StartTimer() for i := 0; i < b.N; i++ { @@ -135,8 +178,8 @@ func BenchmarkSplitting(b *testing.B) { 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) + 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) cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", TimeStart: t1, TimeEnd: t2} cd.RestoreFromStorage(getter) b.StartTimer() @@ -150,8 +193,8 @@ func BenchmarkKyotoGetCost(b *testing.B) { 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) + 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) cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", TimeStart: t1, TimeEnd: t2} b.StartTimer() for i := 0; i < b.N; i++ { diff --git a/timespans/test.kch b/timespans/test.kch index 1484b32a1..db7902939 100644 Binary files a/timespans/test.kch and b/timespans/test.kch differ diff --git a/timespans/test_data.json b/timespans/test_data.json index 8a8bc2a62..8216b7545 100644 --- a/timespans/test_data.json +++ b/timespans/test_data.json @@ -1,18 +1,24 @@ [ {"TOR": 0,"CstmId":"vdf","Subject":"rif","DestinationPrefix":"0256", "ActivationPeriods": [ {"ActivationTime": "2012-01-01T00:00:00Z", "Intervals": [ - {"BillingUnit":1,"ConnectFee":0,"EndTime":"18:00:00","Month":0,"MonthDay":0,"Ponder":0,"Price":0.2,"StartTime":"","WeekDays":[1,2,3,4,5]}, - {"BillingUnit":1,"ConnectFee":0,"EndTime":"","Month":0,"MonthDay":0,"Ponder":0,"Price":0.1,"StartTime":"18:00:00","WeekDays":[1,2,3,4,5]}, - {"BillingUnit":1,"ConnectFee":0,"EndTime":"","Month":0,"MonthDay":0,"Ponder":0,"Price":0.1,"StartTime":"","WeekDays":[6,0]} + {"BillingUnit":1,"ConnectFee":0,"Month":0,"MonthDay":0,"Ponder":0,"Price":0.2,"StartTime":"","EndTime":"18:00:00","WeekDays":[1,2,3,4,5]}, + {"BillingUnit":1,"ConnectFee":0,"Month":0,"MonthDay":0,"Ponder":0,"Price":0.1,"StartTime":"18:00:00","EndTime":"","WeekDays":[1,2,3,4,5]}, + {"BillingUnit":1,"ConnectFee":0,"Month":0,"MonthDay":0,"Ponder":0,"Price":0.1,"StartTime":"","EndTime":"","WeekDays":[6,0]} ] } ] }, {"TOR": 0,"CstmId":"vdf","Subject":"rif","DestinationPrefix":"0257", "ActivationPeriods": [ {"ActivationTime": "2012-01-01T00:00:00Z", "Intervals": [ - {"BillingUnit":1,"ConnectFee":0,"EndTime":"","Month":0,"MonthDay":0,"Ponder":0,"Price":0.1,"StartTime":"18:00:00","WeekDays":[1,2,3,4,5]}, - {"BillingUnit":1,"ConnectFee":0,"EndTime":"18:00:00","Month":0,"MonthDay":0,"Ponder":0,"Price":0.2,"StartTime":"","WeekDays":[1,2,3,4,5]}, - {"BillingUnit":1,"ConnectFee":0,"EndTime":"","Month":0,"MonthDay":0,"Ponder":0,"Price":0.1,"StartTime":"","WeekDays":[6,0]} + {"BillingUnit":1,"ConnectFee":0,"Month":0,"MonthDay":0,"Ponder":0,"Price":0.1,"StartTime":"18:00:00","EndTime":"","WeekDays":[1,2,3,4,5]}, + {"BillingUnit":1,"ConnectFee":0,"Month":0,"MonthDay":0,"Ponder":0,"Price":0.2,"StartTime":"","EndTime":"18:00:00","WeekDays":[1,2,3,4,5]}, + {"BillingUnit":1,"ConnectFee":0,"Month":0,"MonthDay":0,"Ponder":0,"Price":0.1,"StartTime":"","EndTime":"","WeekDays":[6,0]} + ] + }, + {"ActivationTime": "2012-02-08T00:00:00Z", "Intervals": [ + {"BillingUnit":60,"ConnectFee":0,"Month":0,"MonthDay":0,"Ponder":0,"Price":10,"StartTime":"","EndTime":"18:00:00","WeekDays":[1,2,3,4,5]}, + {"BillingUnit":60,"ConnectFee":0,"Month":0,"MonthDay":0,"Ponder":0,"Price":1,"StartTime":"18:00:00","EndTime":"","WeekDays":[1,2,3,4,5]}, + {"BillingUnit":60,"ConnectFee":0,"Month":0,"MonthDay":0,"Ponder":0,"Price":1,"StartTime":"","EndTime":"","WeekDays":[6,0]} ] } ]