Skip to content

Commit

Permalink
OADP-4291 Add no-pod/immediate bind VM tests. (#1479)
Browse files Browse the repository at this point in the history
* OADP-4291 Add no-pod/immediate bind VM tests.

Signed-off-by: Matthew Arnold <[email protected]>

* Silence lint error.

Signed-off-by: Matthew Arnold <[email protected]>

* Add immediate mode storage class and VM templates.

Signed-off-by: Matthew Arnold <[email protected]>

* Fix duplicated VM test.

Signed-off-by: Matthew Arnold <[email protected]>

* Use UninstallApplication instead of delete.

Signed-off-by: Matthew Arnold <[email protected]>

* Expect error on no-pod immediate datamover test.

Signed-off-by: Matthew Arnold <[email protected]>

* Add another expected VM test error.

Signed-off-by: Matthew Arnold <[email protected]>

* Try VM tests without ginkgo.Ordered.

Signed-off-by: Matthew Arnold <[email protected]>

* Replace immediate storage class YAML with live copy.

Signed-off-by: Matthew Arnold <[email protected]>

* Restore order.

Signed-off-by: Matthew Arnold <[email protected]>

* Clean up lint errors.

Signed-off-by: Matthew Arnold <[email protected]>

* Address more review comments.

Signed-off-by: Matthew Arnold <[email protected]>

* Remove VM test that's expected to fail.

There is no fix for this yet.

Signed-off-by: Matthew Arnold <[email protected]>

* Clean up after rebase.

Remove expected restore errors and change immediate-mode CirrOS template
PVC size.

Signed-off-by: Matthew Arnold <[email protected]>

---------

Signed-off-by: Matthew Arnold <[email protected]>
  • Loading branch information
mrnold authored Aug 28, 2024
1 parent c0e62bc commit fe4ca09
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 4 deletions.
8 changes: 4 additions & 4 deletions tests/e2e/lib/virt_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,14 +183,14 @@ func (v *VirtOperator) checkNamespace() bool {
// Checks for the existence of the virtualization operator group
func (v *VirtOperator) checkOperatorGroup() bool {
group := operatorsv1.OperatorGroup{}
err := v.Client.Get(context.TODO(), client.ObjectKey{Namespace: v.Namespace, Name: "kubevirt-hyperconverged-group"}, &group)
err := v.Client.Get(context.Background(), client.ObjectKey{Namespace: v.Namespace, Name: "kubevirt-hyperconverged-group"}, &group)
return err == nil
}

// Checks if there is a virtualization subscription
func (v *VirtOperator) checkSubscription() bool {
subscription := operatorsv1alpha1.Subscription{}
err := v.Client.Get(context.TODO(), client.ObjectKey{Namespace: v.Namespace, Name: "hco-operatorhub"}, &subscription)
err := v.Client.Get(context.Background(), client.ObjectKey{Namespace: v.Namespace, Name: "hco-operatorhub"}, &subscription)
return err == nil
}

Expand Down Expand Up @@ -621,7 +621,7 @@ func (v *VirtOperator) GetVmStatus(namespace, name string) (string, error) {
// /apis/subresources.kubevirt.io/v1/namespaces/{namespace:[a-z0-9]}/virtualmachines/{name:[a-z0-9][a-z0-9\-]}/stop
func (v *VirtOperator) StopVm(namespace, name string) error {
path := fmt.Sprintf(stopVmPath, namespace, name)
return v.Clientset.RESTClient().Put().AbsPath(path).Do(context.TODO()).Error()
return v.Clientset.RESTClient().Put().AbsPath(path).Do(context.Background()).Error()
}

func (v *VirtOperator) checkVmExists(namespace, name string) bool {
Expand All @@ -630,7 +630,7 @@ func (v *VirtOperator) checkVmExists(namespace, name string) bool {
}

func (v *VirtOperator) removeVm(namespace, name string) error {
if err := v.Dynamic.Resource(virtualMachineGvr).Namespace(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{}); err != nil {
if err := v.Dynamic.Resource(virtualMachineGvr).Namespace(namespace).Delete(context.Background(), name, metav1.DeleteOptions{}); err != nil {
if !apierrors.IsNotFound(err) {
return fmt.Errorf("error deleting VM %s/%s: %w", namespace, name, err)
}
Expand Down
41 changes: 41 additions & 0 deletions tests/e2e/lib/virt_storage_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@ package lib

import (
"context"
"errors"
"fmt"
"log"
"strings"
"time"

storagev1 "k8s.io/api/storage/v1"
apierrors "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/runtime/schema"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/utils/ptr"
)

var dataVolumeGVR = schema.GroupVersionResource{
Expand Down Expand Up @@ -203,3 +206,41 @@ func (v *VirtOperator) CreateDataSourceFromPvc(namespace, name string) error {

return nil
}

// Check the VolumeBindingMode of the default storage class, and make an
// Immediate-mode copy if it is set to WaitForFirstConsumer.
func (v *VirtOperator) CreateImmediateModeStorageClass(name string) error {
// Find the default storage class
storageClasses, err := v.Clientset.StorageV1().StorageClasses().List(context.Background(), metav1.ListOptions{})
if err != nil {
return err
}
var defaultStorageClass *storagev1.StorageClass
for _, storageClass := range storageClasses.Items {
if storageClass.Annotations["storageclass.kubernetes.io/is-default-class"] == "true" {
log.Printf("Found default storage class: %s", storageClass.Name)
defaultStorageClass = storageClass.DeepCopy()
if storageClass.VolumeBindingMode != nil && *storageClass.VolumeBindingMode == storagev1.VolumeBindingImmediate {
log.Println("Default storage class already set to Immediate")
return nil
}
break
}
}
if defaultStorageClass == nil {
return errors.New("no default storage class found")
}

immediateStorageClass := defaultStorageClass
immediateStorageClass.VolumeBindingMode = ptr.To[storagev1.VolumeBindingMode](storagev1.VolumeBindingImmediate)
immediateStorageClass.Name = name
immediateStorageClass.ResourceVersion = ""
immediateStorageClass.Annotations["storageclass.kubernetes.io/is-default-class"] = "false"

_, err = v.Clientset.StorageV1().StorageClasses().Create(context.Background(), immediateStorageClass, metav1.CreateOptions{})
return err
}

func (v *VirtOperator) RemoveStorageClass(name string) error {
return v.Clientset.StorageV1().StorageClasses().Delete(context.Background(), name, metav1.DeleteOptions{})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
apiVersion: v1
kind: List
items:
- apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: cirros-test
namespace: cirros-test
spec:
dataVolumeTemplates:
- apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
name: cirros-test-disk
spec:
sourceRef:
kind: DataSource
name: cirros
namespace: openshift-virtualization-os-images
storage:
resources:
requests:
storage: 150Mi
storageClassName: test-sc-immediate
running: true
template:
metadata:
annotations:
vm.kubevirt.io/flavor: tiny
spec:
domain:
devices:
disks:
- disk:
bus: virtio
name: rootdisk
firmware:
bootloader:
efi:
secureBoot: false
resources:
requests:
cpu: 1
memory: 256Mi
volumes:
- name: rootdisk
persistentVolumeClaim:
claimName: cirros-test-disk
58 changes: 58 additions & 0 deletions tests/e2e/virt_backup_restore_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ var _ = ginkgo.Describe("VM backup and restore tests", ginkgo.Ordered, func() {
gomega.Expect(err).To(gomega.BeNil())

dpaCR.VeleroDefaultPlugins = append(dpaCR.VeleroDefaultPlugins, v1alpha1.DefaultPluginKubeVirt)

err = v.CreateImmediateModeStorageClass("test-sc-immediate")
gomega.Expect(err).To(gomega.BeNil())
})

var _ = ginkgo.AfterAll(func() {
Expand All @@ -193,6 +196,9 @@ var _ = ginkgo.Describe("VM backup and restore tests", ginkgo.Ordered, func() {
if v != nil && wasInstalledFromTest {
v.EnsureVirtRemoval()
}

err := v.RemoveStorageClass("test-sc-immediate")
gomega.Expect(err).To(gomega.BeNil())
})

var _ = ginkgo.AfterEach(func(ctx ginkgo.SpecContext) {
Expand Down Expand Up @@ -242,6 +248,58 @@ var _ = ginkgo.Describe("VM backup and restore tests", ginkgo.Ordered, func() {
},
}, nil),

ginkgo.Entry("immediate binding no-application CSI datamover backup and restore, CirrOS VM", ginkgo.Label("virt"), VmBackupRestoreCase{
Template: "./sample-applications/virtual-machines/cirros-test/cirros-test-immediate.yaml",
InitDelay: 2 * time.Minute, // Just long enough to get to login prompt, VM is marked running while kernel messages are still scrolling by
BackupRestoreCase: BackupRestoreCase{
Namespace: "cirros-test",
Name: "cirros-test",
SkipVerifyLogs: true,
BackupRestoreType: lib.CSIDataMover,
BackupTimeout: 20 * time.Minute,
},
}, nil),

ginkgo.Entry("immediate binding no-application CSI backup and restore, CirrOS VM", ginkgo.Label("virt"), VmBackupRestoreCase{
Template: "./sample-applications/virtual-machines/cirros-test/cirros-test-immediate.yaml",
InitDelay: 2 * time.Minute, // Just long enough to get to login prompt, VM is marked running while kernel messages are still scrolling by
BackupRestoreCase: BackupRestoreCase{
Namespace: "cirros-test",
Name: "cirros-test",
SkipVerifyLogs: true,
BackupRestoreType: lib.CSI,
BackupTimeout: 20 * time.Minute,
},
}, nil),

ginkgo.Entry("immediate binding no-application CSI+datamover backup and restore, powered-off CirrOS VM", ginkgo.Label("virt"), VmBackupRestoreCase{
Template: "./sample-applications/virtual-machines/cirros-test/cirros-test-immediate.yaml",
InitDelay: 2 * time.Minute,
PowerState: "Stopped",
BackupRestoreCase: BackupRestoreCase{
Namespace: "cirros-test",
Name: "cirros-test",
SkipVerifyLogs: true,
BackupRestoreType: lib.CSIDataMover,
BackupTimeout: 20 * time.Minute,
PreBackupVerify: vmPoweredOff("cirros-test", "cirros-test"),
},
}, nil),

ginkgo.Entry("immediate binding no-application CSI backup and restore, powered-off CirrOS VM", ginkgo.Label("virt"), VmBackupRestoreCase{
Template: "./sample-applications/virtual-machines/cirros-test/cirros-test-immediate.yaml",
InitDelay: 2 * time.Minute,
PowerState: "Stopped",
BackupRestoreCase: BackupRestoreCase{
Namespace: "cirros-test",
Name: "cirros-test",
SkipVerifyLogs: true,
BackupRestoreType: lib.CSI,
BackupTimeout: 20 * time.Minute,
PreBackupVerify: vmPoweredOff("cirros-test", "cirros-test"),
},
}, nil),

ginkgo.Entry("todolist CSI backup and restore, in a Fedora VM", ginkgo.Label("virt"), VmBackupRestoreCase{
Template: "./sample-applications/virtual-machines/fedora-todolist/fedora-todolist.yaml",
InitDelay: 3 * time.Minute, // For cloud-init
Expand Down

0 comments on commit fe4ca09

Please sign in to comment.