github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/query/parser/promql/matcher_test.go (about) 1 // Copyright (c) 2019 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package promql 22 23 import ( 24 "bytes" 25 "regexp" 26 "testing" 27 28 "github.com/m3db/m3/src/query/models" 29 30 "github.com/prometheus/prometheus/model/labels" 31 "github.com/stretchr/testify/assert" 32 "github.com/stretchr/testify/require" 33 ) 34 35 func TestLabelMatchesToModelMatcher(t *testing.T) { 36 opts := models.NewTagOptions() 37 38 labels := []*labels.Matcher{ 39 { 40 Type: labels.MatchEqual, 41 Name: "foo", 42 }, 43 { 44 Type: labels.MatchEqual, 45 Name: "foo", 46 Value: "bar", 47 }, 48 { 49 Type: labels.MatchNotEqual, 50 Name: "foo", 51 }, 52 { 53 Type: labels.MatchNotEqual, 54 Name: "foo", 55 Value: "bar", 56 }, 57 { 58 Type: labels.MatchRegexp, 59 Name: "foo", 60 Value: ".*", 61 }, 62 { 63 Type: labels.MatchNotRegexp, 64 Name: "foo", 65 Value: ".*", 66 }, 67 } 68 69 matchers, err := LabelMatchersToModelMatcher(labels, opts) 70 assert.NoError(t, err) 71 72 expected := models.Matchers{ 73 models.Matcher{ 74 Type: models.MatchNotField, 75 Name: []byte("foo"), 76 Value: []byte{}, 77 }, 78 models.Matcher{ 79 Type: models.MatchEqual, 80 Name: []byte("foo"), 81 Value: []byte("bar"), 82 }, 83 models.Matcher{ 84 Type: models.MatchField, 85 Name: []byte("foo"), 86 Value: []byte{}, 87 }, 88 models.Matcher{ 89 Type: models.MatchNotEqual, 90 Name: []byte("foo"), 91 Value: []byte("bar"), 92 }, 93 models.Matcher{ 94 Type: models.MatchRegexp, 95 Name: []byte("foo"), 96 Value: []byte(".*"), 97 }, 98 models.Matcher{ 99 Type: models.MatchNotRegexp, 100 Name: []byte("foo"), 101 Value: []byte(".*"), 102 }, 103 } 104 105 require.Equal(t, len(expected), len(matchers)) 106 equalish := func(a, b models.Matcher) bool { 107 return bytes.Equal(a.Name, b.Name) && 108 bytes.Equal(a.Value, b.Value) && 109 a.Type == b.Type 110 } 111 112 for i, ex := range expected { 113 assert.True(t, equalish(ex, matchers[i])) 114 } 115 } 116 117 func TestSanitizeRegex(t *testing.T) { 118 tests := []struct { 119 data, expected string 120 }{ 121 {data: "", expected: ""}, 122 123 {data: "bar", expected: "bar"}, 124 125 {data: "^bar", expected: "bar"}, 126 {data: "b^ar", expected: "ar"}, 127 {data: "ba^r", expected: "r"}, 128 {data: "bar^", expected: ""}, 129 130 {data: "bar$", expected: "bar"}, 131 {data: "ba$r", expected: "ba"}, 132 {data: "b$ar", expected: "b"}, 133 {data: "$bar", expected: ""}, 134 135 {data: "b^a$r", expected: "a"}, 136 {data: "^bar$", expected: "bar"}, 137 138 {data: "b$^ar", expected: ""}, 139 {data: "b$ar^", expected: ""}, 140 141 {data: `ba\^r`, expected: `ba\^r`}, 142 {data: `ba\$r`, expected: `ba\$r`}, 143 {data: `b^a\$r`, expected: `a\$r`}, 144 {data: `b$a\$r`, expected: `b`}, 145 146 {data: "b[$^]ar", expected: "b[$^]ar"}, 147 {data: "b[^$]ar", expected: "b[^$]ar"}, 148 149 {data: `b[^\]$]ar`, expected: `b[^\]$]ar`}, 150 {data: `b[^\]$]^ar`, expected: "ar"}, 151 {data: `b[^\]$]$ar`, expected: `b[^\]$]`}, 152 153 {data: `b\[^\]$]$ar`, expected: `\]$]`}, 154 } 155 156 for _, tt := range tests { 157 ac := sanitizeRegex([]byte(tt.data)) 158 assert.Equal(t, tt.expected, string(ac)) 159 _, err := regexp.Compile("^(?:" + string(ac) + ")$") 160 assert.NoError(t, err) 161 } 162 }