From 22670e12a81dafdb42e4b3c7ec0ee286990f05bd Mon Sep 17 00:00:00 2001 From: DanB Date: Wed, 9 Jul 2014 15:21:42 +0200 Subject: [PATCH] Logic to handle multiple derived charging run filters inside mediator and session manager --- apier/derivedcharging.go | 5 +++ config/config_test.go | 2 +- config/helpers.go | 2 +- engine/loader_csv.go | 7 ++-- engine/loader_csv_test.go | 6 ++-- mediator/mediator.go | 9 ++--- sessionmanager/fsevent_test.go | 2 +- sessionmanager/fssessionmanager.go | 11 +++--- utils/consts.go | 2 ++ utils/derivedchargers.go | 56 ++++++++++++++---------------- utils/derivedchargers_test.go | 10 +++--- utils/rsrfield.go | 7 ++-- utils/rsrfield_test.go | 2 +- utils/storedcdr_test.go | 2 +- 14 files changed, 68 insertions(+), 55 deletions(-) diff --git a/apier/derivedcharging.go b/apier/derivedcharging.go index 0c4e5d648..fb3766e1d 100644 --- a/apier/derivedcharging.go +++ b/apier/derivedcharging.go @@ -46,6 +46,11 @@ func (self *ApierV1) SetDerivedChargers(attrs AttrSetDerivedChargers, reply *str if missing := utils.MissingStructFields(&attrs, []string{"Tenant", "Category", "Direction", "Account", "Subject", "DerivedChargers"}); len(missing) != 0 { return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) } + for _, dc := range attrs.DerivedChargers { + if _, err = utils.ParseRSRFields(dc.RunFilters, utils.INFIELD_SEP); err != nil { // Make sure rules are OK before loading in db + return fmt.Errorf("%s:%s", utils.ERR_PARSER_ERROR, err.Error()) + } + } dcKey := utils.DerivedChargersKey(attrs.Direction, attrs.Tenant, attrs.Category, attrs.Account, attrs.Subject) if err := self.AccountDb.SetDerivedChargers(dcKey, attrs.DerivedChargers); err != nil { return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) diff --git a/config/config_test.go b/config/config_test.go index 1c4eaab56..3bf32117b 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -250,7 +250,7 @@ func TestConfigFromFile(t *testing.T) { eCfg.FreeswitchServer = "test" eCfg.FreeswitchPass = "test" eCfg.FreeswitchReconnects = 99 - eCfg.DerivedChargers = utils.DerivedChargers{&utils.DerivedCharger{RunId: "test", RunFilter: "", ReqTypeField: "test", DirectionField: "test", TenantField: "test", + eCfg.DerivedChargers = utils.DerivedChargers{&utils.DerivedCharger{RunId: "test", RunFilters: "", ReqTypeField: "test", DirectionField: "test", TenantField: "test", CategoryField: "test", AccountField: "test", SubjectField: "test", DestinationField: "test", SetupTimeField: "test", AnswerTimeField: "test", UsageField: "test"}} eCfg.CombinedDerivedChargers = true eCfg.HistoryAgentEnabled = true diff --git a/config/helpers.go b/config/helpers.go index 02fad02ce..4b9bfde4b 100644 --- a/config/helpers.go +++ b/config/helpers.go @@ -39,7 +39,7 @@ func ConfigSlice(cfgVal string) ([]string, error) { return cfgValStrs, nil } -func ParseRSRFields(configVal string) ([]*utils.RSRField, error) { +func ParseRSRFields(configVal string) ([]*utils.RSRField, error) { //ToDo: Unify it with the Parser inside RSRField cfgValStrs := strings.Split(configVal, string(utils.CSV_SEP)) if len(cfgValStrs) == 1 && cfgValStrs[0] == "" { // Prevents returning iterable with empty value return []*utils.RSRField{}, nil diff --git a/engine/loader_csv.go b/engine/loader_csv.go index 47f2ab28f..2e657448e 100644 --- a/engine/loader_csv.go +++ b/engine/loader_csv.go @@ -839,10 +839,13 @@ func (csvr *CSVReader) LoadDerivedChargers() (err error) { for record, err := csvReader.Read(); err == nil; record, err = csvReader.Read() { tag := utils.DerivedChargersKey(record[0], record[1], record[2], record[3], record[4]) _, found := csvr.derivedChargers[tag] + if _, err = utils.ParseRSRFields(record[6], utils.INFIELD_SEP); err != nil { // Make sure rules are OK before loading in db + return err + } if found { if csvr.derivedChargers[tag], err = csvr.derivedChargers[tag].Append(&utils.DerivedCharger{ RunId: ValueOrDefault(record[5], "*default"), - RunFilter: record[6], + RunFilters: record[6], ReqTypeField: ValueOrDefault(record[7], "*default"), DirectionField: ValueOrDefault(record[8], "*default"), TenantField: ValueOrDefault(record[9], "*default"), @@ -862,7 +865,7 @@ func (csvr *CSVReader) LoadDerivedChargers() (err error) { } csvr.derivedChargers[tag] = utils.DerivedChargers{&utils.DerivedCharger{ RunId: ValueOrDefault(record[5], "*default"), - RunFilter: record[6], + RunFilters: record[6], ReqTypeField: ValueOrDefault(record[7], "*default"), DirectionField: ValueOrDefault(record[8], "*default"), TenantField: ValueOrDefault(record[9], "*default"), diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index 82e62011e..6393a4800 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -178,7 +178,7 @@ vdf,emptyY,*out,TOPUP_EMPTY_AT, derivedCharges = ` #Direction,Tenant,Category,Account,Subject,RunId,RunFilter,ReqTypeField,DirectionField,TenantField,TorField,AccountField,SubjectField,DestinationField,SetupTimeField,AnswerTimeField,UsageField -*out,cgrates.org,call,dan,dan,extra1,^filteredHeader1/filterValue1,^prepaid,,,,rif,rif,,,, +*out,cgrates.org,call,dan,dan,extra1,^filteredHeader1/filterValue1/,^prepaid,,,,rif,rif,,,, *out,cgrates.org,call,dan,dan,extra2,,,,,,ivo,ivo,,,, *out,cgrates.org,call,dan,*any,extra1,,,,,,rif2,rif2,,,, ` @@ -932,8 +932,8 @@ func TestLoadDerivedChargers(t *testing.T) { t.Error("Failed to load derivedChargers: ", csvr.derivedChargers) } expCharger1 := utils.DerivedChargers{ - &utils.DerivedCharger{RunId: "extra1", RunFilter: "^filteredHeader1/filterValue1", ReqTypeField: "^prepaid", DirectionField: "*default", TenantField: "*default", - CategoryField: "*default", AccountField: "rif", SubjectField: "rif", DestinationField: "*default", + &utils.DerivedCharger{RunId: "extra1", RunFilters: "^filteredHeader1/filterValue1/", ReqTypeField: "^prepaid", DirectionField: "*default", + TenantField: "*default", CategoryField: "*default", AccountField: "rif", SubjectField: "rif", DestinationField: "*default", SetupTimeField: "*default", AnswerTimeField: "*default", UsageField: "*default"}, &utils.DerivedCharger{RunId: "extra2", ReqTypeField: "*default", DirectionField: "*default", TenantField: "*default", CategoryField: "*default", AccountField: "ivo", SubjectField: "ivo", DestinationField: "*default", SetupTimeField: "*default", AnswerTimeField: "*default", UsageField: "*default"}, diff --git a/mediator/mediator.go b/mediator/mediator.go index 796b7416b..d2005dfcb 100644 --- a/mediator/mediator.go +++ b/mediator/mediator.go @@ -120,10 +120,11 @@ func (self *Mediator) RateCdr(storedCdr *utils.StoredCdr) error { return errors.New(errText) } for _, dc := range dcs { - dcRunFilter, _ := utils.NewRSRField(dc.RunFilter) - if fltrPass, _ := storedCdr.PassesFieldFilter(dcRunFilter); !fltrPass { - //engine.Logger.Info(fmt.Sprintf(" Ignoring DerivedCharger with id %s - non matching filter", dc.RunId)) - continue + runFilters, _ := utils.ParseRSRFields(dc.RunFilters, utils.INFIELD_SEP) + for _, dcRunFilter := range runFilters { + if fltrPass, _ := storedCdr.PassesFieldFilter(dcRunFilter); !fltrPass { + continue + } } dcReqTypeFld, _ := utils.NewRSRField(dc.ReqTypeField) dcDirFld, _ := utils.NewRSRField(dc.DirectionField) diff --git a/sessionmanager/fsevent_test.go b/sessionmanager/fsevent_test.go index 29dc1a9dd..cec0dcc66 100644 --- a/sessionmanager/fsevent_test.go +++ b/sessionmanager/fsevent_test.go @@ -570,7 +570,7 @@ FreeSWITCH-Switchname: h1.ip-switch.net FreeSWITCH-IPv4: 88.198.12.156 Caller-Username: futurem0005` ev := new(FSEvent).New(body) - acntPrefxFltr, _ := utils.NewRSRField(`~account:s/^\w+[s,h,m,p]\d{4}$//`) + acntPrefxFltr, _ := utils.NewRSRField(`~account:s/^\w+[shmp]\d{4}$//`) if pass, _ := ev.PassesFieldFilter(acntPrefxFltr); !pass { t.Error("Not passing valid filter") } diff --git a/sessionmanager/fssessionmanager.go b/sessionmanager/fssessionmanager.go index 9ce699c8c..341791f2f 100644 --- a/sessionmanager/fssessionmanager.go +++ b/sessionmanager/fssessionmanager.go @@ -112,7 +112,7 @@ func (sm *FSSessionManager) DisconnectSession(uuid string, notify string) { return } -// Remove session from sessin list, removes all related in case of multiple runs +// Remove session from session list, removes all related in case of multiple runs func (sm *FSSessionManager) RemoveSession(uuid string) { for i, ss := range sm.sessions { if ss.uuid == uuid { @@ -161,10 +161,11 @@ func (sm *FSSessionManager) OnChannelPark(ev Event) { } dcs, _ = dcs.AppendDefaultRun() for _, dc := range dcs { - dcRunFilter, _ := utils.NewRSRField(dc.RunFilter) - if fltrPass, _ := ev.PassesFieldFilter(dcRunFilter); !fltrPass { - //engine.Logger.Debug(fmt.Sprintf(" Ignoring DerivedCharger with id %s - non matching filter", dc.RunId)) - continue + runFilters, _ := utils.ParseRSRFields(dc.RunFilters, utils.INFIELD_SEP) + for _, dcRunFilter := range runFilters { + if fltrPass, _ := ev.PassesFieldFilter(dcRunFilter); !fltrPass { + continue + } } startTime, err := ev.GetAnswerTime(PARK_TIME) if err != nil { diff --git a/utils/consts.go b/utils/consts.go index 4626d5471..1b220470c 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -20,6 +20,7 @@ const ( ERR_MANDATORY_IE_MISSING = "MANDATORY_IE_MISSING" ERR_EXISTS = "EXISTS" ERR_BROKEN_REFERENCE = "BROKEN_REFERENCE" + ERR_PARSER_ERROR = "PARSER_ERROR" TBL_TP_TIMINGS = "tp_timings" TBL_TP_DESTINATIONS = "tp_destinations" TBL_TP_RATES = "tp_rates" @@ -69,6 +70,7 @@ const ( COMMENT_CHAR = '#' CSV_SEP = ',' FALLBACK_SEP = ';' + INFIELD_SEP = ";" REGEXP_PREFIX = "~" JSON = "json" MSGPACK = "msgpack" diff --git a/utils/derivedchargers.go b/utils/derivedchargers.go index 296d05d15..38b8d736b 100644 --- a/utils/derivedchargers.go +++ b/utils/derivedchargers.go @@ -24,75 +24,73 @@ import ( ) // Wraps regexp compiling in case of rsr fields -func NewDerivedCharger(runId, runFilter, reqTypeFld, dirFld, tenantFld, catFld, acntFld, subjFld, dstFld, sTimeFld, aTimeFld, durFld string) (dc *DerivedCharger, err error) { +func NewDerivedCharger(runId, runFilters, reqTypeFld, dirFld, tenantFld, catFld, acntFld, subjFld, dstFld, sTimeFld, aTimeFld, durFld string) (dc *DerivedCharger, err error) { if len(runId) == 0 { return nil, errors.New("Empty run id field") } dc = &DerivedCharger{RunId: runId} - dc.RunFilter = runFilter - if strings.HasPrefix(dc.RunFilter, REGEXP_PREFIX) || strings.HasPrefix(dc.RunFilter, STATIC_VALUE_PREFIX) { - if dc.rsrRunFilter, err = NewRSRField(dc.RunFilter); err != nil { + dc.RunFilters = runFilters + if strings.HasPrefix(dc.RunFilters, REGEXP_PREFIX) || strings.HasPrefix(dc.RunFilters, STATIC_VALUE_PREFIX) { + if dc.rsrRunFilters, err = ParseRSRFields(dc.RunFilters, INFIELD_SEP); err != nil { return nil, err - } else if len(dc.rsrRunFilter.Id) == 0 { - return nil, errors.New("Empty filter header.") } } dc.ReqTypeField = reqTypeFld - if strings.HasPrefix(dc.ReqTypeField, REGEXP_PREFIX) || strings.HasPrefix(dc.RunFilter, STATIC_VALUE_PREFIX) { + if strings.HasPrefix(dc.ReqTypeField, REGEXP_PREFIX) || strings.HasPrefix(dc.ReqTypeField, STATIC_VALUE_PREFIX) { if dc.rsrReqTypeField, err = NewRSRField(dc.ReqTypeField); err != nil { return nil, err } } dc.DirectionField = dirFld - if strings.HasPrefix(dc.DirectionField, REGEXP_PREFIX) || strings.HasPrefix(dc.RunFilter, STATIC_VALUE_PREFIX) { + if strings.HasPrefix(dc.DirectionField, REGEXP_PREFIX) || strings.HasPrefix(dc.DirectionField, STATIC_VALUE_PREFIX) { if dc.rsrDirectionField, err = NewRSRField(dc.DirectionField); err != nil { return nil, err } } dc.TenantField = tenantFld - if strings.HasPrefix(dc.TenantField, REGEXP_PREFIX) || strings.HasPrefix(dc.RunFilter, STATIC_VALUE_PREFIX) { + if strings.HasPrefix(dc.TenantField, REGEXP_PREFIX) || strings.HasPrefix(dc.TenantField, STATIC_VALUE_PREFIX) { if dc.rsrTenantField, err = NewRSRField(dc.TenantField); err != nil { return nil, err } } dc.CategoryField = catFld - if strings.HasPrefix(dc.CategoryField, REGEXP_PREFIX) || strings.HasPrefix(dc.RunFilter, STATIC_VALUE_PREFIX) { + if strings.HasPrefix(dc.CategoryField, REGEXP_PREFIX) || strings.HasPrefix(dc.CategoryField, STATIC_VALUE_PREFIX) { if dc.rsrCategoryField, err = NewRSRField(dc.CategoryField); err != nil { return nil, err } } dc.AccountField = acntFld - if strings.HasPrefix(dc.AccountField, REGEXP_PREFIX) || strings.HasPrefix(dc.RunFilter, STATIC_VALUE_PREFIX) { + if strings.HasPrefix(dc.AccountField, REGEXP_PREFIX) || strings.HasPrefix(dc.AccountField, STATIC_VALUE_PREFIX) { if dc.rsrAccountField, err = NewRSRField(dc.AccountField); err != nil { return nil, err } } dc.SubjectField = subjFld - if strings.HasPrefix(dc.SubjectField, REGEXP_PREFIX) || strings.HasPrefix(dc.RunFilter, STATIC_VALUE_PREFIX) { + if strings.HasPrefix(dc.SubjectField, REGEXP_PREFIX) || strings.HasPrefix(dc.SubjectField, STATIC_VALUE_PREFIX) { if dc.rsrSubjectField, err = NewRSRField(dc.SubjectField); err != nil { return nil, err } } dc.DestinationField = dstFld - if strings.HasPrefix(dc.DestinationField, REGEXP_PREFIX) || strings.HasPrefix(dc.RunFilter, STATIC_VALUE_PREFIX) { + if strings.HasPrefix(dc.DestinationField, REGEXP_PREFIX) || strings.HasPrefix(dc.DestinationField, STATIC_VALUE_PREFIX) { if dc.rsrDestinationField, err = NewRSRField(dc.DestinationField); err != nil { return nil, err } } dc.SetupTimeField = sTimeFld - if strings.HasPrefix(dc.SetupTimeField, REGEXP_PREFIX) || strings.HasPrefix(dc.RunFilter, STATIC_VALUE_PREFIX) { + if strings.HasPrefix(dc.SetupTimeField, REGEXP_PREFIX) || strings.HasPrefix(dc.SetupTimeField, STATIC_VALUE_PREFIX) { if dc.rsrSetupTimeField, err = NewRSRField(dc.SetupTimeField); err != nil { return nil, err } } dc.AnswerTimeField = aTimeFld - if strings.HasPrefix(dc.AnswerTimeField, REGEXP_PREFIX) || strings.HasPrefix(dc.RunFilter, STATIC_VALUE_PREFIX) { + if strings.HasPrefix(dc.AnswerTimeField, REGEXP_PREFIX) || strings.HasPrefix(dc.AnswerTimeField, STATIC_VALUE_PREFIX) { if dc.rsrAnswerTimeField, err = NewRSRField(dc.AnswerTimeField); err != nil { return nil, err } } dc.UsageField = durFld - if strings.HasPrefix(dc.UsageField, REGEXP_PREFIX) || strings.HasPrefix(dc.RunFilter, STATIC_VALUE_PREFIX) { + if strings.HasPrefix(dc.UsageField, REGEXP_PREFIX) || strings.HasPrefix(dc.UsageField, STATIC_VALUE_PREFIX) { if dc.rsrUsageField, err = NewRSRField(dc.UsageField); err != nil { return nil, err } @@ -101,19 +99,19 @@ func NewDerivedCharger(runId, runFilter, reqTypeFld, dirFld, tenantFld, catFld, } type DerivedCharger struct { - RunId string // Unique runId in the chain - RunFilter string // Only run the charger if the filter matches - ReqTypeField string // Field containing request type info, number in case of csv source, '^' as prefix in case of static values - DirectionField string // Field containing direction info - TenantField string // Field containing tenant info - CategoryField string // Field containing tor info - AccountField string // Field containing account information - SubjectField string // Field containing subject information - DestinationField string // Field containing destination information - SetupTimeField string // Field containing setup time information - AnswerTimeField string // Field containing answer time information - UsageField string // Field containing usage information - rsrRunFilter *RSRField // Storage for compiled Regexp in case of RSRFields + RunId string // Unique runId in the chain + RunFilters string // Only run the charger if all the filters match + ReqTypeField string // Field containing request type info, number in case of csv source, '^' as prefix in case of static values + DirectionField string // Field containing direction info + TenantField string // Field containing tenant info + CategoryField string // Field containing tor info + AccountField string // Field containing account information + SubjectField string // Field containing subject information + DestinationField string // Field containing destination information + SetupTimeField string // Field containing setup time information + AnswerTimeField string // Field containing answer time information + UsageField string // Field containing usage information + rsrRunFilters []*RSRField // Storage for compiled Regexp in case of RSRFields rsrReqTypeField *RSRField rsrDirectionField *RSRField rsrTenantField *RSRField diff --git a/utils/derivedchargers_test.go b/utils/derivedchargers_test.go index 0a079a109..e8a76647f 100644 --- a/utils/derivedchargers_test.go +++ b/utils/derivedchargers_test.go @@ -47,7 +47,7 @@ func TestAppendDerivedChargers(t *testing.T) { func TestNewDerivedCharger(t *testing.T) { edc1 := &DerivedCharger{ RunId: "test1", - RunFilter: "", + RunFilters: "", ReqTypeField: "reqtype1", DirectionField: "direction1", TenantField: "tenant1", @@ -67,7 +67,7 @@ func TestNewDerivedCharger(t *testing.T) { } edc2 := &DerivedCharger{ RunId: "test2", - RunFilter: "^cdr_source/tdm_cdrs/", + RunFilters: "^cdr_source/tdm_cdrs/", ReqTypeField: "~reqtype2:s/sip:(.+)/$1/", DirectionField: "~direction2:s/sip:(.+)/$1/", TenantField: "~tenant2:s/sip:(.+)/$1/", @@ -79,7 +79,7 @@ func TestNewDerivedCharger(t *testing.T) { AnswerTimeField: "~answertime2:s/sip:(.+)/$1/", UsageField: "~duration2:s/sip:(.+)/$1/", } - edc2.rsrRunFilter, _ = NewRSRField("^cdr_source/tdm_cdrs/") + edc2.rsrRunFilters, _ = ParseRSRFields("^cdr_source/tdm_cdrs/", INFIELD_SEP) edc2.rsrReqTypeField, _ = NewRSRField("~reqtype2:s/sip:(.+)/$1/") edc2.rsrDirectionField, _ = NewRSRField("~direction2:s/sip:(.+)/$1/") edc2.rsrTenantField, _ = NewRSRField("~tenant2:s/sip:(.+)/$1/") @@ -116,7 +116,7 @@ func TestDerivedChargersKey(t *testing.T) { func TestAppendDefaultRun(t *testing.T) { var dc1 DerivedChargers - dcDf := &DerivedCharger{RunId: DEFAULT_RUNID, RunFilter: "", ReqTypeField: META_DEFAULT, DirectionField: META_DEFAULT, + dcDf := &DerivedCharger{RunId: DEFAULT_RUNID, RunFilters: "", ReqTypeField: META_DEFAULT, DirectionField: META_DEFAULT, TenantField: META_DEFAULT, CategoryField: META_DEFAULT, AccountField: META_DEFAULT, SubjectField: META_DEFAULT, DestinationField: META_DEFAULT, SetupTimeField: META_DEFAULT, AnswerTimeField: META_DEFAULT, UsageField: META_DEFAULT} eDc1 := DerivedChargers{dcDf} @@ -124,7 +124,7 @@ func TestAppendDefaultRun(t *testing.T) { t.Error("Unexpected result.") } dc2 := DerivedChargers{ - &DerivedCharger{RunId: "extra1", RunFilter: "", ReqTypeField: "reqtype2", DirectionField: "*default", TenantField: "*default", CategoryField: "*default", + &DerivedCharger{RunId: "extra1", RunFilters: "", ReqTypeField: "reqtype2", DirectionField: "*default", TenantField: "*default", CategoryField: "*default", AccountField: "rif", SubjectField: "rif", DestinationField: "*default", SetupTimeField: "*default", AnswerTimeField: "*default", UsageField: "*default"}, &DerivedCharger{RunId: "extra2", ReqTypeField: "*default", DirectionField: "*default", TenantField: "*default", CategoryField: "*default", AccountField: "ivo", SubjectField: "ivo", DestinationField: "*default", SetupTimeField: "*default", AnswerTimeField: "*default", UsageField: "*default"}, diff --git a/utils/rsrfield.go b/utils/rsrfield.go index 6de14784a..ed1c2ec18 100644 --- a/utils/rsrfield.go +++ b/utils/rsrfield.go @@ -100,9 +100,12 @@ func (rsrf *RSRField) RegexpMatched() bool { // Investigate whether we had a reg } // Parses list of RSRFields, used for example as multiple filters in derived charging -func ParseRSRFields(fldsStr string) ([]*RSRField, error) { +func ParseRSRFields(fldsStr, sep string) ([]*RSRField, error) { //rsrRlsPattern := regexp.MustCompile(`^(~\w+:s/.+/.*/)|(\^.+(/.+/)?)(;(~\w+:s/.+/.*/)|(\^.+(/.+/)?))*$`) //ToDo:Fix here rule able to confirm the content - rulesSplt := strings.Split(fldsStr, ";") + if len(fldsStr) == 0 { + return nil, nil + } + rulesSplt := strings.Split(fldsStr, sep) rsrFields := make([]*RSRField, len(rulesSplt)) for idx, ruleStr := range rulesSplt { if !strings.HasSuffix(ruleStr, "/") { diff --git a/utils/rsrfield_test.go b/utils/rsrfield_test.go index 985318003..1c8c0c271 100644 --- a/utils/rsrfield_test.go +++ b/utils/rsrfield_test.go @@ -148,7 +148,7 @@ func TestParseRSRFields(t *testing.T) { rsrFld3, _ := NewRSRField(`^destination/+4912345/`) rsrFld4, _ := NewRSRField(`~mediation_runid:s/^default$/default/`) eRSRFields := []*RSRField{rsrFld1, rsrFld2, rsrFld3, rsrFld4} - if rsrFlds, err := ParseRSRFields(fieldsStr1); err != nil { + if rsrFlds, err := ParseRSRFields(fieldsStr1, INFIELD_SEP); err != nil { t.Error("Unexpected error: ", err) } else if !reflect.DeepEqual(eRSRFields, rsrFlds) { t.Errorf("Expecting: %v, received: %v", eRSRFields, rsrFlds) diff --git a/utils/storedcdr_test.go b/utils/storedcdr_test.go index e71a96ae2..bfc02bfd9 100644 --- a/utils/storedcdr_test.go +++ b/utils/storedcdr_test.go @@ -126,7 +126,7 @@ func TestPassesFieldFilterDn1(t *testing.T) { cdr := &StoredCdr{CgrId: Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), Account: "futurem0005", ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, } - acntPrefxFltr, _ := NewRSRField(`~account:s/^\w+[s,h,m,p]\d{4}$//`) + acntPrefxFltr, _ := NewRSRField(`~account:s/^\w+[shmp]\d{4}$//`) if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); !pass { t.Error("Not passing valid filter") }