[libvirt] [test-API PATCH] repo: Add test for console input and output operations

Guannan Ren gren at redhat.com
Fri Apr 13 13:10:43 UTC 2012


On 04/13/2012 08:54 PM, Martin Kletzander wrote:
> On 04/13/2012 11:41 AM, Peter Krempa wrote:
>> This test checks if the console input and output work as desired. The
>> test takes as an argument a filename, whose contents are sent to the
>> console. The optional parameter 'expect' can be set to a filename that
>> should contain expected output from the guest and is compared with the
>> actual output. The optional parameter 'output' can be set to a filename
>> where the test script saves the output of the host (useful for initial
>> test setup).
>>
>> This test requires that the guest machine runs code that handles input and
>> output on the serial console (programs such as agetty or something like that).
>> ---
>>   repos/domain/console_io.py |  123 ++++++++++++++++++++++++++++++++++++++++++++
>>   1 files changed, 123 insertions(+), 0 deletions(-)
>>   create mode 100644 repos/domain/console_io.py
>>
>> diff --git a/repos/domain/console_io.py b/repos/domain/console_io.py
>> new file mode 100644
>> index 0000000..98fd5b6
>> --- /dev/null
>> +++ b/repos/domain/console_io.py
>> @@ -0,0 +1,123 @@
>> +#!/usr/bin/env python
>> +# test console interactions
>> +# This test sends contents of file 'input' to the guest's console
>> +# and reads from the console the reply and compares it to 'expect' or
>> +# writes the output to file 'output'
>> +
>> +import libvirt
>> +import signal
>> +import os
>> +
>> +from libvirt import libvirtError
>> +from exception import TestError
>> +
>> +required_params = ('guestname',)
>> +optional_params = ('device', 'timeout', 'input', 'output', 'expect',)
>> +
>> +def alarm_handler(signum, frame):
>> +    raise TestError("Timed out while waiting for console")
>> +
>> +def console_io(params):
>> +    """Attach to console"""
>> +    logger = params['logger']
>> +    guest = params['guestname']
>> +    device = params.get('device', 'serial0')
>> +    infile = params.get('input', None)
>> +    outfile = params.get('output', None)
>> +    expect = params.get('expect', None)
>> +    timeout = params.get('timeout', 5)
>> +
>> +    uri = params['uri']
>> +
>> +    #store the old signal handler
>> +    oldhandler = signal.getsignal(signal.SIGALRM)
>> +
>> +    try:
>> +        logger.info("Connecting to hypervisor: '%s'" % uri)
>> +        conn = libvirt.open(uri)
>> +        dom = conn.lookupByName(guest)
>> +        if not dom.isActive():
>> +            raise TestError("Guest '%s' not active" % guest)
>> +
>> +        logger.info("Creating stream object")
>> +        stream = conn.newStream(0)
>> +
>> +        logger.info("Open a new console connection")
>> +        dom.openConsole(device, stream, libvirt.VIR_DOMAIN_CONSOLE_FORCE)
>> +
>> +        if infile != None:
>> +            try:
>> +                f = open(infile, 'r')
>> +                instr = f.read()
>> +                f.close()
>> +            except e:
>> +                raise TestError("Can't read input file '%s': %s" % (infile, str(e)))
>> +
>> +            logger.info("Sending %d bytes of contents of file '%s' to console '%s'" % (len(instr), infile, device))
>> +            stream.send(instr)
>> +
>> +        if expect != None or outfile != None:
>> +            logger.info("Recieving data from console device. Timeout %d seconds." % timeout)
>> +
>> +            # register a new signal handler
>> +            logger.info("Registering custom SIGALRM handler")
>> +            signal.signal(signal.SIGALRM, alarm_handler)
>> +            signal.alarm(timeout)
>> +
>> +            reply = ""
>> +            try:
>> +                while True:
>> +                    recv = stream.recv(1024)
>> +                    reply += recv
>> +            except TestError:
>> +                pass
>> +
>> +            logger.info("Recieved %d bytes." % len(reply))
>> +
>> +            if outfile != None:
>> +                try:
>> +                    f = open(outfile, 'w')
>> +                    f.write(reply)
>> +                    f.close()
>> +                except e:
>> +                    raise TestError("Can't write output to file '%s': %s" % (outfile, str(e)))
>> +
>> +            if expect != None:
>> +                try:
>> +                    f = open(expect, 'r')
>> +                    expectstr = f.read()
>> +                    f.close()
>> +                except Exception, e:
>> +                    raise TestError("Can't read expected output file '%s': '%s'" % (expect, str(e)))
>> +
>> +                if reply.startswith(expectstr):
>> +                    logger.info("Recieved expected output from the host")
>> +                else:
>> +                    raise TestError("Reply from the guest doesn't match with expected reply")
>> +
>> +    except libvirtError, e:
>> +        logger.error("Libvirt call failed: " + str(e))
>> +        ret = 1
>> +
>> +    except TestError, e:
>> +        logger.error("Test failed: " + str(e))
>> +        ret = 1
>> +
>> +    else:
>> +        logger.info("All tests succeeded")
>> +        ret = 0
>> +
>> +    finally:
>> +        logger.info("Restoring signal handler")
>> +        signal.signal(signal.SIGALRM, oldhandler)
>> +        logger.info("Closing hypervisor connection")
>> +        try:
>> +            stream.abort()
>> +        except:
>> +            pass
>> +        conn.close()
>> +
>> +        logger.info("Done")
>> +
>> +    return ret
>> +
> Looks great, ACK.
>
> Martin
>
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list

     Thanks, pushed

      BTW, we don't need _clean function any more if there is nothing to 
clean.
      the TESTCASE_clean function will be optional.

      Guannan Ren




More information about the libvir-list mailing list