github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/api/types/filters/parse_test.go (about)

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