/* Rating system designed to be used in VoIP Carriers World Copyright (C) 2013 ITsysCOM This program is free software: you can Storagetribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITH*out ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see */ package engine import ( "github.com/cgrates/cgrates/history" "log" "testing" "time" ) var ( marsh = NewCodecMsgpackMarshaler() ) func init() { populateDB() historyScribe, _ = history.NewMockScribe() } func populateDB() { minu := &UserBalance{ Id: "*out:vdf:minu", Type: UB_TYPE_PREPAID, BalanceMap: map[string]BalanceChain{ CREDIT: BalanceChain{&Balance{Value: 0}}, MINUTES + OUTBOUND: BalanceChain{ &Balance{Value: 200, DestinationId: "NAT", Weight: 10}, &Balance{Value: 100, DestinationId: "RET", Weight: 20}, }}, } broker := &UserBalance{ Id: "*out:vdf:broker", Type: UB_TYPE_PREPAID, BalanceMap: map[string]BalanceChain{ MINUTES + OUTBOUND: BalanceChain{ &Balance{Value: 20, DestinationId: "NAT", Weight: 10, RateSubject: "rif"}, &Balance{Value: 100, DestinationId: "RET", Weight: 20}, }}, } if storageGetter != nil { storageGetter.(Storage).Flush() storageGetter.SetUserBalance(broker) storageGetter.SetUserBalance(minu) } else { log.Fatal("Could not connect to db!") } } func TestSplitSpans(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) cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} cd.LoadRatingPlans() timespans := cd.splitInTimeSpans(nil) if len(timespans) != 2 { t.Log(cd.RatingPlans) t.Error("Wrong number of timespans: ", len(timespans)) } } func TestGetCost(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) cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2, LoopIndex: 0} result, _ := cd.GetCost() expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0256", Cost: 2700, ConnectFee: 1} if result.Cost != expected.Cost || result.ConnectFee != expected.ConnectFee { t.Errorf("Expected %v was %v", expected, result) } } 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) cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2, LoopIndex: 1} result, _ := cd.GetCost() expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0256", Cost: 2700, ConnectFee: 0} if result.Cost != expected.Cost || result.ConnectFee != expected.ConnectFee { t.Errorf("Expected %v was %v", expected, result) } } func TestGetCostAccount(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) cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Account: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} result, _ := cd.GetCost() expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0256", Cost: 2700, ConnectFee: 1} if result.Cost != expected.Cost || result.ConnectFee != expected.ConnectFee { t.Errorf("Expected %v was %v", expected, result) } } func TestFullDestNotFound(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) cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256308200", TimeStart: t1, TimeEnd: t2} result, _ := cd.GetCost() expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0256", Cost: 2700, ConnectFee: 1} if result.Cost != expected.Cost || result.ConnectFee != expected.ConnectFee { t.Log(cd.RatingPlans) t.Errorf("Expected %v was %v", expected, result) } } func TestSubjectNotFound(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) cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "not_exiting", Destination: "025740532", TimeStart: t1, TimeEnd: t2} result, _ := cd.GetCost() expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0257", Cost: 2700, ConnectFee: 1} if result.Cost != expected.Cost || result.ConnectFee != expected.ConnectFee { t.Log(cd.RatingPlans) t.Errorf("Expected %v was %v", expected, result) } } func TestMultipleRatingPlans(t *testing.T) { 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{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0257308200", TimeStart: t1, TimeEnd: t2} result, _ := cd.GetCost() expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0257", Cost: 2700, ConnectFee: 1} if result.Cost != expected.Cost || result.ConnectFee != expected.ConnectFee { t.Log(result.Timespans) t.Errorf("Expected %v was %v", expected, result) } } func TestSpansMultipleRatingPlans(t *testing.T) { 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{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0257308200", TimeStart: t1, TimeEnd: t2} result, _ := cd.GetCost() expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0257", Cost: 1200, ConnectFee: 0} if result.Cost != expected.Cost || result.ConnectFee != expected.ConnectFee { t.Errorf("Expected %v was %v", expected, result) } } func TestLessThanAMinute(t *testing.T) { 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{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0257308200", TimeStart: t1, TimeEnd: t2} result, _ := cd.GetCost() expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0257", Cost: 15, ConnectFee: 0} if result.Cost != expected.Cost || result.ConnectFee != expected.ConnectFee { t.Errorf("Expected %v was %v", expected, result) } } func TestUniquePrice(t *testing.T) { t1 := time.Date(2012, time.February, 8, 22, 50, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 8, 23, 50, 21, 0, time.UTC) cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0723045326", TimeStart: t1, TimeEnd: t2} result, _ := cd.GetCost() expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0723", Cost: 1810.5, ConnectFee: 0} if result.Cost != expected.Cost || result.ConnectFee != expected.ConnectFee { t.Errorf("Expected %v was %v", expected, result) } } func TestMinutesCost(t *testing.T) { t1 := time.Date(2012, time.February, 8, 22, 50, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 8, 22, 51, 50, 0, time.UTC) cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0723", TimeStart: t1, TimeEnd: t2} result, _ := cd.GetCost() expected := &CallCost{Tenant: "vdf", Subject: "minutosu", Destination: "0723", Cost: 55, ConnectFee: 0} if result.Cost != expected.Cost || result.ConnectFee != expected.ConnectFee { t.Errorf("Expected %v was %v", expected, result) } } func TestMaxSessionTimeNoUserBalance(t *testing.T) { cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0723", Amount: 1000} result, err := cd.GetMaxSessionTime(time.Now()) if result != 1000 || err == nil { t.Errorf("Expected %v was %v (%v)", 1000, result, err) } } func TestMaxSessionTimeWithUserBalance(t *testing.T) { cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "minu", Destination: "0723", Amount: 1000} result, err := cd.GetMaxSessionTime(time.Now()) expected := 300.0 if result != expected || err != nil { t.Errorf("Expected %v was %v", expected, result) } } func TestMaxSessionTimeWithUserBalanceAccount(t *testing.T) { cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "minu_from_tm", Account: "minu", Destination: "0723", Amount: 1000} result, err := cd.GetMaxSessionTime(time.Now()) expected := 300.0 if result != expected || err != nil { t.Errorf("Expected %v was %v", expected, result) } } func TestMaxSessionTimeNoCredit(t *testing.T) { cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "broker", Destination: "0723", Amount: 5400} result, err := cd.GetMaxSessionTime(time.Now()) if result != 100 || err != nil { t.Errorf("Expected %v was %v", 100, result) } } /*********************************** BENCHMARKS ***************************************/ func BenchmarkStorageGetting(b *testing.B) { b.StopTimer() 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{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} b.StartTimer() for i := 0; i < b.N; i++ { storageGetter.GetRatingProfile(cd.GetKey()) } } func BenchmarkStorageRestoring(b *testing.B) { b.StopTimer() 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{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} b.StartTimer() for i := 0; i < b.N; i++ { cd.LoadRatingPlans() } } func BenchmarkStorageGetCost(b *testing.B) { b.StopTimer() 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{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} b.StartTimer() for i := 0; i < b.N; i++ { cd.GetCost() } } func BenchmarkSplitting(b *testing.B) { b.StopTimer() 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{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} cd.LoadRatingPlans() b.StartTimer() for i := 0; i < b.N; i++ { cd.splitInTimeSpans(nil) } } func BenchmarkStorageSingleGetSessionTime(b *testing.B) { b.StopTimer() cd := &CallDescriptor{Tenant: "vdf", Subject: "minutosu", Destination: "0723", Amount: 100} b.StartTimer() for i := 0; i < b.N; i++ { cd.GetMaxSessionTime(time.Now()) } } func BenchmarkStorageMultipleGetSessionTime(b *testing.B) { b.StopTimer() cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "minutosu", Destination: "0723", Amount: 5400} b.StartTimer() for i := 0; i < b.N; i++ { cd.GetMaxSessionTime(time.Now()) } }