Re: [KVM-AUTOTEST][PATCH 1/2][virtio-console] Add subtest layer and prepare to add new tests.

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

 



----- "Lucas Meneghel Rodrigues" <lmr@xxxxxxxxxx> wrote:

> On Mon, 2010-11-22 at 14:38 +0100, JiÅÃ Åupka wrote: 
> > This patch changes structure of the virtio_console test and
> > prepares this test for simpler porting of another required tests.
> > 
> > It creates a new layer for running the elementary tests allowing 
> > them to non-critically fail and let the test to finish the whole
> test loop.
> 
> ^ I must say I really liked the idea. We should turn this into
> framework
> infrastructure to accomodate some requests I've got. Putting it on my
> todo list.

Thank you. I can prepare patch for autotest if you don't want do much 
changes in subtest layer. Subtest layer is prepared for separate from 
virtio_test and there should't be any problem with separate. 

Do you want add subtest layer to kvm_autotest or to autotest client part? 

> 
> Meanwhile, I've respin the patches you guys sent and applied:
> 
> http://autotest.kernel.org/changeset/4949
> http://autotest.kernel.org/changeset/4950
> 
> Thanks!
> 
> > Tests are divided into parts but their behavior is preserved.
> > The patch also includes some code correction.
> > 
> > Class which makes statistic and start subtest is named SubTest.
> > Usage:
> >   def test_func(parma1, param2):
> >     if somethink:
> >         raise error.TestFail("Somethink")
> > 
> >   def clean_func(param1, param2, param3):
> >     clean
> > 
> >   test = SubTest()
> > 
> >   #set cleanup function when subtest crash.
> >   test.set_cleanup_func(clean_func, [param1, param2, ..])
> > 
> >   #start test
> >   test.do_test(test_func,[params..])
> >   test.do_test(test_func,[params..],true)
> >                                    ^^^^ - test is critical.
> > 
> >   #return statistic
> >   print test.get_text_result()
> > 
> > if any non-critical subtests fails the particular test finishes and
> calls
> > the clean-up function. Then the test-loop continues with the next
> > elementary subtest. Although SubTest class displays information
> > about the subtest problem. If the clean-up function also failed or
> > subtest was critical, then the whole test will be interrupted.
> > 
> > At the end of the test-loop it summarizes the passed/failed tests
> and
> > print out the possible subtest trace-backs.
> > ---
> >  client/tests/kvm/scripts/virtio_guest.py |  113 +++--
> >  client/tests/kvm/tests/virtio_console.py |  941
> ++++++++++++++++++------------
> >  2 files changed, 638 insertions(+), 416 deletions(-)
> > 
> > diff --git a/client/tests/kvm/scripts/virtio_guest.py
> b/client/tests/kvm/scripts/virtio_guest.py
> > index 4862ef2..87727c7 100755
> > --- a/client/tests/kvm/scripts/virtio_guest.py
> > +++ b/client/tests/kvm/scripts/virtio_guest.py
> > @@ -3,35 +3,23 @@
> >  """
> >  Auxiliary script used to send data between ports on guests.
> >  
> > -@copyright: 2008-2009 Red Hat Inc.
> > +@copyright: 2010 Red Hat, Inc.
> >  @author: Jiri Zupka (jzupka@xxxxxxxxxx)
> >  @author: Lukas Doktor (ldoktor@xxxxxxxxxx)
> >  """
> > -#from _pydev_SimpleXMLRPCServer import fcntl
> > -
> > -"""
> > -TODO:
> > -virt.init([consoles])   # sysfs, udev, OK
> > -virt.open(name)
> > -virt.close(name)
> > -virt.poll(name, eventmask, timeout) # poll.register(),
> poll.poll(),
> > -return event
> > -virt.send(name, length) # host disconnected
> > -virt.recv(name, length) # host disconnected
> > -virt.blocking(name, true)   # true = blocking, false = nonblocking
> > -virt.loopback(in_names, out_names, type="None")  # use select/poll
> > -"""
> > -
> >  import threading
> >  from threading import Thread
> > -import os, time, select, re, random, sys, array, fcntl, array,
> subprocess
> > +import os, time, select, re, random, sys, array
> > +import fcntl, array, subprocess, traceback
> >  
> >  DEBUGPATH = "/sys/kernel/debug"
> >  SYSFSPATH = "/sys/class/virtio-ports/"
> >  
> > 
> > -class virtio_guest():
> > -
> > +class VirtioGuest:
> > +    """
> > +    Test tools of virtio_ports.
> > +    """
> >      LOOP_NONE = 0
> >      LOOP_POLL = 1
> >      LOOP_SELECT = 2
> > @@ -125,7 +113,7 @@ class virtio_guest():
> >          print "PASS: Init and check virtioconsole files in
> system."
> >  
> > 
> > -    class switch(Thread):
> > +    class Switch(Thread):
> >          """
> >          Thread that sends data between ports.
> >          """
> > @@ -137,7 +125,7 @@ class virtio_guest():
> >              @param method: Method of read/write access.
> >              @param cachesize: Block to receive and send.
> >              """
> > -            Thread.__init__(self)
> > +            Thread.__init__(self, name="Switch")
> >  
> >              self.in_files = in_files
> >              self.out_files = out_files
> > @@ -211,15 +199,15 @@ class virtio_guest():
> >  
> > 
> >          def run(self):
> > -            if (self.method == virtio_guest.LOOP_POLL):
> > +            if (self.method == VirtioGuest.LOOP_POLL):
> >                  self._poll_mode()
> > -            elif (self.method == virtio_guest.LOOP_SELECT):
> > +            elif (self.method == VirtioGuest.LOOP_SELECT):
> >                  self._select_mode()
> >              else:
> >                  self._none_mode()
> >  
> > 
> > -    class sender(Thread):
> > +    class Sender(Thread):
> >          """
> >          Creates a thread which sends random blocks of data to dst
> port.
> >          """
> > @@ -228,7 +216,7 @@ class virtio_guest():
> >              @param port: Destination port
> >              @param length: Length of the random data block
> >              """
> > -            Thread.__init__(self)
> > +            Thread.__init__(self, name="Sender")
> >              self.port = port
> >              self.exit_thread = event
> >              self.data = array.array('L')
> > @@ -296,7 +284,20 @@ class virtio_guest():
> >          if (mask[0][1] & expected) == expected:
> >              print "PASS: Events: " + str
> >          else:
> > -            print "FAIL: Events: " + str
> > +            estr = ""
> > +            if (expected & select.POLLIN):
> > +                estr += "IN "
> > +            if (expected & select.POLLPRI):
> > +                estr += "PRI IN "
> > +            if (expected & select.POLLOUT):
> > +                estr += "OUT "
> > +            if (expected & select.POLLERR):
> > +                estr += "ERR "
> > +            if (expected & select.POLLHUP):
> > +                estr += "HUP "
> > +            if (expected & select.POLLMSG):
> > +                estr += "MSG "
> > +            print "FAIL: Events: " + str + "  Expected: " + estr
> >  
> > 
> >      def blocking(self, port, mode=False):
> > @@ -306,8 +307,7 @@ class virtio_guest():
> >          @param port: port to set mode
> >          @param mode: False to set nonblock mode, True for block
> mode
> >          """
> > -        path = self.ports[port]["path"]
> > -        fd = self.files[path]
> > +        fd = self._open([port])[0]
> >  
> >          try:
> >              fl = fcntl.fcntl(fd, fcntl.F_GETFL)
> > @@ -336,24 +336,28 @@ class virtio_guest():
> >              if path in self.files.keys():
> >                  descriptor = self.files[path]
> >                  del self.files[path]
> > -        try:
> > -            os.close(descriptor)
> > -        except Exception as inst:
> > -            print "FAIL: Closing the file: " + str(inst)
> > -            return
> > +            if descriptor != None:
> > +                try:
> > +                    os.close(descriptor)
> > +                except Exception as inst:
> > +                    print "FAIL: Closing the file: " + str(inst)
> > +                    return
> >          print "PASS: Close"
> >  
> > 
> > -    def open(self, in_files):
> > +    def open(self, in_file):
> >          """
> >          Direct open devices.
> >  
> > -        @param in_files: Array of files.
> > +        @param in_file: Array of files.
> >          @return: Array of descriptors.
> >          """
> > -        name = self.ports[in_files]["path"]
> > +        name = self.ports[in_file]["path"]
> >          try:
> >              self.files[name] = os.open(name, os.O_RDWR)
> > +            if (self.ports[in_file]["is_console"] == "yes"):
> > +                print os.system("stty -F %s raw -echo" % (name))
> > +                print os.system("stty -F %s -a" % (name))
> >              print "PASS: Open all filles correctly."
> >          except Exception as inst:
> >              print "%s\nFAIL: Failed open file %s" % (str(inst),
> name)
> > @@ -374,7 +378,7 @@ class virtio_guest():
> >          in_f = self._open(in_files)
> >          out_f = self._open(out_files)
> >  
> > -        s = self.switch(in_f, out_f, self.exit_thread, cachesize,
> mode)
> > +        s = self.Switch(in_f, out_f, self.exit_thread, cachesize,
> mode)
> >          s.start()
> >          self.threads.append(s)
> >          print "PASS: Start switch"
> > @@ -412,7 +416,7 @@ class virtio_guest():
> >          self.ports = self._get_port_status()
> >          in_f = self._open([port])
> >  
> > -        self.threads.append(self.sender(in_f[0], self.exit_thread,
> length))
> > +        self.threads.append(self.Sender(in_f[0], self.exit_thread,
> length))
> >          print "PASS: Sender prepare"
> >  
> > 
> > @@ -484,6 +488,28 @@ class virtio_guest():
> >                     (length, len(recvs)))
> >  
> > 
> > +    def clean_port(self, port, buffer=1024):
> > +        in_f = self._open([port])
> > +        ret = select.select([in_f[0]], [], [], 1.0)
> > +        buf = ""
> > +        if ret[0]:
> > +            buf = os.read(in_f[0], buffer)
> > +        print ("PASS: Rest in socket: " + buf)
> > +
> > +
> > +def is_alive():
> > +    """
> > +    Check is only main thread is alive and if guest react.
> > +    """
> > +    if threading.activeCount() == 1:
> > +        print ("PASS: Guest is ok no thread alive")
> > +    else:
> > +        threads = ""
> > +        for thread in threading.enumerate():
> > +            threads += thread.name + ", "
> > +        print ("FAIL: On guest run thread. Active thread:" +
> threads)
> > +
> > +
> >  def compile():
> >      """
> >      Compile virtio_guest.py to speed up.
> > @@ -501,12 +527,19 @@ def main():
> >      if (len(sys.argv) > 1) and (sys.argv[1] == "-c"):
> >          compile()
> >  
> > -    virt = virtio_guest()
> > +    virt = VirtioGuest()
> >      print "PASS: Start"
> >  
> >      while True:
> >          str = raw_input()
> > -        exec str
> > +        try:
> > +            exec str
> > +        except:
> > +            exc_type, exc_value, exc_traceback = sys.exc_info()
> > +            print "On Guest exception from: \n" + "".join(
> > +                                   
> traceback.format_exception(exc_type,
> > +                                                              
> exc_value,
> > +                                                              
> exc_traceback))
> >  
> > 
> >  if __name__ == "__main__":
> > diff --git a/client/tests/kvm/tests/virtio_console.py
> b/client/tests/kvm/tests/virtio_console.py
> > index aa668e1..d69c0a5 100644
> > --- a/client/tests/kvm/tests/virtio_console.py
> > +++ b/client/tests/kvm/tests/virtio_console.py
> > @@ -1,15 +1,16 @@
> >  """
> >  virtio_console test
> >  
> > -@copyright: Red Hat 2010
> > +@copyright: 2010 Red Hat, Inc.
> >  """
> >  import array, logging, os, random, re, select, shutil, socket, sys,
> tempfile
> > -import threading, time
> > +import threading, time, traceback
> >  from collections import deque
> >  from threading import Thread
> >  
> >  import kvm_subprocess, kvm_test_utils, kvm_utils,
> kvm_preprocessing
> >  from autotest_lib.client.common_lib import error
> > +from autotest_lib.client.bin import utils
> >  
> > 
> >  def run_virtio_console(test, params, env):
> > @@ -30,7 +31,194 @@ def run_virtio_console(test, params, env):
> >      @param params: Dictionary with the test parameters
> >      @param env: Dictionary with test environment
> >      """
> > -    class th_send(Thread):
> > +    class SubTest(object):
> > +        """
> > +        Collect result of subtest of main test.
> > +        """
> > +        def __init__(self):
> > +            """
> > +            Initialize object
> > +            """
> > +            self.result = []
> > +            self.passed = 0
> > +            self.failed = 0
> > +            self.cleanup_func = None
> > +            self.cleanup_args = None
> > +
> > +
> > +        def set_cleanup_func(self, func, args):
> > +            """
> > +            Set cleanup function which is called when subtest
> fails.
> > +
> > +            @param func: Function which should be called when test
> fails.
> > +            @param args: Arguments of cleanup function.
> > +            """
> > +            self.cleanup_func = func
> > +            self.cleanup_args = args
> > +
> > +
> > +        def do_test(self, function, args=None, fatal=False,
> cleanup=True):
> > +            """
> > +            Execute subtest function.
> > +
> > +            @param function: Object of function.
> > +            @param args: List of arguments of function.
> > +            @param fatal: If true exception is forwarded to main
> test.
> > +            @return: Return what returned executed subtest.
> > +            @raise TestError: If collapse of test is fatal raise
> forward
> > +                        exception from subtest.
> > +            """
> > +            if args == None:
> > +                args = []
> > +            try:
> > +                logging.debug("Start test %s." %
> function.func_name)
> > +                ret = function(*args)
> > +                logging.info(self.result_to_string((True,
> function.func_name,
> > +                                                    args)))
> > +                self.result.append((True, function.func_name,
> args))
> > +                self.passed += 1
> > +                return ret
> > +            except:
> > +                exc_type, exc_value, exc_traceback =
> sys.exc_info()
> > +                logging.error("In function (" + function.func_name
> + "):")
> > +                logging.error("Call from:\n" +
> > +                              traceback.format_stack()[-2][:-1])
> > +                logging.error("Exception from:\n" +
> > +                              "".join(traceback.format_exception(
> > +                                                        exc_type,
> exc_value,
> > +                                                       
> exc_traceback.tb_next)))
> > +                #Clean up environment after subTest crash
> > +                if cleanup:
> > +                    self.cleanup_func(*self.cleanup_args)
> > +                logging.info(self.result_to_string((False,
> function.func_name,
> > +                                                    args)))
> > +                self.result.append((False, function.func_name,
> args))
> > +                self.failed += 1
> > +                if fatal:
> > +                    raise
> > +
> > +
> > +        def is_failed(self):
> > +            """
> > +            @return: If any of subtest not pass return True.
> > +            """
> > +            return True if self.failed > 0 else False
> > +
> > +        def get_result(self):
> > +            """
> > +            @return: Result of subtests.
> > +               Format:
> > +                 tuple(pass/fail,function_name,call_arguments)
> > +            """
> > +            return self.result
> > +
> > +
> > +        def result_to_string_debug(self, result):
> > +            """
> > +            @param result: Result of test.
> > +            """
> > +            sargs = ""
> > +            for arg in result[2]:
> > +                sargs += str(arg) + ","
> > +            sargs = sargs[:-1]
> > +            return ("Subtest (%s(%s)):  -->%s") % (result[1],
> sargs,
> > +                                             "PASS"if result[0]
> else "FAIL")
> > +
> > +
> > +        def result_to_string(self, result):
> > +            """
> > +            @param result: Result of test.
> > +            """
> > +            return ("Subtest (%s):  -->%s") % (result[1], "PASS"if
> result[0]
> > +                                                               else
> "FAIL")
> > +
> > +
> > +        def get_full_text_result(self):
> > +            """
> > +            @return string with text form of result
> > +            """
> > +            result = ""
> > +            for res in self.result:
> > +                result += self.result_to_string_debug(res) + "\n"
> > +            return result
> > +
> > +
> > +        def get_text_result(self):
> > +            """
> > +            @return string with text form of result
> > +            """
> > +            result = ""
> > +            for res in self.result:
> > +                result += self.result_to_string(res) + "\n"
> > +            return result
> > +
> > +
> > +    class Port(object):
> > +        """
> > +        Define structure to keep information about used port.
> > +        """
> > +        def __init__(self, sock, name, port_type, path):
> > +            """
> > +            @param vm: virtual machine object that port owned
> > +            @param sock: Socket of port if port is open.
> > +            @param name: Name of port for guest side.
> > +            @param port_type: Type of port yes = console, no=
> serialport.
> > +            @param path: Path to port on host side.
> > +            """
> > +            self.sock = sock
> > +            self.name = name
> > +            self.port_type = port_type
> > +            self.path = path
> > +            self.is_open = False
> > +
> > +
> > +        def for_guest(self):
> > +            """
> > +            Format data for communication with guest side.
> > +            """
> > +            return [self.name, self.port_type]
> > +
> > +
> > +        def open(self):
> > +            """
> > +            Open port on host side.
> > +            """
> > +            self.sock = socket.socket(socket.AF_UNIX,
> socket.SOCK_STREAM)
> > +            self.sock.connect(self.path)
> > +            self.is_open = True
> > +
> > +
> > +        def clean_port(self):
> > +            """
> > +            Clean all data from opened port on host side.
> > +            """
> > +            if self.is_open:
> > +                self.close()
> > +            self.open()
> > +            ret = select.select([self.sock], [], [], 1.0)
> > +            if ret[0]:
> > +                buf = self.sock.recv(1024)
> > +                logging.debug("Rest in socket: " + buf)
> > +
> > +
> > +        def close(self):
> > +            """
> > +            Close port.
> > +            """
> > +            self.sock.shutdown(socket.SHUT_RDWR)
> > +            self.sock.close()
> > +            self.is_open = False
> > +
> > +
> > +        def __str__(self):
> > +            """
> > +            Convert to text.
> > +            """
> > +            return ("%s,%s,%s,%s,%d" % ("Socket", self.name,
> self.port_type,
> > +                                        self.path, self.is_open))
> > +
> > +
> > +    class ThSend(Thread):
> >          """
> >          Random data sender thread.
> >          """
> > @@ -53,14 +241,14 @@ def run_virtio_console(test, params, env):
> >  
> > 
> >          def run(self):
> > -            logging.debug("th_send %s: run", self.getName())
> > +            logging.debug("ThSend %s: run", self.getName())
> >              while not self.exitevent.isSet():
> >                  self.idx += self.port.send(self.data)
> > -            logging.debug("th_send %s: exit(%d)", self.getName(),
> > +            logging.debug("ThSend %s: exit(%d)", self.getName(),
> >                            self.idx)
> >  
> > 
> > -    class th_send_check(Thread):
> > +    class ThSendCheck(Thread):
> >          """
> >          Random data sender thread.
> >          """
> > @@ -85,7 +273,7 @@ def run_virtio_console(test, params, env):
> >  
> > 
> >          def run(self):
> > -            logging.debug("th_send_check %s: run", self.getName())
> > +            logging.debug("ThSendCheck %s: run", self.getName())
> >              too_much_data = False
> >              while not self.exitevent.isSet():
> >                  # FIXME: workaround the problem with qemu-kvm stall
> when too
> > @@ -109,14 +297,14 @@ def run_virtio_console(test, params, env):
> >                          idx = self.port.send(buf)
> >                          buf = buf[idx:]
> >                          self.idx += idx
> > -            logging.debug("th_send_check %s: exit(%d)",
> self.getName(),
> > +            logging.debug("ThSendCheck %s: exit(%d)",
> self.getName(),
> >                            self.idx)
> >              if too_much_data:
> > -                logging.error("th_send_check: workaround the
> 'too_much_data'"
> > +                logging.error("ThSendCheck: workaround the
> 'too_much_data'"
> >                                "bug")
> >  
> > 
> > -    class th_recv(Thread):
> > +    class ThRecv(Thread):
> >          """
> >          Recieves data and throws it away.
> >          """
> > @@ -134,7 +322,7 @@ def run_virtio_console(test, params, env):
> >              self.blocklen = blocklen
> >              self.idx = 0
> >          def run(self):
> > -            logging.debug("th_recv %s: run", self.getName())
> > +            logging.debug("ThRecv %s: run", self.getName())
> >              while not self.exitevent.isSet():
> >                  # TODO: Workaround, it didn't work with select :-/
> >                  try:
> > @@ -142,10 +330,10 @@ def run_virtio_console(test, params, env):
> >                  except socket.timeout:
> >                      pass
> >              self.port.settimeout(self._port_timeout)
> > -            logging.debug("th_recv %s: exit(%d)", self.getName(),
> self.idx)
> > +            logging.debug("ThRecv %s: exit(%d)", self.getName(),
> self.idx)
> >  
> > 
> > -    class th_recv_check(Thread):
> > +    class ThRecvCheck(Thread):
> >          """
> >          Random data receiver/checker thread.
> >          """
> > @@ -165,10 +353,10 @@ def run_virtio_console(test, params, env):
> >  
> > 
> >          def run(self):
> > -            logging.debug("th_recv_check %s: run", self.getName())
> > +            logging.debug("ThRecvCheck %s: run", self.getName())
> >              while not self.exitevent.isSet():
> >                  ret = select.select([self.port], [], [], 1.0)
> > -                if ret and (not self.exitevent.isSet()):
> > +                if ret[0] and (not self.exitevent.isSet()):
> >                      buf = self.port.recv(self.blocklen)
> >                      if buf:
> >                          # Compare the recvd data with the control
> data
> > @@ -186,156 +374,13 @@ def run_virtio_console(test, params, env):
> >                                  for buf in self.buffer:
> >                                      ch_ += buf
> >                                  logging.error("Queue = %s",
> repr(ch_))
> > -                                raise
> error.TestFail("th_recv_check: incorrect "
> > +                                raise error.TestFail("ThRecvCheck:
> incorrect "
> >                                                       "data")
> >                          self.idx += len(buf)
> > -            logging.debug("th_recv_check %s: exit(%d)",
> self.getName(),
> > +            logging.debug("ThRecvCheck %s: exit(%d)",
> self.getName(),
> >                            self.idx)
> >  
> > 
> > -    class cpu_load():
> > -        """
> > -        Get average cpu load between start and get_load.
> > -        """
> > -        def __init__ (self):
> > -            self.old_load = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
> > -            self.startTime = 0
> > -            self.endTime = 0
> > -
> > -
> > -        def _get_cpu_load(self):
> > -            # Let's see if we can calc system load.
> > -            try:
> > -                f = open("/proc/stat", "r")
> > -                tmp = f.readlines(200)
> > -                f.close()
> > -            except:
> > -                logging.critical("Error reading /proc/stat")
> > -                error.TestFail("average_cpu_load: Error reading
> /proc/stat")
> > -
> > -            # 200 bytes should be enough because the information we
> need
> > -            # is typically stored in the first line
> > -            # Info about individual processors (not yet supported)
> is in
> > -            # the second (third, ...?) line
> > -            for line in tmp:
> > -                if line[0:4] == "cpu ":
> > -                    reg = re.compile('[0-9]+')
> > -                    load_values = reg.findall(line)
> > -                    # extract values from /proc/stat
> > -                    load = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
> > -                    for i in range(8):
> > -                        load[i] = int(load_values[i]) -
> self.old_load[i]
> > -
> > -                    for i in range(8):
> > -                        self.old_load[i] = int(load_values[i])
> > -                    return load
> > -
> > -
> > -        def start (self):
> > -            """
> > -            Start CPU usage measurement
> > -            """
> > -            self.old_load = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
> > -            self.startTime = time.time()
> > -            self._get_cpu_load()
> > -
> > -
> > -        def get_load(self):
> > -            """
> > -            Get and reset CPU usage
> > -
> > -            @return: return group cpu (user[%], system[%], sum[%],
> testTime[s])
> > -            """
> > -            self.endTime = time.time()
> > -            testTime = self.endTime - self.startTime
> > -            load = self._get_cpu_load()
> > -
> > -            user = load[0] / testTime
> > -            system = load[2] / testTime
> > -            sum = user + system
> > -
> > -            return (user, system, sum, testTime)
> > -
> > -
> > -    class pid_load():
> > -        """
> > -        Get average process cpu load between start and get_load
> > -        """
> > -        def __init__ (self, pid, name):
> > -            self.old_load = [0, 0]
> > -            self.startTime = 0
> > -            self.endTime = 0
> > -            self.pid = pid
> > -            self.name = name
> > -
> > -
> > -        def _get_cpu_load(self, pid):
> > -            # Let's see if we can calc system load.
> > -            try:
> > -                f = open("/proc/%d/stat" % (pid), "r")
> > -                line = f.readline()
> > -                f.close()
> > -            except:
> > -                logging.critical("Error reading /proc/%d/stat",
> pid)
> > -                error.TestFail("average_process_cpu_load: Error
> reading "
> > -                               "/proc/stat")
> > -            else:
> > -                reg = re.compile('[0-9]+')
> > -                load_values = reg.findall(line)
> > -                del load_values[0:11]
> > -                # extract values from /proc/stat
> > -                load = [0, 0]
> > -                for i in range(2):
> > -                    load[i] = int(load_values[i]) -
> self.old_load[i]
> > -
> > -                for i in range(2):
> > -                    self.old_load[i] = int(load_values[i])
> > -                return load
> > -
> > -
> > -        def start (self):
> > -            """
> > -            Start CPU usage measurement
> > -            """
> > -            self.old_load = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
> > -            self.startTime = time.time()
> > -            self._get_cpu_load(self.pid)
> > -
> > -
> > -        def get_load(self):
> > -            """
> > -            Get and reset CPU usage.
> > -
> > -            @return: Group cpu
> > -                    (pid, user[%], system[%], sum[%], testTime[s])
> > -            """
> > -            self.endTime = time.time()
> > -            testTime = self.endTime - self.startTime
> > -            load = self._get_cpu_load(self.pid)
> > -
> > -            user = load[0] / testTime
> > -            system = load[1] / testTime
> > -            sum = user + system
> > -
> > -            return (self.name, self.pid, user, system, sum,
> testTime)
> > -
> > -
> > -    def print_load(process, system):
> > -        """
> > -        Print load in tabular mode.
> > -
> > -        @param process: List of process statistic tuples.
> > -        @param system: Tuple of system cpu usage.
> > -        """
> > -
> > -        logging.info("%-10s %6s %5s %5s %5s %11s",
> > -                     "NAME", "PID", "USER", "SYS", "SUM", "TIME")
> > -        for pr in process:
> > -            logging.info("%-10s %6d %4.0f%% %4.0f%% %4.0f%%
> %10.3fs" % pr)
> > -        logging.info("TOTAL:     ------ %4.0f%% %4.0f%% %4.0f%%
> %10.3fs" %
> > -                     system)
> > -
> > -
> >      def process_stats(stats, scale=1.0):
> >          """
> >          Process and print the statistic.
> > @@ -352,7 +397,7 @@ def run_virtio_console(test, params, env):
> >          return stats
> >  
> > 
> > -    def init_guest(vm, timeout=2):
> > +    def _init_guest(vm, timeout=2):
> >          """
> >          Execute virtio_guest.py on guest, wait until it is
> initialized.
> >  
> > @@ -384,6 +429,21 @@ def run_virtio_console(test, params, env):
> >          time.sleep(2)
> >  
> > 
> > +    def init_guest(vm, consoles):
> > +        """
> > +        Prepares guest, executes virtio_guest.py and initialize for
> testing
> > +
> > +        @param vm: Informations about the guest.
> > +        @param consoles: Informations about consoles
> > +        """
> > +        conss = []
> > +        for mode in consoles:
> > +            for cons in mode:
> > +                conss.append(cons.for_guest())
> > +        _init_guest(vm, 10)
> > +        on_guest("virt.init(%s)" % (conss), vm, 10)
> > +
> > +
> >      def _on_guest(command, vm, timeout=2):
> >          """
> >          Execute given command inside the script's main loop,
> indicating the vm
> > @@ -425,29 +485,6 @@ def run_virtio_console(test, params, env):
> >          return (match, data)
> >  
> > 
> > -    def socket_readall(sock, read_timeout, mesagesize):
> > -        """
> > -        Read everything from the socket.
> > -
> > -        @param sock: Socket.
> > -        @param read_timeout: Read timeout.
> > -        @param mesagesize: Size of message.
> > -        """
> > -        sock_decriptor = sock.fileno()
> > -        sock.settimeout(read_timeout)
> > -        message = ""
> > -        try:
> > -            while (len(message) < mesagesize):
> > -                message += sock.recv(mesagesize)
> > -        except Exception as inst:
> > -            if (inst.args[0] == "timed out"):
> > -                logging.debug("Reading timeout")
> > -            else:
> > -                logging.debug(inst)
> > -        sock.setblocking(1)
> > -        return message
> > -
> > -
> >      def _guest_exit_threads(vm, send_pts, recv_pts):
> >          """
> >          Safely executes on_guest("virt.exit_threads()") using
> workaround of
> > @@ -463,7 +500,7 @@ def run_virtio_console(test, params, env):
> >              logging.debug("Workaround the stuck thread on guest")
> >              # Thread is stucked in read/write
> >              for send_pt in send_pts:
> > -                send_pt[0].sendall(".")
> > +                send_pt.sock.sendall(".")
> >          elif match != 0:
> >              # Something else
> >              raise error.TestFail("Unexpected fail\nMatch:
> %s\nData:\n%s"
> > @@ -471,8 +508,8 @@ def run_virtio_console(test, params, env):
> >  
> >          # Read-out all remaining data
> >          for recv_pt in recv_pts:
> > -            while select.select([recv_pt[0]], [], [], 0.1)[0]:
> > -                recv_pt[0].recv(1024)
> > +            while select.select([recv_pt.sock], [], [], 0.1)[0]:
> > +                recv_pt.sock.recv(1024)
> >  
> >          # This will cause fail in case anything went wrong.
> >          on_guest("print 'PASS: nothing'", vm, 10)
> > @@ -482,6 +519,13 @@ def run_virtio_console(test, params, env):
> >          """
> >          Creates the VM and connects the specified number of
> consoles and serial
> >          ports.
> > +        Ports are allocated by 2 per 1 virtio-serial-pci device
> starting with
> > +        console. (3+2 => CC|CS|S; 0+2 => SS; 3+4 => CC|CS|SS|S,
> ...) This way
> > +        it's easy to test communication on the same or different
> > +        virtio-serial-pci device.
> > +        Further in tests the consoles are being picked always from
> the first
> > +        available one (3+2: 2xC => CC|cs|s <communication on the
> same PCI>;
> > +        2xC,1xS => CC|cS|s <communication between 2 PCI devs)
> >  
> >          @param no_console: Number of desired virtconsoles.
> >          @param no_serialport: Number of desired virtserialports.
> > @@ -508,12 +552,10 @@ def run_virtio_console(test, params, env):
> >              params['extra_params'] += (" -device
> virtserialport,chardev=vs%d,"
> >                                         "name=serialport-%d,id=p%d"
> % (i, i, i))
> >  
> > -
> >          logging.debug("Booting first guest %s",
> params.get("main_vm"))
> >          kvm_preprocessing.preprocess_vm(test, params, env,
> >                                          params.get("main_vm"))
> >  
> > -
> >          vm = kvm_utils.env_get_vm(env, params.get("main_vm"))
> >  
> >          session = kvm_test_utils.wait_for_login(vm, 0,
> > @@ -522,30 +564,219 @@ def run_virtio_console(test, params, env):
> >  
> >          # connect the sockets
> >          for i in range(0, no_console):
> > -            sock = socket.socket(socket.AF_UNIX,
> socket.SOCK_STREAM)
> > -            sock.connect("%s/%d" % (tmp_dir, i))
> > -            consoles.append([sock, "console-%d" % i, "yes"])
> > +            consoles.append(Port(None ,"console-%d" % i,
> > +                                 "yes", "%s/%d" % (tmp_dir, i)))
> >          for i in range(no_console, no_console + no_serialport):
> > -            sock = socket.socket(socket.AF_UNIX,
> socket.SOCK_STREAM)
> > -            sock.connect("%s/%d" % (tmp_dir, i))
> > -            serialports.append([sock, "serialport-%d" % i, "no"])
> > +            serialports.append(Port(None ,"serialport-%d" % i,
> > +                                    "no", "%s/%d" % (tmp_dir, i)))
> >  
> >          return [vm, session, tmp_dir], [consoles, serialports]
> >  
> > 
> > -    def test_smoke(vm, consoles, params):
> > +    def topen(vm, port):
> > +        """
> > +        Open virtioconsole port.
> > +
> > +        @param vm: Target virtual machine [vm, session, tmp_dir].
> > +        @param port: Port identifier.
> > +        """
> > +        on_guest("virt.open('%s')" % (port.name), vm, 2)
> > +        port.open()
> > +
> > +
> > +    def tmulti_open(vm, port):
> > +        """
> > +        Multiopen virtioconsole port.
> > +
> > +        @param vm: Target virtual machine [vm, session, tmp_dir].
> > +        @param port: Port identifier.
> > +        """
> > +        on_guest("virt.close('%s')" % (port.name), vm, 2)
> > +        on_guest("virt.open('%s')" % (port.name), vm, 2)
> > +        match = _on_guest("virt.open('%s')" % (port.name), vm,
> 2)[0]
> > +        # Console is permitted to open the device multiple times
> > +        if match != 0 and port.port_type == "yes":
> > +            raise error.TestFail("Unexpected fail of openning the
> console"
> > +                                 " device for the 2nd time.")
> > +        # Serial port is forbidden to open the device multiple
> times
> > +        elif match != 1 and port.port_type == "no":
> > +            raise error.TestFail("Unexpetded pass of oppening the
> serialport"
> > +                                 " device for the 2nd time.")
> > +        port.open()
> > +
> > +    def tclose(vm, port):
> > +        """
> > +        Close socket.
> > +
> > +        @param vm: Target virtual machine [vm, session, tmp_dir].
> > +        @param port: Port to open.
> > +        """
> > +        on_guest("virt.close('%s')" % (port.name), vm, 2)
> > +        port.close()
> > +
> > +
> > +    def tpooling(vm, port):
> > +        """
> > +        Test try pooling function.
> > +
> > +        @param vm: Target virtual machine [vm, session, tmp_dir].
> > +        @param port: Port used in test.
> > +        """
> > +        # Poll (OUT)
> > +        on_guest("virt.poll('%s', %s)" % (port.name,
> select.POLLOUT), vm,
> > +                 2)
> > +
> > +        # Poll (IN, OUT)
> > +        port.sock.sendall("test")
> > +        for test in [select.POLLIN, select.POLLOUT]:
> > +            on_guest("virt.poll('%s', %s)" % (port.name, test), vm,
> 2)
> > +
> > +        # Poll (IN HUP)
> > +        # I store the socket informations and close the socket
> > +        port.close()
> > +        for test in [select.POLLIN, select.POLLHUP]:
> > +            on_guest("virt.poll('%s', %s)" % (port.name, test), vm,
> 2)
> > +
> > +        # Poll (HUP)
> > +        on_guest("virt.recv('%s', 4, 1024, False)" % (port.name),
> vm, 2)
> > +        on_guest("virt.poll('%s', %s)" % (port.name,
> select.POLLHUP), vm,
> > +                 2)
> > +
> > +        # Reconnect the socket
> > +        port.open()
> > +        # Redefine socket in consoles
> > +        on_guest("virt.poll('%s', %s)" % (port.name,
> select.POLLOUT), vm,
> > +                 2)
> > +
> > +
> > +    def trw_host_offline(vm, port):
> > +        """
> > +        Guest read/write from host when host is disconnected.
> > +
> > +        @param vm: Target virtual machine [vm, session, tmp_dir].
> > +        @param port: Port used in test.
> > +        """
> > +        if port.is_open:
> > +            port.close()
> > +
> > +        # Read should pass
> > +        # FIXME: Console doesn't support polling (POLLHUP without
> host shoots
> > +        # the guest OS)
> > +        if port.port_type != "yes":
> > +            on_guest("virt.recv('%s', 0, 1024, False)" % port.name,
> vm, 2)
> > +        else: # Skip this test on virtio-console port
> > +            raise error.TestFail("This test is unable to run with
> virtio"
> > +                                 " console. Please see the in_code
> FIXME"
> > +                                 " note for more info.\n"
> > +                                 "Skipping this round.")
> > +        # Write should timed-out
> > +        match, tmp = _on_guest("virt.send('%s', 10, False)"
> > +                                % port.name, vm, 2)
> > +        if match != None:
> > +            raise error.TestFail("Write on guest while host
> disconnected "
> > +                                 "didn't timed out.\nOutput:\n%s"
> > +                                 % tmp)
> > +
> > +        port.open()
> > +
> > +        if (port.sock.recv(1024) < 10):
> > +            raise error.TestFail("Didn't received data from
> guest")
> > +        # Now the _on_guest("virt.send('%s'... command should be
> finished
> > +        on_guest("print 'PASS: nothing'", vm, 2)
> > +
> > +
> > +    def trw_blocking_mode(vm, port):
> > +        """
> > +        Guest read\write data in blocking mode.
> > +
> > +        @param vm: Target virtual machine [vm, session, tmp_dir].
> > +        @param port: Port used in test.
> > +        """
> > +        # Blocking mode
> > +        if not port.is_open:
> > +            port.open()
> > +        on_guest("virt.blocking('%s', True)" % port.name, vm, 2)
> > +        # Recv should timed out
> > +        match, tmp = _on_guest("virt.recv('%s', 10, 1024, False)"
> %
> > +                               port.name, vm, 2)
> > +        if match == 0:
> > +            raise error.TestFail("Received data even when non were
> sent\n"
> > +                                 "Data:\n%s" % tmp)
> > +        elif match != None:
> > +            raise error.TestFail("Unexpected fail\nMatch:
> %s\nData:\n%s" %
> > +                                 (match, tmp))
> > +        port.sock.sendall("1234567890")
> > +        # Now guest received the data end escaped from the recv()
> > +        on_guest("print 'PASS: nothing'", vm, 2)
> > +
> > +
> > +    def trw_nonblocking_mode(vm, port):
> > +        """
> > +        Guest read\write data in nonblocking mode.
> > +
> > +        @param vm: Target virtual machine [vm, session, tmp_dir].
> > +        @param port: Port used in test.
> > +        """
> > +        # Non-blocking mode
> > +        if not port.is_open:
> > +            port.open()
> > +        on_guest("virt.blocking('%s', False)" % port.name, vm, 2)
> > +        # Recv should return FAIL with 0 received data
> > +        match, tmp = _on_guest("virt.recv('%s', 10, 1024, False)"
> %
> > +                              port.name, vm, 2)
> > +        if match == 0:
> > +            raise error.TestFail("Received data even when non were
> sent\n"
> > +                                 "Data:\n%s" % tmp)
> > +        elif match == None:
> > +            raise error.TestFail("Timed out, probably in blocking
> mode\n"
> > +                                 "Data:\n%s" % tmp)
> > +        elif match != 1:
> > +            raise error.TestFail("Unexpected fail\nMatch:
> %s\nData:\n%s" %
> > +                                 (match, tmp))
> > +        port.sock.sendall("1234567890")
> > +        on_guest("virt.recv('%s', 10, 1024, False)" % port.name,
> vm, 2)
> > +
> > +
> > +    def tbasic_loopback(vm, send_port, recv_port, data="Smoke test
> data"):
> > +        """
> > +        Easy loop back test with loop over only two port.
> > +
> > +        @param vm: Target virtual machine [vm, session, tmp_dir].
> > +        @param port: Port used in test.
> > +        """
> > +        if not send_port.is_open:
> > +            send_port.open()
> > +        if not recv_port.is_open:
> > +            recv_port.open()
> > +        on_guest("virt.loopback(['%s'], ['%s'], 1024,
> virt.LOOP_NONE)" %
> > +                     (send_port.name, recv_port.name), vm, 2)
> > +        send_port.sock.sendall(data)
> > +        tmp = ""
> > +        i = 0
> > +        while i <= 10:
> > +            i += 1
> > +            ret = select.select([recv_port.sock], [], [], 1.0)
> > +            if ret:
> > +                tmp += recv_port.sock.recv(1024)
> > +            if len(tmp) >= len(data):
> > +                break
> > +        if tmp != data:
> > +            raise error.TestFail("Incorrect data: '%s' != '%s'",
> > +                                 data, tmp)
> > +        _guest_exit_threads(vm, [send_port], [recv_port])
> > +
> > +
> > +    def test_smoke(test, vm, consoles, params):
> >          """
> >          Virtio console smoke test.
> >  
> >          Tests the basic functionalities (poll, read/write with and
> without
> >          connected host, etc.
> >  
> > -        @param vm: target virtual machine [vm, session, tmp_dir]
> > -        @param consoles: a field of virtio ports with the minimum
> of 2 items
> > -        @param params: test parameters '$console_type:$data;...'
> > +        @param vm: Target virtual machine [vm, session, tmp_dir].
> > +        @param consoles: Field of virtio ports with the minimum of
> 2 items.
> > +        @param params: Test parameters '$console_type:$data;...'
> >          """
> > -        logging.info("Smoke test: Tests the basic capabilities of
> "
> > -                     "virtio_consoles.")
> >          # PREPARE
> >          for param in params.split(';'):
> >              if not param:
> > @@ -560,121 +791,18 @@ def run_virtio_console(test, params, env):
> >              send_pt = consoles[param][0]
> >              recv_pt = consoles[param][1]
> >  
> > -            # TEST
> > -            # Poll (OUT)
> > -            on_guest("virt.poll('%s', %s)" % (send_pt[1],
> select.POLLOUT), vm,
> > -                     2)
> > -
> > -            # Poll (IN, OUT)
> > -            send_pt[0].sendall("test")
> > -            for test in [select.POLLIN, select.POLLOUT]:
> > -                on_guest("virt.poll('%s', %s)" % (send_pt[1],
> test), vm, 2)
> > -
> > -            # Poll (IN HUP)
> > -            # I store the socket informations and close the socket
> > -            sock = send_pt[0]
> > -            send_pt[0] = sock.getpeername()
> > -            sock.shutdown(2)
> > -            sock.close()
> > -            del sock
> > -            for test in [select.POLLIN, select.POLLHUP]:
> > -                on_guest("virt.poll('%s', %s)" % (send_pt[1],
> test), vm, 2)
> > -
> > -            # Poll (HUP)
> > -            on_guest("virt.recv('%s', 4, 1024, False)" %
> (send_pt[1]), vm, 2)
> > -            on_guest("virt.poll('%s', %s)" % (send_pt[1],
> select.POLLHUP), vm,
> > -                     2)
> > -
> > -            # Reconnect the socket
> > -            sock = socket.socket(socket.AF_UNIX,
> socket.SOCK_STREAM)
> > -            sock.connect(send_pt[0])
> > -            send_pt[0] = sock
> > -            # Redefine socket in consoles
> > -            consoles[param][0] = send_pt
> > -            on_guest("virt.poll('%s', %s)" % (send_pt[1],
> select.POLLOUT), vm,
> > -                     2)
> > -
> > -            # Read/write without host connected
> > -            # I store the socket informations and close the socket
> > -            sock = send_pt[0]
> > -            send_pt[0] = sock.getpeername()
> > -            sock.shutdown(2)
> > -            sock.close()
> > -            del sock
> > -            # Read should pass
> > -            on_guest("virt.recv('%s', 0, 1024, False)" %
> send_pt[1], vm, 2)
> > -            # Write should timed-out
> > -            match, tmp = _on_guest("virt.send('%s', 10, False)"
> > -                                    % send_pt[1], vm, 2)
> > -            if match != None:
> > -                raise error.TestFail("Read on guest while host
> disconnected "
> > -                                     "didn't timed
> out.\nOutput:\n%s"
> > -                                     % tmp)
> > -            sock = socket.socket(socket.AF_UNIX,
> socket.SOCK_STREAM)
> > -            sock.connect(send_pt[0])
> > -            send_pt[0] = sock
> > -
> > -            # Redefine socket in consoles
> > -            consoles[param][0] = send_pt
> > -            if (send_pt[0].recv(1024) < 10):
> > -                raise error.TestFail("Didn't received data from
> guest")
> > -            # Now the _on_guest("virt.send('%s'... command should
> be finished
> > -            on_guest("print 'PASS: nothing'", vm, 2)
> > -
> > -            # Non-blocking mode
> > -            on_guest("virt.blocking('%s', False)" % send_pt[1], vm,
> 2)
> > -            # Recv should return FAIL with 0 received data
> > -            match, tmp = _on_guest("virt.recv('%s', 10, 1024,
> False)" %
> > -                                   send_pt[1], vm, 2)
> > -            if match == 0:
> > -                raise error.TestFail("Received data even when non
> were sent\n"
> > -                                     "Data:\n%s" % tmp)
> > -            elif match == None:
> > -                raise error.TestFail("Timed out, probably in
> blocking mode\n"
> > -                                     "Data:\n%s" % tmp)
> > -            elif match != 1:
> > -                raise error.TestFail("Unexpected fail\nMatch:
> %s\nData:\n%s" %
> > -                                     (match, tmp))
> > -            send_pt[0].sendall("1234567890")
> > -            on_guest("virt.recv('%s', 10, 1024, False)" %
> send_pt[1], vm, 2)
> > -
> > -            # Blocking mode
> > -            on_guest("virt.blocking('%s', True)" % send_pt[1], vm,
> 2)
> > -            # Recv should timed out
> > -            match, tmp = _on_guest("virt.recv('%s', 10, 1024,
> False)" %
> > -                                   send_pt[1], vm, 2)
> > -            if match == 0:
> > -                raise error.TestFail("Received data even when non
> were sent\n"
> > -                                     "Data:\n%s" % tmp)
> > -            elif match != None:
> > -                raise error.TestFail("Unexpected fail\nMatch:
> %s\nData:\n%s" %
> > -                                     (match, tmp))
> > -            send_pt[0].sendall("1234567890")
> > -            # Now guest received the data end escaped from the
> recv()
> > -            on_guest("print 'PASS: nothing'", vm, 2)
> > -
> > -            # Basic loopback test
> > -            on_guest("virt.loopback(['%s'], ['%s'], 1024,
> virt.LOOP_NONE)" %
> > -                     (send_pt[1], recv_pt[1]), vm, 2)
> > -            send_pt[0].sendall(data)
> > -            tmp = ""
> > -            i = 0
> > -            while i <= 10:
> > -                i += 1
> > -                ret = select.select([recv_pt[0]], [], [], 1.0)
> > -                if ret:
> > -                    tmp += recv_pt[0].recv(1024)
> > -                if len(tmp) >= len(data):
> > -                    break
> > -            if tmp != data:
> > -                raise error.TestFail("Incorrect data: '%s' !=
> '%s'",
> > -                                     data, tmp)
> > -            _guest_exit_threads(vm, [send_pt], [recv_pt])
> > -
> > -        return consoles
> > -
> > -
> > -    def test_loopback(vm, consoles, params):
> > +            test.do_test(topen, [vm, send_pt] , True)
> > +            test.do_test(tclose, [vm, send_pt], True)
> > +            test.do_test(tmulti_open, [vm, send_pt], True)
> > +            test.do_test(tpooling, [vm, send_pt])
> > +            test.do_test(trw_host_offline, [vm, send_pt])
> > +            test.do_test(trw_nonblocking_mode, [vm, send_pt])
> > +            test.do_test(trw_blocking_mode, [vm, send_pt])
> > +            test.do_test(tbasic_loopback, [vm, send_pt, recv_pt],
> data)
> > +
> > +
> > +
> > +    def tloopback(vm, consoles, params):
> >          """
> >          Virtio console loopback test.
> >  
> > @@ -682,16 +810,13 @@ def run_virtio_console(test, params, env):
> >          ports and sends length amount of data through this
> connection.
> >          It validates the correctness of the data sent.
> >  
> > -        @param vm: target virtual machine [vm, session, tmp_dir]
> > -        @param consoles: a field of virtio ports with the minimum
> of 2 items
> > +        @param vm: Target virtual machine [vm, session, tmp_dir].
> > +        @param consoles: Field of virtio ports with the minimum of
> 2 items.
> >          @param params: test parameters, multiple recievers
> allowed.
> >              '$source_console_type@buffer_length:
> >               $destination_console_type1@$buffer_length:...:
> >               $loopback_buffer_length;...'
> >          """
> > -        logging.info("Loopback test: Creates a loopback between
> sender port "
> > -                     "and receiving port, send data through this
> connection, "
> > -                     "verify data correctness.")
> >          # PREPARE
> >          for param in params.split(';'):
> >              if not param:
> > @@ -730,6 +855,13 @@ def run_virtio_console(test, params, env):
> >              if len(buf_len) == (idx_console + idx_serialport):
> >                  buf_len.append(1024)
> >  
> > +            for p in recv_pts:
> > +                if not p.is_open:
> > +                    p.open()
> > +
> > +            if not send_pt.is_open:
> > +                send_pt.open()
> > +
> >              if len(recv_pts) == 0:
> >                  raise error.TestFail("test_loopback: incorrect recv
> consoles"
> >                                       "definition")
> > @@ -739,21 +871,22 @@ def run_virtio_console(test, params, env):
> >              for i in range(0, len(recv_pts)):
> >                  queues.append(deque())
> >  
> > -            tmp = "'%s'" % recv_pts[0][1]
> > +            tmp = "'%s'" % recv_pts[0].name
> >              for recv_pt in recv_pts[1:]:
> > -                tmp += ", '%s'" % (recv_pt[1])
> > +                tmp += ", '%s'" % (recv_pt.name)
> >              on_guest("virt.loopback(['%s'], [%s], %d,
> virt.LOOP_POLL)"
> > -                     % (send_pt[1], tmp, buf_len[-1]), vm, 2)
> > +                     % (send_pt.name, tmp, buf_len[-1]), vm, 2)
> >  
> >              exit_event = threading.Event()
> >  
> >              # TEST
> > -            thread = th_send_check(send_pt[0], exit_event, queues,
> buf_len[0])
> > +            thread = ThSendCheck(send_pt.sock, exit_event, queues,
> > +                                   buf_len[0])
> >              thread.start()
> >              threads.append(thread)
> >  
> >              for i in range(len(recv_pts)):
> > -                thread = th_recv_check(recv_pts[i][0], queues[i],
> exit_event,
> > +                thread = ThRecvCheck(recv_pts[i].sock, queues[i],
> exit_event,
> >                                         buf_len[i + 1])
> >                  thread.start()
> >                  threads.append(thread)
> > @@ -770,8 +903,8 @@ def run_virtio_console(test, params, env):
> >  
> >              # Read-out all remaining data
> >              for recv_pt in recv_pts:
> > -                while select.select([recv_pt[0]], [], [], 0.1)[0]:
> > -                    recv_pt[0].recv(1024)
> > +                while select.select([recv_pt.sock], [], [],
> 0.1)[0]:
> > +                    recv_pt.sock.recv(1024)
> >  
> >              _guest_exit_threads(vm, [send_pt], recv_pts)
> >  
> > @@ -779,19 +912,17 @@ def run_virtio_console(test, params, env):
> >              del threads[:]
> >  
> > 
> > -    def test_perf(vm, consoles, params):
> > +    def tperf(vm, consoles, params):
> >          """
> >          Tests performance of the virtio_console tunel. First it
> sends the data
> >          from host to guest and than back. It provides informations
> about
> >          computer utilisation and statistic informations about the
> troughput.
> >  
> > -        @param vm: target virtual machine [vm, session, tmp_dir]
> > -        @param consoles: a field of virtio ports with the minimum
> of 2 items
> > +        @param vm: Target virtual machine [vm, session, tmp_dir].
> > +        @param consoles: Field of virtio ports with the minimum of
> 2 items.
> >          @param params: test parameters:
> >                  '$console_type@$buffer_length:$test_duration;...'
> >          """
> > -        logging.info("Performance test: Measure performance for the
> "
> > -                     "virtio console tunnel")
> >          for param in params.split(';'):
> >              if not param:
> >                  continue
> > @@ -811,39 +942,38 @@ def run_virtio_console(test, params, env):
> >              param = (param[0] == 'serialport')
> >              port = consoles[param][0]
> >  
> > +            if not port.is_open:
> > +                port.open()
> > +
> >              data = ""
> >              for i in range(buf_len):
> >                  data += "%c" % random.randrange(255)
> >  
> >              exit_event = threading.Event()
> > -            slice = float(duration)/100
> > +            slice = float(duration) / 100
> >  
> >              # HOST -> GUEST
> >              on_guest('virt.loopback(["%s"], [], %d,
> virt.LOOP_NONE)' %
> > -                     (port[1], buf_len), vm, 2)
> > -            thread = th_send(port[0], data, exit_event)
> > +                     (port.name, buf_len), vm, 2)
> > +            thread = ThSend(port.sock, data, exit_event)
> >              stats = array.array('f', [])
> > -            loads = []
> > -            loads.append(cpu_load())
> > -            loads.append(pid_load(os.getpid(), 'autotest'))
> > -            loads.append(pid_load(vm[0].get_pid(), 'VM'))
> > -
> > -            for load in loads:
> > -                load.start()
> > +            loads = utils.SystemLoad([(os.getpid(), 'autotest'),
> > +                                      (vm[0].get_pid(), 'VM'), 0])
> > +            loads.start()
> >              _time = time.time()
> >              thread.start()
> >              for i in range(100):
> >                  stats.append(thread.idx)
> >                  time.sleep(slice)
> >              _time = time.time() - _time - duration
> > -            print_load([loads[1].get_load(), loads[2].get_load()],
> > -                       loads[0].get_load())
> > +            logging.info("\n" +
> loads.get_cpu_status_string()[:-1])
> > +            logging.info("\n" +
> loads.get_mem_status_string()[:-1])
> >              exit_event.set()
> >              thread.join()
> >  
> >              # Let the guest read-out all the remaining data
> >              while not _on_guest("virt.poll('%s', %s)" %
> > -                                (port[1], select.POLLIN), vm,
> 2)[0]:
> > +                                (port.name, select.POLLIN), vm,
> 2)[0]:
> >                  time.sleep(1)
> >  
> >              _guest_exit_threads(vm, [port], [])
> > @@ -853,30 +983,29 @@ def run_virtio_console(test, params, env):
> >                  "Test ran %fs longer which is more than one slice",
> _time)
> >              else:
> >                  logging.debug("Test ran %fs longer", _time)
> > -            stats = process_stats(stats[1:], slice*1048576)
> > +            stats = process_stats(stats[1:], slice * 1048576)
> >              logging.debug("Stats = %s", stats)
> >              logging.info("Host -> Guest [MB/s] (min/med/max) =
> %.3f/%.3f/%.3f",
> > -                         stats[0], stats[len(stats)/2], stats[-1])
> > +                        stats[0], stats[len(stats) / 2],
> stats[-1])
> >  
> >              del thread
> >  
> >              # GUEST -> HOST
> >              exit_event.clear()
> >              stats = array.array('f', [])
> > -            on_guest("virt.send_loop_init('%s', %d)" % (port[1],
> buf_len),
> > +            on_guest("virt.send_loop_init('%s', %d)" % (port.name,
> buf_len),
> >                       vm, 30)
> > -            thread = th_recv(port[0], exit_event, buf_len)
> > +            thread = ThRecv(port.sock, exit_event, buf_len)
> >              thread.start()
> > -            for load in loads:
> > -                load.start()
> > +            loads.start()
> >              on_guest("virt.send_loop()", vm, 2)
> >              _time = time.time()
> >              for i in range(100):
> >                  stats.append(thread.idx)
> >                  time.sleep(slice)
> >              _time = time.time() - _time - duration
> > -            print_load([loads[1].get_load(), loads[2].get_load()],
> > -                       loads[0].get_load())
> > +            logging.info("\n" +
> loads.get_cpu_status_string()[:-1])
> > +            logging.info("\n" +
> loads.get_mem_status_string()[:-1])
> >              on_guest("virt.exit_threads()", vm, 2)
> >              exit_event.set()
> >              thread.join()
> > @@ -885,37 +1014,86 @@ def run_virtio_console(test, params, env):
> >                  "Test ran %fs longer which is more than one slice",
> _time)
> >              else:
> >                  logging.debug("Test ran %fs longer" % _time)
> > -            stats = process_stats(stats[1:], slice*1048576)
> > +            stats = process_stats(stats[1:], slice * 1048576)
> >              logging.debug("Stats = %s", stats)
> >              logging.info("Guest -> Host [MB/s] (min/med/max) =
> %.3f/%.3f/%.3f",
> > -                         stats[0], stats[len(stats)/2], stats[-1])
> > +                         stats[0], stats[len(stats) / 2],
> stats[-1])
> >  
> >              del thread
> > -
> >              del exit_event
> > -            del loads[:]
> > +
> > +
> > +    def clean_ports(vm, consoles):
> > +        """
> > +        Clean state of all ports and set port to default state.
> > +        Default state:
> > +           No data on port or in port buffer.
> > +           Read mode = blocking.
> > +
> > +        @param consoles: Consoles which should be clean.
> > +        """
> > +        # Check if python is still alive
> > +        print "CLEANED"
> > +        match, tmp = _on_guest("is_alive()", vm, 10)
> > +        if (match == None) or (match != 0):
> > +            logging.error("Python died/is stucked/have remaining
> threads")
> > +            vm[1].close()
> > +            vm[1] = kvm_test_utils.wait_for_login(vm[0], 0,
> > +                                        
> float(params.get("boot_timeout", 240)),
> > +                                         0, 2)
> > +            (match, data) = _on_guest("killall -9 python "
> > +                                      "&& echo -n PASS: python
> killed"
> > +                                      "|| echo -n PASS: python was
> death",
> > +                                      vm, 30)
> > +            if (match == None):
> > +                # killall -9 command didn't finished - python
> stucked
> > +                raise error.TestFail("Python is really stucked - "
> > +                                     "can't kill -9 it")
> > +
> > +            on_guest("rmmod -f virtio_console && echo -n PASS:
> rmmod "
> > +                     "|| echo -n FAIL: rmmod", vm, 10)
> > +            on_guest("modprobe virtio_console "
> > +                     "&& echo -n PASS: modprobe || echo -n FAIL:
> modprobe",
> > +                     vm, 10)
> > +
> > +            init_guest(vm, consoles)
> > +            (match, data) = _on_guest("virt.clean_port('%s'),1024"
> %
> > +                                      consoles[0][0].name, vm, 2)
> > +            if (match == None) or (match != 0):
> > +                raise error.TestFail("Virtio-console driver is
> irreparably"
> > +                                     " blocked. Every comd end with
> sig KILL.")
> > +
> > +        for ctype in consoles:
> > +            for port in ctype:
> > +                openned = port.is_open
> > +                port.clean_port()
> > +                #on_guest("virt.blocking('%s', True)" % port.name,
> vm, 2)
> > +                on_guest("virt.clean_port('%s'),1024" % port.name,
> vm, 2)
> > +                if not openned:
> > +                    port.close()
> >  
> > 
> >      # INITIALIZE
> > -    test_smoke_params = params.get('virtio_console_smoke', '')
> > -    test_loopback_params = params.get('virtio_console_loopback',
> '')
> > -    test_perf_params = params.get('virtio_console_perf', '')
> > +
> > +    tsmoke_params = params.get('virtio_console_smoke', '')
> > +    tloopback_params = params.get('virtio_console_loopback', '')
> > +    tperf_params = params.get('virtio_console_perf', '')
> >  
> >      no_serialports = 0
> >      no_consoles = 0
> >      # consoles required for Smoke test
> > -    if (test_smoke_params.count('serialport')):
> > +    if (tsmoke_params.count('serialport')):
> >          no_serialports = max(2, no_serialports)
> > -    if (test_smoke_params.count('console')):
> > +    if (tsmoke_params.count('console')):
> >          no_consoles = max(2, no_consoles)
> >      # consoles required for Loopback test
> > -    for param in test_loopback_params.split(';'):
> > +    for param in tloopback_params.split(';'):
> >          no_serialports = max(no_serialports,
> param.count('serialport'))
> >          no_consoles = max(no_consoles, param.count('console'))
> >      # consoles required for Performance test
> > -    if (test_perf_params.count('serialport')):
> > +    if (tperf_params.count('serialport')):
> >          no_serialports = max(1, no_serialports)
> > -    if (test_perf_params.count('console')):
> > +    if (tperf_params.count('console')):
> >          no_consoles = max(1, no_consoles)
> >  
> >      if (no_serialports + no_consoles) == 0:
> > @@ -933,16 +1111,27 @@ def run_virtio_console(test, params, env):
> >  
> >      # ACTUAL TESTING
> >      # Defines all available consoles; tests udev and sysfs
> > -    conss = []
> > -    for mode in consoles:
> > -        for cons in mode:
> > -            conss.append(cons[1:3])
> > -    init_guest(vm, 10)
> > -    on_guest("virt.init(%s)" % (conss), vm, 10)
> > -
> > -    consoles = test_smoke(vm, consoles, test_smoke_params)
> > -    test_loopback(vm, consoles, test_loopback_params)
> > -    test_perf(vm, consoles, test_perf_params)
> > +    init_guest(vm, consoles)
> > +
> > +    test = SubTest()
> > +    test.set_cleanup_func(clean_ports, [vm, consoles])
> > +    #Test Smoke
> > +    test_smoke(test, vm, consoles, tsmoke_params)
> > +
> > +    #Test Loopback
> > +    test.do_test(tloopback, [vm, consoles, tloopback_params])
> > +
> > +    #Test Performance
> > +    test.do_test(tperf, [vm, consoles, tperf_params])
> > +
> > +    logging.info(("Summary: %d tests passed  %d test failed :\n" %
> > +                  (test.passed, test.failed)) +
> test.get_text_result())
> > +    logging.debug(("Summary: %d tests passed  %d test failed :\n"
> %
> > +                   (test.passed, test.failed)) +
> test.get_full_text_result())
> > +
> > +    if test.is_failed():
> > +        raise error.TestFail("Virtio_console test FAILED.")
> > +
> >  
> >      # CLEANUP
> >      vm[1].close()
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux