[libvirt] [libvirt-test-API][PATCH 2/2] Add connection_getAllDomainStats test case
hujianwei
jiahu at redhat.com
Thu Mar 12 07:14:09 UTC 2015
On 11/03/15 17:14, hongming wrote:
> Hi jiahu
>
> Please add the following api calling to your case, we can test them
> using the same checking methods .
>
> def domainListGetStats(self, doms, stats=0, flags=0):
> """ Query statistics for given domains.
>
> Thanks
> Hongming
>
OK, the V2 patch series has been sent out, please review them.
BR,
Jianwei
> On 03/05/2015 04:02 PM, jiahu wrote:
>> The case will validate the getAllDomainStats API in class virConnect
>> ---
>> repos/virconn/connection_getAllDomainStats.py | 528
>> ++++++++++++++++++++++++++
>> 1 file changed, 528 insertions(+)
>> create mode 100644 repos/virconn/connection_getAllDomainStats.py
>>
>> diff --git a/repos/virconn/connection_getAllDomainStats.py
>> b/repos/virconn/connection_getAllDomainStats.py
>> new file mode 100644
>> index 0000000..023564a
>> --- /dev/null
>> +++ b/repos/virconn/connection_getAllDomainStats.py
>> @@ -0,0 +1,528 @@
>> +#!/usr/bin/env python
>> +# test getAllDomainStats() API for libvirt
>> +
>> +import libvirt
>> +
>> +from xml.dom import minidom
>> +from libvirt import libvirtError
>> +from src import sharedmod
>> +from utils import utils
>> +
>> +required_params = ()
>> +optional_params = {'stats': '','flags': ''}
>> +
>> +ds = {"state": libvirt.VIR_DOMAIN_STATS_STATE,
>> + "cpu": libvirt.VIR_DOMAIN_STATS_CPU_TOTAL,
>> + "balloon": libvirt.VIR_DOMAIN_STATS_BALLOON,
>> + "vcpu": libvirt.VIR_DOMAIN_STATS_VCPU,
>> + "interface": libvirt.VIR_DOMAIN_STATS_INTERFACE,
>> + "block": libvirt.VIR_DOMAIN_STATS_BLOCK}
>> +
>> +fg = {"active": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE,
>> + "inactive": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_INACTIVE,
>> + "persistent":
>> libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT,
>> + "transient": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_TRANSIENT,
>> + "running": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_RUNNING,
>> + "paused": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_PAUSED,
>> + "shutoff": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_SHUTOFF,
>> + "other": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_OTHER,
>> + "backing": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING,
>> + "enforce":
>> libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS}
>> +
>> +def filer_domains(logger, flags):
>> + """
>> + return a filtered domains set
>> + """
>> + a = set(active_domains(logger))
>> + d = set(defined_domains(logger))
>> + if flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT
>> and \
>> + flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_TRANSIENT:
>> + domains = a | d
>> + elif flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT:
>> + domains = d
>> + elif flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_TRANSIENT:
>> + domains = a - d
>> + else:
>> + domains = a | d
>> + if flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE and \
>> + flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_INACTIVE:
>> + domains &= (a | d)
>> + elif flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE:
>> + domains &= a
>> + elif flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_INACTIVE:
>> + domains &= (d - a)
>> + else:
>> + domains &= a | d
>> + return domains
>> +
>> +def active_domains(logger):
>> + """
>> + return active domains on current uri
>> + """
>> + NUM = "ls /run/libvirt/qemu|grep \".xml\""
>> + status, output = utils.exec_cmd(NUM, shell=True)
>> + output = [item.replace(".xml","") for item in output]
>> + if status == 0:
>> + logger.debug("Got active domains: %s" % output)
>> + return output
>> + else:
>> + logger.debug("Got active domains: %s" % output)
>> + return output
>> +
>> +def defined_domains(logger):
>> + """
>> + return defined domains on current uri
>> + """
>> + NUM = "ls /etc/libvirt/qemu|grep \".xml\""
>> + status, output = utils.exec_cmd(NUM, shell=True)
>> + output = [item.replace(".xml","") for item in output]
>> + if status == 0:
>> + logger.debug("Got defined domains: %s" % output)
>> + return output
>> + else:
>> + logger.debug("Got defined domains: %s" % output)
>> + return output
>> +
>> +def compare_value(logger,op1,op2):
>> + """
>> + compare 2 variables value
>> + """
>> + if op1 != op2:
>> + logger.debug("Check %s: Fail" % op2)
>> + return False
>> + else:
>> + logger.debug("Check %s: Pass" % op2)
>> + return True
>> +
>> +def check_vcpu(logger,dom_name,dom_active,dom_eles):
>> + """
>> + check vcpu info of given domain
>> + """
>> + iDOM_XML = "/etc/libvirt/qemu/" + dom_name +".xml"
>> + aDOM_XML = "/run/libvirt/qemu/" + dom_name +".xml"
>> + if dom_active:
>> + xml = minidom.parse(aDOM_XML)
>> + dom = xml.getElementsByTagName('domain')[0]
>> + vcpu = dom.getElementsByTagName('vcpu')[0]
>> + vcpu_max = int(vcpu.childNodes[0].data)
>> + if not vcpu.getAttribute('current'):
>> + vcpu_cur = vcpu_max
>> + else:
>> + vcpu_cur = int(vcpu.getAttribute('current'))
>> +
>> + logger.debug("Checking vcpu.current: %d" \
>> + % dom_eles.get("vcpu.current"))
>> + if not compare_value(logger,vcpu_cur, \
>> + dom_eles.get("vcpu.current")):
>> + return False
>> + logger.debug("Checking vcpu.maximum: %d" \
>> + % dom_eles.get("vcpu.maximum"))
>> + if not compare_value(logger,vcpu_max, \
>> + dom_eles.get("vcpu.maximum")):
>> + return False
>> + else:
>> + xml = minidom.parse(iDOM_XML)
>> + vcpu = xml.getElementsByTagName('vcpu')[0]
>> + vcpu_max = int(vcpu.childNodes[0].data)
>> + logger.debug("Checking vcpu.maximum: %d" \
>> + % dom_eles.get("vcpu.maximum"))
>> + if not compare_value(logger,vcpu_max, \
>> + dom_eles.get("vcpu.maximum")):
>> + return False
>> + #for each vcpu.state field
>> + check_each_vcpu(logger,dom_name,dom_active,dom_eles)
>> + return True
>> +
>> +def check_each_vcpu(logger,dom_name,dom_active,dom_eles):
>> + """
>> + check each vcpu info, but ignore vcpu.*.time
>> + """
>> + iDOM_XML = "/etc/libvirt/qemu/" + dom_name +".xml"
>> + aDOM_XML = "/run/libvirt/qemu/" + dom_name +".xml"
>> + vcpu_index = 0
>> + if dom_active:
>> + vcpu_stat = 1
>> + xml = minidom.parse(aDOM_XML)
>> + dom = xml.getElementsByTagName('vcpus')[0]
>> + dom_pid = str(xml.getElementsByTagName("domstatus")[0].\
>> + getAttributeNode('pid').nodeValue)
>> + vcpu = dom.getElementsByTagName('vcpu')
>> + for vcpu_sub in vcpu:
>> + proc_path = "/proc/"
>> + vcpu_pre = "vcpu."+ str(vcpu_index) + "."
>> + attr1 = dom_eles.get(vcpu_pre +"state")
>> + logger.debug("Checking %sstate: %d" %(vcpu_pre, attr1))
>> + if not compare_value(logger,vcpu_stat, attr1):
>> + return False
>> + vcpu_index +=1
>> + else:
>> + vcpu_stat = 0
>> + xml = minidom.parse(iDOM_XML)
>> + vcpu = xml.getElementsByTagName('vcpu')[0]
>> + vcpu_max = int(vcpu.childNodes[0].data)
>> + vcpu_cur = vcpu.getAttributeNode('current')
>> + if not vcpu_cur:
>> + for i in range(0,vcpu_max):
>> + vcpu_pre = "vcpu."+ str(i) + "."
>> + logger.debug("Checking %sstate: %d" \
>> + %(vcpu_pre, dom_eles.get(vcpu_pre + "state")))
>> + if not compare_value(logger,vcpu_stat, \
>> + dom_eles.get(vcpu_pre + "state")):
>> + return False
>> + elif int(vcpu_cur.nodeValue) <= vcpu_max:
>> + for i in range(0,int(vcpu_cur.nodeValue)):
>> + vcpu_pre = "vcpu."+ str(i) + "."
>> + logger.debug("Checking %sstate: %d" \
>> + %(vcpu_pre, dom_eles.get(vcpu_pre + "state")))
>> + if not compare_value(logger,vcpu_stat, \
>> + dom_eles.get(vcpu_pre + "state")):
>> + return False
>> + return True
>> +
>> +def check_balloon(logger,dom_name,dom_active,dom_eles):
>> + """
>> + check balloon of given domain
>> + """
>> + iDOM_XML = "/etc/libvirt/qemu/" + dom_name +".xml"
>> + aDOM_XML = "/run/libvirt/qemu/" + dom_name +".xml"
>> + if dom_active:
>> + xml = minidom.parse(aDOM_XML)
>> + dom = xml.getElementsByTagName('domain')[0]
>> + mem_max = int(dom.getElementsByTagName('memory')[0]\
>> + .childNodes[0].data)
>> + mem_cur = int(dom.getElementsByTagName('currentMemory')[0]\
>> + .childNodes[0].data)
>> + logger.debug("Checking balloon.maximum: %d" \
>> + % dom_eles.get("balloon.maximum"))
>> + if not compare_value(logger,mem_max, \
>> + dom_eles.get("balloon.maximum")):
>> + return False
>> + logger.debug("Checking balloon.current: %d" \
>> + % dom_eles.get("balloon.current"))
>> + if not compare_value(logger,mem_cur, \
>> + dom_eles.get("balloon.current")):
>> + return False
>> + else:
>> + xml = minidom.parse(iDOM_XML)
>> + mem_max = int(xml.getElementsByTagName('memory')[0].\
>> + childNodes[0].data)
>> + logger.debug("Checking balloon.maximum: %d" \
>> + % dom_eles.get("balloon.maximum"))
>> + if not compare_value(logger,mem_max, \
>> + dom_eles.get("balloon.maximum")):
>> + return False
>> + return True
>> +
>> +def check_interface(logger,dom_name,dom_active, dom_eles):
>> + """
>> + check interface info, only check the count and name attributes
>> + other sub-attributes of net.* will be ignored
>> + """
>> + iDOM_XML = "/etc/libvirt/qemu/" + dom_name +".xml"
>> + aDOM_XML = "/run/libvirt/qemu/" + dom_name +".xml"
>> + netfile = "/proc/net/dev"
>> + if dom_active:
>> + xml = minidom.parse(aDOM_XML)
>> + dom = xml.getElementsByTagName('domain')[0]
>> + dev = dom.getElementsByTagName('devices')[0]
>> + nic = dev.getElementsByTagName('interface')
>> + logger.debug("Checking net.count: %d" %
>> dom_eles.get("net.count"))
>> + if not
>> compare_value(logger,len(nic),dom_eles.get("net.count")):
>> + return False
>> + for iface in nic:
>> + if_name = iface.getElementsByTagName("target")[0].\
>> + getAttribute('dev')
>> + if_name += ":"
>> + logger.debug("Checking %s" % if_name)
>> + content = open(netfile, 'r')
>> + if if_name in str(content.readlines()):
>> + logger.debug("Check %s: Pass" % if_name)
>> + else:
>> + logger.debug("Check %s: Fail" % if_name)
>> + return False
>> + content.close()
>> + else:
>> + pass
>> + return True
>> +
>> +def count_disk_chain(logger,filepath,dom_active):
>> + """
>> + count deep of disk chain
>> + """
>> + CMD = "file %s"
>> + num = 0
>> + while True:
>> + status, output = utils.exec_cmd(CMD % filepath, shell=True)
>> + if status != 0:
>> + logger.debug("Can not see the back file")
>> + if "has backing file" in output[0]:
>> + num +=1
>> + filepath =
>> output[0].split("(path")[1].split(")")[0].strip()
>> + else:
>> + break
>> + if not dom_active:
>> + break
>> + return num
>> +
>> +def check_block(logger,dom_name,dom_active,dom_eles,backing_f):
>> + """
>> + check the block info, only check count, name and path
>> attributes,
>> + other sub-attributes of block.* will be ignored
>> + """
>> + iDOM_XML = "/etc/libvirt/qemu/" + dom_name +".xml"
>> + aDOM_XML = "/run/libvirt/qemu/" + dom_name +".xml"
>> + disk_index = 0
>> + if dom_active:
>> + xml = minidom.parse(aDOM_XML)
>> + dom = xml.getElementsByTagName('domain')[0]
>> + dev = dom.getElementsByTagName('devices')[0]
>> + disk = dev.getElementsByTagName('disk')
>> + disk_count = len(disk)
>> + for dk in disk:
>> + disk_name = dk.getElementsByTagName('target')[0]\
>> + .getAttributeNode('dev').nodeValue
>> + disk_sour = dk.getElementsByTagName('source')[0]\
>> + .getAttributeNode('file').nodeValue
>> + if backing_f:
>> + disk_count +=
>> count_disk_chain(logger,disk_sour,dom_active)
>> + logger.debug("Checking disk.count: %d" %
>> dom_eles.get("block.count"))
>> + if not
>> compare_value(logger,disk_count,dom_eles.get("block.count")):
>> + return False
>> + if not check_each_block(logger,dom_name,dom_eles,backing_f):
>> + return False
>> + else:
>> + xml = minidom.parse(iDOM_XML)
>> + dev = xml.getElementsByTagName('devices')[0]
>> + disk = dev.getElementsByTagName('disk')
>> + disk_count = len(disk)
>> + logger.debug("Checking disk.count: %d" %
>> dom_eles.get("block.count"))
>> + if not
>> compare_value(logger,disk_count,dom_eles.get("block.count")):
>> + return False
>> + for dk in disk:
>> + disk_pre = "block."+ str(disk_index) + "."
>> + disk_name = dk.getElementsByTagName('target')[0]\
>> + .getAttributeNode('dev').nodeValue
>> + logger.debug("Checking %sname: %s" \
>> + % (disk_pre, dom_eles.get(disk_pre + "name")))
>> + if not compare_value(logger,disk_name,\
>> + dom_eles.get(disk_pre + "name")):
>> + return False
>> + disk_sour = dk.getElementsByTagName('source')[0]\
>> + .getAttributeNode('file').nodeValue
>> + logger.debug("Checking %spath: %s" \
>> + % (disk_pre, dom_eles.get(disk_pre + "path")))
>> + if not compare_value(logger,disk_sour,\
>> + dom_eles.get(disk_pre + "path")):
>> + return False
>> + disk_index += 1
>> + return True
>> +
>> +def check_each_block(logger,dom_name,dom_eles,backing_f):
>> + """
>> + for a active domain, this function will list all backing
>> + block info
>> + """
>> + aDOM_XML = "/run/libvirt/qemu/" + dom_name +".xml"
>> + disk_index = 0
>> + xml = minidom.parse(aDOM_XML)
>> + dom = xml.getElementsByTagName('domain')[0]
>> + dev = dom.getElementsByTagName('devices')[0]
>> + disk = dev.getElementsByTagName('disk')
>> + for dk in disk:
>> + disk_pre = "block."+ str(disk_index) + "."
>> + disk_name = dk.getElementsByTagName('target')[0]\
>> + .getAttributeNode('dev').nodeValue
>> + disk_sour = dk.getElementsByTagName('source')[0]\
>> + .getAttributeNode('file').nodeValue
>> + logger.debug("Checking %s %s" % (disk_name,disk_sour))
>> + if not compare_value(logger,disk_name, \
>> + dom_eles.get(disk_pre + "name")):
>> + return False
>> + if not compare_value(logger,disk_sour, \
>> + dom_eles.get(disk_pre + "path")):
>> + return False
>> + if not backing_f:
>> + disk_index += 1
>> + continue
>> + while True:
>> + temp = dk.getElementsByTagName('backingStore')[0]
>> + if temp.hasChildNodes():
>> + temp_name = disk_name
>> + temp_backingIndex =
>> int(temp.getAttributeNode('index').\
>> + nodeValue)
>> + temp_path = temp.getElementsByTagName('source')[0].\
>> + getAttributeNode('file').nodeValue
>> + logger.debug("Checking %s %s %s" \
>> + % (temp_name, temp_backingIndex, temp_path))
>> + disk_index += 1
>> + disk_pre = "block."+ str(disk_index) + "."
>> + if not compare_value(logger,temp_name, \
>> + dom_eles.get(disk_pre + "name")):
>> + return False
>> + if not compare_value(logger,temp_backingIndex, \
>> + dom_eles.get(disk_pre + "backingIndex")):
>> + return False
>> + if not compare_value(logger,temp_path, \
>> + dom_eles.get(disk_pre + "path")):
>> + return False
>> + else:
>> + break
>> + dk = temp
>> + disk_index += 1
>> + return True
>> +
>> +def connection_getAllDomainStats(params):
>> + """
>> + test API for getAllDomainStats in class virConnect, the
>> script need
>> + static values to compare with those returned by API,but they are
>> + hard to calculate, so ignore below attributes temporarily:
>> + cpu.time
>> + cpu.user
>> + cpu.system
>> + *.*.time
>> + net.*.rx.*
>> + net.*.tx.*
>> + block.*.rd
>> + block.*.wr
>> + block.*.fl
>> + ...
>> + for below two attributes, no good method to obtain values when
>> + out of libvirt, pass them temporarily too.
>> + state.state
>> + state.reason
>> + """
>> + balloon_f = False
>> + vcpu_f = False
>> + interface_f = False
>> + block_f = False
>> + backing_f = False
>> + filter_f = True
>> +
>> + logger = params['logger']
>> + domstats = params.get('stats', "all")
>> + domstats_string = domstats.split("|")
>> + logger.info("The stats are %s" % domstats)
>> + domstats = 0
>> + for domstat in domstats_string:
>> + if domstat == 'state':
>> + domstats |= ds.get('state')
>> + elif domstat == 'cpu':
>> + domstats |= ds.get('cpu')
>> + elif domstat == 'balloon':
>> + domstats |= ds.get('balloon')
>> + balloon_f = True
>> + elif domstat == 'vcpu':
>> + domstats |= ds.get('vcpu')
>> + vcpu_f = True
>> + elif domstat == 'interface':
>> + domstats |= ds.get('interface')
>> + interface_f = True
>> + elif domstat == 'block':
>> + domstats |= ds.get('block')
>> + block_f = True
>> + elif domstat == "all":
>> + domstats = 0
>> + balloon_f = True
>> + vcpu_f = True
>> + interface_f = True
>> + block_f = True
>> + else:
>> + logger.error("Unknown flags")
>> + return 1
>> + logger.info("The given stats is %d" % domstats)
>> +
>> + flags = params.get('flags',"all")
>> + logger.info("The flags are %s" % flags)
>> + flags_string = flags.split("|")
>> + flags = 0
>> + for flag in flags_string:
>> + if flag == 'active':
>> + flags |= fg.get('active')
>> + elif flag == 'inactive':
>> + flags |= fg.get('inactive')
>> + elif flag == 'persistent':
>> + flags |= fg.get('persistent')
>> + elif flag == 'transient':
>> + flags |= fg.get('transient')
>> + elif flag == 'running':
>> + flags |= fg.get('running')
>> + filter_f = False
>> + elif flag == 'paused':
>> + flags |= fg.get('paused')
>> + filter_f = False
>> + elif flag == 'shutoff':
>> + flags |= fg.get('shutoff')
>> + filter_f = False
>> + elif flag == 'other':
>> + flags |= fg.get('other')
>> + filter_f = False
>> + elif flag == 'backing':
>> + flags |= fg.get('backing')
>> + backing_f = True
>> + elif flag == 'enforce':
>> + flags |= fg.get('enforce')
>> + elif flag == 'all':
>> + flags = 0
>> + filter_f = False
>> + else:
>> + logger.error("Unknown flags")
>> + return 1
>> + logger.info("The given flags is %d" % flags)
>> +
>> + try:
>> + conn = sharedmod.libvirtobj['conn']
>> +
>> + domstats_from_api = conn.getAllDomainStats(domstats,flags)
>> + logger.info("Got the number of domain from API: %s" \
>> + % len(domstats_from_api))
>> + #filter expected domains
>> + domains = filer_domains(logger,flags)
>> + if not filter_f:
>> + logger.info("Check the number of domain: Skip")
>> + elif len(domains) == len(domstats_from_api):
>> + logger.info("Available domains: %s" % list(domains))
>> + logger.info("Check the number of domain %s: Pass" \
>> + % len(domstats_from_api))
>> + else:
>> + logger.info("Available domains: %s" % list(domains))
>> + logger.info("Check the number of domain %s: Fail" \
>> + % len(domstats_from_api))
>> + return 1
>> +
>> + for dom in domstats_from_api:
>> + dom_name = dom[0].name()
>> + dom_active = dom[0].isActive()
>> + dom_eles = dom[1]
>> + logger.debug("Domain elements are %s" %(dom_eles))
>> + logger.info("Checking %s:" %(dom_name))
>> + if vcpu_f:
>> + if not check_vcpu(logger,dom_name,dom_active,dom_eles):
>> + logger.info("Failed to check vcpu states")
>> + return 1
>> + else:
>> + logger.info("Success to check vcpu state")
>> + if balloon_f:
>> + if not
>> check_balloon(logger,dom_name,dom_active,dom_eles):
>> + logger.info("Failed to check balloon state")
>> + return 1
>> + else:
>> + logger.info("Success to check balloon state")
>> + if interface_f:
>> + if not
>> check_interface(logger,dom_name,dom_active,dom_eles):
>> + logger.info("Failed to check interface state")
>> + return 1
>> + else:
>> + logger.info("Success to check interface state")
>> + if block_f:
>> + if not check_block(logger,dom_name,dom_active,\
>> + dom_eles,backing_f):
>> + logger.info("Failed to check block state")
>> + return 1
>> + else:
>> + logger.info("Success to check block state")
>> +
>> + except libvirtError, e:
>> + logger.error("API error message: %s" % e.message)
>> + return 1
>> +
>> + return 0
>
More information about the libvir-list
mailing list