From 913f626adb6bc5925fa65fc58044ef4b8cbce2bf Mon Sep 17 00:00:00 2001 From: Andi Li Date: Wed, 8 Jul 2020 16:33:55 +0000 Subject: [PATCH] Add data semantics test for volume snapshots The test steps are as follows: 1. Write some data 2. Take a snapshot 3. Write more data 4. Create a new volume from snapshot 5. Validate data is the old data --- test/e2e/storage/testsuites/snapshottable.go | 47 ++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/test/e2e/storage/testsuites/snapshottable.go b/test/e2e/storage/testsuites/snapshottable.go index b3765ff3198..efac710b55c 100644 --- a/test/e2e/storage/testsuites/snapshottable.go +++ b/test/e2e/storage/testsuites/snapshottable.go @@ -33,6 +33,7 @@ import ( "k8s.io/client-go/dynamic" clientset "k8s.io/client-go/kubernetes" "k8s.io/kubernetes/test/e2e/framework" + e2epod "k8s.io/kubernetes/test/e2e/framework/pod" e2epv "k8s.io/kubernetes/test/e2e/framework/pv" e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper" e2evolume "k8s.io/kubernetes/test/e2e/framework/volume" @@ -236,7 +237,53 @@ func (s *snapshottableTestSuite) DefineTests(driver TestDriver, pattern testpatt framework.ExpectEqual(volumeSnapshotRef["name"], vs.GetName()) framework.ExpectEqual(volumeSnapshotRef["namespace"], vs.GetNamespace()) }) + ginkgo.It("should restore from snapshot with saved data after modifying source data", func() { + var restoredPVC *v1.PersistentVolumeClaim + var restoredPod *v1.Pod + ginkgo.By("modifying the data in the source PVC") + command := "echo junkdata > /mnt/test/data" + RunInPodWithVolume(cs, pvc.Namespace, pvc.Name, "pvc-snapshottable-data-tester", command, config.ClientNodeSelection) + + ginkgo.By("creating a pvc from the snapshot") + restoredPVC = e2epv.MakePersistentVolumeClaim(e2epv.PersistentVolumeClaimConfig{ + ClaimSize: claimSize, + StorageClassName: &(sc.Name), + }, config.Framework.Namespace.Name) + + group := "snapshot.storage.k8s.io" + dataSourceRef := &v1.TypedLocalObjectReference{ + APIGroup: &group, + Kind: "VolumeSnapshot", + Name: vs.GetName(), + } + + restoredPVC.Spec.DataSource = dataSourceRef + + restoredPVC, err = cs.CoreV1().PersistentVolumeClaims(restoredPVC.Namespace).Create(context.TODO(), restoredPVC, metav1.CreateOptions{}) + framework.ExpectNoError(err) + cleanupSteps = append(cleanupSteps, func() { + framework.Logf("deleting claim %q/%q", restoredPVC.Namespace, restoredPVC.Name) + // typically this claim has already been deleted + err = cs.CoreV1().PersistentVolumeClaims(restoredPVC.Namespace).Delete(context.TODO(), restoredPVC.Name, metav1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + framework.Failf("Error deleting claim %q. Error: %v", restoredPVC.Name, err) + } + }) + + ginkgo.By("starting a pod to use the claim") + + restoredPod = StartInPodWithVolume(cs, restoredPVC.Namespace, restoredPVC.Name, "restored-pvc-tester", "sleep 300", config.ClientNodeSelection) + framework.ExpectNoError(e2epod.WaitForPodRunningInNamespaceSlow(cs, restoredPod.Name, restoredPod.Namespace)) + cleanupSteps = append(cleanupSteps, func() { + StopPod(cs, restoredPod) + }) + + command = "cat /mnt/test/data" + actualData, err := utils.PodExec(f, restoredPod, command) + framework.ExpectNoError(err) + framework.ExpectEqual(actualData, "hello world") + }) }) }) }