Files
velero/test/e2e/basic/namespace-mapping.go
KrishhnaT 1e6c6e9287 e2e: give the namespace-mapping cases real volumes on kind under CSI (#10679)
* e2e: give the namespace-mapping cases real volumes on kind under CSI

Init had two kind branches that are not skips. The first replaces
Kibishii's dataset with every dimension zero, so generate.sh and verify.sh
run over nothing. The second forces --snapshot-volumes=false and clears
UseVolumeSnapshots, which also skips the else branch that would add
--default-volumes-to-fs-backup.

Both were right while Kibishii's PVs on kind were hostPath, since neither
a CSI snapshot nor a PodVolumeBackup would pick them up. The effect is
that the two NamespaceMapping FSBackup cases in the kind matrix, which run
on every PR, assert the namespace mapping and nothing about the volumes
despite their label.

Gate both on the same predicate as the other Kibishii cases, so a run with
EnableCSI gets the real dataset and a real snapshot, and add a
NamespaceMapping && Snapshot row to the CSI matrix to select the two cases
that were in no row before.

The FSBackup pair keeps its current behaviour: it runs in the non-CSI job
where Kibishii is still hostPath, so it still takes the zero-data path.
Moving it needs file system backup proven on a CSI-backed class first.

Signed-off-by: krishhna24 <krishhnatupedev@gmail.com>

* Add changelog for #10679

Signed-off-by: krishhna24 <krishhnatupedev@gmail.com>

---------

Signed-off-by: krishhna24 <krishhnatupedev@gmail.com>
2026-10-25 03:54:28 -04:00

161 lines
5.6 KiB
Go

package basic
import (
"context"
"fmt"
"strings"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
. "github.com/velero-io/velero/test/e2e/test"
. "github.com/velero-io/velero/test/util/k8s"
. "github.com/velero-io/velero/test/util/kibishii"
)
type NamespaceMapping struct {
TestCase
MappedNamespaceList []string
kibishiiData *KibishiiData
}
const NamespaceBaseName string = "ns-mp-"
var OneNamespaceMappingFSBackupTest func() = TestFunc(&NamespaceMapping{TestCase: TestCase{NamespacesTotal: 1, UseVolumeSnapshots: false}})
var MultiNamespacesMappingFSBackupTest func() = TestFunc(&NamespaceMapping{TestCase: TestCase{NamespacesTotal: 2, UseVolumeSnapshots: false}})
var OneNamespaceMappingSnapshotTest func() = TestFunc(&NamespaceMapping{TestCase: TestCase{NamespacesTotal: 1, UseVolumeSnapshots: true}})
var MultiNamespacesMappingSnapshotTest func() = TestFunc(&NamespaceMapping{TestCase: TestCase{NamespacesTotal: 2, UseVolumeSnapshots: true}})
func (n *NamespaceMapping) Init() error {
n.TestCase.Init()
n.CaseBaseName = "ns-mp-" + n.UUIDgen
n.BackupName = "backup-" + n.CaseBaseName
n.RestoreName = "restore-" + n.CaseBaseName
n.VeleroCfg.UseVolumeSnapshots = n.UseVolumeSnapshots
n.VeleroCfg.UseNodeAgent = !n.UseVolumeSnapshots
n.kibishiiData = &KibishiiData{Levels: 2, DirsPerLevel: 10, FilesPerLevel: 10, FileLength: 1024, BlockSize: 1024, PassNum: 0, ExpectedNodes: 2}
if KibishiiVolumesAreHostPath(n.VeleroCfg) {
// Nothing written here can survive a backup, since Velero skips hostPath
// PVs for both CSI snapshots and PodVolumeBackups. generate.sh and
// verify.sh are still run, with every dimension zero, so the case checks
// the namespace mapping itself and nothing about the volumes.
n.kibishiiData = &KibishiiData{Levels: 0, DirsPerLevel: 0, FilesPerLevel: 0, FileLength: 0, BlockSize: 0, PassNum: 0, ExpectedNodes: 2}
}
backupType := "fs-backup"
if n.UseVolumeSnapshots {
backupType = "snapshot"
}
var mappedNSSb strings.Builder
var mappedNSList []string
n.NSIncluded = &[]string{}
for nsNum := 0; nsNum < n.NamespacesTotal; nsNum++ {
if nsNum > 0 {
mappedNSSb.WriteString(",")
}
createNSName := fmt.Sprintf("%s-%00000d", n.CaseBaseName, nsNum)
*n.NSIncluded = append(*n.NSIncluded, createNSName)
mappedNSSb.WriteString(createNSName)
mappedNSSb.WriteString(":")
mappedNSSb.WriteString(createNSName)
mappedNSSb.WriteString("-mapped")
mappedNSList = append(mappedNSList, createNSName+"-mapped")
}
mappedNS := mappedNSSb.String()
n.TestMsg = &TestMSG{
Desc: fmt.Sprintf("Restore namespace %s with namespace mapping by %s test", *n.NSIncluded, backupType),
FailedMSG: "Failed to restore with namespace mapping",
Text: fmt.Sprintf("should restore namespace %s with namespace mapping by %s", *n.NSIncluded, backupType),
}
n.MappedNamespaceList = mappedNSList
fmt.Println(mappedNSList)
n.BackupArgs = []string{
"create", "--namespace", n.VeleroCfg.VeleroNamespace, "backup", n.BackupName,
"--include-namespaces", strings.Join(*n.NSIncluded, ","), "--wait",
}
if KibishiiVolumesAreHostPath(n.VeleroCfg) {
// Neither a snapshot nor a PodVolumeBackup would pick these volumes up,
// so ask for neither rather than asserting on a backup that quietly
// contains no volume data.
n.BackupArgs = append(n.BackupArgs, "--snapshot-volumes=false")
n.UseVolumeSnapshots = false
} else if n.UseVolumeSnapshots {
n.BackupArgs = append(n.BackupArgs, "--snapshot-volumes")
} else {
n.BackupArgs = append(n.BackupArgs, "--snapshot-volumes=false")
n.BackupArgs = append(n.BackupArgs, "--default-volumes-to-fs-backup")
}
n.RestoreArgs = []string{
"create", "--namespace", n.VeleroCfg.VeleroNamespace, "restore", n.RestoreName,
"--from-backup", n.BackupName, "--namespace-mappings", mappedNS,
"--wait",
}
return nil
}
func (n *NamespaceMapping) CreateResources() error {
for index, ns := range *n.NSIncluded {
n.kibishiiData.Levels = len(*n.NSIncluded) + index
By(fmt.Sprintf("Creating namespaces ...%s\n", ns), func() {
Expect(CreateNamespace(n.Ctx, n.Client, ns)).To(Succeed(), fmt.Sprintf("Failed to create namespace %s", ns))
})
By("Deploy sample workload of Kibishii", func() {
Expect(KibishiiPrepareBeforeBackup(
n.Ctx,
n.Client,
n.VeleroCfg.CloudProvider,
ns,
n.VeleroCfg.RegistryCredentialFile,
n.VeleroCfg.Features,
n.VeleroCfg.KibishiiDirectory,
n.kibishiiData,
n.VeleroCfg.ImageRegistryProxy,
n.VeleroCfg.WorkerOS,
)).To(Succeed())
})
}
return nil
}
func (n *NamespaceMapping) Verify() error {
for index, ns := range n.MappedNamespaceList {
n.kibishiiData.Levels = len(*n.NSIncluded) + index
By(fmt.Sprintf("Verify workload %s after restore ", ns), func() {
Expect(KibishiiVerifyAfterRestore(
n.Client,
ns,
n.Ctx,
n.kibishiiData,
"",
n.VeleroCfg.WorkerOS,
)).To(Succeed(), "Fail to verify workload after restore")
})
}
for _, ns := range *n.NSIncluded {
By(fmt.Sprintf("Verify namespace %s for backup is no longer exist after restore with namespace mapping", ns), func() {
Expect(NamespaceShouldNotExist(n.Ctx, n.Client, ns)).To(Succeed())
})
}
return nil
}
func (n *NamespaceMapping) Clean() error {
if CurrentSpecReport().Failed() && n.VeleroCfg.FailFast {
fmt.Println("Test case failed and fail fast is enabled. Skip resource clean up.")
} else {
if err := DeleteStorageClass(context.Background(), n.Client, KibishiiStorageClassName); err != nil {
return err
}
for _, ns := range n.MappedNamespaceList {
if err := DeleteNamespace(context.Background(), n.Client, ns, false); err != nil {
return err
}
}
return n.GetTestCase().Clean()
}
return nil
}