Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vm snapshot test case #11045

Merged
merged 4 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ocs_ci/helpers/cnv_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ def create_dv(
namespace=constants.CNV_NAMESPACE,
):
"""
Create/Clones a DV using a specified data source
Creates a DV using a specified data source

Args:
access_mode (str): The access mode for the volume. Default is `constants.ACCESS_MODE_RWX`
Expand Down
24 changes: 23 additions & 1 deletion ocs_ci/ocs/cnv/virtual_machine.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from ocs_ci.ocs.cnv.virtual_machine_instance import VirtualMachineInstance
from ocs_ci.ocs import constants, ocp
from ocs_ci.ocs.resources import pvc
from ocs_ci.ocs.resources.pvc import PVC
from ocs_ci.utility import templating
from ocs_ci.utility.utils import TimeoutSampler
from ocs_ci.ocs.exceptions import UsernameNotFoundException, CommandFailed
Expand Down Expand Up @@ -93,6 +94,7 @@ def create_vm_workload(
access_mode=constants.ACCESS_MODE_RWX,
pvc_size="30Gi",
source_url=constants.CNV_CENTOS_SOURCE,
pvc_obj=None,
ssh=True,
verify=True,
):
Expand All @@ -107,6 +109,7 @@ def create_vm_workload(
sc_name (str): The name of the storage class to use. Default is `constants.DEFAULT_CNV_CEPH_RBD_SC`.
pvc_size (str): The size of the PVC. Default is "30Gi".
source_url (str): The URL of the vm registry image. Default is `constants.CNV_CENTOS_SOURCE`
pvc_obj (obj, optional): PVC object to use existing pvc as a backend volume to VM

"""
self.volume_interface = volume_interface
Expand All @@ -121,7 +124,12 @@ def create_vm_workload(
self._add_ssh_key_to_vm(vm_data)

if volume_interface == constants.VM_VOLUME_PVC:
self._create_vm_pvc(vm_data=vm_data)
if pvc_obj:
vm_data["spec"]["template"]["spec"]["volumes"][0][
"persistentVolumeClaim"
] = {"claimName": pvc_obj.name}
else:
self._create_vm_pvc(vm_data=vm_data)
elif volume_interface == constants.VM_VOLUME_DV:
self._create_vm_data_volume(vm_data=vm_data)
elif volume_interface == constants.VM_VOLUME_DVT:
Expand Down Expand Up @@ -280,6 +288,20 @@ def get(self, out_yaml_format=True):
resource_name=self._vm_name, out_yaml_format=out_yaml_format
)

def get_vm_pvc_obj(self):
"""
Retrieves VM PVC obj

Returns:
obj: PVC object

"""
ocp_pvc_obj = OCP(kind=constants.PVC, namespace=self.namespace).get(
resource_name=self.pvc_name
)
pvc_obj = PVC(**ocp_pvc_obj)
return pvc_obj

def get_os_username(self):
"""
Retrieve the operating system username from the cloud-init data associated with the virtual machine
Expand Down
6 changes: 5 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7056,6 +7056,7 @@ def factory(
storageclass=constants.DEFAULT_CNV_CEPH_RBD_SC,
pvc_size="30Gi",
source_url=constants.CNV_CENTOS_SOURCE,
pvc_obj=None,
namespace=None,
):
"""
Expand All @@ -7065,6 +7066,7 @@ def factory(
storageclass (str): The name of the storage class to use. Default is `constants.DEFAULT_CNV_CEPH_RBD_SC`.
pvc_size (str): The size of the PVC. Default is "30Gi".
source_url (str): The URL of the vm registry image. Default is `constants.CNV_CENTOS_SOURCE`.
pvc_obj (obj, optional): PVC object to use existing pvc as a backend volume to VM
namespace (str, optional): The namespace to create the vm on. Default, creates a unique namespace.

Returns:
Expand All @@ -7079,6 +7081,7 @@ def factory(
sc_name=storageclass,
pvc_size=pvc_size,
source_url=source_url,
pvc_obj=pvc_obj,
)
cnv_workloads.append(cnv_wl)
return cnv_workloads
Expand All @@ -7088,7 +7091,8 @@ def teardown():
Cleans up the CNV workloads

"""
for cnv_wl in cnv_workloads:
# Iterating from end so that restored VMs are deleted before source
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is deleting the restored VMs before the source causing any problems? At least in PVCs, IIRC, I don't think there will be any issues. The parent PVC can be deleted even with the restored PVC in use

Copy link
Contributor

@avd-sagare avd-sagare Dec 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure I am working on this and I will take care of this in my next immediate PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on avadhoot's comments, I will merge this PR as it's required urgently and low priority review comments will be handled in a followup PR

for cnv_wl in cnv_workloads[::-1]:
cnv_wl.delete()

request.addfinalizer(teardown)
Expand Down
57 changes: 57 additions & 0 deletions tests/functional/workloads/cnv/test_vm_cloning_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,60 @@ def test_vm_clone(self, cnv_workload, clone_vm_workload, setup_cnv):
), f"Failed: MD5 comparison between source {vm_obj.name} and cloned {clone_obj.name} VMs"
run_dd_io(vm_obj=clone_obj, file_path=file_paths[1])
clone_obj.stop()

@workloads
@pytest.mark.polarion_id("OCS-6299")
def test_vm_snapshot_ops(
avd-sagare marked this conversation as resolved.
Show resolved Hide resolved
self, cnv_workload, snapshot_factory, snapshot_restore_factory
):
"""
This test performs the VM PVC snapshot operations

Test steps:
1. Create VMs, add data(e.g., files) to all the VMs
2. Create a snapshot for a VM backed pvc
3. Restore the snapshot (to same access mode of the parent PVC and storage_class) by following the
documented procedure from ODF official docs
4. Create new vm using restored pvc Verify existing data of the VM are not changed.
5. Add further data(e.g., new file) to the VM
6. Repeat the above procedure for all the VMs in the system
7. Delete all the VMs created as part of this test
"""
file_paths = ["/file.txt", "/new_file.txt"]
# TODO: Add multi_cnv fixture to configure VMs based on specifications
vm_obj = cnv_workload(
volume_interface=constants.VM_VOLUME_PVC,
source_url=constants.CNV_FEDORA_SOURCE,
)[0]
# Writing IO on source VM
source_csum = run_dd_io(vm_obj=vm_obj, file_path=file_paths[0], verify=True)
# Stopping VM before taking snapshot of the VM PVC
vm_obj.stop()
avd-sagare marked this conversation as resolved.
Show resolved Hide resolved
# Taking Snapshot of PVC
pvc_obj = vm_obj.get_vm_pvc_obj()
snap_obj = snapshot_factory(pvc_obj)
# Restore snapshot
res_snap_obj = snapshot_restore_factory(
snapshot_obj=snap_obj,
storageclass=vm_obj.sc_name,
size=vm_obj.pvc_size,
volume_mode=snap_obj.parent_volume_mode,
access_mode=vm_obj.pvc_access_mode,
status=constants.STATUS_BOUND,
timeout=300,
)
# Create new PVC using the restore PVC
avd-sagare marked this conversation as resolved.
Show resolved Hide resolved
res_vm_obj = cnv_workload(
volume_interface=constants.VM_VOLUME_PVC,
source_url=constants.CNV_FEDORA_SOURCE,
pvc_obj=res_snap_obj,
namespace=vm_obj.namespace,
)[1]
# Write new file to VM
run_dd_io(vm_obj=res_vm_obj, file_path=file_paths[1], verify=True)
# Validate data integrity of file written before taking snapshot
res_csum = cal_md5sum_vm(vm_obj=res_vm_obj, file_path=file_paths[0])
assert (
source_csum == res_csum
), f"Failed: MD5 comparison between source {vm_obj.name} and cloned {res_vm_obj.name} VMs"
res_vm_obj.stop()
Loading