[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [test-API][PATCH] Add 2 vcpupin cases cover config and live flags



* use pinVcpuFlags to pin domain vcpu to host cpu
* 2 cases cover config and live flags
* cpulist with '^', '-' and ',' is supported to give multiple
  host cpus
* vcpus and vcpuPinInfo are used as part of the checking
* a sample conf is added

Signed-off-by: Wayne Sun <gsun redhat com>
---
 cases/vcpupin.conf               |   67 +++++++++++++++
 repos/setVcpus/vcpupin_config.py |  174 ++++++++++++++++++++++++++++++++++++++
 repos/setVcpus/vcpupin_live.py   |  166 ++++++++++++++++++++++++++++++++++++
 3 files changed, 407 insertions(+), 0 deletions(-)
 create mode 100644 cases/vcpupin.conf
 create mode 100644 repos/setVcpus/vcpupin_config.py
 create mode 100644 repos/setVcpus/vcpupin_live.py

diff --git a/cases/vcpupin.conf b/cases/vcpupin.conf
new file mode 100644
index 0000000..880247f
--- /dev/null
+++ b/cases/vcpupin.conf
@@ -0,0 +1,67 @@
+domain:install_linux_cdrom
+    guestname
+        $defaultname
+    guestos
+        $defaultos
+    guestarch
+        $defaultarch
+    vcpu
+        4
+    memory
+        $defaultmem
+    hddriver
+        $defaulthd
+    nicdriver
+        $defaultnic
+    imageformat
+        qcow2
+
+setVcpus:vcpupin_live
+    guestname
+        $defaultname
+    vcpu
+        0
+    cpulist
+        2,4-6,^4
+
+setVcpus:vcpupin_live
+    guestname
+        $defaultname
+    vcpu
+        1
+    cpulist
+        3
+
+domain:destroy
+    guestname
+        $defaultname
+
+setVcpus:vcpupin_config
+    guestname
+        $defaultname
+    vcpu
+        2
+    cpulist
+        0-8,^1
+
+setVcpus:vcpupin_config
+    guestname
+        $defaultname
+    vcpu
+        3
+    cpulist
+        ^2,0-8
+
+domain:start
+    guestname
+        $defaultname
+
+domain:destroy
+    guestname
+        $defaultname
+
+domain:undefine
+    guestname
+        $defaultname
+
+options cleanup=enable
diff --git a/repos/setVcpus/vcpupin_config.py b/repos/setVcpus/vcpupin_config.py
new file mode 100644
index 0000000..12d9598
--- /dev/null
+++ b/repos/setVcpus/vcpupin_config.py
@@ -0,0 +1,174 @@
+#!/usr/bin/env python
+# Test domain vcpu pin with flag VIR_DOMAIN_AFFECT_CONFIG, check
+# domain config xml with vcpupin configuration.
+
+import re
+from xml.dom import minidom
+
+import libvirt
+from libvirt import libvirtError
+
+from src import sharedmod
+from utils import utils
+
+required_params = ('guestname', 'vcpu', 'cpulist',)
+optional_params = {}
+
+def vcpupin_check(domobj, vcpu, cpumap):
+    """check domain config xml with vcpupin element
+    """
+    guestxml = domobj.XMLDesc(2)
+    logger.debug("domain %s xml :\n%s" %(domobj.name(), guestxml))
+
+    doc = minidom.parseString(guestxml)
+    vcpupin = doc.getElementsByTagName('vcpupin')
+    if not vcpupin:
+        logger.error("no vcpupin element in domain xml")
+        return 1
+
+    for i in range(len(vcpupin)):
+        if vcpupin[i].hasAttribute('vcpu') and \
+           vcpupin[i].hasAttribute('cpuset'):
+            vcpu_attr = vcpupin[i].getAttributeNode('vcpu')
+            cpu_attr = vcpupin[i].getAttributeNode('cpuset')
+            if int(vcpu_attr.nodeValue) == vcpu:
+                cpulist = cpu_attr.nodeValue
+                if cpulist == '':
+                    cpumap_tmp = ()
+                    for i in range(maxcpu):
+                        cpumap_tmp += (False,)
+                else:
+                    cpumap_tmp = get_cpumap(cpulist)
+
+                if cpumap_tmp == cpumap:
+                    logger.info("cpuset is as expected in domain xml")
+                    return 0
+                else:
+                    logger.error("cpuset is not as expected in domain xml")
+                    return 1
+
+        if i == len(vcpupin) - 1:
+            logger.error("the vcpupin element with given vcpu is not found")
+            return 1
+
+def format_cpumap(cpulist, cpumap_test):
+    """ format cpumap base on cpulist
+    """
+    cpumap = ()
+
+    try:
+        if re.match('\^', cpulist):
+            unuse = int(re.split('\^', cpulist)[1])
+            for i in range(maxcpu):
+                if i == unuse:
+                    cpumap += (False,)
+                else:
+                    cpumap += (cpumap_test[i],)
+
+        elif '-' in cpulist:
+            cpu_list = re.split('-', cpulist)
+            if not len(cpu_list) == 2:
+                return False
+            if not int(cpu_list[1]) < maxcpu:
+                logger.error("cpulist: out of host cpu range")
+                return False
+            if int(cpu_list[1]) < int(cpu_list[0]):
+                return False
+
+            for i in range(maxcpu):
+                if i in range(int(cpu_list[0]), int(cpu_list[1])+1):
+                    cpumap += (True,)
+                else:
+                    cpumap += (cpumap_test[i],)
+
+        else:
+            for i in range(maxcpu):
+                if i == int(cpulist):
+                    cpumap += (True,)
+                else:
+                    cpumap += (cpumap_test[i],)
+
+        return cpumap
+    except ValueError, e:
+        logger.error("ValueError: " + str(e))
+        return False
+
+def get_cpumap(cpulist):
+    """get cpumap base on given cpulist
+    """
+    cpumap_test = ()
+    for i in range(maxcpu):
+        cpumap_test += (False,)
+
+    if ',' in cpulist:
+        cpu_list = re.split(',', cpulist)
+        for i in range(len(cpu_list)):
+            cpumap = format_cpumap(cpu_list[i], cpumap_test)
+            if cpumap:
+                cpumap_test = cpumap
+            else:
+                return False
+        return cpumap
+
+    else:
+        cpumap = format_cpumap(cpulist, cpumap_test)
+        if cpumap:
+            return cpumap
+        else:
+            return False
+
+def vcpupin_config(params):
+    """pin domain vcpu to host cpu with config flag
+    """
+    global logger
+    logger = params['logger']
+    params.pop('logger')
+    guestname = params['guestname']
+    vcpu = int(params['vcpu'])
+    cpulist = params['cpulist']
+
+    logger.info("the name of virtual machine is %s" % guestname)
+    logger.info("the given vcpu is %s" % vcpu)
+    logger.info("the given cpulist is %s" % cpulist)
+
+    global maxcpu
+    maxcpu = utils.get_host_cpus()
+    logger.info("%s physical cpu on host" % maxcpu)
+
+    conn = sharedmod.libvirtobj['conn']
+
+    try:
+        domobj = conn.lookupByName(guestname)
+        cpumap = get_cpumap(cpulist)
+        if not cpumap:
+            logger.error("cpulist: Invalid format")
+            return 1
+
+        logger.debug("cpumap for vcpu pin is:")
+        logger.debug(cpumap)
+
+        logger.info("pin domain vcpu %s to host cpulist %s with flag: %s" %
+                    (vcpu, cpulist, libvirt.VIR_DOMAIN_AFFECT_CONFIG))
+        domobj.pinVcpuFlags(vcpu, cpumap, libvirt.VIR_DOMAIN_AFFECT_CONFIG)
+
+        logger.info("check vcpu pin info")
+        ret = domobj.vcpuPinInfo(libvirt.VIR_DOMAIN_AFFECT_CONFIG)
+        logger.debug("vcpu pin info is:")
+        logger.debug(ret)
+        if ret[vcpu] == cpumap:
+            logger.info("vcpu pin info is expected")
+        else:
+            logger.error("vcpu pin info is not expected")
+            return 1
+    except libvirtError, e:
+        logger.error("libvirt call failed: " + str(e))
+        return 1
+
+    logger.info("check domain vcpupin configuration in xml")
+    ret = vcpupin_check(domobj, vcpu, cpumap)
+    if ret:
+        logger.error("domain vcpu pin check failed")
+        return 1
+    else:
+        logger.info("domain vcpu pin check succeed")
+        return 0
diff --git a/repos/setVcpus/vcpupin_live.py b/repos/setVcpus/vcpupin_live.py
new file mode 100644
index 0000000..09744a5
--- /dev/null
+++ b/repos/setVcpus/vcpupin_live.py
@@ -0,0 +1,166 @@
+#!/usr/bin/env python
+# Test domain vcpu pin with flag VIR_DOMAIN_AFFECT_LIVE, check
+# vcpu subprocess status under domain task list on host.
+
+import re
+
+import libvirt
+from libvirt import libvirtError
+
+from src import sharedmod
+from utils import utils
+
+required_params = ('guestname', 'vcpu', 'cpulist',)
+optional_params = {}
+
+def vcpupin_check(guestname, vcpu, cpumap):
+    """check vcpu subprocess status of the running virtual machine
+       grep Cpus_allowed_list /proc/PID/task/*/status
+    """
+    tmp_str = ''
+    cmd = "cat /var/run/libvirt/qemu/%s.pid" % guestname
+    status, pid = utils.exec_cmd(cmd, shell=True)
+    if status:
+        logger.error("failed to get the pid of domain %s" % guestname)
+        return 1
+
+    cmd = "grep Cpus_allowed_list /proc/%s/task/*/status" % pid[0]
+    status, output = utils.exec_cmd(cmd, shell=True)
+    logger.debug("command '%s' output is:" % cmd)
+    for i in range(len(output)):
+        tmp_str += ''.join(output[i]) + '\n'
+    logger.debug(tmp_str)
+
+    task_list = output[1:]
+    vcpu_task = task_list[int(vcpu)]
+    cpulist = vcpu_task.split('\t')[1]
+    ret = get_cpumap(cpulist)
+    if ret == cpumap:
+        logger.info("vcpu process cpus allowed list is expected")
+        return 0
+    else:
+        logger.error("vcpu process cpus allowed list is not expected")
+        return 1
+
+def format_cpumap(cpulist, cpumap_test):
+    """ format cpumap base on cpulist
+    """
+    cpumap = ()
+
+    try:
+        if re.match('\^', cpulist):
+            unuse = int(re.split('\^', cpulist)[1])
+            for i in range(maxcpu):
+                if i == unuse:
+                    cpumap += (False,)
+                else:
+                    cpumap += (cpumap_test[i],)
+
+        elif '-' in cpulist:
+            cpu_list = re.split('-', cpulist)
+            if not len(cpu_list) == 2:
+                return False
+            if not int(cpu_list[1]) < maxcpu:
+                logger.error("cpulist: out of host cpu range")
+                return False
+            if int(cpu_list[1]) < int(cpu_list[0]):
+                return False
+
+            for i in range(maxcpu):
+                if i in range(int(cpu_list[0]), int(cpu_list[1])+1):
+                    cpumap += (True,)
+                else:
+                    cpumap += (cpumap_test[i],)
+
+        else:
+            for i in range(maxcpu):
+                if i == int(cpulist):
+                    cpumap += (True,)
+                else:
+                    cpumap += (cpumap_test[i],)
+
+        return cpumap
+    except ValueError, e:
+        logger.error("ValueError: " + str(e))
+        return False
+
+def get_cpumap(cpulist):
+    """get cpumap base on given cpulist
+    """
+    cpumap_test = ()
+    for i in range(maxcpu):
+        cpumap_test += (False,)
+
+    if ',' in cpulist:
+        cpu_list = re.split(',', cpulist)
+        for i in range(len(cpu_list)):
+            cpumap = format_cpumap(cpu_list[i], cpumap_test)
+            if cpumap:
+                cpumap_test = cpumap
+            else:
+                return False
+        return cpumap
+
+    else:
+        cpumap = format_cpumap(cpulist, cpumap_test)
+        if cpumap:
+            return cpumap
+        else:
+            return False
+
+def vcpupin_live(params):
+    """pin domain vcpu to host cpu with live flag
+    """
+    global logger
+    logger = params['logger']
+    params.pop('logger')
+    guestname = params['guestname']
+    vcpu = int(params['vcpu'])
+    cpulist = params['cpulist']
+
+    logger.info("the name of virtual machine is %s" % guestname)
+    logger.info("the given vcpu is %s" % vcpu)
+    logger.info("the given cpulist is %s" % cpulist)
+
+    global maxcpu
+    maxcpu = utils.get_host_cpus()
+    logger.info("%s physical cpu on host" % maxcpu)
+
+    conn = sharedmod.libvirtobj['conn']
+
+    try:
+        domobj = conn.lookupByName(guestname)
+        cpumap = get_cpumap(cpulist)
+        if not cpumap:
+            logger.error("cpulist: Invalid format")
+            return 1
+
+        logger.debug("cpumap for vcpu pin is:")
+        logger.debug(cpumap)
+
+        logger.info("pin domain vcpu %s to host cpu %s with flag: %s" %
+                    (vcpu, cpulist, libvirt.VIR_DOMAIN_AFFECT_LIVE))
+        domobj.pinVcpuFlags(vcpu, cpumap, libvirt.VIR_DOMAIN_AFFECT_LIVE)
+
+        logger.info("check vcpus info")
+        ret = domobj.vcpus()
+        logger.debug("vcpus info is:")
+        logger.debug(ret)
+        if ret[1][vcpu] == cpumap:
+            logger.info("vcpus info is expected")
+        else:
+            logger.error("vcpus info is not expected")
+            return 1
+
+    except libvirtError, e:
+        logger.error("libvirt call failed: " + str(e))
+        return 1
+
+    logger.info("check vcpu pin status on host")
+    ret = vcpupin_check(guestname, vcpu, cpumap)
+    if ret:
+        logger.error("domain vcpu pin failed")
+        return 1
+    else:
+        logger.info("domain vcpu pin succeed")
+        return 0
-- 
1.7.1


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]