...

Source file src/github.com/prometheus/alertmanager/pkg/labels/parse_test.go

Documentation: github.com/prometheus/alertmanager/pkg/labels

     1  // Copyright 2018 Prometheus Team
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package labels
    15  
    16  import (
    17  	"reflect"
    18  	"testing"
    19  )
    20  
    21  func TestMatchers(t *testing.T) {
    22  	for _, tc := range []struct {
    23  		input string
    24  		want  []*Matcher
    25  		err   string
    26  	}{
    27  		{
    28  			input: `{foo="bar"}`,
    29  			want: func() []*Matcher {
    30  				ms := []*Matcher{}
    31  				m, _ := NewMatcher(MatchEqual, "foo", "bar")
    32  				return append(ms, m)
    33  			}(),
    34  		},
    35  		{
    36  			input: `{foo=~"bar.*"}`,
    37  			want: func() []*Matcher {
    38  				ms := []*Matcher{}
    39  				m, _ := NewMatcher(MatchRegexp, "foo", "bar.*")
    40  				return append(ms, m)
    41  			}(),
    42  		},
    43  		{
    44  			input: `{foo!="bar"}`,
    45  			want: func() []*Matcher {
    46  				ms := []*Matcher{}
    47  				m, _ := NewMatcher(MatchNotEqual, "foo", "bar")
    48  				return append(ms, m)
    49  			}(),
    50  		},
    51  		{
    52  			input: `{foo!~"bar.*"}`,
    53  			want: func() []*Matcher {
    54  				ms := []*Matcher{}
    55  				m, _ := NewMatcher(MatchNotRegexp, "foo", "bar.*")
    56  				return append(ms, m)
    57  			}(),
    58  		},
    59  		{
    60  			input: `{foo="bar", baz!="quux"}`,
    61  			want: func() []*Matcher {
    62  				ms := []*Matcher{}
    63  				m, _ := NewMatcher(MatchEqual, "foo", "bar")
    64  				m2, _ := NewMatcher(MatchNotEqual, "baz", "quux")
    65  				return append(ms, m, m2)
    66  			}(),
    67  		},
    68  		{
    69  			input: `{foo="bar", baz!~"quux.*"}`,
    70  			want: func() []*Matcher {
    71  				ms := []*Matcher{}
    72  				m, _ := NewMatcher(MatchEqual, "foo", "bar")
    73  				m2, _ := NewMatcher(MatchNotRegexp, "baz", "quux.*")
    74  				return append(ms, m, m2)
    75  			}(),
    76  		},
    77  		{
    78  			input: `{foo="bar",baz!~".*quux", derp="wat"}`,
    79  			want: func() []*Matcher {
    80  				ms := []*Matcher{}
    81  				m, _ := NewMatcher(MatchEqual, "foo", "bar")
    82  				m2, _ := NewMatcher(MatchNotRegexp, "baz", ".*quux")
    83  				m3, _ := NewMatcher(MatchEqual, "derp", "wat")
    84  				return append(ms, m, m2, m3)
    85  			}(),
    86  		},
    87  		{
    88  			input: `{foo="bar", baz!="quux", derp="wat"}`,
    89  			want: func() []*Matcher {
    90  				ms := []*Matcher{}
    91  				m, _ := NewMatcher(MatchEqual, "foo", "bar")
    92  				m2, _ := NewMatcher(MatchNotEqual, "baz", "quux")
    93  				m3, _ := NewMatcher(MatchEqual, "derp", "wat")
    94  				return append(ms, m, m2, m3)
    95  			}(),
    96  		},
    97  		{
    98  			input: `{foo="bar", baz!~".*quux.*", derp="wat"}`,
    99  			want: func() []*Matcher {
   100  				ms := []*Matcher{}
   101  				m, _ := NewMatcher(MatchEqual, "foo", "bar")
   102  				m2, _ := NewMatcher(MatchNotRegexp, "baz", ".*quux.*")
   103  				m3, _ := NewMatcher(MatchEqual, "derp", "wat")
   104  				return append(ms, m, m2, m3)
   105  			}(),
   106  		},
   107  		{
   108  			input: `{foo="bar", instance=~"some-api.*"}`,
   109  			want: func() []*Matcher {
   110  				ms := []*Matcher{}
   111  				m, _ := NewMatcher(MatchEqual, "foo", "bar")
   112  				m2, _ := NewMatcher(MatchRegexp, "instance", "some-api.*")
   113  				return append(ms, m, m2)
   114  			}(),
   115  		},
   116  		{
   117  			input: `{foo=""}`,
   118  			want: func() []*Matcher {
   119  				ms := []*Matcher{}
   120  				m, _ := NewMatcher(MatchEqual, "foo", "")
   121  				return append(ms, m)
   122  			}(),
   123  		},
   124  		{
   125  			input: `{foo="bar,quux", job="job1"}`,
   126  			want: func() []*Matcher {
   127  				ms := []*Matcher{}
   128  				m, _ := NewMatcher(MatchEqual, "foo", "bar,quux")
   129  				m2, _ := NewMatcher(MatchEqual, "job", "job1")
   130  				return append(ms, m, m2)
   131  			}(),
   132  		},
   133  		{
   134  			input: `{foo = "bar", dings != "bums", }`,
   135  			want: func() []*Matcher {
   136  				ms := []*Matcher{}
   137  				m, _ := NewMatcher(MatchEqual, "foo", "bar")
   138  				m2, _ := NewMatcher(MatchNotEqual, "dings", "bums")
   139  				return append(ms, m, m2)
   140  			}(),
   141  		},
   142  		{
   143  			input: `foo=bar,dings!=bums`,
   144  			want: func() []*Matcher {
   145  				ms := []*Matcher{}
   146  				m, _ := NewMatcher(MatchEqual, "foo", "bar")
   147  				m2, _ := NewMatcher(MatchNotEqual, "dings", "bums")
   148  				return append(ms, m, m2)
   149  			}(),
   150  		},
   151  		{
   152  			input: `{quote="She said: \"Hi, ladies! That's gender-neutral…\""}`,
   153  			want: func() []*Matcher {
   154  				ms := []*Matcher{}
   155  				m, _ := NewMatcher(MatchEqual, "quote", `She said: "Hi, ladies! That's gender-neutral…"`)
   156  				return append(ms, m)
   157  			}(),
   158  		},
   159  		{
   160  			input: `statuscode=~"5.."`,
   161  			want: func() []*Matcher {
   162  				ms := []*Matcher{}
   163  				m, _ := NewMatcher(MatchRegexp, "statuscode", "5..")
   164  				return append(ms, m)
   165  			}(),
   166  		},
   167  		{
   168  			input: `tricky=~~~`,
   169  			want: func() []*Matcher {
   170  				ms := []*Matcher{}
   171  				m, _ := NewMatcher(MatchRegexp, "tricky", "~~")
   172  				return append(ms, m)
   173  			}(),
   174  		},
   175  		{
   176  			input: `trickier==\\=\=\"`,
   177  			want: func() []*Matcher {
   178  				ms := []*Matcher{}
   179  				m, _ := NewMatcher(MatchEqual, "trickier", `=\=\="`)
   180  				return append(ms, m)
   181  			}(),
   182  		},
   183  		{
   184  			input: `contains_quote != "\"" , contains_comma !~ "foo,bar" , `,
   185  			want: func() []*Matcher {
   186  				ms := []*Matcher{}
   187  				m, _ := NewMatcher(MatchNotEqual, "contains_quote", `"`)
   188  				m2, _ := NewMatcher(MatchNotRegexp, "contains_comma", "foo,bar")
   189  				return append(ms, m, m2)
   190  			}(),
   191  		},
   192  		{
   193  			input: `job=`,
   194  			want: func() []*Matcher {
   195  				m, _ := NewMatcher(MatchEqual, "job", "")
   196  				return []*Matcher{m}
   197  			}(),
   198  		},
   199  		{
   200  			input: `job="value`,
   201  			err:   `matcher value contains unescaped double quote: "value`,
   202  		},
   203  		{
   204  			input: `job=value"`,
   205  			err:   `matcher value contains unescaped double quote: value"`,
   206  		},
   207  		{
   208  			input: `trickier==\\=\=\""`,
   209  			err:   `matcher value contains unescaped double quote: =\\=\=\""`,
   210  		},
   211  		{
   212  			input: `contains_unescaped_quote = foo"bar`,
   213  			err:   `matcher value contains unescaped double quote: foo"bar`,
   214  		},
   215  		{
   216  			input: `{invalid-name = "valid label"}`,
   217  			err:   `bad matcher format: invalid-name = "valid label"`,
   218  		},
   219  		{
   220  			input: `{foo=~"invalid[regexp"}`,
   221  			err:   "error parsing regexp: missing closing ]: `[regexp)$`",
   222  		},
   223  		// Double escaped strings.
   224  		{
   225  			input: `"{foo=\"bar"}`,
   226  			err:   `bad matcher format: "{foo=\"bar"`,
   227  		},
   228  		{
   229  			input: `"foo=\"bar"`,
   230  			err:   `bad matcher format: "foo=\"bar"`,
   231  		},
   232  		{
   233  			input: `"foo=\"bar\""`,
   234  			err:   `bad matcher format: "foo=\"bar\""`,
   235  		},
   236  		{
   237  			input: `"foo=\"bar\"`,
   238  			err:   `bad matcher format: "foo=\"bar\"`,
   239  		},
   240  		{
   241  			input: `"{foo=\"bar\"}"`,
   242  			err:   `bad matcher format: "{foo=\"bar\"}"`,
   243  		},
   244  		{
   245  			input: `"foo="bar""`,
   246  			err:   `bad matcher format: "foo="bar""`,
   247  		},
   248  	} {
   249  		t.Run(tc.input, func(t *testing.T) {
   250  			got, err := ParseMatchers(tc.input)
   251  			if err != nil && tc.err == "" {
   252  				t.Fatalf("got error where none expected: %v", err)
   253  			}
   254  			if err == nil && tc.err != "" {
   255  				t.Fatalf("expected error but got none: %v", tc.err)
   256  			}
   257  			if err != nil && err.Error() != tc.err {
   258  				t.Fatalf("error not equal:\ngot  %v\nwant %v", err, tc.err)
   259  			}
   260  			if !reflect.DeepEqual(got, tc.want) {
   261  				t.Fatalf("labels not equal:\ngot  %v\nwant %v", got, tc.want)
   262  			}
   263  		})
   264  	}
   265  }
   266  

View as plain text