1
16
17 package storage
18
19 import (
20 "context"
21
22 "github.com/onsi/ginkgo/v2"
23 "github.com/onsi/gomega"
24
25 v1 "k8s.io/api/core/v1"
26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27 clientset "k8s.io/client-go/kubernetes"
28 "k8s.io/kubernetes/test/e2e/framework"
29 e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
30 e2epv "k8s.io/kubernetes/test/e2e/framework/pv"
31 e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper"
32 "k8s.io/kubernetes/test/e2e/storage/testsuites"
33 "k8s.io/kubernetes/test/e2e/storage/utils"
34 admissionapi "k8s.io/pod-security-admission/api"
35 )
36
37 var _ = utils.SIGDescribe("GenericPersistentVolume", framework.WithDisruptive(), func() {
38 f := framework.NewDefaultFramework("generic-disruptive-pv")
39 f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged
40 var (
41 c clientset.Interface
42 ns string
43 )
44
45 ginkgo.BeforeEach(func() {
46
47 e2eskipper.SkipUnlessNodeCountIsAtLeast(2)
48 e2eskipper.SkipIfProviderIs("local")
49 c = f.ClientSet
50 ns = f.Namespace.Name
51 })
52 disruptiveTestTable := []disruptiveTest{
53 {
54 testItStmt: "Should test that a file written to the mount before kubelet restart is readable after restart.",
55 runTest: utils.TestKubeletRestartsAndRestoresMount,
56 },
57 {
58 testItStmt: "Should test that a volume mounted to a pod that is deleted while the kubelet is down unmounts when the kubelet returns.",
59 runTest: utils.TestVolumeUnmountsFromDeletedPod,
60 },
61 {
62 testItStmt: "Should test that a volume mounted to a pod that is force deleted while the kubelet is down unmounts when the kubelet returns.",
63 runTest: utils.TestVolumeUnmountsFromForceDeletedPod,
64 },
65 }
66
67 ginkgo.Context("When kubelet restarts", func() {
68
69
70
71 var (
72 clientPod *v1.Pod
73 pvc *v1.PersistentVolumeClaim
74 pv *v1.PersistentVolume
75 )
76 ginkgo.BeforeEach(func(ctx context.Context) {
77 e2epv.SkipIfNoDefaultStorageClass(ctx, c)
78 framework.Logf("Initializing pod and pvcs for test")
79 clientPod, pvc, pv = createPodPVCFromSC(ctx, f, c, ns)
80 })
81 for _, test := range disruptiveTestTable {
82 func(t disruptiveTest) {
83 ginkgo.It(t.testItStmt, func(ctx context.Context) {
84 e2eskipper.SkipUnlessSSHKeyPresent()
85 ginkgo.By("Executing Spec")
86 t.runTest(ctx, c, f, clientPod, e2epod.VolumeMountPath1)
87 })
88 }(test)
89 }
90 ginkgo.AfterEach(func(ctx context.Context) {
91 framework.Logf("Tearing down test spec")
92 tearDownTestCase(ctx, c, f, ns, clientPod, pvc, pv, false)
93 pvc, clientPod = nil, nil
94 })
95 })
96 })
97
98 func createPodPVCFromSC(ctx context.Context, f *framework.Framework, c clientset.Interface, ns string) (*v1.Pod, *v1.PersistentVolumeClaim, *v1.PersistentVolume) {
99 var err error
100 test := testsuites.StorageClassTest{
101 Name: "default",
102 Timeouts: f.Timeouts,
103 ClaimSize: "2Gi",
104 }
105 pvc := e2epv.MakePersistentVolumeClaim(e2epv.PersistentVolumeClaimConfig{
106 ClaimSize: test.ClaimSize,
107 VolumeMode: &test.VolumeMode,
108 }, ns)
109 pvc, err = c.CoreV1().PersistentVolumeClaims(pvc.Namespace).Create(ctx, pvc, metav1.CreateOptions{})
110 framework.ExpectNoError(err, "Error creating pvc")
111 pvcClaims := []*v1.PersistentVolumeClaim{pvc}
112 pvs, err := e2epv.WaitForPVClaimBoundPhase(ctx, c, pvcClaims, framework.ClaimProvisionTimeout)
113 framework.ExpectNoError(err, "Failed waiting for PVC to be bound %v", err)
114 gomega.Expect(pvs).To(gomega.HaveLen(1))
115
116 ginkgo.By("Creating a pod with dynamically provisioned volume")
117 podConfig := e2epod.Config{
118 NS: ns,
119 PVCs: pvcClaims,
120 SeLinuxLabel: e2epv.SELinuxLabel,
121 }
122 pod, err := e2epod.CreateSecPod(ctx, c, &podConfig, f.Timeouts.PodStart)
123 framework.ExpectNoError(err, "While creating pods for kubelet restart test")
124 return pod, pvc, pvs[0]
125 }
126
View as plain text