v1: add 7 new cases using domain memory related API add 1 conf for domain memory testing v2: fix the file not close problem and a typo 7 new cases are: memory_params_config: test set memory params with config flag memory_params_live: test set memory params with live flag memory_peek: test memory peek memory_stats: test get memory stats set_maxmem_config: test set maximum memory with config flag set_memory_config: test set current memory with config flag set_memory_live: test set current memory with live flag memory hotplug is not supported yet, so live set max memory case is not added. Signed-off-by: Wayne Sun <gsun@xxxxxxxxxx> --- cases/domain_memory_test.conf | 99 +++++++++++++++++++++++++++++++ repos/domain/memory_params_config.py | 96 ++++++++++++++++++++++++++++++ repos/domain/memory_params_live.py | 112 +++++++++++++++++++++++++++++++++++ repos/domain/memory_peek.py | 48 +++++++++++++++ repos/domain/memory_stats.py | 65 ++++++++++++++++++++ repos/domain/set_maxmem_config.py | 59 ++++++++++++++++++ repos/domain/set_memory_config.py | 94 +++++++++++++++++++++++++++++ repos/domain/set_memory_live.py | 86 +++++++++++++++++++++++++++ 8 files changed, 659 insertions(+) create mode 100644 cases/domain_memory_test.conf create mode 100644 repos/domain/memory_params_config.py create mode 100644 repos/domain/memory_params_live.py create mode 100644 repos/domain/memory_peek.py create mode 100644 repos/domain/memory_stats.py create mode 100644 repos/domain/set_maxmem_config.py create mode 100644 repos/domain/set_memory_config.py create mode 100644 repos/domain/set_memory_live.py diff --git a/cases/domain_memory_test.conf b/cases/domain_memory_test.conf new file mode 100644 index 0000000..90879ab --- /dev/null +++ b/cases/domain_memory_test.conf @@ -0,0 +1,99 @@ +domain:install_linux_cdrom + guestname + $defaultname + guestos + $defaultos + guestarch + $defaultarch + vcpu + $defaultvcpu + memory + $defaultmem + hddriver + $defaulthd + nicdriver + $defaultnic + macaddr + 54:52:00:4a:c1:22 + +domain:balloon_memory + guestname + $defaultname + memorypair + 1024,2048 + +domain:destroy + guestname + $defaultname + +domain:memory_params_config + guestname + $defaultname + hard_limit + 0 + soft_limit + 9007199254740991 + swap_hard_limit + -1 + +domain:set_maxmem_config + guestname + $defaultname + memory + 16777216 + +domain:set_memory_config + guestname + $defaultname + memory + 1048576 + maxmem + 4194304 + +domain:start + guestname + $defaultname + +domain:memory_stats + guestname + $defaultname + +domain:memory_peek + guestname + $defaultname + +domain:memory_params_live + guestname + $defaultname + hard_limit + 25417224 + soft_limit + 9007199254740900 + swap_hard_limit + -1 + +domain:set_memory_live + guestname + $defaultname + memory + 2097152 + username + $username + password + $password + +domain:set_memory_config + guestname + $defaultname + memory + 4194304 + +domain:destroy + guestname + $defaultname + +domain:undefine + guestname + $defaultname + +options cleanup=enable diff --git a/repos/domain/memory_params_config.py b/repos/domain/memory_params_config.py new file mode 100644 index 0000000..af9781b --- /dev/null +++ b/repos/domain/memory_params_config.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python +# Test set domain memory parameters with flag +# VIR_DOMAIN_AFFECT_CONFIG + +from xml.dom import minidom + +import libvirt +from libvirt import libvirtError + +from src import sharedmod + +required_params = ('guestname', 'hard_limit', 'soft_limit', 'swap_hard_limit', ) +optional_params = {} + +UNLIMITED = 9007199254740991 + +def get_memory_config(domobj, param_dict): + """get domain config memory parameters + """ + new_dict = {} + try: + guestxml = domobj.XMLDesc(2) + logger.debug("domain %s xml is :\n%s" %(domobj.name(), guestxml)) + xml = minidom.parseString(guestxml) + logger.info("get domain memory parameters in config xml") + for i in param_dict.keys(): + if xml.getElementsByTagName(i): + limit_element = xml.getElementsByTagName(i)[0] + limit = int(limit_element.childNodes[0].data) + logger.info("%s in config xml is: %s" % (i, limit)) + new_dict[i] = limit + else: + logger.info("%s is not in config xml" % i) + new_dict[i] = 0 + + except libvirtError, e: + logger.error("libvirt call failed: " + str(e)) + return False + + return new_dict + +def memory_params_config(params): + """set domain memory parameters with config flag and check + """ + global logger + logger = params['logger'] + guestname = params['guestname'] + hard_limit = int(params['hard_limit']) + soft_limit = int(params['soft_limit']) + swap_hard_limit = int(params['swap_hard_limit']) + + logger.info("the name of virtual machine is %s" % guestname) + param_dict = {'hard_limit': hard_limit, + 'soft_limit': soft_limit, + 'swap_hard_limit': swap_hard_limit + } + + for i in param_dict.keys(): + if param_dict[i] == -1: + param_dict[i] = UNLIMITED + + logger.info("the param dict for setting is %s" % param_dict) + + conn = sharedmod.libvirtobj['conn'] + + try: + domobj = conn.lookupByName(guestname) + flags = libvirt.VIR_DOMAIN_AFFECT_CONFIG + logger.info("set %s memory parameters with flag: %s" % + (guestname, flags)) + domobj.setMemoryParameters(param_dict, flags) + logger.info("set memory parameters done") + + logger.info("get %s memory parameters with flag: %s" % + (guestname, flags)) + ret = domobj.memoryParameters(flags) + logger.info("%s memory parameters is %s" % (guestname, ret)) + + if ret == param_dict: + logger.info("memory parameters is as expected") + else: + logger.error("memory parameters is not as expected") + return 1 + + ret = get_memory_config(domobj, param_dict) + if ret == param_dict: + logger.info("memory parameters is as expected in config xml") + else: + logger.error("memory parameters is not as expected in config xml") + return 1 + + except libvirtError, e: + logger.error("libvirt call failed: " + str(e)) + return 1 + + return 0 diff --git a/repos/domain/memory_params_live.py b/repos/domain/memory_params_live.py new file mode 100644 index 0000000..44fb8b4 --- /dev/null +++ b/repos/domain/memory_params_live.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# Test set domain memory parameters with flag +# VIR_DOMAIN_AFFECT_LIVE + +import os +import math +from xml.dom import minidom + +import libvirt +from libvirt import libvirtError + +from src import sharedmod + +required_params = ('guestname', 'hard_limit', 'soft_limit', 'swap_hard_limit', ) +optional_params = {} + +UNLIMITED = 9007199254740991 +CGROUP_PATH = "/cgroup/memory/libvirt/qemu" + +def get_cgroup_setting(guestname): + """get domain memory parameters in cgroup + """ + if os.path.exists(CGROUP_PATH): + cgroup_path = "%s/%s" % (CGROUP_PATH, guestname) + else: + cgroup_path = "/sys/fs%s/%s" % (CGROUP_PATH, guestname) + + f = open("%s/memory.limit_in_bytes" % cgroup_path) + hard = int(f.read()) + logger.info("memory.limit_in_bytes value is %s" % hard) + f.close() + + f = open("%s/memory.soft_limit_in_bytes" % cgroup_path) + soft = int(f.read()) + logger.info("memory.soft_limit_in_bytes value is %s" % soft) + f.close() + + f = open("%s/memory.memsw.limit_in_bytes" % cgroup_path) + swap = int(f.read()) + logger.info("memory.memsw.limit_in_bytes value is %s" % swap) + f.close() + + new_dict = {'hard_limit': hard/1024, + 'soft_limit': soft/1024, + 'swap_hard_limit': swap/1024 + } + logger.debug("memory parameters dict get from cgroup is %s" % new_dict) + + return new_dict + +def memory_params_live(params): + """set domain memory parameters with live flag and check + """ + global logger + logger = params['logger'] + guestname = params['guestname'] + hard_limit = int(params['hard_limit']) + soft_limit = int(params['soft_limit']) + swap_hard_limit = int(params['swap_hard_limit']) + + logger.info("the name of virtual machine is %s" % guestname) + param_dict = {'hard_limit': hard_limit, + 'soft_limit': soft_limit, + 'swap_hard_limit': swap_hard_limit + } + + for i in param_dict.keys(): + if param_dict[i] == -1: + param_dict[i] = UNLIMITED + + logger.info("the param dict for setting is %s" % param_dict) + + conn = sharedmod.libvirtobj['conn'] + + try: + domobj = conn.lookupByName(guestname) + flags = libvirt.VIR_DOMAIN_AFFECT_LIVE + logger.info("get %s memory parameters with flag: %s" % + (guestname, flags)) + ret_pre = domobj.memoryParameters(flags) + logger.info("%s memory parameters is %s" % (guestname, ret_pre)) + + logger.info("set %s memory parameters with flag: %s" % + (guestname, flags)) + domobj.setMemoryParameters(param_dict, flags) + logger.info("set memory parameters done") + + logger.info("get %s memory parameters with flag: %s" % + (guestname, flags)) + ret_pos = domobj.memoryParameters(flags) + logger.info("%s memory parameters is %s" % (guestname, ret_pos)) + + if ret_pos == param_dict: + logger.info("memory parameters is as expected") + else: + logger.error("memory parameters is not as expected") + return 1 + + logger.info("check memory parameters in cgroup") + ret = get_cgroup_setting(guestname) + for i in param_dict.keys(): + if math.fabs(param_dict[i] - ret[i]) > 1: + logger.error("%s value not match with cgroup setting" % i) + return 1 + + logger.info("memory parameters is as expected in cgroup setting") + + except libvirtError, e: + logger.error("libvirt call failed: " + str(e)) + return 1 + + return 0 diff --git a/repos/domain/memory_peek.py b/repos/domain/memory_peek.py new file mode 100644 index 0000000..de1ff87 --- /dev/null +++ b/repos/domain/memory_peek.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# Test domain memory peek + +import libvirt +from libvirt import libvirtError + +from src import sharedmod + +required_params = ('guestname', ) +optional_params = {} + +def memory_peek(params): + """domain memory peek + """ + logger = params['logger'] + guestname = params['guestname'] + + flag_dict = {'1':"VIR_MEMORY_VIRTUAL", '2':"VIR_MEMORY_PHYSICAL"} + + logger.info("the name of virtual machine is %s" % guestname) + + conn = sharedmod.libvirtobj['conn'] + + try: + domobj = conn.lookupByName(guestname) + logger.info("test memory peek API") + for flag in flag_dict.keys(): + logger.info("using flag: %s" % flag_dict[flag]) + mem = domobj.memoryPeek(0, 0, int(flag)) + if mem: + return 1 + logger.info("memory peek API works fine with flag: %s" % + flag_dict[flag]) + + logger.info("peek 8 bytes from domain memory") + for flag in flag_dict.keys(): + logger.info("using flag: %s" % flag_dict[flag]) + mem = domobj.memoryPeek(0, 8, int(flag)) + if not mem: + return 1 + logger.info("8 bytes start with 0 with flag %s is: %s" % + (flag_dict[flag], mem)) + + except libvirtError, e: + logger.error("libvirt call failed: " + str(e)) + return 1 + + return 0 diff --git a/repos/domain/memory_stats.py b/repos/domain/memory_stats.py new file mode 100644 index 0000000..a82adad --- /dev/null +++ b/repos/domain/memory_stats.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# Test get domain memory stats + +import libvirt +from libvirt import libvirtError + +from src import sharedmod +from utils import utils + +required_params = ('guestname', ) +optional_params = {} + +VIRSH = "virsh qemu-monitor-command" + +def get_memory_actual(guestname): + """get memory stats with virsh commands + """ + qmp_actual = -1 + cmd ="%s %s '{ \"execute\": \"query-balloon\" }'" % (VIRSH, guestname) + logger.info("check memory stats with virsh command: %s" % cmd) + ret, out = utils.exec_cmd(cmd, shell=True) + out_dict = eval(out[0]) + if out_dict.has_key('return'): + if out_dict['return'].has_key('actual'): + qmp_actual = out_dict['return']['actual'] + else: + return False + + if qmp_actual == -1: + return False + + logger.info("the memory actual is: %s" % qmp_actual) + return qmp_actual + +def memory_stats(params): + """get domain memory stats + """ + global logger + logger = params['logger'] + guestname = params['guestname'] + + logger.info("the name of virtual machine is %s" % guestname) + + conn = sharedmod.libvirtobj['conn'] + + try: + domobj = conn.lookupByName(guestname) + mem = domobj.memoryStats() + logger.info("%s memory stats is: %s" % (guestname, mem)) + ret = get_memory_actual(guestname) + if not ret: + logger.error("get memory actual with qmp command failed") + return 1 + + if ret == mem['actual']*1024: + logger.info("actual memory is equal to output of qmp command") + else: + logger.error("actual memory is not equal to output of qmp command") + return 1 + + except libvirtError, e: + logger.error("libvirt call failed: " + str(e)) + return 1 + + return 0 diff --git a/repos/domain/set_maxmem_config.py b/repos/domain/set_maxmem_config.py new file mode 100644 index 0000000..262d7b1 --- /dev/null +++ b/repos/domain/set_maxmem_config.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +# Test set domain max memory with API setMaxMemory. + +from xml.dom import minidom + +import libvirt +from libvirt import libvirtError + +from src import sharedmod + +required_params = ('guestname', 'memory', ) +optional_params = {} + +def set_maxmem_config(params): + """set domain max memory, check with config xml and + maxMemory API + """ + global logger + logger = params['logger'] + guestname = params['guestname'] + memory = int(params['memory']) + + logger.info("the name of virtual machine is %s" % guestname) + logger.info("the given max memory value is %s" % memory) + + conn = sharedmod.libvirtobj['conn'] + + try: + domobj = conn.lookupByName(guestname) + logger.info("set domain max memory as %s" % memory) + domobj.setMaxMemory(memory) + + guestxml = domobj.XMLDesc(2) + logger.debug("domain %s xml is :\n%s" %(guestname, guestxml)) + xml = minidom.parseString(guestxml) + mem = xml.getElementsByTagName('memory')[0] + maxmem = int(mem.childNodes[0].data) + logger.info("domain max memory in config xml is: %s" % maxmem) + if maxmem == memory: + logger.info("max memory in domain config xml is equal to set") + else: + logger.error("set max memory failed") + return 1 + + maxmem = domobj.maxMemory() + logger.info("max memory got by maxMemory API is: %s" % maxmem) + if maxmem == memory: + logger.info("max memory got by maxMemory API is equal to set") + else: + logger.error("set max memory failed") + return 1 + + logger.info("set max memory succeed") + + except libvirtError, e: + logger.error("libvirt call failed: " + str(e)) + return 1 + + return 0 diff --git a/repos/domain/set_memory_config.py b/repos/domain/set_memory_config.py new file mode 100644 index 0000000..c8ef6c3 --- /dev/null +++ b/repos/domain/set_memory_config.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# Test set domain balloon memory with flag VIR_DOMAIN_AFFECT_CONFIG +# or VIR_DOMAIN_VCPU_MAXIMUM, depend on which optional param is +# given. + +from xml.dom import minidom + +import libvirt +from libvirt import libvirtError + +from src import sharedmod + +required_params = ('guestname', ) +optional_params = {'memory': 1048576, + 'maxmem': 4194304, + } +def get_memory_config(domobj): + """get domain config current memory and max memory + """ + try: + guestxml = domobj.XMLDesc(2) + logger.debug("domain %s xml is :\n%s" %(domobj.name(), guestxml)) + xml = minidom.parseString(guestxml) + + logger.info("get domain memory info in config xml") + mem = xml.getElementsByTagName('currentMemory')[0] + current = int(mem.childNodes[0].data) + logger.info("current memory in config xml is: %s" % current) + + mem = xml.getElementsByTagName('memory')[0] + max_memory = int(mem.childNodes[0].data) + logger.info("max memory in config xml is: %s" % max_memory) + + except libvirtError, e: + logger.error("libvirt call failed: " + str(e)) + return False + + return current, max_memory + +def set_memory_config(params): + """set domain memory with live flag and check + """ + global logger + logger = params['logger'] + guestname = params['guestname'] + memory = params.get('memory', None) + maxmem = params.get('maxmem', None) + + logger.info("the name of virtual machine is %s" % guestname) + if memory == None and maxmem == None: + logger.error("at least one of memory or maxmem should be provided") + return 1 + + conn = sharedmod.libvirtobj['conn'] + + try: + domobj = conn.lookupByName(guestname) + if memory: + memory = int(memory) + flags = libvirt.VIR_DOMAIN_AFFECT_CONFIG + logger.info("set domain memory as %s with flag: %s" % + (memory, flags)) + domobj.setMemoryFlags(memory, flags) + ret = get_memory_config(domobj) + if not ret: + return 1 + + if ret[0] == memory: + logger.info("set current memory succeed") + else: + logger.error("set current memory failed") + return 1 + + if maxmem: + maxmem = int(maxmem) + flags = libvirt.VIR_DOMAIN_MEM_MAXIMUM + logger.info("set domain max memory as %s with flag: %s" % + (maxmem, flags)) + domobj.setMemoryFlags(maxmem, flags) + ret = get_memory_config(domobj) + if not ret: + return 1 + + if ret[1] == maxmem: + logger.info("set max memory succeed") + else: + logger.error("set max memory failed") + return 1 + + except libvirtError, e: + logger.error("libvirt call failed: " + str(e)) + return 1 + + return 0 diff --git a/repos/domain/set_memory_live.py b/repos/domain/set_memory_live.py new file mode 100644 index 0000000..f7c77f9 --- /dev/null +++ b/repos/domain/set_memory_live.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +# Test set domain balloon memory with flag VIR_DOMAIN_AFFECT_LIVE. +# Check domain info and inside domain to get current memory value. +# The live flag only work on running domain, so test on shutoff +# domain will fail. + +import time +import math + +import libvirt +from libvirt import libvirtError + +from src import sharedmod +from utils import utils + +required_params = ('guestname', 'memory', 'username', 'password', ) +optional_params = {} + +def compare_memory(expect_memory, actual_memory): + """ comparing expected memory size with actual memory size """ + + logger.info("expected memory size is %s" % expect_memory) + logger.info("actual memory size is %s" % actual_memory) + diff = int(expect_memory) - int(actual_memory) + + if math.fabs(diff)/expect_memory < 0.05: + return 0 + else: + return 1 + +def get_current_memory(guestname, username, password): + """get domain current memory inside domain + """ + logger.debug("get the mac address of vm %s" % guestname) + mac = utils.get_dom_mac_addr(guestname) + logger.debug("the mac address of vm %s is %s" % (guestname, mac)) + ip = utils.mac_to_ip(mac, 180) + current = utils.get_remote_memory(ip, username, password) + + return current + +def set_memory_live(params): + """set domain memory with live flag and check + """ + global logger + logger = params['logger'] + params.pop('logger') + guestname = params['guestname'] + memory = int(params['memory']) + username = params['username'] + password = params['password'] + + logger.info("the name of virtual machine is %s" % guestname) + logger.info("the given memory value is %s" % memory) + + conn = sharedmod.libvirtobj['conn'] + + try: + domobj = conn.lookupByName(guestname) + logger.info("set domain memory as %s with flag: %s" % + (memory, libvirt.VIR_DOMAIN_AFFECT_LIVE)) + domobj.setMemoryFlags(memory, libvirt.VIR_DOMAIN_AFFECT_LIVE) + logger.info("get domain current memory") + time.sleep(3) + dominfo = domobj.info() + logger.debug("domain info list is: %s" % dominfo) + logger.info("domain current memory value is: %s KiB" % dominfo[2]) + if memory == dominfo[2]: + logger.info("set memory match with domain info") + else: + logger.error("set memory not match with domain info") + return 1 + + logger.info("check domain memory inside domain") + ret = get_current_memory(guestname, username, password) + if not compare_memory(memory, ret): + logger.info("set domain memory succeed") + else: + logger.error("set domain memory failed") + return 1 + + except libvirtError, e: + logger.error("libvirt call failed: " + str(e)) + return 1 + + return 0 -- 1.8.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list