Skip to content

Commit

Permalink
add case for invalid nvdimm config
Browse files Browse the repository at this point in the history
    xxxx-299194: Invalid nvdimm memory device config values
Signed-off-by: nanli <[email protected]>
  • Loading branch information
nanli1 committed Jan 9, 2024
1 parent e302976 commit 4bc17fb
Show file tree
Hide file tree
Showing 3 changed files with 233 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
- memory.devices.invalid_nvdimm:
type = invalid_nvdimm_memory_device_config
nvdimm_file_size = "512M"
target_size = 524288
guest_node = 0
slot = 0
addr_type = 'dimm'
addr_base = '0x100000000'
nvdimm_path = "/tmp/nvdimm"
alignsize = 2048
label_size = 128
discard_attr = ""
label_attrs = ""
align_attrs = "'alignsize':${alignsize},'alignsize_unit': 'KiB'"
label_attrs = "'label':{'size_unit':'KiB','size':${label_size}}"
addr_attrs = "'address':{'attrs': {'type': '${addr_type}', 'base': '${addr_base}', 'slot': '${slot}'}}"
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"
attach_error = "nvdimm is not enabled: missing 'nvdimm' in '-M'"
aarch64:
attach_error = "nvdimm is not enabled: add 'nvdimm=on' to '-M'"
- 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_path:
nvdimm_path = "/tmp/nonexist.file"
start_vm_error = "No such file or directory"
- invalid_alignsize:
alignsize = '2'
align_attrs = "'alignsize':${alignsize},'alignsize_unit': 'KiB'"
start_vm_error = "must be multiples of page size 0x1000"
- 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}'"
attach_error_8 = "unknown address type '${addr_type}'"
- small_label:
label_size = 100
label_attrs = "'label':{'size_unit':'KiB','size':${label_size}}"
define_error ="nvdimm label must be at least 128KiB"
- bigger_label:
label_size = 524289
label_attrs = "'label':{'size_unit':'KiB','size':${label_size}}"
define_error ="label size must be smaller than NVDIMM size"
- bigger_target_memory:
target_size = 1048576
start_vm_error = "backing store size 0x20000000 does not match 'size' option 0x40000000"
- with_discard:
mem_discard = "yes"
discard_attr = " 'mem_discard':'${mem_discard}',"
define_error = "discard is not supported for nvdimms"
addr_attrs = "'address':{'attrs': {'type': '${addr_type}', 'base': '${addr_base}', 'slot': '${slot}'}}"
source_attrs = "'source': {${align_attrs},'path': '${nvdimm_path}'}"
target_attrs = "'target': {'size': ${target_size},'size_unit': 'KiB','node':${guest_node}, ${label_attrs}}"
nvdimm_dict = {'mem_model':'nvdimm', ${source_attrs}, ${target_attrs},${addr_attrs},${discard_attr}}
variants:
- with_numa:
no s390-virtio
mem_value = 2097152
current_mem = 2097152
numa_mem = 1048576
max_dict = '"max_mem_rt": 10485760, "max_mem_rt_slots":16, "max_mem_rt_unit": "KiB"'
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,151 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright Redhat
#
# SPDX-License-Identifier: GPL-2.0

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

from avocado.utils import process

from virttest import libvirt_version
from virttest import virsh
from virttest.libvirt_xml import vm_xml
from virttest.utils_test import libvirt

from provider.memory import memory_base


def define_guest(test, params):
"""
Define guest.
:param test: test object.
:param params: dict, test parameters.
"""
vm_name = params.get("main_vm")
vm_attrs = eval(params.get("vm_attrs"))
nvdimm_dict = eval(params.get("nvdimm_dict"))
invalid_setting = params.get("invalid_setting")

vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
vmxml.setup_attrs(**vm_attrs)
mem_obj = memory_base.prepare_mem_obj(nvdimm_dict)
vmxml.devices = vmxml.devices.append(mem_obj)
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, 9, 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})

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 nvdimm memory device configs
1.invalid value:
exceed slot number, max address base, nonexistent guest node
nonexistent path, invalid pagesize, invalid address type, small label size
label size bigger than memory size, :memory size bigger than backing file size
discard.
2.memory setting: with numa
"""

def setup_test():
"""
Create file backend for nvdimm device.
"""
test.log.info("Setup env.")
if invalid_setting != "unexisted_path":
process.run('truncate -s %s %s' % (nvdimm_file_size, nvdimm_path),
verbose=True, shell=True)

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

test.log.info("TEST_STEP2: Start guest ")
start_result = virsh.start(vm_name, debug=True, ignore_status=True)
if start_vm_error:
libvirt.check_result(start_result, start_vm_error)
else:
libvirt.check_exit_status(start_result)

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

test.log.info("TEST_STEP4: Hotplug nvdimm memory device")
mem_obj = memory_base.prepare_mem_obj(nvdimm_dict)
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()
if os.path.exists(nvdimm_path):
os.remove(nvdimm_path)

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()
invalid_setting = params.get("invalid_setting")
nvdimm_file_size = params.get("nvdimm_file_size")
nvdimm_path = params.get("nvdimm_path")
nvdimm_dict = eval(params.get("nvdimm_dict"))
vm_attrs = eval(params.get("vm_attrs"))
# Get start vm error
if libvirt_version.version_compare(9, 0, 0) and \
invalid_setting == "unexisted_node":
start_vm_error = ""
else:
start_vm_error = params.get("start_vm_error")

# Get attach error
if invalid_setting == "max_addr":
attach_error = params.get('attach_error')
elif not libvirt_version.version_compare(9, 9, 0) and \
invalid_setting == "invalid_addr_type":
attach_error = params.get('attach_error_8')
else:
attach_error = params.get("start_vm_error", params.get("define_error"))

try:
setup_test()
run_test()

finally:
teardown_test()
13 changes: 13 additions & 0 deletions provider/memory/memory_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from virttest import libvirt_version
from virttest import utils_misc

from virttest.libvirt_xml.devices import memory
from virttest.utils_version import VersionInterval

from avocado.core import exceptions
Expand Down Expand Up @@ -76,3 +77,15 @@ def check_supported_version(params, test, vm):
if vm_kerv not in VersionInterval(guest_required_kernel):
test.cancel("Got guest kernel version:%s, which is not in %s" %
(vm_kerv, guest_required_kernel))


def prepare_mem_obj(dest_dict):
"""
Prepare memory object
:param dest_dict: dimm memory dict.
:return mem_obj, memory object.
"""
mem_obj = memory.Memory()
mem_obj.setup_attrs(**dest_dict)

return mem_obj

0 comments on commit 4bc17fb

Please sign in to comment.