better validation and names fixes

This commit is contained in:
Radu Ioan Fericean
2015-06-08 11:06:14 +03:00
parent d3ec5c27e6
commit 2de5b4811c
13 changed files with 77 additions and 58 deletions

View File

@@ -547,12 +547,12 @@ func TestApierTPActionPlan(t *testing.T) {
return
}
reply := ""
at := &utils.TPActionPlan{TPid: engine.TEST_SQL, Id: "PREPAID_10", ActionPlan: []*utils.TPActionTiming{
at := &utils.TPActionPlan{TPid: engine.TEST_SQL, ActionPlanId: "PREPAID_10", ActionPlan: []*utils.TPActionTiming{
&utils.TPActionTiming{ActionsId: "PREPAID_10", TimingId: "ASAP", Weight: 10},
}}
atTst := new(utils.TPActionPlan)
*atTst = *at
atTst.Id = engine.TEST_SQL
atTst.ActionPlanId = engine.TEST_SQL
for _, act := range []*utils.TPActionPlan{at, atTst} {
if err := rater.Call("ApierV1.SetTPActionPlan", act, &reply); err != nil {
t.Error("Got error on ApierV1.SetTPActionPlan: ", err.Error())
@@ -574,13 +574,13 @@ func TestApierTPActionPlan(t *testing.T) {
}
// Test get
var rplyActs *utils.TPActionPlan
if err := rater.Call("ApierV1.GetTPActionPlan", AttrGetTPActionPlan{TPid: atTst.TPid, Id: atTst.Id}, &rplyActs); err != nil {
if err := rater.Call("ApierV1.GetTPActionPlan", AttrGetTPActionPlan{TPid: atTst.TPid, Id: atTst.ActionPlanId}, &rplyActs); err != nil {
t.Error("Calling ApierV1.GetTPActionPlan, got error: ", err.Error())
} else if !reflect.DeepEqual(atTst, rplyActs) {
t.Errorf("Calling ApierV1.GetTPActionPlan expected: %v, received: %v", atTst, rplyActs)
}
// Test remove
if err := rater.Call("ApierV1.RemTPActionPlan", AttrGetTPActionPlan{TPid: atTst.TPid, Id: atTst.Id}, &reply); err != nil {
if err := rater.Call("ApierV1.RemTPActionPlan", AttrGetTPActionPlan{TPid: atTst.TPid, Id: atTst.ActionPlanId}, &reply); err != nil {
t.Error("Calling ApierV1.RemTPActionPlan, got error: ", err.Error())
} else if reply != "OK" {
t.Error("Calling ApierV1.RemTPActionPlan received: ", reply)

View File

@@ -65,9 +65,9 @@ func (self *ApierV1) GetTPActionPlan(attrs AttrGetTPActionPlan, reply *utils.TPA
return err
}
atRply := &utils.TPActionPlan{
TPid: attrs.TPid,
Id: attrs.Id,
ActionPlan: aps[attrs.Id],
TPid: attrs.TPid,
ActionPlanId: attrs.Id,
ActionPlan: aps[attrs.Id],
}
*reply = *atRply
}

View File

@@ -311,7 +311,7 @@ func TestLoadTimimgs(t *testing.T) {
}
timing := csvr.timings["WORKDAYS_00"]
if !reflect.DeepEqual(timing, &utils.TPTiming{
Id: "WORKDAYS_00",
TimingId: "WORKDAYS_00",
Years: utils.Years{},
Months: utils.Months{},
MonthDays: utils.MonthDays{},
@@ -322,7 +322,7 @@ func TestLoadTimimgs(t *testing.T) {
}
timing = csvr.timings["WORKDAYS_18"]
if !reflect.DeepEqual(timing, &utils.TPTiming{
Id: "WORKDAYS_18",
TimingId: "WORKDAYS_18",
Years: utils.Years{},
Months: utils.Months{},
MonthDays: utils.MonthDays{},
@@ -333,7 +333,7 @@ func TestLoadTimimgs(t *testing.T) {
}
timing = csvr.timings["WEEKENDS"]
if !reflect.DeepEqual(timing, &utils.TPTiming{
Id: "WEEKENDS",
TimingId: "WEEKENDS",
Years: utils.Years{},
Months: utils.Months{},
MonthDays: utils.MonthDays{},
@@ -344,7 +344,7 @@ func TestLoadTimimgs(t *testing.T) {
}
timing = csvr.timings["ONE_TIME_RUN"]
if !reflect.DeepEqual(timing, &utils.TPTiming{
Id: "ONE_TIME_RUN",
TimingId: "ONE_TIME_RUN",
Years: utils.Years{2012},
Months: utils.Months{},
MonthDays: utils.MonthDays{},
@@ -581,33 +581,37 @@ func TestLoadRatingPlans(t *testing.T) {
expected := &RatingPlan{
Id: "STANDARD",
Timings: map[string]*RITiming{
"4c954a4f": &RITiming{
"59a981b9": &RITiming{
Years: utils.Years{},
Months: utils.Months{},
MonthDays: utils.MonthDays{},
WeekDays: utils.WeekDays{1, 2, 3, 4, 5},
StartTime: "00:00:00",
tag: "WORKDAYS_00",
},
"4d593287": &RITiming{
"2d9ca6c4": &RITiming{
Years: utils.Years{},
Months: utils.Months{},
MonthDays: utils.MonthDays{},
WeekDays: utils.WeekDays{1, 2, 3, 4, 5},
StartTime: "18:00:00",
tag: "WORKDAYS_18",
},
"a60bfb13": &RITiming{
"ec8ed374": &RITiming{
Years: utils.Years{},
Months: utils.Months{},
MonthDays: utils.MonthDays{},
WeekDays: utils.WeekDays{time.Saturday, time.Sunday},
StartTime: "00:00:00",
tag: "WEEKENDS",
},
"30eab300": &RITiming{
"83429156": &RITiming{
Years: utils.Years{},
Months: utils.Months{},
MonthDays: utils.MonthDays{},
WeekDays: utils.WeekDays{},
StartTime: "00:00:00",
tag: "ALWAYS",
},
},
Ratings: map[string]*RIRate{
@@ -623,6 +627,7 @@ func TestLoadRatingPlans(t *testing.T) {
},
RoundingMethod: utils.ROUNDING_MIDDLE,
RoundingDecimals: 4,
tag: "R1",
},
"16e9ee19": &RIRate{
ConnectFee: 0,
@@ -636,6 +641,7 @@ func TestLoadRatingPlans(t *testing.T) {
},
RoundingMethod: utils.ROUNDING_MIDDLE,
RoundingDecimals: 4,
tag: "R2",
},
"638dc1ab": &RIRate{
ConnectFee: 0,
@@ -649,6 +655,7 @@ func TestLoadRatingPlans(t *testing.T) {
},
RoundingMethod: utils.ROUNDING_MIDDLE,
RoundingDecimals: 4,
tag: "R3",
},
"3913037f": &RIRate{
ConnectFee: 0,
@@ -662,17 +669,18 @@ func TestLoadRatingPlans(t *testing.T) {
},
RoundingMethod: utils.ROUNDING_MIDDLE,
RoundingDecimals: 4,
tag: "R_URG",
},
},
DestinationRates: map[string]RPRateList{
"GERMANY": []*RPRate{
&RPRate{
Timing: "4c954a4f",
Timing: "ec8ed374",
Rating: "b457f86d",
Weight: 10,
},
&RPRate{
Timing: "4d593287",
Timing: "83429156",
Rating: "16e9ee19",
Weight: 10,
},
@@ -684,12 +692,12 @@ func TestLoadRatingPlans(t *testing.T) {
},
"GERMANY_O2": []*RPRate{
&RPRate{
Timing: "4c954a4f",
Timing: "ec8ed374",
Rating: "16e9ee19",
Weight: 10,
},
&RPRate{
Timing: "4d593287",
Timing: "83429156",
Rating: "638dc1ab",
Weight: 10,
},
@@ -701,22 +709,25 @@ func TestLoadRatingPlans(t *testing.T) {
},
"GERMANY_PREMIUM": []*RPRate{
&RPRate{
Timing: "4c954a4f",
Timing: "ec8ed374",
Rating: "16e9ee19",
Weight: 10,
},
},
"URG": []*RPRate{
&RPRate{
Timing: "30eab300",
Timing: "2d9ca64",
Rating: "3913037f",
Weight: 20,
},
},
},
}
if !reflect.DeepEqual(rplan, expected) {
if !reflect.DeepEqual(rplan.Ratings, expected.Ratings) {
t.Errorf("Error loading destination rate timing: %+v", rplan.Ratings)
/*for tag, key := range rplan.Ratings {
log.Print(tag, key)
}*/
}
}

View File

@@ -196,7 +196,7 @@ func APItoModelActionPlan(aps *utils.TPActionPlan) (result []TpActionPlan) {
for _, ap := range aps.ActionPlan {
result = append(result, TpActionPlan{
Tpid: aps.TPid,
Tag: aps.Id,
Tag: aps.ActionPlanId,
ActionsTag: ap.ActionsId,
TimingTag: ap.TimingId,
Weight: ap.Weight,
@@ -205,7 +205,7 @@ func APItoModelActionPlan(aps *utils.TPActionPlan) (result []TpActionPlan) {
if len(aps.ActionPlan) == 0 {
result = append(result, TpActionPlan{
Tpid: aps.TPid,
Tag: aps.Id,
Tag: aps.ActionPlanId,
})
}
return

View File

@@ -187,7 +187,7 @@ func (tps TpTimings) GetTimings() (map[string]*utils.TPTiming, error) {
timings := make(map[string]*utils.TPTiming)
for _, tp := range tps {
rt := &utils.TPTiming{}
rt.Id = tp.Tag
rt.TimingId = tp.Tag
rt.Years.Parse(tp.Years, utils.INFIELD_SEP)
rt.Months.Parse(tp.Months, utils.INFIELD_SEP)
rt.MonthDays.Parse(tp.MonthDays, utils.INFIELD_SEP)
@@ -310,6 +310,7 @@ func GetRateInterval(rpl *utils.TPRatingPlanBinding, dr *utils.DestinationRate)
MonthDays: rpl.Timing().MonthDays,
WeekDays: rpl.Timing().WeekDays,
StartTime: rpl.Timing().StartTime,
tag: rpl.Timing().TimingId,
},
Weight: rpl.Weight,
Rating: &RIRate{
@@ -318,6 +319,7 @@ func GetRateInterval(rpl *utils.TPRatingPlanBinding, dr *utils.DestinationRate)
RoundingDecimals: dr.RoundingDecimals,
MaxCost: dr.MaxCost,
MaxCostStrategy: dr.MaxCostStrategy,
tag: dr.Rate.RateId,
},
}
for _, rl := range dr.Rate.RateSlots {

View File

@@ -510,8 +510,8 @@ func TestTPDerivedChargersAsExportSlice(t *testing.T) {
func TestTPActionTriggersAsExportSlice(t *testing.T) {
ap := &utils.TPActionPlan{
TPid: "TEST_TPID",
Id: "PACKAGE_10",
TPid: "TEST_TPID",
ActionPlanId: "PACKAGE_10",
ActionPlan: []*utils.TPActionTiming{
&utils.TPActionTiming{
ActionsId: "TOPUP_RST_10",

View File

@@ -46,6 +46,7 @@ type RITiming struct {
WeekDays utils.WeekDays
StartTime, EndTime string // ##:##:## format
cronString string
tag string // loading validation only
}
func (rit *RITiming) CronString() string {
@@ -192,6 +193,7 @@ type RIRate struct {
MaxCost float64
MaxCostStrategy string
Rates RateGroups // GroupRateInterval (start time): Rate
tag string // loading validation only
}
func (rir *RIRate) Stringify() string {

View File

@@ -148,33 +148,33 @@ func (rp *RatingPlan) isContinous() bool {
return false
}
func (rp *RatingPlan) areRatesSane() bool {
func (rp *RatingPlan) getFirstUnsaneRating() string {
for _, rating := range rp.Ratings {
rating.Rates.Sort()
for i, rate := range rating.Rates {
if i < (len(rating.Rates) - 1) {
nextRate := rating.Rates[i+1]
if nextRate.GroupIntervalStart <= rate.GroupIntervalStart {
return false
return rating.tag
}
if math.Mod(nextRate.GroupIntervalStart.Seconds(), rate.RateIncrement.Seconds()) != 0 {
return false
return rating.tag
}
if rate.RateUnit == 0 || rate.RateIncrement == 0 {
return false
return rating.tag
}
}
}
}
return true
return ""
}
func (rp *RatingPlan) areTimingsSane() bool {
func (rp *RatingPlan) getFirstUnsaneTiming() string {
for _, timing := range rp.Timings {
if (len(timing.Years) != 0 || len(timing.Months) != 0 || len(timing.MonthDays) != 0) &&
len(timing.WeekDays) != 0 {
return false
return timing.tag
}
}
return true
return ""
}

View File

@@ -308,10 +308,10 @@ func TestRatingPlanIsContinousMissing(t *testing.T) {
func TestRatingPlanSaneTimingsBad(t *testing.T) {
rpl := &RatingPlan{
Timings: map[string]*RITiming{
"one": &RITiming{Years: utils.Years{2015}, WeekDays: utils.WeekDays{time.Monday}},
"one": &RITiming{Years: utils.Years{2015}, WeekDays: utils.WeekDays{time.Monday}, tag: "first"},
},
}
if rpl.areTimingsSane() {
if crazyTiming := rpl.getFirstUnsaneTiming(); crazyTiming == "" {
t.Errorf("Error detecting bad timings in rating profile: %+v", rpl)
}
}
@@ -319,11 +319,11 @@ func TestRatingPlanSaneTimingsBad(t *testing.T) {
func TestRatingPlanSaneTimingsGood(t *testing.T) {
rpl := &RatingPlan{
Timings: map[string]*RITiming{
"one": &RITiming{Years: utils.Years{2015}},
"two": &RITiming{WeekDays: utils.WeekDays{0, 1, 2, 3, 4}, StartTime: "00:00:00"},
"one": &RITiming{Years: utils.Years{2015}, tag: "first"},
"two": &RITiming{WeekDays: utils.WeekDays{0, 1, 2, 3, 4}, StartTime: "00:00:00", tag: "second"},
},
}
if !rpl.areTimingsSane() {
if crazyTiming := rpl.getFirstUnsaneTiming(); crazyTiming != "" {
t.Errorf("Error detecting bad timings in rating profile: %+v", rpl)
}
}
@@ -332,6 +332,7 @@ func TestRatingPlanSaneRatingsEqual(t *testing.T) {
rpl := &RatingPlan{
Ratings: map[string]*RIRate{
"one": &RIRate{
tag: "first",
Rates: RateGroups{
&Rate{
GroupIntervalStart: 0 * time.Second,
@@ -345,7 +346,7 @@ func TestRatingPlanSaneRatingsEqual(t *testing.T) {
},
},
}
if rpl.areRatesSane() {
if crazyRating := rpl.getFirstUnsaneRating(); crazyRating == "" {
t.Errorf("Error detecting bad rate groups in rating profile: %+v", rpl)
}
}
@@ -354,6 +355,7 @@ func TestRatingPlanSaneRatingsNotMultiple(t *testing.T) {
rpl := &RatingPlan{
Ratings: map[string]*RIRate{
"one": &RIRate{
tag: "first",
Rates: RateGroups{
&Rate{
GroupIntervalStart: 0 * time.Second,
@@ -367,7 +369,7 @@ func TestRatingPlanSaneRatingsNotMultiple(t *testing.T) {
},
},
}
if rpl.areRatesSane() {
if crazyRating := rpl.getFirstUnsaneRating(); crazyRating == "" {
t.Errorf("Error detecting bad rate groups in rating profile: %+v", rpl)
}
}
@@ -376,6 +378,7 @@ func TestRatingPlanSaneRatingsGoot(t *testing.T) {
rpl := &RatingPlan{
Ratings: map[string]*RIRate{
"one": &RIRate{
tag: "first",
Rates: RateGroups{
&Rate{
GroupIntervalStart: 60 * time.Second,
@@ -391,7 +394,7 @@ func TestRatingPlanSaneRatingsGoot(t *testing.T) {
},
},
}
if !rpl.areRatesSane() {
if crazyRating := rpl.getFirstUnsaneRating(); crazyRating != "" {
t.Errorf("Error detecting bad rate groups in rating profile: %+v", rpl)
}
}

View File

@@ -281,9 +281,9 @@ func TestMySQLTPActionTimings(t *testing.T) {
}
AP_ID := "AP_1"
ap := &utils.TPActionPlan{
TPid: TEST_SQL,
Id: AP_ID,
ActionPlan: []*utils.TPActionTiming{&utils.TPActionTiming{ActionsId: "ACTS_1", TimingId: "TM_1", Weight: 10.0}},
TPid: TEST_SQL,
ActionPlanId: AP_ID,
ActionPlan: []*utils.TPActionTiming{&utils.TPActionTiming{ActionsId: "ACTS_1", TimingId: "TM_1", Weight: 10.0}},
}
maps := APItoModelActionPlan(ap)
if err := mysqlDb.SetTpActionPlans(maps); err != nil {

View File

@@ -276,9 +276,9 @@ func TestPSQLTPActionTimings(t *testing.T) {
}
AP_ID := "AP_1"
ap := &utils.TPActionPlan{
TPid: TEST_SQL,
Id: AP_ID,
ActionPlan: []*utils.TPActionTiming{&utils.TPActionTiming{ActionsId: "ACTS_1", TimingId: "TM_1", Weight: 10.0}},
TPid: TEST_SQL,
ActionPlanId: AP_ID,
ActionPlan: []*utils.TPActionTiming{&utils.TPActionTiming{ActionsId: "ACTS_1", TimingId: "TM_1", Weight: 10.0}},
}
maps := APItoModelActionPlan(ap)
if err := psqlDb.SetTpActionPlans(maps); err != nil {

View File

@@ -932,12 +932,12 @@ func (tpr *TpReader) IsValid() bool {
log.Printf("The rating plan %s is not covering all weekdays", rplTag)
valid = false
}
if !rpl.areRatesSane() {
log.Printf("The rating plan %s contains invalid rate groups", rplTag)
if crazyRate := rpl.getFirstUnsaneRating(); crazyRate != "" {
log.Printf("The rate %s is invalid", crazyRate)
valid = false
}
if !rpl.areTimingsSane() {
log.Printf("The rating plan %s contains invalid timings", rplTag)
if crazyTiming := rpl.getFirstUnsaneTiming(); crazyTiming != "" {
log.Printf("The timing %s is invalid", crazyTiming)
valid = false
}
}

View File

@@ -80,6 +80,7 @@ type RateSlot struct {
rateUnitDur time.Duration
rateIncrementDur time.Duration
groupIntervalStartDur time.Duration
tag string // load validation only
}
// Used to set the durations we need out of strings
@@ -133,7 +134,7 @@ type ApierTPTiming struct {
}
type TPTiming struct {
Id string
TimingId string
Years Years
Months Months
MonthDays MonthDays
@@ -144,7 +145,7 @@ type TPTiming struct {
func NewTiming(timingInfo ...string) (rt *TPTiming) {
rt = &TPTiming{}
rt.Id = timingInfo[0]
rt.TimingId = timingInfo[0]
rt.Years.Parse(timingInfo[1], INFIELD_SEP)
rt.Months.Parse(timingInfo[2], INFIELD_SEP)
rt.MonthDays.Parse(timingInfo[3], INFIELD_SEP)
@@ -408,9 +409,9 @@ type TPDerivedCharger struct {
}
type TPActionPlan struct {
TPid string // Tariff plan id
Id string // ActionPlan id
ActionPlan []*TPActionTiming // Set of ActionTiming bindings this profile will group
TPid string // Tariff plan id
ActionPlanId string // ActionPlan id
ActionPlan []*TPActionTiming // Set of ActionTiming bindings this profile will group
}
type TPActionTiming struct {