Skip to content

Commit 72e0d67

Browse files
committed
Test managedsave-edit
Test the virsh cmd managedsave-edit with different vm status. Signed-off-by: Yalan Zhang <yalzhang@redhat.com>
1 parent 108f12a commit 72e0d67

File tree

2 files changed

+179
-0
lines changed

2 files changed

+179
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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+
err_msg = 'mutually exclusive'
19+
status_error = 'yes'
20+
variants:
21+
- normal:
22+
readonly = 'no'
23+
- readonly:
24+
only opt_none
25+
readonly = 'yes'
26+
status_error = 'yes'
27+
err_msg = 'operation forbidden'
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import logging
2+
import os
3+
import re
4+
import aexpect
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 run(test, params, env):
16+
"""
17+
Test command: virsh managedsave-edit <vm_name> [option]
18+
1) Prepare test environment, ensure VM is in requested state: running or paused
19+
2) Do managedsave for the VM
20+
3) Execute virsh managedsave-edit to edit xml
21+
4) Start VM
22+
5) Check the new xml of the VM and its state
23+
"""
24+
25+
def edit_vm_xml(xml_before_, xml_after_, option):
26+
"""
27+
Edit XML content using virsh managedsave-edit command.
28+
Args:
29+
xml_before_ (str): Original XML content.
30+
xml_after_ (str): Updated XML content.
31+
option (str): Command-line option for managedsave-edit.
32+
Returns:
33+
None
34+
"""
35+
edit_cmd = r":%s /" + xml_before_.replace("/", "\/")
36+
edit_cmd += "/" + xml_after_.replace("/", "\/")
37+
session = aexpect.ShellSession("sudo -s")
38+
39+
try:
40+
LOG.info(f"Executing virsh managedsave-edit {vm_name} with option '{option}'...")
41+
if readonly:
42+
cmd = f"virsh -r managedsave-edit {vm_name} {option}"
43+
else:
44+
cmd = f"virsh managedsave-edit {vm_name} {option}"
45+
session.sendline(cmd)
46+
LOG.info(f"Replacing '{xml_before_}' with '{xml_after_}' in the XML file")
47+
session.sendline(edit_cmd)
48+
session.send('\x1b')
49+
session.send('ZZ')
50+
session.read_until_any_line_matches(
51+
patterns=['Managed save image of Domain.* XML configuration edited', 'not changed'],
52+
timeout=5,
53+
print_func=logging.debug
54+
)
55+
except (aexpect.ShellError, aexpect.ExpectError, aexpect.ShellTimeoutError) as details:
56+
session.close()
57+
if status_error:
58+
LOG.info("Failed to do managedsave-edit: %s", details)
59+
if err_msg not in str(details):
60+
test.error(f"Managedsave-edit failed as expected but did not find the expected error message: '{err_msg}'")
61+
else:
62+
LOG.info(f'Managedsave-edit failed as expected with error message: "{err_msg}"')
63+
else:
64+
test.error(f"Failed to do managedsave-edit: {details}")
65+
66+
def vm_state_check():
67+
"""
68+
Check domain xml and state after restore from saved image.
69+
Returns:
70+
None
71+
"""
72+
cmd_re = virsh.dumpxml(vm_name, debug=True)
73+
if cmd_re.exit_status:
74+
test.fail(f"Failed to dump xml of domain '{vm_name}'")
75+
76+
# The xml should contain the match_string
77+
xml = cmd_re.stdout.strip()
78+
LOG.info(f"The after domain is {xml_after}")
79+
end_index = xml_after.find(".qcow2'") + len(".qcow2'")
80+
xml_to_check = xml_after[:end_index]
81+
LOG.info(f"The xml to check is '{xml_to_check}'")
82+
83+
if not re.search(xml_to_check, xml):
84+
test.fail(f"After domain restore the xml is not expected, expected '{xml_to_check}'")
85+
else:
86+
LOG.info(f'Found {xml_to_check} in the domain xml successfully!')
87+
88+
dom_state = virsh.domstate(vm_name, debug=True).stdout.strip()
89+
LOG.info(f"VM state after restore is '{dom_state}'")
90+
if virsh_opt == '--running' and dom_state == 'paused':
91+
test.fail("The domain state is not as expected with option '--running'. Got 'paused', expected 'running'")
92+
elif virsh_opt == '--paused' and dom_state == "running":
93+
test.fail("The domain state is not as expected with option '--paused'. Got 'running', expected 'paused'")
94+
95+
pre_state = params.get("pre_state")
96+
err_msg = params.get('err_msg', '')
97+
readonly = "yes" == params.get("readonly", "no")
98+
status_error = "yes" == params.get("status_error", "no")
99+
virsh_opt = params.get("virsh_opt")
100+
101+
vm_name = params.get("main_vm")
102+
vm = env.get_vm(vm_name)
103+
vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
104+
bk_xml = vmxml.copy()
105+
try:
106+
LOG.info("Preparing the VM state...")
107+
if not vm.is_alive():
108+
vm.start()
109+
if pre_state == "paused":
110+
virsh.suspend(vm_name, debug=True)
111+
vm_state = virsh.domstate(vm_name).stdout_text.strip()
112+
LOG.info(f"The VM state is '{vm_state}' before save")
113+
114+
LOG.info("TEST STEP 1: Perform 'virsh managedsave' to save the vm...")
115+
cmd_result = virsh.managedsave(vm_name, debug=True)
116+
libvirt.check_result(cmd_result)
117+
118+
LOG.info("TEST STEP 2: Run managedsave-edit to update the disk path:")
119+
disk_path = vm.get_first_disk_devices()['source']
120+
dirname = os.path.dirname(disk_path)
121+
basename = os.path.basename(disk_path)
122+
filename, ext = os.path.splitext(basename)
123+
new_filename = f"{filename}-test{ext}"
124+
new_path = os.path.join(dirname, new_filename)
125+
126+
# Ensure the new path does not already exist
127+
if os.path.exists(new_path):
128+
LOG.warning(f"The path '{new_path}' already exists. Removing it...")
129+
os.remove(new_path)
130+
131+
process.run(f"cp {disk_path} {new_path}", shell=True)
132+
LOG.info("The original disk path is '%s'", disk_path)
133+
xml_before = f"<source file='{disk_path}'/>"
134+
LOG.info("The original XML content is: %s", xml_before)
135+
136+
xml_after = f"<source file='{new_path}'/>"
137+
LOG.info("The updated XML content will be: %s", xml_after)
138+
139+
edit_vm_xml(xml_before, xml_after, virsh_opt)
140+
141+
if not status_error:
142+
LOG.info("TEST STEP 3: Start VM for positive scenarios:")
143+
cmd_result = virsh.start(vm_name, debug=True)
144+
libvirt.check_result(cmd_result)
145+
LOG.info("TEST STEP 4: Verify VM status and the XML content for positive scenarios:")
146+
vm_state_check()
147+
finally:
148+
# Cleanup
149+
LOG.info(f"Remove the file {new_path}")
150+
os.remove(new_path)
151+
virsh.managedsave_remove(vm_name, debug=True)
152+
bk_xml.sync()

0 commit comments

Comments
 (0)