diff --git a/config/navigablemap.go b/config/navigablemap.go index 091d4bd4f..e881dea3a 100644 --- a/config/navigablemap.go +++ b/config/navigablemap.go @@ -505,10 +505,9 @@ func getPathFromInterface(in interface{}, prefix string) (out []string) { } case []string: prefix = strings.TrimSuffix(prefix, ".") - for i, val := range vin { + for i := range vin { pref := fmt.Sprintf("%s[%v]", prefix, i) out = append(out, pref) - out = append(out, getPathFromInterface(val, pref+".")...) } case nil, int, int32, int64, uint32, uint64, bool, float32, float64, []uint8, time.Duration, time.Time, string: //no path default: //reflect based diff --git a/config/navigablemap_test.go b/config/navigablemap_test.go index db3e7cb35..c7caf898f 100644 --- a/config/navigablemap_test.go +++ b/config/navigablemap_test.go @@ -21,6 +21,7 @@ import ( "encoding/xml" "fmt" "reflect" + "sort" "strings" "testing" @@ -1056,3 +1057,57 @@ func TestNavMapFieldAsInterface(t *testing.T) { t.Errorf("Expected: %s , received: %s", utils.ToJSON(eVal), utils.ToJSON(rplyVal)) } } + +func TestNavMapGetKeys(t *testing.T) { + navMp := NewNavigableMap( + map[string]interface{}{ + "FirstLevel": map[string]interface{}{ + "SecondLevel": map[string]interface{}{ + "ThirdLevel": map[string]interface{}{ + "Fld1": 123.123, + }, + }, + }, + "FistLever2": map[string]interface{}{ + "SecondLevel2": map[string]interface{}{ + "Field2": 123, + }, + "Field3": "Value3", + "Field4": &testStruct{ + Item1: "Ten", + Item2: 10, + }, + }, + "Field5": &testStruct{ + Item1: "Ten", + Item2: 10, + }, + "Field6": []string{"1", "2"}, + }, + ) + expKeys := []string{ + "FirstLevel", + "FirstLevel.SecondLevel", + "FirstLevel.SecondLevel.ThirdLevel", + "FirstLevel.SecondLevel.ThirdLevel.Fld1", + "FistLever2", + "FistLever2.SecondLevel2", + "FistLever2.SecondLevel2.Field2", + "FistLever2.Field3", + "FistLever2.Field4", + "FistLever2.Field4.Item1", + "FistLever2.Field4.Item2", + "Field5", + "Field5.Item1", + "Field5.Item2", + "Field6", + "Field6[0]", + "Field6[1]", + } + keys := navMp.GetKeys() + sort.Strings(expKeys) + sort.Strings(keys) + if !reflect.DeepEqual(expKeys, keys) { + t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(expKeys), utils.ToJSON(keys)) + } +} diff --git a/engine/filterhelpers_test.go b/engine/filterhelpers_test.go index df152224b..324c30500 100644 --- a/engine/filterhelpers_test.go +++ b/engine/filterhelpers_test.go @@ -103,3 +103,75 @@ func TestFilterMatchingItemIDsForEvent(t *testing.T) { t.Errorf("Expecting: %+v, received: %+v", prefixFilterID, aPrflIDs) } } + +func TestFilterMatchingItemIDsForEvent2(t *testing.T) { + var stringFilter, prefixFilter, defaultFilter []*FilterRule + stringFilterID := "stringFilterID" + prefixFilterID := "prefixFilterID" + data := NewInternalDB(nil, nil) + dmMatch = NewDataManager(data, config.CgrConfig().CacheCfg(), nil) + context := utils.MetaRating + x, err := NewFilterRule(utils.MetaString, "~*req.CallCost.Account", []string{"1001"}) + if err != nil { + t.Errorf("Error: %+v", err) + } + stringFilter = append(stringFilter, x) + attribStringF := &Filter{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "stringFilter", + Rules: stringFilter} + dmMatch.SetFilter(attribStringF) + x, err = NewFilterRule(utils.MetaPrefix, "~*req.CallCost.Field", []string{"profile"}) + if err != nil { + t.Errorf("Error: %+v", err) + } + prefixFilter = append(prefixFilter, x) + attribPrefF := &Filter{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "prefFilter", + Rules: prefixFilter} + dmMatch.SetFilter(attribPrefF) + x, err = NewFilterRule(utils.MetaGreaterOrEqual, "~*req.Weight", []string{"200.00"}) + if err != nil { + t.Errorf("Error: %+v", err) + } + defaultFilter = append(defaultFilter, x) + attribDefaultF := &Filter{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "defaultFilter", + Rules: defaultFilter} + dmMatch.SetFilter(attribDefaultF) + prefix := utils.ConcatenatedKey(config.CgrConfig().GeneralCfg().DefaultTenant, context) + atrRFI := NewFilterIndexer(dmMatch, utils.AttributeProfilePrefix, prefix) + atrRFI.IndexTPFilter(FilterToTPFilter(attribStringF), stringFilterID) + atrRFI.IndexTPFilter(FilterToTPFilter(attribPrefF), prefixFilterID) + err = atrRFI.StoreIndexes(true, utils.NonTransactional) + if err != nil { + t.Errorf("Error: %+v", err) + } + matchEV = map[string]interface{}{ + utils.AnswerTime: time.Date(2014, 7, 14, 14, 30, 0, 0, time.UTC), + "CallCost": map[string]interface{}{"Account": 1001}, + } + aPrflIDs, err := MatchingItemIDsForEvent(matchEV, nil, nil, + dmMatch, utils.CacheAttributeFilterIndexes, prefix, true, true) + if err != nil { + t.Errorf("Error: %+v", err) + } + _, has := aPrflIDs[stringFilterID] + if !has { + t.Errorf("Expecting: %+v, received: %+v", stringFilterID, aPrflIDs) + } + matchEV = map[string]interface{}{ + "CallCost": map[string]interface{}{"Field": "profilePrefix"}, + } + aPrflIDs, err = MatchingItemIDsForEvent(matchEV, nil, nil, + dmMatch, utils.CacheAttributeFilterIndexes, prefix, true, true) + if err != nil { + t.Errorf("Error: %+v", err) + } + _, has = aPrflIDs[prefixFilterID] + if !has { + t.Errorf("Expecting: %+v, received: %+v", prefixFilterID, aPrflIDs) + } +}