[libvirt] [test-API][PATCH] Add managedsave test cases

Guannan Ren gren at redhat.com
Mon Nov 26 13:45:48 UTC 2012


On 11/22/2012 11:56 AM, hongming wrote:
> The managedsave test cases and test suite cover test include
> verifying virsh commands managedsave(include all flags and their
> combination)/managedsave-remove and managedSaveRemove/ManagedSave/
> hasManagedSaveImage python APIs.
> The following new files be created.
> new file: cases/managedsave.conf
> - Test all test cases
> new file: repos/managedsave/__init__.py
> new file: repos/managedsave/managedsave.py
> - Test mangaedsave command/API and all flags
> new file: repos/managedsave/managedsave_remove.py
> - Test managedsave-remove command/API
> new file: repos/managedsave/managedsave_start.py
> - Verfiy managedsave'flags and start from managedsave image
> ---
>   cases/managedsave.conf                  |   63 ++++++++++++
>   repos/managedsave/managedsave.py        |  162 +++++++++++++++++++++++++++++++
>   repos/managedsave/managedsave_remove.py |   61 ++++++++++++
>   repos/managedsave/managedsave_start.py  |  152 +++++++++++++++++++++++++++++
>   4 files changed, 438 insertions(+), 0 deletions(-)
>   create mode 100644 cases/managedsave.conf
>   create mode 100644 repos/managedsave/__init__.py
>   create mode 100644 repos/managedsave/managedsave.py
>   create mode 100644 repos/managedsave/managedsave_remove.py
>   create mode 100644 repos/managedsave/managedsave_start.py
>
> diff --git a/cases/managedsave.conf b/cases/managedsave.conf
> new file mode 100644
> index 0000000..8dcafe2
> --- /dev/null
> +++ b/cases/managedsave.conf
> @@ -0,0 +1,63 @@
> +domain:install_linux_cdrom
> +    guestname
> +        $defaultname
> +    guestos
> +        $defaultos
> +    guestarch
> +        $defaultarch
> +    vcpu
> +        $defaultvcpu
> +    memory
> +        $defaultmem
> +    hddriver
> +        $defaulthd
> +    nicdriver
> +        $defaultnic
> +    imageformat
> +        qcow2
> +    macaddr
> +        54:52:00:4a:16:30
> +
> +#VIR_DOMAIN_SAVE_BYPASS_CACHE = 1
> +#VIR_DOMAIN_SAVE_RUNNING = 2
> +#VIR_DOMAIN_SAVE_PAUSED = 4
> +#No_FLAGS = 0
> +managedsave:managedsave
> +    guestname
> +        $defaultname
> +    flags
> +        1|2
> +
> +managedsave:managedsave_start
> +    guestname
> +        $defaultname
> +    flags
> +        noping
> +
> +managedsave:managedsave
> +    guestname
> +        $defaultname
> +    flags
> +        1|4
> +
> +managedsave:managedsave_start
> +    guestname
> +        $defaultname
> +    flags
> +        noping
> +
> +managedsave:managedsave
> +    guestname
> +        $defaultname
> +    flags
> +        0
> +
> +managedsave:managedsave_remove
> +    guestname
> +        $defaultname
> +
> +managedsave:managedsave_start
> +    guestname
> +        $defaultname
> +    flags
> +        noping
> diff --git a/repos/managedsave/__init__.py b/repos/managedsave/__init__.py
> new file mode 100644
> index 0000000..e69de29
> diff --git a/repos/managedsave/managedsave.py b/repos/managedsave/managedsave.py
> new file mode 100644
> index 0000000..5e7c105
> --- /dev/null
> +++ b/repos/managedsave/managedsave.py
> @@ -0,0 +1,162 @@
> +#!/usr/bin/env python
> +
> +import os
> +import math
> +
> +import libvirt
> +from libvirt import libvirtError
> +
> +from src import sharedmod
> +from utils import utils
> +
> +required_params = ('guestname', 'flags',)
> +optional_params = {}
> +
> +def check_guest_status(*args):
> +    """Check guest current status"""
> +    (domobj, logger) = args
> +    state = domobj.info()[0]
> +    logger.debug("current guest status: %s" % state)
> +
> +    if state == libvirt.VIR_DOMAIN_SHUTOFF or \
> +       state == libvirt.VIR_DOMAIN_SHUTDOWN or \
> +       state == libvirt.VIR_DOMAIN_BLOCKED:
> +        return False
> +    else:
> +        return True
> +
> +def check_savefile_create(*args):
> +    """Check guest's managed save file be created"""
> +
> +    (guestname) = args
> +    cmds = "ls /var/lib/libvirt/qemu/save/%s" % guestname + ".save -lh"
> +    logger.info("Execute cmd  %s" % cmds)
> +    (status, output) = utils.exec_cmd(cmds, shell=True)
> +    if status != 0:
> +        logger.error("No managed save file")
> +        return False
> +    else :
> +        logger.info("managed save file exists")
> +        return True
> +
> +def compare_cachedfile(cachebefore, cacheafter):
> +    """Compare cached value before managed save and its value after
> +    managed save """
> +
> +    diff = cacheafter - cachebefore
> +    logger.info("diff is %s " % diff)
> +    percent = math.fabs(diff)/cachebefore
> +    logger.info("diff percent is %s " % percent)
> +    if math.fabs(diff)/cachebefore < 0.05:

             We get the variable 'percent', we can use it here instead 
of computing it twice.


> +        return True
> +    else:
> +        return False
> +
> +def get_cachevalue():
> +    """Get the file system cached value """
> +
> +    cmds = "head -n4 /proc/meminfo|grep Cached|awk '{print $2}'"
> +    (status, output) = utils.exec_cmd(cmds, shell=True)
> +    if status != 0:
> +        logger.error("failed to run cmd line to get cache")
> +        return 1
> +    else:
> +        logger.debug(output[0])
> +    cachevalue= int(output[0])
> +    return cachevalue
> +
> +def managedsave(params):
> +    """Managed save a running domain"""
> +
> +    global logger
> +    logger = params['logger']
> +    guestname = params['guestname']
> +    flags = params ['flags']
> +    #Save given flags to sharedmod.data
> +    sharedmod.data['flagsave'] = flags
> +
> +    logger.info("The given flags are %s " % flags)
> +    if not '|' in flags:
> +        flagn = int(flags)
> +    else:
> +        flagstr = flags.split('|')
> +        flagcont = ''.join(flagstr)
> +        length = len(flagcont)
> +        # bitwise-OR of flags of managedsave
> +        flagn = int(flagcont[0])
> +        for i in range(0,length-1):
> +            flagn = flagn |int(flagcont[i+1])

        The else branch codes are a little more complicated.
        The following is better I think.
            flaglist = flags.split('|');
            flagn = 0;
            for flag in flaglist:
                flagn |= int(flag)



> +
> +    conn = sharedmod.libvirtobj['conn']
> +    domobj = conn.lookupByName(guestname)
> +
> +    if not check_guest_status(domobj, logger):
> +        logger.error("Error: current guest status is shutoff")

          We can omit the "Error" string in the logger.error("...")

> +        return 1
> +
> +    try:
> +
> +        logger.info("bitwise OR value of flags is %s" % flagn)
> +
> +        if flagn == 0:
> +            logger.info("managedsave %s domain with no flag" % guestname)
> +        elif flagn == 1:
> +            logger.info("managedsave %s domain --bypass-cache" % guestname)
> +        elif flagn == 2:
> +            logger.info("managedsave %s domain --running" % guestname)
> +        elif flagn == 3:
> +            logger.info("managedsave %s domain --running --bypass-cache"\
> +                         % guestname)
> +        elif flagn == 4:
> +            logger.info("managedsave %s domain --paused" % guestname)
> +        elif flagn == 5:
> +            logger.info("managedsave %s domain --paused --bypass-cache"\
> +                         % guestname)
> +        elif flagn == 6:
> +            logger.error("Error:--running and --paused are mutually exclusive")

                 The same.

> +            return 1
> +        elif flagn == 7:
> +            logger.error("Error:--running and --paused are mutually exclusive")

                 The same.

> +            return 1
> +        else:
> +            logger.error("Error:Wrong flags be given and fail to \
> +            managedsave domain")

                The same.

> +            return 1
> +
> +        #If given flags include bypass-cache,check if bypass file system cache
> +        if flagn %2 == 1:

               Add a space between "%": if flagn % 2 == 1

> +            logger.info("Given flags include --bypass-cache")
> +            os.system('echo 3 > /proc/sys/vm/drop_caches')
> +            cache_before = get_cachevalue()
> +            logger.info("Cached value before managedsave is %s" % cache_before)
> +
> +            domobj.managedSave(flagn)
> +
> +            cache_after = get_cachevalue()
> +            logger.info("Cached value after managedsave is %s" % cache_after)
> +
> +            if compare_cachedfile(cache_before, cache_after):
> +                logger.info("Bypass file system cache successfully")
> +            else:
> +                logger.error("Bypass file system cache failed")
> +                return 1
> +        else:
> +            domobj.managedSave(flagn)
> +
> +        #Check if domain has managedsave image
> +        if  domobj.hasManagedSaveImage(0) and \
> +            domobj.info()[0]==libvirt.VIR_DOMAIN_SHUTOFF and \
> +            check_savefile_create(guestname):
> +            logger.info("Domain %s managedsave successfully " % guestname)
> +        else:
> +            logger.error("Error: fail to managedsave domain")

                 The same

>       
> +            return 1
> +
> +    except libvirtError, e:
> +        logger.error("API error message: %s, error code is %s" \
> +                     % e.message)
> +        logger.error("Error: fail to managedsave %s domain" % guestname)
> +        return 1
> +
> +    return 0
> +
> diff --git a/repos/managedsave/managedsave_remove.py b/repos/managedsave/managedsave_remove.py
> new file mode 100644
> index 0000000..143312f
> --- /dev/null
> +++ b/repos/managedsave/managedsave_remove.py
> @@ -0,0 +1,61 @@
> +#!/usr/bin/env python
> +# Save domain as a statefile
> +
> +import libvirt
> +from libvirt import libvirtError
> +
> +from src import sharedmod
> +from utils import utils
> +
> +required_params = ('guestname',)
> +optional_params = {}
> +
> +def check_savefile_remove(*args):
> +    """Check if guest's managedsave file be removed """
> +
> +    (guestname) = args
> +    cmds = "ls /var/lib/libvirt/qemu/save/%s" % guestname + ".save -lh"
> +    logger.info("Execute cmd  %s" % cmds)
> +    (status, output) = utils.exec_cmd(cmds, shell=True)
> +    if status != 0:
> +        logger.info("No managed save file")
> +        return True
> +    else :
> +        logger.error("managed save file exits")
> +        return False
> +
> +
> +def managedsave_remove(params):
> +    """Remove an existing managed save state file from a domain"""
> +
> +    global logger
> +    logger = params['logger']
> +    guestname = params['guestname']
> +
> +    conn = sharedmod.libvirtobj['conn']
> +    domobj = conn.lookupByName(guestname)
> +
> +    if not domobj.hasManagedSaveImage(0) and check_savefile_remove(guestname):
> +        logger.info("Domain %s hasn't managedsave image" % guestname)

             logger.error("...")

> +        return 1
> +    else:
> +        logger.info("Domain %s has managedsave image" % guestname)
> +
> +    try:
> +        domobj.managedSaveRemove(0)
> +        #Check if domain has managedsave image
> +        if not domobj.hasManagedSaveImage(0) and \
> +           check_savefile_remove(guestname):
> +            logger.info("Domain %s's managedsave image has been removed"\
> +                         % guestname)
> +        else:
> +            logger.error("Error: fail to remove managedsave domain")
> +            return 1
> +
> +    except libvirtError, e:
> +        logger.error("API error message: %s, error code is %s" % e.message)
> +        logger.error("Error: fail to managedsave %s domain" % guestname)
> +        return 1
> +
> +    return 0
> +
> diff --git a/repos/managedsave/managedsave_start.py b/repos/managedsave/managedsave_start.py
> new file mode 100644
> index 0000000..f5da0b3
> --- /dev/null
> +++ b/repos/managedsave/managedsave_start.py
> @@ -0,0 +1,152 @@
> +#!/usr/bin/env python
> +
> +import time
> +
> +import libvirt
> +from libvirt import libvirtError
> +
> +from src import sharedmod
> +from utils import utils
> +
> +required_params = ('guestname',)
> +optional_params = {'flags' : ''}
> +
> +NONE = 0
> +START_PAUSED = 1
> +START_BYPASS_CACHE = 4
> +START_FORCE_BOOT = 8
> +
> +def check_savefile_remove(*args):
> +    """Check guest managed save file"""
> +    (guestname) = args
> +    cmds = "ls /var/lib/libvirt/qemu/save/%s" % guestname + ".save -lh"
> +    logger.info("Execute cmd  %s" % cmds)
> +    (status, output) = utils.exec_cmd(cmds, shell=True)
> +    if status != 0:
> +        logger.info("No managed save file")
> +        return True
> +    else :
> +        logger.error("managed save file exists")
> +        return False
> +
> +def managedsave_start(params):
> +    """ Start domain with managedsave image and check if its status is rigth

                 s/rigth/right

> +        according to given flags of running managedsave command.If it is
> +        correctly paused , resume it.
> +
> +        Argument is a dictionary with two keys:
> +        {'logger': logger, 'guestname': guestname}
> +
> +        logger -- an object of utils/log.py
> +        mandatory arguments : guestname -- same as the domain name
> +        optional arguments : flags -- domain create flags <none|start_paused
> +        |noping>.It allows only one flag be given.
> +
> +        Return 0 on SUCCESS or 1 on FAILURE
> +    """
> +    domname = params['guestname']
> +    global logger
> +    logger = params['logger']
> +    flags = params.get('flags', '')
> +    # Get given flags of managedsave
> +    if sharedmod.data.has_key('flagsave'):
> +        flagsave = sharedmod.data.get('flagsave')
> +    else:
> +        logger.error("Failed to get flags from managedsave")
> +    # Clean sharedmod.data
> +    sharedmod.data = {}
> +
> +    conn = sharedmod.libvirtobj['conn']
> +    domobj = conn.lookupByName(domname)
> +
> +    timeout = 600
> +    logger.info('start domain')
> +    # Check if guest has managedsave image before start
> +    if domobj.hasManagedSaveImage(0) :
> +        logger.info("Domain has managedsave image")
> +    else:
> +        logger.info("Domain hasn't managedsave image")
> +
> +    try:
> +        if "none" in flags:
> +            domobj.createWithFlags(NONE)
> +        elif "start_paused" in flags:
> +            domobj.createWithFlags(START_PAUSED)
> +        else:
> +            # this covers flags = None as well as flags = 'noping'
> +            domobj.create()
> +    except libvirtError, e:
> +        logger.error("API error message: %s, error code is %s" \
> +                     % e.message)
> +        logger.error("start failed")
> +        return 1
> +
> +    while timeout:
> +        state = domobj.info()[0]
> +        expect_states = [libvirt.VIR_DOMAIN_RUNNING,libvirt.VIR_DOMAIN_PAUSED,\
> +                         libvirt.VIR_DOMAIN_NOSTATE,libvirt.VIR_DOMAIN_BLOCKED]
> +
> +        if state in expect_states:
> +            break
> +
> +        time.sleep(10)
> +        timeout -= 10
> +        logger.info(str(timeout) + "s left")
> +
> +    if timeout <= 0:
> +        logger.error('The domain state is not as expected, state: ' + state)
> +        return 1
> +
> +    logger.info("Guest started")
> +
> +    """If domain's current state is paused. Check if start command has
> +    --paused flag or managedsave has --paused flag (given flags in managedsave
> +    include '4'). If yes, it means domain successfully paused , then resume it.
> +    If not, throw error -guest state error."""
> +
> +    if state == libvirt.VIR_DOMAIN_PAUSED:
> +        if "start_paused" in flags or "4" in flagsave:
> +            logger.info("Guest paused successfully ")
> +
> +            try:
> +                domobj.resume()
> +
> +            except libvirtError, e:
> +                logger.error("API error message: %s, error code is %s" \
> +                     % e.message)
> +                logger.error("resume failed")
> +                return 1
> +            stateresume = domobj.info()[0]
> +            expect_states = [libvirt.VIR_DOMAIN_RUNNING, \
> +                             libvirt.VIR_DOMAIN_NOSTATE, \
> +                             libvirt.VIR_DOMAIN_BLOCKED]
> +            if stateresume not in expect_states:
> +                logger.error('The domain state is not equal to "paused"')
> +                return 1
> +            else:
> +                logger.info('Domain resume successfully')
> +            return 0
> +        else:
> +            logger.error("guest state error")
> +            return 1
> +
> +    # Get domain ip and ping ip to check domain's status
> +    if not "noping" in flags:
> +        mac = utils.get_dom_mac_addr(domname)
> +        logger.info("get ip by mac address")
> +        ip = utils.mac_to_ip(mac, 180)
> +
> +        logger.info('ping guest')
> +        if not utils.do_ping(ip, 300):
> +            logger.error('Failed on ping guest, IP: ' + str(ip))
> +            return 1
> +
> +    # Check if domain' managedsave image exists,if not, return 0.
> +    if not domobj.hasManagedSaveImage(0) and check_savefile_remove(domname):
> +        logger.info("Domain %s with managedsave image successfully start" \
> +                    % domname)
> +        return 0
> +    else:
> +        logger.info("Failed to start domain s% with managedsave image" \
> +                    % domname)

           logger.error("...")

>         
> +        return 1

          After I ran these testcases, they are good for me except spots 
above I commented on.
          Another thing you should note  is to remove trailing spaces in 
codes.
          Appending the following two lines into /etc/vimrc could 
highlights them, then remove them.
             "highlight RedundantSpaces ctermbg=red guibg=red
              match RedundantSpaces /\s\+$\| \+\ze\t/
             "
          Please send v2, thanks.

          Guannan




More information about the libvir-list mailing list