Merge pull request #643 from monopole/moarTests

More fully in-memory integration tests.
This commit is contained in:
Kubernetes Prow Robot
2018-12-18 10:49:46 -08:00
committed by GitHub
20 changed files with 422 additions and 213 deletions

View File

@@ -1,7 +0,0 @@
apiVersion: v1
kind: Kustomization
resources:
- serviceaccount.yaml
- rolebinding.yaml
namePrefix: base-
nameSuffix: -suffix

View File

@@ -1,11 +0,0 @@
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: role
subjects:
- kind: ServiceAccount
name: serviceaccount

View File

@@ -1,4 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: serviceaccount

View File

@@ -1,5 +0,0 @@
apiVersion: v1
kind: Kustomization
bases:
- ../overlays/a
- ../overlays/b

View File

@@ -1,10 +0,0 @@
apiVersion: v1
kind: Kustomization
bases:
- ../../base/
namePrefix: a-
nameSuffix: -suffixA
resources:
- serviceaccount.yaml

View File

@@ -1,4 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: serviceaccount

View File

@@ -1,7 +0,0 @@
apiVersion: v1
kind: Kustomization
bases:
- ../../base/
namePrefix: b-
nameSuffix: -suffixB

View File

@@ -1,4 +0,0 @@
description: multibases with name reference
args: []
filename: testdata/testcase-multibases-conflict/combined
expectedError: Multiple matches for name ~G_v1_ServiceAccount

View File

@@ -1,7 +0,0 @@
apiVersion: v1
kind: Kustomization
resources:
- serviceaccount.yaml
- rolebinding.yaml
namePrefix: base-
nameSuffix: -suffix

View File

@@ -1,11 +0,0 @@
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: role
subjects:
- kind: ServiceAccount
name: serviceaccount

View File

@@ -1,4 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: serviceaccount

View File

@@ -1,5 +0,0 @@
apiVersion: v1
kind: Kustomization
bases:
- ../overlays/a
- ../overlays/b

View File

@@ -1,33 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: a-base-serviceaccount-suffix-suffixA
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: b-base-serviceaccount-suffix-suffixB
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: a-base-rolebinding-suffix-suffixA
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: role
subjects:
- kind: ServiceAccount
name: a-base-serviceaccount-suffix-suffixA
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: b-base-rolebinding-suffix-suffixB
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: role
subjects:
- kind: ServiceAccount
name: b-base-serviceaccount-suffix-suffixB

View File

@@ -1,7 +0,0 @@
apiVersion: v1
kind: Kustomization
bases:
- ../../base/
namePrefix: a-
nameSuffix: -suffixA

View File

@@ -1,7 +0,0 @@
apiVersion: v1
kind: Kustomization
bases:
- ../../base/
namePrefix: b-
nameSuffix: -suffixB

View File

@@ -1,4 +0,0 @@
description: multibases with name reference
args: []
filename: testdata/testcase-multibases-nonconflict/combined
expectedStdout: testdata/testcase-multibases-nonconflict/expected.yaml

View File

@@ -84,7 +84,6 @@ spec:
ports:
- containerPort: 80
`)
}
func TestBigBase(t *testing.T) {
@@ -101,7 +100,7 @@ func TestBigBase(t *testing.T) {
if err != nil {
t.Fatalf("Err: %v", err)
}
expected := `apiVersion: v1
assertExpectedEqualsActual(t, s, `apiVersion: v1
kind: Service
metadata:
annotations:
@@ -147,11 +146,7 @@ spec:
name: nginx
ports:
- containerPort: 80
`
if string(s) != expected {
t.Fatalf("Actual results:\n%s\nnot equal to expected:\n%s\n",
s, expected)
}
`)
}
func TestBigOverlay(t *testing.T) {
@@ -224,7 +219,118 @@ spec:
if err != nil {
t.Fatalf("Err: %v", err)
}
if m == nil {
t.Fatalf("Empty map.")
s, err := m.EncodeAsYaml()
if err != nil {
t.Fatalf("Unexpected err: %v", err)
}
assertExpectedEqualsActual(t, s, `apiVersion: v1
data:
app-init.ini: |2
FOO=bar
BAR=baz
kind: ConfigMap
metadata:
annotations:
note: This is a test annotation
labels:
app: mungebot
org: kubernetes
repo: test-infra
name: test-infra-app-config-fd62mfc87h
---
apiVersion: v1
data:
DB_PASSWORD: somepw
DB_USERNAME: admin
kind: ConfigMap
metadata:
annotations:
note: This is a test annotation
labels:
app: mungebot
org: kubernetes
repo: test-infra
name: test-infra-app-env-bh449c299k
---
apiVersion: v1
kind: Service
metadata:
annotations:
baseAnno: This is a base annotation
note: This is a test annotation
labels:
app: mungebot
foo: bar
org: kubernetes
repo: test-infra
name: test-infra-baseprefix-mungebot-service
spec:
ports:
- port: 7002
selector:
app: mungebot
foo: bar
org: kubernetes
repo: test-infra
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
annotations:
baseAnno: This is a base annotation
note: This is a test annotation
labels:
app: mungebot
foo: bar
org: kubernetes
repo: test-infra
name: test-infra-baseprefix-mungebot
spec:
replicas: 2
selector:
matchLabels:
app: mungebot
foo: bar
org: kubernetes
repo: test-infra
template:
metadata:
annotations:
baseAnno: This is a base annotation
note: This is a test annotation
labels:
app: mungebot
foo: bar
org: kubernetes
repo: test-infra
spec:
containers:
- env:
- name: FOO
valueFrom:
configMapKeyRef:
key: somekey
name: test-infra-app-env-bh449c299k
- name: foo
value: bar
image: nginx:1.8.0
name: nginx
ports:
- containerPort: 80
- envFrom:
- configMapRef:
name: someConfigMap
- configMapRef:
name: test-infra-app-env-bh449c299k
image: busybox
name: busybox
volumeMounts:
- mountPath: /tmp/env
name: app-env
volumes:
- configMap:
name: test-infra-app-env-bh449c299k
name: app-env
`)
}

View File

@@ -18,16 +18,12 @@ package target
import (
"encoding/base64"
"path/filepath"
"reflect"
"sort"
"strings"
"testing"
"sigs.k8s.io/kustomize/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/k8sdeps/transformer"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/fs"
"sigs.k8s.io/kustomize/pkg/gvk"
"sigs.k8s.io/kustomize/pkg/ifc"
"sigs.k8s.io/kustomize/pkg/internal/loadertest"
@@ -98,53 +94,24 @@ metadata:
var rf = resmap.NewFactory(resource.NewFactory(
kunstruct.NewKunstructuredFactoryImpl()))
func makeKustTarget(t *testing.T, l ifc.Loader) *KustTarget {
// Warning: the following filesystem - a fake - must be rooted at /.
// This fs root is used as the working directory for the shell spawned by
// the secretgenerator, and has nothing to do with the filesystem used
// to load relative paths from the fake filesystem.
// This trick only works for secret generator commands that don't actually
// try to read the file system, because these tests don't write to the
// real "/" directory. See use of exec package in the secretfactory.
fakeFs := fs.MakeFakeFS()
fakeFs.Mkdir("/")
kt, err := NewKustTarget(
l, fakeFs, rf, transformer.NewFactoryImpl())
if err != nil {
t.Fatalf("Unexpected construction error %v", err)
}
return kt
}
func makeLoader1(t *testing.T) ifc.Loader {
ldr := loadertest.NewFakeLoader("/testpath")
err := ldr.AddFile("/testpath/"+constants.KustomizationFileName, []byte(kustomizationContent1))
if err != nil {
t.Fatalf("Failed to setup fake ldr.")
}
err = ldr.AddFile("/testpath/deployment.yaml", []byte(deploymentContent))
if err != nil {
t.Fatalf("Failed to setup fake ldr.")
}
err = ldr.AddFile("/testpath/namespace.yaml", []byte(namespaceContent))
if err != nil {
t.Fatalf("Failed to setup fake ldr.")
}
err = ldr.AddFile("/testpath/jsonpatch.json", []byte(jsonpatchContent))
if err != nil {
t.Fatalf("Failed to setup fake ldr.")
}
return ldr
}
var deploy = gvk.Gvk{Group: "apps", Version: "v1", Kind: "Deployment"}
var cmap = gvk.Gvk{Version: "v1", Kind: "ConfigMap"}
var secret = gvk.Gvk{Version: "v1", Kind: "Secret"}
var ns = gvk.Gvk{Version: "v1", Kind: "Namespace"}
func makeALoader(t *testing.T) ifc.Loader {
ldr := loadertest.NewFakeLoader("/testpath")
writeK(t, ldr, "/testpath/", kustomizationContent1)
writeF(t, ldr, "/testpath/deployment.yaml", deploymentContent)
writeF(t, ldr, "/testpath/namespace.yaml", namespaceContent)
writeF(t, ldr, "/testpath/jsonpatch.json", jsonpatchContent)
return ldr
}
func TestResources1(t *testing.T) {
expected := resmap.ResMap{
resid.NewResIdWithPrefixSuffixNamespace(deploy, "dply1", "foo-", "-bar", "ns1"): rf.RF().FromMap(
resid.NewResIdWithPrefixSuffixNamespace(
deploy, "dply1", "foo-", "-bar", "ns1"): rf.RF().FromMap(
map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
@@ -177,7 +144,8 @@ func TestResources1(t *testing.T) {
},
},
}),
resid.NewResIdWithPrefixSuffixNamespace(cmap, "literalConfigMap", "foo-", "-bar", "ns1"): rf.RF().FromMap(
resid.NewResIdWithPrefixSuffixNamespace(
cmap, "literalConfigMap", "foo-", "-bar", "ns1"): rf.RF().FromMap(
map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
@@ -196,7 +164,8 @@ func TestResources1(t *testing.T) {
"DB_PASSWORD": "somepw",
},
}).SetBehavior(ifc.BehaviorCreate),
resid.NewResIdWithPrefixSuffixNamespace(secret, "secret", "foo-", "-bar", "ns1"): rf.RF().FromMap(
resid.NewResIdWithPrefixSuffixNamespace(
secret, "secret", "foo-", "-bar", "ns1"): rf.RF().FromMap(
map[string]interface{}{
"apiVersion": "v1",
"kind": "Secret",
@@ -216,7 +185,8 @@ func TestResources1(t *testing.T) {
"DB_PASSWORD": base64.StdEncoding.EncodeToString([]byte("somepw")),
},
}).SetBehavior(ifc.BehaviorCreate),
resid.NewResIdWithPrefixSuffixNamespace(ns, "ns1", "foo-", "-bar", ""): rf.RF().FromMap(
resid.NewResIdWithPrefixSuffixNamespace(
ns, "ns1", "foo-", "-bar", ""): rf.RF().FromMap(
map[string]interface{}{
"apiVersion": "v1",
"kind": "Namespace",
@@ -232,7 +202,7 @@ func TestResources1(t *testing.T) {
}),
}
actual, err := makeKustTarget(
t, makeLoader1(t)).MakeCustomizedResMap()
t, makeALoader(t)).MakeCustomizedResMap()
if err != nil {
t.Fatalf("unexpected Resources error %v", err)
}
@@ -245,11 +215,8 @@ func TestResources1(t *testing.T) {
func TestResourceNotFound(t *testing.T) {
l := loadertest.NewFakeLoader("/testpath")
err := l.AddFile("/testpath/"+constants.KustomizationFileName, []byte(kustomizationContent1))
if err != nil {
t.Fatalf("Failed to setup fake ldr.")
}
_, err = makeKustTarget(t, l).MakeCustomizedResMap()
writeK(t, l, "/testpath", kustomizationContent1)
_, err := makeKustTarget(t, l).MakeCustomizedResMap()
if err == nil {
t.Fatalf("Didn't get the expected error for an unknown resource")
}
@@ -260,11 +227,8 @@ func TestResourceNotFound(t *testing.T) {
func TestSecretTimeout(t *testing.T) {
l := loadertest.NewFakeLoader("/testpath")
err := l.AddFile("/testpath/"+constants.KustomizationFileName, []byte(kustomizationContent2))
if err != nil {
t.Fatalf("Failed to setup fake ldr.")
}
_, err = makeKustTarget(t, l).MakeCustomizedResMap()
writeK(t, l, "/testpath", kustomizationContent2)
_, err := makeKustTarget(t, l).MakeCustomizedResMap()
if err == nil {
t.Fatalf("Didn't get the expected error for an unknown resource")
}
@@ -283,7 +247,7 @@ func findSecret(m resmap.ResMap) *resource.Resource {
}
func TestDisableNameSuffixHash(t *testing.T) {
kt := makeKustTarget(t, makeLoader1(t))
kt := makeKustTarget(t, makeALoader(t))
m, err := kt.MakeCustomizedResMap()
if err != nil {
@@ -312,21 +276,6 @@ func TestDisableNameSuffixHash(t *testing.T) {
}
}
func writeF(t *testing.T, ldr loadertest.FakeLoader, dir string, content string) {
err := ldr.AddFile(dir, []byte(content))
if err != nil {
t.Fatalf("failed write to %s; %v", dir, err)
}
}
func writeK(
t *testing.T, ldr loadertest.FakeLoader, dir string, content string) {
writeF(t, ldr, filepath.Join(dir, constants.KustomizationFileName), `
apiVersion: v1
kind: Kustomization
`+content)
}
func TestIssue596AllowDirectoriesThatAreSubstringsOfEachOther(t *testing.T) {
ldr := loadertest.NewFakeLoader(
"/app/overlays/aws-sandbox2.us-east-1")

View File

@@ -0,0 +1,153 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package target
import (
"strings"
"testing"
"sigs.k8s.io/kustomize/pkg/internal/loadertest"
)
func writeCombinedOverlays(t *testing.T, ldr loadertest.FakeLoader) {
// Base
writeK(t, ldr, "/app/base", `
resources:
- serviceaccount.yaml
- rolebinding.yaml
namePrefix: base-
nameSuffix: -suffix
`)
writeF(t, ldr, "/app/base/rolebinding.yaml", `
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: role
subjects:
- kind: ServiceAccount
name: serviceaccount
`)
writeF(t, ldr, "/app/base/serviceaccount.yaml", `
apiVersion: v1
kind: ServiceAccount
metadata:
name: serviceaccount
`)
// Mid-level overlays
writeK(t, ldr, "/app/overlays/a", `
bases:
- ../../base
namePrefix: a-
nameSuffix: -suffixA
`)
writeK(t, ldr, "/app/overlays/b", `
bases:
- ../../base
namePrefix: b-
nameSuffix: -suffixB
`)
// Top overlay, combining the mid-level overlays
writeK(t, ldr, "/app/combined", `
bases:
- ../overlays/a
- ../overlays/b
`)
}
func TestMultibasesNoConflict(t *testing.T) {
ldr := loadertest.NewFakeLoader("/app/combined")
writeCombinedOverlays(t, ldr)
m, err := makeKustTarget(t, ldr).MakeCustomizedResMap()
if err != nil {
t.Fatalf("Unexpected err: %v", err)
}
s, err := m.EncodeAsYaml()
if err != nil {
t.Fatalf("Unexpected err: %v", err)
}
assertExpectedEqualsActual(t, s, `apiVersion: v1
kind: ServiceAccount
metadata:
name: a-base-serviceaccount-suffix-suffixA
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: b-base-serviceaccount-suffix-suffixB
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: a-base-rolebinding-suffix-suffixA
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: role
subjects:
- kind: ServiceAccount
name: a-base-serviceaccount-suffix-suffixA
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: b-base-rolebinding-suffix-suffixB
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: role
subjects:
- kind: ServiceAccount
name: b-base-serviceaccount-suffix-suffixB
`)
}
func TestMultibasesWithConflict(t *testing.T) {
ldr := loadertest.NewFakeLoader("/app/combined")
writeCombinedOverlays(t, ldr)
writeK(t, ldr, "/app/overlays/a", `
bases:
- ../../base
namePrefix: a-
nameSuffix: -suffixA
resources:
- serviceaccount.yaml
`)
// Expect an error because this resource in the overlay
// matches a resource in the base.
writeF(t, ldr, "/app/overlays/a/serviceaccount.yaml", `
apiVersion: v1
kind: ServiceAccount
metadata:
name: serviceaccount
`)
_, err := makeKustTarget(t, ldr).MakeCustomizedResMap()
if err == nil {
t.Fatalf("Expected resource conflict.")
}
if !strings.Contains(
err.Error(), "Multiple matches for name ~G_v1_ServiceAccount") {
t.Fatalf("Unexpected err: %v", err)
}
}

View File

@@ -0,0 +1,131 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package target
// A collection of utilities used in target tests.
import (
"fmt"
"path/filepath"
"strings"
"testing"
"sigs.k8s.io/kustomize/k8sdeps/transformer"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/fs"
"sigs.k8s.io/kustomize/pkg/ifc"
"sigs.k8s.io/kustomize/pkg/internal/loadertest"
)
func makeKustTarget(t *testing.T, l ifc.Loader) *KustTarget {
// Warning: the following filesystem - a fake - must be rooted at /.
// This fs root is used as the working directory for the shell spawned by
// the secretgenerator, and has nothing to do with the filesystem used
// to load relative paths from the fake filesystem.
// This trick only works for secret generator commands that don't actually
// try to read the file system, because these tests don't write to the
// real "/" directory. See use of exec package in the secretfactory.
fakeFs := fs.MakeFakeFS()
fakeFs.Mkdir("/")
kt, err := NewKustTarget(
l, fakeFs, rf, transformer.NewFactoryImpl())
if err != nil {
t.Fatalf("Unexpected construction error %v", err)
}
return kt
}
func writeF(
t *testing.T, ldr loadertest.FakeLoader, dir string, content string) {
err := ldr.AddFile(dir, []byte(content))
if err != nil {
t.Fatalf("failed write to %s; %v", dir, err)
}
}
func writeK(
t *testing.T, ldr loadertest.FakeLoader, dir string, content string) {
writeF(t, ldr, filepath.Join(dir, constants.KustomizationFileName), `
apiVersion: v1
kind: Kustomization
`+content)
}
func tabToSpace(input string) string {
var result []string
for _, i := range input {
if i == 9 {
result = append(result, " ")
} else {
result = append(result, string(i))
}
}
return strings.Join(result, "")
}
func convertToArray(x string) ([]string, int) {
a := strings.Split(strings.TrimSuffix(x, "\n"), "\n")
maxLen := 0
for i, v := range a {
z := tabToSpace(v)
if len(z) > maxLen {
maxLen = len(z)
}
a[i] = z
}
return a, maxLen
}
func hint(a, b string) string {
if a == b {
return " "
}
return "X"
}
// Pretty printing of file differences.
func assertExpectedEqualsActual(t *testing.T, actual []byte, expected string) {
if expected == string(actual) {
return
}
sE, maxLen := convertToArray(expected)
sA, _ := convertToArray(string(actual))
format := fmt.Sprintf("%%s %%-%ds %%s\n", maxLen+4)
limit := 0
if len(sE) < len(sA) {
limit = len(sE)
} else {
limit = len(sA)
}
fmt.Printf(format, " ", "EXPECTED", "ACTUAL")
fmt.Printf(format, " ", "--------", "------")
for i := 0; i < limit; i++ {
fmt.Printf(format, hint(sE[i], sA[i]), sE[i], sA[i])
}
if len(sE) < len(sA) {
for i := len(sE); i < len(sA); i++ {
fmt.Printf(format, "X", "", sA[i])
}
} else {
for i := len(sA); i < len(sE); i++ {
fmt.Printf(format, "X", sE[i], "")
}
}
t.Fatalf("Expected not equal to actual")
}