Add e2e test for PV protection

This commit is contained in:
NickrenREN 2018-01-31 13:33:16 +08:00
parent d3b783d5ec
commit 3f6d2c8199
5 changed files with 152 additions and 9 deletions

View File

@ -182,7 +182,7 @@ func DeletePVCandValidatePV(c clientset.Interface, ns string, pvc *v1.Persistent
// Wait for the PV's phase to return to be `expectPVPhase` // Wait for the PV's phase to return to be `expectPVPhase`
Logf("Waiting for reclaim process to complete.") Logf("Waiting for reclaim process to complete.")
err = WaitForPersistentVolumePhase(expectPVPhase, c, pv.Name, 1*time.Second, 300*time.Second) err = WaitForPersistentVolumePhase(expectPVPhase, c, pv.Name, Poll, PVReclaimingTimeout)
if err != nil { if err != nil {
return fmt.Errorf("pv %q phase did not become %v: %v", pv.Name, expectPVPhase, err) return fmt.Errorf("pv %q phase did not become %v: %v", pv.Name, expectPVPhase, err)
} }
@ -392,14 +392,14 @@ func CreatePVsPVCs(numpvs, numpvcs int, c clientset.Interface, ns string, pvConf
func WaitOnPVandPVC(c clientset.Interface, ns string, pv *v1.PersistentVolume, pvc *v1.PersistentVolumeClaim) error { func WaitOnPVandPVC(c clientset.Interface, ns string, pv *v1.PersistentVolume, pvc *v1.PersistentVolumeClaim) error {
// Wait for newly created PVC to bind to the PV // Wait for newly created PVC to bind to the PV
Logf("Waiting for PV %v to bind to PVC %v", pv.Name, pvc.Name) Logf("Waiting for PV %v to bind to PVC %v", pv.Name, pvc.Name)
err := WaitForPersistentVolumeClaimPhase(v1.ClaimBound, c, ns, pvc.Name, 3*time.Second, 300*time.Second) err := WaitForPersistentVolumeClaimPhase(v1.ClaimBound, c, ns, pvc.Name, Poll, ClaimBindingTimeout)
if err != nil { if err != nil {
return fmt.Errorf("PVC %q did not become Bound: %v", pvc.Name, err) return fmt.Errorf("PVC %q did not become Bound: %v", pvc.Name, err)
} }
// Wait for PersistentVolume.Status.Phase to be Bound, which it should be // Wait for PersistentVolume.Status.Phase to be Bound, which it should be
// since the PVC is already bound. // since the PVC is already bound.
err = WaitForPersistentVolumePhase(v1.VolumeBound, c, pv.Name, 3*time.Second, 300*time.Second) err = WaitForPersistentVolumePhase(v1.VolumeBound, c, pv.Name, Poll, PVBindingTimeout)
if err != nil { if err != nil {
return fmt.Errorf("PV %q did not become Bound: %v", pv.Name, err) return fmt.Errorf("PV %q did not become Bound: %v", pv.Name, err)
} }
@ -445,7 +445,7 @@ func WaitAndVerifyBinds(c clientset.Interface, ns string, pvols PVMap, claims PV
} }
for pvName := range pvols { for pvName := range pvols {
err := WaitForPersistentVolumePhase(v1.VolumeBound, c, pvName, 3*time.Second, 180*time.Second) err := WaitForPersistentVolumePhase(v1.VolumeBound, c, pvName, Poll, PVBindingTimeout)
if err != nil && len(pvols) > len(claims) { if err != nil && len(pvols) > len(claims) {
Logf("WARN: pv %v is not bound after max wait", pvName) Logf("WARN: pv %v is not bound after max wait", pvName)
Logf(" This may be ok since there are more pvs than pvcs") Logf(" This may be ok since there are more pvs than pvcs")
@ -468,7 +468,7 @@ func WaitAndVerifyBinds(c clientset.Interface, ns string, pvols PVMap, claims PV
return fmt.Errorf("internal: claims map is missing pvc %q", pvcKey) return fmt.Errorf("internal: claims map is missing pvc %q", pvcKey)
} }
err := WaitForPersistentVolumeClaimPhase(v1.ClaimBound, c, ns, cr.Name, 3*time.Second, 180*time.Second) err := WaitForPersistentVolumeClaimPhase(v1.ClaimBound, c, ns, cr.Name, Poll, ClaimBindingTimeout)
if err != nil { if err != nil {
return fmt.Errorf("PVC %q did not become Bound: %v", cr.Name, err) return fmt.Errorf("PVC %q did not become Bound: %v", cr.Name, err)
} }

View File

@ -154,6 +154,21 @@ const (
// How long claims have to become dynamically provisioned // How long claims have to become dynamically provisioned
ClaimProvisionTimeout = 5 * time.Minute ClaimProvisionTimeout = 5 * time.Minute
// How long claims have to become bound
ClaimBindingTimeout = 3 * time.Minute
// How long claims have to become deleted
ClaimDeletingTimeout = 3 * time.Minute
// How long PVs have to beome reclaimed
PVReclaimingTimeout = 3 * time.Minute
// How long PVs have to become bound
PVBindingTimeout = 3 * time.Minute
// How long PVs have to become deleted
PVDeletingTimeout = 3 * time.Minute
// How long a node is allowed to become "Ready" after it is restarted before // How long a node is allowed to become "Ready" after it is restarted before
// the test is considered failed. // the test is considered failed.
RestartNodeReadyAgainTimeout = 5 * time.Minute RestartNodeReadyAgainTimeout = 5 * time.Minute

View File

@ -17,6 +17,7 @@ go_library(
"persistent_volumes-disruptive.go", "persistent_volumes-disruptive.go",
"persistent_volumes-gce.go", "persistent_volumes-gce.go",
"persistent_volumes-local.go", "persistent_volumes-local.go",
"pv_protection.go",
"pvc_protection.go", "pvc_protection.go",
"volume_expand.go", "volume_expand.go",
"volume_io.go", "volume_io.go",

View File

@ -0,0 +1,127 @@
/*
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 (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
clientset "k8s.io/client-go/kubernetes"
"k8s.io/kubernetes/pkg/util/slice"
volumeutil "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/test/e2e/framework"
"k8s.io/kubernetes/test/e2e/storage/utils"
)
var _ = utils.SIGDescribe("PV Protection [Feature:StorageProtection]", func() {
var (
client clientset.Interface
nameSpace string
err error
pvc *v1.PersistentVolumeClaim
pv *v1.PersistentVolume
pvConfig framework.PersistentVolumeConfig
pvcConfig framework.PersistentVolumeClaimConfig
volLabel labels.Set
selector *metav1.LabelSelector
)
f := framework.NewDefaultFramework("pv-protection")
BeforeEach(func() {
client = f.ClientSet
nameSpace = f.Namespace.Name
framework.ExpectNoError(framework.WaitForAllNodesSchedulable(client, framework.TestContext.NodeSchedulableTimeout))
// Enforce binding only within test space via selector labels
volLabel = labels.Set{framework.VolumeSelectorKey: nameSpace}
selector = metav1.SetAsLabelSelector(volLabel)
pvConfig = framework.PersistentVolumeConfig{
NamePrefix: "hostpath-",
Labels: volLabel,
PVSource: v1.PersistentVolumeSource{
HostPath: &v1.HostPathVolumeSource{
Path: "/tmp/data",
},
},
}
pvcConfig = framework.PersistentVolumeClaimConfig{
Annotations: map[string]string{
v1.BetaStorageClassAnnotation: "",
},
Selector: selector,
}
By("Creating a PV")
// make the pv definitions
pv = framework.MakePersistentVolume(pvConfig)
// create the PV
pv, err = client.CoreV1().PersistentVolumes().Create(pv)
Expect(err).NotTo(HaveOccurred(), "Error creating PV")
By("Checking that PV Protection finalizer is set")
pv, err = client.CoreV1().PersistentVolumes().Get(pv.Name, metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred(), "While getting PV status")
Expect(slice.ContainsString(pv.ObjectMeta.Finalizers, volumeutil.PVProtectionFinalizer, nil)).To(BeTrue())
})
AfterEach(func() {
framework.Logf("AfterEach: Cleaning up test resources.")
if errs := framework.PVPVCCleanup(client, nameSpace, pv, pvc); len(errs) > 0 {
framework.Failf("AfterEach: Failed to delete PVC and/or PV. Errors: %v", utilerrors.NewAggregate(errs))
}
})
It("Verify \"immediate\" deletion of a PV that is not bound to a PVC", func() {
By("Deleting the PV")
err = client.CoreV1().PersistentVolumes().Delete(pv.Name, metav1.NewDeleteOptions(0))
Expect(err).NotTo(HaveOccurred(), "Error deleting PV")
framework.WaitForPersistentVolumeDeleted(client, pv.Name, framework.Poll, framework.PVDeletingTimeout)
})
It("Verify that PV bound to a PVC is not removed immediately", func() {
By("Creating a PVC")
pvc = framework.MakePersistentVolumeClaim(pvcConfig, nameSpace)
pvc, err = client.CoreV1().PersistentVolumeClaims(pvc.Namespace).Create(pvc)
Expect(err).NotTo(HaveOccurred(), "Error creating PVC")
By("Waiting for PVC to become Bound")
err = framework.WaitForPersistentVolumeClaimPhase(v1.ClaimBound, client, nameSpace, pvc.Name, framework.Poll, framework.ClaimBindingTimeout)
Expect(err).NotTo(HaveOccurred(), "Failed waiting for PVC to be bound %v", err)
By("Deleting the PV, however, the PV must not be removed from the system as it's bound to a PVC")
err = client.CoreV1().PersistentVolumes().Delete(pv.Name, metav1.NewDeleteOptions(0))
Expect(err).NotTo(HaveOccurred(), "Error deleting PV")
By("Checking that the PV status is Terminating")
pv, err = client.CoreV1().PersistentVolumes().Get(pv.Name, metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred(), "While checking PV status")
Expect(pv.ObjectMeta.DeletionTimestamp).NotTo(Equal(nil))
By("Deleting the PVC that is bound to the PV")
err = client.CoreV1().PersistentVolumeClaims(pvc.Namespace).Delete(pvc.Name, metav1.NewDeleteOptions(0))
Expect(err).NotTo(HaveOccurred(), "Error deleting PVC")
By("Checking that the PV is automatically removed from the system because it's no longer bound to a PVC")
framework.WaitForPersistentVolumeDeleted(client, pv.Name, framework.Poll, framework.PVDeletingTimeout)
})
})

View File

@ -57,7 +57,7 @@ var _ = utils.SIGDescribe("PVC Protection [Feature:StorageProtection]", func() {
pvcCreatedAndNotDeleted = true pvcCreatedAndNotDeleted = true
By("Waiting for PVC to become Bound") By("Waiting for PVC to become Bound")
err = framework.WaitForPersistentVolumeClaimPhase(v1.ClaimBound, client, nameSpace, pvc.Name, framework.Poll, framework.ClaimProvisionTimeout) err = framework.WaitForPersistentVolumeClaimPhase(v1.ClaimBound, client, nameSpace, pvc.Name, framework.Poll, framework.ClaimBindingTimeout)
Expect(err).NotTo(HaveOccurred(), "Failed waiting for PVC to be bound %v", err) Expect(err).NotTo(HaveOccurred(), "Failed waiting for PVC to be bound %v", err)
By("Checking that PVC Protection finalizer is set") By("Checking that PVC Protection finalizer is set")
@ -76,7 +76,7 @@ var _ = utils.SIGDescribe("PVC Protection [Feature:StorageProtection]", func() {
By("Deleting the PVC") By("Deleting the PVC")
err = client.CoreV1().PersistentVolumeClaims(pvc.Namespace).Delete(pvc.Name, metav1.NewDeleteOptions(0)) err = client.CoreV1().PersistentVolumeClaims(pvc.Namespace).Delete(pvc.Name, metav1.NewDeleteOptions(0))
Expect(err).NotTo(HaveOccurred(), "Error deleting PVC") Expect(err).NotTo(HaveOccurred(), "Error deleting PVC")
framework.WaitForPersistentVolumeClaimDeleted(client, pvc.Namespace, pvc.Name, framework.Poll, framework.ClaimProvisionTimeout) framework.WaitForPersistentVolumeClaimDeleted(client, pvc.Namespace, pvc.Name, framework.Poll, framework.ClaimDeletingTimeout)
pvcCreatedAndNotDeleted = false pvcCreatedAndNotDeleted = false
}) })
@ -100,7 +100,7 @@ var _ = utils.SIGDescribe("PVC Protection [Feature:StorageProtection]", func() {
Expect(err).NotTo(HaveOccurred(), "Error terminating and deleting pod") Expect(err).NotTo(HaveOccurred(), "Error terminating and deleting pod")
By("Checking that the PVC is automatically removed from the system because it's no longer in active use by a pod") By("Checking that the PVC is automatically removed from the system because it's no longer in active use by a pod")
framework.WaitForPersistentVolumeClaimDeleted(client, pvc.Namespace, pvc.Name, framework.Poll, framework.ClaimProvisionTimeout) framework.WaitForPersistentVolumeClaimDeleted(client, pvc.Namespace, pvc.Name, framework.Poll, framework.ClaimDeletingTimeout)
pvcCreatedAndNotDeleted = false pvcCreatedAndNotDeleted = false
}) })
@ -137,7 +137,7 @@ var _ = utils.SIGDescribe("PVC Protection [Feature:StorageProtection]", func() {
Expect(err).NotTo(HaveOccurred(), "Error terminating and deleting pod") Expect(err).NotTo(HaveOccurred(), "Error terminating and deleting pod")
By("Checking that the PVC is automatically removed from the system because it's no longer in active use by a pod") By("Checking that the PVC is automatically removed from the system because it's no longer in active use by a pod")
framework.WaitForPersistentVolumeClaimDeleted(client, pvc.Namespace, pvc.Name, framework.Poll, framework.ClaimProvisionTimeout) framework.WaitForPersistentVolumeClaimDeleted(client, pvc.Namespace, pvc.Name, framework.Poll, framework.ClaimDeletingTimeout)
pvcCreatedAndNotDeleted = false pvcCreatedAndNotDeleted = false
}) })
}) })