This commit is contained in:
DanB
2014-10-02 19:04:54 +02:00
21 changed files with 395 additions and 169 deletions

View File

@@ -219,3 +219,18 @@ func (self *ApierV1) SetAccount(attr AttrSetAccount, reply *string) error {
*reply = OK // This will mark saving of the account, error still can show up in actionTimingsId
return nil
}
type AttrGetAccounts struct {
Page int
ItemsPerPage int
SearchTerm string
}
func (self *ApierV1) GetAccounts(attr AttrGetAccounts, reply *[]string) error {
accountKeys, err := self.AccountDb.GetKeysForPrefix(engine.ACCOUNT_PREFIX)
if err != nil {
return err
}
*reply = accountKeys
return nil
}

View File

@@ -187,7 +187,7 @@ func (self *ApierV1) ExportCdrsToFile(attr utils.AttrExpFileCdrs, reply *utils.E
}
cdrs, err := self.CdrDb.GetStoredCdrs(attr.CgrIds, attr.MediationRunIds, attr.TORs, attr.CdrHosts, attr.CdrSources, attr.ReqTypes, attr.Directions,
attr.Tenants, attr.Categories, attr.Accounts, attr.Subjects, attr.DestinationPrefixes, attr.RatedAccounts, attr.RatedSubjects, attr.OrderIdStart, attr.OrderIdEnd,
tStart, tEnd, attr.SkipErrors, attr.SkipRated, false)
tStart, tEnd, attr.SkipErrors, attr.SkipRated, false, nil)
if err != nil {
return err
} else if len(cdrs) == 0 {

View File

@@ -20,9 +20,10 @@ package v1
import (
"fmt"
"time"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
"time"
)
type AttrGetCallCost struct {
@@ -61,7 +62,7 @@ func (apier *ApierV1) GetCdrs(attrs utils.AttrGetCdrs, reply *[]*utils.CgrCdrOut
}
if cdrs, err := apier.CdrDb.GetStoredCdrs(attrs.CgrIds, attrs.MediationRunIds, attrs.TORs, attrs.CdrHosts, attrs.CdrSources, attrs.ReqTypes, attrs.Directions,
attrs.Tenants, attrs.Categories, attrs.Accounts, attrs.Subjects, attrs.DestinationPrefixes, attrs.RatedAccounts, attrs.RatedSubjects,
attrs.OrderIdStart, attrs.OrderIdEnd, tStart, tEnd, attrs.SkipErrors, attrs.SkipRated, false); err != nil {
attrs.OrderIdStart, attrs.OrderIdEnd, tStart, tEnd, attrs.SkipErrors, attrs.SkipRated, false, &utils.TPPagination{Page: attrs.Page, ItemsPerPage: attrs.ItemsPerPage, SearchTerm: attrs.SearchTerm}); err != nil {
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
} else {
for _, cdr := range cdrs {

View File

@@ -20,8 +20,9 @@ package v1
import (
"errors"
"github.com/cgrates/cgrates/utils"
"time"
"github.com/cgrates/cgrates/utils"
)
/*
@@ -98,6 +99,9 @@ import (
type AttrsGetScheduledActions struct {
Direction, Tenant, Account string
TimeStart, TimeEnd time.Time // Filter based on next runTime
Page int
ItemsPerPage int
SearchTerm string
}
type ScheduledActions struct {
@@ -111,7 +115,14 @@ func (self *ApierV1) GetScheduledActions(attrs AttrsGetScheduledActions, reply *
if self.Sched == nil {
return errors.New("SCHEDULER_NOT_ENABLED")
}
for _, qActions := range self.Sched.GetQueue() {
scheduledActions := self.Sched.GetQueue()
paginator := &utils.TPPagination{Page: attrs.Page, ItemsPerPage: attrs.ItemsPerPage, SearchTerm: attrs.SearchTerm}
min, max := paginator.GetLimits()
if max > len(scheduledActions) {
max = len(scheduledActions)
}
scheduledActions = scheduledActions[min : min+max]
for _, qActions := range scheduledActions {
sas := &ScheduledActions{ActionsId: qActions.ActionsId, ActionPlanId: qActions.Id, ActionPlanUuid: qActions.Uuid}
sas.NextRunTime = qActions.GetNextStartTime(time.Now())
if !attrs.TimeStart.IsZero() && sas.NextRunTime.Before(attrs.TimeStart) {

View File

@@ -25,6 +25,7 @@ import (
"time"
"github.com/cgrates/cgrates/utils"
"github.com/gorhill/cronexpr"
)
const (
@@ -46,6 +47,29 @@ type ActionTiming struct {
type ActionPlan []*ActionTiming
func (at *ActionTiming) GetNextStartTime(now time.Time) (t time.Time) {
if !at.stCache.IsZero() {
return at.stCache
}
i := at.Timing
if i == nil || i.Timing == nil {
return
}
// Normalize
if i.Timing.StartTime == "" {
i.Timing.StartTime = "00:00:00"
}
if len(i.Timing.Years) > 0 && len(i.Timing.Months) == 0 {
i.Timing.Months = append(i.Timing.Months, 1)
}
if len(i.Timing.Months) > 0 && len(i.Timing.MonthDays) == 0 {
i.Timing.MonthDays = append(i.Timing.MonthDays, 1)
}
at.stCache = cronexpr.MustParse(i.Timing.CronString()).Next(now)
return at.stCache
}
// To be deleted after the above solution proves reliable
func (at *ActionTiming) GetNextStartTimeOld(now time.Time) (t time.Time) {
if !at.stCache.IsZero() {
return at.stCache
}
@@ -53,9 +77,19 @@ func (at *ActionTiming) GetNextStartTime(now time.Time) (t time.Time) {
if i == nil {
return
}
// Normalize
if i.Timing.StartTime == "" {
i.Timing.StartTime = "00:00:00"
}
if len(i.Timing.Years) > 0 && len(i.Timing.Months) == 0 {
i.Timing.Months = append(i.Timing.Months, 1)
}
if len(i.Timing.Months) > 0 && len(i.Timing.MonthDays) == 0 {
i.Timing.MonthDays = append(i.Timing.MonthDays, 1)
}
y, m, d := now.Date()
z, _ := now.Zone()
if i.Timing.StartTime != "" && i.Timing.StartTime != ASAP {
if i.Timing.StartTime != ASAP {
l := fmt.Sprintf("%d-%d-%d %s %s", y, m, d, i.Timing.StartTime, z)
var err error
t, err = time.Parse(FORMAT, l)
@@ -64,6 +98,9 @@ func (at *ActionTiming) GetNextStartTime(now time.Time) (t time.Time) {
at.stCache = t
return
}
if now.After(t) || now.Equal(t) { // Set it to next day this time
t = t.AddDate(0, 0, 1)
}
}
// weekdays
if i.Timing.WeekDays != nil && len(i.Timing.WeekDays) > 0 {
@@ -71,12 +108,12 @@ func (at *ActionTiming) GetNextStartTime(now time.Time) (t time.Time) {
if t.IsZero() {
t = time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), 0, now.Location())
}
d := t.Day()
for _, j := range []int{0, 1, 2, 3, 4, 5, 6, 7} {
t = time.Date(t.Year(), t.Month(), d, t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), t.Location()).AddDate(0, 0, j)
for j := 0; j < 8; j++ {
n := t.AddDate(0, 0, j)
for _, wd := range i.Timing.WeekDays {
if t.Weekday() == wd && (t.Equal(now) || t.After(now)) {
at.stCache = t
if n.Weekday() == wd && (n.Equal(now) || n.After(now)) {
at.stCache = n
t = n
return
}
}
@@ -85,15 +122,13 @@ func (at *ActionTiming) GetNextStartTime(now time.Time) (t time.Time) {
// monthdays
if i.Timing.MonthDays != nil && len(i.Timing.MonthDays) > 0 {
i.Timing.MonthDays.Sort()
year := now.Year()
month := now
x := sort.SearchInts(i.Timing.MonthDays, now.Day())
year := t.Year()
month := t
x := sort.SearchInts(i.Timing.MonthDays, t.Day())
d = i.Timing.MonthDays[0]
if x < len(i.Timing.MonthDays) {
if i.Timing.MonthDays[x] == now.Day() {
if i.Timing.MonthDays[x] == t.Day() {
if t.Equal(now) || t.After(now) {
h, m, s := t.Clock()
t = time.Date(now.Year(), now.Month(), now.Day(), h, m, s, 0, time.Local)
goto MONTHS
}
if x+1 < len(i.Timing.MonthDays) { // today was found in the list, jump to the next grater day
@@ -107,11 +142,6 @@ func (at *ActionTiming) GetNextStartTime(now time.Time) (t time.Time) {
} else { // today was not found in the list, x is the first greater day
d = i.Timing.MonthDays[x]
}
} else {
if len(i.Timing.Months) == 0 {
t = time.Date(month.Year(), month.Month(), d, 0, 0, 0, 0, time.Local).AddDate(0, 1, 0)
month = t
}
}
h, m, s := t.Clock()
t = time.Date(month.Year(), month.Month(), d, h, m, s, 0, time.Local)
@@ -119,22 +149,18 @@ func (at *ActionTiming) GetNextStartTime(now time.Time) (t time.Time) {
MONTHS:
if i.Timing.Months != nil && len(i.Timing.Months) > 0 {
i.Timing.Months.Sort()
year := now.Year()
x := sort.Search(len(i.Timing.Months), func(x int) bool { return i.Timing.Months[x] >= now.Month() })
year := t.Year()
x := sort.Search(len(i.Timing.Months), func(x int) bool { return i.Timing.Months[x] >= t.Month() })
m = i.Timing.Months[0]
if x < len(i.Timing.Months) {
if i.Timing.Months[x] == now.Month() {
if i.Timing.Months[x] == t.Month() {
if t.Equal(now) || t.After(now) {
//h, m, s := t.Clock()
//t = time.Date(now.Year(), now.Month(), t.Day(), h, m, s, 0, time.Local)
goto YEARS
}
if x+1 < len(i.Timing.Months) { // this month was found in the list so jump to next available month
m = i.Timing.Months[x+1]
// reset the monthday
if i.Timing.MonthDays != nil {
t = time.Date(t.Year(), t.Month(), i.Timing.MonthDays[0], t.Hour(), t.Minute(), t.Second(), 0, t.Location())
}
t = time.Date(t.Year(), t.Month(), i.Timing.MonthDays[0], t.Hour(), t.Minute(), t.Second(), 0, t.Location())
} else { // jump to next year
//not using now to make sure the next year has the the 1 date
//(if today is 31) next month may not have it
@@ -144,18 +170,15 @@ MONTHS:
} else { // this month was not found in the list, x is the first greater month
m = i.Timing.Months[x]
// reset the monthday
if i.Timing.MonthDays != nil {
t = time.Date(t.Year(), t.Month(), i.Timing.MonthDays[0], t.Hour(), t.Minute(), t.Second(), 0, t.Location())
}
}
} else {
if len(i.Timing.Years) == 0 {
t = time.Date(year, m, t.Day(), 0, 0, 0, 0, time.Local).AddDate(1, 0, 0)
year = t.Year()
t = time.Date(t.Year(), t.Month(), i.Timing.MonthDays[0], t.Hour(), t.Minute(), t.Second(), 0, t.Location())
}
}
h, min, s := t.Clock()
t = time.Date(year, m, t.Day(), h, min, s, 0, time.Local)
} else {
if now.After(t) {
t = t.AddDate(0, 1, 0)
}
}
YEARS:
if i.Timing.Years != nil && len(i.Timing.Years) > 0 {
@@ -177,24 +200,20 @@ YEARS:
t = time.Date(t.Year(), i.Timing.Months[0], t.Day(), t.Hour(), t.Minute(), t.Second(), 0, t.Location())
}
// reset the monthday
if i.Timing.MonthDays != nil {
t = time.Date(t.Year(), t.Month(), i.Timing.MonthDays[0], t.Hour(), t.Minute(), t.Second(), 0, t.Location())
}
t = time.Date(t.Year(), t.Month(), i.Timing.MonthDays[0], t.Hour(), t.Minute(), t.Second(), 0, t.Location())
}
} else { // this year was not found in the list, x is the first greater year
y = i.Timing.Years[x]
// reset the month
if i.Timing.Months != nil {
t = time.Date(t.Year(), i.Timing.Months[0], t.Day(), t.Hour(), t.Minute(), t.Second(), 0, t.Location())
}
// reset the monthday
if i.Timing.MonthDays != nil {
t = time.Date(t.Year(), t.Month(), i.Timing.MonthDays[0], t.Hour(), t.Minute(), t.Second(), 0, t.Location())
}
// reset the month/monthday
t = time.Date(t.Year(), i.Timing.Months[0], i.Timing.MonthDays[0], t.Hour(), t.Minute(), t.Second(), 0, t.Location())
}
}
h, min, s := t.Clock()
t = time.Date(y, t.Month(), t.Day(), h, min, s, 0, time.Local)
} else {
if now.After(t) {
t = t.AddDate(1, 0, 0)
}
}
at.stCache = t
return

View File

@@ -28,13 +28,23 @@ import (
)
var (
//referenceDate = time.Date(2014, 1, 1, 0, 0, 0, 0, time.Local)
//referenceDate = time.Date(2013, 7, 10, 10, 30, 0, 0, time.Local)
//referenceDate = time.Date(2013, 12, 31, 23, 59, 59, 0, time.Local)
//referenceDate = time.Date(2011, 1, 1, 0, 0, 0, 1, time.Local)
referenceDate = time.Now()
now = referenceDate
)
func TestActionTimingAlways(t *testing.T) {
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{StartTime: "00:00:00"}}}
st := at.GetNextStartTime(referenceDate)
y, m, d := referenceDate.Date()
expected := time.Date(y, m, d, 0, 0, 0, 0, time.Local).AddDate(0, 0, 1)
if !st.Equal(expected) {
t.Errorf("Expected %v was %v", expected, st)
}
}
func TestActionTimingNothing(t *testing.T) {
at := &ActionTiming{}
st := at.GetNextStartTime(referenceDate)
@@ -50,17 +60,18 @@ func TestActionTimingOnlyHour(t *testing.T) {
y, m, d := now.Date()
expected := time.Date(y, m, d, 10, 1, 0, 0, time.Local)
if referenceDate.After(expected) {
expected = expected.AddDate(0, 0, 1)
}
if !st.Equal(expected) {
t.Errorf("Expected %v was %v", expected, st)
}
}
func TestActionTimingHourYear(t *testing.T) {
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{2012}, StartTime: "10:01:00"}}}
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{2022}, StartTime: "10:01:00"}}}
st := at.GetNextStartTime(referenceDate)
_, m, d := now.Date()
expected := time.Date(2012, m, d, 10, 1, 0, 0, time.Local)
expected := time.Date(2022, 1, 1, 10, 1, 0, 0, time.Local)
if !st.Equal(expected) {
t.Errorf("Expected %v was %v", expected, st)
}
@@ -74,9 +85,11 @@ func TestActionTimingOnlyWeekdays(t *testing.T) {
h, min, s := now.Clock()
e := time.Date(y, m, d, h, min, s, 0, time.Local)
day := e.Day()
for _, i := range []int{0, 1, 2, 3, 4, 5, 6, 7} {
e = time.Date(e.Year(), e.Month(), day, e.Hour(), e.Minute(), e.Second(), e.Nanosecond(), e.Location()).AddDate(0, 0, i)
if e.Weekday() == time.Monday && (e.Equal(now) || e.After(now)) {
e = time.Date(e.Year(), e.Month(), day, 0, 0, 0, 0, e.Location())
for i := 0; i < 8; i++ {
n := e.AddDate(0, 0, i)
if n.Weekday() == time.Monday && (n.Equal(now) || n.After(now)) {
e = n
break
}
}
@@ -92,9 +105,11 @@ func TestActionTimingHourWeekdays(t *testing.T) {
y, m, d := now.Date()
e := time.Date(y, m, d, 10, 1, 0, 0, time.Local)
day := e.Day()
for _, i := range []int{0, 1, 2, 3, 4, 5, 6, 7} {
e = time.Date(e.Year(), e.Month(), day, e.Hour(), e.Minute(), e.Second(), e.Nanosecond(), e.Location()).AddDate(0, 0, i)
if e.Weekday() == time.Monday && (e.Equal(now) || e.After(now)) {
for i := 0; i < 8; i++ {
e = time.Date(e.Year(), e.Month(), day, e.Hour(), e.Minute(), e.Second(), e.Nanosecond(), e.Location())
n := e.AddDate(0, 0, i)
if n.Weekday() == time.Monday && (n.Equal(now) || n.After(now)) {
e = n
break
}
}
@@ -149,6 +164,10 @@ func TestActionTimingHourMonths(t *testing.T) {
y, m, d := now.Date()
testTime := time.Date(y, m, d, 10, 1, 0, 0, time.Local)
nextMonth := time.Date(y, m, 1, 0, 0, 0, 0, time.Local).AddDate(0, 1, 0)
if now.After(testTime) {
testTime = testTime.AddDate(0, 0, 1)
y, m, d = testTime.Date()
}
if now.After(testTime) {
m = nextMonth.Month()
y = nextMonth.Year()
@@ -158,7 +177,10 @@ func TestActionTimingHourMonths(t *testing.T) {
Months: utils.Months{now.Month(), nextMonth.Month()},
StartTime: "10:01:00"}}}
st := at.GetNextStartTime(referenceDate)
expected := time.Date(y, m, d, 10, 1, 0, 0, time.Local)
expected := time.Date(y, m, 1, 10, 1, 0, 0, time.Local)
if referenceDate.After(expected) {
expected = expected.AddDate(0, 1, 0)
}
if !st.Equal(expected) {
t.Errorf("Expected %v was %v", expected, st)
}
@@ -212,38 +234,32 @@ func TestActionTimingFirstOfTheMonth(t *testing.T) {
}
func TestActionTimingOnlyYears(t *testing.T) {
y, m, d := now.Date()
nextYear := time.Date(y, m, d, 0, 0, 0, 0, time.Local).AddDate(1, 0, 0)
y, _, _ := referenceDate.Date()
nextYear := time.Date(y, 1, 1, 0, 0, 0, 0, time.Local).AddDate(1, 0, 0)
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{now.Year(), nextYear.Year()}}}}
st := at.GetNextStartTime(referenceDate)
expected := time.Date(nextYear.Year(), 1, 1, 0, 0, 0, 0, time.Local)
expected := nextYear
if !st.Equal(expected) {
t.Errorf("Expected %v was %v", expected, st)
}
}
func TestActionTimingPast(t *testing.T) {
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{2013}}}}
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{2023}}}}
st := at.GetNextStartTime(referenceDate)
expected := time.Date(2013, 1, 1, 0, 0, 0, 0, time.Local)
expected := time.Date(2023, 1, 1, 0, 0, 0, 0, time.Local)
if !st.Equal(expected) {
t.Errorf("Expected %v was %v", expected, st)
}
}
func TestActionTimingHourYears(t *testing.T) {
y, m, d := now.Date()
testTime := time.Date(y, m, d, 10, 1, 0, 0, time.Local)
nextYear := time.Date(y, m, d, 0, 0, 0, 0, time.Local).AddDate(1, 0, 0)
year := now.Year()
if now.After(testTime) {
year = nextYear.Year()
}
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{now.Year(), nextYear.Year()}, StartTime: "10:01:00"}}}
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{referenceDate.Year(), referenceDate.Year() + 1}, StartTime: "10:01:00"}}}
st := at.GetNextStartTime(referenceDate)
expected := time.Date(year, m, d, 10, 1, 0, 0, time.Local)
expected := time.Date(referenceDate.Year(), 1, 1, 10, 1, 0, 0, time.Local)
if referenceDate.After(expected) {
expected = expected.AddDate(1, 0, 0)
}
if !st.Equal(expected) {
t.Errorf("Expected %v was %v", expected, st)
}
@@ -252,17 +268,16 @@ func TestActionTimingHourYears(t *testing.T) {
func TestActionTimingHourMonthdaysYear(t *testing.T) {
y, m, d := now.Date()
testTime := time.Date(y, m, d, 10, 1, 0, 0, time.Local)
nextYear := time.Date(y, m, 1, 0, 0, 0, 0, time.Local).AddDate(1, 0, 0)
testTime := time.Date(y, 1, d, 10, 1, 0, 0, time.Local)
tomorrow := time.Date(y, m, d, 0, 0, 0, 0, time.Local).AddDate(0, 0, 1)
if now.After(testTime) {
y, m, d = tomorrow.Date()
}
nextDay := time.Date(y, m, d, 10, 1, 0, 0, time.Local)
year := nextDay.Year()
if nextDay.Before(now) {
if now.After(testTime) {
year = nextYear.Year()
nextYear := time.Date(y, 1, 1, 10, 1, 0, 0, time.Local).AddDate(1, 0, 0)
nextDay := time.Date(y, 1, 1, 10, 1, 0, 0, time.Local).AddDate(1, 0, 0)
expected := testTime
if referenceDate.After(testTime) {
if referenceDate.After(nextDay) {
expected = nextYear
} else {
expected = nextDay
}
}
at := &ActionTiming{Timing: &RateInterval{
@@ -273,7 +288,6 @@ func TestActionTimingHourMonthdaysYear(t *testing.T) {
},
}}
st := at.GetNextStartTime(referenceDate)
expected := time.Date(year, m, d, 10, 1, 0, 0, time.Local)
if !st.Equal(expected) {
t.Errorf("Expected %v was %v", expected, st)
}
@@ -339,14 +353,34 @@ func TestActionTimingFirstOfTheYear(t *testing.T) {
func TestActionTimingFirstMonthOfTheYear(t *testing.T) {
y, _, _ := now.Date()
nextYear := time.Date(y, 1, 1, 0, 0, 0, 0, time.Local).AddDate(1, 0, 0)
expected := time.Date(y, 1, 1, 0, 0, 0, 0, time.Local)
if referenceDate.After(expected) {
expected = expected.AddDate(1, 0, 0)
}
at := &ActionTiming{Timing: &RateInterval{
Timing: &RITiming{
Months: utils.Months{time.January},
},
}}
st := at.GetNextStartTime(referenceDate)
expected := nextYear
if !st.Equal(expected) {
t.Errorf("Expected %v was %v", expected, st)
}
}
func TestActionTimingFirstMonthOfTheYearSecondDay(t *testing.T) {
y, _, _ := now.Date()
expected := time.Date(y, 1, 2, 0, 0, 0, 0, time.Local)
if referenceDate.After(expected) {
expected = expected.AddDate(1, 0, 0)
}
at := &ActionTiming{Timing: &RateInterval{
Timing: &RITiming{
Months: utils.Months{time.January},
MonthDays: utils.MonthDays{2},
},
}}
st := at.GetNextStartTime(referenceDate)
if !st.Equal(expected) {
t.Errorf("Expected %v was %v", expected, st)
}
@@ -377,7 +411,7 @@ func TestActionTimingLogFunction(t *testing.T) {
func TestActionTimingPriotityListSortByWeight(t *testing.T) {
at1 := &ActionTiming{Timing: &RateInterval{
Timing: &RITiming{
Years: utils.Years{2100},
Years: utils.Years{2020},
Months: utils.Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December},
MonthDays: utils.MonthDays{1},
StartTime: "00:00:00",
@@ -386,7 +420,7 @@ func TestActionTimingPriotityListSortByWeight(t *testing.T) {
}}
at2 := &ActionTiming{Timing: &RateInterval{
Timing: &RITiming{
Years: utils.Years{2100},
Years: utils.Years{2020},
Months: utils.Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December},
MonthDays: utils.MonthDays{2},
StartTime: "00:00:00",
@@ -909,8 +943,8 @@ func TestActionTriggerLogging(t *testing.T) {
_ = k
_ = v
/*if strings.Contains(k, LOG_ACTION_TRIGGER_PREFIX) && strings.Contains(v, expected) {
key = k
break
key = k
break
}*/
}
if key != "" {
@@ -953,7 +987,7 @@ func TestActionTimingLogging(t *testing.T) {
_ = k
_ = v
/*if strings.Contains(k, LOG_ACTION_TIMMING_PREFIX) && strings.Contains(string(v), expected) {
key = k
key = k
}*/
}
if key != "" {

View File

@@ -532,28 +532,28 @@ func TestLoadRatingPlans(t *testing.T) {
expected := &RatingPlan{
Id: "STANDARD",
Timings: map[string]*RITiming{
"14ae6e41": &RITiming{
"4c954a4f": &RITiming{
Years: utils.Years{},
Months: utils.Months{},
MonthDays: utils.MonthDays{},
WeekDays: utils.WeekDays{1, 2, 3, 4, 5},
StartTime: "00:00:00",
},
"9a6f8e32": &RITiming{
"4d593287": &RITiming{
Years: utils.Years{},
Months: utils.Months{},
MonthDays: utils.MonthDays{},
WeekDays: utils.WeekDays{1, 2, 3, 4, 5},
StartTime: "18:00:00",
},
"7181e535": &RITiming{
"a60bfb13": &RITiming{
Years: utils.Years{},
Months: utils.Months{},
MonthDays: utils.MonthDays{},
WeekDays: utils.WeekDays{time.Saturday, time.Sunday},
StartTime: "00:00:00",
},
"96c78ff5": &RITiming{
"30eab300": &RITiming{
Years: utils.Years{},
Months: utils.Months{},
MonthDays: utils.MonthDays{},
@@ -618,48 +618,48 @@ func TestLoadRatingPlans(t *testing.T) {
DestinationRates: map[string]RPRateList{
"GERMANY": []*RPRate{
&RPRate{
Timing: "14ae6e41",
Timing: "4c954a4f",
Rating: "822a5aef",
Weight: 10,
},
&RPRate{
Timing: "9a6f8e32",
Timing: "4d593287",
Rating: "4a25c533",
Weight: 10,
},
&RPRate{
Timing: "7181e535",
Timing: "a60bfb13",
Rating: "4a25c533",
Weight: 10,
},
},
"GERMANY_O2": []*RPRate{
&RPRate{
Timing: "14ae6e41",
Timing: "4c954a4f",
Rating: "4a25c533",
Weight: 10,
},
&RPRate{
Timing: "9a6f8e32",
Timing: "4d593287",
Rating: "b05c5f6b",
Weight: 10,
},
&RPRate{
Timing: "7181e535",
Timing: "a60bfb13",
Rating: "b05c5f6b",
Weight: 10,
},
},
"GERMANY_PREMIUM": []*RPRate{
&RPRate{
Timing: "14ae6e41",
Timing: "4c954a4f",
Rating: "4a25c533",
Weight: 10,
},
},
"URG": []*RPRate{
&RPRate{
Timing: "96c78ff5",
Timing: "30eab300",
Rating: "9f49ef8e",
Weight: 20,
},
@@ -667,7 +667,7 @@ func TestLoadRatingPlans(t *testing.T) {
},
}
if !reflect.DeepEqual(rplan, expected) {
t.Errorf("Error loading destination rate timing: %+v", rplan.DestinationRates["URG"][0])
t.Errorf("Error loading destination rate timing: %+v", rplan.DestinationRates["GERMANY_O2"][0])
}
}

View File

@@ -187,7 +187,7 @@ func (self *Mediator) RateCdr(storedCdr *utils.StoredCdr, sendToStats bool) erro
func (self *Mediator) RateCdrs(cgrIds, runIds, tors, cdrHosts, cdrSources, reqTypes, directions, tenants, categories, accounts, subjects, destPrefixes, ratedAccounts, ratedSubjects []string, orderIdStart, orderIdEnd int64, timeStart, timeEnd time.Time, rerateErrors, rerateRated, sendToStats bool) error {
cdrs, err := self.cdrDb.GetStoredCdrs(cgrIds, runIds, tors, cdrHosts, cdrSources, reqTypes, directions, tenants, categories, accounts, subjects, destPrefixes, ratedAccounts, ratedSubjects,
orderIdStart, orderIdEnd, timeStart, timeEnd, !rerateErrors, !rerateRated, true)
orderIdStart, orderIdEnd, timeStart, timeEnd, !rerateErrors, !rerateRated, true, nil)
if err != nil {
return err
}

View File

@@ -156,12 +156,12 @@ func TestPostCdrs(t *testing.T) {
}
}
time.Sleep(100 * time.Millisecond) // Give time for CDRs to reach database
if storedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, false, false, false); err != nil {
if storedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, false, false, false, nil); err != nil {
t.Error(err)
} else if len(storedCdrs) != 6 { // Make sure CDRs made it into StorDb
t.Error(fmt.Sprintf("Unexpected number of CDRs stored: %d", len(storedCdrs)))
}
if nonErrorCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, true, false, false); err != nil {
if nonErrorCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, true, false, false, nil); err != nil {
t.Error(err)
} else if len(nonErrorCdrs) != 0 {
t.Error(fmt.Sprintf("Unexpected number of CDRs stored: %d", len(nonErrorCdrs)))
@@ -184,12 +184,12 @@ func TestInjectCdrs(t *testing.T) {
t.Error(err)
}
}
if storedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, false, false, false); err != nil {
if storedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, false, false, false, nil); err != nil {
t.Error(err)
} else if len(storedCdrs) != 8 { // Make sure CDRs made it into StorDb
t.Error(fmt.Sprintf("Unexpected number of CDRs stored: %d", len(storedCdrs)))
}
if nonRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, true, true, false); err != nil {
if nonRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, true, true, false, nil); err != nil {
t.Error(err)
} else if len(nonRatedCdrs) != 2 { // Just two of them should be non-rated
t.Error(fmt.Sprintf("Unexpected number of CDRs non-rated: %d", len(nonRatedCdrs)))
@@ -221,12 +221,12 @@ func TestRateCdrs(t *testing.T) {
} else if reply != utils.OK {
t.Errorf("Unexpected reply: %s", reply)
}
if nonRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, true, true, false); err != nil {
if nonRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, true, true, false, nil); err != nil {
t.Error(err)
} else if len(nonRatedCdrs) != 0 { // All CDRs should be rated
t.Error(fmt.Sprintf("Unexpected number of CDRs non-rated: %d", len(nonRatedCdrs)))
}
if errRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, false, true, false); err != nil {
if errRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, false, true, false, nil); err != nil {
t.Error(err)
} else if len(errRatedCdrs) != 8 { // The first 2 with errors should be still there before rerating
t.Error(fmt.Sprintf("Unexpected number of CDRs with errors: %d", len(errRatedCdrs)))
@@ -236,7 +236,7 @@ func TestRateCdrs(t *testing.T) {
} else if reply != utils.OK {
t.Errorf("Unexpected reply: %s", reply)
}
if errRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, false, true, false); err != nil {
if errRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, false, true, false, nil); err != nil {
t.Error(err)
} else if len(errRatedCdrs) != 4 {
t.Error(fmt.Sprintf("Unexpected number of CDRs with errors: %d", len(errRatedCdrs)))

View File

@@ -45,6 +45,74 @@ type RITiming struct {
MonthDays utils.MonthDays
WeekDays utils.WeekDays
StartTime, EndTime string // ##:##:## format
cronString string
}
func (rit *RITiming) CronString() string {
if rit.cronString != "" {
return rit.cronString
}
var sec, min, hour, monthday, month, weekday, year string
if len(rit.StartTime) == 0 {
hour, min, sec = "*", "*", "*"
} else {
hms := strings.Split(rit.StartTime, ":")
if len(hms) != 3 {
hour, min, sec = "*", "*", "*"
}
hour, min, sec = hms[0], hms[1], hms[2]
if strings.HasPrefix(hour, "0") {
hour = hour[1:]
}
if strings.HasPrefix(min, "0") {
min = min[1:]
}
if strings.HasPrefix(sec, "0") {
sec = sec[1:]
}
}
if len(rit.MonthDays) == 0 {
monthday = "*"
} else {
for i, md := range rit.MonthDays {
if i > 0 {
monthday += ","
}
monthday += strconv.Itoa(md)
}
}
if len(rit.Months) == 0 {
month = "*"
} else {
for i, md := range rit.Months {
if i > 0 {
month += ","
}
month += strconv.Itoa(int(md))
}
}
if len(rit.WeekDays) == 0 {
weekday = "*"
} else {
for i, md := range rit.WeekDays {
if i > 0 {
weekday += ","
}
weekday += strconv.Itoa(int(md))
}
}
if len(rit.Years) == 0 {
year = "*"
} else {
for i, md := range rit.Years {
if i > 0 {
year += ","
}
year += strconv.Itoa(int(md))
}
}
rit.cronString = fmt.Sprintf("%s %s %s %s %s %s %s", sec, min, hour, monthday, month, weekday, year)
return rit.cronString
}
func (rit *RITiming) Stringify() string {

View File

@@ -19,9 +19,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package engine
import (
"github.com/cgrates/cgrates/utils"
"testing"
"time"
"github.com/cgrates/cgrates/utils"
)
func TestRateIntervalSimpleContains(t *testing.T) {
@@ -283,6 +284,59 @@ func TestRateStrigyfy(t *testing.T) {
}
}
func TestRateIntervalCronAll(t *testing.T) {
rit := &RITiming{
Years: utils.Years{2012},
Months: utils.Months{time.February},
MonthDays: utils.MonthDays{1},
WeekDays: []time.Weekday{time.Sunday},
StartTime: "14:30:00",
}
expected := "0 30 14 1 2 0 2012"
cron := rit.CronString()
if cron != expected {
t.Errorf("Expected %s was %s", expected, cron)
}
}
func TestRateIntervalCronMultiple(t *testing.T) {
rit := &RITiming{
Years: utils.Years{2012, 2014},
Months: utils.Months{time.February, time.January},
MonthDays: utils.MonthDays{15, 16},
WeekDays: []time.Weekday{time.Sunday, time.Monday},
StartTime: "14:30:00",
}
expected := "0 30 14 15,16 2,1 0,1 2012,2014"
cron := rit.CronString()
if cron != expected {
t.Errorf("Expected %s was %s", expected, cron)
}
}
func TestRateIntervalCronStar(t *testing.T) {
rit := &RITiming{
StartTime: "*:30:00",
}
expected := "0 30 * * * * *"
cron := rit.CronString()
if cron != expected {
t.Errorf("Expected %s was %s", expected, cron)
}
}
func TestRateIntervalCronEmpty(t *testing.T) {
rit := &RITiming{}
expected := "* * * * * * *"
cron := rit.CronString()
if cron != expected {
t.Errorf("Expected %s was %s", expected, cron)
}
}
/*********************************Benchmarks**************************************/
func BenchmarkRateIntervalContainsDate(b *testing.B) {

View File

@@ -152,19 +152,16 @@ func (rs *Responder) FlushCache(arg CallDescriptor, reply *float64) (err error)
return
}
func (rs *Responder) Status(arg string, reply *string) (err error) {
func (rs *Responder) Status(arg string, reply *map[string]interface{}) (err error) {
memstats := new(runtime.MemStats)
runtime.ReadMemStats(memstats)
response := make(map[string]interface{})
if rs.Bal != nil {
*reply = "Connected raters:\n"
for _, rater := range rs.Bal.GetClientAddresses() {
*reply += fmt.Sprintf("%v\n", rater)
}
*reply += fmt.Sprintf("memstats before GC: %dKb footprint: %dKb", memstats.HeapAlloc/1024, memstats.Sys/1024)
} else {
*reply = fmt.Sprintf("memstats before GC: %dKb footprint: %dKb", memstats.HeapAlloc/1024, memstats.Sys/1024)
response["Raters"] = rs.Bal.GetClientAddresses()
}
response["memstat"] = memstats.HeapAlloc / 1024
response["footprint"] = memstats.Sys / 1024
*reply = response
return
}

View File

@@ -65,6 +65,7 @@ const (
type Storage interface {
Close()
Flush() error
GetKeysForPrefix(string) ([]string, error)
}
/*
@@ -117,7 +118,7 @@ type CdrStorage interface {
SetCdr(*utils.StoredCdr) error
SetRatedCdr(*utils.StoredCdr, string) error
GetStoredCdrs([]string, []string, []string, []string, []string, []string, []string, []string, []string, []string, []string, []string, []string, []string,
int64, int64, time.Time, time.Time, bool, bool, bool) ([]*utils.StoredCdr, error)
int64, int64, time.Time, time.Time, bool, bool, bool, *utils.TPPagination) ([]*utils.StoredCdr, error)
RemStoredCdrs([]string) error
}

View File

@@ -52,6 +52,10 @@ func (ms *MapStorage) Flush() error {
return nil
}
func (ms *MapStorage) GetKeysForPrefix(string) ([]string, error) {
return nil, nil
}
func (ms *MapStorage) CacheRating(dKeys, rpKeys, rpfKeys, alsKeys, lcrKeys []string) error {
cache2go.BeginTransaction()
if dKeys == nil {

View File

@@ -63,6 +63,10 @@ func (ms *MongoStorage) Close() {
ms.session.Close()
}
func (ms *MongoStorage) GetKeysForPrefix(prefix string) ([]string, error) {
return nil, nil
}
func (ms *MongoStorage) Flush() (err error) {
err = ms.db.C("ratingprofiles").DropCollection()
if err != nil {

View File

@@ -67,6 +67,10 @@ func (rs *RedisStorage) Flush() (err error) {
return
}
func (rs *RedisStorage) GetKeysForPrefix(prefix string) ([]string, error) {
return rs.db.Keys(prefix + "*")
}
func (rs *RedisStorage) CacheRating(dKeys, rpKeys, rpfKeys, alsKeys, lcrKeys []string) (err error) {
cache2go.BeginTransaction()
if dKeys == nil {

View File

@@ -60,6 +60,10 @@ func (self *SQLStorage) Flush() (err error) {
return nil
}
func (self *SQLStorage) GetKeysForPrefix(prefix string) ([]string, error) {
return nil, nil
}
func (self *SQLStorage) CreateTablesFromScript(scriptPath string) error {
fileContent, err := ioutil.ReadFile(scriptPath)
if err != nil {
@@ -125,7 +129,7 @@ func (self *SQLStorage) GetTPTableIds(tpid, table string, distinct utils.TPDisti
qry += fmt.Sprintf(")")
}
if pagination != nil {
limLow, limHigh := pagination.GetLimit()
limLow, limHigh := pagination.GetLimits()
qry += fmt.Sprintf(" LIMIT %d,%d", limLow, limHigh)
}
@@ -523,8 +527,8 @@ func (self *SQLStorage) SetTPActionTimings(tpid string, ats map[string][]*utils.
})
}
}
tx.Commit()
return nil
r := tx.Commit()
return r.Error
}
func (self *SQLStorage) GetTPActionTimings(tpid, tag string) (map[string][]*utils.TPActionTiming, error) {
@@ -734,7 +738,7 @@ func (self *SQLStorage) SetRatedCdr(storedCdr *utils.StoredCdr, extraInfo string
// ignoreErr - do not consider cdrs with rating errors
// ignoreRated - do not consider cdrs which were already rated, including here the ones with errors
func (self *SQLStorage) GetStoredCdrs(cgrIds, runIds, tors, cdrHosts, cdrSources, reqTypes, directions, tenants, categories, accounts, subjects, destPrefixes, ratedAccounts, ratedSubjects []string,
orderIdStart, orderIdEnd int64, timeStart, timeEnd time.Time, ignoreErr, ignoreRated, ignoreDerived bool) ([]*utils.StoredCdr, error) {
orderIdStart, orderIdEnd int64, timeStart, timeEnd time.Time, ignoreErr, ignoreRated, ignoreDerived bool, pagination *utils.TPPagination) ([]*utils.StoredCdr, error) {
var cdrs []*utils.StoredCdr
var q *bytes.Buffer // Need to query differently since in case of primary, unmediated CDRs some values will be missing
if ignoreDerived {
@@ -1053,6 +1057,10 @@ func (self *SQLStorage) GetStoredCdrs(cgrIds, runIds, tors, cdrHosts, cdrSources
if fltr.Len() != 0 {
q.WriteString(fmt.Sprintf(" WHERE %s", fltr.String()))
}
if pagination != nil {
limLow, limHigh := pagination.GetLimits()
q.WriteString(fmt.Sprintf(" LIMIT %d,%d", limLow, limHigh))
}
rows, err := self.Db.Query(q.String())
if err != nil {
return nil, err

View File

@@ -20,12 +20,13 @@ package engine
import (
"fmt"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/utils"
"path"
"reflect"
"testing"
"time"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/utils"
)
/*
@@ -257,7 +258,7 @@ func TestGetStoredCdrs(t *testing.T) {
}
var timeStart, timeEnd time.Time
// All CDRs, no filter
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 8 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
@@ -265,7 +266,7 @@ func TestGetStoredCdrs(t *testing.T) {
// Filter on cgrids
if storedCdrs, err := mysqlDb.GetStoredCdrs([]string{utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()),
utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())},
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 2 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
@@ -273,172 +274,172 @@ func TestGetStoredCdrs(t *testing.T) {
// Filter on cgrids plus reqType
if storedCdrs, err := mysqlDb.GetStoredCdrs([]string{utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()),
utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())},
nil, nil, nil, nil, []string{"prepaid"}, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
nil, nil, nil, nil, []string{"prepaid"}, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 1 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on runId
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, []string{utils.DEFAULT_RUNID},
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 2 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on TOR
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, []string{utils.SMS},
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 0 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on multiple TOR
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, []string{utils.SMS, utils.VOICE},
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 8 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on cdrHost
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, []string{"192.168.1.2"},
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 3 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on multiple cdrHost
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, []string{"192.168.1.1", "192.168.1.2"}, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
0, 0, timeStart, timeEnd, false, false, false); err != nil {
0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 8 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on cdrSource
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, []string{"UNKNOWN"},
nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 1 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on multiple cdrSource
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, []string{"UNKNOWN", "UNKNOWN2"},
nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 2 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on reqType
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, []string{"prepaid"},
nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 2 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on multiple reqType
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, []string{"prepaid", "pseudoprepaid"}, nil, nil, nil, nil, nil, nil, nil, nil,
0, 0, timeStart, timeEnd, false, false, false); err != nil {
0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 3 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on direction
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, []string{"*out"}, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, []string{"*out"}, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 8 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on tenant
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, []string{"itsyscom.com"}, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, []string{"itsyscom.com"}, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 3 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on multiple tenants
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, []string{"itsyscom.com", "cgrates.org"}, nil, nil, nil, nil, nil, nil,
0, 0, timeStart, timeEnd, false, false, false); err != nil {
0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 8 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on tor
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, []string{"premium_call"},
nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 1 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on multiple tor
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, []string{"premium_call", "call"},
nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 8 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on account
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1002"},
nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 3 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on multiple account
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1001", "1002"},
nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 8 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on subject
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1000"},
nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 1 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on multiple subject
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1000", "1002"},
nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 3 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on destPrefix
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil, []string{"+498651"}, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
nil, nil, nil, nil, nil, []string{"+498651"}, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 3 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on multiple destPrefixes
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1001", "+498651"}, nil, nil,
0, 0, timeStart, timeEnd, false, false, false); err != nil {
0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 4 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on ratedAccount
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
nil, nil, []string{"8001"}, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
nil, nil, []string{"8001"}, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 1 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on ratedSubject
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
nil, nil, nil, []string{"91001"}, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
nil, nil, nil, []string{"91001"}, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 1 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on ignoreErr
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, true, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, true, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 8 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on ignoreRated
var orderIdStart, orderIdEnd int64 // Capture also orderIds for the next test
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, true, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, true, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 5 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
@@ -453,41 +454,41 @@ func TestGetStoredCdrs(t *testing.T) {
}
}
// Filter on orderIdStart
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, orderIdStart, 0, timeStart, timeEnd, false, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, orderIdStart, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 8 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on orderIdStart and orderIdEnd
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, orderIdStart, orderIdEnd+1, timeStart, timeEnd,
false, false, false); err != nil {
false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 5 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on timeStart
timeStart = time.Date(2013, 11, 8, 8, 0, 0, 0, time.UTC)
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 5 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on timeStart and timeEnd
timeEnd = time.Date(2013, 12, 1, 8, 0, 0, 0, time.UTC)
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 2 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Combined filter
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, []string{"rated"}, nil, nil, nil, nil, nil,
nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 1 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
}
// Filter on ignoreDerived
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, true); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, true, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 2 { // ToDo: Recheck this value
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
@@ -503,7 +504,7 @@ func TestRemStoredCdrs(t *testing.T) {
if err := mysqlDb.RemStoredCdrs([]string{cgrIdB1}); err != nil {
t.Error(err.Error())
}
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 7 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
@@ -524,7 +525,7 @@ func TestRemStoredCdrs(t *testing.T) {
cgrIdB2, cgrIdB3}); err != nil {
t.Error(err.Error())
}
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false); err != nil {
if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil {
t.Error(err.Error())
} else if len(storedCdrs) != 0 {
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)

View File

@@ -14,6 +14,7 @@ libs = ('code.google.com/p/goconf/conf',
'github.com/hoisie/redis'
'github.com/howeyc/fsnotify',
'github.com/jinzhu/gorm',
'github.com/gorhill/cronexpr',
)
if __name__ == "__main__":

View File

@@ -11,3 +11,4 @@ go get -u -v github.com/howeyc/fsnotify
go get -u -v github.com/cgrates/liner
go get -u -v github.com/cgrates/rpcclient
go get -u -v github.com/jinzhu/gorm
go get -u -v github.com/gorhill/cronexpr

View File

@@ -40,7 +40,7 @@ type TPPagination struct {
SearchTerm string
}
func (pag *TPPagination) GetLimit() (low, high int) {
func (pag *TPPagination) GetLimits() (low, high int) {
if pag.ItemsPerPage == 0 {
return 0, math.MaxInt32
}
@@ -582,6 +582,9 @@ type AttrGetCdrs struct {
TimeEnd string // If provided, it will represent the end of the CDRs interval (<)
SkipErrors bool // Do not export errored CDRs
SkipRated bool // Do not export rated CDRs
Page int
ItemsPerPage int
SearchTerm string
}
type AttrRemCdrs struct {