diff --git a/qemu/tests/balloon_check.py b/qemu/tests/balloon_check.py index 64458b4b10bb7edf34669d56f9e8e764d06b6b9e..5b8224d63fe79f204f147eda3f8680efa0248f25 100644 --- a/qemu/tests/balloon_check.py +++ b/qemu/tests/balloon_check.py @@ -91,6 +91,71 @@ class BallooningTest(MemoryBaseTest): raise exceptions.TestFail("Balloon test failed %s" % step) return (mmem, gmem) + def enable_polling(self, device_path): + """ + Enables polling in the specified interval + + :param device_path: QOM path for the balloon device. + """ + polling_interval = int(self.params.get("polling_interval", 2)) + sleep_time = int(self.params.get("polling_sleep_time", 20)) + error_context.context("Enable polling", logging.info) + self.vm.monitor.qom_set(device_path, "guest-stats-polling-interval", polling_interval) + time.sleep(sleep_time) + + def get_memory_stat(self, device_path): + """ + Get memory statistics from qmp. + + :param device_path: QOM path for the balloon device. + """ + return self.vm.monitor.qom_get(device_path, "guest-stats") + + def _memory_stats_compare(self, keyname, memory_stat_qmp): + """ + Check whether memory statistics from qmp is same with guest memory. + + :param keyname: key name of the output of the 'qom-get' property. + :param memory_stat_qmp: memory stat values from qmp. + """ + check_mem_ratio = float(self.params.get("check_mem_ratio", 0.1)) + error_context.context("Get memory from guest", logging.info) + if keyname == "stat-free-memory": + guest_mem = self.get_guest_free_mem(self.vm) + elif keyname == "stat-total-memory": + guest_mem = self.get_vm_mem(self.vm) + memory_stat_qmp = "%sB" % memory_stat_qmp + memory_stat_qmp = int(float(utils_misc.normalize_data_size( + memory_stat_qmp, order_magnitude="M"))) + if (float(abs(guest_mem - memory_stat_qmp)) / guest_mem) > check_mem_ratio: + self.test.fail("%s of guest %s is not equal to %s in qmp,the" + "acceptable ratio is %s" % (keyname, guest_mem, + memory_stat_qmp, + check_mem_ratio)) + + def memory_stats_check(self, keyname, enabled): + """ + Check whether memory statistics reporting works as expected. + + :param keyname: key name of the output of the 'qom-get' property. + :param enabled: expected memory stat working status: True means + memory stat should work, False means not work. + """ + base_path = self.params.get("base_path", "/machine/peripheral/") + device = self.params["balloon"] + device_path = base_path + device + mem_stat_disabled = 0xffffffffffffffff + + self.enable_polling(device_path) + memory_stat_qmp = self.get_memory_stat(device_path)['stats'][keyname] + + stat_enabled = (memory_stat_qmp != mem_stat_disabled) + if stat_enabled != enabled: + self.test.fail("Memory statistics reporting is not working as" + " expected") + elif enabled: + self._memory_stats_compare(keyname, memory_stat_qmp) + @error_context.context_aware def balloon_memory(self, new_mem): """ diff --git a/qemu/tests/balloon_service.py b/qemu/tests/balloon_service.py index 1dd57cc56ed2826ce68ecf60eaec2b0ee1b3638d..11c87d503b2c305278ee109a919ec93a4a2f0f54 100644 --- a/qemu/tests/balloon_service.py +++ b/qemu/tests/balloon_service.py @@ -1,15 +1,9 @@ -import os -import re import time import random import logging from virttest import utils_test -from virttest import utils_misc from virttest import error_context -from avocado.core import exceptions -from aexpect import ShellCmdError -from virttest.utils_test.qemu import MemoryBaseTest from qemu.tests.balloon_check import BallooningTestWin from qemu.tests.balloon_check import BallooningTestLinux @@ -21,109 +15,36 @@ def run(test, params, env): 1) boot a guest with balloon device. 2) enable and check driver verifier in guest(only for windows guest). 3) install balloon service in guest(only for windows guest). - 4) enable polling in qmp. - 5) evict / enlarge balloon. - 6) get polling value in qmp, then do memory check if necessary. - 7) repeat steps 5) and 6) for multi times - 8) uninstall balloon service and clear driver verifier(only for + 4) evict / enlarge balloon. + 5) get polling value in qmp, then do memory check if necessary. + 6) uninstall or stop balloon service(optional) + 7) check memory status(optional) + 8) install or run balloon service(optional) + 9) check memory status(optional) + 10) uninstall balloon service and clear driver verifier(only for windows guest). """ - def get_disk_vol(session): + def balloon_memory(vm, mem_check, min_sz, max_sz): """ - Get virtio-win disk volume letter for windows guest. - - :param session: VM session. - """ - key = "VolumeName like 'virtio-win%'" - try: - return utils_misc.get_win_disk_vol(session, - condition=key) - except Exception: - raise exceptions.TestFail("Could not get virtio-win disk vol!") - - def config_balloon_service(session, drive_letter): - """ - Check / Install balloon service for windows guest. - - :param session: VM session. - :param drive_letter: virtio-win disk volume letter. - """ - status_cmd = params["status_balloon_service"] % drive_letter - logging.debug("Check balloon service status.") - output = session.cmd_output(status_cmd) - if re.search(r"running", output.lower(), re.M): - logging.debug("Balloon service is already running !") - elif re.search(r"stop", output.lower(), re.M): - logging.debug("Run Balloon Service in guest.") - try: - start_cmd = params["run_balloon_service"] % drive_letter - session.cmd(start_cmd) - except ShellCmdError: - raise exceptions.TestError("Start balloon service failed!") - else: - logging.debug("Install Balloon Service in guest.") - try: - install_cmd = params["install_balloon_service"] % drive_letter - session.cmd(install_cmd) - except ShellCmdError: - raise exceptions.TestError("Install balloon service failed !") - - def memory_check(vm, get_polling_output, keyname): - """ - Check memory status. - - :param vm: VM object. - :param get_polling_output: output of get polling in qmp. - :param keyname: key name of the output of the 'qom-get' property. - """ - check_mem_ratio = float(params.get("check_mem_ratio", 0.1)) - - error_context.context("Get memory from guest", logging.info) - mem_base = MemoryBaseTest(test, params, env) - if keyname == "stat-free-memory": - guest_mem = mem_base.get_guest_free_mem(vm) - elif keyname == "stat-total-memory": - guest_mem = mem_base.get_vm_mem(vm) - - error_context.context("Get memory from qmp", logging.info) - stat_memory_qmp = get_polling_output['stats'][keyname] - stat_memory_qmp = "%sB" % stat_memory_qmp - stat_memory_qmp = int(float(utils_misc.normalize_data_size( - (stat_memory_qmp), order_magnitude="M"))) - - error_context.context("Compare memory from guest with qmp", - logging.info) - if (abs(guest_mem - stat_memory_qmp) / guest_mem) > check_mem_ratio: - raise exceptions.TestFail("%s of guest %s is not equal to %s in" - " qmp, the acceptable ratio is %s" % - (keyname, guest_mem, stat_memory_qmp, - check_mem_ratio)) - - def balloon_memory(vm, device_path, mem_check): - """ - Doing memory balloon in a loop and check memory status during balloon. + Doing memory balloon in a loop and check memory statistics during balloon. :param vm: VM object. - :param device_path: balloon polling path. :param mem_check: need to do memory check if param mem_check is 'yes' + :param min_sz: guest minimal memory size + :param max_sz: guest maximal memory size """ repeat_times = int(params.get("repeat_times", 5)) logging.info("repeat times: %d" % repeat_times) - if params['os_type'] == 'windows': - balloon_test = BallooningTestWin(test, params, env) - else: - balloon_test = BallooningTestLinux(test, params, env) - min_sz, max_sz = balloon_test.get_memory_boundary() while repeat_times: for tag in params.objects('test_tags'): error_context.context("Running %s test" % tag, logging.info) params_tag = params.object_params(tag) balloon_type = params_tag['balloon_type'] if balloon_type == 'evict': - expect_mem = int(random.uniform(min_sz, - balloon_test.get_ballooned_memory())) + expect_mem = int(random.uniform( + min_sz, balloon_test.get_ballooned_memory())) else: expect_mem = int(random.uniform( balloon_test.get_ballooned_memory(), max_sz)) @@ -131,72 +52,49 @@ def run(test, params, env): quit_after_test = balloon_test.run_ballooning_test(expect_mem, tag) time.sleep(20) - get_polling_output = vm.monitor.qom_get(device_path, - stats_property) - time.sleep(20) if mem_check == "yes": - memory_check(vm, get_polling_output, 'stat-free-memory') + balloon_test.memory_stats_check('stat-free-memory', mem_stat_working) if quit_after_test: return repeat_times -= 1 - timeout = int(params.get("login_timeout", 360)) mem_check = params.get("mem_check", "yes") + mem_stat_working = True error_context.context("Boot guest with balloon device", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() - sleep_time = int(params.get("polling_sleep_time", 20)) - base_path = params.get("base_path", "/machine/peripheral/") - device = params.get("balloon", "balloon0") - device_path = os.path.join(base_path, device) - polling_property = params.get("polling_property", - "guest-stats-polling-interval") - stats_property = params.get("stats_property", "guest-stats") - polling_interval = int(params.get("polling_interval", 2)) - - session = vm.wait_for_login(timeout=timeout) + session = vm.wait_for_login() if params['os_type'] == 'windows': driver_name = params.get("driver_name", "balloon") session = utils_test.qemu.windrv_check_running_verifier(session, vm, - test, driver_name, - timeout) - + test, driver_name) + balloon_test = BallooningTestWin(test, params, env) error_context.context("Config balloon service in guest", logging.info) - drive_letter = get_disk_vol(session) - config_balloon_service(session, drive_letter) + balloon_test.configure_balloon_service(session) + else: + balloon_test = BallooningTestLinux(test, params, env) try: - error_context.context("Enable polling in qemu", logging.info) - try: - vm.monitor.qom_set(device_path, polling_property, - polling_interval) - except Exception as e: - match_str = params.get("match_str") - if match_str: - if match_str not in str(e): - test.fail("Fail to get expected result. Expect" - "'%s' when set polling-interval to %s" % - (match_str, polling_interval)) - return - time.sleep(sleep_time) - get_polling_interval = vm.monitor.qom_get(device_path, polling_property) - if get_polling_interval != polling_interval: - test.fail("polling interval is not expected, expected " - "%s, but it is %s actually." % - (polling_interval, get_polling_interval)) - get_polling_output = vm.monitor.qom_get(device_path, stats_property) - memory_check(vm, get_polling_output, 'stat-total-memory') - error_context.context("Balloon vm memory in loop", logging.info) - balloon_memory(vm, device_path, mem_check) + min_sz, max_sz = balloon_test.get_memory_boundary() + balloon_memory(vm, mem_check, min_sz, max_sz) + blnsrv_operation = params.objects("blnsrv_operation") + mem_stat_working = False + for bln_oper in blnsrv_operation: + error_context.context("%s balloon service" % bln_oper, logging.info) + balloon_test.operate_balloon_service(session, bln_oper) + + error_context.context("Balloon vm memory after %s balloon service" + % bln_oper, logging.info) + balloon_memory(vm, mem_check, min_sz, max_sz) + mem_stat_working = True finally: if params['os_type'] == 'windows': error_context.context("Clear balloon service in guest", logging.info) - uninstall_cmd = params["uninstall_balloon_service"] % drive_letter - session.cmd(uninstall_cmd, ignore_all_errors=True) + balloon_test.operate_balloon_service(session, "uninstall") session.close() diff --git a/qemu/tests/cfg/balloon_service.cfg b/qemu/tests/cfg/balloon_service.cfg index d4f91bff6f75fcb43276bd33cfc4d07018401a92..a398af316f9bf601ee4571a85b08793c9f716cde 100644 --- a/qemu/tests/cfg/balloon_service.cfg +++ b/qemu/tests/cfg/balloon_service.cfg @@ -21,6 +21,7 @@ uninstall_balloon_service = "%s:\Balloon\GUEST_OS\amd64\blnsvr.exe -u" status_balloon_service = "%s:\Balloon\GUEST_OS\amd64\blnsvr.exe status" run_balloon_service = "%s:\Balloon\GUEST_OS\amd64\blnsvr.exe -r" + stop_balloon_service = "%s:\Balloon\GUEST_OS\amd64\blnsvr.exe -s" repeat_times = 5 base_path = "/machine/peripheral/" polling_property = "guest-stats-polling-interval" @@ -49,6 +50,14 @@ polling_interval = 4294967296 match_str = "timer value is too big" mem_check = no + - install_uninstall: + only Windows + repeat_times = 1 + blnsrv_operation = "uninstall install" + - disable_enable: + only Windows + repeat_times = 1 + blnsrv_operation = "stop run" - sc_interrogate: type = balloon_sc_interrogate only Windows