From 11231e65fc2bb2aa086a3512e41399d82fedc9ad Mon Sep 17 00:00:00 2001 From: nanli Date: Tue, 26 Sep 2023 21:07:05 +0800 Subject: [PATCH] add case for period config of memballoon VIRT-299028: Period config of memory balloon Signed-off-by: nanli --- .../period_config_of_memory_balloon.cfg | 33 ++++ .../period_config_of_memory_balloon.py | 163 ++++++++++++++++++ 2 files changed, 196 insertions(+) create mode 100644 libvirt/tests/cfg/memory/memory_balloon/period_config_of_memory_balloon.cfg create mode 100644 libvirt/tests/src/memory/memory_balloon/period_config_of_memory_balloon.py diff --git a/libvirt/tests/cfg/memory/memory_balloon/period_config_of_memory_balloon.cfg b/libvirt/tests/cfg/memory/memory_balloon/period_config_of_memory_balloon.cfg new file mode 100644 index 00000000000..a656cb52c45 --- /dev/null +++ b/libvirt/tests/cfg/memory/memory_balloon/period_config_of_memory_balloon.cfg @@ -0,0 +1,33 @@ +- memory.balloon.period: + type = period_config_of_memory_balloon + start_vm = no + mem_unit = "KiB" + current_mem_unit = "KiB" + current_mem = "2097152" + mem_value = "2097152" + mem_operation = "swapoff -a; dd if=/dev/zero of=/tmp/temp bs=1024K count=10; memhog -r5 500M" + variants: + - virtio_model: + memballoon_model = "virtio" + - virtio_trans_model: + memballoon_model = "virtio-transitional" + - virtio_non_trans_model: + memballoon_model = "virtio-non-transitional" + variants: + - undefined_period: + period_value_1 = "undefined" + period_attr = "" + xpath = [{'element_attrs': [".//memballoon/stats"]}] + xpath_ignore = True + period_value_2 = "0" + period_cmd = "--period ${period_value_2}" + - int_period: + period_value_1 = "2" + period_attr = ",'stats_period':'${period_value_1}'" + xpath = [{'element_attrs': [".//stats[@period='${period_value_1}']"]}] + period_value_2 = "0" + period_cmd = "--period ${period_value_2}" + device_dict = "{'model':'${memballoon_model}' ${period_attr}}" + variants: + - memory_allocation: + mem_attrs = {'memory_unit':'${mem_unit}','memory':${mem_value},'current_mem':${current_mem},'current_mem_unit':'${current_mem_unit}'} diff --git a/libvirt/tests/src/memory/memory_balloon/period_config_of_memory_balloon.py b/libvirt/tests/src/memory/memory_balloon/period_config_of_memory_balloon.py new file mode 100644 index 00000000000..adf1d145899 --- /dev/null +++ b/libvirt/tests/src/memory/memory_balloon/period_config_of_memory_balloon.py @@ -0,0 +1,163 @@ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright Redhat +# +# SPDX-License-Identifier: GPL-2.0 + +# Author: Nannan Li +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +import re + +from virttest import utils_misc +from virttest import virsh + +from virttest.libvirt_xml import vm_xml +from virttest.utils_libvirt import libvirt_vmxml + + +def run(test, params, env): + """ + Verify memory statistics config "period" takes effect with various memory balloon models + + Scenario: + 1.memory balloon models: virtio, virtio-transitional, virtio-non-transitional. + 2.period: int period, undefined. + 3.mem config: mem, current mem. + """ + + def check_same_value(value1, value2, log_msg): + """ + This function checks whether two values are same or not. + + :param value1: First value to be checked. + :param value2: Second value to be checked. + :param log_msg: Log message to display in case of failure. + :raises: Test.Fail if values are not same. + """ + if value1 != value2: + test.fail("The %s should not change from '%s' to '%s'" + % (log_msg, value1, value2)) + + def get_memory_statistics(): + """ + Get memory statistics by virsh dommemstat + + :return: usable mem, last_update, disk_caches value in result. + """ + def _get_response(): + res = virsh.dommemstat(vm_name, ignore_status=False, + debug=True).stdout_text + return re.findall(r'usable (\d+)', res) + + if utils_misc.wait_for(_get_response, 30, 5): + res = virsh.dommemstat(vm_name, ignore_status=False, + debug=True).stdout_text + usable_mem = re.findall(r'usable (\d+)', res)[0] + last_update = re.findall(r'last_update (\d+)', res)[0] + disk_caches = re.findall(r'disk_caches (\d+)', res)[0] + return usable_mem, last_update, disk_caches + else: + test.fail("Not get virsh dommemstat result in 25s") + + def check_vm_dommemstat(period_config, usable_mem, last_update, + disk_caches): + """ + Check correct vm dommemstat result. + + :params: period_config: period config, undefined , 0 or number + :params: usable_mem, the usable mem value before consume mem + :params: last_update, the last update value before consume mem + :params: disk_caches, the disk caches value before consume mem + """ + usable_mem_new, last_update_new, disk_caches_new = get_memory_statistics() + + if period_config in ["undefined", "0"]: + check_same_value(usable_mem_new, usable_mem, "usable value") + check_same_value(last_update_new, last_update, "last update") + check_same_value(disk_caches_new, disk_caches, "disk caches") + + elif period_config.isdigit() and period_config != "0": + if usable_mem_new == usable_mem: + test.fail("The usable mem should be as '%s' instead of '%s'" + % (usable_mem_new, usable_mem)) + if last_update_new <= last_update: + test.fail("The last update '%s' should bigger than to '%s'" + % (last_update_new, last_update)) + if disk_caches_new == disk_caches: + test.fail("The disk caches mem '%s' should not same as '%s' " % + (disk_caches_new, disk_caches)) + + def run_test(): + """ + Define and start guest + Check memTotal and memory allocation + """ + test.log.info("TEST_STEP1: Define guest with memballon") + vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) + vmxml.setup_attrs(**mem_attrs) + vmxml.del_device('memballoon', by_tag=True) + libvirt_vmxml.modify_vm_device(vmxml, 'memballoon', device_dict) + + test.log.info("TEST_STEP2: Start guest ") + vm.start() + vm.wait_for_login().close() + vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) + test.log.debug("After start vm, get xml is:\n%s", vmxml) + + test.log.info("TEST_STEP3: Check memory balloon config by virsh dumpxml") + if libvirt_vmxml.check_guest_xml_by_xpaths( + vmxml, expect_xpath, xpath_ignore) == xpath_ignore: + test.fail("Expect to get '%s' in xml result is '%s'" % (expect_xpath, xpath_ignore)) + + test.log.info("TEST_STEP4: Get vm memory statistics by virsh dommemstat") + usable_mem_1, last_update_1, disk_caches_1 = get_memory_statistics() + + test.log.info("TEST_STEP5: Do memory operation and check dommemstat") + session = vm.wait_for_login() + status, stdout = session.cmd_status_output(mem_operation) + if status: + test.fail("Failed to consume memory:%s" % stdout) + check_vm_dommemstat(period_value_1, usable_mem_1, last_update_1, disk_caches_1) + + test.log.info("TEST_STEP6: Change the period setting") + virsh.dommemstat(vm_name, period_cmd, ignore_status=False, debug=True) + + test.log.info("TEST_STEP7: Repeat TEST_STEP3-5") + if libvirt_vmxml.check_guest_xml_by_xpaths( + vmxml, expect_xpath, xpath_ignore) == xpath_ignore: + test.fail("Expect to get '%s' in xml is '%s'" % (expect_xpath, xpath_ignore)) + + usable_mem_3, last_update_3, disk_caches_3 = get_memory_statistics() + status, stdout = session.cmd_status_output(mem_operation) + session.close() + if status: + test.fail("Failed to consume memory:%s" % stdout) + check_vm_dommemstat(period_value_2, usable_mem_3, last_update_3, disk_caches_3) + + 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() + + mem_attrs = eval(params.get("mem_attrs", "{}")) + device_dict = eval(params.get("device_dict", "{}")) + mem_operation = params.get("mem_operation") + period_value_1 = params.get("period_value_1") + period_value_2 = params.get("period_value_2") + period_cmd = params.get("period_cmd") + expect_xpath = eval(params.get("xpath")) + xpath_ignore = bool(params.get("xpath_ignore", False)) + + try: + run_test() + + finally: + teardown_test()