[libvirt] [test-API][PATCH] Add cpu hotplug test case

Guannan Ren gren at redhat.com
Fri Nov 16 08:09:05 UTC 2012


On 11/16/2012 02:47 PM, Wayne Sun wrote:
> Test hotplug domain CPU, loop increase cpu to max then decrease
> to min. Now qemu did not support decrease plug of cpu, so decrease
> part will fail, leave it in the case to keep integrity.
>
> Signed-off-by: Wayne Sun <gsun at redhat.com>
> ---
>   cases/cpu_hotplug.conf      |   38 +++++++
>   repos/domain/cpu_hotplug.py |  257 +++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 295 insertions(+), 0 deletions(-)
>   create mode 100644 cases/cpu_hotplug.conf
>   create mode 100644 repos/domain/cpu_hotplug.py
>
> diff --git a/cases/cpu_hotplug.conf b/cases/cpu_hotplug.conf
> new file mode 100644
> index 0000000..7ac0612
> --- /dev/null
> +++ b/cases/cpu_hotplug.conf
> @@ -0,0 +1,38 @@
> +domain:install_linux_cdrom
> +    guestname
> +        $defaultname
> +    guestos
> +        $defaultos
> +    guestarch
> +        $defaultarch
> +    vcpu
> +        $defaultvcpu
> +    memory
> +        $defaultmem
> +    hddriver
> +        $defaulthd
> +    nicdriver
> +        $defaultnic
> +    macaddr
> +        54:52:00:45:c3:8a
> +
> +domain:cpu_hotplug
> +    guestname
> +        $defaultname
> +    vcpu
> +        4
> +    username
> +        $username
> +    password
> +        $password
> +
> +domain:destroy
> +    guestname
> +        $defaultname
> +
> +domain:undefine
> +    guestname
> +        $defaultname
> +
> +options cleanup=enable
> +
> diff --git a/repos/domain/cpu_hotplug.py b/repos/domain/cpu_hotplug.py
> new file mode 100644
> index 0000000..3626db7
> --- /dev/null
> +++ b/repos/domain/cpu_hotplug.py
> @@ -0,0 +1,257 @@
> +#!/usr/bin/env python
> +# Test hotplug domain CPU, loop increase cpu to max then decrease
> +# to min
> +
> +import time
> +import commands
> +from xml.dom import minidom
> +
> +import libvirt
> +from libvirt import libvirtError
> +
> +from src import sharedmod
> +from utils import utils
> +
> +required_params = ('guestname', 'vcpu', 'username', 'password')
> +optional_params = {}
> +
> +def check_domain_running(conn, guestname):
> +    """ check if the domain exists, may or may not be active """
> +    guest_names = []
> +    ids = conn.listDomainsID()
> +    for id in ids:
> +        obj = conn.lookupByID(id)
> +        guest_names.append(obj.name())
> +
> +    if guestname not in guest_names:
> +        logger.error("%s doesn't exist or not running" % guestname)
> +        return 1
> +    else:
> +        return 0
> +
> +def redefine_vcpu_number(domobj, guestname, vcpu):
> +    """dump domain xml description to change the vcpu number,
> +       then, define the domain again
> +    """
> +    guestxml = domobj.XMLDesc(0)
> +    logger.debug('''original guest %s xml :\n%s''' %(guestname, guestxml))
> +
> +    doc = minidom.parseString(guestxml)
> +
> +    newvcpu = doc.createElement('vcpu')
> +    newvcpuval = doc.createTextNode(str(vcpu))
> +    newvcpu.appendChild(newvcpuval)
> +    newvcpu.setAttribute('current', '1')
> +
> +    domain = doc.getElementsByTagName('domain')[0]
> +    oldvcpu = doc.getElementsByTagName('vcpu')[0]
> +
> +    domain.replaceChild(newvcpu, oldvcpu)
> +
> +    return doc.toxml()
> +
> +def check_current_vcpu(domobj, username, password):
> +    """dump domain xml description to get current vcpu number
> +    """
> +    guestxml = domobj.XMLDesc(1)
> +    logger.debug("domain %s xml is :\n%s" %(domobj.name(), guestxml))
> +
> +    xml = minidom.parseString(guestxml)
> +    vcpu = xml.getElementsByTagName('vcpu')[0]
> +    if vcpu.hasAttribute('current'):
> +        attr = vcpu.getAttributeNode('current')
> +        current_vcpu = int(attr.nodeValue)
> +    else:
> +        logger.info("domain did not have 'current' attribute in vcpu element")
> +        current_vcpu = int(vcpu.childNodes[0].data)
> +
> +    logger.info("check cpu number in domain")
> +    ip = utils.mac_to_ip(mac, 180)
> +
> +    cmd = "cat /proc/cpuinfo | grep processor | wc -l"
> +    ret, output = utils.remote_exec_pexpect(ip, username, password, cmd)
> +    if not ret:
> +        logger.info("cpu number in domain is %s" % output)
> +        if int(output) == current_vcpu:
> +            logger.info("cpu number in domain is equal to current vcpu value")
> +            return current_vcpu
> +        else:
> +            logger.error("current vcpu is not equal as check in domain")
> +            return False
> +    else:
> +        logger.error("check in domain fail")
> +        return False
> +
> +
> +def set_vcpus(domobj, guestname, vcpu, username, password):
> +    """set the value of virtual machine to vcpu offline , then boot up
> +       the virtual machine
> +    """
> +    timeout = 60
> +    logger.info('destroy domain')
> +
> +    try:
> +        domobj.destroy()
> +    except libvirtError, e:
> +        logger.error("API error message: %s, error code is %s" \
> +                    % (e.message, e.get_error_code()))
> +        logger.error("fail to destroy domain")
> +        return 1
> +
> +    newguestxml = redefine_vcpu_number(domobj, guestname, vcpu)
> +    logger.debug('''new guest %s xml :\n%s''' %(guestname, newguestxml))
> +
> +    logger.info("undefine the original guest")
> +    try:
> +        domobj.undefine()
> +    except libvirtError, e:
> +        logger.error("API error message: %s, error code is %s" \
> +                     % (e.message, e.get_error_code()))
> +        logger.error("fail to undefine guest %" % guestname)
> +        return 1
> +
> +    logger.info("define guest with new xml")
> +    try:
> +        conn = domobj._conn
> +        conn.defineXML(newguestxml)
> +    except libvirtError, e:
> +        logger.error("API error message: %s, error code is %s" \
> +                     % (e.message, e.get_error_code()))
> +        logger.error("fail to define guest %s" % guestname)
> +        return 1
> +
> +    try:
> +        logger.info('boot guest up ...')
> +        domobj.create()
> +    except libvirtError, e:
> +        logger.error("API error message: %s, error code is %s" \
> +                     % (e.message, e.get_error_code()))
> +        logger.error("fail to start domain %s" % guestname)
> +        return 1
> +
> +    timeout = 600
> +
> +    while timeout:
> +        time.sleep(10)
> +        timeout -= 10
> +
> +        logger.debug("get ip by mac address")
> +        ip = utils.mac_to_ip(mac, 180)
> +        logger.debug("the ip address of vm %s is %s" % (guestname, ip))
> +
> +        if not ip:
> +            logger.info(str(timeout) + "s left")
> +        else:
> +            logger.info("vm %s power on successfully" % guestname)
> +            logger.info("the ip address of vm %s is %s" % (guestname, ip))
> +            break
> +
> +    if timeout <= 0:
> +        logger.info("fail to power on vm %s" % guestname)
> +        return 1
> +
> +    ret = check_current_vcpu(domobj, username, password)
> +    if ret != 'False':
> +        return 0
> +    else:
> +        return 1
> +
> +    return 0
> +
> +def cpu_hotplug(params):
> +    """set vcpu of virtual machine to value of parameter vcpu and
> +       current cpu as 1, then loop set runnning domain vcpu from
> +       min to max and loop hotplug it to min
> +    """
> +    global logger
> +    logger = params['logger']
> +    params.pop('logger')
> +    guestname = params['guestname']
> +    vcpu = int(params['vcpu'])
> +    username = params['username']
> +    password = params['password']
> +
> +    logger.info("the name of virtual machine is %s" % guestname)
> +    logger.info("the vcpu given is %s" % vcpu)
> +    if not vcpu > 1:
> +        logger.error("vcpu number should bigger than 1")
> +        return 1
> +
> +    conn = sharedmod.libvirtobj['conn']
> +
> +    try:
> +        max_vcpus = int(conn.getMaxVcpus('kvm'))
> +        logger.debug("hypervisor supported max vcpu is %s" % max_vcpus)
> +    except libvirtError, e:
> +        logger.error("libvirt call failed: " + str(e))
> +        return 1
> +
> +    if vcpu > max_vcpus:
> +        logger.error("the given vcpu %s is bigger than hypervisor supported" %
> +                     vcpu)
> +        return 1
> +
> +    ret = check_domain_running(conn, guestname)
> +    if ret:
> +        return 1
> +
> +    logger.debug("get the mac address of vm %s" % guestname)
> +    global mac
> +    mac = utils.get_dom_mac_addr(guestname)
> +    logger.debug("the mac address of vm %s is %s" % (guestname, mac))
> +
> +    domobj = conn.lookupByName(guestname)
> +
> +    logger.info("set domain vcpu to %s and restart with current cpu as 1" %
> +                    vcpu)
> +    ret = set_vcpus(domobj, guestname, vcpu, username, password)
> +    if ret != 0:
> +        return 1
> +
> +    try:
> +        max = domobj.maxVcpus()
> +        logger.info("max vcpu of domain %s is %s" % (guestname, max))
> +    except libvirtError, e:
> +        logger.error("libvirt call failed: " + str(e))
> +        return 1
> +
> +    logger.info("loop increasing domain %s vcpu count to max" % guestname)
> +    for i in range(max):
> +        i += 1
> +        try:
> +            domobj.setVcpus(i)
> +            logger.info("set vcpus to %s" % i)
> +        except libvirtError, e:
> +            logger.error("libvirt call failed: " + str(e))
> +            return 1
> +
> +        time.sleep(5)
> +
> +        ret = check_current_vcpu(domobj, username, password)
> +        if ret == i:
> +            logger.info("current vcpu number is %s and equal to set" % ret)
> +        else:
> +            logger.error("set current vcpu failed")
> +            return 1
> +
> +    logger.info("loop decreasing domain %s vcpu count to min" % guestname)
> +    for i in reversed(range(max)):
> +        if i == 0:
> +            break
> +        logger.info("set vcpus to %s" % i)
> +        try:
> +            max = domobj.setVcpus(i)
> +        except libvirtError, e:
> +            logger.error("libvirt call failed: " + str(e))
> +            return 1
> +
> +        time.sleep(5)
> +
> +        ret = check_current_vcpu(domobj, username, password)
> +        if ret == i:
> +            logger.info("current vcpu number is %s and equal to set" % ret)
> +        else:
> +            logger.error("set current vcpu failed")
> +            return 1
> +
> +    return 0

      ACK and pushed.

      Guannan Ren




More information about the libvir-list mailing list