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  }