----- "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