mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-25 00:58:45 +05:00
Add support for RSRFilter for > , >= , < , <=
This commit is contained in:
committed by
Dan Christian Bogos
parent
dda6a2ec7d
commit
1192df9843
@@ -122,3 +122,36 @@ func TestAgReqAsNavigableMap(t *testing.T) {
|
||||
t.Errorf("expecting: %+v, received: %+v", eMp, mpOut)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAgReqMaxCost(t *testing.T) {
|
||||
data, _ := engine.NewMapStorage()
|
||||
dm := engine.NewDataManager(data)
|
||||
cfg, _ := config.NewDefaultCGRConfig()
|
||||
filterS := engine.NewFilterS(cfg, nil, dm)
|
||||
agReq := newAgentRequest(nil, nil, nil, nil, "cgrates.org", "", filterS)
|
||||
// populate request, emulating the way will be done in HTTPAgent
|
||||
agReq.CGRRequest.Set([]string{utils.CapMaxUsage}, "120s", false)
|
||||
|
||||
cgrRply := map[string]interface{}{
|
||||
utils.CapMaxUsage: time.Duration(120 * time.Second),
|
||||
}
|
||||
agReq.CGRReply = config.NewNavigableMap(cgrRply)
|
||||
|
||||
tplFlds := []*config.FCTemplate{
|
||||
&config.FCTemplate{Tag: "MaxUsage",
|
||||
FieldId: "MaxUsage", Type: utils.META_COMPOSED,
|
||||
Filters: []string{"*rsr::~*cgrep.MaxUsage(>0s)"},
|
||||
Value: config.NewRSRParsersMustCompile(
|
||||
"~*cgrep.MaxUsage{*duration_seconds}", true)},
|
||||
}
|
||||
eMp := config.NewNavigableMap(nil)
|
||||
|
||||
eMp.Set([]string{"MaxUsage"}, []*config.NMItem{
|
||||
&config.NMItem{Data: "120", Path: []string{"MaxUsage"},
|
||||
Config: tplFlds[0]}}, true)
|
||||
if mpOut, err := agReq.AsNavigableMap(tplFlds); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eMp, mpOut) {
|
||||
t.Errorf("expecting: %+v, received: %+v", eMp, mpOut)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,7 +353,7 @@ func (fltr *FilterRule) passGreaterThan(dP config.DataProvider) (bool, error) {
|
||||
return false, err
|
||||
} else if utils.IsSliceMember([]string{MetaGreaterThan, MetaGreaterOrEqual}, fltr.Type) && gte {
|
||||
return true, nil
|
||||
} else if !gte && utils.IsSliceMember([]string{MetaLessThan, MetaLessOrEqual}, fltr.Type) && !gte {
|
||||
} else if utils.IsSliceMember([]string{MetaLessThan, MetaLessOrEqual}, fltr.Type) && !gte {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,3 +467,43 @@ func TestPassFiltersForEventWithEmptyFilter(t *testing.T) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", true, pass)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPassFilterMaxCost(t *testing.T) {
|
||||
data, _ := NewMapStorage()
|
||||
dmFilterPass := NewDataManager(data)
|
||||
cfg, _ := config.NewDefaultCGRConfig()
|
||||
filterS := FilterS{
|
||||
cfg: cfg,
|
||||
dm: dmFilterPass,
|
||||
}
|
||||
//check with max usage -1 should fail
|
||||
passEvent1 := map[string]interface{}{
|
||||
"MaxUsage": time.Duration(-1),
|
||||
}
|
||||
if pass, err := filterS.Pass("cgrates.org",
|
||||
[]string{"*rsr::~MaxUsage{*duration_nanoseconds}(>0)"}, config.NewNavigableMap(passEvent1)); err != nil {
|
||||
t.Errorf(err.Error())
|
||||
} else if pass {
|
||||
t.Errorf("Expecting: false , received: %+v", pass)
|
||||
}
|
||||
//check with max usage 0 should fail
|
||||
passEvent2 := map[string]interface{}{
|
||||
"MaxUsage": time.Duration(0),
|
||||
}
|
||||
if pass, err := filterS.Pass("cgrates.org",
|
||||
[]string{"*rsr::~MaxUsage{*duration_nanoseconds}(>0)"}, config.NewNavigableMap(passEvent2)); err != nil {
|
||||
t.Errorf(err.Error())
|
||||
} else if pass {
|
||||
t.Errorf("Expecting: false, received: %+v", pass)
|
||||
}
|
||||
//check with max usage 123 should pass
|
||||
passEvent3 := map[string]interface{}{
|
||||
"MaxUsage": time.Duration(123),
|
||||
}
|
||||
if pass, err := filterS.Pass("cgrates.org",
|
||||
[]string{"*rsr::~MaxUsage{*duration_nanoseconds}(>0)"}, config.NewNavigableMap(passEvent3)); err != nil {
|
||||
t.Errorf(err.Error())
|
||||
} else if !pass {
|
||||
t.Errorf("Expecting: true, received: %+v", pass)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,6 +315,10 @@ const (
|
||||
MetaString = "*string"
|
||||
NegativePrefix = "!"
|
||||
MatchStartPrefix = "^"
|
||||
MatchGreaterThanOrEqual = ">="
|
||||
MatchLessThanOrEqual = "<="
|
||||
MatchGreaterThan = ">"
|
||||
MatchLessThan = "<"
|
||||
MatchEndPrefix = "$"
|
||||
MetaGrouped = "*grouped"
|
||||
MetaRaw = "*raw"
|
||||
|
||||
@@ -254,6 +254,47 @@ func (rsrFltr *RSRFilter) Pass(val string) bool {
|
||||
if rsrFltr.filterRule[lastIdx:] == MatchEndPrefix {
|
||||
return strings.HasSuffix(val, rsrFltr.filterRule[:lastIdx]) != rsrFltr.negative
|
||||
}
|
||||
if len(rsrFltr.filterRule) > 2 && rsrFltr.filterRule[:2] == MatchGreaterThanOrEqual {
|
||||
gt, err := GreaterThan(StringToInterface(val),
|
||||
StringToInterface(rsrFltr.filterRule[2:]), true)
|
||||
if err != nil {
|
||||
Logger.Warning(fmt.Sprintf("<RSRFilter> rule: <%s>, err: <%s>", rsrFltr.filterRule, err.Error()))
|
||||
return false
|
||||
}
|
||||
return gt && !rsrFltr.negative
|
||||
}
|
||||
|
||||
if len(rsrFltr.filterRule) > 2 && rsrFltr.filterRule[:2] == MatchLessThanOrEqual {
|
||||
gt, err := GreaterThan(StringToInterface(rsrFltr.filterRule[2:]), // compare the rule with the val
|
||||
StringToInterface(val),
|
||||
true)
|
||||
if err != nil {
|
||||
Logger.Warning(fmt.Sprintf("<RSRFilter> rule: <%s>, err: <%s>", rsrFltr.filterRule, err.Error()))
|
||||
return false
|
||||
}
|
||||
return gt && !rsrFltr.negative
|
||||
}
|
||||
|
||||
if rsrFltr.filterRule[:1] == MatchGreaterThan {
|
||||
gt, err := GreaterThan(StringToInterface(val),
|
||||
StringToInterface(rsrFltr.filterRule[1:]), false)
|
||||
if err != nil {
|
||||
Logger.Warning(fmt.Sprintf("<RSRFilter> rule: <%s>, err: <%s>", rsrFltr.filterRule, err.Error()))
|
||||
return false
|
||||
}
|
||||
return gt && !rsrFltr.negative
|
||||
}
|
||||
|
||||
if rsrFltr.filterRule[:1] == MatchLessThan {
|
||||
gt, err := GreaterThan(StringToInterface(rsrFltr.filterRule[1:]), // compare the rule with the val
|
||||
StringToInterface(val),
|
||||
false)
|
||||
if err != nil {
|
||||
Logger.Warning(fmt.Sprintf("<RSRFilter> rule: <%s>, err: <%s>", rsrFltr.filterRule, err.Error()))
|
||||
return false
|
||||
}
|
||||
return gt && !rsrFltr.negative
|
||||
}
|
||||
return (strings.Index(val, rsrFltr.filterRule) != -1) != rsrFltr.negative // default is string index
|
||||
}
|
||||
|
||||
|
||||
@@ -481,6 +481,75 @@ func TestRSRFilterPass(t *testing.T) {
|
||||
if !fltr.Pass("") {
|
||||
t.Error("Passing!")
|
||||
}
|
||||
|
||||
// compare greaterThan
|
||||
fltr, err = NewRSRFilter(">0s")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if fltr.Pass("0s") {
|
||||
t.Error("passing!")
|
||||
}
|
||||
if fltr.Pass("13") {
|
||||
t.Error("passing!")
|
||||
}
|
||||
if !fltr.Pass("12s") {
|
||||
t.Error("not passing!")
|
||||
}
|
||||
|
||||
// compare greaterThanOrEqual
|
||||
fltr, err = NewRSRFilter(">=0s")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if fltr.Pass("-1s") {
|
||||
t.Error("passing!")
|
||||
}
|
||||
if !fltr.Pass("0s") {
|
||||
t.Error("not passing!")
|
||||
}
|
||||
if fltr.Pass("13") {
|
||||
t.Error("passing!")
|
||||
}
|
||||
if !fltr.Pass("12s") {
|
||||
t.Error("not passing!")
|
||||
}
|
||||
|
||||
// compare lessThan
|
||||
fltr, err = NewRSRFilter("<0s")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if fltr.Pass("1ns") {
|
||||
t.Error("passing!")
|
||||
}
|
||||
if fltr.Pass("13") {
|
||||
t.Error("passing!")
|
||||
}
|
||||
if fltr.Pass("12s") {
|
||||
t.Error("passing!")
|
||||
}
|
||||
if !fltr.Pass("-12s") {
|
||||
t.Error("not passing!")
|
||||
}
|
||||
|
||||
// compare lessThanOrEqual
|
||||
fltr, err = NewRSRFilter("<=0s")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !fltr.Pass("-1s") {
|
||||
t.Error("not passing!")
|
||||
}
|
||||
if !fltr.Pass("0s") {
|
||||
t.Error("not passing!")
|
||||
}
|
||||
if fltr.Pass("13") {
|
||||
t.Error("passing!")
|
||||
}
|
||||
if fltr.Pass("12s") {
|
||||
t.Error("passing!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRSRFiltersPass(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user