Skip to content

Commit 6e1f27d

Browse files
committed
Add comprehensive test for virsh managedsave-edit
This commit introduces a new test for `virsh managedsave-edit`, verifying its ability to modify a VM's saved XML configuration, specifically the disk path, and successfully restore the VM. It includes scenarios for different VM states and validates error handling for invalid options and readonly mode. Signed-off-by: Yalan Zhang <yalzhang@redhat.com>
1 parent f69f72e commit 6e1f27d

File tree

2 files changed

+148
-0
lines changed

2 files changed

+148
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
- save_and_restore.managedsave_edit:
2+
type = managedsave_edit
3+
start_vm = "yes"
4+
status_error = "no"
5+
variants:
6+
- opt_none:
7+
virsh_opt = ''
8+
pre_state = 'running'
9+
- opt_running:
10+
virsh_opt = '--running'
11+
pre_state = 'paused'
12+
- opt_paused:
13+
virsh_opt = '--paused'
14+
pre_state = 'running'
15+
- opt_exclusive:
16+
virsh_opt = '--running --paused'
17+
pre_state = 'running'
18+
status_error = 'yes'
19+
variants:
20+
- normal:
21+
readonly = 'no'
22+
- readonly:
23+
only opt_none
24+
readonly = 'yes'
25+
status_error = 'yes'
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import logging
2+
import os
3+
import re
4+
import shutil
5+
6+
from avocado.utils import process
7+
8+
from virttest import virsh
9+
from virttest.libvirt_xml import vm_xml
10+
from virttest.utils_test import libvirt
11+
12+
LOG = logging.getLogger("avocado.test." + __name__)
13+
14+
15+
def vm_state_check(test, vm_name, new_disk_path, virsh_opt):
16+
"""
17+
Check domain xml and state after restore from saved image.
18+
"""
19+
cmd_re = virsh.dumpxml(vm_name, debug=True)
20+
if cmd_re.exit_status:
21+
test.fail(f"Failed to dump xml of domain '{vm_name}'")
22+
23+
# The xml should contain the match_string
24+
xml = cmd_re.stdout.strip()
25+
xml_pattern = f"<source file='{new_disk_path}'"
26+
LOG.info(f"Checking for disk path '{new_disk_path}' in domain XML.")
27+
28+
if not re.search(xml_pattern, xml):
29+
test.fail(
30+
f"After domain restore the xml is not expected, could not find source file='{new_disk_path}'"
31+
)
32+
else:
33+
LOG.info(f"Found source file='{new_disk_path}' in the domain xml successfully!")
34+
35+
dom_state = virsh.domstate(vm_name, debug=True).stdout.strip()
36+
LOG.info(f"VM state after restore is '{dom_state}'")
37+
if virsh_opt == "--running" and dom_state != "running":
38+
test.fail(
39+
"The domain state is not as expected with option '--running'. Got 'paused', expected 'running'"
40+
)
41+
elif virsh_opt == "--paused" and dom_state != "paused":
42+
test.fail(
43+
"The domain state is not as expected with option '--paused'. Got 'running', expected 'paused'"
44+
)
45+
46+
47+
def run(test, params, env):
48+
"""
49+
Test command: virsh managedsave-edit <vm_name> [option]
50+
1) Prepare test environment, ensure VM is in requested state: running or paused
51+
2) Do managedsave for the VM
52+
3) Execute virsh managedsave-edit to edit xml
53+
4) Start VM
54+
5) Check the new xml of the VM and its state
55+
"""
56+
pre_state = params.get("pre_state")
57+
readonly = "yes" == params.get("readonly", "no")
58+
status_error = "yes" == params.get("status_error", "no")
59+
virsh_opt = params.get("virsh_opt")
60+
61+
vm_name = params.get("main_vm")
62+
vm = env.get_vm(vm_name)
63+
new_path = None
64+
try:
65+
LOG.info("Preparing the VM state...")
66+
if not vm.is_alive():
67+
vm.start()
68+
if pre_state == "paused":
69+
virsh.suspend(vm_name, debug=True)
70+
vm_state = virsh.domstate(vm_name).stdout_text.strip()
71+
LOG.info(f"The VM state is '{vm_state}' before save")
72+
73+
LOG.info("TEST STEP 1: Perform 'virsh managedsave' to save the vm...")
74+
cmd_result = virsh.managedsave(vm_name, debug=True)
75+
libvirt.check_result(cmd_result)
76+
77+
LOG.info("TEST STEP 2: Run managedsave-edit to update the disk path:")
78+
disk_path = vm.get_first_disk_devices()["source"]
79+
new_path = f"{disk_path}.test"
80+
81+
# Ensure the new path does not already exist
82+
if os.path.exists(new_path):
83+
LOG.warning(f"The path '{new_path}' already exists. Removing it...")
84+
os.remove(new_path)
85+
86+
shutil.copy(disk_path, new_path)
87+
LOG.info(f"The original disk path is '{disk_path}'")
88+
LOG.info(f"The new disk path will be: '{new_path}'")
89+
90+
replace_string = r":%s /" + disk_path.replace("/", "\/")
91+
replace_string += "/" + new_path.replace("/", "\/")
92+
stat = libvirt.exec_virsh_edit(
93+
vm_name,
94+
[replace_string],
95+
managedsave_edit=True,
96+
readonly=readonly,
97+
virsh_opt=virsh_opt,
98+
)
99+
if not stat:
100+
if status_error:
101+
LOG.info("Failed to edit the xml, this was expected!")
102+
else:
103+
test.fail("managedsave-edit failed!")
104+
else:
105+
if status_error:
106+
test.fail("managedsave-edit succeeded when it should have failed!")
107+
108+
if not status_error:
109+
LOG.info("TEST STEP 3: Start VM for positive scenarios:")
110+
cmd_result = virsh.start(vm_name, debug=True)
111+
libvirt.check_result(cmd_result)
112+
LOG.info(
113+
"TEST STEP 4: Verify VM status and the XML content for positive scenarios:"
114+
)
115+
vm_state_check(test, vm_name, new_path, virsh_opt)
116+
except Exception as e:
117+
test.error(f"Unexpected error happened during the test execution: {e}")
118+
finally:
119+
# Cleanup
120+
if new_path and os.path.exists(new_path):
121+
LOG.info(f"Remove the file {new_path}")
122+
os.remove(new_path)
123+
virsh.managedsave_remove(vm_name, debug=True)

0 commit comments

Comments
 (0)