mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-22 23:58:44 +05:00
Merge branch 'master' of https://github.com/cgrates/cgrates
This commit is contained in:
@@ -36,6 +36,15 @@
|
||||
<rule avp="Recipient-Address" required="false" max="1" />
|
||||
</data>
|
||||
</avp>
|
||||
<avp name="TransactionId" code="29001" must="V" may="P,M" must-not="-" may-encrypt="N" vendor-id="2011">
|
||||
<data type="OctetString"/>
|
||||
</avp>
|
||||
<avp name="MC-Service-Id" code="29002" must="V" may="P,M" must-not="-" may-encrypt="N" vendor-id="2011">
|
||||
<data type="UTF8String"/>
|
||||
</avp>
|
||||
<avp name="TransparentData" code="29003" must="V" may="P,M" must-not="-" may-encrypt="N" vendor-id="2011">
|
||||
<data type="UTF8String"/>
|
||||
</avp>
|
||||
<avp name="CallingPartyAddress" code="20336" must="V" may="P,M" must-not="-" may-encrypt="N" vendor-id="2011">
|
||||
<data type="UTF8String" />
|
||||
</avp>
|
||||
|
||||
@@ -26,7 +26,7 @@ COPY mongod.conf /etc/mongod.conf
|
||||
RUN useradd -c CGRateS -d /var/run/cgrates -s /bin/false -r cgrates
|
||||
|
||||
# install golang
|
||||
RUN wget -qO- https://storage.googleapis.com/golang/go1.6.linux-amd64.tar.gz | tar xzf - -C /root/
|
||||
RUN wget -qO- https://storage.googleapis.com/golang/go1.6.1.linux-amd64.tar.gz | tar xzf - -C /root/
|
||||
|
||||
#install glide
|
||||
RUN GOROOT=/root/go GOPATH=/root/code /root/go/bin/go get github.com/Masterminds/glide
|
||||
|
||||
@@ -362,6 +362,7 @@ func (cd *CallDescriptor) splitInTimeSpans() (timespans []*TimeSpan) {
|
||||
// split on rating plans
|
||||
afterStart, afterEnd := false, false //optimization for multiple activation periods
|
||||
for _, rp := range cd.RatingInfos {
|
||||
//log.Print("RP: ", utils.ToJSON(rp))
|
||||
if !afterStart && !afterEnd && rp.ActivationTime.Before(cd.TimeStart) {
|
||||
firstSpan.setRatingInfo(rp)
|
||||
} else {
|
||||
@@ -369,7 +370,6 @@ func (cd *CallDescriptor) splitInTimeSpans() (timespans []*TimeSpan) {
|
||||
for i := 0; i < len(timespans); i++ {
|
||||
newTs := timespans[i].SplitByRatingPlan(rp)
|
||||
if newTs != nil {
|
||||
//log.Print("NEW TS", newTs.TimeStart)
|
||||
timespans = append(timespans, newTs)
|
||||
} else {
|
||||
afterEnd = true
|
||||
@@ -378,8 +378,23 @@ func (cd *CallDescriptor) splitInTimeSpans() (timespans []*TimeSpan) {
|
||||
}
|
||||
}
|
||||
}
|
||||
//log.Printf("After SplitByRatingPlan: %+v", utils.ToJSON(timespans))
|
||||
// split on days
|
||||
for i := 0; i < len(timespans); i++ {
|
||||
rp := timespans[i].ratingInfo
|
||||
newTs := timespans[i].SplitByDay()
|
||||
if newTs != nil {
|
||||
//log.Print("NEW TS: ", newTs.TimeStart, newTs.TimeEnd)
|
||||
newTs.setRatingInfo(rp)
|
||||
// insert the new timespan
|
||||
index := i + 1
|
||||
timespans = append(timespans, nil)
|
||||
copy(timespans[index+1:], timespans[index:])
|
||||
timespans[index] = newTs
|
||||
}
|
||||
}
|
||||
}
|
||||
// utils.Logger.Debug(fmt.Sprintf("After SplitByRatingPlan: %+v", timespans))
|
||||
//log.Printf("After SplitByDay: %+v", utils.ToJSON(timespans))
|
||||
// split on rate intervals
|
||||
for i := 0; i < len(timespans); i++ {
|
||||
//log.Printf("==============%v==================", i)
|
||||
@@ -388,6 +403,7 @@ func (cd *CallDescriptor) splitInTimeSpans() (timespans []*TimeSpan) {
|
||||
// utils.Logger.Debug(fmt.Sprintf("rp: %+v", rp))
|
||||
//timespans[i].RatingPlan = nil
|
||||
rateIntervals := rp.SelectRatingIntevalsForTimespan(timespans[i])
|
||||
//log.Print("RIs: ", utils.ToJSON(rateIntervals))
|
||||
/*for _, interval := range rp.RateIntervals {
|
||||
if !timespans[i].hasBetterRateIntervalThan(interval) {
|
||||
timespans[i].SetRateInterval(interval)
|
||||
@@ -520,6 +536,7 @@ func (cd *CallDescriptor) getCost() (*CallCost, error) {
|
||||
cd.TOR = utils.VOICE
|
||||
}
|
||||
err := cd.LoadRatingPlans()
|
||||
//log.Print("RI: ", utils.ToJSON(cd.RatingInfos))
|
||||
if err != nil {
|
||||
//utils.Logger.Err(fmt.Sprintf("error getting cost for key <%s>: %s", cd.GetKey(cd.Subject), err.Error()))
|
||||
return &CallCost{Cost: -1}, err
|
||||
|
||||
@@ -326,6 +326,43 @@ func TestGetCostRatingPlansAndRatingIntervalsMore(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCostRatingPlansAndRatingIntervalsMoreDays(t *testing.T) {
|
||||
t1 := time.Date(2012, time.February, 20, 9, 50, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 23, 18, 10, 0, 0, time.UTC)
|
||||
cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "CUSTOMER_1", Subject: "rif:from:tm", Destination: "49178", TimeStart: t1, TimeEnd: t2, LoopIndex: 0, DurationIndex: t2.Sub(t1)}
|
||||
result, _ := cd.GetCost()
|
||||
if len(result.Timespans) != 8 ||
|
||||
!result.Timespans[0].TimeEnd.Equal(result.Timespans[1].TimeStart) ||
|
||||
!result.Timespans[1].TimeEnd.Equal(result.Timespans[2].TimeStart) ||
|
||||
!result.Timespans[2].TimeEnd.Equal(result.Timespans[3].TimeStart) ||
|
||||
!result.Timespans[3].TimeEnd.Equal(result.Timespans[4].TimeStart) ||
|
||||
!result.Timespans[4].TimeEnd.Equal(result.Timespans[5].TimeStart) ||
|
||||
!result.Timespans[5].TimeEnd.Equal(result.Timespans[6].TimeStart) ||
|
||||
!result.Timespans[6].TimeEnd.Equal(result.Timespans[7].TimeStart) {
|
||||
for _, ts := range result.Timespans {
|
||||
t.Logf("TS %+v", ts)
|
||||
}
|
||||
t.Errorf("Expected %+v was %+v", 4, len(result.Timespans))
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCostRatingPlansAndRatingIntervalsMoreDaysWeekend(t *testing.T) {
|
||||
t1 := time.Date(2012, time.February, 24, 9, 50, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 27, 18, 10, 0, 0, time.UTC)
|
||||
cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "CUSTOMER_1", Subject: "rif:from:tm", Destination: "49178", TimeStart: t1, TimeEnd: t2, LoopIndex: 0, DurationIndex: t2.Sub(t1)}
|
||||
result, _ := cd.GetCost()
|
||||
if len(result.Timespans) != 5 ||
|
||||
!result.Timespans[0].TimeEnd.Equal(result.Timespans[1].TimeStart) ||
|
||||
!result.Timespans[1].TimeEnd.Equal(result.Timespans[2].TimeStart) ||
|
||||
!result.Timespans[2].TimeEnd.Equal(result.Timespans[3].TimeStart) ||
|
||||
!result.Timespans[3].TimeEnd.Equal(result.Timespans[4].TimeStart) {
|
||||
for _, ts := range result.Timespans {
|
||||
t.Logf("TS %+v", ts)
|
||||
}
|
||||
t.Errorf("Expected %+v was %+v", 4, len(result.Timespans))
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCostRateGroups(t *testing.T) {
|
||||
t1 := time.Date(2013, time.October, 7, 14, 50, 0, 0, time.UTC)
|
||||
t2 := time.Date(2013, time.October, 7, 14, 52, 12, 0, time.UTC)
|
||||
|
||||
@@ -50,12 +50,10 @@ func DerivedChargersMatchesDest(dcs *utils.DerivedChargers, dest string) bool {
|
||||
for _, p := range utils.SplitPrefix(dest, MIN_PREFIX_MATCH) {
|
||||
if x, err := cache2go.Get(utils.DESTINATION_PREFIX + p); err == nil {
|
||||
destIds := x.(map[interface{}]struct{})
|
||||
for value := range dcs.DestinationIDs {
|
||||
for idId := range destIds {
|
||||
dId := idId.(string)
|
||||
if value == dId {
|
||||
return true
|
||||
}
|
||||
for dId := range destIds {
|
||||
includeDest, found := dcs.DestinationIDs[dId.(string)]
|
||||
if found {
|
||||
return includeDest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,3 +119,21 @@ func TestHandleDeivedChargersMatchDestNatRet(t *testing.T) {
|
||||
t.Error("Derived charger failed to match dest")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleDeivedChargersMatchDestSpec(t *testing.T) {
|
||||
dcs := &utils.DerivedChargers{
|
||||
DestinationIDs: utils.NewStringMap("NAT", "SPEC"),
|
||||
}
|
||||
if !DerivedChargersMatchesDest(dcs, "0723045326") {
|
||||
t.Error("Derived charger failed to match dest")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleDeivedChargersMatchDestNegativeSpec(t *testing.T) {
|
||||
dcs := &utils.DerivedChargers{
|
||||
DestinationIDs: utils.NewStringMap("NAT", "!SPEC"),
|
||||
}
|
||||
if DerivedChargersMatchesDest(dcs, "0723045326") {
|
||||
t.Error("Derived charger failed to match dest")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ func TestHistoryDestinations(t *testing.T) {
|
||||
{"Id":"PSTN_71","Prefixes":["+4971"]},
|
||||
{"Id":"PSTN_72","Prefixes":["+4972"]},
|
||||
{"Id":"RET","Prefixes":["0723","0724"]},
|
||||
{"Id":"SPEC","Prefixes":["0723045"]},
|
||||
{"Id":"URG","Prefixes":["112"]}`
|
||||
if !strings.Contains(buf.String(), expected) {
|
||||
t.Error("Error in destination history content:", buf.String())
|
||||
|
||||
@@ -42,6 +42,7 @@ NAT,0723
|
||||
NAT,+49
|
||||
RET,0723
|
||||
RET,0724
|
||||
SPEC,0723045
|
||||
PSTN_71,+4971
|
||||
PSTN_72,+4972
|
||||
PSTN_70,+4970
|
||||
@@ -319,7 +320,7 @@ func init() {
|
||||
}
|
||||
|
||||
func TestLoadDestinations(t *testing.T) {
|
||||
if len(csvr.destinations) != 12 {
|
||||
if len(csvr.destinations) != 13 {
|
||||
t.Error("Failed to load destinations: ", len(csvr.destinations))
|
||||
}
|
||||
for _, d := range csvr.destinations {
|
||||
|
||||
@@ -289,7 +289,7 @@ Returns true if the received time result inside the interval
|
||||
*/
|
||||
func (i *RateInterval) Contains(t time.Time, endTime bool) bool {
|
||||
if endTime {
|
||||
if t.Hour() == 0 && t.Minute() == 0 && t.Second() == 0 { // back one second to 23:59:59
|
||||
if utils.TimeIs0h(t) { // back one second to 23:59:59
|
||||
t = t.Add(-1 * time.Second)
|
||||
}
|
||||
}
|
||||
@@ -360,23 +360,6 @@ func (ri *RateInterval) GetMaxCost() (float64, string) {
|
||||
// Structure to store intervals according to weight
|
||||
type RateIntervalList []*RateInterval
|
||||
|
||||
func (il RateIntervalList) Len() int {
|
||||
return len(il)
|
||||
}
|
||||
|
||||
func (il RateIntervalList) Swap(i, j int) {
|
||||
il[i], il[j] = il[j], il[i]
|
||||
}
|
||||
|
||||
// we need higher weights earlyer in the list
|
||||
func (il RateIntervalList) Less(j, i int) bool {
|
||||
return il[i].Weight < il[j].Weight //|| il[i].Timing.StartTime > il[j].Timing.StartTime
|
||||
}
|
||||
|
||||
func (il RateIntervalList) Sort() {
|
||||
sort.Sort(il)
|
||||
}
|
||||
|
||||
// Structure to store intervals according to weight
|
||||
type RateIntervalTimeSorter struct {
|
||||
referenceTime time.Time
|
||||
@@ -393,6 +376,9 @@ func (il *RateIntervalTimeSorter) Swap(i, j int) {
|
||||
|
||||
// we need higher weights earlyer in the list
|
||||
func (il *RateIntervalTimeSorter) Less(j, i int) bool {
|
||||
if il.ris[i].Weight < il.ris[j].Weight {
|
||||
return il.ris[i].Weight < il.ris[j].Weight
|
||||
}
|
||||
t1 := il.ris[i].Timing.getLeftMargin(il.referenceTime)
|
||||
t2 := il.ris[j].Timing.getLeftMargin(il.referenceTime)
|
||||
return t1.After(t2)
|
||||
|
||||
@@ -59,12 +59,7 @@ func (rp *RatingPlan) RateIntervalList(dId string) RateIntervalList {
|
||||
return ril
|
||||
}
|
||||
|
||||
/*
|
||||
type xCachedRatingPlan struct {
|
||||
rp *RatingPlan
|
||||
*cache2go.XEntry
|
||||
}
|
||||
*/
|
||||
// no sorter because it's sorted with RateIntervalTimeSorter
|
||||
|
||||
/*
|
||||
Adds one ore more intervals to the internal interval list only if it is not allready in the list.
|
||||
|
||||
@@ -92,28 +92,36 @@ type RatingInfo struct {
|
||||
|
||||
// SelectRatingIntevalsForTimespan orders rate intervals in time preserving only those which aply to the specified timestamp
|
||||
func (ri RatingInfo) SelectRatingIntevalsForTimespan(ts *TimeSpan) (result RateIntervalList) {
|
||||
ri.RateIntervals.Sort()
|
||||
sorter := &RateIntervalTimeSorter{referenceTime: ts.TimeStart, ris: ri.RateIntervals}
|
||||
rateIntervals := sorter.Sort()
|
||||
// get the rating interval closest to begining of timespan
|
||||
var delta time.Duration = -1
|
||||
var bestRateIntervalIndex int
|
||||
var bestIntervalWeight float64
|
||||
for index, rateInterval := range rateIntervals {
|
||||
if !rateInterval.Contains(ts.TimeStart, false) {
|
||||
continue
|
||||
}
|
||||
if rateInterval.Weight < bestIntervalWeight {
|
||||
break // don't consider lower weights'
|
||||
}
|
||||
startTime := rateInterval.Timing.getLeftMargin(ts.TimeStart)
|
||||
tmpDelta := ts.TimeStart.Sub(startTime)
|
||||
if (startTime.Before(ts.TimeStart) ||
|
||||
startTime.Equal(ts.TimeStart)) &&
|
||||
(delta == -1 || tmpDelta < delta) {
|
||||
bestRateIntervalIndex = index
|
||||
bestIntervalWeight = rateInterval.Weight
|
||||
delta = tmpDelta
|
||||
}
|
||||
}
|
||||
result = append(result, rateIntervals[bestRateIntervalIndex])
|
||||
// check if later rating intervals influence this timespan
|
||||
//log.Print("RIS: ", utils.ToIJSON(rateIntervals))
|
||||
for i := bestRateIntervalIndex + 1; i < len(rateIntervals); i++ {
|
||||
if rateIntervals[i].Weight < bestIntervalWeight {
|
||||
break // don't consider lower weights'
|
||||
}
|
||||
startTime := rateIntervals[i].Timing.getLeftMargin(ts.TimeStart)
|
||||
if startTime.Before(ts.TimeEnd) {
|
||||
result = append(result, rateIntervals[i])
|
||||
|
||||
@@ -250,6 +250,143 @@ func TestRatingProfileRIforTSMidnight(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRatingProfileYearMonthDay(t *testing.T) {
|
||||
ri := &RatingInfo{
|
||||
RateIntervals: RateIntervalList{
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
StartTime: "09:00:00",
|
||||
},
|
||||
},
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
},
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: utils.Years{2016},
|
||||
Months: utils.Months{1},
|
||||
MonthDays: utils.MonthDays{6, 7},
|
||||
WeekDays: utils.WeekDays{},
|
||||
StartTime: "19:00:00",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
ts := &TimeSpan{
|
||||
TimeStart: time.Date(2016, 1, 6, 23, 40, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2016, 1, 7, 1, 1, 30, 0, time.UTC),
|
||||
}
|
||||
rIntervals := ri.SelectRatingIntevalsForTimespan(ts)
|
||||
if len(rIntervals) != 1 ||
|
||||
rIntervals[0].Timing.StartTime != "19:00:00" {
|
||||
t.Error("Wrong interval list: ", utils.ToIJSON(rIntervals))
|
||||
}
|
||||
}
|
||||
|
||||
func TestRatingProfileWeighted(t *testing.T) {
|
||||
ri := &RatingInfo{
|
||||
RateIntervals: RateIntervalList{
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
StartTime: "09:00:00",
|
||||
},
|
||||
Weight: 10,
|
||||
},
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
Weight: 10,
|
||||
},
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
StartTime: "19:00:00",
|
||||
},
|
||||
Weight: 10,
|
||||
},
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: utils.Years{2016},
|
||||
Months: utils.Months{1},
|
||||
MonthDays: utils.MonthDays{6},
|
||||
WeekDays: utils.WeekDays{},
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
Weight: 11,
|
||||
},
|
||||
},
|
||||
}
|
||||
ts := &TimeSpan{
|
||||
TimeStart: time.Date(2016, 1, 6, 23, 40, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2016, 1, 6, 23, 45, 30, 0, time.UTC),
|
||||
}
|
||||
rIntervals := ri.SelectRatingIntevalsForTimespan(ts)
|
||||
if len(rIntervals) != 1 ||
|
||||
rIntervals[0].Timing.StartTime != "00:00:00" ||
|
||||
rIntervals[0].Weight != 11 {
|
||||
t.Error("Wrong interval list: ", utils.ToIJSON(rIntervals))
|
||||
}
|
||||
}
|
||||
|
||||
func TestRatingProfileWeightedMultiple(t *testing.T) {
|
||||
ri := &RatingInfo{
|
||||
RateIntervals: RateIntervalList{
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
StartTime: "09:00:00",
|
||||
},
|
||||
Weight: 10,
|
||||
},
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
Weight: 10,
|
||||
},
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
StartTime: "19:00:00",
|
||||
},
|
||||
Weight: 10,
|
||||
},
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: utils.Years{2016},
|
||||
Months: utils.Months{1},
|
||||
MonthDays: utils.MonthDays{6},
|
||||
WeekDays: utils.WeekDays{},
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
Weight: 11,
|
||||
},
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: utils.Years{2016},
|
||||
Months: utils.Months{1},
|
||||
MonthDays: utils.MonthDays{6},
|
||||
WeekDays: utils.WeekDays{},
|
||||
StartTime: "18:00:00",
|
||||
},
|
||||
Weight: 11,
|
||||
},
|
||||
},
|
||||
}
|
||||
ts := &TimeSpan{
|
||||
TimeStart: time.Date(2016, 1, 6, 17, 40, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2016, 1, 6, 23, 45, 30, 0, time.UTC),
|
||||
}
|
||||
rIntervals := ri.SelectRatingIntevalsForTimespan(ts)
|
||||
if len(rIntervals) != 2 ||
|
||||
rIntervals[0].Timing.StartTime != "00:00:00" ||
|
||||
rIntervals[0].Weight != 11 ||
|
||||
rIntervals[1].Timing.StartTime != "18:00:00" ||
|
||||
rIntervals[1].Weight != 11 {
|
||||
t.Error("Wrong interval list: ", utils.ToIJSON(rIntervals))
|
||||
}
|
||||
}
|
||||
|
||||
func TestRatingProfileSubjectPrefixMatching(t *testing.T) {
|
||||
rpSubjectPrefixMatching = true
|
||||
rp, err := RatingProfileSubjectPrefixMatching("*out:cgrates.org:data:rif")
|
||||
|
||||
@@ -612,6 +612,26 @@ func (ts *TimeSpan) SplitByRatingPlan(rp *RatingInfo) (newTs *TimeSpan) {
|
||||
return
|
||||
}
|
||||
|
||||
// Splits the given timespan on activation period's activation time.
|
||||
func (ts *TimeSpan) SplitByDay() (newTs *TimeSpan) {
|
||||
if ts.TimeStart.Day() == ts.TimeEnd.Day() || utils.TimeIs0h(ts.TimeEnd) {
|
||||
return
|
||||
}
|
||||
|
||||
splitDate := ts.TimeStart.AddDate(0, 0, 1)
|
||||
splitDate = time.Date(splitDate.Year(), splitDate.Month(), splitDate.Day(), 0, 0, 0, 0, splitDate.Location())
|
||||
newTs = &TimeSpan{
|
||||
TimeStart: splitDate,
|
||||
TimeEnd: ts.TimeEnd,
|
||||
}
|
||||
newTs.copyRatingInfo(ts)
|
||||
newTs.DurationIndex = ts.DurationIndex
|
||||
ts.TimeEnd = splitDate
|
||||
ts.SetNewDurationIndex(newTs)
|
||||
// Logger.Debug(fmt.Sprintf("RP SPLITTING: %+v %+v", ts, newTs))
|
||||
return
|
||||
}
|
||||
|
||||
// Returns the starting time of this timespan
|
||||
func (ts *TimeSpan) GetGroupStart() time.Duration {
|
||||
s := ts.DurationIndex - ts.GetDuration()
|
||||
|
||||
@@ -161,6 +161,12 @@ func TestTpZeroCost(t *testing.T) {
|
||||
if !*testIntegration {
|
||||
return
|
||||
}
|
||||
var acnt *engine.Account
|
||||
attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1012"}
|
||||
if err := tpRPC.Call("ApierV2.GetAccount", attrs, &acnt); err != nil {
|
||||
t.Error("Got error on ApierV2.GetAccount: ", err.Error())
|
||||
}
|
||||
balanceValueBefore := acnt.BalanceMap[utils.MONETARY][0].Value
|
||||
tStart := time.Date(2016, 3, 31, 0, 0, 0, 0, time.UTC)
|
||||
cd := engine.CallDescriptor{
|
||||
Direction: "*out",
|
||||
@@ -175,15 +181,13 @@ func TestTpZeroCost(t *testing.T) {
|
||||
}
|
||||
var cc engine.CallCost
|
||||
if err := tpRPC.Call("Responder.Debit", cd, &cc); err != nil {
|
||||
t.Error("Got error on Responder.GetCost: ", err.Error())
|
||||
t.Error("Got error on Responder.Debit: ", err.Error())
|
||||
} else if cc.GetDuration() != 20*time.Second {
|
||||
t.Errorf("Calling Responder.MaxDebit got callcost: %v", utils.ToIJSON(cc))
|
||||
}
|
||||
var acnt *engine.Account
|
||||
attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1012"}
|
||||
if err := tpRPC.Call("ApierV2.GetAccount", attrs, &acnt); err != nil {
|
||||
t.Error("Got error on ApierV2.GetAccount: ", err.Error())
|
||||
} else if acnt.BalanceMap[utils.MONETARY][0].Value != 11.0 {
|
||||
} else if acnt.BalanceMap[utils.MONETARY][0].Value != balanceValueBefore {
|
||||
t.Errorf("Calling ApierV2.GetAccount received: %s", utils.ToIJSON(acnt))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -547,3 +547,7 @@ func SizeFmt(num float64, suffix string) string {
|
||||
}
|
||||
return fmt.Sprintf("%.1f%s%s", num, "Yi", suffix)
|
||||
}
|
||||
|
||||
func TimeIs0h(t time.Time) bool {
|
||||
return t.Hour() == 0 && t.Minute() == 0 && t.Second() == 0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user