github.com/netdata/go.d.plugin@v0.58.1/agent/discovery/sd/pipeline/selector_test.go (about) 1 // SPDX-License-Identifier: GPL-3.0-or-later 2 3 package pipeline 4 5 import ( 6 "regexp" 7 "testing" 8 9 "github.com/netdata/go.d.plugin/agent/discovery/sd/model" 10 11 "github.com/stretchr/testify/assert" 12 ) 13 14 var reSrString = regexp.MustCompile(`^{[^{}]+}$`) 15 16 func TestTrueSelector_String(t *testing.T) { 17 var sr trueSelector 18 assert.Equal(t, "{*}", sr.String()) 19 } 20 21 func TestExactSelector_String(t *testing.T) { 22 sr := exactSelector("selector") 23 24 assert.True(t, reSrString.MatchString(sr.String())) 25 } 26 27 func TestNegSelector_String(t *testing.T) { 28 srs := []selector{ 29 exactSelector("selector"), 30 negSelector{exactSelector("selector")}, 31 orSelector{ 32 lhs: exactSelector("selector"), 33 rhs: exactSelector("selector")}, 34 orSelector{ 35 lhs: orSelector{lhs: exactSelector("selector"), rhs: negSelector{exactSelector("selector")}}, 36 rhs: orSelector{lhs: exactSelector("selector"), rhs: negSelector{exactSelector("selector")}}, 37 }, 38 andSelector{ 39 lhs: andSelector{lhs: exactSelector("selector"), rhs: negSelector{exactSelector("selector")}}, 40 rhs: andSelector{lhs: exactSelector("selector"), rhs: negSelector{exactSelector("selector")}}, 41 }, 42 } 43 44 for i, sr := range srs { 45 neg := negSelector{sr} 46 assert.True(t, reSrString.MatchString(neg.String()), "selector num %d", i+1) 47 } 48 } 49 50 func TestOrSelector_String(t *testing.T) { 51 sr := orSelector{ 52 lhs: orSelector{lhs: exactSelector("selector"), rhs: negSelector{exactSelector("selector")}}, 53 rhs: orSelector{lhs: exactSelector("selector"), rhs: negSelector{exactSelector("selector")}}, 54 } 55 56 assert.True(t, reSrString.MatchString(sr.String())) 57 } 58 59 func TestAndSelector_String(t *testing.T) { 60 sr := andSelector{ 61 lhs: andSelector{lhs: exactSelector("selector"), rhs: negSelector{exactSelector("selector")}}, 62 rhs: andSelector{lhs: exactSelector("selector"), rhs: negSelector{exactSelector("selector")}}, 63 } 64 65 assert.True(t, reSrString.MatchString(sr.String())) 66 } 67 68 func TestExactSelector_Matches(t *testing.T) { 69 matchTests := struct { 70 tags model.Tags 71 srs []exactSelector 72 }{ 73 tags: model.Tags{"a": {}, "b": {}}, 74 srs: []exactSelector{ 75 "a", 76 "b", 77 }, 78 } 79 notMatchTests := struct { 80 tags model.Tags 81 srs []exactSelector 82 }{ 83 tags: model.Tags{"a": {}, "b": {}}, 84 srs: []exactSelector{ 85 "c", 86 "d", 87 }, 88 } 89 90 for i, sr := range matchTests.srs { 91 assert.Truef(t, sr.matches(matchTests.tags), "match selector num %d", i+1) 92 } 93 for i, sr := range notMatchTests.srs { 94 assert.Falsef(t, sr.matches(notMatchTests.tags), "not match selector num %d", i+1) 95 } 96 } 97 98 func TestNegSelector_Matches(t *testing.T) { 99 matchTests := struct { 100 tags model.Tags 101 srs []negSelector 102 }{ 103 tags: model.Tags{"a": {}, "b": {}}, 104 srs: []negSelector{ 105 {exactSelector("c")}, 106 {exactSelector("d")}, 107 }, 108 } 109 notMatchTests := struct { 110 tags model.Tags 111 srs []negSelector 112 }{ 113 tags: model.Tags{"a": {}, "b": {}}, 114 srs: []negSelector{ 115 {exactSelector("a")}, 116 {exactSelector("b")}, 117 }, 118 } 119 120 for i, sr := range matchTests.srs { 121 assert.Truef(t, sr.matches(matchTests.tags), "match selector num %d", i+1) 122 } 123 for i, sr := range notMatchTests.srs { 124 assert.Falsef(t, sr.matches(notMatchTests.tags), "not match selector num %d", i+1) 125 } 126 } 127 128 func TestOrSelector_Matches(t *testing.T) { 129 matchTests := struct { 130 tags model.Tags 131 srs []orSelector 132 }{ 133 tags: model.Tags{"a": {}, "b": {}}, 134 srs: []orSelector{ 135 { 136 lhs: orSelector{lhs: exactSelector("c"), rhs: exactSelector("d")}, 137 rhs: orSelector{lhs: exactSelector("e"), rhs: exactSelector("b")}, 138 }, 139 }, 140 } 141 notMatchTests := struct { 142 tags model.Tags 143 srs []orSelector 144 }{ 145 tags: model.Tags{"a": {}, "b": {}}, 146 srs: []orSelector{ 147 { 148 lhs: orSelector{lhs: exactSelector("c"), rhs: exactSelector("d")}, 149 rhs: orSelector{lhs: exactSelector("e"), rhs: exactSelector("f")}, 150 }, 151 }, 152 } 153 154 for i, sr := range matchTests.srs { 155 assert.Truef(t, sr.matches(matchTests.tags), "match selector num %d", i+1) 156 } 157 for i, sr := range notMatchTests.srs { 158 assert.Falsef(t, sr.matches(notMatchTests.tags), "not match selector num %d", i+1) 159 } 160 } 161 162 func TestAndSelector_Matches(t *testing.T) { 163 matchTests := struct { 164 tags model.Tags 165 srs []andSelector 166 }{ 167 tags: model.Tags{"a": {}, "b": {}, "c": {}, "d": {}}, 168 srs: []andSelector{ 169 { 170 lhs: andSelector{lhs: exactSelector("a"), rhs: exactSelector("b")}, 171 rhs: andSelector{lhs: exactSelector("c"), rhs: exactSelector("d")}, 172 }, 173 }, 174 } 175 notMatchTests := struct { 176 tags model.Tags 177 srs []andSelector 178 }{ 179 tags: model.Tags{"a": {}, "b": {}, "c": {}, "d": {}}, 180 srs: []andSelector{ 181 { 182 lhs: andSelector{lhs: exactSelector("a"), rhs: exactSelector("b")}, 183 rhs: andSelector{lhs: exactSelector("c"), rhs: exactSelector("z")}, 184 }, 185 }, 186 } 187 188 for i, sr := range matchTests.srs { 189 assert.Truef(t, sr.matches(matchTests.tags), "match selector num %d", i+1) 190 } 191 for i, sr := range notMatchTests.srs { 192 assert.Falsef(t, sr.matches(notMatchTests.tags), "not match selector num %d", i+1) 193 } 194 } 195 196 func TestParseSelector(t *testing.T) { 197 tests := map[string]struct { 198 wantSelector selector 199 wantErr bool 200 }{ 201 "": {wantSelector: trueSelector{}}, 202 "a": {wantSelector: exactSelector("a")}, 203 "Z": {wantSelector: exactSelector("Z")}, 204 "a_b": {wantSelector: exactSelector("a_b")}, 205 "a=b": {wantSelector: exactSelector("a=b")}, 206 "!a": {wantSelector: negSelector{exactSelector("a")}}, 207 "a b": {wantSelector: andSelector{lhs: exactSelector("a"), rhs: exactSelector("b")}}, 208 "a|b": {wantSelector: orSelector{lhs: exactSelector("a"), rhs: exactSelector("b")}}, 209 "*": {wantSelector: trueSelector{}}, 210 "!*": {wantSelector: negSelector{trueSelector{}}}, 211 "a b !c d|e f": { 212 wantSelector: andSelector{ 213 lhs: andSelector{ 214 lhs: andSelector{ 215 lhs: andSelector{lhs: exactSelector("a"), rhs: exactSelector("b")}, 216 rhs: negSelector{exactSelector("c")}, 217 }, 218 rhs: orSelector{ 219 lhs: exactSelector("d"), 220 rhs: exactSelector("e"), 221 }, 222 }, 223 rhs: exactSelector("f"), 224 }, 225 }, 226 "!": {wantErr: true}, 227 "a !": {wantErr: true}, 228 "a!b": {wantErr: true}, 229 "0a": {wantErr: true}, 230 "a b c*": {wantErr: true}, 231 "__": {wantErr: true}, 232 "a|b|c*": {wantErr: true}, 233 } 234 235 for name, test := range tests { 236 t.Run(name, func(t *testing.T) { 237 sr, err := parseSelector(name) 238 239 if test.wantErr { 240 assert.Nil(t, sr) 241 assert.Error(t, err) 242 } else { 243 assert.NoError(t, err) 244 assert.Equal(t, test.wantSelector, sr) 245 } 246 }) 247 } 248 }