From a9d1182322bea23d0689f060832dfdf648f794c5 Mon Sep 17 00:00:00 2001 From: Donny Xia Date: Mon, 27 Jul 2020 12:45:45 -0700 Subject: [PATCH] Add test for name ref --- api/filters/nameref/nameref.go | 2 +- api/filters/nameref/nameref_test.go | 333 ++++++++++++++++++++++++++++ 2 files changed, 334 insertions(+), 1 deletion(-) create mode 100644 api/filters/nameref/nameref_test.go diff --git a/api/filters/nameref/nameref.go b/api/filters/nameref/nameref.go index d72967c6f..1da3396fd 100644 --- a/api/filters/nameref/nameref.go +++ b/api/filters/nameref/nameref.go @@ -48,7 +48,7 @@ func (f Filter) set(node *yaml.RNode) error { return f.setSequence(node) default: return fmt.Errorf( - "%#v is expected to be either a string or a slice of string or a map of string", node) + "node is expected to be either a string or a slice of string or a map of string") } } diff --git a/api/filters/nameref/nameref_test.go b/api/filters/nameref/nameref_test.go new file mode 100644 index 000000000..951ff73eb --- /dev/null +++ b/api/filters/nameref/nameref_test.go @@ -0,0 +1,333 @@ +package nameref + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "sigs.k8s.io/kustomize/api/k8sdeps/kunstruct" + "sigs.k8s.io/kustomize/api/resid" + "sigs.k8s.io/kustomize/api/resmap" + "sigs.k8s.io/kustomize/api/resource" + filtertest_test "sigs.k8s.io/kustomize/api/testutils/filtertest" + "sigs.k8s.io/kustomize/api/types" +) + +func TestNamerefFilter(t *testing.T) { + testCases := map[string]struct { + input string + candidates string + expected string + filter Filter + originalNames []string + }{ + "simple scalar": { + input: ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dep +ref: + name: oldName +`, + candidates: ` +apiVersion: apps/v1 +kind: Secret +metadata: + name: newName +--- +apiVersion: apps/v1 +kind: NotSecret +metadata: + name: newName2 +`, + originalNames: []string{"oldName", ""}, + expected: ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dep +ref: + name: newName +`, + filter: Filter{ + FieldSpec: types.FieldSpec{Path: "ref/name"}, + Target: resid.Gvk{ + Group: "apps", + Version: "v1", + Kind: "Secret", + }, + }, + }, + "sequence": { + input: ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dep +seq: +- oldName1 +- oldName2 +`, + candidates: ` +apiVersion: apps/v1 +kind: Secret +metadata: + name: newName +--- +apiVersion: apps/v1 +kind: NotSecret +metadata: + name: newName2 +`, + originalNames: []string{"oldName1", ""}, + expected: ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dep +seq: +- newName +- oldName2 +`, + filter: Filter{ + FieldSpec: types.FieldSpec{Path: "seq"}, + Target: resid.Gvk{ + Group: "apps", + Version: "v1", + Kind: "Secret", + }, + }, + }, + "mapping": { + input: ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dep +map: + name: oldName +`, + candidates: ` +apiVersion: apps/v1 +kind: Secret +metadata: + name: newName +--- +apiVersion: apps/v1 +kind: NotSecret +metadata: + name: newName2 +`, + originalNames: []string{"oldName", ""}, + expected: ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dep +map: + name: newName +`, + filter: Filter{ + FieldSpec: types.FieldSpec{Path: "map"}, + Target: resid.Gvk{ + Group: "apps", + Version: "v1", + Kind: "Secret", + }, + }, + }, + "mapping with namespace": { + input: ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dep +map: + name: oldName + namespace: oldNs +`, + candidates: ` +apiVersion: apps/v1 +kind: Secret +metadata: + name: newName + namespace: oldNs +--- +apiVersion: apps/v1 +kind: NotSecret +metadata: + name: newName2 +`, + originalNames: []string{"oldName", ""}, + expected: ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dep +map: + name: newName + namespace: oldNs +`, + filter: Filter{ + FieldSpec: types.FieldSpec{Path: "map"}, + Target: resid.Gvk{ + Group: "apps", + Version: "v1", + Kind: "Secret", + }, + }, + }, + } + + for tn, tc := range testCases { + t.Run(tn, func(t *testing.T) { + factory := resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl()) + referrer, err := factory.FromBytes([]byte(tc.input)) + if err != nil { + t.Fatal(err) + } + tc.filter.Referrer = referrer + + resMapFactory := resmap.NewFactory(factory, nil) + candidatesRes, err := factory.SliceFromBytesWithNames( + tc.originalNames, []byte(tc.candidates)) + if err != nil { + t.Fatal(err) + } + + candidates := resMapFactory.FromResourceSlice(candidatesRes) + tc.filter.ReferralCandidates = candidates + + if !assert.Equal(t, + strings.TrimSpace(tc.expected), + strings.TrimSpace( + filtertest_test.RunFilter(t, tc.input, tc.filter))) { + t.FailNow() + } + }) + } +} + +func TestNamerefFilterUnhappy(t *testing.T) { + testCases := map[string]struct { + input string + candidates string + expected string + filter Filter + originalNames []string + }{ + "invalid node type": { + input: ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dep +ref: + name: null +`, + candidates: "", + originalNames: []string{}, + expected: "obj '' at path 'ref/name': node is expected to be either a string or a slice of string or a map of string", + filter: Filter{ + FieldSpec: types.FieldSpec{Path: "ref/name"}, + Target: resid.Gvk{ + Group: "apps", + Version: "v1", + Kind: "Secret", + }, + }, + }, + "multiple match": { + input: ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dep +ref: + name: oldName +`, + candidates: ` +apiVersion: apps/v1 +kind: Secret +metadata: + name: newName +--- +apiVersion: apps/v1 +kind: Secret +metadata: + name: newName2 +`, + originalNames: []string{"oldName", "oldName"}, + expected: "", + filter: Filter{ + FieldSpec: types.FieldSpec{Path: "ref/name"}, + Target: resid.Gvk{ + Group: "apps", + Version: "v1", + Kind: "Secret", + }, + }, + }, + "no name": { + input: ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dep +ref: + notName: oldName +`, + candidates: ` +apiVersion: apps/v1 +kind: Secret +metadata: + name: newName +--- +apiVersion: apps/v1 +kind: Secret +metadata: + name: newName2 +`, + originalNames: []string{"oldName", "oldName"}, + expected: "", + filter: Filter{ + FieldSpec: types.FieldSpec{Path: "ref"}, + Target: resid.Gvk{ + Group: "apps", + Version: "v1", + Kind: "Secret", + }, + }, + }, + } + + for tn, tc := range testCases { + t.Run(tn, func(t *testing.T) { + factory := resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl()) + referrer, err := factory.FromBytes([]byte(tc.input)) + if err != nil { + t.Fatal(err) + } + tc.filter.Referrer = referrer + + resMapFactory := resmap.NewFactory(factory, nil) + candidatesRes, err := factory.SliceFromBytesWithNames( + tc.originalNames, []byte(tc.candidates)) + if err != nil { + t.Fatal(err) + } + + candidates := resMapFactory.FromResourceSlice(candidatesRes) + tc.filter.ReferralCandidates = candidates + + _, err = filtertest_test.RunFilterE(t, tc.input, tc.filter) + if err == nil { + t.Fatalf("expect an error") + } + if tc.expected != "" && !assert.EqualError(t, err, tc.expected) { + t.FailNow() + } + }) + } +}