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

add case for invalid dimm device config #5263

Merged
merged 1 commit into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
- memory.devices.invalid_dimm:
type = invalid_dimm_memory_device_config
node_mask = '1'
target_size = 524288
guest_node = 0
slot = 0
addr_type = 'dimm'
addr_base = '0x100000000'
pagesize_cmd = "getconf PAGE_SIZE"
pagesize_unit = 'b'
mem_value = 2097152
mem_unit = 'KiB'
current_mem = 2097152
current_mem_unit = 'KiB'
numa_mem = 1048576
max_mem_slots = 16
max_mem = 10485760
max_mem_unit = 'KiB'
max_dict = '"max_mem_rt": ${max_mem}, "max_mem_rt_slots": ${max_mem_slots}, "max_mem_rt_unit": "${max_mem_unit}"'
variants invalid_setting:
- exceed_slot:
slot = '4294967295'
define_error = "memory device slot '${slot}' exceeds slots count"
- max_addr:
addr_base = '0xffffffffffffffff'
start_vm_error = "address must be aligned to"
- unexisted_node:
guest_node = '6'
start_vm_error = "can't add memory backend for guest node '${guest_node}' as the guest has only '2' NUMA nodes configured"
- unexisted_nodemask:
node_mask = '7'
start_vm_error = "NUMA node ${node_mask} is unavailable"
- invalid_pagesize:
invalid_pagesize = '9216'
pagesize_unit = 'b'
start_vm_error = "Unable to find any usable hugetlbfs mount for 9 KiB"
- invalid_addr_type:
addr_type = 'fakedimm'
define_error = "Invalid value for attribute 'type' in element 'address': '${addr_type}'"
define_error_8 = "unknown address type '${addr_type}'"
aarch64:
define_error = "unknown address type '${addr_type}'"
addr_dict = "'address':{'attrs': {'type': '${addr_type}', 'base': '${addr_base}', 'slot': '${slot}'}}"
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe move those 3 lines to just follow up line 19

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks chunfu, But the addr_dict has some variables in the lines after L19 , such as ${addr_type},So I add addr_dict here .

source_dict = "'source': {'nodemask': '${node_mask}','pagesize': %d, 'pagesize_unit':'${pagesize_unit}'}"
dimm_dict = {'mem_model':'dimm', ${source_dict}, ${addr_dict}, 'target': {'size':${target_size}, 'size_unit':'KiB','node':${guest_node}}}
variants basic_memory:
- with_numa:
no s390-virtio
numa_attrs = "'vcpu': 4,'cpu': {'numa_cell': [{'id': '0', 'cpus': '0-1', 'memory': '${numa_mem}', 'unit': 'KiB'},{'id':'1','cpus': '2-3','memory':'${numa_mem}','unit':'KiB'}]}"
vm_attrs = {${numa_attrs}, ${max_dict}, 'memory_unit':'KiB','memory':${mem_value},'current_mem':${current_mem},'current_mem_unit':"KiB"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright Redhat
#
# SPDX-License-Identifier: GPL-2.0

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

from avocado.utils import process

from virttest import libvirt_version
from virttest import virsh

from virttest.libvirt_xml import vm_xml
from virttest.libvirt_xml.devices import memory
from virttest.utils_test import libvirt

from provider.numa import numa_base


def get_pagesize_value(params):
"""
Get pagesize value

:param params: Dictionary with the test parameters
:return: page_size, The page size to set in original vmxml
"""
invalid_pagesize = params.get("invalid_pagesize")
pagesize_cmd = params.get("pagesize_cmd")

if invalid_pagesize:
page_size = invalid_pagesize
else:
page_size = process.run(pagesize_cmd, ignore_status=True,
shell=True).stdout_text.strip()
return int(page_size)
Copy link
Contributor

Choose a reason for hiding this comment

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

Need to add docstring for return value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks liping ,Updated



def get_mem_obj(mem_dict):
"""
Get mem object.

:param mem_dict: memory dict value.
:return mem_obj: object of memory devices.
"""
mem_obj = memory.Memory()
mem_obj.setup_attrs(**eval(mem_dict))
return mem_obj
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks liping ,Updated



def define_guest(test, params, page_size):
"""
Define guest with specific

:param test: test object.
:param params: dict, test parameters.
:param page_size: page size value in vm xml.
"""
Copy link
Contributor

Choose a reason for hiding this comment

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

Miss docstring.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks liping ,Updated

vm_name = params.get("main_vm")
vm_attrs = eval(params.get("vm_attrs"))
dimm_dict = params.get("dimm_dict")
invalid_setting = params.get("invalid_setting")

vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
vmxml.setup_attrs(**vm_attrs)

devices = vmxml.get_devices()
mem_obj = get_mem_obj(dimm_dict % page_size)
devices.append(mem_obj)
vmxml.set_devices(devices)
test.log.debug("Define vm with %s." % vmxml)

# Check libvirt version
if libvirt_version.version_compare(9, 0, 0) and \
invalid_setting == "unexisted_node":
define_error = params.get("start_vm_error")
elif not libvirt_version.version_compare(9, 0, 0) and \
invalid_setting == "invalid_addr_type":
define_error = params.get("define_error_8")
else:
define_error = params.get("define_error")
# Redefine define_error for checking start_vm_error
params.update({"define_error": define_error})

# Define guest
try:
vmxml.sync()
except Exception as e:
if define_error:
if define_error not in str(e):
test.fail("Expect to get '%s' error, but got '%s'" % (define_error, e))
else:
test.fail("Expect define successfully, but failed with '%s'" % e)


def run(test, params, env):
"""
Verify error messages prompt with invalid memory device configs

1.invalid value:
exceed slot number, max address base, nonexistent guest node
nonexistent node mask, invalid pagesize, invalid address type
2.memory setting: with numa
"""

def setup_test():
Copy link
Contributor

Choose a reason for hiding this comment

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

since previously most of method were moved out of scope of run(test, params, env).
Can setup_test(), run_test() and teardown_test() be moved out ? and just put above def run(test, params, env):

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi, chunfu , Thanks your advice. Have we confirmed we should do like that? I think both are OK.

"""
Check host has at least 2 numa nodes.
"""
test.log.info("TEST_SETUP: Check the numa nodes")
numa_obj = numa_base.NumaTest(vm, params, test)
numa_obj.check_numa_nodes_availability()

def run_test():
"""
Define vm with dimm.
Start vm.
Hotplug dimm.
"""
test.log.info("TEST_STEP1: Define vm and check result")
source_pagesize = get_pagesize_value(params)
define_guest(test, params, source_pagesize)

test.log.info("TEST_STEP2: Start guest ")
start_result = virsh.start(vm_name, ignore_status=True)
if start_vm_error:
# Start success for unexisted_node scenario and version>9.0
if libvirt_version.version_compare(9, 0, 0) and \
invalid_setting == "unexisted_node":
libvirt.check_exit_status(start_result)
else:
libvirt.check_result(start_result, start_vm_error)

test.log.info("TEST_STEP3: Start guest without dimm devices")
original_xml.setup_attrs(**vm_attrs)
test.log.debug("Define vm by '%s' \n", original_xml)
original_xml.sync()
virsh.start(vm_name, debug=True, ignore_status=False)

test.log.info("TEST_STEP4: Hotplug dimm memory device")
attach_error = params.get("start_vm_error", params.get("define_error"))

mem_obj = get_mem_obj(dimm_dict % source_pagesize)
result = virsh.attach_device(vm_name, mem_obj.xml, debug=True).stderr_text
if attach_error not in result:
test.fail("Expected get error '%s', but got '%s'" % (attach_error, result))

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)
original_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
bkxml = original_xml.copy()
dimm_dict = params.get("dimm_dict")
invalid_setting = params.get("invalid_setting")
vm_attrs = eval(params.get("vm_attrs"))
start_vm_error = params.get("start_vm_error")

try:
setup_test()
run_test()

finally:
teardown_test()
Loading