storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/bucket/policy/condition/stringequalsfunc_test.go (about)

     1  /*
     2   * MinIO Cloud Storage, (C) 2018 MinIO, Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package condition
    18  
    19  import (
    20  	"reflect"
    21  	"testing"
    22  )
    23  
    24  func TestStringEqualsFuncEvaluate(t *testing.T) {
    25  	case1Function, err := newStringEqualsFunc(S3XAmzCopySource, NewValueSet(NewStringValue("mybucket/myobject")))
    26  	if err != nil {
    27  		t.Fatalf("unexpected error. %v\n", err)
    28  	}
    29  
    30  	case2Function, err := newStringEqualsFunc(S3XAmzServerSideEncryption, NewValueSet(NewStringValue("AES256")))
    31  	if err != nil {
    32  		t.Fatalf("unexpected error. %v\n", err)
    33  	}
    34  
    35  	case3Function, err := newStringEqualsFunc(S3XAmzMetadataDirective, NewValueSet(NewStringValue("REPLACE")))
    36  	if err != nil {
    37  		t.Fatalf("unexpected error. %v\n", err)
    38  	}
    39  
    40  	case4Function, err := newStringEqualsFunc(S3LocationConstraint, NewValueSet(NewStringValue("eu-west-1")))
    41  	if err != nil {
    42  		t.Fatalf("unexpected error. %v\n", err)
    43  	}
    44  
    45  	testCases := []struct {
    46  		function       Function
    47  		values         map[string][]string
    48  		expectedResult bool
    49  	}{
    50  		{case1Function, map[string][]string{"x-amz-copy-source": {"mybucket/myobject"}}, true},
    51  		{case1Function, map[string][]string{"x-amz-copy-source": {"yourbucket/myobject"}}, false},
    52  		{case1Function, map[string][]string{}, false},
    53  		{case1Function, map[string][]string{"delimiter": {"/"}}, false},
    54  
    55  		{case2Function, map[string][]string{"x-amz-server-side-encryption": {"AES256"}}, true},
    56  		{case2Function, map[string][]string{}, false},
    57  		{case2Function, map[string][]string{"delimiter": {"/"}}, false},
    58  
    59  		{case3Function, map[string][]string{"x-amz-metadata-directive": {"REPLACE"}}, true},
    60  		{case3Function, map[string][]string{"x-amz-metadata-directive": {"COPY"}}, false},
    61  		{case3Function, map[string][]string{}, false},
    62  		{case3Function, map[string][]string{"delimiter": {"/"}}, false},
    63  
    64  		{case4Function, map[string][]string{"LocationConstraint": {"eu-west-1"}}, true},
    65  		{case4Function, map[string][]string{"LocationConstraint": {"us-east-1"}}, false},
    66  		{case4Function, map[string][]string{}, false},
    67  		{case4Function, map[string][]string{"delimiter": {"/"}}, false},
    68  	}
    69  
    70  	for i, testCase := range testCases {
    71  		result := testCase.function.evaluate(testCase.values)
    72  
    73  		if result != testCase.expectedResult {
    74  			t.Fatalf("case %v: expected: %v, got: %v\n", i+1, testCase.expectedResult, result)
    75  		}
    76  	}
    77  }
    78  
    79  func TestStringEqualsFuncKey(t *testing.T) {
    80  	case1Function, err := newStringEqualsFunc(S3XAmzCopySource, NewValueSet(NewStringValue("mybucket/myobject")))
    81  	if err != nil {
    82  		t.Fatalf("unexpected error. %v\n", err)
    83  	}
    84  
    85  	case2Function, err := newStringEqualsFunc(S3XAmzServerSideEncryption, NewValueSet(NewStringValue("AES256")))
    86  	if err != nil {
    87  		t.Fatalf("unexpected error. %v\n", err)
    88  	}
    89  
    90  	case3Function, err := newStringEqualsFunc(S3XAmzMetadataDirective, NewValueSet(NewStringValue("REPLACE")))
    91  	if err != nil {
    92  		t.Fatalf("unexpected error. %v\n", err)
    93  	}
    94  
    95  	case4Function, err := newStringEqualsFunc(S3LocationConstraint, NewValueSet(NewStringValue("eu-west-1")))
    96  	if err != nil {
    97  		t.Fatalf("unexpected error. %v\n", err)
    98  	}
    99  
   100  	testCases := []struct {
   101  		function       Function
   102  		expectedResult Key
   103  	}{
   104  		{case1Function, S3XAmzCopySource},
   105  		{case2Function, S3XAmzServerSideEncryption},
   106  		{case3Function, S3XAmzMetadataDirective},
   107  		{case4Function, S3LocationConstraint},
   108  	}
   109  
   110  	for i, testCase := range testCases {
   111  		result := testCase.function.key()
   112  
   113  		if result != testCase.expectedResult {
   114  			t.Fatalf("case %v: expected: %v, got: %v\n", i+1, testCase.expectedResult, result)
   115  		}
   116  	}
   117  }
   118  
   119  func TestStringEqualsFuncToMap(t *testing.T) {
   120  	case1Function, err := newStringEqualsFunc(S3XAmzCopySource, NewValueSet(NewStringValue("mybucket/myobject")))
   121  	if err != nil {
   122  		t.Fatalf("unexpected error. %v\n", err)
   123  	}
   124  
   125  	case1Result := map[Key]ValueSet{
   126  		S3XAmzCopySource: NewValueSet(NewStringValue("mybucket/myobject")),
   127  	}
   128  
   129  	case2Function, err := newStringEqualsFunc(S3XAmzCopySource,
   130  		NewValueSet(
   131  			NewStringValue("mybucket/myobject"),
   132  			NewStringValue("yourbucket/myobject"),
   133  		),
   134  	)
   135  	if err != nil {
   136  		t.Fatalf("unexpected error. %v\n", err)
   137  	}
   138  
   139  	case2Result := map[Key]ValueSet{
   140  		S3XAmzCopySource: NewValueSet(
   141  			NewStringValue("mybucket/myobject"),
   142  			NewStringValue("yourbucket/myobject"),
   143  		),
   144  	}
   145  
   146  	case3Function, err := newStringEqualsFunc(S3XAmzServerSideEncryption, NewValueSet(NewStringValue("AES256")))
   147  	if err != nil {
   148  		t.Fatalf("unexpected error. %v\n", err)
   149  	}
   150  
   151  	case3Result := map[Key]ValueSet{
   152  		S3XAmzServerSideEncryption: NewValueSet(NewStringValue("AES256")),
   153  	}
   154  
   155  	case4Function, err := newStringEqualsFunc(S3XAmzServerSideEncryption,
   156  		NewValueSet(
   157  			NewStringValue("AES256"),
   158  		),
   159  	)
   160  	if err != nil {
   161  		t.Fatalf("unexpected error. %v\n", err)
   162  	}
   163  
   164  	case4Result := map[Key]ValueSet{
   165  		S3XAmzServerSideEncryption: NewValueSet(
   166  			NewStringValue("AES256"),
   167  		),
   168  	}
   169  
   170  	case5Function, err := newStringEqualsFunc(S3XAmzMetadataDirective, NewValueSet(NewStringValue("REPLACE")))
   171  	if err != nil {
   172  		t.Fatalf("unexpected error. %v\n", err)
   173  	}
   174  
   175  	case5Result := map[Key]ValueSet{
   176  		S3XAmzMetadataDirective: NewValueSet(NewStringValue("REPLACE")),
   177  	}
   178  
   179  	case6Function, err := newStringEqualsFunc(S3XAmzMetadataDirective,
   180  		NewValueSet(
   181  			NewStringValue("REPLACE"),
   182  			NewStringValue("COPY"),
   183  		),
   184  	)
   185  	if err != nil {
   186  		t.Fatalf("unexpected error. %v\n", err)
   187  	}
   188  
   189  	case6Result := map[Key]ValueSet{
   190  		S3XAmzMetadataDirective: NewValueSet(
   191  			NewStringValue("REPLACE"),
   192  			NewStringValue("COPY"),
   193  		),
   194  	}
   195  
   196  	case7Function, err := newStringEqualsFunc(S3LocationConstraint, NewValueSet(NewStringValue("eu-west-1")))
   197  	if err != nil {
   198  		t.Fatalf("unexpected error. %v\n", err)
   199  	}
   200  
   201  	case7Result := map[Key]ValueSet{
   202  		S3LocationConstraint: NewValueSet(NewStringValue("eu-west-1")),
   203  	}
   204  
   205  	case8Function, err := newStringEqualsFunc(S3LocationConstraint,
   206  		NewValueSet(
   207  			NewStringValue("eu-west-1"),
   208  			NewStringValue("us-west-1"),
   209  		),
   210  	)
   211  	if err != nil {
   212  		t.Fatalf("unexpected error. %v\n", err)
   213  	}
   214  
   215  	case8Result := map[Key]ValueSet{
   216  		S3LocationConstraint: NewValueSet(
   217  			NewStringValue("eu-west-1"),
   218  			NewStringValue("us-west-1"),
   219  		),
   220  	}
   221  
   222  	testCases := []struct {
   223  		f              Function
   224  		expectedResult map[Key]ValueSet
   225  	}{
   226  		{case1Function, case1Result},
   227  		{case2Function, case2Result},
   228  		{case3Function, case3Result},
   229  		{case4Function, case4Result},
   230  		{case5Function, case5Result},
   231  		{case6Function, case6Result},
   232  		{case7Function, case7Result},
   233  		{case8Function, case8Result},
   234  		{&stringEqualsFunc{}, nil},
   235  	}
   236  
   237  	for i, testCase := range testCases {
   238  		result := testCase.f.toMap()
   239  
   240  		if !reflect.DeepEqual(result, testCase.expectedResult) {
   241  			t.Fatalf("case %v: result: expected: %v, got: %v\n", i+1, testCase.expectedResult, result)
   242  		}
   243  	}
   244  }
   245  
   246  func TestStringNotEqualsFuncEvaluate(t *testing.T) {
   247  	case1Function, err := newStringNotEqualsFunc(S3XAmzCopySource, NewValueSet(NewStringValue("mybucket/myobject")))
   248  	if err != nil {
   249  		t.Fatalf("unexpected error. %v\n", err)
   250  	}
   251  
   252  	case2Function, err := newStringNotEqualsFunc(S3XAmzServerSideEncryption, NewValueSet(NewStringValue("AES256")))
   253  	if err != nil {
   254  		t.Fatalf("unexpected error. %v\n", err)
   255  	}
   256  
   257  	case3Function, err := newStringNotEqualsFunc(S3XAmzMetadataDirective, NewValueSet(NewStringValue("REPLACE")))
   258  	if err != nil {
   259  		t.Fatalf("unexpected error. %v\n", err)
   260  	}
   261  
   262  	case4Function, err := newStringNotEqualsFunc(S3LocationConstraint, NewValueSet(NewStringValue("eu-west-1")))
   263  	if err != nil {
   264  		t.Fatalf("unexpected error. %v\n", err)
   265  	}
   266  
   267  	testCases := []struct {
   268  		function       Function
   269  		values         map[string][]string
   270  		expectedResult bool
   271  	}{
   272  		{case1Function, map[string][]string{"x-amz-copy-source": {"mybucket/myobject"}}, false},
   273  		{case1Function, map[string][]string{"x-amz-copy-source": {"yourbucket/myobject"}}, true},
   274  		{case1Function, map[string][]string{}, true},
   275  		{case1Function, map[string][]string{"delimiter": {"/"}}, true},
   276  
   277  		{case2Function, map[string][]string{"x-amz-server-side-encryption": {"AES256"}}, false},
   278  		{case2Function, map[string][]string{}, true},
   279  		{case2Function, map[string][]string{"delimiter": {"/"}}, true},
   280  
   281  		{case3Function, map[string][]string{"x-amz-metadata-directive": {"REPLACE"}}, false},
   282  		{case3Function, map[string][]string{"x-amz-metadata-directive": {"COPY"}}, true},
   283  		{case3Function, map[string][]string{}, true},
   284  		{case3Function, map[string][]string{"delimiter": {"/"}}, true},
   285  
   286  		{case4Function, map[string][]string{"LocationConstraint": {"eu-west-1"}}, false},
   287  		{case4Function, map[string][]string{"LocationConstraint": {"us-east-1"}}, true},
   288  		{case4Function, map[string][]string{}, true},
   289  		{case4Function, map[string][]string{"delimiter": {"/"}}, true},
   290  	}
   291  
   292  	for i, testCase := range testCases {
   293  		result := testCase.function.evaluate(testCase.values)
   294  
   295  		if result != testCase.expectedResult {
   296  			t.Fatalf("case %v: expected: %v, got: %v\n", i+1, testCase.expectedResult, result)
   297  		}
   298  	}
   299  }
   300  
   301  func TestStringNotEqualsFuncKey(t *testing.T) {
   302  	case1Function, err := newStringNotEqualsFunc(S3XAmzCopySource, NewValueSet(NewStringValue("mybucket/myobject")))
   303  	if err != nil {
   304  		t.Fatalf("unexpected error. %v\n", err)
   305  	}
   306  
   307  	case2Function, err := newStringNotEqualsFunc(S3XAmzServerSideEncryption, NewValueSet(NewStringValue("AES256")))
   308  	if err != nil {
   309  		t.Fatalf("unexpected error. %v\n", err)
   310  	}
   311  
   312  	case3Function, err := newStringNotEqualsFunc(S3XAmzMetadataDirective, NewValueSet(NewStringValue("REPLACE")))
   313  	if err != nil {
   314  		t.Fatalf("unexpected error. %v\n", err)
   315  	}
   316  
   317  	case4Function, err := newStringNotEqualsFunc(S3LocationConstraint, NewValueSet(NewStringValue("eu-west-1")))
   318  	if err != nil {
   319  		t.Fatalf("unexpected error. %v\n", err)
   320  	}
   321  
   322  	testCases := []struct {
   323  		function       Function
   324  		expectedResult Key
   325  	}{
   326  		{case1Function, S3XAmzCopySource},
   327  		{case2Function, S3XAmzServerSideEncryption},
   328  		{case3Function, S3XAmzMetadataDirective},
   329  		{case4Function, S3LocationConstraint},
   330  	}
   331  
   332  	for i, testCase := range testCases {
   333  		result := testCase.function.key()
   334  
   335  		if result != testCase.expectedResult {
   336  			t.Fatalf("case %v: expected: %v, got: %v\n", i+1, testCase.expectedResult, result)
   337  		}
   338  	}
   339  }
   340  
   341  func TestStringNotEqualsFuncToMap(t *testing.T) {
   342  	case1Function, err := newStringNotEqualsFunc(S3XAmzCopySource, NewValueSet(NewStringValue("mybucket/myobject")))
   343  	if err != nil {
   344  		t.Fatalf("unexpected error. %v\n", err)
   345  	}
   346  
   347  	case1Result := map[Key]ValueSet{
   348  		S3XAmzCopySource: NewValueSet(NewStringValue("mybucket/myobject")),
   349  	}
   350  
   351  	case2Function, err := newStringNotEqualsFunc(S3XAmzCopySource,
   352  		NewValueSet(
   353  			NewStringValue("mybucket/myobject"),
   354  			NewStringValue("yourbucket/myobject"),
   355  		),
   356  	)
   357  	if err != nil {
   358  		t.Fatalf("unexpected error. %v\n", err)
   359  	}
   360  
   361  	case2Result := map[Key]ValueSet{
   362  		S3XAmzCopySource: NewValueSet(
   363  			NewStringValue("mybucket/myobject"),
   364  			NewStringValue("yourbucket/myobject"),
   365  		),
   366  	}
   367  
   368  	case3Function, err := newStringNotEqualsFunc(S3XAmzServerSideEncryption, NewValueSet(NewStringValue("AES256")))
   369  	if err != nil {
   370  		t.Fatalf("unexpected error. %v\n", err)
   371  	}
   372  
   373  	case3Result := map[Key]ValueSet{
   374  		S3XAmzServerSideEncryption: NewValueSet(NewStringValue("AES256")),
   375  	}
   376  
   377  	case4Function, err := newStringNotEqualsFunc(S3XAmzServerSideEncryption,
   378  		NewValueSet(
   379  			NewStringValue("AES256"),
   380  		),
   381  	)
   382  	if err != nil {
   383  		t.Fatalf("unexpected error. %v\n", err)
   384  	}
   385  
   386  	case4Result := map[Key]ValueSet{
   387  		S3XAmzServerSideEncryption: NewValueSet(
   388  			NewStringValue("AES256"),
   389  		),
   390  	}
   391  
   392  	case5Function, err := newStringNotEqualsFunc(S3XAmzMetadataDirective, NewValueSet(NewStringValue("REPLACE")))
   393  	if err != nil {
   394  		t.Fatalf("unexpected error. %v\n", err)
   395  	}
   396  
   397  	case5Result := map[Key]ValueSet{
   398  		S3XAmzMetadataDirective: NewValueSet(NewStringValue("REPLACE")),
   399  	}
   400  
   401  	case6Function, err := newStringNotEqualsFunc(S3XAmzMetadataDirective,
   402  		NewValueSet(
   403  			NewStringValue("REPLACE"),
   404  			NewStringValue("COPY"),
   405  		),
   406  	)
   407  	if err != nil {
   408  		t.Fatalf("unexpected error. %v\n", err)
   409  	}
   410  
   411  	case6Result := map[Key]ValueSet{
   412  		S3XAmzMetadataDirective: NewValueSet(
   413  			NewStringValue("REPLACE"),
   414  			NewStringValue("COPY"),
   415  		),
   416  	}
   417  
   418  	case7Function, err := newStringNotEqualsFunc(S3LocationConstraint, NewValueSet(NewStringValue("eu-west-1")))
   419  	if err != nil {
   420  		t.Fatalf("unexpected error. %v\n", err)
   421  	}
   422  
   423  	case7Result := map[Key]ValueSet{
   424  		S3LocationConstraint: NewValueSet(NewStringValue("eu-west-1")),
   425  	}
   426  
   427  	case8Function, err := newStringNotEqualsFunc(S3LocationConstraint,
   428  		NewValueSet(
   429  			NewStringValue("eu-west-1"),
   430  			NewStringValue("us-west-1"),
   431  		),
   432  	)
   433  	if err != nil {
   434  		t.Fatalf("unexpected error. %v\n", err)
   435  	}
   436  
   437  	case8Result := map[Key]ValueSet{
   438  		S3LocationConstraint: NewValueSet(
   439  			NewStringValue("eu-west-1"),
   440  			NewStringValue("us-west-1"),
   441  		),
   442  	}
   443  
   444  	testCases := []struct {
   445  		f              Function
   446  		expectedResult map[Key]ValueSet
   447  	}{
   448  		{case1Function, case1Result},
   449  		{case2Function, case2Result},
   450  		{case3Function, case3Result},
   451  		{case4Function, case4Result},
   452  		{case5Function, case5Result},
   453  		{case6Function, case6Result},
   454  		{case7Function, case7Result},
   455  		{case8Function, case8Result},
   456  		{&stringNotEqualsFunc{}, nil},
   457  	}
   458  
   459  	for i, testCase := range testCases {
   460  		result := testCase.f.toMap()
   461  
   462  		if !reflect.DeepEqual(result, testCase.expectedResult) {
   463  			t.Fatalf("case %v: result: expected: %v, got: %v\n", i+1, testCase.expectedResult, result)
   464  		}
   465  	}
   466  }
   467  
   468  func TestNewStringEqualsFunc(t *testing.T) {
   469  	case1Function, err := newStringEqualsFunc(S3XAmzCopySource, NewValueSet(NewStringValue("mybucket/myobject")))
   470  	if err != nil {
   471  		t.Fatalf("unexpected error. %v\n", err)
   472  	}
   473  
   474  	case2Function, err := newStringEqualsFunc(S3XAmzCopySource,
   475  		NewValueSet(
   476  			NewStringValue("mybucket/myobject"),
   477  			NewStringValue("yourbucket/myobject"),
   478  		),
   479  	)
   480  	if err != nil {
   481  		t.Fatalf("unexpected error. %v\n", err)
   482  	}
   483  
   484  	case3Function, err := newStringEqualsFunc(S3XAmzServerSideEncryption, NewValueSet(NewStringValue("AES256")))
   485  	if err != nil {
   486  		t.Fatalf("unexpected error. %v\n", err)
   487  	}
   488  
   489  	case4Function, err := newStringEqualsFunc(S3XAmzServerSideEncryption,
   490  		NewValueSet(
   491  			NewStringValue("AES256"),
   492  		),
   493  	)
   494  	if err != nil {
   495  		t.Fatalf("unexpected error. %v\n", err)
   496  	}
   497  
   498  	case5Function, err := newStringEqualsFunc(S3XAmzMetadataDirective, NewValueSet(NewStringValue("REPLACE")))
   499  	if err != nil {
   500  		t.Fatalf("unexpected error. %v\n", err)
   501  	}
   502  
   503  	case6Function, err := newStringEqualsFunc(S3XAmzMetadataDirective,
   504  		NewValueSet(
   505  			NewStringValue("REPLACE"),
   506  			NewStringValue("COPY"),
   507  		),
   508  	)
   509  	if err != nil {
   510  		t.Fatalf("unexpected error. %v\n", err)
   511  	}
   512  
   513  	case7Function, err := newStringEqualsFunc(S3LocationConstraint, NewValueSet(NewStringValue("eu-west-1")))
   514  	if err != nil {
   515  		t.Fatalf("unexpected error. %v\n", err)
   516  	}
   517  
   518  	case8Function, err := newStringEqualsFunc(S3LocationConstraint,
   519  		NewValueSet(
   520  			NewStringValue("eu-west-1"),
   521  			NewStringValue("us-west-1"),
   522  		),
   523  	)
   524  	if err != nil {
   525  		t.Fatalf("unexpected error. %v\n", err)
   526  	}
   527  
   528  	testCases := []struct {
   529  		key            Key
   530  		values         ValueSet
   531  		expectedResult Function
   532  		expectErr      bool
   533  	}{
   534  		{S3XAmzCopySource, NewValueSet(NewStringValue("mybucket/myobject")), case1Function, false},
   535  		{S3XAmzCopySource,
   536  			NewValueSet(
   537  				NewStringValue("mybucket/myobject"),
   538  				NewStringValue("yourbucket/myobject"),
   539  			), case2Function, false},
   540  
   541  		{S3XAmzServerSideEncryption, NewValueSet(NewStringValue("AES256")), case3Function, false},
   542  		{S3XAmzServerSideEncryption,
   543  			NewValueSet(
   544  				NewStringValue("AES256"),
   545  			), case4Function, false},
   546  
   547  		{S3XAmzMetadataDirective, NewValueSet(NewStringValue("REPLACE")), case5Function, false},
   548  		{S3XAmzMetadataDirective,
   549  			NewValueSet(
   550  				NewStringValue("REPLACE"),
   551  				NewStringValue("COPY"),
   552  			), case6Function, false},
   553  
   554  		{S3LocationConstraint, NewValueSet(NewStringValue("eu-west-1")), case7Function, false},
   555  		{S3LocationConstraint,
   556  			NewValueSet(
   557  				NewStringValue("eu-west-1"),
   558  				NewStringValue("us-west-1"),
   559  			), case8Function, false},
   560  
   561  		// Unsupported value error.
   562  		{S3XAmzCopySource, NewValueSet(NewStringValue("mybucket/myobject"), NewIntValue(7)), nil, true},
   563  		{S3XAmzServerSideEncryption, NewValueSet(NewStringValue("AES256"), NewIntValue(7)), nil, true},
   564  		{S3XAmzMetadataDirective, NewValueSet(NewStringValue("REPLACE"), NewIntValue(7)), nil, true},
   565  		{S3LocationConstraint, NewValueSet(NewStringValue("eu-west-1"), NewIntValue(7)), nil, true},
   566  
   567  		// Invalid value error.
   568  		{S3XAmzCopySource, NewValueSet(NewStringValue("mybucket")), nil, true},
   569  		{S3XAmzServerSideEncryption, NewValueSet(NewStringValue("SSE-C")), nil, true},
   570  		{S3XAmzMetadataDirective, NewValueSet(NewStringValue("DUPLICATE")), nil, true},
   571  	}
   572  
   573  	for i, testCase := range testCases {
   574  		result, err := newStringEqualsFunc(testCase.key, testCase.values)
   575  		expectErr := (err != nil)
   576  
   577  		if expectErr != testCase.expectErr {
   578  			t.Fatalf("case %v: error: expected: %v, got: %v\n", i+1, testCase.expectErr, expectErr)
   579  		}
   580  
   581  		if !testCase.expectErr {
   582  			if !reflect.DeepEqual(result, testCase.expectedResult) {
   583  				t.Fatalf("case %v: result: expected: %v, got: %v\n", i+1, testCase.expectedResult, result)
   584  			}
   585  		}
   586  	}
   587  }
   588  
   589  func TestNewStringNotEqualsFunc(t *testing.T) {
   590  	case1Function, err := newStringNotEqualsFunc(S3XAmzCopySource, NewValueSet(NewStringValue("mybucket/myobject")))
   591  	if err != nil {
   592  		t.Fatalf("unexpected error. %v\n", err)
   593  	}
   594  
   595  	case2Function, err := newStringNotEqualsFunc(S3XAmzCopySource,
   596  		NewValueSet(
   597  			NewStringValue("mybucket/myobject"),
   598  			NewStringValue("yourbucket/myobject"),
   599  		),
   600  	)
   601  	if err != nil {
   602  		t.Fatalf("unexpected error. %v\n", err)
   603  	}
   604  
   605  	case3Function, err := newStringNotEqualsFunc(S3XAmzServerSideEncryption, NewValueSet(NewStringValue("AES256")))
   606  	if err != nil {
   607  		t.Fatalf("unexpected error. %v\n", err)
   608  	}
   609  
   610  	case4Function, err := newStringNotEqualsFunc(S3XAmzServerSideEncryption,
   611  		NewValueSet(
   612  			NewStringValue("AES256"),
   613  		),
   614  	)
   615  	if err != nil {
   616  		t.Fatalf("unexpected error. %v\n", err)
   617  	}
   618  
   619  	case5Function, err := newStringNotEqualsFunc(S3XAmzMetadataDirective, NewValueSet(NewStringValue("REPLACE")))
   620  	if err != nil {
   621  		t.Fatalf("unexpected error. %v\n", err)
   622  	}
   623  
   624  	case6Function, err := newStringNotEqualsFunc(S3XAmzMetadataDirective,
   625  		NewValueSet(
   626  			NewStringValue("REPLACE"),
   627  			NewStringValue("COPY"),
   628  		),
   629  	)
   630  	if err != nil {
   631  		t.Fatalf("unexpected error. %v\n", err)
   632  	}
   633  
   634  	case7Function, err := newStringNotEqualsFunc(S3LocationConstraint, NewValueSet(NewStringValue("eu-west-1")))
   635  	if err != nil {
   636  		t.Fatalf("unexpected error. %v\n", err)
   637  	}
   638  
   639  	case8Function, err := newStringNotEqualsFunc(S3LocationConstraint,
   640  		NewValueSet(
   641  			NewStringValue("eu-west-1"),
   642  			NewStringValue("us-west-1"),
   643  		),
   644  	)
   645  	if err != nil {
   646  		t.Fatalf("unexpected error. %v\n", err)
   647  	}
   648  
   649  	testCases := []struct {
   650  		key            Key
   651  		values         ValueSet
   652  		expectedResult Function
   653  		expectErr      bool
   654  	}{
   655  		{S3XAmzCopySource, NewValueSet(NewStringValue("mybucket/myobject")), case1Function, false},
   656  		{S3XAmzCopySource,
   657  			NewValueSet(
   658  				NewStringValue("mybucket/myobject"),
   659  				NewStringValue("yourbucket/myobject"),
   660  			), case2Function, false},
   661  
   662  		{S3XAmzServerSideEncryption, NewValueSet(NewStringValue("AES256")), case3Function, false},
   663  		{S3XAmzServerSideEncryption,
   664  			NewValueSet(
   665  				NewStringValue("AES256"),
   666  			), case4Function, false},
   667  
   668  		{S3XAmzMetadataDirective, NewValueSet(NewStringValue("REPLACE")), case5Function, false},
   669  		{S3XAmzMetadataDirective,
   670  			NewValueSet(
   671  				NewStringValue("REPLACE"),
   672  				NewStringValue("COPY"),
   673  			), case6Function, false},
   674  
   675  		{S3LocationConstraint, NewValueSet(NewStringValue("eu-west-1")), case7Function, false},
   676  		{S3LocationConstraint,
   677  			NewValueSet(
   678  				NewStringValue("eu-west-1"),
   679  				NewStringValue("us-west-1"),
   680  			), case8Function, false},
   681  
   682  		// Unsupported value error.
   683  		{S3XAmzCopySource, NewValueSet(NewStringValue("mybucket/myobject"), NewIntValue(7)), nil, true},
   684  		{S3XAmzServerSideEncryption, NewValueSet(NewStringValue("AES256"), NewIntValue(7)), nil, true},
   685  		{S3XAmzMetadataDirective, NewValueSet(NewStringValue("REPLACE"), NewIntValue(7)), nil, true},
   686  		{S3LocationConstraint, NewValueSet(NewStringValue("eu-west-1"), NewIntValue(7)), nil, true},
   687  
   688  		// Invalid value error.
   689  		{S3XAmzCopySource, NewValueSet(NewStringValue("mybucket")), nil, true},
   690  		{S3XAmzServerSideEncryption, NewValueSet(NewStringValue("SSE-C")), nil, true},
   691  		{S3XAmzMetadataDirective, NewValueSet(NewStringValue("DUPLICATE")), nil, true},
   692  	}
   693  
   694  	for i, testCase := range testCases {
   695  		result, err := newStringNotEqualsFunc(testCase.key, testCase.values)
   696  		expectErr := (err != nil)
   697  
   698  		if expectErr != testCase.expectErr {
   699  			t.Fatalf("case %v: error: expected: %v, got: %v\n", i+1, testCase.expectErr, expectErr)
   700  		}
   701  
   702  		if !testCase.expectErr {
   703  			if !reflect.DeepEqual(result, testCase.expectedResult) {
   704  				t.Fatalf("case %v: result: expected: %v, got: %v\n", i+1, testCase.expectedResult, result)
   705  			}
   706  		}
   707  	}
   708  }