github.com/shopify/docker@v1.13.1/api/types/filters/parse_test.go (about) 1 package filters 2 3 import ( 4 "fmt" 5 "testing" 6 ) 7 8 func TestParseArgs(t *testing.T) { 9 // equivalent of `docker ps -f 'created=today' -f 'image.name=ubuntu*' -f 'image.name=*untu'` 10 flagArgs := []string{ 11 "created=today", 12 "image.name=ubuntu*", 13 "image.name=*untu", 14 } 15 var ( 16 args = NewArgs() 17 err error 18 ) 19 for i := range flagArgs { 20 args, err = ParseFlag(flagArgs[i], args) 21 if err != nil { 22 t.Errorf("failed to parse %s: %s", flagArgs[i], err) 23 } 24 } 25 if len(args.Get("created")) != 1 { 26 t.Errorf("failed to set this arg") 27 } 28 if len(args.Get("image.name")) != 2 { 29 t.Errorf("the args should have collapsed") 30 } 31 } 32 33 func TestParseArgsEdgeCase(t *testing.T) { 34 var filters Args 35 args, err := ParseFlag("", filters) 36 if err != nil { 37 t.Fatal(err) 38 } 39 if args.Len() != 0 { 40 t.Fatalf("Expected an empty Args (map), got %v", args) 41 } 42 if args, err = ParseFlag("anything", args); err == nil || err != ErrBadFormat { 43 t.Fatalf("Expected ErrBadFormat, got %v", err) 44 } 45 } 46 47 func TestToParam(t *testing.T) { 48 fields := map[string]map[string]bool{ 49 "created": {"today": true}, 50 "image.name": {"ubuntu*": true, "*untu": true}, 51 } 52 a := Args{fields: fields} 53 54 _, err := ToParam(a) 55 if err != nil { 56 t.Errorf("failed to marshal the filters: %s", err) 57 } 58 } 59 60 func TestToParamWithVersion(t *testing.T) { 61 fields := map[string]map[string]bool{ 62 "created": {"today": true}, 63 "image.name": {"ubuntu*": true, "*untu": true}, 64 } 65 a := Args{fields: fields} 66 67 str1, err := ToParamWithVersion("1.21", a) 68 if err != nil { 69 t.Errorf("failed to marshal the filters with version < 1.22: %s", err) 70 } 71 str2, err := ToParamWithVersion("1.22", a) 72 if err != nil { 73 t.Errorf("failed to marshal the filters with version >= 1.22: %s", err) 74 } 75 if str1 != `{"created":["today"],"image.name":["*untu","ubuntu*"]}` && 76 str1 != `{"created":["today"],"image.name":["ubuntu*","*untu"]}` { 77 t.Errorf("incorrectly marshaled the filters: %s", str1) 78 } 79 if str2 != `{"created":{"today":true},"image.name":{"*untu":true,"ubuntu*":true}}` && 80 str2 != `{"created":{"today":true},"image.name":{"ubuntu*":true,"*untu":true}}` { 81 t.Errorf("incorrectly marshaled the filters: %s", str2) 82 } 83 } 84 85 func TestFromParam(t *testing.T) { 86 invalids := []string{ 87 "anything", 88 "['a','list']", 89 "{'key': 'value'}", 90 `{"key": "value"}`, 91 } 92 valid := map[*Args][]string{ 93 &Args{fields: map[string]map[string]bool{"key": {"value": true}}}: { 94 `{"key": ["value"]}`, 95 `{"key": {"value": true}}`, 96 }, 97 &Args{fields: map[string]map[string]bool{"key": {"value1": true, "value2": true}}}: { 98 `{"key": ["value1", "value2"]}`, 99 `{"key": {"value1": true, "value2": true}}`, 100 }, 101 &Args{fields: map[string]map[string]bool{"key1": {"value1": true}, "key2": {"value2": true}}}: { 102 `{"key1": ["value1"], "key2": ["value2"]}`, 103 `{"key1": {"value1": true}, "key2": {"value2": true}}`, 104 }, 105 } 106 107 for _, invalid := range invalids { 108 if _, err := FromParam(invalid); err == nil { 109 t.Fatalf("Expected an error with %v, got nothing", invalid) 110 } 111 } 112 113 for expectedArgs, matchers := range valid { 114 for _, json := range matchers { 115 args, err := FromParam(json) 116 if err != nil { 117 t.Fatal(err) 118 } 119 if args.Len() != expectedArgs.Len() { 120 t.Fatalf("Expected %v, go %v", expectedArgs, args) 121 } 122 for key, expectedValues := range expectedArgs.fields { 123 values := args.Get(key) 124 125 if len(values) != len(expectedValues) { 126 t.Fatalf("Expected %v, go %v", expectedArgs, args) 127 } 128 129 for _, v := range values { 130 if !expectedValues[v] { 131 t.Fatalf("Expected %v, go %v", expectedArgs, args) 132 } 133 } 134 } 135 } 136 } 137 } 138 139 func TestEmpty(t *testing.T) { 140 a := Args{} 141 v, err := ToParam(a) 142 if err != nil { 143 t.Errorf("failed to marshal the filters: %s", err) 144 } 145 v1, err := FromParam(v) 146 if err != nil { 147 t.Errorf("%s", err) 148 } 149 if a.Len() != v1.Len() { 150 t.Errorf("these should both be empty sets") 151 } 152 } 153 154 func TestArgsMatchKVListEmptySources(t *testing.T) { 155 args := NewArgs() 156 if !args.MatchKVList("created", map[string]string{}) { 157 t.Fatalf("Expected true for (%v,created), got true", args) 158 } 159 160 args = Args{map[string]map[string]bool{"created": {"today": true}}} 161 if args.MatchKVList("created", map[string]string{}) { 162 t.Fatalf("Expected false for (%v,created), got true", args) 163 } 164 } 165 166 func TestArgsMatchKVList(t *testing.T) { 167 // Not empty sources 168 sources := map[string]string{ 169 "key1": "value1", 170 "key2": "value2", 171 "key3": "value3", 172 } 173 174 matches := map[*Args]string{ 175 &Args{}: "field", 176 &Args{map[string]map[string]bool{ 177 "created": map[string]bool{"today": true}, 178 "labels": map[string]bool{"key1": true}}, 179 }: "labels", 180 &Args{map[string]map[string]bool{ 181 "created": map[string]bool{"today": true}, 182 "labels": map[string]bool{"key1=value1": true}}, 183 }: "labels", 184 } 185 186 for args, field := range matches { 187 if args.MatchKVList(field, sources) != true { 188 t.Fatalf("Expected true for %v on %v, got false", sources, args) 189 } 190 } 191 192 differs := map[*Args]string{ 193 &Args{map[string]map[string]bool{ 194 "created": map[string]bool{"today": true}}, 195 }: "created", 196 &Args{map[string]map[string]bool{ 197 "created": map[string]bool{"today": true}, 198 "labels": map[string]bool{"key4": true}}, 199 }: "labels", 200 &Args{map[string]map[string]bool{ 201 "created": map[string]bool{"today": true}, 202 "labels": map[string]bool{"key1=value3": true}}, 203 }: "labels", 204 } 205 206 for args, field := range differs { 207 if args.MatchKVList(field, sources) != false { 208 t.Fatalf("Expected false for %v on %v, got true", sources, args) 209 } 210 } 211 } 212 213 func TestArgsMatch(t *testing.T) { 214 source := "today" 215 216 matches := map[*Args]string{ 217 &Args{}: "field", 218 &Args{map[string]map[string]bool{ 219 "created": map[string]bool{"today": true}}, 220 }: "today", 221 &Args{map[string]map[string]bool{ 222 "created": map[string]bool{"to*": true}}, 223 }: "created", 224 &Args{map[string]map[string]bool{ 225 "created": map[string]bool{"to(.*)": true}}, 226 }: "created", 227 &Args{map[string]map[string]bool{ 228 "created": map[string]bool{"tod": true}}, 229 }: "created", 230 &Args{map[string]map[string]bool{ 231 "created": map[string]bool{"anyting": true, "to*": true}}, 232 }: "created", 233 } 234 235 for args, field := range matches { 236 if args.Match(field, source) != true { 237 t.Fatalf("Expected true for %v on %v, got false", source, args) 238 } 239 } 240 241 differs := map[*Args]string{ 242 &Args{map[string]map[string]bool{ 243 "created": map[string]bool{"tomorrow": true}}, 244 }: "created", 245 &Args{map[string]map[string]bool{ 246 "created": map[string]bool{"to(day": true}}, 247 }: "created", 248 &Args{map[string]map[string]bool{ 249 "created": map[string]bool{"tom(.*)": true}}, 250 }: "created", 251 &Args{map[string]map[string]bool{ 252 "created": map[string]bool{"tom": true}}, 253 }: "created", 254 &Args{map[string]map[string]bool{ 255 "created": map[string]bool{"today1": true}, 256 "labels": map[string]bool{"today": true}}, 257 }: "created", 258 } 259 260 for args, field := range differs { 261 if args.Match(field, source) != false { 262 t.Fatalf("Expected false for %v on %v, got true", source, args) 263 } 264 } 265 } 266 267 func TestAdd(t *testing.T) { 268 f := NewArgs() 269 f.Add("status", "running") 270 v := f.fields["status"] 271 if len(v) != 1 || !v["running"] { 272 t.Fatalf("Expected to include a running status, got %v", v) 273 } 274 275 f.Add("status", "paused") 276 if len(v) != 2 || !v["paused"] { 277 t.Fatalf("Expected to include a paused status, got %v", v) 278 } 279 } 280 281 func TestDel(t *testing.T) { 282 f := NewArgs() 283 f.Add("status", "running") 284 f.Del("status", "running") 285 v := f.fields["status"] 286 if v["running"] { 287 t.Fatalf("Expected to not include a running status filter, got true") 288 } 289 } 290 291 func TestLen(t *testing.T) { 292 f := NewArgs() 293 if f.Len() != 0 { 294 t.Fatalf("Expected to not include any field") 295 } 296 f.Add("status", "running") 297 if f.Len() != 1 { 298 t.Fatalf("Expected to include one field") 299 } 300 } 301 302 func TestExactMatch(t *testing.T) { 303 f := NewArgs() 304 305 if !f.ExactMatch("status", "running") { 306 t.Fatalf("Expected to match `running` when there are no filters, got false") 307 } 308 309 f.Add("status", "running") 310 f.Add("status", "pause*") 311 312 if !f.ExactMatch("status", "running") { 313 t.Fatalf("Expected to match `running` with one of the filters, got false") 314 } 315 316 if f.ExactMatch("status", "paused") { 317 t.Fatalf("Expected to not match `paused` with one of the filters, got true") 318 } 319 } 320 321 func TestOnlyOneExactMatch(t *testing.T) { 322 f := NewArgs() 323 324 if !f.UniqueExactMatch("status", "running") { 325 t.Fatalf("Expected to match `running` when there are no filters, got false") 326 } 327 328 f.Add("status", "running") 329 330 if !f.UniqueExactMatch("status", "running") { 331 t.Fatalf("Expected to match `running` with one of the filters, got false") 332 } 333 334 if f.UniqueExactMatch("status", "paused") { 335 t.Fatalf("Expected to not match `paused` with one of the filters, got true") 336 } 337 338 f.Add("status", "pause") 339 if f.UniqueExactMatch("status", "running") { 340 t.Fatalf("Expected to not match only `running` with two filters, got true") 341 } 342 } 343 344 func TestInclude(t *testing.T) { 345 f := NewArgs() 346 if f.Include("status") { 347 t.Fatalf("Expected to not include a status key, got true") 348 } 349 f.Add("status", "running") 350 if !f.Include("status") { 351 t.Fatalf("Expected to include a status key, got false") 352 } 353 } 354 355 func TestValidate(t *testing.T) { 356 f := NewArgs() 357 f.Add("status", "running") 358 359 valid := map[string]bool{ 360 "status": true, 361 "dangling": true, 362 } 363 364 if err := f.Validate(valid); err != nil { 365 t.Fatal(err) 366 } 367 368 f.Add("bogus", "running") 369 if err := f.Validate(valid); err == nil { 370 t.Fatalf("Expected to return an error, got nil") 371 } 372 } 373 374 func TestWalkValues(t *testing.T) { 375 f := NewArgs() 376 f.Add("status", "running") 377 f.Add("status", "paused") 378 379 f.WalkValues("status", func(value string) error { 380 if value != "running" && value != "paused" { 381 t.Fatalf("Unexpected value %s", value) 382 } 383 return nil 384 }) 385 386 err := f.WalkValues("status", func(value string) error { 387 return fmt.Errorf("return") 388 }) 389 if err == nil { 390 t.Fatalf("Expected to get an error, got nil") 391 } 392 393 err = f.WalkValues("foo", func(value string) error { 394 return fmt.Errorf("return") 395 }) 396 if err != nil { 397 t.Fatalf("Expected to not iterate when the field doesn't exist, got %v", err) 398 } 399 } 400 401 func TestFuzzyMatch(t *testing.T) { 402 f := NewArgs() 403 f.Add("container", "foo") 404 405 cases := map[string]bool{ 406 "foo": true, 407 "foobar": true, 408 "barfoo": false, 409 "bar": false, 410 } 411 for source, match := range cases { 412 got := f.FuzzyMatch("container", source) 413 if got != match { 414 t.Fatalf("Expected %v, got %v: %s", match, got, source) 415 } 416 } 417 }