<commit_before>/*
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 storage

import (
	"fmt"
	"path/filepath"
	"strings"

	"k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/fields"
	utilerrors "k8s.io/apimachinery/pkg/util/errors"
	"k8s.io/apimachinery/pkg/util/rand"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/kubernetes/test/e2e/framework"
	"k8s.io/kubernetes/test/e2e/storage/utils"
	imageutils "k8s.io/kubernetes/test/utils/image"

	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var (
	volumePath    = "/test-volume"
	volumeName    = "test-volume"
	fileName      = "test-file"
	retryDuration = 180
	mountImage    = imageutils.GetE2EImage(imageutils.Mounttest)
)

type volInfo struct {
	source *v1.VolumeSource
	node   string
}

type volSource interface {
	createVolume(f *framework.Framework) volInfo
	cleanupVolume(f *framework.Framework)
}

var initVolSources = map[string]func() volSource{
	"hostPath":         initHostpath,
	"hostPathSymlink":  initHostpathSymlink,
	"emptyDir":         initEmptydir,
	"gcePD":            initGCEPD,
	"gcePDPartitioned": initGCEPDPartition,
	"nfs":              initNFS,
	"nfsPVC":           initNFSPVC,
	"gluster":          initGluster,
}

var _ = utils.SIGDescribe("Subpath", func() {
	var (
		subPath           string
		subPathDir        string
		filePathInSubpath string
		filePathInVolume  string
		pod               *v1.Pod
		vol               volSource
	)

	f := framework.NewDefaultFramework("subpath")

	for volType, volInit := range initVolSources {<commit_msg>Add atomic writer subpath e2e tests<commit_after>/*
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 storage

import (
	"fmt"
	"path/filepath"
	"strings"

	"k8s.io/api/core/v1"
	apierrors "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/fields"
	utilerrors "k8s.io/apimachinery/pkg/util/errors"
	"k8s.io/apimachinery/pkg/util/rand"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/kubernetes/test/e2e/framework"
	"k8s.io/kubernetes/test/e2e/storage/utils"
	imageutils "k8s.io/kubernetes/test/utils/image"

	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var (
	volumePath    = "/test-volume"
	volumeName    = "test-volume"
	fileName      = "test-file"
	retryDuration = 180
	mountImage    = imageutils.GetE2EImage(imageutils.Mounttest)
)

type volInfo struct {
	source *v1.VolumeSource
	node   string
}

type volSource interface {
	createVolume(f *framework.Framework) volInfo
	cleanupVolume(f *framework.Framework)
}

var initVolSources = map[string]func() volSource{
	"hostPath":         initHostpath,
	"hostPathSymlink":  initHostpathSymlink,
	"emptyDir":         initEmptydir,
	"gcePD":            initGCEPD,
	"gcePDPartitioned": initGCEPDPartition,
	"nfs":              initNFS,
	"nfsPVC":           initNFSPVC,
	"gluster":          initGluster,
}

var _ = utils.SIGDescribe("Subpath", func() {
	var (
		subPath           string
		subPathDir        string
		filePathInSubpath string
		filePathInVolume  string
		pod               *v1.Pod
		vol               volSource
	)

	f := framework.NewDefaultFramework("subpath")

	Context("Atomic writer volumes", func() {
		var err error

		BeforeEach(func() {
			By("Setting up data")
			secret := &v1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "my-secret"}, Data: map[string][]byte{"secret-key": []byte("secret-value")}}
			secret, err = f.ClientSet.CoreV1().Secrets(f.Namespace.Name).Create(secret)
			if err != nil && !apierrors.IsAlreadyExists(err) {
				Expect(err).ToNot(HaveOccurred())
			}

			configmap := &v1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Name: "my-configmap"}, Data: map[string]string{"configmap-key": "configmap-value"}}
			configmap, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Create(configmap)
			if err != nil && !apierrors.IsAlreadyExists(err) {
				Expect(err).ToNot(HaveOccurred())
			}
		})

		gracePeriod := int64(1)

		It("should support subpaths with secret pod", func() {
			pod := &v1.Pod{
				ObjectMeta: metav1.ObjectMeta{Name: "pod-subpath-test-secret"},
				Spec: v1.PodSpec{
					Containers: []v1.Container{{
						Name:         "test",
						Image:        mountImage,
						Args:         []string{"--file_content=" + volumePath},
						VolumeMounts: []v1.VolumeMount{{Name: "secret", MountPath: volumePath, SubPath: "secret-key"}},
					}},
					RestartPolicy:                 v1.RestartPolicyNever,
					TerminationGracePeriodSeconds: &gracePeriod,
					Volumes: []v1.Volume{{Name: "secret", VolumeSource: v1.VolumeSource{Secret: &v1.SecretVolumeSource{SecretName: "my-secret"}}}},
				},
			}
			By(fmt.Sprintf("Creating pod %s", pod.Name))
			f.TestContainerOutput("secret", pod, 0, []string{"secret-value"})
		})

		It("should support subpaths with configmap pod", func() {
			pod := &v1.Pod{
				ObjectMeta: metav1.ObjectMeta{Name: "pod-subpath-test-configmap"},
				Spec: v1.PodSpec{
					Containers: []v1.Container{{
						Name:         "test",
						Image:        mountImage,
						Args:         []string{"--file_content=" + volumePath},
						VolumeMounts: []v1.VolumeMount{{Name: "configmap", MountPath: volumePath, SubPath: "configmap-key"}},
					}},
					RestartPolicy:                 v1.RestartPolicyNever,
					TerminationGracePeriodSeconds: &gracePeriod,
					Volumes: []v1.Volume{{Name: "configmap", VolumeSource: v1.VolumeSource{ConfigMap: &v1.ConfigMapVolumeSource{LocalObjectReference: v1.LocalObjectReference{Name: "my-configmap"}}}}},
				},
			}
			By(fmt.Sprintf("Creating pod %s", pod.Name))
			f.TestContainerOutput("configmap", pod, 0, []string{"configmap-value"})
		})

		It("should support subpaths with downward pod", func() {
			pod := &v1.Pod{
				ObjectMeta: metav1.ObjectMeta{Name: "pod-subpath-test-downward"},
				Spec: v1.PodSpec{
					Containers: []v1.Container{{
						Name:         "test",
						Image:        mountImage,
						Args:         []string{"--file_content=" + volumePath},
						VolumeMounts: []v1.VolumeMount{{Name: "downward", MountPath: volumePath, SubPath: "downward/podname"}},
					}},
					RestartPolicy:                 v1.RestartPolicyNever,
					TerminationGracePeriodSeconds: &gracePeriod,
					Volumes: []v1.Volume{
						{Name: "downward", VolumeSource: v1.VolumeSource{
							DownwardAPI: &v1.DownwardAPIVolumeSource{
								Items: []v1.DownwardAPIVolumeFile{{Path: "downward/podname", FieldRef: &v1.ObjectFieldSelector{APIVersion: "v1", FieldPath: "metadata.name"}}},
							},
						}},
					},
				},
			}
			By(fmt.Sprintf("Creating pod %s", pod.Name))
			f.TestContainerOutput("downward", pod, 0, []string{"content of file \"" + volumePath + "\": " + pod.Name})
		})

		It("should support subpaths with projected pod", func() {
			pod := &v1.Pod{
				ObjectMeta: metav1.ObjectMeta{Name: "pod-subpath-test-secret"},
				Spec: v1.PodSpec{
					Containers: []v1.Container{{
						Name:         "test",
						Image:        mountImage,
						Args:         []string{"--file_content=" + volumePath},
						VolumeMounts: []v1.VolumeMount{{Name: "projected", MountPath: volumePath, SubPath: "projected/configmap-key"}},
					}},
					RestartPolicy:                 v1.RestartPolicyNever,
					TerminationGracePeriodSeconds: &gracePeriod,
					Volumes: []v1.Volume{
						{Name: "projected", VolumeSource: v1.VolumeSource{
							Projected: &v1.ProjectedVolumeSource{
								Sources: []v1.VolumeProjection{
									{ConfigMap: &v1.ConfigMapProjection{
										LocalObjectReference: v1.LocalObjectReference{Name: "my-configmap"},
										Items:                []v1.KeyToPath{{Path: "projected/configmap-key", Key: "configmap-key"}},
									}},
								},
							},
						}},
					},
				},
			}
			By(fmt.Sprintf("Creating pod %s", pod.Name))
			f.TestContainerOutput("projected", pod, 0, []string{"configmap-value"})
		})
	})

	for volType, volInit := range initVolSources {
{'fraction_non_alphanumeric': 0.1341150195421552, 'fraction_numerical': 0.012841987716359575, 'mean_word_length': 3.3623964929371652, 'pattern_counts': {'":': 19, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4093261', 'n_tokens_mistral': 3435, 'n_tokens_neox': 2988, 'n_words': 621}