Skip to content

Commit

Permalink
Merge pull request autotest#5485 from nanli1/virtio_mem_memory_cold_p…
Browse files Browse the repository at this point in the history
…lug_and_unplug

add case for virtio-mem coldplug and cold unplug
  • Loading branch information
dzhengfy authored May 27, 2024
2 parents fa0d202 + 9c787bd commit e489d28
Show file tree
Hide file tree
Showing 2 changed files with 277 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
- memory.devices.virtio_mem.coldplug_and_unplug:
type = virtio_mem_coldplug_and_unplug
no s390-virtio
start_vm = "no"
mem_model = "virtio-mem"
target_size = 524288
request_size = 524288
size_unit = 'KiB'
request_unit = 'KiB'
block_unit = 'KiB'
plug_size_unit = 'KiB'
plug_request_unit = 'KiB'
plug_block_unit = 'KiB'
mem_value = 2097152
current_mem = 2097152
numa_mem = 1048576
max_mem = 4194304
max_mem_slots = 16
max_dict = '"max_mem_rt": ${max_mem}, "max_mem_rt_slots": ${max_mem_slots}, "max_mem_rt_unit": "KiB"'
numa_dict = "'vcpu': 4,'cpu':{'numa_cell': [{'id': '0', 'cpus': '0-1', 'memory': '${numa_mem}'}, {'id': '1', 'cpus': '2-3', 'memory': '${numa_mem}'}]}"
vm_attrs = {${numa_dict},${max_dict},'memory_unit':'KiB','memory':${mem_value},'current_mem':${current_mem},'current_mem_unit':'KiB'}
numa_xpath = [{'element_attrs':[".//cell[@unit='KiB']",".//cell[@id='0']",".//cell[@memory='${numa_mem}']"]}]
base = '0x100000000'
plug_option = " --config"
required_kernel = [5.14.0,)
guest_required_kernel = [5.8.0,)
func_supported_since_libvirt_ver = (8, 0, 0)
func_supported_since_qemu_kvm_ver = (6, 2, 0)
variants case:
- with_addr:
plug_target_size = 1048576
plug_request_size = 1048576
addr_dict = "'address':{'attrs': {'base': '${base}'}}"
virtio_dict = {'mem_model':'${mem_model}','target': {${addr_dict},'size':${target_size}, 'size_unit':'${size_unit}', 'node':0,'requested_size': ${request_size},'requested_unit':'${request_unit}', 'block_size': %s, 'block_unit':'${block_unit}'}}
unplug_dict = ${virtio_dict}
plug_dict = {'mem_model':'${mem_model}','target': {${addr_dict},'size':${plug_target_size},'requested_size': ${plug_request_size}, 'block_size': %s, 'size_unit':'${plug_size_unit}','requested_unit':'${plug_request_unit}','block_unit':'${plug_block_unit}','node':0}}
virtio_xpath = [{'element_attrs':["./devices/memory/target/size[@unit='${size_unit}']"],'text':'${target_size}'},{'element_attrs':[".//memory/target/block[@unit='${block_unit}']"],'text':'%s'}, {'element_attrs':[".//memory/target/requested[@unit='${request_unit}']"],'text':'${request_size}'},{'element_attrs':[".//memory/target/address[@base='${base}']"]}]
unplug_xpath = ${virtio_xpath}
plug_xpath = [{'element_attrs':[".//memory/target/size[@unit='${plug_size_unit}']"],'text':'${plug_target_size}'},{'element_attrs':[".//memory/target/block[@unit='${block_unit}']"],'text':'%s'}, {'element_attrs':[".//memory/target/requested[@unit='${plug_request_unit}']"],'text':'${plug_request_size}'},{'element_attrs':[".//memory/target/address[@base='${base}']"]}]
- source_and_mib:
target_size = 512
request_size = 512
size_unit = 'MiB'
request_unit = 'MiB'
plug_target_size = 1024
plug_request_size = 1024
plug_size_unit = 'MiB'
plug_request_unit = 'MiB'
plug_block_unit = 'KiB'
nodemask = '0'
source_dict = "'source': {'nodemask': '0','pagesize': 4, 'pagesize_unit':'KiB'}"
virtio_dict = {'mem_model':'${mem_model}',${source_dict}, 'target': {'size':${target_size}, 'size_unit':'${size_unit}','requested_unit':'${request_unit}','block_unit':'${block_unit}','node':1,'requested_size': ${request_size}, 'block_size': %s}}
unplug_dict = ${virtio_dict}
plug_dict = {'mem_model':'${mem_model}',${source_dict},'target': {'size':${plug_target_size},'requested_size': ${plug_request_size}, 'block_size': %s, 'size_unit':'${plug_size_unit}','requested_unit':'${plug_request_unit}','block_unit':'${plug_block_unit}','node':1}}
virtio_xpath = [{'element_attrs':[".//memory/target/size[@unit='KiB']"],'text':'%s'},{'element_attrs':[".//memory/target/block[@unit='KiB']"],'text':'%s'}, {'element_attrs':[".//memory/target/requested[@unit='KiB']"],'text':'%s'}, {'element_attrs':[".//memory/source/pagesize"]}, {'element_attrs':[".//memory/source/nodemask"],'text':'${nodemask}'}]
unplug_xpath = ${virtio_xpath}
plug_xpath = [{'element_attrs':[".//memory/target/size[@unit='KiB']"],'text':'%s'},{'element_attrs':[".//memory/target/block[@unit='KiB']"],'text':'%s'}, {'element_attrs':[".//memory/target/requested[@unit='KiB']"],'text':'%s'}]
- unplug_none_dev:
addr_dict = "'address':{'attrs': {'base': '${base}'}}"
virtio_dict = {'mem_model':'${mem_model}', 'target': {'size':${target_size}, 'size_unit':'KiB', ${addr_dict}, 'node':0,'requested_size': ${request_size}, 'block_size': %s}}
unplug_request_size = 0
unplug_dict = {'mem_model':'${mem_model}', 'target': {'requested_size': ${unplug_request_size}, 'size':${target_size}, 'size_unit':'KiB', ${addr_dict}, 'node':0,'block_size': %s}}
unplug_error = "matching memory device was not found"
virtio_xpath = [{'element_attrs':[".//memory/target/size[@unit='${size_unit}']"],'text':'${target_size}'},{'element_attrs':[".//memory/target/block[@unit='${block_unit}']"],'text':'%s'}, {'element_attrs':[".//memory/target/requested[@unit='${request_unit}']"],'text':'${request_size}'},{'element_attrs':[".//memory/target/address[@base='${base}']"]}]
unplug_xpath = [{'element_attrs':[".//memory/target/size[@unit='${size_unit}']"],'text':'${target_size}'},{'element_attrs':[".//memory/target/block[@unit='${plug_block_unit}']"],'text':'%s'}, {'element_attrs':[".//memory/target/requested[@unit='${plug_request_unit}']"],'text':'${unplug_request_size}'},{'element_attrs':[".//memory/target/address[@base='${base}']"]}]
- plug_exceeded_max_mem:
target_size = 1572864
request_size = 1572864
plug_target_size = 1024
plug_request_size = 1024
virtio_dict = {'mem_model':'${mem_model}', 'target': {'size':${target_size}, 'size_unit':'KiB','node':1,'requested_size': ${request_size}, 'block_size': %s}}
plug_size_unit = 'MiB'
plug_request_unit = 'MiB'
plug_dict = {'mem_model':'${mem_model}','target': {'size':${plug_target_size},'requested_size': ${plug_request_size}, 'block_size': %s, 'size_unit':'${plug_size_unit}','requested_unit':'${plug_request_unit}','block_unit':'${plug_block_unit}','node':1}}
virtio_xpath = [{'element_attrs':[".//memory/target/size[@unit='${size_unit}']"],'text':'${target_size}'},{'element_attrs':[".//memory/target/block[@unit='${block_unit}']"],'text':'%s'}, {'element_attrs':[".//memory/target/requested[@unit='${request_unit}']"],'text':'${request_size}'}]
plug_xpath = [{'element_attrs':[".//memory/target/size[@unit='${size_unit}']"],'text':'%s'},{'element_attrs':[".//memory/target/block[@unit='${block_unit}']"],'text':'%s'}, {'element_attrs':[".//memory/target/requested[@unit='${request_unit}']"],'text':'%s'}]
plug_error = "Attaching memory device with size '\S+' would exceed domain's maxMemory config size '${max_mem}'"
- duplicate_addr:
addr_dict = "'address':{'attrs': {'base': '0x100000000'}}"
virtio_dict = {'mem_model':'${mem_model}', 'target': {${addr_dict},'size':${target_size}, 'size_unit':'KiB', ${addr_dict}, 'node':0,'requested_size': ${request_size}, 'block_size': %s}}
plug_dict = ${virtio_dict}
plug_error = "unsupported configuration: memory device address [0x100000000:0x108000000] overlaps with other memory device (0x100000000)"
virtio_xpath = [{'element_attrs':[".//memory/target/size[@unit='${size_unit}']"],'text':'${target_size}'},{'element_attrs':[".//memory/target/block[@unit='${block_unit}']"],'text':'%s'}, {'element_attrs':[".//memory/target/requested[@unit='${request_unit}']"],'text':'${request_size}'},{'element_attrs':[".//memory/target/address[@base='${base}']"]}]
plug_xpath = ${virtio_xpath}
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright Redhat
#
# SPDX-License-Identifier: GPL-2.0

# Author: Nannan Li <[email protected]>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

from avocado.utils import memory

from virttest import virsh
from virttest.libvirt_xml import vm_xml
from virttest.utils_test import libvirt
from virttest.utils_libvirt import libvirt_vmxml

from provider.memory import memory_base


def adjust_virtio_params(params):
"""
Adjust all virtio related size and xpath.
:param params: dict wrapped with params.
"""
plug_target_size = int(params.get('plug_target_size', 0))
plug_request_size = int(params.get('plug_request_size', 0))
target_size, request_size = int(params.get('target_size')), int(params.get('request_size'))
plug_size_unit = params.get('plug_size_unit')
plug_request_unit = params.get('plug_request_unit')
size_unit, request_unit = params.get('size_unit'), params.get('request_unit')

def _convert_size(curr_size, curr_unit, var_str):
if curr_unit != "KiB":
new_size = memory_base.convert_data_size(str(curr_size) + curr_unit)
params.update({var_str: int(new_size)})

_convert_size(target_size, size_unit, 'target_size')
_convert_size(request_size, request_unit, 'request_size')
_convert_size(plug_target_size, plug_size_unit, 'plug_target_size')
_convert_size(plug_request_size, plug_request_unit, 'plug_request_size')


def adjust_virtio_xpath(params):
"""
Adjust all expected virtio xpath in different scenarios.
:param params: dict wrapped with params.
:return virtio_xpath, unplug_xpath, plug_xpath, expected defined virtio xpath,
expected plugged virtio xpath, expected unplugged virtio xpath.
"""
default_hugepage_size = memory.get_huge_page_size()
adjust_virtio_params(params)

plug_target_size = params.get('plug_target_size')
plug_request_size = params.get('plug_request_size')
target_size, request_size = params.get('target_size'), params.get('request_size')
case = params.get("case")
virtio_xpath = params.get("virtio_xpath")
unplug_xpath = params.get("unplug_xpath")
plug_xpath = params.get("plug_xpath")

if case == "source_and_mib":
virtio_xpath = virtio_xpath % (target_size, default_hugepage_size,
request_size)
unplug_xpath = eval(virtio_xpath)
plug_xpath = eval(plug_xpath % (plug_target_size, default_hugepage_size,
plug_request_size))
elif case == "plug_exceeded_max_mem":
virtio_xpath = virtio_xpath % default_hugepage_size
plug_xpath = eval(plug_xpath % (plug_target_size, default_hugepage_size,
plug_request_size))
else:
virtio_xpath = virtio_xpath % default_hugepage_size
if unplug_xpath:
unplug_xpath = eval(unplug_xpath % default_hugepage_size)
if plug_xpath:
plug_xpath = eval(plug_xpath % default_hugepage_size)
return eval(virtio_xpath), unplug_xpath, plug_xpath


def check_xpath_unexist(test, vmxml, not_exist_path):
"""
Check specific xpath info not exist in guest xml.
:param test: test object.
:param vmxml: current guest xml.
:param not_exist_path: The xpath that should not exist in guest.
"""
if libvirt_vmxml.check_guest_xml_by_xpaths(
vmxml, not_exist_path, ignore_status=True):
test.fail("Expect to not get %s in guest" % not_exist_path)


def run(test, params, env):
"""
Verify virtio-mem memory device cold-plug and cold-unplug
with different configs
"""
def setup_test():
"""
Check Versions.
"""
test.log.info("TEST_SETUP: Check related version")
memory_base.check_supported_version(params, test, vm)

def run_test():
"""
Define guest, then cold unplug and cold plug virtio mem device.
"""
test.log.info("TEST_SETUP1: Define guest")
vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
vmxml.setup_attrs(**vm_attrs)
vmxml.devices = vmxml.devices.append(
libvirt_vmxml.create_vm_device_by_type('memory', virtio_dict))
virsh.define(vmxml.xml, debug=True, ignore_status=False)

test.log.info("TEST_STEP2: Check guest xml")
virtio_xpath, unplug_xpath, plug_xpath = adjust_virtio_xpath(params)
vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
libvirt_vmxml.check_guest_xml_by_xpaths(vmxml, numa_xpath+virtio_xpath)

if unplug_dict:
test.log.info("TEST_SETUP3,4:Cold unplug a virtio-mem and check xml")
cold_unplug_obj = libvirt_vmxml.create_vm_device_by_type(
'memory', unplug_dict)
ret = virsh.detach_device(vm.name, cold_unplug_obj.xml,
flagstr=plug_option, debug=True)

vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
if unplug_error:
libvirt.check_result(ret, unplug_error)
libvirt_vmxml.check_guest_xml_by_xpaths(vmxml, numa_xpath+virtio_xpath)
else:
libvirt.check_exit_status(ret)
check_xpath_unexist(test, vmxml, unplug_xpath)

if plug_dict:
test.log.info("TEST_SETUP5-7: Cold plug virtio-mem and check xml")
cold_plug_obj = libvirt_vmxml.create_vm_device_by_type(
'memory', plug_dict)
ret = virsh.attach_device(vm.name, cold_plug_obj.xml,
flagstr=plug_option, debug=True)
if case in ["with_addr", "source_and_mib", "duplicate_addr"]:
vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
if plug_error:
libvirt.check_result(ret, plug_error, any_error=True)
libvirt_vmxml.check_guest_xml_by_xpaths(vmxml, numa_xpath+virtio_xpath)
if case != "duplicate_addr":
check_xpath_unexist(test, vmxml, plug_xpath)
else:
libvirt.check_exit_status(ret)
libvirt_vmxml.check_guest_xml_by_xpaths(vmxml, numa_xpath+plug_xpath)
elif case in ["plug_exceeded_max_mem"]:
for plug_time in range(0, 3):
ret = virsh.attach_device(vm.name, cold_plug_obj.xml,
flagstr=plug_option, debug=True)
if plug_time == 2:
libvirt.check_result(ret, plug_error)

def teardown_test():
"""
Clean data.
"""
test.log.info("TEST_TEARDOWN: Clean up env.")
bkxml.sync()

vm_name = params.get("main_vm")
vm = env.get_vm(vm_name)
vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
bkxml = vmxml.copy()
case = params.get("case")
default_hugepage_size = memory.get_huge_page_size()

plug_option = params.get("plug_option")
vm_attrs = eval(params.get('vm_attrs', '{}'))
numa_xpath = eval(params.get("numa_xpath", ""))
unplug_error = params.get("unplug_error")
plug_error = params.get("plug_error")
virtio_dict = eval(params.get('virtio_dict', '{}') % default_hugepage_size)
unplug_dict = params.get('unplug_dict')
plug_dict = params.get('plug_dict')

unplug_dict = eval(unplug_dict % default_hugepage_size) if unplug_dict else ''
plug_dict = eval(plug_dict % default_hugepage_size) if plug_dict else ''

try:
setup_test()
run_test()

finally:
teardown_test()

0 comments on commit e489d28

Please sign in to comment.