...

Source file src/sigs.k8s.io/structured-merge-diff/v4/merge/leaf_test.go

Documentation: sigs.k8s.io/structured-merge-diff/v4/merge

     1  /*
     2  Copyright 2018 The Kubernetes Authors.
     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 merge_test
    18  
    19  import (
    20  	"testing"
    21  
    22  	"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
    23  	. "sigs.k8s.io/structured-merge-diff/v4/internal/fixture"
    24  	"sigs.k8s.io/structured-merge-diff/v4/merge"
    25  	"sigs.k8s.io/structured-merge-diff/v4/typed"
    26  )
    27  
    28  var leafFieldsParser = func() Parser {
    29  	parser, err := typed.NewParser(`types:
    30  - name: leafFields
    31    map:
    32      fields:
    33      - name: numeric
    34        type:
    35          scalar: numeric
    36      - name: string
    37        type:
    38          scalar: string
    39      - name: bool
    40        type:
    41          scalar: boolean`)
    42  	if err != nil {
    43  		panic(err)
    44  	}
    45  	return SameVersionParser{T: parser.Type("leafFields")}
    46  }()
    47  
    48  func TestUpdateLeaf(t *testing.T) {
    49  	tests := map[string]TestCase{
    50  		"apply_twice": {
    51  			Ops: []Operation{
    52  				Apply{
    53  					Manager: "default",
    54  					Object: `
    55  						numeric: 1
    56  						string: "string"
    57  					`,
    58  					APIVersion: "v1",
    59  				},
    60  				Apply{
    61  					Manager: "default",
    62  					Object: `
    63  						numeric: 2
    64  						string: "string"
    65  						bool: false
    66  					`,
    67  					APIVersion: "v1",
    68  				},
    69  			},
    70  			Object: `
    71  				numeric: 2
    72  				string: "string"
    73  				bool: false
    74  			`,
    75  			APIVersion: "v1",
    76  			Managed: fieldpath.ManagedFields{
    77  				"default": fieldpath.NewVersionedSet(
    78  					_NS(
    79  						_P("numeric"), _P("string"), _P("bool"),
    80  					),
    81  					"v1",
    82  					false,
    83  				),
    84  			},
    85  		},
    86  		"apply_twice_different_versions": {
    87  			Ops: []Operation{
    88  				Apply{
    89  					Manager: "default",
    90  					Object: `
    91  						numeric: 1
    92  						string: "string"
    93  					`,
    94  					APIVersion: "v1",
    95  				},
    96  				Apply{
    97  					Manager: "default",
    98  					Object: `
    99  						numeric: 2
   100  						string: "string"
   101  						bool: false
   102  					`,
   103  					APIVersion: "v2",
   104  				},
   105  			},
   106  			Object: `
   107  				numeric: 2
   108  				string: "string"
   109  				bool: false
   110  			`,
   111  			APIVersion: "v1",
   112  			Managed: fieldpath.ManagedFields{
   113  				"default": fieldpath.NewVersionedSet(
   114  					_NS(
   115  						_P("numeric"), _P("string"), _P("bool"),
   116  					),
   117  					"v2",
   118  					false,
   119  				),
   120  			},
   121  		},
   122  		"apply_update_apply_no_conflict": {
   123  			Ops: []Operation{
   124  				Apply{
   125  					Manager:    "default",
   126  					APIVersion: "v1",
   127  					Object: `
   128  						numeric: 1
   129  						string: "string"
   130  					`,
   131  				},
   132  				Update{
   133  					Manager:    "controller",
   134  					APIVersion: "v1",
   135  					Object: `
   136  						numeric: 1
   137  						string: "string"
   138  						bool: true
   139  					`,
   140  				},
   141  				Apply{
   142  					Manager:    "default",
   143  					APIVersion: "v1",
   144  					Object: `
   145  						numeric: 2
   146  						string: "string"
   147  					`,
   148  				},
   149  			},
   150  			Object: `
   151  				numeric: 2
   152  				string: "string"
   153  				bool: true
   154  			`,
   155  			APIVersion: "v1",
   156  			Managed: fieldpath.ManagedFields{
   157  				"default": fieldpath.NewVersionedSet(
   158  					_NS(
   159  						_P("numeric"), _P("string"),
   160  					),
   161  					"v1",
   162  					false,
   163  				),
   164  				"controller": fieldpath.NewVersionedSet(
   165  					_NS(
   166  						_P("bool"),
   167  					),
   168  					"v1",
   169  					false,
   170  				),
   171  			},
   172  		},
   173  		"apply_update_apply_no_conflict_different_version": {
   174  			Ops: []Operation{
   175  				Apply{
   176  					Manager:    "default",
   177  					APIVersion: "v1",
   178  					Object: `
   179  						numeric: 1
   180  						string: "string"
   181  					`,
   182  				},
   183  				Update{
   184  					Manager:    "controller",
   185  					APIVersion: "v2",
   186  					Object: `
   187  						numeric: 1
   188  						string: "string"
   189  						bool: true
   190  					`,
   191  				},
   192  				Apply{
   193  					Manager:    "default",
   194  					APIVersion: "v1",
   195  					Object: `
   196  						numeric: 2
   197  						string: "string"
   198  					`,
   199  				},
   200  			},
   201  			Object: `
   202  				numeric: 2
   203  				string: "string"
   204  				bool: true
   205  			`,
   206  			APIVersion: "v1",
   207  			Managed: fieldpath.ManagedFields{
   208  				"default": fieldpath.NewVersionedSet(
   209  					_NS(
   210  						_P("numeric"), _P("string"),
   211  					),
   212  					"v1",
   213  					false,
   214  				),
   215  				"controller": fieldpath.NewVersionedSet(
   216  					_NS(
   217  						_P("bool"),
   218  					),
   219  					"v2",
   220  					false,
   221  				),
   222  			},
   223  		},
   224  		"apply_update_apply_with_conflict": {
   225  			Ops: []Operation{
   226  				Apply{
   227  					Manager:    "default",
   228  					APIVersion: "v1",
   229  					Object: `
   230  						numeric: 1
   231  						string: "string"
   232  					`,
   233  				},
   234  				Update{
   235  					Manager:    "controller",
   236  					APIVersion: "v1",
   237  					Object: `
   238  						numeric: 1
   239  						string: "controller string"
   240  						bool: true
   241  					`,
   242  				},
   243  				Apply{
   244  					Manager:    "default",
   245  					APIVersion: "v1",
   246  					Object: `
   247  						numeric: 2
   248  						string: "user string"
   249  					`,
   250  					Conflicts: merge.Conflicts{
   251  						merge.Conflict{Manager: "controller", Path: _P("string")},
   252  					},
   253  				},
   254  				ForceApply{
   255  					Manager:    "default",
   256  					APIVersion: "v1",
   257  					Object: `
   258  						numeric: 2
   259  						string: "user string"
   260  					`,
   261  				},
   262  			},
   263  			Object: `
   264  				numeric: 2
   265  				string: "user string"
   266  				bool: true
   267  			`,
   268  			APIVersion: "v1",
   269  			Managed: fieldpath.ManagedFields{
   270  				"default": fieldpath.NewVersionedSet(
   271  					_NS(
   272  						_P("numeric"), _P("string"),
   273  					),
   274  					"v1",
   275  					false,
   276  				),
   277  				"controller": fieldpath.NewVersionedSet(
   278  					_NS(
   279  						_P("bool"),
   280  					),
   281  					"v1",
   282  					false,
   283  				),
   284  			},
   285  		},
   286  		"apply_update_apply_with_conflict_across_version": {
   287  			Ops: []Operation{
   288  				Apply{
   289  					Manager:    "default",
   290  					APIVersion: "v1",
   291  					Object: `
   292  						numeric: 1
   293  						string: "string"
   294  					`,
   295  				},
   296  				Update{
   297  					Manager:    "controller",
   298  					APIVersion: "v2",
   299  					Object: `
   300  						numeric: 1
   301  						string: "controller string"
   302  						bool: true
   303  					`,
   304  				},
   305  				Apply{
   306  					Manager:    "default",
   307  					APIVersion: "v1",
   308  					Object: `
   309  						numeric: 2
   310  						string: "user string"
   311  					`,
   312  					Conflicts: merge.Conflicts{
   313  						merge.Conflict{Manager: "controller", Path: _P("string")},
   314  					},
   315  				},
   316  				ForceApply{
   317  					Manager:    "default",
   318  					APIVersion: "v1",
   319  					Object: `
   320  						numeric: 2
   321  						string: "user string"
   322  					`,
   323  				},
   324  			},
   325  			Object: `
   326  				numeric: 2
   327  				string: "user string"
   328  				bool: true
   329  			`,
   330  			APIVersion: "v1",
   331  			Managed: fieldpath.ManagedFields{
   332  				"default": fieldpath.NewVersionedSet(
   333  					_NS(
   334  						_P("numeric"), _P("string"),
   335  					),
   336  					"v1",
   337  					false,
   338  				),
   339  				"controller": fieldpath.NewVersionedSet(
   340  					_NS(
   341  						_P("bool"),
   342  					),
   343  					"v2",
   344  					false,
   345  				),
   346  			},
   347  		},
   348  		"apply_twice_remove": {
   349  			Ops: []Operation{
   350  				Apply{
   351  					Manager:    "default",
   352  					APIVersion: "v1",
   353  					Object: `
   354  						numeric: 1
   355  						string: "string"
   356  						bool: false
   357  					`,
   358  				},
   359  				Apply{
   360  					Manager:    "default",
   361  					APIVersion: "v1",
   362  					Object: `
   363  						string: "new string"
   364  					`,
   365  				},
   366  			},
   367  			Object: `
   368  				string: "new string"
   369  			`,
   370  			APIVersion: "v1",
   371  			Managed: fieldpath.ManagedFields{
   372  				"default": fieldpath.NewVersionedSet(
   373  					_NS(
   374  						_P("string"),
   375  					),
   376  					"v1",
   377  					false,
   378  				),
   379  			},
   380  		},
   381  		"update_apply_omits": {
   382  			Ops: []Operation{
   383  				Apply{
   384  					Manager:    "default",
   385  					APIVersion: "v1",
   386  					Object: `
   387  						numeric: 2
   388  					`,
   389  				},
   390  				Update{
   391  					Manager:    "controller",
   392  					APIVersion: "v1",
   393  					Object: `
   394  						numeric: 1
   395  					`,
   396  				},
   397  				Apply{
   398  					Manager:    "default",
   399  					APIVersion: "v1",
   400  					Object:     ``,
   401  				},
   402  			},
   403  			Object: `
   404  						numeric: 1
   405  			`,
   406  			APIVersion: "v1",
   407  			Managed: fieldpath.ManagedFields{
   408  				"controller": fieldpath.NewVersionedSet(
   409  					_NS(
   410  						_P("numeric"),
   411  					),
   412  					"v1",
   413  					false,
   414  				),
   415  			},
   416  		},
   417  		"apply_twice_remove_different_version": {
   418  			Ops: []Operation{
   419  				Apply{
   420  					Manager:    "default",
   421  					APIVersion: "v1",
   422  					Object: `
   423  						numeric: 1
   424  						string: "string"
   425  						bool: false
   426  					`,
   427  				},
   428  				Apply{
   429  					Manager:    "default",
   430  					APIVersion: "v2",
   431  					Object: `
   432  						string: "new string"
   433  					`,
   434  				},
   435  			},
   436  			Object: `
   437  				string: "new string"
   438  			`,
   439  			APIVersion: "v1",
   440  			Managed: fieldpath.ManagedFields{
   441  				"default": fieldpath.NewVersionedSet(
   442  					_NS(
   443  						_P("string"),
   444  					),
   445  					"v2",
   446  					false,
   447  				),
   448  			},
   449  		},
   450  		"update_remove_empty_set": {
   451  			Ops: []Operation{
   452  				Apply{
   453  					Manager:    "default",
   454  					APIVersion: "v1",
   455  					Object: `
   456  						string: "string"
   457  					`,
   458  				},
   459  				Update{
   460  					Manager:    "controller",
   461  					APIVersion: "v1",
   462  					Object: `
   463  						string: "new string"
   464  					`,
   465  				},
   466  			},
   467  			Object: `
   468  				string: "new string"
   469  			`,
   470  			APIVersion: "v1",
   471  			Managed: fieldpath.ManagedFields{
   472  				"controller": fieldpath.NewVersionedSet(
   473  					_NS(
   474  						_P("string"),
   475  					),
   476  					"v1",
   477  					false,
   478  				),
   479  			},
   480  		},
   481  		"apply_remove_empty_set": {
   482  			Ops: []Operation{
   483  				Apply{
   484  					Manager:    "default",
   485  					APIVersion: "v1",
   486  					Object: `
   487  						string: "string"
   488  					`,
   489  				},
   490  				Apply{
   491  					Manager:    "default",
   492  					APIVersion: "v1",
   493  					Object:     "",
   494  				},
   495  			},
   496  			Object: `
   497  			`,
   498  			APIVersion: "v1",
   499  			Managed:    fieldpath.ManagedFields{},
   500  		},
   501  	}
   502  
   503  	for name, test := range tests {
   504  		t.Run(name, func(t *testing.T) {
   505  			if err := test.Test(leafFieldsParser); err != nil {
   506  				t.Fatal(err)
   507  			}
   508  		})
   509  	}
   510  }
   511  
   512  func BenchmarkLeafConflictAcrossVersion(b *testing.B) {
   513  	test := TestCase{
   514  		Ops: []Operation{
   515  			Apply{
   516  				Manager:    "default",
   517  				APIVersion: "v1",
   518  				Object: `
   519  					numeric: 1
   520  					string: "string"
   521  				`,
   522  			},
   523  			Update{
   524  				Manager:    "controller",
   525  				APIVersion: "v2",
   526  				Object: `
   527  					numeric: 1
   528  					string: "controller string"
   529  					bool: true
   530  				`,
   531  			},
   532  			Apply{
   533  				Manager:    "default",
   534  				APIVersion: "v1",
   535  				Object: `
   536  					numeric: 2
   537  					string: "user string"
   538  				`,
   539  				Conflicts: merge.Conflicts{
   540  					merge.Conflict{Manager: "controller", Path: _P("string")},
   541  				},
   542  			},
   543  			ForceApply{
   544  				Manager:    "default",
   545  				APIVersion: "v1",
   546  				Object: `
   547  					numeric: 2
   548  					string: "user string"
   549  				`,
   550  			},
   551  		},
   552  		Object: `
   553  			numeric: 2
   554  			string: "user string"
   555  			bool: true
   556  		`,
   557  		APIVersion: "v1",
   558  		Managed: fieldpath.ManagedFields{
   559  			"default": fieldpath.NewVersionedSet(
   560  				_NS(
   561  					_P("numeric"), _P("string"),
   562  				),
   563  				"v1",
   564  				false,
   565  			),
   566  			"controller": fieldpath.NewVersionedSet(
   567  				_NS(
   568  					_P("bool"),
   569  				),
   570  				"v2",
   571  				false,
   572  			),
   573  		},
   574  	}
   575  
   576  	// Make sure this passes...
   577  	if err := test.Test(leafFieldsParser); err != nil {
   578  		b.Fatal(err)
   579  	}
   580  
   581  	test.PreprocessOperations(leafFieldsParser)
   582  
   583  	b.ReportAllocs()
   584  	b.ResetTimer()
   585  	for n := 0; n < b.N; n++ {
   586  		if err := test.Bench(leafFieldsParser); err != nil {
   587  			b.Fatal(err)
   588  		}
   589  	}
   590  }
   591  

View as plain text