From f5df55666b6268112bea6b2840db36c6692cb118 Mon Sep 17 00:00:00 2001 From: Stuart Nelson Date: Tue, 20 Mar 2018 10:08:20 +0100 Subject: [PATCH] Filter empty matchers correctly --- api/api.go | 6 ++++++ api/api_test.go | 32 ++++++++++++++++++++++++++++++++ pkg/parse/parse.go | 4 ++-- pkg/parse/parse_test.go | 8 ++++++++ 4 files changed, 48 insertions(+), 2 deletions(-) diff --git a/api/api.go b/api/api.go index a1bee551..e64738bf 100644 --- a/api/api.go +++ b/api/api.go @@ -696,10 +696,16 @@ func matchFilterLabels(matchers []*labels.Matcher, sms map[string]string) bool { v, prs := sms[m.Name] switch m.Type { case labels.MatchNotEqual, labels.MatchNotRegexp: + if string(v) == "" && prs { + return true + } if !m.Matches(string(v)) { return false } default: + if string(v) == "" && !prs { + return true + } if !prs || !m.Matches(string(v)) { return false } diff --git a/api/api_test.go b/api/api_test.go index 6090ba70..643dfd37 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -312,6 +312,38 @@ func TestReceiversMatchFilter(t *testing.T) { require.False(t, receiversMatchFilter(receivers, filter)) } +func TestMatchFilterLabels(t *testing.T) { + testCases := []struct { + matcher labels.MatchType + expected bool + }{ + {labels.MatchEqual, true}, + {labels.MatchRegexp, true}, + {labels.MatchNotEqual, false}, + {labels.MatchNotRegexp, false}, + } + + for _, tc := range testCases { + l, err := labels.NewMatcher(tc.matcher, "foo", "") + require.NoError(t, err) + sms := map[string]string{ + "baz": "bar", + } + ls := []*labels.Matcher{l} + + require.Equal(t, tc.expected, matchFilterLabels(ls, sms)) + + l, err = labels.NewMatcher(tc.matcher, "foo", "") + require.NoError(t, err) + sms = map[string]string{ + "baz": "bar", + "foo": "quux", + } + ls = []*labels.Matcher{l} + require.NotEqual(t, tc.expected, matchFilterLabels(ls, sms)) + } +} + func newMatcher(labelSet model.LabelSet) types.Matchers { matchers := make([]*types.Matcher, 0, len(labelSet)) for key, val := range labelSet { diff --git a/pkg/parse/parse.go b/pkg/parse/parse.go index 593e3e24..33ea22c0 100644 --- a/pkg/parse/parse.go +++ b/pkg/parse/parse.go @@ -9,7 +9,7 @@ import ( ) var ( - re = regexp.MustCompile(`(?:\s?)(\w+)(=|=~|!=|!~)(?:\"([^"=~!]+)\"|([^"=~!]+))`) + re = regexp.MustCompile(`(?:\s?)(\w+)(=|=~|!=|!~)(?:\"([^"=~!]+)\"|([^"=~!]+)|\"\")`) typeMap = map[string]labels.MatchType{ "=": labels.MatchEqual, "!=": labels.MatchNotEqual, @@ -66,7 +66,7 @@ func Input(s string) (name, value string, matchType labels.MatchType, err error) value = ms[4] } - if name == "" || value == "" || !prs { + if name == "" || !prs { return "", "", labels.MatchEqual, fmt.Errorf("failed to parse") } diff --git a/pkg/parse/parse_test.go b/pkg/parse/parse_test.go index 2d496b74..a9be6b12 100644 --- a/pkg/parse/parse_test.go +++ b/pkg/parse/parse_test.go @@ -101,6 +101,14 @@ func TestMatchers(t *testing.T) { return append(ms, m, m2) }(), }, + { + input: `{foo=""}`, + want: func() []*labels.Matcher { + ms := []*labels.Matcher{} + m, _ := labels.NewMatcher(labels.MatchEqual, "foo", "") + return append(ms, m) + }(), + }, } for i, tc := range testCases {