diff --git a/go.mod b/go.mod index 21f3eaf2c..8daea7ffb 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.12 require ( github.com/PuerkitoBio/purell v1.1.1 // indirect - github.com/appscode/go v0.0.0-20191016085057-e186b6c94a3b + github.com/appscode/go v0.0.0-20191025021232-311ac347b3ef github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2 github.com/cenkalti/backoff v2.1.1+incompatible github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 @@ -26,7 +26,7 @@ require ( github.com/spf13/cobra v0.0.5 github.com/spf13/pflag v1.0.3 github.com/stretchr/testify v1.3.0 - gomodules.xyz/cert v1.0.0 + gomodules.xyz/cert v1.0.1 gomodules.xyz/envsubst v0.1.0 gomodules.xyz/stow v0.2.2 gopkg.in/ini.v1 v1.41.0 diff --git a/go.sum b/go.sum index fa0f138e6..3af219412 100644 --- a/go.sum +++ b/go.sum @@ -38,8 +38,9 @@ github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb github.com/appscode/docker-registry-client v0.0.0-20180426150142-1bb02bb202b0/go.mod h1:W9bsWfSbgJXUXzBZ+tSBV2g+zzT7ANPHQFsSXRHYKsA= github.com/appscode/go v0.0.0-20190808133642-1d4ef1f1c1e0/go.mod h1:iy07dV61Z7QQdCKJCIvUoDL21u6AIceRhZzyleh2ymc= github.com/appscode/go v0.0.0-20191006073906-e3d193d493fc/go.mod h1:hUW7Fq0KY2/ntGnYAzemyUpIhLL6bXrTljN6SRY/+Lc= -github.com/appscode/go v0.0.0-20191016085057-e186b6c94a3b h1:UskbETXW8u0DRCPU1pyBIgA55BFUnjuYjmt3qOBMdAY= github.com/appscode/go v0.0.0-20191016085057-e186b6c94a3b/go.mod h1:hUW7Fq0KY2/ntGnYAzemyUpIhLL6bXrTljN6SRY/+Lc= +github.com/appscode/go v0.0.0-20191025021232-311ac347b3ef h1:nTbtvdVAVwFgKANCR4KU36Jo1V9Xs/Z2GMEAlpOVG1Y= +github.com/appscode/go v0.0.0-20191025021232-311ac347b3ef/go.mod h1:hUW7Fq0KY2/ntGnYAzemyUpIhLL6bXrTljN6SRY/+Lc= github.com/appscode/osm v0.12.0 h1:7Rde+KnOp3EvHscXHS6rfdqiq6IO/2HZ2pKeE4f/sRo= github.com/appscode/osm v0.12.0/go.mod h1:+ZXU2HilSSow2o0gsOolJfOTkhqQ2FcGROOum4wEh4w= github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2 h1:7Ip0wMmLHLRJdrloDxZfhMm0xrLXZS8+COSu2bXmEQs= @@ -410,8 +411,8 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -gomodules.xyz/cert v1.0.0 h1:9vcN2V4g9Ol8LGqHd0FWSO0N8SjIbFLombfVk8Js22o= -gomodules.xyz/cert v1.0.0/go.mod h1:MG5H3SxZdkG8nng6QuQhXMTs+qt/qDLNXgUtbme82hQ= +gomodules.xyz/cert v1.0.1 h1:rowTfCHIKfcItwYurd1LYEmeMg9Svt4n5HWaoNS2HkE= +gomodules.xyz/cert v1.0.1/go.mod h1:DBLsvMRZSqek9FyAX/wVtUWkO6muPoWIvSlqGtrjGWg= gomodules.xyz/envsubst v0.1.0 h1:xvS0A4NeRwa8y3qW/+jgc13nT3rW1nlcuePDJujHzBM= gomodules.xyz/envsubst v0.1.0/go.mod h1:2o5f7bd13XIITbE2ZKieE05YkqB2KDoZkqKccGebduA= gomodules.xyz/jsonpatch/v2 v2.0.0 h1:OyHbl+7IOECpPKfVK42oFr6N7+Y2dR+Jsb/IiDV3hOo= diff --git a/test/e2e/auto-backup/daemonset.go b/test/e2e/auto-backup/daemonset.go new file mode 100644 index 000000000..6dbfb49ce --- /dev/null +++ b/test/e2e/auto-backup/daemonset.go @@ -0,0 +1,215 @@ +package auto_backup + +import ( + "fmt" + + "stash.appscode.dev/stash/apis" + "stash.appscode.dev/stash/apis/stash/v1alpha1" + "stash.appscode.dev/stash/apis/stash/v1beta1" + "stash.appscode.dev/stash/pkg/eventer" + "stash.appscode.dev/stash/test/e2e/framework" + "stash.appscode.dev/stash/test/e2e/matcher" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + store "kmodules.xyz/objectstore-api/api/v1" +) + +var _ = Describe("Auto-Backup", func() { + + var f *framework.Invocation + + BeforeEach(func() { + f = framework.NewInvocation() + }) + + AfterEach(func() { + err := f.CleanupTestResources() + Expect(err).NotTo(HaveOccurred()) + }) + + annotations := func(backupBlueprintName string) map[string]string { + return map[string]string{ + v1beta1.KeyBackupBlueprint: backupBlueprintName, + v1beta1.KeyTargetPaths: framework.TestSourceDataTargetPath, + v1beta1.KeyVolumeMounts: framework.TestSourceDataVolumeMount, + } + } + + Context("DaemonSet", func() { + + Context("Success Case", func() { + + It("should backup successfully", func() { + // Create BackupBlueprint + bb, err := f.CreateBackupBlueprintForWorkload(fmt.Sprintf("backupblueprint-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a DaemonSet + dmn, err := f.DeployDaemonSet(fmt.Sprintf("dmn-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(dmn.ObjectMeta, apis.KindDaemonSet) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(bb.Name), dmn) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(dmn.ObjectMeta, apis.KindDaemonSet) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has succeeded") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) + }) + }) + + Context("Failure Case", func() { + + Context("Missing AutoBackup resource credential in BackupBlueprint", func() { + It("should fail BackupSession for missing backend repository credential", func() { + // Create Secret for BackupBlueprint + secret, err := f.CreateBackendSecretForMinio() + Expect(err).NotTo(HaveOccurred()) + + // Generate BackupBlueprint definition + bb := f.BackupBlueprint(secret.Name) + bb.Spec.Backend.S3 = &store.S3Spec{} + By(fmt.Sprintf("Creating BackupBlueprint: %s", bb.Name)) + _, err = f.CreateBackupBlueprint(bb) + Expect(err).NotTo(HaveOccurred()) + f.AppendToCleanupList(bb) + + // Deploy a DaemonSet + dmn, err := f.DeployDaemonSet(fmt.Sprintf("dmn-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(dmn.ObjectMeta, apis.KindDaemonSet) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(bb.Name), dmn) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(dmn.ObjectMeta, apis.KindDaemonSet) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has failed") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionFailed)) + }) + It("should fail BackupSession for missing RetentionPolicy", func() { + // Create Storage Secret for Minio + secret, err := f.CreateBackendSecretForMinio() + Expect(err).NotTo(HaveOccurred()) + + // Generate BackupBlueprint definition + bb := f.BackupBlueprint(secret.Name) + bb.Spec.RetentionPolicy = v1alpha1.RetentionPolicy{} + By(fmt.Sprintf("Creating BackupBlueprint: %s", bb.Name)) + _, err = f.CreateBackupBlueprint(bb) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a DaemonSet + dmn, err := f.DeployDaemonSet(fmt.Sprintf("dmn-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(dmn.ObjectMeta, apis.KindDaemonSet) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(bb.Name), dmn) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(dmn.ObjectMeta, apis.KindDaemonSet) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has failed") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionFailed)) + }) + }) + + Context("Add inappropriate annotation to Target", func() { + It("should fail to create AutoBackup resources", func() { + // Create BackupBlueprint + _, err := f.CreateBackupBlueprintForWorkload(fmt.Sprintf("backupblueprint-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a DaemonSet + dmn, err := f.DeployDaemonSet(fmt.Sprintf("dmn-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(dmn.ObjectMeta, apis.KindDaemonSet) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(framework.WrongBackupBlueprintName), dmn) + Expect(err).NotTo(HaveOccurred()) + + // AutoBackup Resource creation failed + f.EventuallyEvent(dmn.ObjectMeta, apis.KindDaemonSet).Should(matcher.HaveEvent(eventer.EventReasonAutoBackupResourcesCreationFailed)) + + }) + It("should fail BackupSession for adding inappropriate TargetPath/MountPath", func() { + // Create BackupBlueprint + bb, err := f.CreateBackupBlueprintForWorkload(fmt.Sprintf("backupblueprint-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a DaemonSet + dmn, err := f.DeployDaemonSet(fmt.Sprintf("dmn-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(dmn.ObjectMeta, apis.KindDaemonSet) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + anno := annotations(bb.Name) + anno[v1beta1.KeyTargetPaths] = framework.WrongTargetPath + err = f.AddAutoBackupAnnotations(anno, dmn) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(dmn.ObjectMeta, apis.KindDaemonSet) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has failed") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionFailed)) + }) + + }) + }) + }) + +}) diff --git a/test/e2e/auto-backup/deployment.go b/test/e2e/auto-backup/deployment.go new file mode 100644 index 000000000..457e1cadc --- /dev/null +++ b/test/e2e/auto-backup/deployment.go @@ -0,0 +1,212 @@ +package auto_backup + +import ( + "fmt" + + "stash.appscode.dev/stash/apis" + "stash.appscode.dev/stash/apis/stash/v1alpha1" + "stash.appscode.dev/stash/apis/stash/v1beta1" + "stash.appscode.dev/stash/pkg/eventer" + "stash.appscode.dev/stash/test/e2e/framework" + "stash.appscode.dev/stash/test/e2e/matcher" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + store "kmodules.xyz/objectstore-api/api/v1" +) + +var _ = Describe("Auto-Backup", func() { + + var f *framework.Invocation + + BeforeEach(func() { + f = framework.NewInvocation() + }) + + AfterEach(func() { + err := f.CleanupTestResources() + Expect(err).NotTo(HaveOccurred()) + }) + + annotations := func(backupBlueprintName string) map[string]string { + return map[string]string{ + v1beta1.KeyBackupBlueprint: backupBlueprintName, + v1beta1.KeyTargetPaths: framework.TestSourceDataTargetPath, + v1beta1.KeyVolumeMounts: framework.TestSourceDataVolumeMount, + } + } + + Context("Deployment", func() { + + Context("Success Case", func() { + It("should backup successfully", func() { + // Create BackupBlueprint + bb, err := f.CreateBackupBlueprintForWorkload(fmt.Sprintf("backupblueprint-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a Deployment + deployment, err := f.DeployDeployment(fmt.Sprintf("deployment1-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(deployment.ObjectMeta, apis.KindDeployment) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(bb.Name), deployment) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(deployment.ObjectMeta, apis.KindDeployment) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has succeeded") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) + }) + }) + + Context("Failure Case", func() { + + Context("Missing AutoBackup resource credential in BackupBlueprint", func() { + It("should fail BackupSession for missing Backend credential", func() { + // Create Secret for BackupBlueprint + secret, err := f.CreateBackendSecretForMinio() + Expect(err).NotTo(HaveOccurred()) + + // Generate BackupBlueprint definition + bb := f.BackupBlueprint(secret.Name) + bb.Spec.Backend.S3 = &store.S3Spec{} + By(fmt.Sprintf("Creating BackupBlueprint: %s", bb.Name)) + _, err = f.CreateBackupBlueprint(bb) + Expect(err).NotTo(HaveOccurred()) + f.AppendToCleanupList(bb) + + // Deploy a Deployment + deployment, err := f.DeployDeployment(fmt.Sprintf("deployment2-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(deployment.ObjectMeta, apis.KindDeployment) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(bb.Name), deployment) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(deployment.ObjectMeta, apis.KindDeployment) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has failed") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionFailed)) + }) + It("should fail BackupSession for missing RetentionPolicy", func() { + // Create Storage Secret for Minio + secret, err := f.CreateBackendSecretForMinio() + Expect(err).NotTo(HaveOccurred()) + + // Generate BackupBlueprint definition + bb := f.BackupBlueprint(secret.Name) + bb.Spec.RetentionPolicy = v1alpha1.RetentionPolicy{} + By(fmt.Sprintf("Creating BackupBlueprint: %s", bb.Name)) + _, err = f.CreateBackupBlueprint(bb) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a Deployment + deployment, err := f.DeployDeployment(fmt.Sprintf("deployment3-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(deployment.ObjectMeta, apis.KindDeployment) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(bb.Name), deployment) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(deployment.ObjectMeta, apis.KindDeployment) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has failed") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionFailed)) + }) + }) + + Context("Add inappropriate annotation to Target", func() { + It("should fail to create AutoBackup resources", func() { + // Create BackupBlueprint + _, err := f.CreateBackupBlueprintForWorkload(fmt.Sprintf("backupblueprint-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a Deployment + deployment, err := f.DeployDeployment(fmt.Sprintf("deployment4-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(deployment.ObjectMeta, apis.KindDeployment) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(framework.WrongBackupBlueprintName), deployment) + Expect(err).NotTo(HaveOccurred()) + + // AutoBackup Resource creation failed + f.EventuallyEvent(deployment.ObjectMeta, apis.KindDeployment).Should(matcher.HaveEvent(eventer.EventReasonAutoBackupResourcesCreationFailed)) + }) + It("should fail BackupSession for adding inappropriate TargetPath/MountPath", func() { + // Create BackupBlueprint + bb, err := f.CreateBackupBlueprintForWorkload(fmt.Sprintf("backupblueprint-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a Deployment + deployment, err := f.DeployDeployment(fmt.Sprintf("deployment5-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(deployment.ObjectMeta, apis.KindDeployment) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + anno := annotations(bb.Name) + anno[v1beta1.KeyTargetPaths] = framework.WrongTargetPath + err = f.AddAutoBackupAnnotations(anno, deployment) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(deployment.ObjectMeta, apis.KindDeployment) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has failed") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionFailed)) + }) + }) + }) + }) + +}) diff --git a/test/e2e/auto-backup/pvc.go b/test/e2e/auto-backup/pvc.go new file mode 100644 index 000000000..209d4ad38 --- /dev/null +++ b/test/e2e/auto-backup/pvc.go @@ -0,0 +1,196 @@ +package auto_backup + +import ( + "fmt" + + "stash.appscode.dev/stash/apis" + "stash.appscode.dev/stash/apis/stash/v1alpha1" + "stash.appscode.dev/stash/apis/stash/v1beta1" + "stash.appscode.dev/stash/pkg/eventer" + "stash.appscode.dev/stash/test/e2e/framework" + "stash.appscode.dev/stash/test/e2e/matcher" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + store "kmodules.xyz/objectstore-api/api/v1" +) + +var _ = Describe("Auto-Backup", func() { + + var f *framework.Invocation + + BeforeEach(func() { + f = framework.NewInvocation() + }) + + AfterEach(func() { + err := f.CleanupTestResources() + Expect(err).NotTo(HaveOccurred()) + }) + + annotations := func(backupBlueprintName string) map[string]string { + return map[string]string{ + v1beta1.KeyBackupBlueprint: backupBlueprintName, + } + } + + Context("PVC", func() { + + Context("Success Case", func() { + + It("should backup successfully", func() { + // Create BackupBlueprint + bb, err := f.CreateBackupBlueprintForPVC(fmt.Sprintf("backupblueprint-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Create a PVC + pvc, err := f.CreateNewPVC(fmt.Sprintf("pvc1-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a Pod + pod, err := f.DeployPod(pvc.Name) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(pod.ObjectMeta, apis.KindPod) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(bb.Name), pvc) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(pvc.ObjectMeta, apis.KindPersistentVolumeClaim) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has succeeded") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) + }) + }) + + Context("Failure Case", func() { + + Context("Missing AutoBackup resource credential in BackupBlueprint", func() { + It("should fail BackupSession for missing Backend credential", func() { + // Create Secret for BackupBlueprint + secret, err := f.CreateBackendSecretForMinio() + Expect(err).NotTo(HaveOccurred()) + + // Generate BackupBlueprint definition + bb := f.BackupBlueprint(secret.Name) + bb.Spec.Backend.S3 = &store.S3Spec{} + By(fmt.Sprintf("Creating BackupBlueprint: %s", bb.Name)) + _, err = f.CreateBackupBlueprint(bb) + Expect(err).NotTo(HaveOccurred()) + f.AppendToCleanupList(bb) + + // Create a PVC + pvc, err := f.CreateNewPVC(fmt.Sprintf("pvc2-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a Pod + pod, err := f.DeployPod(pvc.Name) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(pod.ObjectMeta, apis.KindPod) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(bb.Name), pvc) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(pvc.ObjectMeta, apis.KindPersistentVolumeClaim) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has failed") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionFailed)) + }) + It("should fail BackupSession for missing RetentionPolicy", func() { + // Create storage Secret for Minio + secret, err := f.CreateBackendSecretForMinio() + Expect(err).NotTo(HaveOccurred()) + + // Generate BackupBlueprint definition + bb := f.BackupBlueprint(secret.Name) + bb.Spec.RetentionPolicy = v1alpha1.RetentionPolicy{} + By(fmt.Sprintf("Creating BackupBlueprint: %s", bb.Name)) + _, err = f.CreateBackupBlueprint(bb) + Expect(err).NotTo(HaveOccurred()) + + // Create a PVC + pvc, err := f.CreateNewPVC(fmt.Sprintf("pvc3-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a Pod + pod, err := f.DeployPod(pvc.Name) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(pod.ObjectMeta, apis.KindPod) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(bb.Name), pvc) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(pvc.ObjectMeta, apis.KindPersistentVolumeClaim) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has failed") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionFailed)) + }) + }) + + Context("Add inappropriate annotation to Target", func() { + It("should fail to create AutoBackup resources", func() { + // Create BackupBlueprint + bb, err := f.CreateBackupBlueprintForPVC(fmt.Sprintf("backupblueprint-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Create a PVC + pvc, err := f.CreateNewPVC(fmt.Sprintf("pvc4-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a Pod + pod, err := f.DeployPod(pvc.Name) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(pod.ObjectMeta, apis.KindPod) + Expect(err).NotTo(HaveOccurred()) + + anno := annotations(bb.Name) + anno[v1beta1.KeyBackupBlueprint] = framework.WrongBackupBlueprintName + err = f.AddAutoBackupAnnotations(anno, pvc) + Expect(err).NotTo(HaveOccurred()) + + // AutoBackup Resource creation failed + f.EventuallyEvent(pvc.ObjectMeta, apis.KindPersistentVolumeClaim).Should(matcher.HaveEvent(eventer.EventReasonAutoBackupResourcesCreationFailed)) + }) + }) + }) + }) + +}) diff --git a/test/e2e/auto-backup/replicaset.go b/test/e2e/auto-backup/replicaset.go new file mode 100644 index 000000000..6a3eef2ca --- /dev/null +++ b/test/e2e/auto-backup/replicaset.go @@ -0,0 +1,214 @@ +package auto_backup + +import ( + "fmt" + + "stash.appscode.dev/stash/apis" + "stash.appscode.dev/stash/apis/stash/v1alpha1" + "stash.appscode.dev/stash/apis/stash/v1beta1" + "stash.appscode.dev/stash/pkg/eventer" + "stash.appscode.dev/stash/test/e2e/framework" + "stash.appscode.dev/stash/test/e2e/matcher" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + store "kmodules.xyz/objectstore-api/api/v1" +) + +var _ = Describe("Auto-Backup", func() { + + var f *framework.Invocation + + BeforeEach(func() { + f = framework.NewInvocation() + }) + + AfterEach(func() { + err := f.CleanupTestResources() + Expect(err).NotTo(HaveOccurred()) + }) + + annotations := func(backupBlueprintName string) map[string]string { + return map[string]string{ + v1beta1.KeyBackupBlueprint: backupBlueprintName, + v1beta1.KeyTargetPaths: framework.TestSourceDataTargetPath, + v1beta1.KeyVolumeMounts: framework.TestSourceDataVolumeMount, + } + } + + Context("ReplicaSet", func() { + + Context("Success Case", func() { + + It("should success auto-backup for the ReplicaSet", func() { + // Create BackupBlueprint + bb, err := f.CreateBackupBlueprintForWorkload(fmt.Sprintf("backupblueprint-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a ReplicaSet + rs, err := f.DeployReplicaSet(fmt.Sprintf("rs1-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(rs.ObjectMeta, apis.KindReplicaSet) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(bb.Name), rs) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(rs.ObjectMeta, apis.KindReplicaSet) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has succeeded") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) + }) + }) + + Context("Failure Case", func() { + + Context("Missing AutoBackup resource credential in BackupBlueprint", func() { + It("should fail BackupSession for missing Backend credential", func() { + // Create Secret for BackupBlueprint + secret, err := f.CreateBackendSecretForMinio() + Expect(err).NotTo(HaveOccurred()) + + // Generate BackupBlueprint definition + bb := f.BackupBlueprint(secret.Name) + bb.Spec.Backend.S3 = &store.S3Spec{} + By(fmt.Sprintf("Creating BackupBlueprint: %s", bb.Name)) + _, err = f.CreateBackupBlueprint(bb) + Expect(err).NotTo(HaveOccurred()) + f.AppendToCleanupList(bb) + + // Deploy a ReplicaSet + rs, err := f.DeployReplicaSet(fmt.Sprintf("rs2-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(rs.ObjectMeta, apis.KindReplicaSet) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(bb.Name), rs) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(rs.ObjectMeta, apis.KindReplicaSet) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has failed") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionFailed)) + }) + It("should fail BackupSession for missing RetentionPolicy", func() { + // Create Storage Secret for Minio + secret, err := f.CreateBackendSecretForMinio() + Expect(err).NotTo(HaveOccurred()) + + // Generate BackupBlueprint definition + bb := f.BackupBlueprint(secret.Name) + bb.Spec.RetentionPolicy = v1alpha1.RetentionPolicy{} + By(fmt.Sprintf("Creating BackupBlueprint: %s", bb.Name)) + _, err = f.CreateBackupBlueprint(bb) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a ReplicaSet + rs, err := f.DeployReplicaSet(fmt.Sprintf("rs3-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(rs.ObjectMeta, apis.KindReplicaSet) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(bb.Name), rs) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(rs.ObjectMeta, apis.KindReplicaSet) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has failed") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionFailed)) + }) + }) + + Context("Add inappropriate annotation to Target", func() { + It("should fail to create AutoBackup resources", func() { + // Create BackupBlueprint + _, err := f.CreateBackupBlueprintForWorkload(fmt.Sprintf("backupblueprint-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a ReplicaSet + rs, err := f.DeployReplicaSet(fmt.Sprintf("rs4-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(rs.ObjectMeta, apis.KindReplicaSet) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(framework.WrongBackupBlueprintName), rs) + Expect(err).NotTo(HaveOccurred()) + + // AutoBackup Resource creation failed + f.EventuallyEvent(rs.ObjectMeta, apis.KindReplicaSet).Should(matcher.HaveEvent(eventer.EventReasonAutoBackupResourcesCreationFailed)) + }) + It("should fail BackupSession for adding inappropriate TargetPath/MountPath", func() { + // Create BackupBlueprint + bb, err := f.CreateBackupBlueprintForWorkload(fmt.Sprintf("backupblueprint-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a ReplicaSet + rs, err := f.DeployReplicaSet(fmt.Sprintf("rs5-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(rs.ObjectMeta, apis.KindReplicaSet) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + anno := annotations(bb.Name) + anno[v1beta1.KeyTargetPaths] = framework.WrongTargetPath + err = f.AddAutoBackupAnnotations(anno, rs) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(rs.ObjectMeta, apis.KindReplicaSet) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has failed") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionFailed)) + }) + + }) + }) + }) + +}) diff --git a/test/e2e/auto-backup/replicationcontroller.go b/test/e2e/auto-backup/replicationcontroller.go new file mode 100644 index 000000000..7816dd7d1 --- /dev/null +++ b/test/e2e/auto-backup/replicationcontroller.go @@ -0,0 +1,214 @@ +package auto_backup + +import ( + "fmt" + + "stash.appscode.dev/stash/apis" + "stash.appscode.dev/stash/apis/stash/v1alpha1" + "stash.appscode.dev/stash/apis/stash/v1beta1" + "stash.appscode.dev/stash/pkg/eventer" + "stash.appscode.dev/stash/test/e2e/framework" + "stash.appscode.dev/stash/test/e2e/matcher" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + store "kmodules.xyz/objectstore-api/api/v1" +) + +var _ = Describe("Auto-Backup", func() { + + var f *framework.Invocation + + BeforeEach(func() { + f = framework.NewInvocation() + }) + + AfterEach(func() { + err := f.CleanupTestResources() + Expect(err).NotTo(HaveOccurred()) + }) + + annotations := func(backupBlueprintName string) map[string]string { + return map[string]string{ + v1beta1.KeyBackupBlueprint: backupBlueprintName, + v1beta1.KeyTargetPaths: framework.TestSourceDataTargetPath, + v1beta1.KeyVolumeMounts: framework.TestSourceDataVolumeMount, + } + } + + Context("ReplicationController", func() { + + Context("Success Case", func() { + + It("should backup successfully", func() { + // Create BackupBlueprint + bb, err := f.CreateBackupBlueprintForWorkload(fmt.Sprintf("backupblueprint-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a ReplicationController + rc, err := f.DeployReplicationController(fmt.Sprintf("rc1-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(rc.ObjectMeta, apis.KindReplicationController) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(bb.Name), rc) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(rc.ObjectMeta, apis.KindReplicationController) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has succeeded") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) + }) + }) + + Context("Failure Case", func() { + + Context("Missing AutoBackup resource credential in BackupBlueprint", func() { + It("should fail BackupSession for missing Backend credential", func() { + // Create Secret for BackupBlueprint + secret, err := f.CreateBackendSecretForMinio() + Expect(err).NotTo(HaveOccurred()) + + // Generate BackupBlueprint definition + bb := f.BackupBlueprint(secret.Name) + bb.Spec.Backend.S3 = &store.S3Spec{} + By(fmt.Sprintf("Creating BackupBlueprint: %s", bb.Name)) + _, err = f.CreateBackupBlueprint(bb) + Expect(err).NotTo(HaveOccurred()) + f.AppendToCleanupList(bb) + + // Deploy a ReplicationController + rc, err := f.DeployReplicationController(fmt.Sprintf("rc2-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(rc.ObjectMeta, apis.KindReplicationController) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(bb.Name), rc) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(rc.ObjectMeta, apis.KindReplicationController) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has failed") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionFailed)) + }) + It("should fail BackupSession for missing RetentionPolicy", func() { + // Create Storage Secret for Minio + secret, err := f.CreateBackendSecretForMinio() + Expect(err).NotTo(HaveOccurred()) + + // Generate BackupBlueprint definition + bb := f.BackupBlueprint(secret.Name) + bb.Spec.RetentionPolicy = v1alpha1.RetentionPolicy{} + By(fmt.Sprintf("Creating BackupBlueprint: %s", bb.Name)) + _, err = f.CreateBackupBlueprint(bb) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a ReplicationController + rc, err := f.DeployReplicationController(fmt.Sprintf("rc3-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(rc.ObjectMeta, apis.KindReplicationController) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(bb.Name), rc) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(rc.ObjectMeta, apis.KindReplicationController) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has failed") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionFailed)) + }) + }) + + Context("Add inappropriate annotation to Target", func() { + It("should fail auto-backup for adding inappropriate BackupBlueprint annotation in ReplicationController", func() { + // Create BackupBlueprint + _, err := f.CreateBackupBlueprintForWorkload(fmt.Sprintf("backupblueprint-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a ReplicationController + rc, err := f.DeployReplicationController(fmt.Sprintf("rc4-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(rc.ObjectMeta, apis.KindReplicationController) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(framework.WrongBackupBlueprintName), rc) + Expect(err).NotTo(HaveOccurred()) + + // AutoBackup Resource creation failed + f.EventuallyEvent(rc.ObjectMeta, apis.KindReplicationController).Should(matcher.HaveEvent(eventer.EventReasonAutoBackupResourcesCreationFailed)) + }) + It("should fail BackupSession for adding inappropriate TargetPath/MountPath ReplicationController", func() { + // Create BackupBlueprint + bb, err := f.CreateBackupBlueprintForWorkload(fmt.Sprintf("backupblueprint-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a ReplicationController + rc, err := f.DeployReplicationController(fmt.Sprintf("rc5-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(rc.ObjectMeta, apis.KindReplicationController) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + anno := annotations(bb.Name) + anno[v1beta1.KeyTargetPaths] = framework.WrongTargetPath + err = f.AddAutoBackupAnnotations(anno, rc) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(rc.ObjectMeta, apis.KindReplicationController) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has failed") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionFailed)) + }) + }) + + }) + }) + +}) diff --git a/test/e2e/auto-backup/statefulset.go b/test/e2e/auto-backup/statefulset.go new file mode 100644 index 000000000..cfad22da2 --- /dev/null +++ b/test/e2e/auto-backup/statefulset.go @@ -0,0 +1,213 @@ +package auto_backup + +import ( + "fmt" + + "stash.appscode.dev/stash/apis" + "stash.appscode.dev/stash/apis/stash/v1alpha1" + "stash.appscode.dev/stash/apis/stash/v1beta1" + "stash.appscode.dev/stash/pkg/eventer" + "stash.appscode.dev/stash/test/e2e/framework" + "stash.appscode.dev/stash/test/e2e/matcher" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + store "kmodules.xyz/objectstore-api/api/v1" +) + +var _ = Describe("Auto-Backup", func() { + + var f *framework.Invocation + + BeforeEach(func() { + f = framework.NewInvocation() + }) + + AfterEach(func() { + err := f.CleanupTestResources() + Expect(err).NotTo(HaveOccurred()) + }) + + annotations := func(backupBlueprintName string) map[string]string { + return map[string]string{ + v1beta1.KeyBackupBlueprint: backupBlueprintName, + v1beta1.KeyTargetPaths: framework.TestSourceDataTargetPath, + v1beta1.KeyVolumeMounts: framework.TestSourceDataVolumeMount, + } + } + + Context("StatefulSet", func() { + + Context("Success Case", func() { + + It("should success auto-backup for the StatefulSet", func() { + // Create BackupBlueprint + bb, err := f.CreateBackupBlueprintForWorkload(fmt.Sprintf("backupblueprint-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a StatefulSet + ss, err := f.DeployStatefulSet(fmt.Sprintf("ss1-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(ss.ObjectMeta, apis.KindStatefulSet) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(bb.Name), ss) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(ss.ObjectMeta, apis.KindStatefulSet) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has succeeded") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) + }) + }) + + Context("Failure Case", func() { + + Context("Missing AutoBackup resource credential in BackupBlueprint", func() { + It("should fail BackupSession for missing Backend credential", func() { + // Create Secret for BackupBlueprint + secret, err := f.CreateBackendSecretForMinio() + Expect(err).NotTo(HaveOccurred()) + + // Generate BackupBlueprint definition + bb := f.BackupBlueprint(secret.Name) + bb.Spec.Backend.S3 = &store.S3Spec{} + By(fmt.Sprintf("Creating BackupBlueprint: %s", bb.Name)) + _, err = f.CreateBackupBlueprint(bb) + Expect(err).NotTo(HaveOccurred()) + f.AppendToCleanupList(bb) + + // Deploy a StatefulSet + ss, err := f.DeployStatefulSet(fmt.Sprintf("ss2-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(ss.ObjectMeta, apis.KindStatefulSet) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(bb.Name), ss) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(ss.ObjectMeta, apis.KindStatefulSet) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has failed") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionFailed)) + }) + It("should fail BackupSession for missing RetentionPolicy", func() { + // Create Storage Secret for Minio + secret, err := f.CreateBackendSecretForMinio() + Expect(err).NotTo(HaveOccurred()) + + // Generate BackupBlueprint definition + bb := f.BackupBlueprint(secret.Name) + bb.Spec.RetentionPolicy = v1alpha1.RetentionPolicy{} + By(fmt.Sprintf("Creating BackupBlueprint: %s", bb.Name)) + _, err = f.CreateBackupBlueprint(bb) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a StatefulSet + ss, err := f.DeployStatefulSet(fmt.Sprintf("ss3-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(ss.ObjectMeta, apis.KindStatefulSet) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(bb.Name), ss) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(ss.ObjectMeta, apis.KindStatefulSet) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has failed") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionFailed)) + }) + }) + + Context("Add inappropriate annotation to Target", func() { + It("Should fail auto-backup for adding inappropriate BackupBlueprint annotation in StatefulSet", func() { + // Create BackupBlueprint + _, err := f.CreateBackupBlueprintForWorkload(fmt.Sprintf("backupblueprint-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a StatefulSet + ss, err := f.DeployStatefulSet(fmt.Sprintf("ss4-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(ss.ObjectMeta, apis.KindStatefulSet) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + err = f.AddAutoBackupAnnotations(annotations(framework.WrongBackupBlueprintName), ss) + Expect(err).NotTo(HaveOccurred()) + + // AutoBackup Resource creation failed + f.EventuallyEvent(ss.ObjectMeta, apis.KindStatefulSet).Should(matcher.HaveEvent(eventer.EventReasonAutoBackupResourcesCreationFailed)) + }) + It("should fail BackupSession for adding inappropriate TargetPath/MountPath StatefulSet", func() { + // Create BackupBlueprint + bb, err := f.CreateBackupBlueprintForWorkload(fmt.Sprintf("backupblueprint-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Deploy a StatefulSet + ss, err := f.DeployStatefulSet(fmt.Sprintf("ss5-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Generate Sample Data + _, err = f.GenerateSampleData(ss.ObjectMeta, apis.KindStatefulSet) + Expect(err).NotTo(HaveOccurred()) + + // Add and Ensure annotations to Target + anno := annotations(bb.Name) + anno[v1beta1.KeyTargetPaths] = framework.WrongTargetPath + err = f.AddAutoBackupAnnotations(anno, ss) + Expect(err).NotTo(HaveOccurred()) + + // ensure Repository and BackupConfiguration + backupConfig, err := f.VerifyAutoBackupConfigured(ss.ObjectMeta, apis.KindStatefulSet) + Expect(err).NotTo(HaveOccurred()) + + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has failed") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionFailed)) + }) + }) + }) + }) + +}) diff --git a/test/e2e/daemonset_test.go b/test/e2e/daemonset_test.go index 6e6254107..27581cdd8 100644 --- a/test/e2e/daemonset_test.go +++ b/test/e2e/daemonset_test.go @@ -88,7 +88,7 @@ var _ = XDescribe("DaemonSet", func() { var ( shouldBackupNewDaemonSet = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -116,7 +116,7 @@ var _ = XDescribe("DaemonSet", func() { shouldBackupExistingDaemonSet = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating DaemonSet " + daemon.Name) @@ -144,7 +144,7 @@ var _ = XDescribe("DaemonSet", func() { shouldStopBackup = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -174,7 +174,7 @@ var _ = XDescribe("DaemonSet", func() { shouldStopBackupIfLabelChanged = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -209,7 +209,7 @@ var _ = XDescribe("DaemonSet", func() { shouldStopBackupIfSelectorChanged = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -246,7 +246,7 @@ var _ = XDescribe("DaemonSet", func() { shouldMutateAndBackupNewDaemonSet = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -275,7 +275,7 @@ var _ = XDescribe("DaemonSet", func() { shouldNotMutateNewDaemonSet = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating DaemonSet " + daemon.Name) @@ -288,7 +288,7 @@ var _ = XDescribe("DaemonSet", func() { shouldRejectToCreateNewDaemonSet = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating first restic " + restic.Name) @@ -306,7 +306,7 @@ var _ = XDescribe("DaemonSet", func() { shouldRemoveSidecarInstantly = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -341,7 +341,7 @@ var _ = XDescribe("DaemonSet", func() { shouldAddSidecarInstantly = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -597,7 +597,7 @@ var _ = XDescribe("DaemonSet", func() { }) It(`should backup new DaemonSet`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -665,7 +665,7 @@ var _ = XDescribe("DaemonSet", func() { }) It(`should be able to Pause and Resume backup`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic") @@ -746,7 +746,7 @@ var _ = XDescribe("DaemonSet", func() { }) It(`should create Repository CRD`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic") @@ -800,7 +800,7 @@ var _ = XDescribe("DaemonSet", func() { }) It(`recovered volume should have same data`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic") @@ -893,7 +893,7 @@ var _ = XDescribe("DaemonSet", func() { }) It(`recovered volume should have same data`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) daemon.Spec.Template.Spec.Volumes = f.HostPathVolumeWithMultipleDirectory() @@ -1006,7 +1006,7 @@ var _ = XDescribe("DaemonSet", func() { }) It(`recovered volume should have same data`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic") diff --git a/test/e2e/deployment_test.go b/test/e2e/deployment_test.go index 5cb456d71..181cacdf9 100644 --- a/test/e2e/deployment_test.go +++ b/test/e2e/deployment_test.go @@ -84,7 +84,7 @@ var _ = XDescribe("Deployment", func() { } restic.Spec.Backend.StorageSecretName = cred.Name secondRestic.Spec.Backend.StorageSecretName = cred.Name - pvc := f.PersistentVolumeClaim() + pvc := f.PersistentVolumeClaim(rand.WithUniqSuffix("pvc")) _, err := f.CreatePersistentVolumeClaim(pvc) Expect(err).NotTo(HaveOccurred()) deployment = f.Deployment(pvc.Name) @@ -98,7 +98,7 @@ var _ = XDescribe("Deployment", func() { var ( shouldBackupNewDeployment = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -126,7 +126,7 @@ var _ = XDescribe("Deployment", func() { shouldBackupExistingDeployment = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating Deployment " + deployment.Name) @@ -154,7 +154,7 @@ var _ = XDescribe("Deployment", func() { shouldStopBackup = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -184,7 +184,7 @@ var _ = XDescribe("Deployment", func() { shouldStopBackupIfLabelChanged = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -219,7 +219,7 @@ var _ = XDescribe("Deployment", func() { shouldStopBackupIfSelectorChanged = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -256,7 +256,7 @@ var _ = XDescribe("Deployment", func() { shouldElectLeaderAndBackupDeployment = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -288,7 +288,7 @@ var _ = XDescribe("Deployment", func() { shouldMutateAndBackupNewDeployment = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -317,7 +317,7 @@ var _ = XDescribe("Deployment", func() { shouldNotMutateNewDeployment = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating Deployment " + deployment.Name) @@ -330,7 +330,7 @@ var _ = XDescribe("Deployment", func() { shouldRejectToCreateNewDeployment = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating first restic " + restic.Name) @@ -348,7 +348,7 @@ var _ = XDescribe("Deployment", func() { shouldRemoveSidecarInstantly = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -383,7 +383,7 @@ var _ = XDescribe("Deployment", func() { shouldAddSidecarInstantly = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -613,7 +613,7 @@ var _ = XDescribe("Deployment", func() { It(`should delete job after recovery deleted`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic") @@ -721,7 +721,7 @@ var _ = XDescribe("Deployment", func() { }) It(`should backup new Deployment`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -782,7 +782,7 @@ var _ = XDescribe("Deployment", func() { }) It(`should backup new Deployment`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -881,7 +881,7 @@ var _ = XDescribe("Deployment", func() { It("Should backup new Deployment", func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic") @@ -921,7 +921,7 @@ var _ = XDescribe("Deployment", func() { It("Should fail to backup new Deployment", func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic without cacert") @@ -967,7 +967,7 @@ var _ = XDescribe("Deployment", func() { registryCred = f.SecretForRegistry(dockerCfgJson) By("Creating registry Secret " + registryCred.Name) - err = f.CreateSecret(registryCred) + _, err = f.CreateSecret(registryCred) Expect(err).NotTo(HaveOccurred()) cred = f.SecretForLocalBackend() @@ -997,7 +997,7 @@ var _ = XDescribe("Deployment", func() { }) It(`should be able to Pause and Resume backup`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic") @@ -1083,7 +1083,7 @@ var _ = XDescribe("Deployment", func() { }) It(`should create Repository CRD`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic") @@ -1137,7 +1137,7 @@ var _ = XDescribe("Deployment", func() { }) It(`recovered volume should have same data`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic") @@ -1218,7 +1218,7 @@ var _ = XDescribe("Deployment", func() { }) It(`recovered volume should have same data`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) deployment.Spec.Template.Spec.Volumes = f.HostPathVolumeWithMultipleDirectory() @@ -1334,7 +1334,7 @@ var _ = XDescribe("Deployment", func() { }) It(`recovered volume should have same data`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic") @@ -1439,7 +1439,7 @@ var _ = XDescribe("Deployment", func() { }) It(`recovered volume should have old data`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) deployment.Spec.Template.Spec.Volumes = f.HostPathVolumeWithMultipleDirectory() @@ -1654,7 +1654,7 @@ var _ = XDescribe("Deployment", func() { }) It(`should create checkJob`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) diff --git a/test/e2e/e2e_suite_test.go b/test/e2e/e2e_suite_test.go index bb3e1bafa..3512ffabc 100644 --- a/test/e2e/e2e_suite_test.go +++ b/test/e2e/e2e_suite_test.go @@ -25,6 +25,7 @@ import ( "stash.appscode.dev/stash/client/clientset/versioned/scheme" _ "stash.appscode.dev/stash/client/clientset/versioned/scheme" "stash.appscode.dev/stash/pkg/controller" + _ "stash.appscode.dev/stash/test/e2e/auto-backup" "stash.appscode.dev/stash/test/e2e/framework" _ "stash.appscode.dev/stash/test/e2e/volumes" _ "stash.appscode.dev/stash/test/e2e/workloads" diff --git a/test/e2e/framework/backup_blueprint.go b/test/e2e/framework/backup_blueprint.go new file mode 100644 index 000000000..008426914 --- /dev/null +++ b/test/e2e/framework/backup_blueprint.go @@ -0,0 +1,96 @@ +package framework + +import ( + "fmt" + + "stash.appscode.dev/stash/apis/stash/v1alpha1" + "stash.appscode.dev/stash/apis/stash/v1beta1" + + "github.com/appscode/go/crypto/rand" + . "github.com/onsi/ginkgo" + kerr "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + store "kmodules.xyz/objectstore-api/api/v1" +) + +func (f *Invocation) BackupBlueprint(secretName string) *v1beta1.BackupBlueprint { + + return &v1beta1.BackupBlueprint{ + ObjectMeta: metav1.ObjectMeta{ + Name: rand.WithUniqSuffix(f.app), + }, + Spec: v1beta1.BackupBlueprintSpec{ + RepositorySpec: v1alpha1.RepositorySpec{ + Backend: store.Backend{ + S3: &store.S3Spec{ + Endpoint: f.MinioServiceAddres(), + Bucket: "minio-bucket", + Prefix: fmt.Sprintf("stash-e2e/%s/%s", f.Namespace(), f.App()), + }, + StorageSecretName: secretName, + }, + WipeOut: false, + }, + Schedule: "*/59 * * * *", + RetentionPolicy: v1alpha1.RetentionPolicy{ + Name: "keep-last-5", + KeepLast: 5, + Prune: true, + }, + }, + } +} + +func (f *Framework) CreateBackupBlueprint(backupBlueprint *v1beta1.BackupBlueprint) (*v1beta1.BackupBlueprint, error) { + return f.StashClient.StashV1beta1().BackupBlueprints().Create(backupBlueprint) +} + +func (f *Invocation) DeleteBackupBlueprint(name string) error { + if name == "" { + return nil + } + err := f.StashClient.StashV1beta1().BackupBlueprints().Delete(name, &metav1.DeleteOptions{}) + if kerr.IsNotFound(err) { + return nil + } + return err +} + +func (f *Framework) GetBackupBlueprint(name string) (*v1beta1.BackupBlueprint, error) { + return f.StashClient.StashV1beta1().BackupBlueprints().Get(name, metav1.GetOptions{}) +} + +func (f Invocation) CreateBackupBlueprintForWorkload(name string) (*v1beta1.BackupBlueprint, error) { + // Create Secret for BackupBlueprint + secret, err := f.CreateBackendSecretForMinio() + if err != nil { + return &v1beta1.BackupBlueprint{}, err + } + + // Generate BackupBlueprint definition + bb := f.BackupBlueprint(secret.Name) + bb.Name = name + + By(fmt.Sprintf("Creating BackupBlueprint: %s", bb.Name)) + createdBB, err := f.CreateBackupBlueprint(bb) + f.AppendToCleanupList(createdBB) + return createdBB, err +} + +func (f Invocation) CreateBackupBlueprintForPVC(name string) (*v1beta1.BackupBlueprint, error) { + // Create Secret for BackupBlueprint + secret, err := f.CreateBackendSecretForMinio() + if err != nil { + return &v1beta1.BackupBlueprint{}, err + } + + // Generate BackupBlueprint definition + bb := f.BackupBlueprint(secret.Name) + bb.Spec.Task.Name = TaskPVCBackup + bb.Name = name + + By(fmt.Sprintf("Creating BackupBlueprint: %s", bb.Name)) + createdBB, err := f.CreateBackupBlueprint(bb) + f.AppendToCleanupList(createdBB) + return createdBB, err +} diff --git a/test/e2e/framework/backup_configuration.go b/test/e2e/framework/backup_configuration.go index f903f861f..eb8158e07 100644 --- a/test/e2e/framework/backup_configuration.go +++ b/test/e2e/framework/backup_configuration.go @@ -103,7 +103,24 @@ func (f *Framework) EventuallyCronJobCreated(meta metav1.ObjectMeta) GomegaAsync return Eventually( func() bool { _, err := f.KubeClient.BatchV1beta1().CronJobs(meta.Namespace).Get(meta.Name, metav1.GetOptions{}) - return err == nil + if err == nil && !kerr.IsNotFound(err) { + return true + } + return false + }, + time.Minute*2, + time.Second*5, + ) +} + +func (f *Framework) EventuallyBackupConfigurationCreated(meta metav1.ObjectMeta) GomegaAsyncAssertion { + return Eventually( + func() bool { + _, err := f.StashClient.StashV1beta1().BackupConfigurations(meta.Namespace).Get(meta.Name, metav1.GetOptions{}) + if err == nil && !kerr.IsNotFound(err) { + return true + } + return false }, time.Minute*2, time.Second*5, diff --git a/test/e2e/framework/backup_session.go b/test/e2e/framework/backup_session.go index 3ff27b02a..1a5f6b45d 100644 --- a/test/e2e/framework/backup_session.go +++ b/test/e2e/framework/backup_session.go @@ -17,7 +17,7 @@ package framework import ( "fmt" - "time" + "strings" "stash.appscode.dev/stash/apis/stash/v1beta1" "stash.appscode.dev/stash/pkg/util" @@ -62,8 +62,6 @@ func (f *Framework) EventuallyBackupSessionCreated(meta metav1.ObjectMeta) Gomeg Expect(err).NotTo(HaveOccurred()) return len(backupsnlist.Items) > 0 }, - time.Minute*7, - time.Second*5, ) } @@ -73,7 +71,11 @@ func (f *Framework) GetBackupSession(meta metav1.ObjectMeta) (*v1beta1.BackupSes return nil, err } if len(backupsnlist.Items) > 0 { - return &backupsnlist.Items[0], nil + for _, bs := range backupsnlist.Items { + if strings.HasPrefix(bs.Name, meta.Name) { + return &bs, nil + } + } } return nil, fmt.Errorf("no BackupSession found") } @@ -88,21 +90,21 @@ func (f *Framework) EventuallyBackupSessionTotalHost(meta metav1.ObjectMeta) Gom ) } -func (f *Invocation) TriggerInstantBackup(backupConfig *v1beta1.BackupConfiguration) (*v1beta1.BackupSession, error) { +func (f *Invocation) TriggerInstantBackup(objMeta metav1.ObjectMeta) (*v1beta1.BackupSession, error) { backupSession := &v1beta1.BackupSession{ ObjectMeta: metav1.ObjectMeta{ - Name: rand.WithUniqSuffix(backupConfig.Name), - Namespace: backupConfig.Namespace, + Name: rand.WithUniqSuffix(objMeta.Name), + Namespace: objMeta.Namespace, Labels: map[string]string{ util.LabelApp: util.AppLabelStash, - util.LabelBackupConfiguration: backupConfig.Name, + util.LabelBackupConfiguration: objMeta.Name, }, }, Spec: v1beta1.BackupSessionSpec{ Invoker: v1beta1.BackupInvokerRef{ APIGroup: v1beta1.SchemeGroupVersion.Group, Kind: v1beta1.ResourceKindBackupConfiguration, - Name: backupConfig.Name, + Name: objMeta.Name, }, }, } diff --git a/test/e2e/framework/common.go b/test/e2e/framework/common.go new file mode 100644 index 000000000..df3debd3d --- /dev/null +++ b/test/e2e/framework/common.go @@ -0,0 +1,234 @@ +package framework + +import ( + "fmt" + + "stash.appscode.dev/stash/apis" + api "stash.appscode.dev/stash/apis/stash/v1alpha1" + "stash.appscode.dev/stash/apis/stash/v1beta1" + "stash.appscode.dev/stash/pkg/util" + . "stash.appscode.dev/stash/test/e2e/matcher" + + "github.com/appscode/go/sets" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + apps "k8s.io/api/apps/v1" + core "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func (f *Framework) GenerateSampleData(objMeta metav1.ObjectMeta, kind string) (sets.String, error) { + By("Generating sample data inside workload pods") + err := f.CreateSampleDataInsideWorkload(objMeta, kind) + if err != nil { + return sets.String{}, err + } + + By("Verifying that sample data has been generated") + sampleData, err := f.ReadSampleDataFromFromWorkload(objMeta, kind) + Expect(err).NotTo(HaveOccurred()) + Expect(sampleData).ShouldNot(BeEmpty()) + + return sampleData, nil +} + +func (f *Invocation) SetupWorkloadBackup(objMeta metav1.ObjectMeta, repo *api.Repository, kind string) (*v1beta1.BackupConfiguration, error) { + // Generate desired BackupConfiguration definition + backupConfig := f.GetBackupConfigurationForWorkload(repo.Name, GetTargetRef(objMeta.Name, kind)) + + By("Creating BackupConfiguration: " + backupConfig.Name) + createdBC, err := f.StashClient.StashV1beta1().BackupConfigurations(backupConfig.Namespace).Create(backupConfig) + Expect(err).NotTo(HaveOccurred()) + f.AppendToCleanupList(createdBC) + + By("Verifying that backup triggering CronJob has been created") + f.EventuallyCronJobCreated(backupConfig.ObjectMeta).Should(BeTrue()) + + By("Verifying that sidecar has been injected") + switch kind { + case apis.KindDeployment: + f.EventuallyDeployment(objMeta).Should(HaveSidecar(util.StashContainer)) + By("Waiting for Deployment to be ready with sidecar") + err = f.WaitUntilDeploymentReadyWithSidecar(objMeta) + case apis.KindDaemonSet: + f.EventuallyDaemonSet(objMeta).Should(HaveSidecar(util.StashContainer)) + By("Waiting for DaemonSet to be ready with sidecar") + err = f.WaitUntilDaemonSetReadyWithSidecar(objMeta) + case apis.KindStatefulSet: + f.EventuallyStatefulSet(objMeta).Should(HaveSidecar(util.StashContainer)) + By("Waiting for StatefulSet to be ready with sidecar") + err = f.WaitUntilStatefulSetReadyWithSidecar(objMeta) + case apis.KindReplicaSet: + f.EventuallyReplicaSet(objMeta).Should(HaveSidecar(util.StashContainer)) + By("Waiting for ReplicaSet to be ready with sidecar") + err = f.WaitUntilRSReadyWithSidecar(objMeta) + case apis.KindReplicationController: + f.EventuallyReplicationController(objMeta).Should(HaveSidecar(util.StashContainer)) + By("Waiting for ReplicationController to be ready with sidecar") + err = f.WaitUntilRCReadyWithSidecar(objMeta) + } + return createdBC, err +} + +func (f *Invocation) TakeInstantBackup(objMeta metav1.ObjectMeta) (*v1beta1.BackupSession, error) { + // Trigger Instant Backup + By("Triggering Instant Backup") + backupSession, err := f.TriggerInstantBackup(objMeta) + if err != nil { + return backupSession, err + } + f.AppendToCleanupList(backupSession) + + By("Waiting for backup process to complete") + f.EventuallyBackupProcessCompleted(backupSession.ObjectMeta).Should(BeTrue()) + + return backupSession, nil +} + +func (f *Invocation) RestoredData(objMeta metav1.ObjectMeta, kind string) sets.String { + By("Reading restored data") + restoredData, err := f.ReadSampleDataFromFromWorkload(objMeta, kind) + Expect(err).NotTo(HaveOccurred()) + Expect(restoredData).NotTo(BeEmpty()) + + return restoredData +} + +func (f *Invocation) SetupRestoreProcess(objMeta metav1.ObjectMeta, repo *api.Repository, kind string) (*v1beta1.RestoreSession, error) { + By("Creating RestoreSession") + restoreSession := f.GetRestoreSessionForWorkload(repo.Name, GetTargetRef(objMeta.Name, kind)) + err := f.CreateRestoreSession(restoreSession) + Expect(err).NotTo(HaveOccurred()) + f.AppendToCleanupList(restoreSession) + + By("Verifying that init-container has been injected") + switch kind { + case apis.KindDeployment: + f.EventuallyDeployment(objMeta).Should(HaveInitContainer(util.StashInitContainer)) + By("Waiting for workload to be ready with init-container") + err = f.WaitUntilDeploymentReadyWithInitContainer(objMeta) + case apis.KindDaemonSet: + f.EventuallyDaemonSet(objMeta).Should(HaveInitContainer(util.StashInitContainer)) + By("Waiting for workload to be ready with init-container") + err = f.WaitUntilDaemonSetReadyWithInitContainer(objMeta) + case apis.KindStatefulSet: + f.EventuallyStatefulSet(objMeta).Should(HaveInitContainer(util.StashInitContainer)) + By("Waiting for workload to be ready with init-container") + err = f.WaitUntilStatefulSetWithInitContainer(objMeta) + case apis.KindReplicaSet: + f.EventuallyReplicaSet(objMeta).Should(HaveInitContainer(util.StashInitContainer)) + By("Waiting for workload to be ready with init-container") + err = f.WaitUntilRSReadyWithInitContainer(objMeta) + case apis.KindReplicationController: + f.EventuallyReplicationController(objMeta).Should(HaveInitContainer(util.StashInitContainer)) + By("Waiting for workload to be ready with init-container") + err = f.WaitUntilRCReadyWithInitContainer(objMeta) + } + f.EventuallyPodAccessible(objMeta).Should(BeTrue()) + By("Waiting for restore process to complete") + f.EventuallyRestoreProcessCompleted(restoreSession.ObjectMeta).Should(BeTrue()) + + return restoreSession, err +} + +func GetTargetRef(name string, kind string) v1beta1.TargetRef { + targetRef := v1beta1.TargetRef{ + Name: name, + } + switch kind { + case apis.KindDeployment: + targetRef.Kind = apis.KindDeployment + targetRef.APIVersion = apps.SchemeGroupVersion.String() + case apis.KindDaemonSet: + targetRef.Kind = apis.KindDaemonSet + targetRef.APIVersion = apps.SchemeGroupVersion.String() + case apis.KindStatefulSet: + targetRef.Kind = apis.KindStatefulSet + targetRef.APIVersion = apps.SchemeGroupVersion.String() + case apis.KindReplicationController: + targetRef.Kind = apis.KindReplicationController + targetRef.APIVersion = core.SchemeGroupVersion.String() + case apis.KindReplicaSet: + targetRef.Kind = apis.KindReplicaSet + targetRef.APIVersion = apps.SchemeGroupVersion.String() + case apis.KindPersistentVolumeClaim: + targetRef.Kind = apis.KindPersistentVolumeClaim + targetRef.APIVersion = core.SchemeGroupVersion.String() + } + return targetRef +} + +func (f Invocation) AddAutoBackupAnnotations(annotations map[string]string, obj interface{}) error { + By("Adding auto-backup specific annotations to the Target") + err := f.AddAnnotations(annotations, obj) + if err != nil { + return err + } + + By("Verifying that the auto-backup annotations has been added successfully") + f.EventuallyAnnotationsFound(annotations, obj).Should(BeTrue()) + return nil +} + +func (f Invocation) VerifyAutoBackupConfigured(workloadMeta metav1.ObjectMeta, kind string) (*v1beta1.BackupConfiguration, error) { + // BackupBlueprint create BackupConfiguration and Repository such that + // the name of the BackupConfiguration and Repository will follow + // the patter: -. + // we will form the meta name and namespace for farther process. + objMeta := metav1.ObjectMeta{ + Namespace: f.Namespace(), + } + switch kind { + case apis.KindDeployment: + objMeta.Name = fmt.Sprintf("deployment-%s", workloadMeta.Name) + case apis.KindDaemonSet: + objMeta.Name = fmt.Sprintf("daemonset-%s", workloadMeta.Name) + case apis.KindStatefulSet: + objMeta.Name = fmt.Sprintf("statefulset-%s", workloadMeta.Name) + case apis.KindReplicationController: + objMeta.Name = fmt.Sprintf("replicationcontroller-%s", workloadMeta.Name) + case apis.KindReplicaSet: + objMeta.Name = fmt.Sprintf("replicaset-%s", workloadMeta.Name) + case apis.KindPersistentVolumeClaim: + objMeta.Name = fmt.Sprintf("persistentvolumeclaim-%s", workloadMeta.Name) + } + + By("Waiting for Repository") + f.EventuallyRepositoryCreated(objMeta).Should(BeTrue()) + + By("Waiting for BackupConfiguration") + f.EventuallyBackupConfigurationCreated(objMeta).Should(BeTrue()) + backupConfig, err := f.StashClient.StashV1beta1().BackupConfigurations(objMeta.Namespace).Get(objMeta.Name, metav1.GetOptions{}) + if err != nil { + return backupConfig, err + } + + By("Verifying that backup triggering CronJob has been created") + f.EventuallyCronJobCreated(objMeta).Should(BeTrue()) + + By("Verifying that sidecar has been injected") + switch kind { + case apis.KindDeployment: + f.EventuallyDeployment(workloadMeta).Should(HaveSidecar(util.StashContainer)) + By("Waiting for Deployment to be ready with sidecar") + err = f.WaitUntilDeploymentReadyWithSidecar(workloadMeta) + case apis.KindDaemonSet: + f.EventuallyDaemonSet(workloadMeta).Should(HaveSidecar(util.StashContainer)) + By("Waiting for DaemonSet to be ready with sidecar") + err = f.WaitUntilDaemonSetReadyWithSidecar(workloadMeta) + case apis.KindStatefulSet: + f.EventuallyStatefulSet(workloadMeta).Should(HaveSidecar(util.StashContainer)) + By("Waiting for StatefulSet to be ready with sidecar") + err = f.WaitUntilStatefulSetReadyWithSidecar(workloadMeta) + case apis.KindReplicaSet: + f.EventuallyReplicaSet(workloadMeta).Should(HaveSidecar(util.StashContainer)) + By("Waiting for ReplicaSet to be ready with sidecar") + err = f.WaitUntilRSReadyWithSidecar(workloadMeta) + case apis.KindReplicationController: + f.EventuallyReplicationController(workloadMeta).Should(HaveSidecar(util.StashContainer)) + By("Waiting for ReplicationController to be ready with sidecar") + err = f.WaitUntilRCReadyWithSidecar(workloadMeta) + } + + return backupConfig, err +} diff --git a/test/e2e/framework/daemonset.go b/test/e2e/framework/daemonset.go index d8e94610f..67fd5784a 100644 --- a/test/e2e/framework/daemonset.go +++ b/test/e2e/framework/daemonset.go @@ -16,9 +16,12 @@ limitations under the License. package framework import ( + "fmt" + "stash.appscode.dev/stash/pkg/util" "github.com/appscode/go/crypto/rand" + . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" apps "k8s.io/api/apps/v1" core "k8s.io/api/core/v1" @@ -27,6 +30,7 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/wait" kutil "kmodules.xyz/client-go" + apps_util "kmodules.xyz/client-go/apps/v1" ) func (fi *Invocation) DaemonSet() apps.DaemonSet { @@ -161,3 +165,24 @@ func (f *Invocation) WaitUntilDaemonSetReadyWithInitContainer(meta metav1.Object return false, nil }) } + +func (f *Invocation) DeployDaemonSet(name string) (*apps.DaemonSet, error) { + // Generate DaemonSet definition + dmn := f.DaemonSet() + dmn.Name = name + + By(fmt.Sprintf("Deploying DaemonSet: %s/%s", dmn.Namespace, dmn.Name)) + createdDmn, err := f.CreateDaemonSet(dmn) + if err != nil { + return createdDmn, err + } + f.AppendToCleanupList(createdDmn) + + By("Waiting for DaemonSet to be ready") + err = apps_util.WaitUntilDaemonSetReady(f.KubeClient, createdDmn.ObjectMeta) + // check that we can execute command to the pod. + // this is necessary because we will exec into the pods and create sample data + f.EventuallyPodAccessible(createdDmn.ObjectMeta).Should(BeTrue()) + + return createdDmn, err +} diff --git a/test/e2e/framework/deployment.go b/test/e2e/framework/deployment.go index fd4fc5b65..ad71ce511 100644 --- a/test/e2e/framework/deployment.go +++ b/test/e2e/framework/deployment.go @@ -16,16 +16,20 @@ limitations under the License. package framework import ( + "time" + "stash.appscode.dev/stash/pkg/util" "github.com/appscode/go/crypto/rand" "github.com/appscode/go/types" + . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" apps "k8s.io/api/apps/v1" kerr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" kutil "kmodules.xyz/client-go" + apps_util "kmodules.xyz/client-go/apps/v1" ) func (fi *Invocation) Deployment(pvcName string) apps.Deployment { @@ -66,7 +70,10 @@ func (f *Framework) EventuallyDeployment(meta metav1.ObjectMeta) GomegaAsyncAsse obj, err := f.KubeClient.AppsV1().Deployments(meta.Namespace).Get(meta.Name, metav1.GetOptions{}) Expect(err).NotTo(HaveOccurred()) return obj - }) + }, + time.Minute*2, + time.Second*5, + ) } func (f *Invocation) WaitUntilDeploymentReadyWithSidecar(meta metav1.ObjectMeta) error { @@ -124,3 +131,31 @@ func (f *Invocation) WaitUntilDeploymentReadyWithInitContainer(meta metav1.Objec return false, nil }) } + +func (f *Invocation) DeployDeployment(name string, replica int32) (*apps.Deployment, error) { + // Create PVC for Deployment + pvc, err := f.CreateNewPVC(name) + if err != nil { + return &apps.Deployment{}, err + } + // Generate Deployment definition + deployment := f.Deployment(pvc.Name) + deployment.Name = name + deployment.Spec.Replicas = &replica + + By("Deploying Deployment: " + deployment.Name) + createdDeployment, err := f.CreateDeployment(deployment) + if err != nil { + return createdDeployment, err + } + f.AppendToCleanupList(createdDeployment) + + By("Waiting for Deployment to be ready") + err = apps_util.WaitUntilDeploymentReady(f.KubeClient, createdDeployment.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + // check that we can execute command to the pod. + // this is necessary because we will exec into the pods and create sample data + f.EventuallyPodAccessible(createdDeployment.ObjectMeta).Should(BeTrue()) + + return createdDeployment, err +} diff --git a/test/e2e/framework/minio_server.go b/test/e2e/framework/minio_server.go index f5bdda847..99140106f 100644 --- a/test/e2e/framework/minio_server.go +++ b/test/e2e/framework/minio_server.go @@ -21,6 +21,7 @@ import ( "path/filepath" "github.com/appscode/go/types" + . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "gomodules.xyz/cert" apps "k8s.io/api/apps/v1" @@ -59,7 +60,7 @@ var ( func (f *Framework) CreateMinioServer(tls bool, ips []net.IP) (string, error) { //creating secret for minio server mcred = f.SecretForMinioServer(ips) - err := f.CreateSecret(mcred) + _, err := f.CreateSecret(mcred) if err != nil { return "", err } @@ -100,7 +101,7 @@ func (f *Framework) SecretForMinioServer(ips []net.IP) core.Secret { return core.Secret{ ObjectMeta: metav1.ObjectMeta{ - Name: MinioServerSecret, + Name: fmt.Sprintf(MinioServerSecret + f.namespace), Namespace: f.namespace, }, Data: map[string][]byte{ @@ -113,7 +114,7 @@ func (f *Framework) SecretForMinioServer(ips []net.IP) core.Secret { func (f *Framework) PVCForMinioServer() core.PersistentVolumeClaim { return core.PersistentVolumeClaim{ ObjectMeta: metav1.ObjectMeta{ - Name: MinioPVCStorage, + Name: fmt.Sprintf(MinioPVCStorage+"%s", f.namespace), Namespace: f.namespace, Labels: map[string]string{ // this label will be used to mount this pvc as volume in minio server container @@ -169,7 +170,7 @@ func (f *Framework) DeploymentForMinioServer() apps.Deployment { Name: "minio-storage", VolumeSource: core.VolumeSource{ PersistentVolumeClaim: &core.PersistentVolumeClaimVolumeSource{ - ClaimName: MinioPVCStorage, + ClaimName: fmt.Sprintf(MinioPVCStorage+"%s", f.namespace), }, }, }, @@ -177,7 +178,7 @@ func (f *Framework) DeploymentForMinioServer() apps.Deployment { Name: "minio-certs", VolumeSource: core.VolumeSource{ Secret: &core.SecretVolumeSource{ - SecretName: MinioServerSecret, + SecretName: fmt.Sprintf(MinioServerSecret+"%s", f.namespace), Items: []core.KeyToPath{ { Key: MINIO_PUBLIC_CRT_NAME, @@ -260,7 +261,7 @@ func (f *Framework) CreateDeploymentForMinioServer(obj apps.Deployment) error { func (f *Framework) ServiceForMinioServer() core.Service { return core.Service{ ObjectMeta: metav1.ObjectMeta{ - Name: MinioNodePortServic, + Name: fmt.Sprintf(MinioNodePortServic+"%s", f.namespace), Namespace: f.namespace, }, Spec: core.ServiceSpec{ @@ -339,6 +340,20 @@ func (f *Framework) MinioServerSANs(ips []net.IP) cert.AltNames { } func (f *Framework) MinioServiceAddres() string { - return fmt.Sprintf(MinioNodePortServic+".%s.svc", f.namespace) + return fmt.Sprintf(MinioNodePortServic+"%s"+".%s.svc", f.namespace, f.namespace) } + +func (f Invocation) CreateBackendSecretForMinio() (*core.Secret, error) { + // Create Storage Secret + cred := f.SecretForMinioBackend(true) + + if missing, _ := BeZero().Match(cred); missing { + Skip("Missing Minio credential") + } + By(fmt.Sprintf("Creating Storage Secret for Minio: %s/%s", cred.Namespace, cred.Name)) + createdCred, err := f.CreateSecret(cred) + f.AppendToCleanupList(&cred) + + return createdCred, err +} diff --git a/test/e2e/framework/pod.go b/test/e2e/framework/pod.go index 847c58743..9628cf0cf 100644 --- a/test/e2e/framework/pod.go +++ b/test/e2e/framework/pod.go @@ -22,11 +22,13 @@ import ( "time" "github.com/appscode/go/crypto/rand" + . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" core "k8s.io/api/core/v1" kerr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" + v1 "kmodules.xyz/client-go/core/v1" ) const ( @@ -199,3 +201,23 @@ func (f *Framework) EventuallyPodAccessible(meta metav1.ObjectMeta) GomegaAsyncA time.Second*2, ) } + +func (f *Invocation) DeployPod(pvcName string) (*core.Pod, error) { + // Generate Pod definition + pod := f.Pod(pvcName) + + By(fmt.Sprintf("Deploying Pod: %s/%s", pod.Namespace, pod.Name)) + createdPod, err := f.CreatePod(pod) + if err != nil { + return createdPod, err + } + f.AppendToCleanupList(createdPod) + + By("Waiting for Pod to be ready") + err = v1.WaitUntilPodRunning(f.KubeClient, createdPod.ObjectMeta) + // check that we can execute command to the pod. + // this is necessary because we will exec into the pods and create sample data + f.EventuallyPodAccessible(createdPod.ObjectMeta).Should(BeTrue()) + + return createdPod, err +} diff --git a/test/e2e/framework/pvc.go b/test/e2e/framework/pvc.go index 3e4049060..9e6e9bc6f 100644 --- a/test/e2e/framework/pvc.go +++ b/test/e2e/framework/pvc.go @@ -16,14 +16,17 @@ limitations under the License. package framework import ( + "fmt" + "github.com/appscode/go/crypto/rand" + . "github.com/onsi/ginkgo" core "k8s.io/api/core/v1" kerr "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -func (f *Invocation) PersistentVolumeClaim() *core.PersistentVolumeClaim { +func (f *Invocation) PersistentVolumeClaim(name string) *core.PersistentVolumeClaim { return &core.PersistentVolumeClaim{ ObjectMeta: metav1.ObjectMeta{ Name: rand.WithUniqSuffix("pvc"), @@ -54,3 +57,14 @@ func (f *Invocation) DeletePersistentVolumeClaim(meta metav1.ObjectMeta) error { } return nil } + +func (f *Invocation) CreateNewPVC(name string) (*core.PersistentVolumeClaim, error) { + // Generate PVC definition + pvc := f.PersistentVolumeClaim(name) + + By(fmt.Sprintf("Creating PVC: %s/%s", pvc.Namespace, pvc.Name)) + createdPVC, err := f.CreatePersistentVolumeClaim(pvc) + f.AppendToCleanupList(createdPVC) + + return createdPVC, err +} diff --git a/test/e2e/framework/replicaset.go b/test/e2e/framework/replicaset.go index 197f22244..ae6327e90 100644 --- a/test/e2e/framework/replicaset.go +++ b/test/e2e/framework/replicaset.go @@ -20,12 +20,14 @@ import ( "github.com/appscode/go/crypto/rand" "github.com/appscode/go/types" + . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" apps "k8s.io/api/apps/v1" kerr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" kutil "kmodules.xyz/client-go" + apps_util "kmodules.xyz/client-go/apps/v1" ) func (fi *Invocation) ReplicaSet(pvcName string) apps.ReplicaSet { @@ -124,3 +126,31 @@ func (f *Invocation) WaitUntilRSReadyWithInitContainer(meta metav1.ObjectMeta) e return false, nil }) } + +func (f *Invocation) DeployReplicaSet(name string, replica int32) (*apps.ReplicaSet, error) { + // Create PVC for ReplicaSet + pvc, err := f.CreateNewPVC(name) + if err != nil { + return &apps.ReplicaSet{}, err + } + // Generate ReplicaSet definition + rs := f.ReplicaSet(pvc.Name) + rs.Spec.Replicas = &replica + rs.Name = name + + By("Deploying ReplicaSet: " + rs.Name) + createdRS, err := f.CreateReplicaSet(rs) + if err != nil { + return createdRS, err + } + f.AppendToCleanupList(createdRS) + + By("Waiting for ReplicaSet to be ready") + err = apps_util.WaitUntilReplicaSetReady(f.KubeClient, createdRS.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + // check that we can execute command to the pod. + // this is necessary because we will exec into the pods and create sample data + f.EventuallyPodAccessible(createdRS.ObjectMeta).Should(BeTrue()) + + return createdRS, err +} diff --git a/test/e2e/framework/replicationcontroller.go b/test/e2e/framework/replicationcontroller.go index 71cbb0bda..7a7498f23 100644 --- a/test/e2e/framework/replicationcontroller.go +++ b/test/e2e/framework/replicationcontroller.go @@ -20,6 +20,7 @@ import ( "github.com/appscode/go/crypto/rand" "github.com/appscode/go/types" + . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" core "k8s.io/api/core/v1" kerr "k8s.io/apimachinery/pkg/api/errors" @@ -124,3 +125,31 @@ func (f *Invocation) WaitUntilRCReadyWithInitContainer(meta metav1.ObjectMeta) e return false, nil }) } + +func (f *Invocation) DeployReplicationController(name string, replica int32) (*core.ReplicationController, error) { + // Create PVC for ReplicationController + pvc, err := f.CreateNewPVC(name) + if err != nil { + return &core.ReplicationController{}, err + } + // Generate ReplicationController definition + rc := f.ReplicationController(pvc.Name) + rc.Spec.Replicas = &replica + rc.Name = name + + By("Deploying ReplicationController: " + rc.Name) + createdRC, err := f.CreateReplicationController(rc) + if err != nil { + return createdRC, err + } + f.AppendToCleanupList(createdRC) + + By("Waiting for ReplicationController to be ready") + err = util.WaitUntilRCReady(f.KubeClient, createdRC.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + // check that we can execute command to the pod. + // this is necessary because we will exec into the pods and create sample data + f.EventuallyPodAccessible(createdRC.ObjectMeta).Should(BeTrue()) + + return createdRC, err +} diff --git a/test/e2e/framework/repository.go b/test/e2e/framework/repository.go index 60557e0db..ccb9d1fee 100644 --- a/test/e2e/framework/repository.go +++ b/test/e2e/framework/repository.go @@ -19,6 +19,7 @@ import ( "fmt" "math" "strconv" + "time" "stash.appscode.dev/stash/apis" api "stash.appscode.dev/stash/apis/stash/v1alpha1" @@ -61,6 +62,19 @@ func (f *Framework) EventuallyRepository(workload interface{}) GomegaAsyncAssert }) } +func (f *Framework) EventuallyRepositoryCreated(meta metav1.ObjectMeta) GomegaAsyncAssertion { + return Eventually(func() bool { + _, err := f.StashClient.StashV1alpha1().Repositories(meta.Namespace).Get(meta.Name, metav1.GetOptions{}) + if err == nil && !kerr.IsNotFound(err) { + return true + } + return false + }, + time.Minute*2, + time.Second*5, + ) +} + func (f *Framework) GetRepositories(kmr KindMetaReplicas) []*api.Repository { repoNames := make([]string, 0) nodeName := f.GetNodeName(kmr.Meta) @@ -211,13 +225,13 @@ func (f *Invocation) SetupLocalRepository() (*api.Repository, error) { // Create Storage Secret By("Creating Storage Secret") cred := f.SecretForLocalBackend() - err := f.CreateSecret(cred) + _, err := f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) f.AppendToCleanupList(&cred) // We are going to use an PVC as backend By("Creating Backend PVC") - backendPVC := f.PersistentVolumeClaim() + backendPVC := f.PersistentVolumeClaim(rand.WithUniqSuffix("pvc")) backendPVC, err = f.CreatePersistentVolumeClaim(backendPVC) Expect(err).NotTo(HaveOccurred()) f.AppendToCleanupList(backendPVC) @@ -238,7 +252,7 @@ func (f *Invocation) SetupGCSRepository() (*api.Repository, error) { if missing, _ := BeZero().Match(cred); missing { Skip("Missing GCS credential") } - err := f.CreateSecret(cred) + _, err := f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) f.AppendToCleanupList(&cred) @@ -258,7 +272,7 @@ func (f *Invocation) SetupMinioRepository() (*api.Repository, error) { if missing, _ := BeZero().Match(cred); missing { Skip("Missing Minio credential") } - err := f.CreateSecret(cred) + _, err := f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) f.AppendToCleanupList(&cred) diff --git a/test/e2e/framework/secret.go b/test/e2e/framework/secret.go index 1532d3821..5826ea566 100644 --- a/test/e2e/framework/secret.go +++ b/test/e2e/framework/secret.go @@ -204,9 +204,9 @@ func (fi *Invocation) SecretForRegistry(dockerCfgJson []byte) core.Secret { // TODO: Add more methods for Swift, Backblaze B2, Rest server backend. -func (f *Framework) CreateSecret(obj core.Secret) error { - _, err := f.KubeClient.CoreV1().Secrets(obj.Namespace).Create(&obj) - return err +func (f *Framework) CreateSecret(obj core.Secret) (*core.Secret, error) { + return f.KubeClient.CoreV1().Secrets(obj.Namespace).Create(&obj) + } func (f *Framework) DeleteSecret(meta metav1.ObjectMeta) error { diff --git a/test/e2e/framework/statefulset.go b/test/e2e/framework/statefulset.go index 1fc24f6ed..6943327f5 100644 --- a/test/e2e/framework/statefulset.go +++ b/test/e2e/framework/statefulset.go @@ -20,6 +20,7 @@ import ( "github.com/appscode/go/crypto/rand" "github.com/appscode/go/types" + . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" apps "k8s.io/api/apps/v1" core "k8s.io/api/core/v1" @@ -28,6 +29,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" kutil "kmodules.xyz/client-go" + apps_util "kmodules.xyz/client-go/apps/v1" ) func (fi *Invocation) StatefulSet(pvcName string) apps.StatefulSet { @@ -193,3 +195,26 @@ func (f *Invocation) WaitUntilStatefulSetWithInitContainer(meta metav1.ObjectMet return false, nil }) } + +func (f *Invocation) DeployStatefulSet(name string, replica int32) (*apps.StatefulSet, error) { + // Generate StatefulSet definition + ss := f.StatefulSetForV1beta1API() + ss.Spec.Replicas = &replica + ss.Name = name + + By("Deploying StatefulSet: " + ss.Name) + createdss, err := f.CreateStatefulSet(ss) + if err != nil { + return createdss, err + } + f.AppendToCleanupList(createdss) + + By("Waiting for StatefulSet to be ready") + err = apps_util.WaitUntilStatefulSetReady(f.KubeClient, createdss.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + // check that we can execute command to the pod. + // this is necessary because we will exec into the pods and create sample data + f.EventuallyPodAccessible(createdss.ObjectMeta).Should(BeTrue()) + + return createdss, err +} diff --git a/test/e2e/framework/util.go b/test/e2e/framework/util.go index ca2dd77f9..0b203fb19 100644 --- a/test/e2e/framework/util.go +++ b/test/e2e/framework/util.go @@ -37,10 +37,14 @@ import ( core "k8s.io/api/core/v1" kerr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/scheme" + "kmodules.xyz/client-go/dynamic" + "kmodules.xyz/client-go/meta" appCatalog "kmodules.xyz/custom-resources/apis/appcatalog/v1alpha1" ocapps "kmodules.xyz/openshift/apis/apps/v1" ) @@ -50,16 +54,20 @@ var ( ) const ( - TestSoucreDemoDataPath = "/data/stash-test/demo-data" - TestSourceDataDir1 = "/source/data/dir-1" - TestSourceDataDir2 = "/source/data/dir-2" - KindRestic = "Restic" - KindRepository = "Repository" - KindRecovery = "Recovery" - PullInterval = time.Second * 2 - WaitTimeOut = time.Minute * 3 - TaskPVCBackup = "pvc-backup" - TaskPVCRestore = "pvc-restore" + TestSoucreDemoDataPath = "/data/stash-test/demo-data" + TestSourceDataDir1 = "/source/data/dir-1" + TestSourceDataDir2 = "/source/data/dir-2" + KindRestic = "Restic" + KindRepository = "Repository" + KindRecovery = "Recovery" + PullInterval = time.Second * 2 + WaitTimeOut = time.Minute * 3 + TaskPVCBackup = "pvc-backup" + TaskPVCRestore = "pvc-restore" + TestSourceDataTargetPath = "/source/data" + TestSourceDataVolumeMount = "source-data:/source/data" + WrongBackupBlueprintName = "backup-blueprint" + WrongTargetPath = "/source/data-1" ) func (f *Framework) EventualEvent(meta metav1.ObjectMeta) GomegaAsyncAssertion { @@ -90,6 +98,20 @@ func (f *Framework) EventualWarning(meta metav1.ObjectMeta, involvedObjectKind s }) } +func (f *Framework) EventuallyEvent(meta metav1.ObjectMeta, involvedObjectKind string) GomegaAsyncAssertion { + return Eventually(func() []core.Event { + fieldSelector := fields.SelectorFromSet(fields.Set{ + "involvedObject.kind": involvedObjectKind, + "involvedObject.name": meta.Name, + "involvedObject.namespace": meta.Namespace, + "type": core.EventTypeWarning, + }) + events, err := f.KubeClient.CoreV1().Events(f.namespace).List(metav1.ListOptions{FieldSelector: fieldSelector.String()}) + Expect(err).NotTo(HaveOccurred()) + return events.Items + }) +} + func (f *Framework) CountSuccessfulBackups(events []core.Event) int { count := 0 for _, e := range events { @@ -216,7 +238,7 @@ func (f *Framework) ReadSampleDataFromMountedDirectory(meta metav1.ObjectMeta, p func (f *Framework) ReadSampleDataFromFromWorkload(meta metav1.ObjectMeta, resourceKind string) (sets.String, error) { switch resourceKind { - case apis.KindDeployment, apis.KindReplicaSet, apis.KindReplicationController, apis.KindPersistentVolumeClaim: + case apis.KindDeployment, apis.KindReplicaSet, apis.KindReplicationController, apis.KindPod: pod, err := f.GetPod(meta) if err != nil { return nil, err @@ -641,7 +663,7 @@ func (f *Framework) GetNodeName(meta metav1.ObjectMeta) string { func (f *Framework) CreateSampleDataInsideWorkload(meta metav1.ObjectMeta, resourceKind string) error { switch resourceKind { - case apis.KindDeployment, apis.KindReplicaSet, apis.KindReplicationController, apis.KindPersistentVolumeClaim: + case apis.KindDeployment, apis.KindReplicaSet, apis.KindReplicationController, apis.KindPod: pod, err := f.GetPod(meta) if err != nil { return err @@ -668,7 +690,7 @@ func (f *Framework) CreateSampleDataInsideWorkload(meta metav1.ObjectMeta, resou func (f *Invocation) CleanupSampleDataFromWorkload(meta metav1.ObjectMeta, resourceKind string) error { switch resourceKind { - case apis.KindDeployment, apis.KindReplicaSet, apis.KindReplicationController, apis.KindPersistentVolumeClaim: + case apis.KindDeployment, apis.KindReplicaSet, apis.KindReplicationController, apis.KindPod: pod, err := f.GetPod(meta) if err != nil { return err @@ -814,3 +836,47 @@ func getGVRAndObjectMeta(obj interface{}) (schema.GroupVersionResource, metav1.O return schema.GroupVersionResource{}, metav1.ObjectMeta{}, fmt.Errorf("failed to get GroupVersionResource. Reason: Unknown resource type") } } + +func (f *Invocation) AddAnnotations(annotations map[string]string, obj interface{}) error { + schm := scheme.Scheme + gvr, _, _ := getGVRAndObjectMeta(obj) + cur := &unstructured.Unstructured{} + err := schm.Convert(obj, cur, nil) + if err != nil { + return err + } + mod := cur.DeepCopy() + mod.SetAnnotations(annotations) + out, _, err := dynamic.PatchObject(f.dmClient, gvr, cur, mod) + if err != nil { + + return err + } + err = schm.Convert(out, obj, nil) + if err != nil { + return err + } + return nil +} + +func (f *Framework) EventuallyAnnotationsFound(expectedAnnotations map[string]string, obj interface{}) GomegaAsyncAssertion { + return Eventually( + func() bool { + schm := scheme.Scheme + cur := &unstructured.Unstructured{} + err := schm.Convert(obj, cur, nil) + if err != nil { + return false + } + annotations := cur.GetAnnotations() + for k, v := range expectedAnnotations { + if !(meta.HasKey(annotations, k) && annotations[k] == v) { + return false + } + } + return true + }, + time.Minute*2, + time.Second*5, + ) +} diff --git a/test/e2e/matcher/auto_backup_event.go b/test/e2e/matcher/auto_backup_event.go new file mode 100644 index 000000000..7f5dd0e8c --- /dev/null +++ b/test/e2e/matcher/auto_backup_event.go @@ -0,0 +1,40 @@ +package matcher + +import ( + "fmt" + + "github.com/onsi/gomega/types" + core "k8s.io/api/core/v1" +) + +func HaveEvent(expected string) types.GomegaMatcher { + return &eventMatcher{ + expected: expected, + } +} + +type eventMatcher struct { + expected string +} + +func (matcher *eventMatcher) Match(actual interface{}) (success bool, err error) { + events := actual.([]core.Event) + return matcher.find(events) +} + +func (matcher *eventMatcher) find(events []core.Event) (success bool, err error) { + for _, e := range events { + if e.Reason == matcher.expected { + return true, nil + } + } + return false, nil +} + +func (matcher *eventMatcher) FailureMessage(actual interface{}) (message string) { + return fmt.Sprintf("Expected\n\t%#v\n to contain event \n\t%#v", actual, matcher.expected) +} + +func (matcher *eventMatcher) NegatedFailureMessage(actual interface{}) (message string) { + return fmt.Sprintf("Expected\n\t%#v\n not to contain the event\n\t%#v", actual, matcher.expected) +} diff --git a/test/e2e/rc_test.go b/test/e2e/rc_test.go index ad8ea6e12..e120c9e4e 100644 --- a/test/e2e/rc_test.go +++ b/test/e2e/rc_test.go @@ -79,7 +79,7 @@ var _ = XDescribe("ReplicationController", func() { } restic.Spec.Backend.StorageSecretName = cred.Name secondRestic.Spec.Backend.StorageSecretName = cred.Name - pvc := f.PersistentVolumeClaim() + pvc := f.PersistentVolumeClaim(rand.WithUniqSuffix("pvc")) _, err := f.CreatePersistentVolumeClaim(pvc) Expect(err).NotTo(HaveOccurred()) rc = f.ReplicationController(pvc.Name) @@ -92,7 +92,7 @@ var _ = XDescribe("ReplicationController", func() { var ( shouldBackupNewReplicationController = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -120,7 +120,7 @@ var _ = XDescribe("ReplicationController", func() { shouldBackupExistingReplicationController = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating ReplicationController " + rc.Name) @@ -148,7 +148,7 @@ var _ = XDescribe("ReplicationController", func() { shouldStopBackup = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -178,7 +178,7 @@ var _ = XDescribe("ReplicationController", func() { shouldStopBackupIfLabelChanged = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -213,7 +213,7 @@ var _ = XDescribe("ReplicationController", func() { shouldStopBackupIfSelectorChanged = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -250,7 +250,7 @@ var _ = XDescribe("ReplicationController", func() { shouldElectLeaderAndBackupRC = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -281,7 +281,7 @@ var _ = XDescribe("ReplicationController", func() { shouldMutateAndBackupNewReplicationController = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -310,7 +310,7 @@ var _ = XDescribe("ReplicationController", func() { shouldNotMutateNewReplicationController = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating ReplicationController " + rc.Name) @@ -323,7 +323,7 @@ var _ = XDescribe("ReplicationController", func() { shouldRejectToCreateNewReplicationController = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating first restic " + restic.Name) @@ -341,7 +341,7 @@ var _ = XDescribe("ReplicationController", func() { shouldRemoveSidecarInstantly = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -376,7 +376,7 @@ var _ = XDescribe("ReplicationController", func() { shouldAddSidecarInstantly = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -651,7 +651,7 @@ var _ = XDescribe("ReplicationController", func() { }) It(`should backup new RC`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -712,7 +712,7 @@ var _ = XDescribe("ReplicationController", func() { }) It(`should backup new Replication Controller`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -782,7 +782,7 @@ var _ = XDescribe("ReplicationController", func() { }) It(`should be able to Pause and Resume backup`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -863,7 +863,7 @@ var _ = XDescribe("ReplicationController", func() { }) It(`should create Repository CRD`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -917,7 +917,7 @@ var _ = XDescribe("ReplicationController", func() { }) It(`recovered volume should have same data`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic") @@ -1013,7 +1013,7 @@ var _ = XDescribe("ReplicationController", func() { }) It(`recovered volume should have same data`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) rc.Spec.Template.Spec.Volumes = f.HostPathVolumeWithMultipleDirectory() @@ -1124,7 +1124,7 @@ var _ = XDescribe("ReplicationController", func() { }) It(`recovered volume should have same data`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic") diff --git a/test/e2e/replicaset_test.go b/test/e2e/replicaset_test.go index 5f909cae2..a9b211188 100644 --- a/test/e2e/replicaset_test.go +++ b/test/e2e/replicaset_test.go @@ -81,7 +81,7 @@ var _ = XDescribe("ReplicaSet", func() { } restic.Spec.Backend.StorageSecretName = cred.Name secondRestic.Spec.Backend.StorageSecretName = cred.Name - pvc := f.PersistentVolumeClaim() + pvc := f.PersistentVolumeClaim(rand.WithUniqSuffix("pvc")) _, err := f.CreatePersistentVolumeClaim(pvc) Expect(err).NotTo(HaveOccurred()) rs = f.ReplicaSet(pvc.Name) @@ -94,7 +94,7 @@ var _ = XDescribe("ReplicaSet", func() { var ( shouldBackupNewReplicaSet = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -122,7 +122,7 @@ var _ = XDescribe("ReplicaSet", func() { shouldBackupExistingReplicaSet = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating ReplicaSet " + rs.Name) @@ -150,7 +150,7 @@ var _ = XDescribe("ReplicaSet", func() { shouldStopBackup = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -179,7 +179,7 @@ var _ = XDescribe("ReplicaSet", func() { shouldStopBackupIfLabelChanged = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -213,7 +213,7 @@ var _ = XDescribe("ReplicaSet", func() { shouldStopBackupIfSelectorChanged = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -250,7 +250,7 @@ var _ = XDescribe("ReplicaSet", func() { shouldElectLeaderAndBackupRS = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -282,7 +282,7 @@ var _ = XDescribe("ReplicaSet", func() { shouldMutateAndBackupNewReplicaSet = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -311,7 +311,7 @@ var _ = XDescribe("ReplicaSet", func() { shouldNotMutateNewReplicaSet = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating ReplicaSet " + rs.Name) @@ -324,7 +324,7 @@ var _ = XDescribe("ReplicaSet", func() { shouldRejectToCreateNewReplicaSet = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating first restic " + restic.Name) @@ -342,7 +342,7 @@ var _ = XDescribe("ReplicaSet", func() { shouldRemoveSidecarInstantly = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -377,7 +377,7 @@ var _ = XDescribe("ReplicaSet", func() { shouldAddSidecarInstantly = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -652,7 +652,7 @@ var _ = XDescribe("ReplicaSet", func() { }) It(`should backup new ReplicaSet`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -713,7 +713,7 @@ var _ = XDescribe("ReplicaSet", func() { }) It(`should backup new ReplicaSet`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -783,7 +783,7 @@ var _ = XDescribe("ReplicaSet", func() { }) It(`should be able to Pause and Resume backup`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -864,7 +864,7 @@ var _ = XDescribe("ReplicaSet", func() { }) It(`should create Repository CRD`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -917,7 +917,7 @@ var _ = XDescribe("ReplicaSet", func() { }) It(`recovered volume should have same data`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic") @@ -1010,7 +1010,7 @@ var _ = XDescribe("ReplicaSet", func() { }) It(`recovered volume should have same data`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) rs.Spec.Template.Spec.Volumes = f.HostPathVolumeWithMultipleDirectory() @@ -1120,7 +1120,7 @@ var _ = XDescribe("ReplicaSet", func() { }) It(`recovered volume should have same data`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic") diff --git a/test/e2e/snapshots_test.go b/test/e2e/snapshots_test.go index d9adcb973..1dfcf7a57 100644 --- a/test/e2e/snapshots_test.go +++ b/test/e2e/snapshots_test.go @@ -26,6 +26,7 @@ import ( "stash.appscode.dev/stash/test/e2e/framework" . "stash.appscode.dev/stash/test/e2e/matcher" + "github.com/appscode/go/crypto/rand" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" apps "k8s.io/api/apps/v1" @@ -117,7 +118,7 @@ var _ = XDescribe("Snapshots", func() { Skip("Missing repository credential") } restic.Spec.Backend.StorageSecretName = cred.Name - pvc := f.PersistentVolumeClaim() + pvc := f.PersistentVolumeClaim(rand.WithUniqSuffix("pvc")) _, err := f.CreatePersistentVolumeClaim(pvc) Expect(err).NotTo(HaveOccurred()) daemon = f.DaemonSet() @@ -216,7 +217,7 @@ var _ = XDescribe("Snapshots", func() { performOperationOnSnapshot = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic") diff --git a/test/e2e/statefulset_test.go b/test/e2e/statefulset_test.go index e63fce8f7..1aefc4e6b 100644 --- a/test/e2e/statefulset_test.go +++ b/test/e2e/statefulset_test.go @@ -84,7 +84,7 @@ var _ = XDescribe("StatefulSet", func() { restic.Spec.Backend.StorageSecretName = cred.Name secondRestic.Spec.Backend.StorageSecretName = cred.Name svc = f.HeadlessService() - pvc := f.PersistentVolumeClaim() + pvc := f.PersistentVolumeClaim(rand.WithUniqSuffix("pvc")) _, err := f.CreatePersistentVolumeClaim(pvc) Expect(err).NotTo(HaveOccurred()) @@ -98,7 +98,7 @@ var _ = XDescribe("StatefulSet", func() { var ( shouldBackupNewStatefulSet = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -132,7 +132,7 @@ var _ = XDescribe("StatefulSet", func() { shouldBackupExistingStatefulSet = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating service " + svc.Name) @@ -166,7 +166,7 @@ var _ = XDescribe("StatefulSet", func() { shouldStopBackup = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -202,7 +202,7 @@ var _ = XDescribe("StatefulSet", func() { shouldStopBackupIfLabelChanged = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -243,7 +243,7 @@ var _ = XDescribe("StatefulSet", func() { shouldStopBackupIfSelectorChanged = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -285,7 +285,7 @@ var _ = XDescribe("StatefulSet", func() { shouldMutateAndBackupNewStatefulSet = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -320,7 +320,7 @@ var _ = XDescribe("StatefulSet", func() { shouldNotMutateNewStatefulSet = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating service " + svc.Name) @@ -337,7 +337,7 @@ var _ = XDescribe("StatefulSet", func() { shouldRejectToCreateNewStatefulSet = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating first restic " + restic.Name) @@ -359,7 +359,7 @@ var _ = XDescribe("StatefulSet", func() { shouldRemoveSidecarInstantly = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -400,7 +400,7 @@ var _ = XDescribe("StatefulSet", func() { shouldAddSidecarInstantly = func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -676,7 +676,7 @@ var _ = XDescribe("StatefulSet", func() { }) It(`should backup new StatefulSet`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -743,7 +743,7 @@ var _ = XDescribe("StatefulSet", func() { }) It(`should backup new StatefulSet`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic " + restic.Name) @@ -820,7 +820,7 @@ var _ = XDescribe("StatefulSet", func() { }) It(`should able to Pause and Resume backup`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic") @@ -908,7 +908,7 @@ var _ = XDescribe("StatefulSet", func() { }) It(`create`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic") @@ -958,7 +958,7 @@ var _ = XDescribe("StatefulSet", func() { }) It(`create`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic") @@ -1018,7 +1018,7 @@ var _ = XDescribe("StatefulSet", func() { }) It(`recovered volume should have same data`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic") @@ -1116,7 +1116,7 @@ var _ = XDescribe("StatefulSet", func() { }) It(`recovered volume should have same data`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) ss.Spec.Template.Spec.Volumes = f.HostPathVolumeWithMultipleDirectory() @@ -1245,7 +1245,7 @@ var _ = XDescribe("StatefulSet", func() { }) It(`recovered volume should have same data`, func() { By("Creating repository Secret " + cred.Name) - err = f.CreateSecret(cred) + _, err = f.CreateSecret(cred) Expect(err).NotTo(HaveOccurred()) By("Creating restic") diff --git a/test/e2e/volumes/volume.go b/test/e2e/volumes/volume.go index 47a6a9ef9..951f7e670 100644 --- a/test/e2e/volumes/volume.go +++ b/test/e2e/volumes/volume.go @@ -24,12 +24,10 @@ import ( "stash.appscode.dev/stash/test/e2e/framework" . "stash.appscode.dev/stash/test/e2e/matcher" - "github.com/appscode/go/sets" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" core "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - v1 "kmodules.xyz/client-go/core/v1" ) var _ = Describe("Volume", func() { @@ -46,99 +44,26 @@ var _ = Describe("Volume", func() { }) var ( - createPVC = func(name string) *core.PersistentVolumeClaim { - // Generate PVC definition - pvc := f.PersistentVolumeClaim() - pvc.Name = name - - By("Creating PVC: " + pvc.Name) - createdPVC, err := f.CreatePersistentVolumeClaim(pvc) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(createdPVC) - - return createdPVC - } - - deployPod = func(pvcName string) *core.Pod { - // Generate Pod definition - pod := f.Pod(pvcName) - - By("Deploying Pod: " + pod.Name) - createdPod, err := f.CreatePod(pod) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(createdPod) - - By("Waiting for Pod to be ready") - err = v1.WaitUntilPodRunning(f.KubeClient, createdPod.ObjectMeta) - Expect(err).NotTo(HaveOccurred()) - // check that we can execute command to the pod. - // this is necessary because we will exec into the pods and create sample data - f.EventuallyPodAccessible(createdPod.ObjectMeta).Should(BeTrue()) - - return createdPod - } - - generateSampleData = func(pod *core.Pod) sets.String { - By("Generating sample data inside Pod") - err := f.CreateSampleDataInsideWorkload(pod.ObjectMeta, apis.KindPersistentVolumeClaim) - Expect(err).NotTo(HaveOccurred()) - - By("Verifying that sample data has been generated") - sampleData, err := f.ReadSampleDataFromFromWorkload(pod.ObjectMeta, apis.KindPersistentVolumeClaim) - Expect(err).NotTo(HaveOccurred()) - Expect(sampleData).ShouldNot(BeEmpty()) - - return sampleData - } - - getTargetRef = func(pvc *core.PersistentVolumeClaim) v1beta1.TargetRef { - return v1beta1.TargetRef{ - Name: pvc.Name, - Kind: apis.KindPersistentVolumeClaim, - APIVersion: "v1", - } - } - - setupPVCBackup = func(pvc *core.PersistentVolumeClaim, repo *api.Repository) *v1beta1.BackupConfiguration { + setupPVCBackup = func(pvc *core.PersistentVolumeClaim, repo *api.Repository) (*v1beta1.BackupConfiguration, error) { // Generate desired BackupConfiguration definition - backupConfig := f.GetBackupConfigurationForWorkload(repo.Name, getTargetRef(pvc)) + backupConfig := f.GetBackupConfigurationForWorkload(repo.Name, framework.GetTargetRef(pvc.Name, apis.KindPersistentVolumeClaim)) backupConfig.Spec.Target = f.PVCBackupTarget(pvc.Name) backupConfig.Spec.Task.Name = framework.TaskPVCBackup By("Creating BackupConfiguration: " + backupConfig.Name) createdBC, err := f.StashClient.StashV1beta1().BackupConfigurations(backupConfig.Namespace).Create(backupConfig) - Expect(err).NotTo(HaveOccurred()) f.AppendToCleanupList(createdBC) By("Verifying that backup triggering CronJob has been created") f.EventuallyCronJobCreated(backupConfig.ObjectMeta).Should(BeTrue()) - return createdBC - } - - takeInstantBackup = func(pvc *core.PersistentVolumeClaim, repo *api.Repository) { - // Setup Backup - backupConfig := setupPVCBackup(pvc, repo) - - // Trigger Instant Backup - By("Triggering Instant Backup") - backupSession, err := f.TriggerInstantBackup(backupConfig) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(backupSession) - - By("Waiting for backup process to complete") - f.EventuallyBackupProcessCompleted(backupSession.ObjectMeta).Should(BeTrue()) - - By("Verifying that BackupSession has succeeded") - completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) - Expect(err).NotTo(HaveOccurred()) - Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) + return createdBC, err } - restoreData = func(pvc *core.PersistentVolumeClaim, pod *core.Pod, repo *api.Repository) sets.String { + setupRestoreProcessForPVC = func(pvc *core.PersistentVolumeClaim, repo *api.Repository) (*v1beta1.RestoreSession, error) { // Generate desired RestoreSession definition By("Creating RestoreSession") - restoreSession := f.GetRestoreSessionForWorkload(repo.Name, getTargetRef(pvc)) + restoreSession := f.GetRestoreSessionForWorkload(repo.Name, framework.GetTargetRef(pvc.Name, apis.KindPersistentVolumeClaim)) restoreSession.Spec.Target = f.PVCRestoreTarget(pvc.Name) restoreSession.Spec.Rules = []v1beta1.Rule{ { @@ -150,56 +75,66 @@ var _ = Describe("Volume", func() { restoreSession.Spec.Task.Name = framework.TaskPVCRestore err := f.CreateRestoreSession(restoreSession) - Expect(err).NotTo(HaveOccurred()) f.AppendToCleanupList(restoreSession) By("Waiting for restore process to complete") f.EventuallyRestoreProcessCompleted(restoreSession.ObjectMeta).Should(BeTrue()) - By("Verifying that RestoreSession succeeded") - completedRS, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) - Expect(err).NotTo(HaveOccurred()) - Expect(completedRS.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) - - By("Reading restored data") - restoredData, err := f.ReadSampleDataFromFromWorkload(pod.ObjectMeta, apis.KindPersistentVolumeClaim) - Expect(err).NotTo(HaveOccurred()) - Expect(restoredData).NotTo(BeEmpty()) - - return restoredData + return restoreSession, err } ) Context("PVC", func() { Context("Restore in same PVC", func() { - It("should Backup & Restore in the source PVC", func() { // Create new PVC - pvc := createPVC(fmt.Sprintf("source-pvc-%s", f.App())) + pvc, err := f.CreateNewPVC(fmt.Sprintf("source-pvc-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + // Deploy a Pod - pod := deployPod(pvc.Name) + pod, err := f.DeployPod(pvc.Name) + Expect(err).NotTo(HaveOccurred()) // Generate Sample Data - sampleData := generateSampleData(pod) + sampleData, err := f.GenerateSampleData(pod.ObjectMeta, apis.KindPod) + Expect(err).NotTo(HaveOccurred()) // Setup a Minio Repository - By("Creating Repository") repo, err := f.SetupMinioRepository() Expect(err).NotTo(HaveOccurred()) f.AppendToCleanupList(repo) + // Setup PVC Backup + backupConfig, err := setupPVCBackup(pvc, repo) + Expect(err).NotTo(HaveOccurred()) + // Take an Instant Backup the Sample Data - takeInstantBackup(pvc, repo) + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has succeeded") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) // Simulate disaster scenario. Delete the data from source PVC By("Deleting sample data from source Pod") - err = f.CleanupSampleDataFromWorkload(pod.ObjectMeta, apis.KindPersistentVolumeClaim) + err = f.CleanupSampleDataFromWorkload(pod.ObjectMeta, apis.KindPod) Expect(err).NotTo(HaveOccurred()) - // Restore the backup data + // Restore the backed up data By("Restoring the backed up data in the original Pod") - restoredData := restoreData(pvc, pod, repo) + restoreSession, err := setupRestoreProcessForPVC(pvc, repo) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that RestoreSession succeeded") + completedRS, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedRS.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) + + // Get restored data + restoredData := f.RestoredData(pod.ObjectMeta, apis.KindPod) // Verify that restored data is same as the original data By("Verifying restored data is same as the original data") @@ -208,34 +143,57 @@ var _ = Describe("Volume", func() { }) Context("Restore in different PVC", func() { - It("should restore backed up data into different PVC", func() { // Create new PVC - pvc := createPVC(fmt.Sprintf("source-pvc-%s", f.App())) + pvc, err := f.CreateNewPVC(fmt.Sprintf("source-pvc1-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + // Deploy a Pod - pod := deployPod(pvc.Name) + pod, err := f.DeployPod(pvc.Name) + Expect(err).NotTo(HaveOccurred()) // Generate Sample Data - sampleData := generateSampleData(pod) + sampleData, err := f.GenerateSampleData(pod.ObjectMeta, apis.KindPod) + Expect(err).NotTo(HaveOccurred()) // Setup a Minio Repository - By("Creating Repository") repo, err := f.SetupMinioRepository() Expect(err).NotTo(HaveOccurred()) f.AppendToCleanupList(repo) + // Setup PVC Backup + backupConfig, err := setupPVCBackup(pvc, repo) + Expect(err).NotTo(HaveOccurred()) + // Take an Instant Backup the Sample Data - takeInstantBackup(pvc, repo) + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has succeeded") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) // Create restored Pvc - restoredPVC := createPVC(fmt.Sprintf("restore-pvc-%s", f.App())) + restoredPVC, err := f.CreateNewPVC(fmt.Sprintf("restore-pvc-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) // Deploy another Pod - restoredPod := deployPod(restoredPVC.Name) + restoredPod, err := f.DeployPod(restoredPVC.Name) + Expect(err).NotTo(HaveOccurred()) + + // Restore the backed up data + By("Restoring the backed up data in the original Pod") + restoreSession, err := setupRestoreProcessForPVC(restoredPVC, repo) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that RestoreSession succeeded") + completedRS, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedRS.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) - // Restore the backup data - By("Restoring the backed up data in the restored PVC") - restoredData := restoreData(restoredPVC, restoredPod, repo) + // Get restored data + restoredData := f.RestoredData(restoredPod.ObjectMeta, apis.KindPod) // Verify that restored data is same as the original data By("Verifying restored data is same as the original data") diff --git a/test/e2e/workloads/daemonset.go b/test/e2e/workloads/daemonset.go index d7a934444..8c157e106 100644 --- a/test/e2e/workloads/daemonset.go +++ b/test/e2e/workloads/daemonset.go @@ -19,139 +19,19 @@ import ( "fmt" "stash.appscode.dev/stash/apis" - api "stash.appscode.dev/stash/apis/stash/v1alpha1" "stash.appscode.dev/stash/apis/stash/v1beta1" - "stash.appscode.dev/stash/pkg/util" "stash.appscode.dev/stash/test/e2e/framework" . "stash.appscode.dev/stash/test/e2e/matcher" - "github.com/appscode/go/sets" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - apps "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - apps_util "kmodules.xyz/client-go/apps/v1" ) var _ = Describe("Workload Test", func() { var f *framework.Invocation - var ( - deployDaemonSet = func(name string) *apps.DaemonSet { - // Generate DaemonSet definition - dmn := f.DaemonSet() - dmn.Name = name - - By("Deploying DaemonSet: " + dmn.Name) - createdDmn, err := f.CreateDaemonSet(dmn) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(createdDmn) - - By("Waiting for DaemonSet to be ready") - err = apps_util.WaitUntilDaemonSetReady(f.KubeClient, dmn.ObjectMeta) - Expect(err).NotTo(HaveOccurred()) - // check that we can execute command to the pod. - // this is necessary because we will exec into the pods and create sample data - f.EventuallyPodAccessible(dmn.ObjectMeta).Should(BeTrue()) - - return createdDmn - } - - generateSampleData = func(dmn *apps.DaemonSet) sets.String { - By("Generating sample data inside daemon pods") - err := f.CreateSampleDataInsideWorkload(dmn.ObjectMeta, apis.KindDaemonSet) - Expect(err).NotTo(HaveOccurred()) - - By("Verifying that sample data has been generated") - sampleData, err := f.ReadSampleDataFromFromWorkload(dmn.ObjectMeta, apis.KindDaemonSet) - Expect(err).NotTo(HaveOccurred()) - Expect(sampleData).ShouldNot(BeEmpty()) - - return sampleData - } - - getTargetRef = func(dmn *apps.DaemonSet) v1beta1.TargetRef { - return v1beta1.TargetRef{ - Name: dmn.Name, - Kind: apis.KindDaemonSet, - APIVersion: "apps/v1", - } - } - - setupDaemonBackup = func(dmn *apps.DaemonSet, repo *api.Repository) *v1beta1.BackupConfiguration { - // Generate desired BackupConfiguration definition - backupConfig := f.GetBackupConfigurationForWorkload(repo.Name, getTargetRef(dmn)) - - By("Creating BackupConfiguration: " + backupConfig.Name) - createdBC, err := f.StashClient.StashV1beta1().BackupConfigurations(backupConfig.Namespace).Create(backupConfig) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(createdBC) - - By("Verifying that backup triggering CronJob has been created") - f.EventuallyCronJobCreated(backupConfig.ObjectMeta).Should(BeTrue()) - - By("Verifying that sidecar has been injected") - f.EventuallyDaemonSet(dmn.ObjectMeta).Should(HaveSidecar(util.StashContainer)) - - By("Waiting for DaemonSet to be ready with sidecar") - err = f.WaitUntilDaemonSetReadyWithSidecar(dmn.ObjectMeta) - Expect(err).NotTo(HaveOccurred()) - - return createdBC - } - - takeInstantBackup = func(dmn *apps.DaemonSet, repo *api.Repository) { - // Setup Backup - backupConfig := setupDaemonBackup(dmn, repo) - - // Trigger Instant Backup - By("Triggering Instant Backup") - backupSession, err := f.TriggerInstantBackup(backupConfig) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(backupSession) - - By("Waiting for backup process to complete") - f.EventuallyBackupProcessCompleted(backupSession.ObjectMeta).Should(BeTrue()) - - By("Verifying that BackupSession has succeeded") - completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) - Expect(err).NotTo(HaveOccurred()) - Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) - } - - restoreData = func(dmn *apps.DaemonSet, repo *api.Repository) sets.String { - By("Creating RestoreSession") - restoreSession := f.GetRestoreSessionForWorkload(repo.Name, getTargetRef(dmn)) - err := f.CreateRestoreSession(restoreSession) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(restoreSession) - - By("Verifying that init-container has been injected") - f.EventuallyDaemonSet(dmn.ObjectMeta).Should(HaveInitContainer(util.StashInitContainer)) - - By("Waiting for restore process to complete") - f.EventuallyRestoreProcessCompleted(restoreSession.ObjectMeta).Should(BeTrue()) - - By("Verifying that RestoreSession succeeded") - completedRS, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) - Expect(err).NotTo(HaveOccurred()) - Expect(completedRS.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) - - By("Waiting for DaemonSet to be ready with init-container") - err = f.WaitUntilDaemonSetReadyWithInitContainer(dmn.ObjectMeta) - Expect(err).NotTo(HaveOccurred()) - f.EventuallyPodAccessible(dmn.ObjectMeta).Should(BeTrue()) - - By("Reading restored data") - restoredData, err := f.ReadSampleDataFromFromWorkload(dmn.ObjectMeta, apis.KindDaemonSet) - Expect(err).NotTo(HaveOccurred()) - Expect(restoredData).NotTo(BeEmpty()) - - return restoredData - } - ) - BeforeEach(func() { f = framework.NewInvocation() }) @@ -164,31 +44,50 @@ var _ = Describe("Workload Test", func() { Context("DaemonSet", func() { Context("Restore in same DaemonSet", func() { - It("should Backup & Restore in the source DaemonSet", func() { // Deploy a DaemonSet - dmn := deployDaemonSet(fmt.Sprintf("source-daemon-%s", f.App())) + dmn, err := f.DeployDaemonSet(fmt.Sprintf("source-daemon1-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) // Generate Sample Data - sampleData := generateSampleData(dmn) + sampleData, err := f.GenerateSampleData(dmn.ObjectMeta, apis.KindDaemonSet) + Expect(err).NotTo(HaveOccurred()) // Setup a Minio Repository - By("Creating Repository") repo, err := f.SetupMinioRepository() Expect(err).NotTo(HaveOccurred()) f.AppendToCleanupList(repo) + // Setup workload Backup + backupConfig, err := f.SetupWorkloadBackup(dmn.ObjectMeta, repo, apis.KindDaemonSet) + Expect(err).NotTo(HaveOccurred()) + // Take an Instant Backup the Sample Data - takeInstantBackup(dmn, repo) + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has succeeded") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) // Simulate disaster scenario. Delete the data from source PVC By("Deleting sample data from source DaemonSet") err = f.CleanupSampleDataFromWorkload(dmn.ObjectMeta, apis.KindDaemonSet) Expect(err).NotTo(HaveOccurred()) - // Restore the backup data + // Restore the backed up data By("Restoring the backed up data in the original DaemonSet") - restoredData := restoreData(dmn, repo) + restoreSession, err := f.SetupRestoreProcess(dmn.ObjectMeta, repo, apis.KindDaemonSet) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that RestoreSession succeeded") + completedRS, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedRS.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) + + // Get restored data + restoredData := f.RestoredData(dmn.ObjectMeta, apis.KindDaemonSet) // Verify that restored data is same as the original data By("Verifying restored data is same as the original data") @@ -197,29 +96,49 @@ var _ = Describe("Workload Test", func() { }) Context("Restore in different DaemonSet", func() { - It("should restore backed up data into different DaemonSet", func() { // Deploy a DaemonSet - dmn := deployDaemonSet(fmt.Sprintf("source-daemon-%s", f.App())) + dmn, err := f.DeployDaemonSet(fmt.Sprintf("source-daemon2-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) // Generate Sample Data - sampleData := generateSampleData(dmn) + sampleData, err := f.GenerateSampleData(dmn.ObjectMeta, apis.KindDaemonSet) + Expect(err).NotTo(HaveOccurred()) // Setup a Minio Repository - By("Creating Repository") repo, err := f.SetupMinioRepository() Expect(err).NotTo(HaveOccurred()) f.AppendToCleanupList(repo) + // Setup workload Backup + backupConfig, err := f.SetupWorkloadBackup(dmn.ObjectMeta, repo, apis.KindDaemonSet) + Expect(err).NotTo(HaveOccurred()) + // Take an Instant Backup the Sample Data - takeInstantBackup(dmn, repo) + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has succeeded") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) // Deploy restored DaemonSet - restoredDmn := deployDaemonSet(fmt.Sprintf("restored-daemon-%s", f.App())) + restoredDmn, err := f.DeployDaemonSet(fmt.Sprintf("restored-daemon-%s", f.App())) + Expect(err).NotTo(HaveOccurred()) + + // Restore the backed up data + By("Restoring the backed up data in different DaemonSet") + restoreSession, err := f.SetupRestoreProcess(restoredDmn.ObjectMeta, repo, apis.KindDaemonSet) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that RestoreSession succeeded") + completedRS, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedRS.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) - // Restore the backup data - By("Restoring the backed up data in the restored DaemonSet") - restoredData := restoreData(restoredDmn, repo) + // Get restored data + restoredData := f.RestoredData(restoredDmn.ObjectMeta, apis.KindDaemonSet) // Verify that restored data is same as the original data By("Verifying restored data is same as the original data") diff --git a/test/e2e/workloads/deployment.go b/test/e2e/workloads/deployment.go index 60ce99bc5..6deaf33a2 100644 --- a/test/e2e/workloads/deployment.go +++ b/test/e2e/workloads/deployment.go @@ -17,23 +17,15 @@ package workloads import ( "fmt" - "strings" "stash.appscode.dev/stash/apis" - api "stash.appscode.dev/stash/apis/stash/v1alpha1" "stash.appscode.dev/stash/apis/stash/v1beta1" - "stash.appscode.dev/stash/pkg/util" "stash.appscode.dev/stash/test/e2e/framework" . "stash.appscode.dev/stash/test/e2e/matcher" - "github.com/appscode/go/sets" - "github.com/appscode/go/types" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - apps "k8s.io/api/apps/v1" - core "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - apps_util "kmodules.xyz/client-go/apps/v1" ) var _ = Describe("Deployment", func() { @@ -49,187 +41,53 @@ var _ = Describe("Deployment", func() { Expect(err).NotTo(HaveOccurred()) }) - var ( - createPVC = func(name string) *core.PersistentVolumeClaim { - // Generate PVC definition - pvc := f.PersistentVolumeClaim() - pvc.Name = fmt.Sprintf("%s-pvc-%s", strings.Split(name, "-")[0], f.App()) - - By("Creating PVC: " + pvc.Name) - createdPVC, err := f.CreatePersistentVolumeClaim(pvc) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(createdPVC) - - return createdPVC - } - - deployDeployment = func(name string) *apps.Deployment { - // Create PVC for Deployment - pvc := createPVC(name) - // Generate Deployment definition - deployment := f.Deployment(pvc.Name) - deployment.Name = name - - By("Deploying Deployment: " + deployment.Name) - createdDeployment, err := f.CreateDeployment(deployment) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(createdDeployment) - - By("Waiting for Deployment to be ready") - err = apps_util.WaitUntilDeploymentReady(f.KubeClient, createdDeployment.ObjectMeta) - Expect(err).NotTo(HaveOccurred()) - // check that we can execute command to the pod. - // this is necessary because we will exec into the pods and create sample data - f.EventuallyPodAccessible(createdDeployment.ObjectMeta).Should(BeTrue()) - - return createdDeployment - } - - deployDeploymentWithMultipleReplica = func(name string) *apps.Deployment { - // Create PVC for Deployment - pvc := createPVC(fmt.Sprintf("source-pvc-%s", f.App())) - // Generate Deployment definition - deployment := f.Deployment(pvc.Name) - deployment.Spec.Replicas = types.Int32P(2) // two replicas - deployment.Name = name - - By("Deploying Deployment: " + deployment.Name) - createdDeployment, err := f.CreateDeployment(deployment) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(createdDeployment) - - By("Waiting for Deployment to be ready") - err = apps_util.WaitUntilDeploymentReady(f.KubeClient, createdDeployment.ObjectMeta) - Expect(err).NotTo(HaveOccurred()) - // check that we can execute command to the pod. - // this is necessary because we will exec into the pods and create sample data - f.EventuallyPodAccessible(createdDeployment.ObjectMeta).Should(BeTrue()) - - return createdDeployment - } - - generateSampleData = func(deployment *apps.Deployment) sets.String { - By("Generating sample data inside Deployment pods") - err := f.CreateSampleDataInsideWorkload(deployment.ObjectMeta, apis.KindDeployment) - Expect(err).NotTo(HaveOccurred()) - - By("Verifying that sample data has been generated") - sampleData, err := f.ReadSampleDataFromFromWorkload(deployment.ObjectMeta, apis.KindDeployment) - Expect(err).NotTo(HaveOccurred()) - Expect(sampleData).ShouldNot(BeEmpty()) - - return sampleData - } - - getTargetRef = func(deployment *apps.Deployment) v1beta1.TargetRef { - return v1beta1.TargetRef{ - Name: deployment.Name, - Kind: apis.KindDeployment, - APIVersion: "apps/v1", - } - } - - setupDeploymentBackup = func(deployment *apps.Deployment, repo *api.Repository) *v1beta1.BackupConfiguration { - // Generate desired BackupConfiguration definition - backupConfig := f.GetBackupConfigurationForWorkload(repo.Name, getTargetRef(deployment)) - - By("Creating BackupConfiguration: " + backupConfig.Name) - createdBC, err := f.StashClient.StashV1beta1().BackupConfigurations(backupConfig.Namespace).Create(backupConfig) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(createdBC) - - By("Verifying that backup triggering CronJob has been created") - f.EventuallyCronJobCreated(backupConfig.ObjectMeta).Should(BeTrue()) - - By("Verifying that sidecar has been injected") - f.EventuallyDeployment(deployment.ObjectMeta).Should(HaveSidecar(util.StashContainer)) - - By("Waiting for Deployment to be ready with sidecar") - err = f.WaitUntilDeploymentReadyWithSidecar(deployment.ObjectMeta) - Expect(err).NotTo(HaveOccurred()) - - return createdBC - } - - takeInstantBackup = func(deployment *apps.Deployment, repo *api.Repository) { - // Setup Backup - backupConfig := setupDeploymentBackup(deployment, repo) - - // Trigger Instant Backup - By("Triggering Instant Backup") - backupSession, err := f.TriggerInstantBackup(backupConfig) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(backupSession) - - By("Waiting for backup process to complete") - f.EventuallyBackupProcessCompleted(backupSession.ObjectMeta).Should(BeTrue()) - - By("Verifying that BackupSession has succeeded") - completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) - Expect(err).NotTo(HaveOccurred()) - Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) - } - - restoreData = func(deployment *apps.Deployment, repo *api.Repository) sets.String { - By("Creating RestoreSession") - restoreSession := f.GetRestoreSessionForWorkload(repo.Name, getTargetRef(deployment)) - err := f.CreateRestoreSession(restoreSession) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(restoreSession) - - By("Verifying that init-container has been injected") - f.EventuallyDeployment(deployment.ObjectMeta).Should(HaveInitContainer(util.StashInitContainer)) - - By("Waiting for restore process to complete") - f.EventuallyRestoreProcessCompleted(restoreSession.ObjectMeta).Should(BeTrue()) - - By("Verifying that RestoreSession succeeded") - completedRS, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) - Expect(err).NotTo(HaveOccurred()) - Expect(completedRS.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) - - By("Waiting for Deployment to be ready with init-container") - err = f.WaitUntilDeploymentReadyWithInitContainer(deployment.ObjectMeta) - Expect(err).NotTo(HaveOccurred()) - f.EventuallyPodAccessible(deployment.ObjectMeta).Should(BeTrue()) - - By("Reading restored data") - restoredData, err := f.ReadSampleDataFromFromWorkload(deployment.ObjectMeta, apis.KindDeployment) - Expect(err).NotTo(HaveOccurred()) - Expect(restoredData).NotTo(BeEmpty()) - - return restoredData - } - ) - Context("Deployment", func() { Context("Restore in same Deployment", func() { - It("should Backup & Restore in the source Deployment", func() { // Deploy a Deployment - deployment := deployDeployment(fmt.Sprintf("source-deployment-%s", f.App())) + deployment, err := f.DeployDeployment(fmt.Sprintf("source-deployment1-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) // Generate Sample Data - sampleData := generateSampleData(deployment) + sampleData, err := f.GenerateSampleData(deployment.ObjectMeta, apis.KindDeployment) + Expect(err).NotTo(HaveOccurred()) // Setup a Minio Repository - By("Creating Repository") repo, err := f.SetupMinioRepository() Expect(err).NotTo(HaveOccurred()) f.AppendToCleanupList(repo) + // Setup workload Backup + backupConfig, err := f.SetupWorkloadBackup(deployment.ObjectMeta, repo, apis.KindDeployment) + Expect(err).NotTo(HaveOccurred()) + // Take an Instant Backup the Sample Data - takeInstantBackup(deployment, repo) + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has succeeded") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) // Simulate disaster scenario. Delete the data from source PVC By("Deleting sample data from source Deployment") err = f.CleanupSampleDataFromWorkload(deployment.ObjectMeta, apis.KindDeployment) Expect(err).NotTo(HaveOccurred()) - // Restore the backup data + // Restore the backed up data By("Restoring the backed up data in the original Deployment") - restoredData := restoreData(deployment, repo) + restoreSession, err := f.SetupRestoreProcess(deployment.ObjectMeta, repo, apis.KindDeployment) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that RestoreSession succeeded") + completedRS, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedRS.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) + + // Get restored data + restoredData := f.RestoredData(deployment.ObjectMeta, apis.KindDeployment) // Verify that restored data is same as the original data By("Verifying restored data is same as the original data") @@ -238,13 +96,14 @@ var _ = Describe("Deployment", func() { }) Context("Restore in different Deployment", func() { - It("should restore backed up data into different Deployment", func() { // Deploy a Deployment - deployment := deployDeployment(fmt.Sprintf("source-deployment-%s", f.App())) + deployment, err := f.DeployDeployment(fmt.Sprintf("source-deployment2-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) // Generate Sample Data - sampleData := generateSampleData(deployment) + sampleData, err := f.GenerateSampleData(deployment.ObjectMeta, apis.KindDeployment) + Expect(err).NotTo(HaveOccurred()) // Setup a Minio Repository By("Creating Repository") @@ -252,15 +111,35 @@ var _ = Describe("Deployment", func() { Expect(err).NotTo(HaveOccurred()) f.AppendToCleanupList(repo) + // Setup workload Backup + backupConfig, err := f.SetupWorkloadBackup(deployment.ObjectMeta, repo, apis.KindDeployment) + Expect(err).NotTo(HaveOccurred()) + // Take an Instant Backup the Sample Data - takeInstantBackup(deployment, repo) + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has succeeded") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) // Deploy restored Deployment - restoredDeployment := deployDeployment(fmt.Sprintf("restored-deployment-%s", f.App())) + restoredDeployment, err := f.DeployDeployment(fmt.Sprintf("restored-deployment-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Restore the backed up data + By("Restoring the backed up data in different Deployment") + restoreSession, err := f.SetupRestoreProcess(restoredDeployment.ObjectMeta, repo, apis.KindDeployment) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that RestoreSession succeeded") + completedRS, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedRS.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) - // Restore the backup data - By("Restoring the backed up data in the restored Deployment") - restoredData := restoreData(restoredDeployment, repo) + // Get restored data + restoredData := f.RestoredData(restoredDeployment.ObjectMeta, apis.KindDeployment) // Verify that restored data is same as the original data By("Verifying restored data is same as the original data") @@ -269,34 +148,30 @@ var _ = Describe("Deployment", func() { }) Context("Leader election for backup and restore Deployment", func() { - It("Should leader elect and backup and restore Deployment", func() { // Deploy a Deployment - deployment := deployDeploymentWithMultipleReplica(fmt.Sprintf("source-deployment-%s", f.App())) + deployment, err := f.DeployDeployment(fmt.Sprintf("source-deployment3-%s", f.App()), int32(2)) + Expect(err).NotTo(HaveOccurred()) // Generate Sample Data - sampleData := generateSampleData(deployment) + sampleData, err := f.GenerateSampleData(deployment.ObjectMeta, apis.KindDeployment) + Expect(err).NotTo(HaveOccurred()) // Setup a Minio Repository - By("Creating Repository") repo, err := f.SetupMinioRepository() Expect(err).NotTo(HaveOccurred()) f.AppendToCleanupList(repo) - // Setup Backup - backupConfig := setupDeploymentBackup(deployment, repo) + // Setup workload Backup + backupConfig, err := f.SetupWorkloadBackup(deployment.ObjectMeta, repo, apis.KindDeployment) + Expect(err).NotTo(HaveOccurred()) By("Waiting for leader election") f.CheckLeaderElection(deployment.ObjectMeta, apis.KindDeployment, v1beta1.ResourceKindBackupConfiguration) - // Create Instant BackupSession Trigger Instant Backup - By("Triggering Instant Backup") - backupSession, err := f.TriggerInstantBackup(backupConfig) + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(backupSession) - - By("Waiting for backup process to complete") - f.EventuallyBackupProcessCompleted(backupSession.ObjectMeta).Should(BeTrue()) By("Verifying that BackupSession has succeeded") completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) @@ -308,9 +183,18 @@ var _ = Describe("Deployment", func() { err = f.CleanupSampleDataFromWorkload(deployment.ObjectMeta, apis.KindDeployment) Expect(err).NotTo(HaveOccurred()) - // Restore the backup data + // Restore the backed up data By("Restoring the backed up data in the original Deployment") - restoredData := restoreData(deployment, repo) + restoreSession, err := f.SetupRestoreProcess(deployment.ObjectMeta, repo, apis.KindDeployment) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that RestoreSession succeeded") + completedRS, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedRS.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) + + // Get restored data + restoredData := f.RestoredData(deployment.ObjectMeta, apis.KindDeployment) // Verify that restored data is same as the original data By("Verifying restored data is same as the original data") diff --git a/test/e2e/workloads/replicaset.go b/test/e2e/workloads/replicaset.go index e39ebcda5..8eada616c 100644 --- a/test/e2e/workloads/replicaset.go +++ b/test/e2e/workloads/replicaset.go @@ -17,23 +17,15 @@ package workloads import ( "fmt" - "strings" "stash.appscode.dev/stash/apis" - api "stash.appscode.dev/stash/apis/stash/v1alpha1" "stash.appscode.dev/stash/apis/stash/v1beta1" - "stash.appscode.dev/stash/pkg/util" "stash.appscode.dev/stash/test/e2e/framework" . "stash.appscode.dev/stash/test/e2e/matcher" - "github.com/appscode/go/sets" - "github.com/appscode/go/types" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - apps "k8s.io/api/apps/v1" - core "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - apps_util "kmodules.xyz/client-go/apps/v1" ) var _ = Describe("ReplicaSet", func() { @@ -49,187 +41,53 @@ var _ = Describe("ReplicaSet", func() { Expect(err).NotTo(HaveOccurred()) }) - var ( - createPVC = func(name string) *core.PersistentVolumeClaim { - // Generate PVC definition - pvc := f.PersistentVolumeClaim() - pvc.Name = fmt.Sprintf("%s-pvc-%s", strings.Split(name, "-")[0], f.App()) - - By("Creating PVC: " + pvc.Name) - createdPVC, err := f.CreatePersistentVolumeClaim(pvc) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(createdPVC) - - return createdPVC - } - - deployRS = func(name string) *apps.ReplicaSet { - // Create PVC for ReplicaSet - pvc := createPVC(name) - // Generate ReplicaSet definition - rs := f.ReplicaSet(pvc.Name) - rs.Name = name - - By("Deploying ReplicaSet: " + rs.Name) - createdRS, err := f.CreateReplicaSet(rs) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(createdRS) - - By("Waiting for ReplicaSet to be ready") - err = apps_util.WaitUntilReplicaSetReady(f.KubeClient, createdRS.ObjectMeta) - Expect(err).NotTo(HaveOccurred()) - // check that we can execute command to the pod. - // this is necessary because we will exec into the pods and create sample data - f.EventuallyPodAccessible(createdRS.ObjectMeta).Should(BeTrue()) - - return createdRS - } - - deployRSWithMultipleReplica = func(name string) *apps.ReplicaSet { - // Create PVC for ReplicaSet - pvc := createPVC(fmt.Sprintf("source-pvc-%s", f.App())) - // Generate ReplicaSet definition - rs := f.ReplicaSet(pvc.Name) - rs.Spec.Replicas = types.Int32P(2) // two replicas - rs.Name = name - - By("Deploying ReplicaSet: " + rs.Name) - createdRS, err := f.CreateReplicaSet(rs) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(createdRS) - - By("Waiting for ReplicaSet to be ready") - err = apps_util.WaitUntilReplicaSetReady(f.KubeClient, createdRS.ObjectMeta) - Expect(err).NotTo(HaveOccurred()) - // check that we can execute command to the pod. - // this is necessary because we will exec into the pods and create sample data - f.EventuallyPodAccessible(createdRS.ObjectMeta).Should(BeTrue()) - - return createdRS - } - - generateSampleData = func(rs *apps.ReplicaSet) sets.String { - By("Generating sample data inside ReplicaSet pods") - err := f.CreateSampleDataInsideWorkload(rs.ObjectMeta, apis.KindReplicaSet) - Expect(err).NotTo(HaveOccurred()) - - By("Verifying that sample data has been generated") - sampleData, err := f.ReadSampleDataFromFromWorkload(rs.ObjectMeta, apis.KindReplicaSet) - Expect(err).NotTo(HaveOccurred()) - Expect(sampleData).ShouldNot(BeEmpty()) - - return sampleData - } - - getTargetRef = func(rs *apps.ReplicaSet) v1beta1.TargetRef { - return v1beta1.TargetRef{ - Name: rs.Name, - Kind: apis.KindReplicaSet, - APIVersion: "apps/v1", - } - } - - setupRSBackup = func(rs *apps.ReplicaSet, repo *api.Repository) *v1beta1.BackupConfiguration { - // Generate desired BackupConfiguration definition - backupConfig := f.GetBackupConfigurationForWorkload(repo.Name, getTargetRef(rs)) - - By("Creating BackupConfiguration: " + backupConfig.Name) - createdBC, err := f.StashClient.StashV1beta1().BackupConfigurations(backupConfig.Namespace).Create(backupConfig) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(createdBC) - - By("Verifying that backup triggering CronJob has been created") - f.EventuallyCronJobCreated(backupConfig.ObjectMeta).Should(BeTrue()) - - By("Verifying that sidecar has been injected") - f.EventuallyReplicaSet(rs.ObjectMeta).Should(HaveSidecar(util.StashContainer)) - - By("Waiting for ReplicaSet to be ready with sidecar") - err = f.WaitUntilRSReadyWithSidecar(rs.ObjectMeta) - Expect(err).NotTo(HaveOccurred()) - - return createdBC - } - - takeInstantBackup = func(rs *apps.ReplicaSet, repo *api.Repository) { - // Setup Backup - backupConfig := setupRSBackup(rs, repo) - - // Trigger Instant Backup - By("Triggering Instant Backup") - backupSession, err := f.TriggerInstantBackup(backupConfig) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(backupSession) - - By("Waiting for backup process to complete") - f.EventuallyBackupProcessCompleted(backupSession.ObjectMeta).Should(BeTrue()) - - By("Verifying that BackupSession has succeeded") - completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) - Expect(err).NotTo(HaveOccurred()) - Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) - } - - restoreData = func(rs *apps.ReplicaSet, repo *api.Repository) sets.String { - By("Creating RestoreSession") - restoreSession := f.GetRestoreSessionForWorkload(repo.Name, getTargetRef(rs)) - err := f.CreateRestoreSession(restoreSession) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(restoreSession) - - By("Verifying that init-container has been injected") - f.EventuallyReplicaSet(rs.ObjectMeta).Should(HaveInitContainer(util.StashInitContainer)) - - By("Waiting for restore process to complete") - f.EventuallyRestoreProcessCompleted(restoreSession.ObjectMeta).Should(BeTrue()) - - By("Verifying that RestoreSession succeeded") - completedRestore, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) - Expect(err).NotTo(HaveOccurred()) - Expect(completedRestore.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) - - By("Waiting for ReplicaSet to be ready with init-container") - err = f.WaitUntilRSReadyWithInitContainer(rs.ObjectMeta) - Expect(err).NotTo(HaveOccurred()) - f.EventuallyPodAccessible(rs.ObjectMeta).Should(BeTrue()) - - By("Reading restored data") - restoredData, err := f.ReadSampleDataFromFromWorkload(rs.ObjectMeta, apis.KindReplicaSet) - Expect(err).NotTo(HaveOccurred()) - Expect(restoredData).NotTo(BeEmpty()) - - return restoredData - } - ) - Context("ReplicaSet", func() { Context("Restore in same ReplicaSet", func() { - It("should Backup & Restore in the source ReplicaSet", func() { // Deploy a ReplicaSet - rs := deployRS(fmt.Sprintf("source-rs-%s", f.App())) + rs, err := f.DeployReplicaSet(fmt.Sprintf("source-rs1-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) // Generate Sample Data - sampleData := generateSampleData(rs) + sampleData, err := f.GenerateSampleData(rs.ObjectMeta, apis.KindReplicaSet) + Expect(err).NotTo(HaveOccurred()) // Setup a Minio Repository - By("Creating Repository") repo, err := f.SetupMinioRepository() Expect(err).NotTo(HaveOccurred()) f.AppendToCleanupList(repo) + // Setup workload Backup + backupConfig, err := f.SetupWorkloadBackup(rs.ObjectMeta, repo, apis.KindReplicaSet) + Expect(err).NotTo(HaveOccurred()) + // Take an Instant Backup the Sample Data - takeInstantBackup(rs, repo) + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has succeeded") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) // Simulate disaster scenario. Delete the data from source PVC By("Deleting sample data from source ReplicaSet") err = f.CleanupSampleDataFromWorkload(rs.ObjectMeta, apis.KindReplicaSet) Expect(err).NotTo(HaveOccurred()) - // Restore the backup data + // Restore the backed up data By("Restoring the backed up data in the original ReplicaSet") - restoredData := restoreData(rs, repo) + restoreSession, err := f.SetupRestoreProcess(rs.ObjectMeta, repo, apis.KindReplicaSet) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that RestoreSession succeeded") + completedRS, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedRS.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) + + // Get restored data + restoredData := f.RestoredData(rs.ObjectMeta, apis.KindReplicaSet) // Verify that restored data is same as the original data By("Verifying restored data is same as the original data") @@ -238,29 +96,49 @@ var _ = Describe("ReplicaSet", func() { }) Context("Restore in different ReplicaSet", func() { - It("should restore backed up data into different ReplicaSet", func() { // Deploy a ReplicaSet - rs := deployRS(fmt.Sprintf("source-rs-%s", f.App())) + rs, err := f.DeployReplicaSet(fmt.Sprintf("source-rs2-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) // Generate Sample Data - sampleData := generateSampleData(rs) + sampleData, err := f.GenerateSampleData(rs.ObjectMeta, apis.KindReplicaSet) + Expect(err).NotTo(HaveOccurred()) // Setup a Minio Repository - By("Creating Repository") repo, err := f.SetupMinioRepository() Expect(err).NotTo(HaveOccurred()) f.AppendToCleanupList(repo) + // Setup workload Backup + backupConfig, err := f.SetupWorkloadBackup(rs.ObjectMeta, repo, apis.KindReplicaSet) + Expect(err).NotTo(HaveOccurred()) + // Take an Instant Backup the Sample Data - takeInstantBackup(rs, repo) + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has succeeded") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) // Deploy restored ReplicaSet - restoredRS := deployRS(fmt.Sprintf("restored-rs-%s", f.App())) + restoredRS, err := f.DeployReplicaSet(fmt.Sprintf("restored-rs-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Restore the backed up data + By("Restoring the backed up data in different ReplicaSet") + restoreSession, err := f.SetupRestoreProcess(restoredRS.ObjectMeta, repo, apis.KindReplicaSet) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that RestoreSession succeeded") + completedRS, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedRS.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) - // Restore the backup data - By("Restoring the backed up data in the restored ReplicaSet") - restoredData := restoreData(restoredRS, repo) + // Get restored data + restoredData := f.RestoredData(restoredRS.ObjectMeta, apis.KindReplicaSet) // Verify that restored data is same as the original data By("Verifying restored data is same as the original data") @@ -269,34 +147,30 @@ var _ = Describe("ReplicaSet", func() { }) Context("Leader election for backup and restore ReplicaSet", func() { - It("Should leader elect and backup and restore ReplicaSet", func() { // Deploy a ReplicaSet - rs := deployRSWithMultipleReplica(fmt.Sprintf("source-rs-%s", f.App())) + rs, err := f.DeployReplicaSet(fmt.Sprintf("source-rs3-%s", f.App()), int32(2)) + Expect(err).NotTo(HaveOccurred()) // Generate Sample Data - sampleData := generateSampleData(rs) + sampleData, err := f.GenerateSampleData(rs.ObjectMeta, apis.KindReplicaSet) + Expect(err).NotTo(HaveOccurred()) // Setup a Minio Repository - By("Creating Repository") repo, err := f.SetupMinioRepository() Expect(err).NotTo(HaveOccurred()) f.AppendToCleanupList(repo) - // Setup Backup - backupConfig := setupRSBackup(rs, repo) + // Setup workload Backup + backupConfig, err := f.SetupWorkloadBackup(rs.ObjectMeta, repo, apis.KindReplicaSet) + Expect(err).NotTo(HaveOccurred()) By("Waiting for leader election") f.CheckLeaderElection(rs.ObjectMeta, apis.KindReplicaSet, v1beta1.ResourceKindBackupConfiguration) - // Create Instant BackupSession for Trigger Instant Backup - By("Triggering Instant Backup") - backupSession, err := f.TriggerInstantBackup(backupConfig) + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(backupSession) - - By("Waiting for backup process to complete") - f.EventuallyBackupProcessCompleted(backupSession.ObjectMeta).Should(BeTrue()) By("Verifying that BackupSession has succeeded") completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) @@ -308,9 +182,18 @@ var _ = Describe("ReplicaSet", func() { err = f.CleanupSampleDataFromWorkload(rs.ObjectMeta, apis.KindReplicaSet) Expect(err).NotTo(HaveOccurred()) - // Restore the backup data + // Restore the backed up data By("Restoring the backed up data in the original ReplicaSet") - restoredData := restoreData(rs, repo) + restoreSession, err := f.SetupRestoreProcess(rs.ObjectMeta, repo, apis.KindReplicaSet) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that RestoreSession succeeded") + completedRS, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedRS.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) + + // Get restored data + restoredData := f.RestoredData(rs.ObjectMeta, apis.KindReplicaSet) // Verify that restored data is same as the original data By("Verifying restored data is same as the original data") diff --git a/test/e2e/workloads/replicationcontroller.go b/test/e2e/workloads/replicationcontroller.go index 2dab9d9d3..6e7901298 100644 --- a/test/e2e/workloads/replicationcontroller.go +++ b/test/e2e/workloads/replicationcontroller.go @@ -17,20 +17,14 @@ package workloads import ( "fmt" - "strings" "stash.appscode.dev/stash/apis" - api "stash.appscode.dev/stash/apis/stash/v1alpha1" "stash.appscode.dev/stash/apis/stash/v1beta1" - "stash.appscode.dev/stash/pkg/util" "stash.appscode.dev/stash/test/e2e/framework" . "stash.appscode.dev/stash/test/e2e/matcher" - "github.com/appscode/go/sets" - "github.com/appscode/go/types" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - core "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -47,187 +41,53 @@ var _ = Describe("ReplicationController", func() { Expect(err).NotTo(HaveOccurred()) }) - var ( - createPVC = func(name string) *core.PersistentVolumeClaim { - // Generate PVC definition - pvc := f.PersistentVolumeClaim() - pvc.Name = fmt.Sprintf("%s-pvc-%s", strings.Split(name, "-")[0], f.App()) - - By("Creating PVC: " + pvc.Name) - createdPVC, err := f.CreatePersistentVolumeClaim(pvc) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(createdPVC) - - return createdPVC - } - - deployRC = func(name string) *core.ReplicationController { - // Create PVC for ReplicationController - pvc := createPVC(name) - // Generate ReplicationController definition - rc := f.ReplicationController(pvc.Name) - rc.Name = name - - By("Deploying ReplicationController: " + rc.Name) - createdRC, err := f.CreateReplicationController(rc) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(createdRC) - - By("Waiting for ReplicationController to be ready") - err = util.WaitUntilRCReady(f.KubeClient, createdRC.ObjectMeta) - Expect(err).NotTo(HaveOccurred()) - // check that we can execute command to the pod. - // this is necessary because we will exec into the pods and create sample data - f.EventuallyPodAccessible(createdRC.ObjectMeta).Should(BeTrue()) - - return createdRC - } - - deployRCWithMultipleReplica = func(name string) *core.ReplicationController { - // Create PVC for ReplicationController - pvc := createPVC(fmt.Sprintf("source-pvc-%s", f.App())) - // Generate ReplicationController definition - rc := f.ReplicationController(pvc.Name) - rc.Spec.Replicas = types.Int32P(2) // two replicas - rc.Name = name - - By("Deploying ReplicationController: " + rc.Name) - createdRC, err := f.CreateReplicationController(rc) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(createdRC) - - By("Waiting for ReplicationController to be ready") - err = util.WaitUntilRCReady(f.KubeClient, createdRC.ObjectMeta) - Expect(err).NotTo(HaveOccurred()) - // check that we can execute command to the pod. - // this is necessary because we will exec into the pods and create sample data - f.EventuallyPodAccessible(createdRC.ObjectMeta).Should(BeTrue()) - - return createdRC - } - - generateSampleData = func(rc *core.ReplicationController) sets.String { - By("Generating sample data inside ReplicationController pods") - err := f.CreateSampleDataInsideWorkload(rc.ObjectMeta, apis.KindReplicationController) - Expect(err).NotTo(HaveOccurred()) - - By("Verifying that sample data has been generated") - sampleData, err := f.ReadSampleDataFromFromWorkload(rc.ObjectMeta, apis.KindReplicationController) - Expect(err).NotTo(HaveOccurred()) - Expect(sampleData).ShouldNot(BeEmpty()) - - return sampleData - } - - getTargetRef = func(rc *core.ReplicationController) v1beta1.TargetRef { - return v1beta1.TargetRef{ - Name: rc.Name, - Kind: apis.KindReplicationController, - APIVersion: "v1", - } - } - - setupRCBackup = func(rc *core.ReplicationController, repo *api.Repository) *v1beta1.BackupConfiguration { - // Generate desired BackupConfiguration definition - backupConfig := f.GetBackupConfigurationForWorkload(repo.Name, getTargetRef(rc)) - - By("Creating BackupConfiguration: " + backupConfig.Name) - createdBC, err := f.StashClient.StashV1beta1().BackupConfigurations(backupConfig.Namespace).Create(backupConfig) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(createdBC) - - By("Verifying that backup triggering CronJob has been created") - f.EventuallyCronJobCreated(backupConfig.ObjectMeta).Should(BeTrue()) - - By("Verifying that sidecar has been injected") - f.EventuallyReplicationController(rc.ObjectMeta).Should(HaveSidecar(util.StashContainer)) - - By("Waiting for ReplicationController to be ready with sidecar") - err = f.WaitUntilRCReadyWithSidecar(rc.ObjectMeta) - Expect(err).NotTo(HaveOccurred()) - - return createdBC - } - - takeInstantBackup = func(rc *core.ReplicationController, repo *api.Repository) { - // Setup Backup - backupConfig := setupRCBackup(rc, repo) - - // Trigger Instant Backup - By("Triggering Instant Backup") - backupSession, err := f.TriggerInstantBackup(backupConfig) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(backupSession) - - By("Waiting for backup process to complete") - f.EventuallyBackupProcessCompleted(backupSession.ObjectMeta).Should(BeTrue()) - - By("Verifying that BackupSession has succeeded") - completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) - Expect(err).NotTo(HaveOccurred()) - Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) - } - - restoreData = func(rc *core.ReplicationController, repo *api.Repository) sets.String { - By("Creating RestoreSession") - restoreSession := f.GetRestoreSessionForWorkload(repo.Name, getTargetRef(rc)) - err := f.CreateRestoreSession(restoreSession) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(restoreSession) - - By("Verifying that init-container has been injected") - f.EventuallyReplicationController(rc.ObjectMeta).Should(HaveInitContainer(util.StashInitContainer)) - - By("Waiting for restore process to complete") - f.EventuallyRestoreProcessCompleted(restoreSession.ObjectMeta).Should(BeTrue()) - - By("Verifying that RestoreSession succeeded") - completedRestore, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) - Expect(err).NotTo(HaveOccurred()) - Expect(completedRestore.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) - - By("Waiting for ReplicationController to be ready with init-container") - err = f.WaitUntilRCReadyWithInitContainer(rc.ObjectMeta) - Expect(err).NotTo(HaveOccurred()) - f.EventuallyPodAccessible(rc.ObjectMeta).Should(BeTrue()) - - By("Reading restored data") - restoredData, err := f.ReadSampleDataFromFromWorkload(rc.ObjectMeta, apis.KindReplicationController) - Expect(err).NotTo(HaveOccurred()) - Expect(restoredData).NotTo(BeEmpty()) - - return restoredData - } - ) - Context("ReplicationController", func() { Context("Restore in same ReplicationController", func() { - It("should Backup & Restore in the source ReplicationController", func() { // Deploy a ReplicationController - rc := deployRC(fmt.Sprintf("source-rc-%s", f.App())) + rc, err := f.DeployReplicationController(fmt.Sprintf("source-rc1-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) // Generate Sample Data - sampleData := generateSampleData(rc) + sampleData, err := f.GenerateSampleData(rc.ObjectMeta, apis.KindReplicationController) + Expect(err).NotTo(HaveOccurred()) // Setup a Minio Repository - By("Creating Repository") repo, err := f.SetupMinioRepository() Expect(err).NotTo(HaveOccurred()) f.AppendToCleanupList(repo) + // Setup workload Backup + backupConfig, err := f.SetupWorkloadBackup(rc.ObjectMeta, repo, apis.KindReplicationController) + Expect(err).NotTo(HaveOccurred()) + // Take an Instant Backup the Sample Data - takeInstantBackup(rc, repo) + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has succeeded") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) // Simulate disaster scenario. Delete the data from source PVC By("Deleting sample data from source ReplicationController") err = f.CleanupSampleDataFromWorkload(rc.ObjectMeta, apis.KindReplicationController) Expect(err).NotTo(HaveOccurred()) - // Restore the backup data + // Restore the backed up data By("Restoring the backed up data in the original ReplicationController") - restoredData := restoreData(rc, repo) + restoreSession, err := f.SetupRestoreProcess(rc.ObjectMeta, repo, apis.KindReplicationController) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that RestoreSession succeeded") + completedRS, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedRS.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) + + // Get restored data + restoredData := f.RestoredData(rc.ObjectMeta, apis.KindReplicationController) // Verify that restored data is same as the original data By("Verifying restored data is same as the original data") @@ -236,29 +96,49 @@ var _ = Describe("ReplicationController", func() { }) Context("Restore in different ReplicationController", func() { - It("should restore backed up data into different ReplicationController", func() { // Deploy a ReplicationController - rc := deployRC(fmt.Sprintf("source-rc-%s", f.App())) + rc, err := f.DeployReplicationController(fmt.Sprintf("source-rc2-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) // Generate Sample Data - sampleData := generateSampleData(rc) + sampleData, err := f.GenerateSampleData(rc.ObjectMeta, apis.KindReplicationController) + Expect(err).NotTo(HaveOccurred()) // Setup a Minio Repository - By("Creating Repository") repo, err := f.SetupMinioRepository() Expect(err).NotTo(HaveOccurred()) f.AppendToCleanupList(repo) + // Setup workload Backup + backupConfig, err := f.SetupWorkloadBackup(rc.ObjectMeta, repo, apis.KindReplicationController) + Expect(err).NotTo(HaveOccurred()) + // Take an Instant Backup the Sample Data - takeInstantBackup(rc, repo) + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has succeeded") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) // Deploy restored ReplicationController - restoredRC := deployRC(fmt.Sprintf("restored-rc-%s", f.App())) + restoredRC, err := f.DeployReplicationController(fmt.Sprintf("restored-rc-%s", f.App()), int32(1)) + Expect(err).NotTo(HaveOccurred()) + + // Restore the backed up data + By("Restoring the backed up data in different ReplicationController") + restoreSession, err := f.SetupRestoreProcess(restoredRC.ObjectMeta, repo, apis.KindReplicationController) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that RestoreSession succeeded") + completedRS, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedRS.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) - // Restore the backup data - By("Restoring the backed up data in the restored ReplicationController") - restoredData := restoreData(restoredRC, repo) + // Get restored data + restoredData := f.RestoredData(restoredRC.ObjectMeta, apis.KindReplicationController) // Verify that restored data is same as the original data By("Verifying restored data is same as the original data") @@ -267,34 +147,30 @@ var _ = Describe("ReplicationController", func() { }) Context("Leader election for backup and restore ReplicationController", func() { - It("Should leader elect and backup and restore ReplicationController", func() { // Deploy a ReplicationController - rc := deployRCWithMultipleReplica(fmt.Sprintf("source-rc-%s", f.App())) + rc, err := f.DeployReplicationController(fmt.Sprintf("source-rc3-%s", f.App()), int32(2)) + Expect(err).NotTo(HaveOccurred()) // Generate Sample Data - sampleData := generateSampleData(rc) + sampleData, err := f.GenerateSampleData(rc.ObjectMeta, apis.KindReplicationController) + Expect(err).NotTo(HaveOccurred()) // Setup a Minio Repository - By("Creating Repository") repo, err := f.SetupMinioRepository() Expect(err).NotTo(HaveOccurred()) f.AppendToCleanupList(repo) - // Setup Backup - backupConfig := setupRCBackup(rc, repo) + // Setup workload Backup + backupConfig, err := f.SetupWorkloadBackup(rc.ObjectMeta, repo, apis.KindReplicationController) + Expect(err).NotTo(HaveOccurred()) By("Waiting for leader election") f.CheckLeaderElection(rc.ObjectMeta, apis.KindReplicationController, v1beta1.ResourceKindBackupConfiguration) - // Create Instant BackupSession for Trigger Instant Backup - By("Triggering Instant Backup") - backupSession, err := f.TriggerInstantBackup(backupConfig) + // Take an Instant Backup the Sample Data + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(backupSession) - - By("Waiting for backup process to complete") - f.EventuallyBackupProcessCompleted(backupSession.ObjectMeta).Should(BeTrue()) By("Verifying that BackupSession has succeeded") completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) @@ -306,9 +182,18 @@ var _ = Describe("ReplicationController", func() { err = f.CleanupSampleDataFromWorkload(rc.ObjectMeta, apis.KindReplicationController) Expect(err).NotTo(HaveOccurred()) - // Restore the backup data + // Restore the backed up data By("Restoring the backed up data in the original ReplicationController") - restoredData := restoreData(rc, repo) + restoreSession, err := f.SetupRestoreProcess(rc.ObjectMeta, repo, apis.KindReplicationController) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that RestoreSession succeeded") + completedRS, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedRS.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) + + // Get restored data + restoredData := f.RestoredData(rc.ObjectMeta, apis.KindReplicationController) // Verify that restored data is same as the original data By("Verifying restored data is same as the original data") diff --git a/test/e2e/workloads/statefulset.go b/test/e2e/workloads/statefulset.go index 42496e523..4b9080eae 100644 --- a/test/e2e/workloads/statefulset.go +++ b/test/e2e/workloads/statefulset.go @@ -25,13 +25,10 @@ import ( "stash.appscode.dev/stash/test/e2e/framework" . "stash.appscode.dev/stash/test/e2e/matcher" - "github.com/appscode/go/sets" - "github.com/appscode/go/types" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" apps "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - apps_util "kmodules.xyz/client-go/apps/v1" ) var _ = Describe("StatefulSet", func() { @@ -48,147 +45,9 @@ var _ = Describe("StatefulSet", func() { }) var ( - deploySS = func(name string) *apps.StatefulSet { - // Generate StatefulSet definition - ss := f.StatefulSetForV1beta1API() - ss.Name = name - - By("Deploying StatefulSet: " + ss.Name) - createdss, err := f.CreateStatefulSet(ss) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(createdss) - - By("Waiting for StatefulSet to be ready") - err = apps_util.WaitUntilStatefulSetReady(f.KubeClient, createdss.ObjectMeta) - Expect(err).NotTo(HaveOccurred()) - // check that we can execute command to the pod. - // this is necessary because we will exec into the pods and create sample data - f.EventuallyPodAccessible(createdss.ObjectMeta).Should(BeTrue()) - - return createdss - } - - deployScaledUpSS = func(name string) *apps.StatefulSet { - // Generate StatefulSet definition - ss := f.StatefulSetForV1beta1API() - ss.Name = name - // scaled up StatefulSet - ss.Spec.Replicas = types.Int32P(5) - - By("Deploying StatefulSet: " + ss.Name) - createdss, err := f.CreateStatefulSet(ss) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(createdss) - - By("Waiting for StatefulSet to be ready") - err = apps_util.WaitUntilStatefulSetReady(f.KubeClient, createdss.ObjectMeta) - Expect(err).NotTo(HaveOccurred()) - // check that we can execute command to the pod. - // this is necessary because we will exec into the pods and create sample data - f.EventuallyPodAccessible(createdss.ObjectMeta).Should(BeTrue()) - - return createdss - } - - generateSampleData = func(ss *apps.StatefulSet) sets.String { - By("Generating sample data inside StatefulSet pods") - err := f.CreateSampleDataInsideWorkload(ss.ObjectMeta, apis.KindStatefulSet) - Expect(err).NotTo(HaveOccurred()) - - By("Verifying that sample data has been generated") - sampleData, err := f.ReadSampleDataFromFromWorkload(ss.ObjectMeta, apis.KindStatefulSet) - Expect(err).NotTo(HaveOccurred()) - Expect(sampleData).ShouldNot(BeEmpty()) - - return sampleData - } - - getTargetRef = func(ss *apps.StatefulSet) v1beta1.TargetRef { - return v1beta1.TargetRef{ - Name: ss.Name, - Kind: apis.KindStatefulSet, - APIVersion: "apps/v1", - } - } - - setupSSBackup = func(ss *apps.StatefulSet, repo *api.Repository) *v1beta1.BackupConfiguration { - // Generate desired BackupConfiguration definition - backupConfig := f.GetBackupConfigurationForWorkload(repo.Name, getTargetRef(ss)) - - By("Creating BackupConfiguration: " + backupConfig.Name) - createdBC, err := f.StashClient.StashV1beta1().BackupConfigurations(backupConfig.Namespace).Create(backupConfig) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(createdBC) - - By("Verifying that backup triggering CronJob has been created") - f.EventuallyCronJobCreated(backupConfig.ObjectMeta).Should(BeTrue()) - - By("Verifying that sidecar has been injected") - f.EventuallyStatefulSet(ss.ObjectMeta).Should(HaveSidecar(util.StashContainer)) - - By("Waiting for StatefulSet to be ready with sidecar") - err = f.WaitUntilStatefulSetReadyWithSidecar(ss.ObjectMeta) - Expect(err).NotTo(HaveOccurred()) - - return createdBC - } - - takeInstantBackup = func(ss *apps.StatefulSet, repo *api.Repository) { - // Setup Backup - backupConfig := setupSSBackup(ss, repo) - - // Trigger Instant Backup - By("Triggering Instant Backup") - backupSession, err := f.TriggerInstantBackup(backupConfig) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(backupSession) - - By("Waiting for backup process to complete") - f.EventuallyBackupProcessCompleted(backupSession.ObjectMeta).Should(BeTrue()) - - By("Verifying that BackupSession has succeeded") - completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) - Expect(err).NotTo(HaveOccurred()) - Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) - } - - restoreData = func(ss *apps.StatefulSet, repo *api.Repository) sets.String { - By("Creating RestoreSession") - restoreSession := f.GetRestoreSessionForWorkload(repo.Name, getTargetRef(ss)) - err := f.CreateRestoreSession(restoreSession) - Expect(err).NotTo(HaveOccurred()) - f.AppendToCleanupList(restoreSession) - - By("Verifying that init-container has been injected") - f.EventuallyStatefulSet(ss.ObjectMeta).Should(HaveInitContainer(util.StashInitContainer)) - - By("Waiting for restore process to complete") - f.EventuallyRestoreProcessCompleted(restoreSession.ObjectMeta).Should(BeTrue()) - - By("Verifying that RestoreSession succeeded") - completedRS, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) - Expect(err).NotTo(HaveOccurred()) - Expect(completedRS.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) - - By("Waiting for StatefulSet to be ready with init-container") - err = f.WaitUntilStatefulSetWithInitContainer(ss.ObjectMeta) - Expect(err).NotTo(HaveOccurred()) - f.EventuallyPodAccessible(ss.ObjectMeta).Should(BeTrue()) - - //fmt.Println("sleeping.......") - //time.Sleep(2 * time.Minute) - - By("Reading restored data") - restoredData, err := f.ReadSampleDataFromFromWorkload(ss.ObjectMeta, apis.KindStatefulSet) - Expect(err).NotTo(HaveOccurred()) - Expect(restoredData).NotTo(BeEmpty()) - - return restoredData - } - - restoreDataOnScaledUpSS = func(ss *apps.StatefulSet, repo *api.Repository) sets.String { + setupRestoreProcessOnScaledUpSS = func(ss *apps.StatefulSet, repo *api.Repository) (*v1beta1.RestoreSession, error) { By("Creating RestoreSession") - restoreSession := f.GetRestoreSessionForWorkload(repo.Name, getTargetRef(ss)) + restoreSession := f.GetRestoreSessionForWorkload(repo.Name, framework.GetTargetRef(ss.Name, apis.KindStatefulSet)) restoreSession.Spec.Rules = []v1beta1.Rule{ { TargetHosts: []string{ @@ -215,118 +74,166 @@ var _ = Describe("StatefulSet", func() { By("Verifying that init-container has been injected") f.EventuallyStatefulSet(ss.ObjectMeta).Should(HaveInitContainer(util.StashInitContainer)) - By("Waiting for restore process to complete") - f.EventuallyRestoreProcessCompleted(restoreSession.ObjectMeta).Should(BeTrue()) - - By("Verifying that RestoreSession succeeded") - completedRS, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) - Expect(err).NotTo(HaveOccurred()) - Expect(completedRS.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) - By("Waiting for StatefulSet to be ready with init-container") err = f.WaitUntilStatefulSetWithInitContainer(ss.ObjectMeta) - Expect(err).NotTo(HaveOccurred()) f.EventuallyPodAccessible(ss.ObjectMeta).Should(BeTrue()) - By("Reading restored data") - restoredData, err := f.ReadSampleDataFromFromWorkload(ss.ObjectMeta, apis.KindStatefulSet) - Expect(err).NotTo(HaveOccurred()) - Expect(restoredData).NotTo(BeEmpty()) + By("Waiting for restore process to complete") + f.EventuallyRestoreProcessCompleted(restoreSession.ObjectMeta).Should(BeTrue()) - return restoredData + return restoreSession, err } ) Context("StatefulSet", func() { Context("Restore in same StatefulSet", func() { - It("should Backup & Restore in the source StatefulSet", func() { // Deploy a StatefulSet - ss := deploySS(fmt.Sprintf("source-ss-%s", f.App())) + ss, err := f.DeployStatefulSet(fmt.Sprintf("source-ss1-%s", f.App()), int32(3)) + Expect(err).NotTo(HaveOccurred()) // Generate Sample Data - sampleData := generateSampleData(ss) + sampleData, err := f.GenerateSampleData(ss.ObjectMeta, apis.KindStatefulSet) + Expect(err).NotTo(HaveOccurred()) // Setup a Minio Repository - By("Creating Repository") repo, err := f.SetupMinioRepository() Expect(err).NotTo(HaveOccurred()) f.AppendToCleanupList(repo) + // Setup workload Backup + backupConfig, err := f.SetupWorkloadBackup(ss.ObjectMeta, repo, apis.KindStatefulSet) + Expect(err).NotTo(HaveOccurred()) + // Take an Instant Backup the Sample Data - takeInstantBackup(ss, repo) + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has succeeded") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) // Simulate disaster scenario. Delete the data from source PVC By("Deleting sample data from source StatefulSet") err = f.CleanupSampleDataFromWorkload(ss.ObjectMeta, apis.KindStatefulSet) Expect(err).NotTo(HaveOccurred()) - // Restore the backup data - By("Restoring the backed up data in the original Statefulset") - restoredData := restoreData(ss, repo) + // Restore the backed up data + By("Restoring the backed up data in the original StatefulSet") + restoreSession, err := f.SetupRestoreProcess(ss.ObjectMeta, repo, apis.KindStatefulSet) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that RestoreSession succeeded") + completedRS, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedRS.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) + + // Get restored data + restoredData := f.RestoredData(ss.ObjectMeta, apis.KindStatefulSet) // Verify that restored data is same as the original data By("Verifying restored data is same as the original data") - Expect(restoredData).Should(Equal(sampleData)) + Expect(restoredData).Should(BeSameAs(sampleData)) }) }) Context("Restore in different StatefulSet", func() { - It("should restore backed up data into different StatefulSet", func() { // Deploy a StatefulSet - ss := deploySS(fmt.Sprintf("source-ss-%s", f.App())) + ss, err := f.DeployStatefulSet(fmt.Sprintf("source-ss2-%s", f.App()), int32(3)) + Expect(err).NotTo(HaveOccurred()) // Generate Sample Data - sampleData := generateSampleData(ss) + sampleData, err := f.GenerateSampleData(ss.ObjectMeta, apis.KindStatefulSet) + Expect(err).NotTo(HaveOccurred()) // Setup a Minio Repository - By("Creating Repository") repo, err := f.SetupMinioRepository() Expect(err).NotTo(HaveOccurred()) f.AppendToCleanupList(repo) + // Setup workload Backup + backupConfig, err := f.SetupWorkloadBackup(ss.ObjectMeta, repo, apis.KindStatefulSet) + Expect(err).NotTo(HaveOccurred()) + // Take an Instant Backup the Sample Data - takeInstantBackup(ss, repo) + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has succeeded") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) // Deploy restored StatefulSet - restoredSS := deploySS(fmt.Sprintf("restored-ss-%s", f.App())) + restoredSS, err := f.DeployStatefulSet(fmt.Sprintf("restored-ss2-%s", f.App()), int32(3)) + Expect(err).NotTo(HaveOccurred()) - // Restore the backup data - By("Restoring the backed up data in the restored StatefulSet") - restoredData := restoreData(restoredSS, repo) + // Restore the backed up data + By("Restoring the backed up data in the original StatefulSet") + restoreSession, err := f.SetupRestoreProcess(restoredSS.ObjectMeta, repo, apis.KindStatefulSet) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that RestoreSession succeeded") + completedRS, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedRS.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) + + // Get restored data + restoredData := f.RestoredData(restoredSS.ObjectMeta, apis.KindStatefulSet) // Verify that restored data is same as the original data By("Verifying restored data is same as the original data") - Expect(restoredData).Should(Equal(sampleData)) + Expect(restoredData).Should(BeSameAs(sampleData)) }) }) Context("Restore on scaled up StatefulSet", func() { - It("should restore backed up data into scaled up StatefulSet", func() { // Deploy a StatefulSet - ss := deploySS(fmt.Sprintf("source-ss-%s", f.App())) + ss, err := f.DeployStatefulSet(fmt.Sprintf("source-ss3-%s", f.App()), int32(3)) + Expect(err).NotTo(HaveOccurred()) // Generate Sample Data - sampleData := generateSampleData(ss) + sampleData, err := f.GenerateSampleData(ss.ObjectMeta, apis.KindStatefulSet) + Expect(err).NotTo(HaveOccurred()) // Setup a Minio Repository - By("Creating Repository") repo, err := f.SetupMinioRepository() Expect(err).NotTo(HaveOccurred()) f.AppendToCleanupList(repo) + // Setup workload Backup + backupConfig, err := f.SetupWorkloadBackup(ss.ObjectMeta, repo, apis.KindStatefulSet) + Expect(err).NotTo(HaveOccurred()) + // Take an Instant Backup the Sample Data - takeInstantBackup(ss, repo) + backupSession, err := f.TakeInstantBackup(backupConfig.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that BackupSession has succeeded") + completedBS, err := f.StashClient.StashV1beta1().BackupSessions(backupSession.Namespace).Get(backupSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedBS.Status.Phase).Should(Equal(v1beta1.BackupSessionSucceeded)) // Deploy restored StatefulSet - restoredSS := deployScaledUpSS(fmt.Sprintf("restored-ss-%s", f.App())) + restoredSS, err := f.DeployStatefulSet(fmt.Sprintf("restored-ss3-%s", f.App()), int32(5)) + Expect(err).NotTo(HaveOccurred()) - // Restore the backup data - By("Restoring the backed up data in the original StatefulSet") - restoredData := restoreDataOnScaledUpSS(restoredSS, repo) + // Restore the backed up data + By("Restoring the backed up data in different StatefulSet") + restoreSession, err := setupRestoreProcessOnScaledUpSS(restoredSS, repo) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying that RestoreSession succeeded") + completedRS, err := f.StashClient.StashV1beta1().RestoreSessions(restoreSession.Namespace).Get(restoreSession.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(completedRS.Status.Phase).Should(Equal(v1beta1.RestoreSessionSucceeded)) + + // Get restored data + restoredData := f.RestoredData(restoredSS.ObjectMeta, apis.KindStatefulSet) // Verify that restored data is same as the original data By("Verifying restored data is same as the original data") diff --git a/vendor/gomodules.xyz/cert/go.mod b/vendor/gomodules.xyz/cert/go.mod index ca0b338a5..1d654c0e3 100644 --- a/vendor/gomodules.xyz/cert/go.mod +++ b/vendor/gomodules.xyz/cert/go.mod @@ -3,7 +3,7 @@ module gomodules.xyz/cert go 1.12 require ( - github.com/appscode/go v0.0.0-20190808133642-1d4ef1f1c1e0 + github.com/appscode/go v0.0.0-20191025021232-311ac347b3ef github.com/pkg/errors v0.8.1 github.com/spf13/afero v1.2.2 ) diff --git a/vendor/gomodules.xyz/cert/go.sum b/vendor/gomodules.xyz/cert/go.sum index 1704bbd10..ee7b174b3 100644 --- a/vendor/gomodules.xyz/cert/go.sum +++ b/vendor/gomodules.xyz/cert/go.sum @@ -1,5 +1,5 @@ -github.com/appscode/go v0.0.0-20190808133642-1d4ef1f1c1e0 h1:EZp2qE4LUJUG0wMHyUxOg982hVbOFh7qqcM1XIMVGpk= -github.com/appscode/go v0.0.0-20190808133642-1d4ef1f1c1e0/go.mod h1:iy07dV61Z7QQdCKJCIvUoDL21u6AIceRhZzyleh2ymc= +github.com/appscode/go v0.0.0-20191025021232-311ac347b3ef h1:nTbtvdVAVwFgKANCR4KU36Jo1V9Xs/Z2GMEAlpOVG1Y= +github.com/appscode/go v0.0.0-20191025021232-311ac347b3ef/go.mod h1:hUW7Fq0KY2/ntGnYAzemyUpIhLL6bXrTljN6SRY/+Lc= github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg= github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= @@ -53,6 +53,7 @@ golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +gomodules.xyz/version v0.1.0/go.mod h1:Y8xuV02mL/45psyPKG3NCVOwvAOy6T5Kx0l3rCjKSjU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/modules.txt b/vendor/modules.txt index 318ab11db..3a34eb9cf 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -22,7 +22,7 @@ github.com/NYTimes/gziphandler github.com/PuerkitoBio/purell # github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 github.com/PuerkitoBio/urlesc -# github.com/appscode/go v0.0.0-20191016085057-e186b6c94a3b +# github.com/appscode/go v0.0.0-20191025021232-311ac347b3ef github.com/appscode/go/log github.com/appscode/go/version github.com/appscode/go/encoding/json/types @@ -371,7 +371,7 @@ golang.org/x/text/internal/language/compact golang.org/x/text/internal/tag # golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 golang.org/x/time/rate -# gomodules.xyz/cert v1.0.0 +# gomodules.xyz/cert v1.0.1 gomodules.xyz/cert gomodules.xyz/cert/certstore # gomodules.xyz/envsubst v0.1.0