From f15684e0c4aace9fac7e1dbf0ed3ce3d32c3eb8a Mon Sep 17 00:00:00 2001 From: Paul Morie Date: Wed, 27 Jul 2016 12:08:17 -0400 Subject: [PATCH] Add e2e coverage for mount collisions --- test/e2e/configmap.go | 79 +++++++++++++++++++++++++++++- test/e2e/secrets.go | 111 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 170 insertions(+), 20 deletions(-) diff --git a/test/e2e/configmap.go b/test/e2e/configmap.go index ac216b96790..87490ee0079 100644 --- a/test/e2e/configmap.go +++ b/test/e2e/configmap.go @@ -29,7 +29,6 @@ import ( ) var _ = framework.KubeDescribe("ConfigMap", func() { - f := framework.NewDefaultFramework("configmap") It("should be consumable from pods in volume [Conformance]", func() { @@ -200,6 +199,84 @@ var _ = framework.KubeDescribe("ConfigMap", func() { "CONFIG_DATA_1=value-1", }, f.Namespace.Name) }) + + It("should be consumable in multiple volumes in the same pod", func() { + var ( + name = "configmap-test-volume-" + string(util.NewUUID()) + volumeName = "configmap-volume" + volumeMountPath = "/etc/configmap-volume" + volumeName2 = "configmap-volume-2" + volumeMountPath2 = "/etc/configmap-volume-2" + configMap = newConfigMap(f, name) + ) + + By(fmt.Sprintf("Creating configMap with name %s", configMap.Name)) + defer func() { + By("Cleaning up the configMap") + if err := f.Client.ConfigMaps(f.Namespace.Name).Delete(configMap.Name); err != nil { + framework.Failf("unable to delete configMap %v: %v", configMap.Name, err) + } + }() + var err error + if configMap, err = f.Client.ConfigMaps(f.Namespace.Name).Create(configMap); err != nil { + framework.Failf("unable to create test configMap %s: %v", configMap.Name, err) + } + + pod := &api.Pod{ + ObjectMeta: api.ObjectMeta{ + Name: "pod-configmaps-" + string(util.NewUUID()), + }, + Spec: api.PodSpec{ + Volumes: []api.Volume{ + { + Name: volumeName, + VolumeSource: api.VolumeSource{ + ConfigMap: &api.ConfigMapVolumeSource{ + LocalObjectReference: api.LocalObjectReference{ + Name: name, + }, + }, + }, + }, + { + Name: volumeName2, + VolumeSource: api.VolumeSource{ + ConfigMap: &api.ConfigMapVolumeSource{ + LocalObjectReference: api.LocalObjectReference{ + Name: name, + }, + }, + }, + }, + }, + Containers: []api.Container{ + { + Name: "configmap-volume-test", + Image: "gcr.io/google_containers/mounttest:0.6", + Args: []string{"--file_content=/etc/configmap-volume/data-1"}, + VolumeMounts: []api.VolumeMount{ + { + Name: volumeName, + MountPath: volumeMountPath, + ReadOnly: true, + }, + { + Name: volumeName2, + MountPath: volumeMountPath2, + ReadOnly: true, + }, + }, + }, + }, + RestartPolicy: api.RestartPolicyNever, + }, + } + + framework.TestContainerOutput("consume configMaps", f.Client, pod, 0, []string{ + "content of file \"/etc/configmap-volume/data-1\": value-1", + }, f.Namespace.Name) + + }) }) func newConfigMap(f *framework.Framework, name string) *api.ConfigMap { diff --git a/test/e2e/secrets.go b/test/e2e/secrets.go index f501c81f777..960d9194cde 100644 --- a/test/e2e/secrets.go +++ b/test/e2e/secrets.go @@ -33,18 +33,7 @@ var _ = framework.KubeDescribe("Secrets", func() { name := "secret-test-" + string(util.NewUUID()) volumeName := "secret-volume" volumeMountPath := "/etc/secret-volume" - - secret := &api.Secret{ - ObjectMeta: api.ObjectMeta{ - Namespace: f.Namespace.Name, - Name: name, - }, - Data: map[string][]byte{ - "data-1": []byte("value-1\n"), - "data-2": []byte("value-2\n"), - "data-3": []byte("value-3\n"), - }, - } + secret := secretForTest(f.Namespace.Name, name) By(fmt.Sprintf("Creating secret with name %s", secret.Name)) defer func() { @@ -99,19 +88,89 @@ var _ = framework.KubeDescribe("Secrets", func() { }, f.Namespace.Name) }) - It("should be consumable from pods in env vars [Conformance]", func() { - name := "secret-test-" + string(util.NewUUID()) + It("should be consumable in multiple volumes in a pod [Conformance]", func() { + // This test ensures that the same secret can be mounted in multiple + // volumes in the same pod. This test case exists to prevent + // regressions that break this use-case. + var ( + name = "secret-test-" + string(util.NewUUID()) + volumeName = "secret-volume" + volumeMountPath = "/etc/secret-volume" + volumeName2 = "secret-volume-2" + volumeMountPath2 = "/etc/secret-volume-2" + secret = secretForTest(f.Namespace.Name, name) + ) - secret := &api.Secret{ + By(fmt.Sprintf("Creating secret with name %s", secret.Name)) + defer func() { + By("Cleaning up the secret") + if err := f.Client.Secrets(f.Namespace.Name).Delete(secret.Name); err != nil { + framework.Failf("unable to delete secret %v: %v", secret.Name, err) + } + }() + var err error + if secret, err = f.Client.Secrets(f.Namespace.Name).Create(secret); err != nil { + framework.Failf("unable to create test secret %s: %v", secret.Name, err) + } + + pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ - Namespace: f.Namespace.Name, - Name: name, + Name: "pod-secrets-" + string(util.NewUUID()), }, - Data: map[string][]byte{ - "data-1": []byte("value-1"), + Spec: api.PodSpec{ + Volumes: []api.Volume{ + { + Name: volumeName, + VolumeSource: api.VolumeSource{ + Secret: &api.SecretVolumeSource{ + SecretName: name, + }, + }, + }, + { + Name: volumeName2, + VolumeSource: api.VolumeSource{ + Secret: &api.SecretVolumeSource{ + SecretName: name, + }, + }, + }, + }, + Containers: []api.Container{ + { + Name: "secret-volume-test", + Image: "gcr.io/google_containers/mounttest:0.7", + Args: []string{ + "--file_content=/etc/secret-volume/data-1", + "--file_mode=/etc/secret-volume/data-1"}, + VolumeMounts: []api.VolumeMount{ + { + Name: volumeName, + MountPath: volumeMountPath, + ReadOnly: true, + }, + { + Name: volumeName2, + MountPath: volumeMountPath2, + ReadOnly: true, + }, + }, + }, + }, + RestartPolicy: api.RestartPolicyNever, }, } + framework.TestContainerOutput("consume secrets", f.Client, pod, 0, []string{ + "content of file \"/etc/secret-volume/data-1\": value-1", + "mode of file \"/etc/secret-volume/data-1\": -rw-r--r--", + }, f.Namespace.Name) + }) + + It("should be consumable from pods in env vars [Conformance]", func() { + name := "secret-test-" + string(util.NewUUID()) + secret := secretForTest(f.Namespace.Name, name) + By(fmt.Sprintf("Creating secret with name %s", secret.Name)) defer func() { By("Cleaning up the secret") @@ -158,3 +217,17 @@ var _ = framework.KubeDescribe("Secrets", func() { }, f.Namespace.Name) }) }) + +func secretForTest(namespace, name string) *api.Secret { + return &api.Secret{ + ObjectMeta: api.ObjectMeta{ + Namespace: namespace, + Name: name, + }, + Data: map[string][]byte{ + "data-1": []byte("value-1\n"), + "data-2": []byte("value-2\n"), + "data-3": []byte("value-3\n"), + }, + } +}