Files
velero/test/e2e/schedule/periodical.go
Xun Jiang 226d50d9cb Modify the schedule cases.
* Modify the OrderResource case's verification code.
* Simplify the Periodical case.
* Simplify the InProgess case.
* Prettify the code.
* Replace math/rand with crypto/rand
* Replace PollUnitl with PollUntilContextTimeout

Signed-off-by: Xun Jiang <xun.jiang@broadcom.com>
2024-11-21 15:16:50 +08:00

211 lines
5.0 KiB
Go

package schedule
import (
"context"
"fmt"
"strings"
"time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"k8s.io/apimachinery/pkg/util/wait"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
framework "github.com/vmware-tanzu/velero/test/e2e/test"
k8sutil "github.com/vmware-tanzu/velero/test/util/k8s"
veleroutil "github.com/vmware-tanzu/velero/test/util/velero"
)
type PeriodicalCase struct {
framework.TestCase
ScheduleName string
ScheduleArgs []string
Period int // The minimum unit is minute.
}
var SchedulePeriodicalTest func() = framework.TestFunc(&PeriodicalCase{})
func (n *PeriodicalCase) Init() error {
Expect(n.TestCase.Init()).To(Succeed())
n.CaseBaseName = "schedule-backup-" + n.UUIDgen
n.NSIncluded = &[]string{n.CaseBaseName}
n.ScheduleName = "schedule-" + n.CaseBaseName
n.RestoreName = "restore-" + n.CaseBaseName
n.TestMsg = &framework.TestMSG{
Desc: "Set up a scheduled backup defined by a Cron expression",
FailedMSG: "Failed to schedule a backup",
Text: "Should backup periodically according to the schedule",
}
n.ScheduleArgs = []string{
"--include-namespaces", strings.Join(*n.NSIncluded, ","),
"--schedule=@every 1m",
}
return nil
}
func (n *PeriodicalCase) CreateResources() error {
for _, ns := range *n.NSIncluded {
By(fmt.Sprintf("Creating namespaces %s ......\n", ns), func() {
Expect(
k8sutil.CreateNamespace(
n.Ctx,
n.Client,
ns,
),
).To(
Succeed(),
fmt.Sprintf("Failed to create namespace %s", ns),
)
})
cmName := n.CaseBaseName
fmt.Printf("Creating ConfigMap %s in namespaces ...%s\n", cmName, ns)
_, err := k8sutil.CreateConfigMap(
n.Client.ClientGo,
ns,
cmName,
nil,
nil,
)
Expect(err).To(Succeed(), fmt.Sprintf("failed to create ConfigMap in the namespace %q", ns))
}
return nil
}
func (n *PeriodicalCase) Backup() error {
By(fmt.Sprintf("Creating schedule %s ......\n", n.ScheduleName), func() {
Expect(
veleroutil.VeleroScheduleCreate(
n.Ctx,
n.VeleroCfg.VeleroCLI,
n.VeleroCfg.VeleroNamespace,
n.ScheduleName,
n.ScheduleArgs,
),
).To(Succeed())
})
By(fmt.Sprintf("No immediate backup is created by schedule %s\n", n.ScheduleName), func() {
backups, err := veleroutil.GetBackupsForSchedule(
n.Ctx,
n.Client.Kubebuilder,
n.ScheduleName,
n.VeleroCfg.Namespace,
)
Expect(err).To(Succeed())
Expect(backups).To(BeEmpty())
})
By("Wait until schedule triggers backup.", func() {
err := wait.PollUntilContextTimeout(
n.Ctx,
30*time.Second,
5*time.Minute,
true,
func(ctx context.Context) (bool, error) {
backups, err := veleroutil.GetBackupsForSchedule(
n.Ctx,
n.Client.Kubebuilder,
n.ScheduleName,
n.VeleroCfg.Namespace,
)
if err != nil {
fmt.Println("Fail to get backups for schedule.")
return false, err
}
// The triggered backup completed.
if len(backups) == 1 &&
backups[0].Status.Phase == velerov1api.BackupPhaseCompleted {
n.BackupName = backups[0].Name
return true, nil
}
return false, nil
},
)
Expect(err).To(Succeed())
})
n.RestoreArgs = []string{
"create", "--namespace", n.VeleroCfg.VeleroNamespace, "restore", n.RestoreName,
"--from-backup", n.BackupName,
"--wait",
}
By(fmt.Sprintf("Pause schedule %s ......\n", n.ScheduleName), func() {
Expect(
veleroutil.VeleroSchedulePause(
n.Ctx,
n.VeleroCfg.VeleroCLI,
n.VeleroCfg.VeleroNamespace,
n.ScheduleName,
),
).To(Succeed())
})
By(("Sleep 2 minutes"), func() {
time.Sleep(2 * time.Minute)
})
backups, err := veleroutil.GetBackupsForSchedule(
n.Ctx,
n.Client.Kubebuilder,
n.ScheduleName,
n.VeleroCfg.Namespace,
)
Expect(err).To(Succeed(), fmt.Sprintf("Fail to get backups from schedule %s", n.ScheduleName))
backupCountPostPause := len(backups)
fmt.Printf("After pause, backups count is %d\n", backupCountPostPause)
By(fmt.Sprintf("Verify no new backups from %s ......\n", n.ScheduleName), func() {
Expect(backupCountPostPause).To(Equal(1))
})
By(fmt.Sprintf("Unpause schedule %s ......\n", n.ScheduleName), func() {
Expect(
veleroutil.VeleroScheduleUnpause(
n.Ctx,
n.VeleroCfg.VeleroCLI,
n.VeleroCfg.VeleroNamespace,
n.ScheduleName,
),
).To(Succeed())
})
return nil
}
func (n *PeriodicalCase) Verify() error {
By("Namespaces were restored", func() {
for _, ns := range *n.NSIncluded {
_, err := k8sutil.GetConfigMap(n.Client.ClientGo, ns, n.CaseBaseName)
Expect(err).ShouldNot(HaveOccurred(), fmt.Sprintf("failed to list CM in namespace: %s\n", ns))
}
})
return nil
}
func (n *PeriodicalCase) Clean() error {
if CurrentSpecReport().Failed() && n.VeleroCfg.FailFast {
fmt.Println("Test case failed and fail fast is enabled. Skip resource clean up.")
} else {
Expect(
veleroutil.VeleroScheduleDelete(
n.Ctx,
n.VeleroCfg.VeleroCLI,
n.VeleroCfg.VeleroNamespace,
n.ScheduleName,
),
).To(Succeed())
Expect(n.TestCase.Clean()).To(Succeed())
}
return nil
}