github.com/rancher/elemental/tests@v0.0.0-20240517125144-ae048c615b3f/e2e/backup-restore_test.go (about)

     1  /*
     2  Copyright © 2024 SUSE LLC
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7      http://www.apache.org/licenses/LICENSE-2.0
     8  Unless required by applicable law or agreed to in writing, software
     9  distributed under the License is distributed on an "AS IS" BASIS,
    10  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  See the License for the specific language governing permissions and
    12  limitations under the License.
    13  */
    14  
    15  package e2e_test
    16  
    17  import (
    18  	"strings"
    19  	"time"
    20  
    21  	. "github.com/onsi/ginkgo/v2"
    22  	. "github.com/onsi/gomega"
    23  	"github.com/rancher-sandbox/ele-testhelpers/kubectl"
    24  	"github.com/rancher-sandbox/ele-testhelpers/rancher"
    25  	"github.com/rancher-sandbox/ele-testhelpers/tools"
    26  )
    27  
    28  var _ = Describe("E2E - Install Backup/Restore Operator", Label("install-backup-restore"), func() {
    29  	// Create kubectl context
    30  	// Default timeout is too small, so New() cannot be used
    31  	k := &kubectl.Kubectl{
    32  		Namespace:    "",
    33  		PollTimeout:  tools.SetTimeout(300 * time.Second),
    34  		PollInterval: 500 * time.Millisecond,
    35  	}
    36  
    37  	It("Install Backup/Restore Operator", func() {
    38  		// Report to Qase
    39  		testCaseID = 64
    40  
    41  		// Default chart
    42  		chartRepo := "rancher-chart"
    43  
    44  		By("Configuring Chart repository", func() {
    45  			// Set specific operator version if defined
    46  			if backupRestoreVersion != "" {
    47  				chartRepo = "https://github.com/rancher/backup-restore-operator/releases/download/" + backupRestoreVersion
    48  			} else {
    49  				RunHelmCmdWithRetry("repo", "add", chartRepo, "https://charts.rancher.io")
    50  				RunHelmCmdWithRetry("repo", "update")
    51  			}
    52  		})
    53  
    54  		By("Installing rancher-backup-operator", func() {
    55  			for _, chart := range []string{"rancher-backup-crd", "rancher-backup"} {
    56  				// Set the filename in chart if a custom version is defined
    57  				chartName := chart
    58  				if backupRestoreVersion != "" {
    59  					chartName = chart + "-" + strings.Trim(backupRestoreVersion, "v") + ".tgz"
    60  				}
    61  
    62  				// Global installation flags
    63  				flags := []string{
    64  					"upgrade", "--install", chart, chartRepo + "/" + chartName,
    65  					"--namespace", "cattle-resources-system",
    66  					"--create-namespace",
    67  					"--wait", "--wait-for-jobs",
    68  				}
    69  
    70  				// Add specific options for the rancher-backup chart
    71  				if chart == "rancher-backup" {
    72  					flags = append(flags,
    73  						"--set", "persistence.enabled=true",
    74  						"--set", "persistence.storageClass=local-path",
    75  					)
    76  				}
    77  
    78  				// Install through Helm
    79  				RunHelmCmdWithRetry(flags...)
    80  
    81  				// Delay few seconds for all to be installed
    82  				time.Sleep(tools.SetTimeout(20 * time.Second))
    83  			}
    84  		})
    85  
    86  		By("Waiting for rancher-backup-operator pod", func() {
    87  			// Wait for pod to be started
    88  			Eventually(func() error {
    89  				return rancher.CheckPod(k, [][]string{{"cattle-resources-system", "app.kubernetes.io/name=rancher-backup"}})
    90  			}, tools.SetTimeout(4*time.Minute), 30*time.Second).Should(BeNil())
    91  		})
    92  	})
    93  })
    94  
    95  var _ = Describe("E2E - Test Backup/Restore", Label("test-backup-restore"), func() {
    96  	backupResourceName := "elemental-backup"
    97  	restoreResourceName := "elemental-restore"
    98  
    99  	It("Do a backup", func() {
   100  		// Report to Qase
   101  		testCaseID = 65
   102  
   103  		By("Adding a backup resource", func() {
   104  			err := kubectl.Apply(clusterNS, backupYaml)
   105  			Expect(err).To(Not(HaveOccurred()))
   106  		})
   107  
   108  		By("Checking that the backup has been done", func() {
   109  			out, err := kubectl.RunWithoutErr("get", "backup", backupResourceName,
   110  				"-o", "jsonpath={.metadata.name}")
   111  			Expect(err).To(Not(HaveOccurred()))
   112  			Expect(out).To(ContainSubstring(backupResourceName))
   113  
   114  			// Check operator logs
   115  			Eventually(func() string {
   116  				out, _ := kubectl.RunWithoutErr("logs", "-l app.kubernetes.io/name=rancher-backup",
   117  					"--tail=-1", "--since=5m",
   118  					"--namespace", "cattle-resources-system")
   119  				return out
   120  			}, tools.SetTimeout(5*time.Minute), 10*time.Second).Should(ContainSubstring("Done with backup"))
   121  		})
   122  	})
   123  
   124  	It("Do a restore", func() {
   125  		// Report to Qase
   126  		testCaseID = 66
   127  
   128  		By("Deleting some Elemental resources", func() {
   129  			for _, obj := range []string{"MachineRegistration", "MachineInventorySelectorTemplate"} {
   130  				// List the resources
   131  				list, err := kubectl.RunWithoutErr("get", obj,
   132  					"--namespace", clusterNS,
   133  					"-o", "jsonpath={.items[*].metadata.name}")
   134  				Expect(err).To(Not(HaveOccurred()))
   135  
   136  				// Delete the resources
   137  				for _, rsc := range strings.Split(list, " ") {
   138  					_, err := kubectl.RunWithoutErr("delete", obj, "--namespace", clusterNS, rsc)
   139  					Expect(err).To(Not(HaveOccurred()))
   140  				}
   141  			}
   142  		})
   143  
   144  		By("Adding a restore resource", func() {
   145  			// Get the backup file from the previous backup
   146  			backupFile, err := kubectl.RunWithoutErr("get", "backup", backupResourceName, "-o", "jsonpath={.status.filename}")
   147  			Expect(err).To(Not(HaveOccurred()))
   148  
   149  			// Set the backup file in the restore resource
   150  			err = tools.Sed("%BACKUP_FILE%", backupFile, restoreYaml)
   151  			Expect(err).To(Not(HaveOccurred()))
   152  
   153  			// And apply
   154  			err = kubectl.Apply(clusterNS, restoreYaml)
   155  			Expect(err).To(Not(HaveOccurred()))
   156  		})
   157  
   158  		By("Checking that the restore has been done", func() {
   159  			// Wait until resources are available again
   160  			Eventually(func() string {
   161  				out, _ := kubectl.RunWithoutErr("get", "restore", restoreResourceName,
   162  					"-o", "jsonpath={.metadata.name}")
   163  				return out
   164  			}, tools.SetTimeout(5*time.Minute), 10*time.Second).Should(ContainSubstring(restoreResourceName))
   165  
   166  			// Check operator logs
   167  			Eventually(func() string {
   168  				out, _ := kubectl.RunWithoutErr("logs", "-l app.kubernetes.io/name=rancher-backup",
   169  					"--tail=-1", "--since=5m",
   170  					"--namespace", "cattle-resources-system")
   171  				return out
   172  			}, tools.SetTimeout(5*time.Minute), 10*time.Second).Should(ContainSubstring("Done restoring"))
   173  		})
   174  
   175  		By("Checking cluster state after restore", func() {
   176  			WaitCluster(clusterNS, clusterName)
   177  		})
   178  	})
   179  })