From d184336de649ffb4fd7458c43091dd725123dc25 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Fri, 18 May 2012 15:40:54 +0300 Subject: [PATCH] test for call cost merge --- data/test.kch | Bin 6298928 -> 6299128 bytes timespans/callcost.go | 58 ++++++++++++ timespans/callcost_test.go | 113 ++++++++++++++++++++++++ timespans/calldesc.go | 19 ---- timespans/{intervals.go => interval.go} | 0 timespans/timespans.go | 4 +- 6 files changed, 173 insertions(+), 21 deletions(-) create mode 100644 timespans/callcost.go create mode 100644 timespans/callcost_test.go rename timespans/{intervals.go => interval.go} (100%) diff --git a/data/test.kch b/data/test.kch index fda994069637e8e59f6f0654295cad4e6186042c..ded3f7961dc9d2d5b5cdf2f980087bd690bce220 100644 GIT binary patch delta 565 zcmb8syDvjg9KdnyB~nV6#h@PbD7~juEf>Asih9-i)mBJMnp9)e4owFnZWoi-EEa}p zFi3a*MR!Rzqi;Q;M(5=7%SnEZ{E~C`6qDYcW737iP+L+s!TR^ONC;h8=y$bbO4CEi zq_onjQ^_dZ{^sIpTGee|C-Xi7Do_a{s!*ND`%F(JS{{m95~?n(>it?={qO5ueK|{J za}Akn&TKtr?#;dMOeSrQjc7tMT3|sd+R%;;SkZ|t*dRl|4hOp7L=RkWqZfTp(2oHO z!UGjU7{&-jF@|wWps<%0Q<%mKe3-=?=COc9__2g#tY8&uSjPr7v4w5yWNeQC-JbWg z{PVBAgH(MOipqAU%S!06$}YR(?JM=S&fq@U4@E+O<8WBWvQoI0Cv`!&^QXG8cxqWq WIC`)jQG{K5mdc7l5wh~83G)Yw9mVJX delta 419 zcmb8pJ5B;&7=>YH#s(F3K%pWR1&2{VM37%Z0TplH4FL(EXA4Y0rXVB^HO4JSF_{1r zYheX;mcCTl`Xx_tigS|hd(u`u$8F`!=Ws2|ukH@(T1S&CO>US*-;|-)eRJ`>tBa11 zEFl+7U06bDeHdQ_2bQpm6*%GgTl}5;Hw{I1U`%JL_H?!u>7~E5VoNr3=KQj#U3JvVjnRaAdW*Mki-#E5I9B}C&=IwXUJmyS03lMz$FT}!ZmJi bi#rri!aW}Fh$lRwj2Bc;Ma@=6uTt{|{q3lf diff --git a/timespans/callcost.go b/timespans/callcost.go new file mode 100644 index 000000000..1fd3daf56 --- /dev/null +++ b/timespans/callcost.go @@ -0,0 +1,58 @@ +/* +Rating system designed to be used in VoIP Carriers World +Copyright (C) 2012 Radu Ioan Fericean + +This program is free software: you can redistribute 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 WITHOUT 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 timespans + +import ( + "fmt" + "reflect" +) + +/* +The output structure that will be returned with the call cost information. +*/ +type CallCost struct { + TOR, CstmId, Subject, DestinationPrefix string + Cost, ConnectFee float64 + Timespans []*TimeSpan +} + +// Pretty printing for call cost +func (cc *CallCost) String() (r string) { + r = fmt.Sprintf("%v[%v] : %s -> %s (", cc.Cost, cc.ConnectFee, cc.Subject, cc.DestinationPrefix) + for _, ts := range cc.Timespans { + r += fmt.Sprintf(" %v,", ts.GetDuration()) + } + r += " )" + return +} + +// Merges the received timespan if they are similar (same activation period, same interval, same minute info. +func (cc *CallCost) Merge(other *CallCost) *CallCost { + ts := cc.Timespans[len(cc.Timespans)-1] + otherTs := other.Timespans[0] + if reflect.DeepEqual(ts.ActivationPeriod, otherTs.ActivationPeriod) && + reflect.DeepEqual(ts.MinuteInfo, otherTs.MinuteInfo) && reflect.DeepEqual(ts.Interval, otherTs.Interval) { + cc.Cost += other.Cost + // extend the last timespan with + ts.TimeEnd = ts.TimeEnd.Add(otherTs.GetDuration()) + // add the rest of the timspans + cc.Timespans = append(cc.Timespans, other.Timespans[1:]...) + return nil + } + return other +} diff --git a/timespans/callcost_test.go b/timespans/callcost_test.go new file mode 100644 index 000000000..d123bd94a --- /dev/null +++ b/timespans/callcost_test.go @@ -0,0 +1,113 @@ +/* +Rating system designed to be used in VoIP Carriers World +Copyright (C) 2012 Radu Ioan Fericean + +This program is free software: you can redistribute 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 WITHOUT 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 timespans + +import ( + // "log" + "testing" + "time" +) + +func TestSingleResultMerge(t *testing.T) { + getter, _ := NewRedisStorage("tcp:127.0.0.1:6379", 10) + defer getter.Close() + 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) + cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", TimeStart: t1, TimeEnd: t2, storageGetter: getter} + cc1, _ := cd.GetCost() + if cc1.Cost != 12 { + t.Errorf("expected 12 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) + cd = &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", TimeStart: t1, TimeEnd: t2, storageGetter: getter} + cc2, _ := cd.GetCost() + if cc2.Cost != 12 { + t.Errorf("expected 12 was %v", cc2.Cost) + } + result := cc1.Merge(cc2) + if result != nil { + t.Error("expected nil result") + } + if len(cc1.Timespans) != 1 || cc1.Timespans[0].GetDuration().Seconds() != 120 { + t.Error("wrong resulted timespan") + } + if cc1.Cost != 24 { + t.Errorf("Exdpected 24 was %v", cc1.Cost) + } +} + +func TestMultipleResultMerge(t *testing.T) { + getter, _ := NewRedisStorage("tcp:127.0.0.1:6379", 10) + defer getter.Close() + 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) + cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", TimeStart: t1, TimeEnd: t2, storageGetter: getter} + cc1, _ := cd.GetCost() + if cc1.Cost != 12 { + t.Errorf("expected 12 was %v", cc1.Cost) + } + t1 = time.Date(2012, time.February, 2, 18, 00, 0, 0, time.UTC) + t2 = time.Date(2012, time.February, 2, 18, 01, 0, 0, time.UTC) + cd = &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", TimeStart: t1, TimeEnd: t2, storageGetter: getter} + cc2, _ := cd.GetCost() + if cc2.Cost != 6 { + t.Errorf("expected 12 was %v", cc2.Cost) + } + result := cc1.Merge(cc2) + if result == nil { + t.Error("expected non nil result") + } + if len(cc1.Timespans) != 1 || cc1.Timespans[0].GetDuration().Seconds() != 60 { + t.Error("wrong resulted timespan") + } + if cc1.Cost != 12 { + t.Errorf("Exdpected 12 was %v", cc1.Cost) + } +} + +func TestMultipleInputLeftMerge(t *testing.T) { + getter, _ := NewRedisStorage("tcp:127.0.0.1:6379", 10) + defer getter.Close() + t1 := time.Date(2012, time.February, 2, 17, 59, 0, 0, time.UTC) + t2 := time.Date(2012, time.February, 2, 18, 01, 0, 0, time.UTC) + cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", TimeStart: t1, TimeEnd: t2, storageGetter: getter} + cc1, _ := cd.GetCost() + if cc1.Cost != 18 { + t.Errorf("expected 12 was %v", cc1.Cost) + } + t1 = time.Date(2012, time.February, 2, 18, 01, 0, 0, time.UTC) + t2 = time.Date(2012, time.February, 2, 18, 02, 0, 0, time.UTC) + cd = &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", TimeStart: t1, TimeEnd: t2, storageGetter: getter} + cc2, _ := cd.GetCost() + if cc2.Cost != 6 { + t.Errorf("expected 12 was %v", cc2.Cost) + } + result := cc1.Merge(cc2) + if result != nil { + t.Error("expected nil result") + } + if len(cc1.Timespans) != 2 || cc1.Timespans[1].GetDuration().Seconds() != 120 { + t.Error("wrong resulted timespan") + t.Log(cc1.Timespans[1].GetDuration()) + } + if cc1.Cost != 24 { + t.Errorf("Exdpected 24 was %v", cc1.Cost) + } +} diff --git a/timespans/calldesc.go b/timespans/calldesc.go index f8cae822a..ed2db05c5 100644 --- a/timespans/calldesc.go +++ b/timespans/calldesc.go @@ -224,25 +224,6 @@ func (cd *CallDescriptor) GetCost() (*CallCost, error) { return cc, err } -/* -The output structure that will be returned with the call cost information. -*/ -type CallCost struct { - TOR, CstmId, Subject, DestinationPrefix string - Cost, ConnectFee float64 - Timespans []*TimeSpan -} - -// Pretty printing for call cost -func (cc *CallCost) String() (r string) { - r = fmt.Sprintf("%v[%v] : %s -> %s (", cc.Cost, cc.ConnectFee, cc.Subject, cc.DestinationPrefix) - for _, ts := range cc.Timespans { - r += fmt.Sprintf(" %v,", ts.GetDuration()) - } - r += " )" - return -} - /* Returns the cost of a second in the present time conditions. */ diff --git a/timespans/intervals.go b/timespans/interval.go similarity index 100% rename from timespans/intervals.go rename to timespans/interval.go diff --git a/timespans/timespans.go b/timespans/timespans.go index af3011c61..14366533f 100644 --- a/timespans/timespans.go +++ b/timespans/timespans.go @@ -20,8 +20,8 @@ package timespans import ( "fmt" + // "log" "time" - //"log" ) /* @@ -81,7 +81,7 @@ func (ts *TimeSpan) Contains(t time.Time) bool { } /* -will set the interval as spans's interval if new ponder is greater then span's interval ponder +Will set the interval as spans's interval if new ponder is greater then span's interval ponder or if the ponders are equal and new price is lower then spans's interval price */ func (ts *TimeSpan) SetInterval(i *Interval) {