From 286792a63c96855802e83f2446ebac933cc49979 Mon Sep 17 00:00:00 2001 From: Sayf Uddin Al Azad Sagor <33339455+suaas21@users.noreply.github.com> Date: Wed, 17 Apr 2019 16:30:04 +0600 Subject: [PATCH] Stash v1beta1 E2E test for DaemonSet (#741) xref: #707 Tasks: [x] Workload backup and restore for DaemonSet --- hack/deploy/rbac-list.yaml | 4 +- pkg/controller/sidecar.go | 14 +- pkg/util/util.go | 2 +- test/e2e/framework/backup_configuration.go | 3 +- test/e2e/framework/backup_session.go | 14 +- test/e2e/framework/daemonset.go | 23 ++ test/e2e/framework/pod.go | 3 +- test/e2e/framework/repository.go | 5 + test/e2e/framework/restore_session.go | 4 +- test/e2e/framework/service.go | 9 + test/e2e/framework/util.go | 36 ++- test/e2e/workload_test.go | 292 ++++++++++++++++++++- 12 files changed, 376 insertions(+), 33 deletions(-) diff --git a/hack/deploy/rbac-list.yaml b/hack/deploy/rbac-list.yaml index 73e752c7b..9cefa8062 100644 --- a/hack/deploy/rbac-list.yaml +++ b/hack/deploy/rbac-list.yaml @@ -27,9 +27,9 @@ rules: - "*" verbs: ["*"] - apiGroups: - - appcatalog.appscode.com + - appcatalog.appscode.com resources: - - "*" + - "*" verbs: ["*"] - apiGroups: - apps diff --git a/pkg/controller/sidecar.go b/pkg/controller/sidecar.go index ee0f5955a..071e78cbc 100644 --- a/pkg/controller/sidecar.go +++ b/pkg/controller/sidecar.go @@ -250,7 +250,7 @@ func (c *StashController) ensureBackupSidecarDeleted(w *wapi.Workload, bc *api_v func (c *StashController) ensureWorkloadLatestState(w *wapi.Workload) (bool, error) { stateChanged := false - err := wait.PollImmediateInfinite(3*time.Second, func() (done bool, err error) { + err := wait.PollImmediate(3*time.Second, 5*time.Minute, func() (done bool, err error) { r, err := metav1.LabelSelectorAsSelector(w.Spec.Selector) if err != nil { return false, err @@ -274,6 +274,9 @@ func (c *StashController) ensureWorkloadLatestState(w *wapi.Workload) (bool, err // we have to restart these pods so that it starts with latest update var podsToRestart []core.Pod for _, pod := range pods.Items { + if !isPodOwnedByWorkload(w, pod) { + continue + } podSidecarState := hasStashSidecar(pod.Spec.Containers) podInitContainerState := hasStashInitContainer(pod.Spec.InitContainers) podBackupResourceHash := util.GetString(pod.Annotations, api_v1beta1.AppliedBackupConfigurationSpecHash) @@ -305,3 +308,12 @@ func (c *StashController) ensureWorkloadLatestState(w *wapi.Workload) (bool, err return stateChanged, nil } + +func isPodOwnedByWorkload(w *wapi.Workload, pod core.Pod) bool { + for _, ref := range pod.OwnerReferences { + if ref.Kind == w.Kind && ref.Name == w.Name { + return true + } + } + return false +} diff --git a/pkg/util/util.go b/pkg/util/util.go index 7d0afb974..e29a1fb79 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -44,7 +44,7 @@ func GetHostName(target *api_v1beta1.Target) (string, error) { podOrdinal := podInfo[len(podInfo)-1] return "host-" + podOrdinal, nil case apis.KindDaemonSet: - nodeName := os.Getenv("POD_NAME") + nodeName := os.Getenv("NODE_NAME") if nodeName == "" { return "", fmt.Errorf("missing nodeName for %s", apis.KindDaemonSet) } diff --git a/test/e2e/framework/backup_configuration.go b/test/e2e/framework/backup_configuration.go index e4eca5928..b24ad6432 100644 --- a/test/e2e/framework/backup_configuration.go +++ b/test/e2e/framework/backup_configuration.go @@ -5,7 +5,6 @@ import ( "github.com/appscode/stash/apis/stash/v1alpha1" "github.com/appscode/stash/apis/stash/v1beta1" core "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -47,5 +46,5 @@ func (f *Invocation) CreateBackupConfiguration(backupCfg v1beta1.BackupConfigura } func (f *Invocation) DeleteBackupConfiguration(backupCfg v1beta1.BackupConfiguration) error { - return f.StashClient.StashV1beta1().BackupConfigurations(backupCfg.Namespace).Delete(backupCfg.Name, &v1.DeleteOptions{}) + return f.StashClient.StashV1beta1().BackupConfigurations(backupCfg.Namespace).Delete(backupCfg.Name, &metav1.DeleteOptions{}) } diff --git a/test/e2e/framework/backup_session.go b/test/e2e/framework/backup_session.go index 65ee29d11..5f0786279 100644 --- a/test/e2e/framework/backup_session.go +++ b/test/e2e/framework/backup_session.go @@ -21,7 +21,7 @@ func (f *Framework) EventuallyBackupSessionPhase(meta metav1.ObjectMeta) GomegaA func (f *Framework) EventuallyBackupSessionCreated(meta metav1.ObjectMeta) GomegaAsyncAssertion { return Eventually( - func() bool { + func() bool { backupsnlist, err := f.StashClient.StashV1beta1().BackupSessions(meta.Namespace).List(metav1.ListOptions{}) Expect(err).NotTo(HaveOccurred()) if len(backupsnlist.Items) > 0 { @@ -34,15 +34,15 @@ func (f *Framework) EventuallyBackupSessionCreated(meta metav1.ObjectMeta) Gomeg ) } -func (f *Framework) GetBackupSession(meta metav1.ObjectMeta) (*v1beta1.BackupSession, error){ +func (f *Framework) GetBackupSession(meta metav1.ObjectMeta) (*v1beta1.BackupSession, error) { backupsnlist, err := f.StashClient.StashV1beta1().BackupSessions(meta.Namespace).List(metav1.ListOptions{}) - if err != nil{ - return nil,err + if err != nil { + return nil, err } - if len(backupsnlist.Items)>0{ - return &backupsnlist.Items[0],nil + if len(backupsnlist.Items) > 0 { + return &backupsnlist.Items[0], nil } - return nil,fmt.Errorf("no BackupSession found") + return nil, fmt.Errorf("no BackupSession found") } func (f *Framework) EventuallyBackupSessionTotalHost(meta metav1.ObjectMeta) GomegaAsyncAssertion { diff --git a/test/e2e/framework/daemonset.go b/test/e2e/framework/daemonset.go index 9099277e5..54b8cda53 100644 --- a/test/e2e/framework/daemonset.go +++ b/test/e2e/framework/daemonset.go @@ -1,10 +1,13 @@ package framework import ( + "time" + "github.com/appscode/go/crypto/rand" . "github.com/onsi/gomega" apps "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/util/intstr" ) @@ -54,3 +57,23 @@ func (f *Framework) EventuallyDaemonSet(meta metav1.ObjectMeta) GomegaAsyncAsser return obj }) } + +func (f *Framework) EventuallyPodAccessible(meta metav1.ObjectMeta) GomegaAsyncAssertion { + return Eventually(func() bool { + labelSelector := fields.SelectorFromSet(meta.Labels) + podList, err := f.KubeClient.CoreV1().Pods(meta.Namespace).List(metav1.ListOptions{LabelSelector: labelSelector.String()}) + Expect(err).NotTo(HaveOccurred()) + + for _, pod := range podList.Items { + _, err := f.ExecOnPod(&pod, "ls", "-R") + if err == nil { + return true + } + } + return false + }, + time.Minute*2, + time.Second*2, + ) + +} diff --git a/test/e2e/framework/pod.go b/test/e2e/framework/pod.go index fe49a7eb0..932572871 100644 --- a/test/e2e/framework/pod.go +++ b/test/e2e/framework/pod.go @@ -56,8 +56,7 @@ func (fi *Invocation) PodTemplate(labels map[string]string, pvcName string) core } func (f *Framework) GetPod(meta metav1.ObjectMeta) (*core.Pod, error) { - labelSelector := fields.SelectorFromSet(meta.Labels) - podList, err := f.KubeClient.CoreV1().Pods(meta.Namespace).List(metav1.ListOptions{LabelSelector: labelSelector.String()}) + podList, err := f.KubeClient.CoreV1().Pods(meta.Namespace).List(metav1.ListOptions{}) if err != nil { return nil, err } diff --git a/test/e2e/framework/repository.go b/test/e2e/framework/repository.go index 9908ec883..6d86b30c8 100644 --- a/test/e2e/framework/repository.go +++ b/test/e2e/framework/repository.go @@ -70,6 +70,11 @@ func (f *Framework) DeleteRepositories(repositories []*api.Repository) { Expect(err).NotTo(HaveOccurred()) } } + +func (f *Framework) DeleteRepository(repository *api.Repository) error { + err := f.StashClient.StashV1alpha1().Repositories(repository.Namespace).Delete(repository.Name, deleteInBackground()) + return err +} func (f *Framework) BrowseResticRepository(repository *api.Repository) ([]stow.Item, error) { cfg, err := osm.NewOSMContext(f.KubeClient, repository) if err != nil { diff --git a/test/e2e/framework/restore_session.go b/test/e2e/framework/restore_session.go index 3b1d7b3b1..a0132b446 100644 --- a/test/e2e/framework/restore_session.go +++ b/test/e2e/framework/restore_session.go @@ -39,8 +39,8 @@ func (f *Invocation) CreateRestoreSession(restoreSession v1beta1.RestoreSession) return err } -func (f Invocation) DeleteRestoreSession(meta metav1.ObjectMeta) error{ - _,err := f.StashClient.StashV1beta1().RestoreSessions(meta.Namespace).Get(meta.Name, metav1.GetOptions{}) +func (f Invocation) DeleteRestoreSession(meta metav1.ObjectMeta) error { + err := f.StashClient.StashV1beta1().RestoreSessions(meta.Namespace).Delete(meta.Name, &metav1.DeleteOptions{}) return err } diff --git a/test/e2e/framework/service.go b/test/e2e/framework/service.go index 6cd977b98..a2224a119 100644 --- a/test/e2e/framework/service.go +++ b/test/e2e/framework/service.go @@ -3,6 +3,7 @@ package framework import ( core "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + core_util "kmodules.xyz/client-go/core/v1" ) const ( @@ -38,3 +39,11 @@ func (f *Framework) CreateService(obj core.Service) error { func (f *Framework) DeleteService(meta metav1.ObjectMeta) error { return f.KubeClient.CoreV1().Services(meta.Namespace).Delete(meta.Name, deleteInForeground()) } + +func (f *Framework) CreateOrPatchService(obj core.Service) error { + _, _, err := core_util.CreateOrPatchService(f.KubeClient, obj.ObjectMeta, func(in *core.Service) *core.Service { + in.Spec = obj.Spec + return in + }) + return err +} diff --git a/test/e2e/framework/util.go b/test/e2e/framework/util.go index 26a10b023..7c6b62009 100644 --- a/test/e2e/framework/util.go +++ b/test/e2e/framework/util.go @@ -23,6 +23,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" ) + var ( files = []string{"test-data1.txt", "test-data2.txt", "test-data3.txt", "test-data4.txt", "test-data5.txt"} ) @@ -340,7 +341,7 @@ func GetPathsFromResticFileGroups(restic *api.Restic) []string { func GetPathsFromRestoreSession(restoreSession *v1beta1.RestoreSession) []string { paths := make([]string, 0) - for i, _ := range restoreSession.Spec.Rules { + for i := range restoreSession.Spec.Rules { for _, p := range restoreSession.Spec.Rules[i].Paths { paths = append(paths, p) } @@ -353,13 +354,13 @@ func removeDuplicates(elements []string) []string { encountered := map[string]bool{} // Create a map of all unique elements. - for v:= range elements { + for v := range elements { encountered[elements[v]] = true } // Place all keys from the map into a slice. result := []string{} - for key, _ := range encountered { + for key := range encountered { result = append(result, key) } return result @@ -521,6 +522,19 @@ func WaitUntilBackupConfigurationDeleted(sc cs.Interface, meta metav1.ObjectMeta }) } +func WaitUntilRestoreSessionDeleted(sc cs.Interface, meta metav1.ObjectMeta) error { + return wait.PollImmediate(PullInterval, WaitTimeOut, func() (done bool, err error) { + if _, err := sc.StashV1beta1().RestoreSessions(meta.Namespace).Get(meta.Name, metav1.GetOptions{}); err != nil { + if kerr.IsNotFound(err) { + return true, nil + } else { + return true, err + } + } + return false, nil + }) +} + func WaitUntilRecoveryDeleted(sc cs.Interface, meta metav1.ObjectMeta) error { return wait.PollImmediate(PullInterval, WaitTimeOut, func() (done bool, err error) { @@ -555,6 +569,19 @@ func WaitUntilRepositoriesDeleted(sc cs.Interface, repositories []*api.Repositor return false, nil }) } +func WaitUntilRepositoryDeleted(sc cs.Interface, repository *api.Repository) error { + + return wait.PollImmediate(PullInterval, WaitTimeOut, func() (done bool, err error) { + if _, err := sc.StashV1alpha1().Repositories(repository.Namespace).Get(repository.Name, metav1.GetOptions{}); err != nil { + if kerr.IsNotFound(err) { + return true, nil + } else { + return true, err + } + } + return false, nil + }) +} func (f *Framework) WaitUntilDaemonPodReady(meta metav1.ObjectMeta) error { @@ -563,10 +590,11 @@ func (f *Framework) WaitUntilDaemonPodReady(meta metav1.ObjectMeta) error { if err != nil { return false, nil } - if pod.Status.Phase == core.PodPhase(core.PodReady) { + if pod.Status.Phase == core.PodPhase(core.PodRunning) { return true, nil } return false, nil + }) } diff --git a/test/e2e/workload_test.go b/test/e2e/workload_test.go index 4747ce58a..0a38cc145 100644 --- a/test/e2e/workload_test.go +++ b/test/e2e/workload_test.go @@ -29,6 +29,8 @@ var ( targetref v1beta1.TargetRef rules []v1beta1.Rule svc core.Service + daemonset apps.DaemonSet + recoveredDaemonset apps.DaemonSet ) var ( sampleData []string @@ -36,7 +38,6 @@ var ( ) var _ = Describe("Deployment", func() { - BeforeEach(func() { f = root.Invoke() }) @@ -141,8 +142,15 @@ var _ = Describe("Deployment", func() { err = framework.WaitUntilDeploymentDeleted(f.KubeClient, deployment.ObjectMeta) Expect(err).NotTo(HaveOccurred()) + err = f.DeleteRepository(repo) + Expect(err).NotTo(HaveOccurred()) + err = framework.WaitUntilRepositoryDeleted(f.StashClient, repo) + Expect(err).NotTo(HaveOccurred()) + err = f.DeleteRestoreSession(restoreSession.ObjectMeta) Expect(err).NotTo(HaveOccurred()) + err = framework.WaitUntilRestoreSessionDeleted(f.StashClient, restoreSession.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) }) It("General Backup new Deployment", func() { @@ -194,8 +202,15 @@ var _ = Describe("Deployment", func() { err = framework.WaitUntilDeploymentDeleted(f.KubeClient, deployment.ObjectMeta) Expect(err).NotTo(HaveOccurred()) + err = f.DeleteRepository(repo) + Expect(err).NotTo(HaveOccurred()) + err = framework.WaitUntilRepositoryDeleted(f.StashClient, repo) + Expect(err).NotTo(HaveOccurred()) + err = f.DeleteRestoreSession(restoreSession.ObjectMeta) Expect(err).NotTo(HaveOccurred()) + err = framework.WaitUntilRestoreSessionDeleted(f.StashClient, restoreSession.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) }) It("Should leader elect and Backup new deployment", func() { deployment.Spec.Replicas = types.Int32P(2) // two replicas @@ -262,7 +277,7 @@ var _ = Describe("Deployment", func() { }) }) - Context("Backup && Restore data on different Deployment", func() { + Context("Restore data on different Deployment", func() { BeforeEach(func() { pvc = f.GetPersistentVolumeClaim() err = f.CreatePersistentVolumeClaim(pvc) @@ -290,8 +305,15 @@ var _ = Describe("Deployment", func() { err = framework.WaitUntilDeploymentDeleted(f.KubeClient, recoveredDeployment.ObjectMeta) Expect(err).NotTo(HaveOccurred()) + err = f.DeleteRepository(repo) + Expect(err).NotTo(HaveOccurred()) + err = framework.WaitUntilRepositoryDeleted(f.StashClient, repo) + Expect(err).NotTo(HaveOccurred()) + err = f.DeleteRestoreSession(restoreSession.ObjectMeta) Expect(err).NotTo(HaveOccurred()) + err = framework.WaitUntilRestoreSessionDeleted(f.StashClient, restoreSession.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) }) It("Restore data on different Deployment", func() { By("Creating New Deployment Backup") @@ -304,6 +326,7 @@ var _ = Describe("Deployment", func() { Expect(err).NotTo(HaveOccurred()) restoreSession.Spec.Target.Ref.Name = recoveredDeployment.Name + By("Creating Restore Session") err = f.CreateRestoreSession(restoreSession) Expect(err).NotTo(HaveOccurred()) @@ -326,8 +349,7 @@ var _ = Describe("Deployment", func() { }) }) -var _ = Describe("Statefulset", func() { - +var _ = Describe("StatefulSet", func() { BeforeEach(func() { f = root.Invoke() }) @@ -336,6 +358,11 @@ var _ = Describe("Statefulset", func() { if missing, _ := BeZero().Match(cred); missing { Skip("Missing repository credential") } + + By("Creating service " + svc.Name) + err = f.CreateOrPatchService(svc) + Expect(err).NotTo(HaveOccurred()) + pvc = f.GetPersistentVolumeClaim() err = f.CreatePersistentVolumeClaim(pvc) Expect(err).NotTo(HaveOccurred()) @@ -366,6 +393,7 @@ var _ = Describe("Statefulset", func() { By("Reading sample data from /source/data mountPath inside workload") sampleData, err = f.ReadSampleDataFromFromWorkload(ss.ObjectMeta, apis.KindStatefulSet) Expect(err).NotTo(HaveOccurred()) + Expect(sampleData).ShouldNot(BeEmpty()) By("Creating storage Secret " + cred.Name) err = f.CreateSecret(cred) @@ -407,10 +435,6 @@ var _ = Describe("Statefulset", func() { Context("General Backup new StatefulSet", func() { BeforeEach(func() { svc = f.HeadlessService() - By("Creating service " + svc.Name) - err = f.CreateService(svc) - Expect(err).NotTo(HaveOccurred()) - ss = f.StatefulSetForV1beta1API() targetref = v1beta1.TargetRef{ Name: ss.Name, @@ -431,8 +455,15 @@ var _ = Describe("Statefulset", func() { err = framework.WaitUntilStatefulSetDeleted(f.KubeClient, ss.ObjectMeta) Expect(err).NotTo(HaveOccurred()) + err = f.DeleteRepository(repo) + Expect(err).NotTo(HaveOccurred()) + err = framework.WaitUntilRepositoryDeleted(f.StashClient, repo) + Expect(err).NotTo(HaveOccurred()) + err = f.DeleteRestoreSession(restoreSession.ObjectMeta) Expect(err).NotTo(HaveOccurred()) + err = framework.WaitUntilRestoreSessionDeleted(f.StashClient, restoreSession.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) }) It("General Backup new Statefulset", func() { @@ -492,12 +523,19 @@ var _ = Describe("Statefulset", func() { err = framework.WaitUntilStatefulSetDeleted(f.KubeClient, recoveredss.ObjectMeta) Expect(err).NotTo(HaveOccurred()) + err = f.DeleteRepository(repo) + Expect(err).NotTo(HaveOccurred()) + err = framework.WaitUntilRepositoryDeleted(f.StashClient, repo) + Expect(err).NotTo(HaveOccurred()) + err = f.DeleteRestoreSession(restoreSession.ObjectMeta) Expect(err).NotTo(HaveOccurred()) + err = framework.WaitUntilRestoreSessionDeleted(f.StashClient, restoreSession.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) }) - It("General Backup new Statefulset", func() { - By("Creating Statefulset Backup") + It("General Backup new StatefulSet", func() { + By("Creating StatefulSet Backup") testStatefulsetBackup() By("Creating another StatefulSet " + recoveredss.Name) @@ -571,12 +609,19 @@ var _ = Describe("Statefulset", func() { err = framework.WaitUntilStatefulSetDeleted(f.KubeClient, recoveredss.ObjectMeta) Expect(err).NotTo(HaveOccurred()) + err = f.DeleteRepository(repo) + Expect(err).NotTo(HaveOccurred()) + err = framework.WaitUntilRepositoryDeleted(f.StashClient, repo) + Expect(err).NotTo(HaveOccurred()) + err = f.DeleteRestoreSession(restoreSession.ObjectMeta) Expect(err).NotTo(HaveOccurred()) + err = framework.WaitUntilRestoreSessionDeleted(f.StashClient, restoreSession.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) }) - It("General Backup new Statefulset", func() { - By("Creating Statefulset Backup") + It("General Backup new StatefulSet", func() { + By("Creating StatefulSet Backup") testStatefulsetBackup() By("Creating another StatefulSet " + recoveredss.Name) @@ -616,3 +661,226 @@ var _ = Describe("Statefulset", func() { }) }) + +var _ = Describe("DaemonSet", func() { + BeforeEach(func() { + f = root.Invoke() + }) + JustBeforeEach(func() { + cred = f.SecretForLocalBackend() + if missing, _ := BeZero().Match(cred); missing { + Skip("Missing repository credential") + } + pvc = f.GetPersistentVolumeClaim() + err = f.CreatePersistentVolumeClaim(pvc) + Expect(err).NotTo(HaveOccurred()) + repo = f.Repository(cred.Name, pvc.Name) + + backupCfg = f.BackupConfiguration(repo.Name, targetref) + rules = []v1beta1.Rule{ + { + Paths: []string{ + framework.TestSourceDataMountPath, + }, + }, + } + restoreSession = f.RestoreSession(repo.Name, targetref, rules) + }) + AfterEach(func() { + err = f.DeleteSecret(cred.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + err = framework.WaitUntilSecretDeleted(f.KubeClient, cred.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + }) + var ( + testDaemonSetBackup = func() { + By("Create DaemonSet" + daemonset.Name) + _, err := f.CreateDaemonSet(daemonset) + Expect(err).NotTo(HaveOccurred()) + err = f.WaitUntilDaemonPodReady(daemonset.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + f.EventuallyPodAccessible(daemonset.ObjectMeta).Should(BeTrue()) + + By("Creating Sample data inside pod") + err = f.CreateSampleDataInsideWorkload(daemonset.ObjectMeta, apis.KindDaemonSet) + Expect(err).NotTo(HaveOccurred()) + + By("Reading sample data from /source/data mountPath inside workload") + sampleData, err = f.ReadSampleDataFromFromWorkload(daemonset.ObjectMeta, apis.KindDaemonSet) + Expect(err).NotTo(HaveOccurred()) + Expect(sampleData).ShouldNot(BeEmpty()) + + By("Creating storage Secret " + cred.Name) + err = f.CreateSecret(cred) + Expect(err).NotTo(HaveOccurred()) + + By("Creating new repository") + err = f.CreateRepository(repo) + Expect(err).NotTo(HaveOccurred()) + + By("Creating BackupConfiguration" + backupCfg.Name) + err = f.CreateBackupConfiguration(backupCfg) + Expect(err).NotTo(HaveOccurred()) + + By("Waiting for sidecar") + f.EventuallyDaemonSet(daemonset.ObjectMeta).Should(matcher.HaveSidecar(util.StashContainer)) + + By("Waiting for BackupSession") + f.EventuallyBackupSessionCreated(backupCfg.ObjectMeta).Should(BeTrue()) + bs, err := f.GetBackupSession(backupCfg.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Check for repository status updated") + f.EventuallyRepository(&daemonset).Should(WithTransform(f.BackupCountInRepositoriesStatus, BeNumerically(">=", 1))) + + By("Check for succeeded BackupSession") + f.EventuallyBackupSessionPhase(bs.ObjectMeta).Should(Equal(v1beta1.BackupSessionSucceeded)) + + By("Delete BackupConfiguration") + err = f.DeleteBackupConfiguration(backupCfg) + err = framework.WaitUntilBackupConfigurationDeleted(f.StashClient, backupCfg.ObjectMeta) + Expect(err).ShouldNot(HaveOccurred()) + + By("Waiting for sidecar to be removed") + f.EventuallyDaemonSet(daemonset.ObjectMeta).ShouldNot(matcher.HaveSidecar(util.StashContainer)) + err = f.WaitUntilDaemonPodReady(daemonset.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("Deleting sample data from pod") + err = f.CleanupSampleDataFromWorkload(daemonset.ObjectMeta, apis.KindDaemonSet) + Expect(err).NotTo(HaveOccurred()) + + } + ) + Context("General Backup new DaemonSet", func() { + BeforeEach(func() { + pvc = f.GetPersistentVolumeClaim() + err = f.CreatePersistentVolumeClaim(pvc) + Expect(err).NotTo(HaveOccurred()) + daemonset = f.DaemonSet(pvc.Name) + targetref = v1beta1.TargetRef{ + Name: daemonset.Name, + Kind: apis.KindDaemonSet, + APIVersion: "apps/v1", + } + }) + AfterEach(func() { + err := f.DeleteDaemonSet(daemonset.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + err = framework.WaitUntilDaemonSetDeleted(f.KubeClient, daemonset.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + err = f.DeleteRepository(repo) + Expect(err).NotTo(HaveOccurred()) + err = framework.WaitUntilRepositoryDeleted(f.StashClient, repo) + Expect(err).NotTo(HaveOccurred()) + + err = f.DeleteRestoreSession(restoreSession.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + err = framework.WaitUntilRestoreSessionDeleted(f.StashClient, restoreSession.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + }) + + It("General Backup new DaemonSet", func() { + By("Creating DaemonSet Backup") + testDaemonSetBackup() + + By("Creating Restore Session") + err = f.CreateRestoreSession(restoreSession) + Expect(err).NotTo(HaveOccurred()) + + By("Waiting for initContainer") + f.EventuallyDaemonSet(daemonset.ObjectMeta).Should(matcher.HaveInitContainer(util.StashInitContainer)) + Expect(err).NotTo(HaveOccurred()) + + By("Waiting for restore to succeed") + f.EventuallyRestoreSessionPhase(restoreSession.ObjectMeta).Should(Equal(v1beta1.RestoreSessionSucceeded)) + err = util.WaitUntilDaemonSetReady(f.KubeClient, daemonset.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + By("checking the workload data has been restored") + restoredData, err = f.ReadSampleDataFromMountedDirectory(daemonset.ObjectMeta, framework.GetPathsFromRestoreSession(&restoreSession), apis.KindDaemonSet) + Expect(err).NotTo(HaveOccurred()) + + By("Compare between restore data and sample data") + Expect(restoredData).To(BeEquivalentTo(sampleData)) + + }) + }) + + Context("Restore data on different DaemonSet", func() { + BeforeEach(func() { + pvc = f.GetPersistentVolumeClaim() + err = f.CreatePersistentVolumeClaim(pvc) + Expect(err).NotTo(HaveOccurred()) + daemonset = f.DaemonSet(pvc.Name) + + pvc = f.GetPersistentVolumeClaim() + err = f.CreatePersistentVolumeClaim(pvc) + Expect(err).NotTo(HaveOccurred()) + recoveredDaemonset = f.DaemonSet(pvc.Name) + + targetref = v1beta1.TargetRef{ + Name: daemonset.Name, + Kind: apis.KindDaemonSet, + APIVersion: "apps/v1", + } + }) + AfterEach(func() { + err := f.DeleteDaemonSet(daemonset.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + err = framework.WaitUntilDaemonSetDeleted(f.KubeClient, daemonset.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + err = f.DeleteDaemonSet(recoveredDaemonset.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + err = framework.WaitUntilDaemonSetDeleted(f.KubeClient, recoveredDaemonset.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + err = f.DeleteRepository(repo) + Expect(err).NotTo(HaveOccurred()) + err = framework.WaitUntilRepositoryDeleted(f.StashClient, repo) + Expect(err).NotTo(HaveOccurred()) + + err = f.DeleteRestoreSession(restoreSession.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + err = framework.WaitUntilRestoreSessionDeleted(f.StashClient, restoreSession.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + }) + + It("General Backup new DaemonSet", func() { + By("Creating DaemonSet Backup") + testDaemonSetBackup() + + By("Creating another DaemonSet " + recoveredDaemonset.Name) + _, err := f.CreateDaemonSet(recoveredDaemonset) + Expect(err).NotTo(HaveOccurred()) + err = f.WaitUntilDaemonPodReady(recoveredDaemonset.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + + restoreSession.Spec.Target.Ref.Name = recoveredDaemonset.Name + + By("Creating Restore Session") + err = f.CreateRestoreSession(restoreSession) + Expect(err).NotTo(HaveOccurred()) + + By("Waiting for initContainer") + f.EventuallyDaemonSet(recoveredDaemonset.ObjectMeta).Should(matcher.HaveInitContainer(util.StashInitContainer)) + + By("Waiting for restore to succeed") + f.EventuallyRestoreSessionPhase(restoreSession.ObjectMeta).Should(Equal(v1beta1.RestoreSessionSucceeded)) + err = f.WaitUntilDaemonPodReady(recoveredDaemonset.ObjectMeta) + Expect(err).NotTo(HaveOccurred()) + f.EventuallyPodAccessible(recoveredDaemonset.ObjectMeta).Should(BeTrue()) + + By("checking the workload data has been restored") + restoredData, err = f.ReadSampleDataFromMountedDirectory(recoveredDaemonset.ObjectMeta, framework.GetPathsFromRestoreSession(&restoreSession), apis.KindDaemonSet) + Expect(err).NotTo(HaveOccurred()) + + By("Compare between restore data and sample data") + Expect(restoredData).To(BeEquivalentTo(sampleData)) + + }) + }) + +})