...

Source file src/sigs.k8s.io/kustomize/api/filters/nameref/nameref_test.go

Documentation: sigs.k8s.io/kustomize/api/filters/nameref

     1  // Copyright 2022 The Kubernetes Authors.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package nameref
     5  
     6  import (
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"sigs.k8s.io/kustomize/api/provider"
    12  	"sigs.k8s.io/kustomize/api/resmap"
    13  	filtertest_test "sigs.k8s.io/kustomize/api/testutils/filtertest"
    14  	"sigs.k8s.io/kustomize/api/types"
    15  	"sigs.k8s.io/kustomize/kyaml/resid"
    16  )
    17  
    18  func TestNamerefFilter(t *testing.T) {
    19  	testCases := map[string]struct {
    20  		referrerOriginal string
    21  		candidates       string
    22  		referrerFinal    string
    23  		filter           Filter
    24  		originalNames    []string
    25  	}{
    26  		"simple scalar": {
    27  			referrerOriginal: `
    28  apiVersion: apps/v1
    29  kind: Deployment
    30  metadata:
    31    name: dep
    32  ref:
    33    name: oldName
    34  `,
    35  			candidates: `
    36  apiVersion: apps/v1
    37  kind: Secret
    38  metadata:
    39    name: newName
    40  ---
    41  apiVersion: apps/v1
    42  kind: NotSecret
    43  metadata:
    44    name: newName2
    45  `,
    46  			originalNames: []string{"oldName", "newName2"},
    47  			referrerFinal: `
    48  apiVersion: apps/v1
    49  kind: Deployment
    50  metadata:
    51    name: dep
    52  ref:
    53    name: newName
    54  `,
    55  			filter: Filter{
    56  				NameFieldToUpdate: types.FieldSpec{Path: "ref/name"},
    57  				ReferralTarget: resid.Gvk{
    58  					Group:   "apps",
    59  					Version: "v1",
    60  					Kind:    "Secret",
    61  				},
    62  			},
    63  		},
    64  		"sequence": {
    65  			referrerOriginal: `
    66  apiVersion: apps/v1
    67  kind: Deployment
    68  metadata:
    69    name: dep
    70  seq:
    71  - oldName1
    72  - oldName2
    73  `,
    74  			candidates: `
    75  apiVersion: apps/v1
    76  kind: Secret
    77  metadata:
    78    name: newName
    79  ---
    80  apiVersion: apps/v1
    81  kind: NotSecret
    82  metadata:
    83    name: newName2
    84  `,
    85  			originalNames: []string{"oldName1", "newName2"},
    86  			referrerFinal: `
    87  apiVersion: apps/v1
    88  kind: Deployment
    89  metadata:
    90    name: dep
    91  seq:
    92  - newName
    93  - oldName2
    94  `,
    95  			filter: Filter{
    96  				NameFieldToUpdate: types.FieldSpec{Path: "seq"},
    97  				ReferralTarget: resid.Gvk{
    98  					Group:   "apps",
    99  					Version: "v1",
   100  					Kind:    "Secret",
   101  				},
   102  			},
   103  		},
   104  		"mapping": {
   105  			referrerOriginal: `
   106  apiVersion: apps/v1
   107  kind: Deployment
   108  metadata:
   109    name: dep
   110  map:
   111    name: oldName
   112  `,
   113  			candidates: `
   114  apiVersion: apps/v1
   115  kind: Secret
   116  metadata:
   117    name: newName
   118  ---
   119  apiVersion: apps/v1
   120  kind: NotSecret
   121  metadata:
   122    name: newName2
   123  `,
   124  			originalNames: []string{"oldName", "newName2"},
   125  			referrerFinal: `
   126  apiVersion: apps/v1
   127  kind: Deployment
   128  metadata:
   129    name: dep
   130  map:
   131    name: newName
   132  `,
   133  			filter: Filter{
   134  				NameFieldToUpdate: types.FieldSpec{Path: "map"},
   135  				ReferralTarget: resid.Gvk{
   136  					Group:   "apps",
   137  					Version: "v1",
   138  					Kind:    "Secret",
   139  				},
   140  			},
   141  		},
   142  		"mapping with namespace": {
   143  			referrerOriginal: `
   144  apiVersion: apps/v1
   145  kind: Deployment
   146  metadata:
   147    name: dep
   148    namespace: someNs
   149  map:
   150    name: oldName
   151    namespace: someNs
   152  `,
   153  			candidates: `
   154  apiVersion: apps/v1
   155  kind: Secret
   156  metadata:
   157    name: newName
   158    namespace: someNs
   159  ---
   160  apiVersion: apps/v1
   161  kind: NotSecret
   162  metadata:
   163    name: newName2
   164  ---
   165  apiVersion: apps/v1
   166  kind: Secret
   167  metadata:
   168    name: thirdName
   169  `,
   170  			originalNames: []string{"oldName", "oldName", "oldName"},
   171  			referrerFinal: `
   172  apiVersion: apps/v1
   173  kind: Deployment
   174  metadata:
   175    name: dep
   176    namespace: someNs
   177  map:
   178    name: newName
   179    namespace: someNs
   180  `,
   181  			filter: Filter{
   182  				NameFieldToUpdate: types.FieldSpec{Path: "map"},
   183  				ReferralTarget: resid.Gvk{
   184  					Group:   "apps",
   185  					Version: "v1",
   186  					Kind:    "Secret",
   187  				},
   188  			},
   189  		},
   190  		"null value": {
   191  			referrerOriginal: `
   192  apiVersion: apps/v1
   193  kind: Deployment
   194  metadata:
   195    name: dep
   196  map:
   197    name: null
   198  `,
   199  			candidates: `
   200  apiVersion: apps/v1
   201  kind: Secret
   202  metadata:
   203    name: newName
   204  ---
   205  apiVersion: apps/v1
   206  kind: NotSecret
   207  metadata:
   208    name: newName2
   209  `,
   210  			originalNames: []string{"oldName", "newName2"},
   211  			referrerFinal: `
   212  apiVersion: apps/v1
   213  kind: Deployment
   214  metadata:
   215    name: dep
   216  map:
   217    name: null
   218  `,
   219  			filter: Filter{
   220  				NameFieldToUpdate: types.FieldSpec{Path: "map"},
   221  				ReferralTarget: resid.Gvk{
   222  					Group:   "apps",
   223  					Version: "v1",
   224  					Kind:    "Secret",
   225  				},
   226  			},
   227  		},
   228  	}
   229  
   230  	for tn, tc := range testCases {
   231  		t.Run(tn, func(t *testing.T) {
   232  			factory := provider.NewDefaultDepProvider().GetResourceFactory()
   233  			referrer, err := factory.FromBytes([]byte(tc.referrerOriginal))
   234  			if err != nil {
   235  				t.Fatal(err)
   236  			}
   237  			tc.filter.Referrer = referrer
   238  
   239  			resMapFactory := resmap.NewFactory(factory)
   240  			candidatesRes, err := factory.SliceFromBytesWithNames(
   241  				tc.originalNames, []byte(tc.candidates))
   242  			if err != nil {
   243  				t.Fatal(err)
   244  			}
   245  
   246  			candidates := resMapFactory.FromResourceSlice(candidatesRes)
   247  			tc.filter.ReferralCandidates = candidates
   248  
   249  			result := filtertest_test.RunFilter(t, tc.referrerOriginal, tc.filter)
   250  			if !assert.Equal(t,
   251  				strings.TrimSpace(tc.referrerFinal),
   252  				strings.TrimSpace(result)) {
   253  				t.FailNow()
   254  			}
   255  		})
   256  	}
   257  }
   258  
   259  func TestNamerefFilterUnhappy(t *testing.T) {
   260  	testCases := map[string]struct {
   261  		referrerOriginal string
   262  		candidates       string
   263  		referrerFinal    string
   264  		filter           Filter
   265  		originalNames    []string
   266  	}{
   267  		"multiple match": {
   268  			referrerOriginal: `
   269  apiVersion: apps/v1
   270  kind: Deployment
   271  metadata:
   272    name: dep
   273  ref:
   274    name: oldName
   275  `,
   276  			candidates: `
   277  apiVersion: apps/v1
   278  kind: Secret
   279  metadata:
   280    name: newName
   281  ---
   282  apiVersion: apps/v1
   283  kind: Secret
   284  metadata:
   285    name: newName2
   286  `,
   287  			originalNames: []string{"oldName", "oldName"},
   288  			referrerFinal: "",
   289  			filter: Filter{
   290  				NameFieldToUpdate: types.FieldSpec{Path: "ref/name"},
   291  				ReferralTarget: resid.Gvk{
   292  					Group:   "apps",
   293  					Version: "v1",
   294  					Kind:    "Secret",
   295  				},
   296  			},
   297  		},
   298  		"no name": {
   299  			referrerOriginal: `
   300  apiVersion: apps/v1
   301  kind: Deployment
   302  metadata:
   303    name: dep
   304  ref:
   305    notName: oldName
   306  `,
   307  			candidates: `
   308  apiVersion: apps/v1
   309  kind: Secret
   310  metadata:
   311    name: newName
   312  ---
   313  apiVersion: apps/v1
   314  kind: Secret
   315  metadata:
   316    name: newName2
   317  `,
   318  			originalNames: []string{"oldName", "oldName"},
   319  			referrerFinal: "",
   320  			filter: Filter{
   321  				NameFieldToUpdate: types.FieldSpec{Path: "ref"},
   322  				ReferralTarget: resid.Gvk{
   323  					Group:   "apps",
   324  					Version: "v1",
   325  					Kind:    "Secret",
   326  				},
   327  			},
   328  		},
   329  	}
   330  
   331  	for tn, tc := range testCases {
   332  		t.Run(tn, func(t *testing.T) {
   333  			factory := provider.NewDefaultDepProvider().GetResourceFactory()
   334  			referrer, err := factory.FromBytes([]byte(tc.referrerOriginal))
   335  			if err != nil {
   336  				t.Fatal(err)
   337  			}
   338  			tc.filter.Referrer = referrer
   339  
   340  			resMapFactory := resmap.NewFactory(factory)
   341  			candidatesRes, err := factory.SliceFromBytesWithNames(
   342  				tc.originalNames, []byte(tc.candidates))
   343  			if err != nil {
   344  				t.Fatal(err)
   345  			}
   346  
   347  			candidates := resMapFactory.FromResourceSlice(candidatesRes)
   348  			tc.filter.ReferralCandidates = candidates
   349  
   350  			_, err = filtertest_test.RunFilterE(t, tc.referrerOriginal, tc.filter)
   351  			if err == nil {
   352  				t.Fatalf("expect an error")
   353  			}
   354  			if tc.referrerFinal != "" && !assert.EqualError(t, err, tc.referrerFinal) {
   355  				t.FailNow()
   356  			}
   357  		})
   358  	}
   359  }
   360  
   361  func TestCandidatesWithDifferentPrefixSuffix(t *testing.T) {
   362  	testCases := map[string]struct {
   363  		referrerOriginal string
   364  		candidates       string
   365  		referrerFinal    string
   366  		filter           Filter
   367  		originalNames    []string
   368  		prefix           []string
   369  		suffix           []string
   370  		inputPrefix      string
   371  		inputSuffix      string
   372  		err              bool
   373  	}{
   374  		"prefix match": {
   375  			referrerOriginal: `
   376  apiVersion: apps/v1
   377  kind: Deployment
   378  metadata:
   379    name: dep
   380  ref:
   381    name: oldName
   382  `,
   383  			candidates: `
   384  apiVersion: apps/v1
   385  kind: Secret
   386  metadata:
   387    name: newName
   388  ---
   389  apiVersion: apps/v1
   390  kind: Secret
   391  metadata:
   392    name: newName2
   393  `,
   394  			originalNames: []string{"oldName", "oldName"},
   395  			prefix:        []string{"prefix1", "prefix2"},
   396  			suffix:        []string{"", "suffix2"},
   397  			inputPrefix:   "prefix1",
   398  			inputSuffix:   "",
   399  			referrerFinal: `
   400  apiVersion: apps/v1
   401  kind: Deployment
   402  metadata:
   403    name: dep
   404  ref:
   405    name: newName
   406  `,
   407  			filter: Filter{
   408  				NameFieldToUpdate: types.FieldSpec{Path: "ref/name"},
   409  				ReferralTarget: resid.Gvk{
   410  					Group:   "apps",
   411  					Version: "v1",
   412  					Kind:    "Secret",
   413  				},
   414  			},
   415  			err: false,
   416  		},
   417  		"suffix match": {
   418  			referrerOriginal: `
   419  apiVersion: apps/v1
   420  kind: Deployment
   421  metadata:
   422    name: dep
   423  ref:
   424    name: oldName
   425  `,
   426  			candidates: `
   427  apiVersion: apps/v1
   428  kind: Secret
   429  metadata:
   430    name: newName
   431  ---
   432  apiVersion: apps/v1
   433  kind: Secret
   434  metadata:
   435    name: newName2
   436  `,
   437  			originalNames: []string{"oldName", "oldName"},
   438  			prefix:        []string{"", "prefix2"},
   439  			suffix:        []string{"suffix1", "suffix2"},
   440  			inputPrefix:   "",
   441  			inputSuffix:   "suffix1",
   442  			referrerFinal: `
   443  apiVersion: apps/v1
   444  kind: Deployment
   445  metadata:
   446    name: dep
   447  ref:
   448    name: newName
   449  `,
   450  			filter: Filter{
   451  				NameFieldToUpdate: types.FieldSpec{Path: "ref/name"},
   452  				ReferralTarget: resid.Gvk{
   453  					Group:   "apps",
   454  					Version: "v1",
   455  					Kind:    "Secret",
   456  				},
   457  			},
   458  			err: false,
   459  		},
   460  		"prefix suffix both match": {
   461  			referrerOriginal: `
   462  apiVersion: apps/v1
   463  kind: Deployment
   464  metadata:
   465    name: dep
   466  ref:
   467    name: oldName
   468  `,
   469  			candidates: `
   470  apiVersion: apps/v1
   471  kind: Secret
   472  metadata:
   473    name: newName
   474  ---
   475  apiVersion: apps/v1
   476  kind: Secret
   477  metadata:
   478    name: newName2
   479  `,
   480  			originalNames: []string{"oldName", "oldName"},
   481  			prefix:        []string{"prefix1", "prefix2"},
   482  			suffix:        []string{"suffix1", "suffix2"},
   483  			inputPrefix:   "prefix1",
   484  			inputSuffix:   "suffix1",
   485  			referrerFinal: `
   486  apiVersion: apps/v1
   487  kind: Deployment
   488  metadata:
   489    name: dep
   490  ref:
   491    name: newName
   492  `,
   493  			filter: Filter{
   494  				NameFieldToUpdate: types.FieldSpec{Path: "ref/name"},
   495  				ReferralTarget: resid.Gvk{
   496  					Group:   "apps",
   497  					Version: "v1",
   498  					Kind:    "Secret",
   499  				},
   500  			},
   501  			err: false,
   502  		},
   503  		"multiple match: both": {
   504  			referrerOriginal: `
   505  apiVersion: apps/v1
   506  kind: Deployment
   507  metadata:
   508    name: dep
   509  ref:
   510    name: oldName
   511  `,
   512  			candidates: `
   513  apiVersion: apps/v1
   514  kind: Secret
   515  metadata:
   516    name: newName
   517  ---
   518  apiVersion: apps/v1
   519  kind: Secret
   520  metadata:
   521    name: newName2
   522  `,
   523  			originalNames: []string{"oldName", "oldName"},
   524  			prefix:        []string{"prefix", "prefix"},
   525  			suffix:        []string{"suffix", "suffix"},
   526  			inputPrefix:   "prefix",
   527  			inputSuffix:   "suffix",
   528  			referrerFinal: "",
   529  			filter: Filter{
   530  				NameFieldToUpdate: types.FieldSpec{Path: "ref/name"},
   531  				ReferralTarget: resid.Gvk{
   532  					Group:   "apps",
   533  					Version: "v1",
   534  					Kind:    "Secret",
   535  				},
   536  			},
   537  			err: true,
   538  		},
   539  		"multiple match: only prefix": {
   540  			referrerOriginal: `
   541  apiVersion: apps/v1
   542  kind: Deployment
   543  metadata:
   544    name: dep
   545  ref:
   546    name: oldName
   547  `,
   548  			candidates: `
   549  apiVersion: apps/v1
   550  kind: Secret
   551  metadata:
   552    name: newName
   553  ---
   554  apiVersion: apps/v1
   555  kind: Secret
   556  metadata:
   557    name: newName2
   558  `,
   559  			originalNames: []string{"oldName", "oldName"},
   560  			prefix:        []string{"prefix", "prefix"},
   561  			suffix:        []string{"", ""},
   562  			inputPrefix:   "prefix",
   563  			inputSuffix:   "",
   564  			referrerFinal: "",
   565  			filter: Filter{
   566  				NameFieldToUpdate: types.FieldSpec{Path: "ref/name"},
   567  				ReferralTarget: resid.Gvk{
   568  					Group:   "apps",
   569  					Version: "v1",
   570  					Kind:    "Secret",
   571  				},
   572  			},
   573  			err: true,
   574  		},
   575  		"multiple match: only suffix": {
   576  			referrerOriginal: `
   577  apiVersion: apps/v1
   578  kind: Deployment
   579  metadata:
   580    name: dep
   581  ref:
   582    name: oldName
   583  `,
   584  			candidates: `
   585  apiVersion: apps/v1
   586  kind: Secret
   587  metadata:
   588    name: newName
   589  ---
   590  apiVersion: apps/v1
   591  kind: Secret
   592  metadata:
   593    name: newName2
   594  `,
   595  			originalNames: []string{"oldName", "oldName"},
   596  			prefix:        []string{"", ""},
   597  			suffix:        []string{"suffix", "suffix"},
   598  			inputPrefix:   "",
   599  			inputSuffix:   "suffix",
   600  			referrerFinal: "",
   601  			filter: Filter{
   602  				NameFieldToUpdate: types.FieldSpec{Path: "ref/name"},
   603  				ReferralTarget: resid.Gvk{
   604  					Group:   "apps",
   605  					Version: "v1",
   606  					Kind:    "Secret",
   607  				},
   608  			},
   609  			err: true,
   610  		},
   611  		"no match: neither match": {
   612  			referrerOriginal: `
   613  apiVersion: apps/v1
   614  kind: Deployment
   615  metadata:
   616    name: dep
   617  ref:
   618    name: oldName
   619  `,
   620  			candidates: `
   621  apiVersion: apps/v1
   622  kind: Secret
   623  metadata:
   624    name: newName
   625  ---
   626  apiVersion: apps/v1
   627  kind: Secret
   628  metadata:
   629    name: newName2
   630  `,
   631  			originalNames: []string{"oldName", "oldName"},
   632  			prefix:        []string{"prefix1", "prefix2"},
   633  			suffix:        []string{"suffix1", "suffix2"},
   634  			inputPrefix:   "prefix",
   635  			inputSuffix:   "suffix",
   636  			referrerFinal: `
   637  apiVersion: apps/v1
   638  kind: Deployment
   639  metadata:
   640    name: dep
   641  ref:
   642    name: oldName
   643  `,
   644  			filter: Filter{
   645  				NameFieldToUpdate: types.FieldSpec{Path: "ref/name"},
   646  				ReferralTarget: resid.Gvk{
   647  					Group:   "apps",
   648  					Version: "v1",
   649  					Kind:    "Secret",
   650  				},
   651  			},
   652  			err: false,
   653  		},
   654  		"no match: prefix doesn't match": {
   655  			referrerOriginal: `
   656  apiVersion: apps/v1
   657  kind: Deployment
   658  metadata:
   659    name: dep
   660  ref:
   661    name: oldName
   662  `,
   663  			candidates: `
   664  apiVersion: apps/v1
   665  kind: Secret
   666  metadata:
   667    name: newName
   668  ---
   669  apiVersion: apps/v1
   670  kind: Secret
   671  metadata:
   672    name: newName2
   673  `,
   674  			originalNames: []string{"oldName", "oldName"},
   675  			prefix:        []string{"prefix1", "prefix2"},
   676  			suffix:        []string{"suffix", "suffix"},
   677  			inputPrefix:   "prefix",
   678  			inputSuffix:   "suffix",
   679  			referrerFinal: `
   680  apiVersion: apps/v1
   681  kind: Deployment
   682  metadata:
   683    name: dep
   684  ref:
   685    name: oldName
   686  `,
   687  			filter: Filter{
   688  				NameFieldToUpdate: types.FieldSpec{Path: "ref/name"},
   689  				ReferralTarget: resid.Gvk{
   690  					Group:   "apps",
   691  					Version: "v1",
   692  					Kind:    "Secret",
   693  				},
   694  			},
   695  			err: false,
   696  		},
   697  		"no match: suffix doesn't match": {
   698  			referrerOriginal: `
   699  apiVersion: apps/v1
   700  kind: Deployment
   701  metadata:
   702    name: dep
   703  ref:
   704    name: oldName
   705  `,
   706  			candidates: `
   707  apiVersion: apps/v1
   708  kind: Secret
   709  metadata:
   710    name: newName
   711  ---
   712  apiVersion: apps/v1
   713  kind: Secret
   714  metadata:
   715    name: newName2
   716  `,
   717  			originalNames: []string{"oldName", "oldName"},
   718  			prefix:        []string{"prefix", "prefix"},
   719  			suffix:        []string{"suffix1", "suffix2"},
   720  			inputPrefix:   "prefix",
   721  			inputSuffix:   "suffix",
   722  			referrerFinal: `
   723  apiVersion: apps/v1
   724  kind: Deployment
   725  metadata:
   726    name: dep
   727  ref:
   728    name: oldName
   729  `,
   730  			filter: Filter{
   731  				NameFieldToUpdate: types.FieldSpec{Path: "ref/name"},
   732  				ReferralTarget: resid.Gvk{
   733  					Group:   "apps",
   734  					Version: "v1",
   735  					Kind:    "Secret",
   736  				},
   737  			},
   738  			err: false,
   739  		},
   740  	}
   741  
   742  	for tn, tc := range testCases {
   743  		t.Run(tn, func(t *testing.T) {
   744  			factory := provider.NewDefaultDepProvider().GetResourceFactory()
   745  			referrer, err := factory.FromBytes([]byte(tc.referrerOriginal))
   746  			if err != nil {
   747  				t.Fatal(err)
   748  			}
   749  			if tc.inputPrefix != "" {
   750  				referrer.AddNamePrefix(tc.inputPrefix)
   751  			}
   752  			if tc.inputSuffix != "" {
   753  				referrer.AddNameSuffix(tc.inputSuffix)
   754  			}
   755  			tc.filter.Referrer = referrer
   756  
   757  			resMapFactory := resmap.NewFactory(factory)
   758  			candidatesRes, err := factory.SliceFromBytesWithNames(
   759  				tc.originalNames, []byte(tc.candidates))
   760  			if err != nil {
   761  				t.Fatal(err)
   762  			}
   763  			for i := range candidatesRes {
   764  				if tc.prefix[i] != "" {
   765  					candidatesRes[i].AddNamePrefix(tc.prefix[i])
   766  				}
   767  				if tc.suffix[i] != "" {
   768  					candidatesRes[i].AddNameSuffix(tc.suffix[i])
   769  				}
   770  			}
   771  
   772  			candidates := resMapFactory.FromResourceSlice(candidatesRes)
   773  			tc.filter.ReferralCandidates = candidates
   774  
   775  			if !tc.err {
   776  				if !assert.Equal(t,
   777  					strings.TrimSpace(tc.referrerFinal),
   778  					strings.TrimSpace(
   779  						filtertest_test.RunFilter(
   780  							t, tc.referrerOriginal, tc.filter))) {
   781  					t.FailNow()
   782  				}
   783  			} else {
   784  				_, err := filtertest_test.RunFilterE(
   785  					t, tc.referrerOriginal, tc.filter)
   786  				if err == nil {
   787  					t.Fatalf("an error is expected")
   788  				}
   789  			}
   790  		})
   791  	}
   792  }
   793  

View as plain text