Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: added check for snapshot and clone creation in e2e #206

Merged
merged 3 commits into from
Jul 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 163 additions & 38 deletions e2e/lvm/pvc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"time"

snapapi "github.com/kubernetes-csi/external-snapshotter/client/v4/apis/volumesnapshot/v1"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
tests "github.com/red-hat-storage/lvm-operator/e2e"
Expand All @@ -15,75 +16,199 @@ import (
const (
timeout = time.Minute * 5
interval = time.Second * 30
size = "5Gi"
)

// Test to verify the PVC status
func PVCTest() {

Describe("PVC Tests", func() {
var filepvc *k8sv1.PersistentVolumeClaim
var filepod *k8sv1.Pod
var blockpvc *k8sv1.PersistentVolumeClaim
var blockpod *k8sv1.Pod
var pvc *k8sv1.PersistentVolumeClaim
var pod *k8sv1.Pod
var snapshot *snapapi.VolumeSnapshot
var clonePvc *k8sv1.PersistentVolumeClaim
var clonePod *k8sv1.Pod
var restorePvc *k8sv1.PersistentVolumeClaim
var restorePod *k8sv1.Pod
client := tests.DeployManagerObj.GetCrClient()
ctx := context.TODO()

Context("create pvc, pod, snapshots, clones", func() {
It("Tests PVC operations for VolumeMode=file system", func() {
By("Creating pvc and pod")
pvc = tests.GetSamplePvc(size, "lvmfilepvc", k8sv1.PersistentVolumeFilesystem, tests.StorageClass, "", "")
pod = tests.GetSamplePod("lvmfilepod", pvc.Name)
err := client.Create(ctx, pvc)
Expect(err).To(BeNil())
err = client.Create(ctx, pod)
Expect(err).To(BeNil())

By("Verifying that the PVC(file system) is bound and the Pod is running")
Eventually(func() bool {
err := client.Get(ctx, types.NamespacedName{Name: pvc.Name, Namespace: pvc.Namespace}, pvc)
return err == nil && pvc.Status.Phase == k8sv1.ClaimBound
}, timeout, interval).Should(BeTrue())
fmt.Printf("PVC %s is bound\n", pvc.Name)

Eventually(func() bool {
err = client.Get(ctx, types.NamespacedName{Name: pod.Name, Namespace: pod.Namespace}, pod)
return err == nil && pod.Status.Phase == k8sv1.PodRunning
}, timeout, interval).Should(BeTrue())
fmt.Printf("Pod %s is running\n", pod.Name)

By("Creating a Snapshot of the file-pvc")
snapshot = tests.GetSampleVolumeSnapshot(pvc.Name+"-snapshot", pvc.Name, tests.StorageClass)
err = client.Create(ctx, snapshot)
Expect(err).To(BeNil())
fmt.Printf("Snapshot %s is created\n", snapshot.Name)

By("Creating a clone of the file-pvc")
clonePvc = tests.GetSamplePvc(size, pvc.Name+"-clone", k8sv1.PersistentVolumeFilesystem, tests.StorageClass, "PersistentVolumeClaim", pvc.Name)
err = client.Create(ctx, clonePvc)
Expect(err).To(BeNil())
fmt.Printf("Cloned PVC %s is created\n", clonePvc.Name)

clonePod = tests.GetSamplePod("clone-lvmfilepod", clonePvc.Name)
err = client.Create(ctx, clonePod)
Expect(err).To(BeNil())

Eventually(func() bool {
err := client.Get(ctx, types.NamespacedName{Name: clonePvc.Name, Namespace: clonePvc.Namespace}, clonePvc)
return err == nil && clonePvc.Status.Phase == k8sv1.ClaimBound
}, timeout, interval).Should(BeTrue())
fmt.Printf("Cloned PVC %s is bound\n", clonePvc.Name)

By("Restore Snapshot for file-pvc")
restorePvc = tests.GetSamplePvc(size, pvc.Name+"-restore", k8sv1.PersistentVolumeFilesystem, tests.StorageClass, "VolumeSnapshot", snapshot.Name)
err = client.Create(ctx, restorePvc)
Expect(err).To(BeNil())
fmt.Printf("Snapshot %s is restored\n", restorePvc.Name)

restorePod = tests.GetSamplePod("restore-lvmfilepod", restorePvc.Name)
err = client.Create(ctx, restorePod)
Expect(err).To(BeNil())

Eventually(func() bool {
err := client.Get(ctx, types.NamespacedName{Name: restorePvc.Name, Namespace: restorePvc.Namespace}, restorePvc)
return err == nil && restorePvc.Status.Phase == k8sv1.ClaimBound
}, timeout, interval).Should(BeTrue())
fmt.Printf("Restored PVC %s is bound\n", restorePvc.Name)

err = client.Delete(ctx, clonePod)
Expect(err).To(BeNil())
fmt.Printf("Pod %s is deleted\n", clonePod.Name)

Context("create pvc and pod", func() {
It("Verifies the status", func() {
By("Creates pvc and pod")
filepvc = tests.GetSamplePVC(tests.StorageClass, "5Gi", "lvmfilepvc", k8sv1.PersistentVolumeFilesystem)
filepod = tests.GetSamplePod("lvmfilepod", "lvmfilepvc")
err := tests.DeployManagerObj.GetCrClient().Create(context.TODO(), filepvc)
err = client.Delete(ctx, clonePvc)
Expect(err).To(BeNil())
err = tests.DeployManagerObj.GetCrClient().Create(context.TODO(), filepod)
fmt.Printf("Clone PVC %s is deleted\n", clonePvc.Name)

err = client.Delete(ctx, restorePod)
Expect(err).To(BeNil())
fmt.Printf("Pod %s is deleted\n", restorePod.Name)

err = client.Delete(ctx, restorePvc)
Expect(err).To(BeNil())
fmt.Printf("Restored Snapshot %s is deleted\n", restorePvc.Name)

blockpvc = tests.GetSamplePVC(tests.StorageClass, "5Gi", "lvmblockpvc", k8sv1.PersistentVolumeBlock)
blockpod = tests.GetSamplePod("lvmblockpod", "lvmblockpvc")
err = tests.DeployManagerObj.GetCrClient().Create(context.TODO(), blockpvc)
err = client.Delete(ctx, snapshot)
Expect(err).To(BeNil())
err = tests.DeployManagerObj.GetCrClient().Create(context.TODO(), blockpod)
fmt.Printf("Snapshot %s is deleted\n", snapshot.Name)

err = client.Delete(ctx, pod)
Expect(err).To(BeNil())
fmt.Printf("Pod %s is deleted\n", pod.Name)

err = client.Delete(ctx, pvc)
Expect(err).To(BeNil())
fmt.Printf("PVC %s is deleted\n", pvc.Name)
})

By("PVC(file system) Should be bound and Pod should be running")
It("Tests PVC operations for VolumeMode=Block", func() {
By("Creating pvc and pod")
pvc = tests.GetSamplePvc(size, "lvmblockpvc", k8sv1.PersistentVolumeBlock, tests.StorageClass, "", "")
pod = tests.GetSamplePod("lvmblockpod", pvc.Name)
err := client.Create(ctx, pvc)
Expect(err).To(BeNil())
err = client.Create(ctx, pod)
Expect(err).To(BeNil())

By("Verifying that the PVC(block) is bound and the Pod is running")
Eventually(func() bool {
err := tests.DeployManagerObj.GetCrClient().Get(context.TODO(), types.NamespacedName{Name: filepvc.Name, Namespace: filepvc.Namespace}, filepvc)
return err == nil && filepvc.Status.Phase == k8sv1.ClaimBound
err := client.Get(ctx, types.NamespacedName{Name: pvc.Name, Namespace: pvc.Namespace}, pvc)
return err == nil && pvc.Status.Phase == k8sv1.ClaimBound
}, timeout, interval).Should(BeTrue())
fmt.Printf("PVC %s is bound\n", filepvc.Name)
fmt.Printf("PVC %s is bound\n", pvc.Name)

Eventually(func() bool {
err = tests.DeployManagerObj.GetCrClient().Get(context.TODO(), types.NamespacedName{Name: filepod.Name, Namespace: filepod.Namespace}, filepod)
return err == nil && filepod.Status.Phase == k8sv1.PodRunning
err = client.Get(ctx, types.NamespacedName{Name: pod.Name, Namespace: pod.Namespace}, pod)
return err == nil && pod.Status.Phase == k8sv1.PodRunning
}, timeout, interval).Should(BeTrue())
fmt.Printf("Pod %s is running\n", filepod.Name)
fmt.Printf("Pod %s is running\n", pod.Name)

err = tests.DeployManagerObj.GetCrClient().Delete(context.TODO(), filepod)
By("Creating a Snapshot of the block-pvc")
snapshot = tests.GetSampleVolumeSnapshot(pvc.Name+"-snapshot", pvc.Name, tests.StorageClass)
err = client.Create(ctx, snapshot)
Expect(err).To(BeNil())
fmt.Printf("Pod %s is deleted\n", filepod.Name)
fmt.Printf("Snapshot %s is created\n", snapshot.Name)

err = tests.DeployManagerObj.GetCrClient().Delete(context.TODO(), filepvc)
By("Creating a clone of the block-pvc")
clonePvc = tests.GetSamplePvc(size, pvc.Name+"-clone", k8sv1.PersistentVolumeBlock, tests.StorageClass, "PersistentVolumeClaim", pvc.Name)
err = client.Create(ctx, clonePvc)
Expect(err).To(BeNil())
fmt.Printf("Cloned PVC %s is created\n", clonePvc.Name)

clonePod = tests.GetSamplePod("clone-lvmblockpod", clonePvc.Name)
err = client.Create(ctx, clonePod)
Expect(err).To(BeNil())
fmt.Printf("PVC %s is deleted\n", filepvc.Name)

By("PVC(block) Should be bound and Pod should be running")
Eventually(func() bool {
err := tests.DeployManagerObj.GetCrClient().Get(context.TODO(), types.NamespacedName{Name: blockpvc.Name, Namespace: blockpvc.Namespace}, blockpvc)
return err == nil && blockpvc.Status.Phase == k8sv1.ClaimBound
err := client.Get(ctx, types.NamespacedName{Name: clonePvc.Name, Namespace: clonePvc.Namespace}, clonePvc)
return err == nil && clonePvc.Status.Phase == k8sv1.ClaimBound
}, timeout, interval).Should(BeTrue())
fmt.Printf("PVC %s is bound\n", blockpvc.Name)
fmt.Printf("Cloned PVC %s is bound\n", clonePvc.Name)

By("Restore Snapshot for block-pvc")
restorePvc = tests.GetSamplePvc(size, pvc.Name+"-restore", k8sv1.PersistentVolumeBlock, tests.StorageClass, "VolumeSnapshot", snapshot.Name)
err = client.Create(ctx, restorePvc)
Expect(err).To(BeNil())
fmt.Printf("Snapshot %s is restored\n", restorePvc.Name)

restorePod = tests.GetSamplePod("restore-lvmblockpod", restorePvc.Name)
err = client.Create(ctx, restorePod)
Expect(err).To(BeNil())

Eventually(func() bool {
err = tests.DeployManagerObj.GetCrClient().Get(context.TODO(), types.NamespacedName{Name: blockpod.Name, Namespace: blockpod.Namespace}, blockpod)
return err == nil && blockpod.Status.Phase == k8sv1.PodRunning
err := client.Get(ctx, types.NamespacedName{Name: restorePvc.Name, Namespace: restorePvc.Namespace}, restorePvc)
return err == nil && restorePvc.Status.Phase == k8sv1.ClaimBound
}, timeout, interval).Should(BeTrue())
fmt.Printf("Pod %s is running\n", blockpod.Name)
fmt.Printf("Restored PVC %s is bound\n", restorePod.Name)

err = client.Delete(ctx, clonePod)
Expect(err).To(BeNil())
fmt.Printf("Pod %s is deleted\n", clonePod.Name)

err = client.Delete(ctx, clonePvc)
Expect(err).To(BeNil())
fmt.Printf("Clone PVC %s is deleted\n", clonePvc.Name)

err = client.Delete(ctx, restorePod)
Expect(err).To(BeNil())
fmt.Printf("Pod %s is deleted\n", restorePod.Name)

err = client.Delete(ctx, restorePvc)
Expect(err).To(BeNil())
fmt.Printf("Restored Snapshot %s is deleted\n", restorePvc.Name)

err = client.Delete(ctx, snapshot)
Expect(err).To(BeNil())
fmt.Printf("Snapshot %s is deleted\n", snapshot.Name)

err = tests.DeployManagerObj.GetCrClient().Delete(context.TODO(), blockpod)
err = client.Delete(ctx, pod)
Expect(err).To(BeNil())
fmt.Printf("Pod %s is deleted\n", blockpod.Name)
fmt.Printf("Pod %s is deleted\n", pod.Name)

err = tests.DeployManagerObj.GetCrClient().Delete(context.TODO(), blockpvc)
err = client.Delete(ctx, pvc)
Expect(err).To(BeNil())
fmt.Printf("PVC %s is deleted\n", blockpvc.Name)
fmt.Printf("PVC %s is deleted\n", pvc.Name)
})
})

Expand Down
75 changes: 55 additions & 20 deletions e2e/testdata.go
Original file line number Diff line number Diff line change
@@ -1,31 +1,13 @@
package e2e

import (
snapapi "github.com/kubernetes-csi/external-snapshotter/client/v4/apis/volumesnapshot/v1"
k8sv1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// GetSamplePVC returns a sample pvc.
func GetSamplePVC(storageClass, quantity, name string, volumemode k8sv1.PersistentVolumeMode) *k8sv1.PersistentVolumeClaim {
pvc := &k8sv1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: TestNamespace,
},
Spec: k8sv1.PersistentVolumeClaimSpec{
StorageClassName: &storageClass,
AccessModes: []k8sv1.PersistentVolumeAccessMode{k8sv1.ReadWriteOnce},
VolumeMode: &volumemode,
Resources: k8sv1.ResourceRequirements{
Requests: k8sv1.ResourceList{
k8sv1.ResourceStorage: resource.MustParse(quantity),
},
},
},
}
return pvc
}
var snapAPIGroup = "snapshot.storage.k8s.io"

// GetSamplePod returns a sample pod.
func GetSamplePod(name, pvcName string) *k8sv1.Pod {
Expand Down Expand Up @@ -61,3 +43,56 @@ func GetSamplePod(name, pvcName string) *k8sv1.Pod {
}
return pod
}

// GetSampleVolumeSnapshot creates and returns the VolumeSnapshot for the provided PVC.
func GetSampleVolumeSnapshot(snapshotName, sourceName string, storageClass string) *snapapi.VolumeSnapshot {
vs := &snapapi.VolumeSnapshot{
ObjectMeta: metav1.ObjectMeta{
Name: snapshotName,
Namespace: TestNamespace,
},
Spec: snapapi.VolumeSnapshotSpec{
VolumeSnapshotClassName: &storageClass,
Source: snapapi.VolumeSnapshotSource{
PersistentVolumeClaimName: &sourceName,
},
},
}
return vs
}

// GetSamplePvc returns restore or clone of the pvc based on the kind provided.
func GetSamplePvc(size, name string, volumemode k8sv1.PersistentVolumeMode, storageClass string, sourceType, sourceName string) *k8sv1.PersistentVolumeClaim {
pvc := &k8sv1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: TestNamespace,
},
Spec: k8sv1.PersistentVolumeClaimSpec{
StorageClassName: &storageClass,
AccessModes: []k8sv1.PersistentVolumeAccessMode{k8sv1.ReadWriteOnce},
VolumeMode: &volumemode,
Resources: k8sv1.ResourceRequirements{
Requests: k8sv1.ResourceList{
k8sv1.ResourceStorage: resource.MustParse(size),
},
},
},
}
if sourceType != "" && sourceName != "" {
if sourceType == "VolumeSnapshot" {
pvc.Spec.DataSource = &k8sv1.TypedLocalObjectReference{
Name: sourceName,
Kind: sourceType,
APIGroup: &snapAPIGroup,
}
} else {
pvc.Spec.DataSource = &k8sv1.TypedLocalObjectReference{
Name: sourceName,
Kind: sourceType,
}
}

}
return pvc
}