| Index: client/tests/kvm/tests/virtio_console.py
|
| diff --git a/client/tests/kvm/tests/virtio_console.py b/client/tests/kvm/tests/virtio_console.py
|
| index af32bf2f337f4bd7b6cda8c7877ea4f182717ba7..bc4083765818dad1b6c8a7dc731042c842761a1e 100644
|
| --- a/client/tests/kvm/tests/virtio_console.py
|
| +++ b/client/tests/kvm/tests/virtio_console.py
|
| @@ -10,7 +10,8 @@ from threading import Thread
|
|
|
| from autotest_lib.client.common_lib import error
|
| from autotest_lib.client.bin import utils
|
| -import kvm_subprocess, kvm_test_utils, kvm_preprocessing
|
| +import kvm_subprocess, kvm_test_utils, kvm_utils
|
| +import kvm_preprocessing, kvm_monitor
|
|
|
|
|
| def run_virtio_console(test, params, env):
|
| @@ -22,10 +23,10 @@ def run_virtio_console(test, params, env):
|
| 3) Start loopback test
|
| 4) Start performance test
|
|
|
| - This test uses an auxiliary script, console_switch.py, that is copied to
|
| - guests. This script has functions to send and write data to virtio console
|
| - ports. Details of each test can be found on the docstrings for the test_*
|
| - functions.
|
| + This test uses an auxiliary script, virtio_console_guest.py, that is copied
|
| + to guests. This script has functions to send and write data to virtio
|
| + console ports. Details of each test can be found on the docstrings for the
|
| + test_* functions.
|
|
|
| @param test: kvm test object
|
| @param params: Dictionary with the test parameters
|
| @@ -57,6 +58,15 @@ def run_virtio_console(test, params, env):
|
| self.cleanup_args = args
|
|
|
|
|
| + def get_cleanup_func(self):
|
| + """
|
| + Returns the tupple of cleanup_func and clenaup_args
|
| +
|
| + @return: Tupple of self.cleanup_func and self.cleanup_args
|
| + """
|
| + return (self.cleanup_func, self.cleanup_args)
|
| +
|
| +
|
| def do_test(self, function, args=None, fatal=False, cleanup=True):
|
| """
|
| Execute subtest function.
|
| @@ -69,11 +79,11 @@ def run_virtio_console(test, params, env):
|
| @raise TestError: If collapse of test is fatal raise forward
|
| exception from subtest.
|
| """
|
| - if args == None:
|
| + if args is None:
|
| args = []
|
| res = [None, function.func_name, args]
|
| try:
|
| - logging.debug("Start test %s.", function.func_name)
|
| + logging.info("Start test %s." % function.func_name)
|
| ret = function(*args)
|
| res[0] = True
|
| logging.info(self.result_to_string(res))
|
| @@ -371,16 +381,16 @@ def run_virtio_console(test, params, env):
|
| """
|
| Random data receiver/checker thread.
|
| """
|
| - def __init__(self, port, buf, event, blocklen=1024):
|
| + def __init__(self, port, buffer, event, blocklen=1024):
|
| """
|
| @param port: Source port.
|
| - @param buf: Control data buffer (FIFO).
|
| + @param buffer: Control data buffer (FIFO).
|
| @param length: Amount of data we want to receive.
|
| @param blocklen: Block length.
|
| """
|
| Thread.__init__(self)
|
| self.port = port
|
| - self.buffer = buf
|
| + self.buffer = buffer
|
| self.exitevent = event
|
| self.blocklen = blocklen
|
| self.idx = 0
|
| @@ -393,7 +403,7 @@ def run_virtio_console(test, params, env):
|
| if ret[0] and (not self.exitevent.isSet()):
|
| buf = self.port.recv(self.blocklen)
|
| if buf:
|
| - # Compare the recvd data with the control data
|
| + # Compare the received data with the control data
|
| for ch in buf:
|
| ch_ = self.buffer.popleft()
|
| if not ch == ch_:
|
| @@ -439,26 +449,28 @@ def run_virtio_console(test, params, env):
|
| @param timeout: Timeout that will be used to verify if the script
|
| started properly.
|
| """
|
| - logging.debug("compile virtio_console_guest.py on guest %s", vm[0].name)
|
| + logging.debug("compile virtio_console_guest.py on guest %s",
|
| + vm[0].name)
|
|
|
| - (match, data) = _on_guest("python -OO /tmp/virtio_console_guest.py -c &&"
|
| - "echo -n 'PASS: Compile virtio_guest finished' ||"
|
| + (match, data) = _on_guest("python -OO /tmp/virtio_console_guest.py -c"
|
| + "&& echo -n 'PASS: Compile virtio_guest finished' ||"
|
| "echo -n 'FAIL: Compile virtio_guest failed'",
|
| vm, timeout)
|
|
|
| if match != 0:
|
| - raise error.TestFail("Command console_switch.py on guest %s failed."
|
| - "\nreturn code: %s\n output:\n%s" %
|
| + raise error.TestFail("Command console_switch.py on guest %s "
|
| + "failed.\nreturn code: %s\n output:\n%s" %
|
| (vm[0].name, match, data))
|
| - logging.debug("Starting virtio_console_guest.py on guest %s", vm[0].name)
|
| + logging.debug("Starting virtio_console_guest.py on guest %s",
|
| + vm[0].name)
|
| vm[1].sendline()
|
| (match, data) = _on_guest("python /tmp/virtio_console_guest.pyo &&"
|
| "echo -n 'PASS: virtio_guest finished' ||"
|
| "echo -n 'FAIL: virtio_guest failed'",
|
| vm, timeout)
|
| if match != 0:
|
| - raise error.TestFail("Command console_switch.py on guest %s failed."
|
| - "\nreturn code: %s\n output:\n%s" %
|
| + raise error.TestFail("Command console_switch.py on guest %s "
|
| + "failed.\nreturn code: %s\n output:\n%s" %
|
| (vm[0].name, match, data))
|
| # Let the system rest
|
| time.sleep(2)
|
| @@ -479,27 +491,27 @@ def run_virtio_console(test, params, env):
|
| on_guest("virt.init(%s)" % (conss), vm, 10)
|
|
|
|
|
| - def _search_kernel_crashlog(vm, timeout = 2):
|
| + def _search_kernel_crashlog(vm_port, timeout=2):
|
| """
|
| Find kernel crash message.
|
|
|
| - @param vm: Informations about the guest.
|
| + @param vm_port : Guest output port.
|
| @param timeout: Timeout used to verify expected output.
|
|
|
| @return: Kernel crash log or None.
|
| """
|
| - data = vm[3].read_nonblocking()
|
| - match = re.search("^BUG:", data, re.MULTILINE)
|
| - if match == None:
|
| + data = vm_port.read_nonblocking()
|
| + match = re.search("BUG:", data, re.MULTILINE)
|
| + if match is None:
|
| return None
|
|
|
| - match = re.search(r"^BUG:.*^---\[ end trace .* \]---",
|
| + match = re.search(r"BUG:.*---\[ end trace .* \]---",
|
| data, re.DOTALL |re.MULTILINE)
|
| - if match == None:
|
| - data += vm[3].read_until_last_line_matches(
|
| - ["---\[ end trace .* \]---"],timeout)
|
| + if match is None:
|
| + data += vm_port.read_until_last_line_matches(
|
| + ["---\[ end trace .* \]---"],timeout)
|
|
|
| - match = re.search(r"(^BUG:.*^---\[ end trace .* \]---)",
|
| + match = re.search(r"(BUG:.*---\[ end trace .* \]---)",
|
| data, re.DOTALL |re.MULTILINE)
|
| return match.group(0)
|
|
|
| @@ -514,10 +526,10 @@ def run_virtio_console(test, params, env):
|
| @param vm: Informations about the guest.
|
| @param timeout: Timeout used to verify expected output.
|
|
|
| - @return: Tuple (match index, data)
|
| + @return: Tuple (match index, data, kernel_crash)
|
| """
|
| - logging.debug("Executing '%s' on virtio_console_guest.py loop, vm: %s," +
|
| - "timeout: %s", command, vm[0].name, timeout)
|
| + logging.debug("Executing '%s' on virtio_console_guest.py loop," +
|
| + " vm: %s, timeout: %s", command, vm[0].name, timeout)
|
| vm[1].sendline(command)
|
| try:
|
| (match, data) = vm[1].read_until_last_line_matches(["PASS:",
|
| @@ -528,8 +540,8 @@ def run_virtio_console(test, params, env):
|
| match = None
|
| data = "Timeout."
|
|
|
| - kcrash_data = _search_kernel_crashlog(vm)
|
| - if (kcrash_data != None):
|
| + kcrash_data = _search_kernel_crashlog(vm[3])
|
| + if kcrash_data is not None:
|
| logging.error(kcrash_data)
|
| vm[4] = True
|
|
|
| @@ -550,7 +562,8 @@ def run_virtio_console(test, params, env):
|
| """
|
| match, data = _on_guest(command, vm, timeout)
|
| if match == 1 or match is None:
|
| - raise error.TestFail("Failed to execute '%s' on virtio_console_guest.py, "
|
| + raise error.TestFail("Failed to execute '%s' on"
|
| + " virtio_console_guest.py, "
|
| "vm: %s, output:\n%s" %
|
| (command, vm[0].name, data))
|
|
|
| @@ -568,7 +581,7 @@ def run_virtio_console(test, params, env):
|
| """
|
| # in LOOP_NONE mode it might stuck in read/write
|
| match, tmp = _on_guest("virt.exit_threads()", vm, 10)
|
| - if match == None:
|
| + if match is None:
|
| logging.debug("Workaround the stuck thread on guest")
|
| # Thread is stucked in read/write
|
| for send_pt in send_pts:
|
| @@ -587,7 +600,7 @@ def run_virtio_console(test, params, env):
|
| on_guest("print 'PASS: nothing'", vm, 10)
|
|
|
|
|
| - def _vm_create(no_console=3, no_serialport=3):
|
| + def _vm_create(no_console=3, no_serialport=3, spread=True):
|
| """
|
| Creates the VM and connects the specified number of consoles and serial
|
| ports.
|
| @@ -608,12 +621,16 @@ def run_virtio_console(test, params, env):
|
| consoles = []
|
| serialports = []
|
| tmp_dir = tempfile.mkdtemp(prefix="virtio-console-", dir="/tmp/")
|
| - if not params.get('extra_params'):
|
| - params['extra_params'] = ''
|
| + params['extra_params'] = ''
|
|
|
| + if not spread:
|
| + pci = "virtio-serial-pci0"
|
| + params['extra_params'] += (" -device virtio-serial-pci,id="
|
| + + pci)
|
| + pci += ".0"
|
| for i in range(0, no_console):
|
| # Spread consoles between multiple PCI devices (2 per a dev)
|
| - if not i % 2:
|
| + if not i % 2 and spread:
|
| pci = "virtio-serial-pci%d" % (i / 2)
|
| params['extra_params'] += (" -device virtio-serial-pci,id="
|
| + pci)
|
| @@ -625,8 +642,8 @@ def run_virtio_console(test, params, env):
|
| % (i, i, i, pci))
|
|
|
| for i in range(no_console, no_console + no_serialport):
|
| - # Spread seroal ports between multiple PCI devices (2 per a dev)
|
| - if not i % 2:
|
| + # Spread serial ports between multiple PCI devices (2 per each dev)
|
| + if not i % 2 and spread:
|
| pci = "virtio-serial-pci%d" % (i / 2)
|
| params['extra_params'] += (" -device virtio-serial-pci,id="
|
| + pci)
|
| @@ -637,17 +654,7 @@ def run_virtio_console(test, params, env):
|
| "name=serialport-%d,id=p%d,bus=%s"
|
| % (i, i, i, pci))
|
|
|
| - logging.debug("Booting first guest %s", params.get("main_vm"))
|
| - kvm_preprocessing.preprocess_vm(test, params, env,
|
| - params.get("main_vm"))
|
| -
|
| - vm = env.get_vm(params.get("main_vm"))
|
| -
|
| - session = vm.wait_for_login(timeout=float(params.get("boot_timeout", 240)))
|
| -
|
| - sserial = kvm_test_utils.wait_for_login(vm, 0,
|
| - float(params.get("boot_timeout", 240)),
|
| - 0, 2, serial=True)
|
| + (vm, session, sserial) = _restore_vm()
|
|
|
| # connect the sockets
|
| for i in range(0, no_console):
|
| @@ -662,6 +669,37 @@ def run_virtio_console(test, params, env):
|
| return [vm, session, tmp_dir, sserial, kcrash], [consoles, serialports]
|
|
|
|
|
| + def _restore_vm():
|
| + """
|
| + Restore old virtual machine when VM is destroyed.
|
| + """
|
| + logging.debug("Booting guest %s", params.get("main_vm"))
|
| + kvm_preprocessing.preprocess_vm(test, params, env,
|
| + params.get("main_vm"))
|
| +
|
| + vm = env.get_vm(params.get("main_vm"))
|
| +
|
| + kernel_bug = None
|
| + try:
|
| + session = kvm_test_utils.wait_for_login(vm, 0,
|
| + float(params.get("boot_timeout", 100)),
|
| + 0, 2)
|
| + except (error.TestFail):
|
| + kernel_bug = _search_kernel_crashlog(vm.serial_console, 10)
|
| + if kernel_bug is not None:
|
| + logging.error(kernel_bug)
|
| + raise
|
| +
|
| + kernel_bug = _search_kernel_crashlog(vm.serial_console, 10)
|
| + if kernel_bug is not None:
|
| + logging.error(kernel_bug)
|
| +
|
| + sserial = kvm_test_utils.wait_for_login(vm, 0,
|
| + float(params.get("boot_timeout", 20)),
|
| + 0, 2, serial=True)
|
| + return [vm, session, sserial]
|
| +
|
| +
|
| def topen(vm, port):
|
| """
|
| Open virtioconsole port.
|
| @@ -673,6 +711,15 @@ def run_virtio_console(test, params, env):
|
| port.open()
|
|
|
|
|
| + def tcheck_zero_sym(vm):
|
| + """
|
| + Check if port /dev/vport0p0 was created.
|
| +
|
| + @param vm: Target virtual machine [vm, session, tmp_dir, ser_session].
|
| + """
|
| + on_guest("virt.check_zero_sym()", vm, 10)
|
| +
|
| +
|
| def tmulti_open(vm, port):
|
| """
|
| Multiopen virtioconsole port.
|
| @@ -819,11 +866,11 @@ def run_virtio_console(test, params, env):
|
| port.close()
|
|
|
| on_guest("virt.recv('%s', 0, 1024, False)" % port.name, vm, 10)
|
| - match, tmp = _on_guest("virt.send('%s', 10, False)"
|
| - % port.name, vm, 10)
|
| - if match != None:
|
| + match, tmp = _on_guest("virt.send('%s', 10, True)" % port.name,
|
| + vm, 10)
|
| + if match is not None:
|
| raise error.TestFail("Write on guest while host disconnected "
|
| - "didn't timed out.\nOutput:\n%s"
|
| + "didn't time out.\nOutput:\n%s"
|
| % tmp)
|
|
|
| port.open()
|
| @@ -834,6 +881,106 @@ def run_virtio_console(test, params, env):
|
| on_guest("print 'PASS: nothing'", vm, 10)
|
|
|
|
|
| + def trw_host_offline_big_data(vm, port):
|
| + """
|
| + Guest read/write from host when host is disconnected.
|
| +
|
| + @param vm: Target virtual machine [vm, session, tmp_dir, ser_session].
|
| + @param port: Port used in test.
|
| + """
|
| + if port.is_open:
|
| + port.close()
|
| +
|
| + port.clean_port()
|
| + port.close()
|
| + on_guest("virt.clean_port('%s'),1024" % port.name, vm, 10)
|
| + match, tmp = _on_guest("virt.send('%s', (1024**3)*3, True, "
|
| + "is_static=True)" % port.name, vm, 30)
|
| + if match is None:
|
| + raise error.TestFail("Write on guest while host disconnected "
|
| + "didn't time out.\nOutput:\n%s"
|
| + % tmp)
|
| +
|
| + time.sleep(20)
|
| +
|
| + port.open()
|
| +
|
| + rlen = 0
|
| + while rlen < (1024**3*3):
|
| + ret = select.select([port.sock], [], [], 10.0)
|
| + if (ret[0] != []):
|
| + rlen += len(port.sock.recv(((4096))))
|
| + elif rlen != (1024**3*3):
|
| + raise error.TestFail("Not all data was received,"
|
| + "only %d from %d" % (rlen, 1024**3*3))
|
| + on_guest("print 'PASS: nothing'", vm, 10)
|
| +
|
| +
|
| + def trw_notconnect_guest(vm, port, consoles):
|
| + """
|
| + Host send data to guest port and guest not read any data from port.
|
| +
|
| + @param vm: Target virtual machine [vm, session, tmp_dir, ser_session].
|
| + @param port: Port used in test.
|
| + """
|
| + vm[0].destroy(gracefully = False)
|
| + (vm[0], vm[1], vm[3]) = _restore_vm()
|
| + if not port.is_open:
|
| + port.open()
|
| + else:
|
| + port.close()
|
| + port.open()
|
| +
|
| + port.sock.settimeout(20.0)
|
| +
|
| + loads = utils.SystemLoad([(os.getpid(), 'autotest'),
|
| + (vm[0].get_pid(), 'VM'), 0])
|
| + loads.start()
|
| +
|
| + try:
|
| + sent1 = 0
|
| + for i in range(1000000):
|
| + sent1 += port.sock.send("a")
|
| + except socket.timeout:
|
| + logging.info("Data sending to closed port timed out.")
|
| +
|
| + logging.info("Bytes sent to client: %d" % (sent1))
|
| + logging.info("\n" + loads.get_cpu_status_string()[:-1])
|
| +
|
| + on_guest('echo -n "PASS:"', vm, 10)
|
| +
|
| + logging.info("Open and then close port %s" % (port.name))
|
| + init_guest(vm, consoles)
|
| + # Test of live and open and close port again
|
| + _clean_ports(vm, consoles)
|
| + on_guest("virt.close('%s')" % (port.name), vm, 10)
|
| +
|
| + # With serialport it is a different behavior
|
| + on_guest("guest_exit()", vm, 10)
|
| + port.sock.settimeout(20.0)
|
| +
|
| + loads.start()
|
| + try:
|
| + sent2 = 0
|
| + for i in range(40000):
|
| + sent2 = port.sock.send("a")
|
| + except socket.timeout:
|
| + logging.info("Data sending to closed port timed out.")
|
| +
|
| + logging.info("Bytes sent to client: %d" % (sent2))
|
| + logging.info("\n" + loads.get_cpu_status_string()[:-1])
|
| + loads.stop()
|
| + if (sent1 != sent2):
|
| + logging.warning("Inconsistent behavior: First sent %d bytes and "
|
| + "second sent %d bytes" % (sent1, sent2))
|
| +
|
| + port.sock.settimeout(None)
|
| + (vm[0], vm[1], vm[3]) = _restore_vm()
|
| +
|
| + init_guest(vm, consoles)
|
| + _clean_ports(vm, consoles)
|
| +
|
| +
|
| def trw_blocking_mode(vm, port):
|
| """
|
| Guest read\write data in blocking mode.
|
| @@ -851,7 +998,7 @@ def run_virtio_console(test, params, env):
|
| if match == 0:
|
| raise error.TestFail("Received data even when non were sent\n"
|
| "Data:\n%s" % tmp)
|
| - elif match != None:
|
| + elif match is not None:
|
| raise error.TestFail("Unexpected fail\nMatch: %s\nData:\n%s" %
|
| (match, tmp))
|
| port.sock.sendall("1234567890")
|
| @@ -876,7 +1023,7 @@ def run_virtio_console(test, params, env):
|
| if match == 0:
|
| raise error.TestFail("Received data even when non were sent\n"
|
| "Data:\n%s" % tmp)
|
| - elif match == None:
|
| + elif match is None:
|
| raise error.TestFail("Timed out, probably in blocking mode\n"
|
| "Data:\n%s" % tmp)
|
| elif match != 1:
|
| @@ -915,6 +1062,134 @@ def run_virtio_console(test, params, env):
|
| _guest_exit_threads(vm, [send_port], [recv_port])
|
|
|
|
|
| + def trmmod(vm, consoles):
|
| + """
|
| + Remove and again install modules of virtio_console.
|
| +
|
| + @param vm: Target virtual machine [vm, session, tmp_dir, ser_session].
|
| + @param consoles: Consoles which should be close before rmmod.
|
| + """
|
| + on_guest("guest_exit()", vm, 5)
|
| +
|
| + 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)
|
| + try:
|
| + cname = consoles[0][0].name
|
| + except (IndexError):
|
| + cname = consoles[1][0].name
|
| + on_guest("virt.clean_port('%s'),1024" % cname, vm, 2)
|
| +
|
| +
|
| + def tmax_serial_ports(vm, consoles):
|
| + """
|
| + Test maximum count of ports in guest machine.
|
| +
|
| + @param vm: Target virtual machine [vm, session, tmp_dir, ser_session].
|
| + @param consoles: Consoles which should be close before rmmod.
|
| + """
|
| + logging.debug("Count of serial ports: 30")
|
| + vm[0].destroy(gracefully = False)
|
| + (vm, consoles) = _vm_create(0, 30, False)
|
| + try:
|
| + init_guest(vm, consoles)
|
| + except error.TestFail as ints:
|
| + logging.info("Count of serial ports: 30")
|
| + raise ints
|
| + clean_reload_vm(vm, consoles, expected=True)
|
| +
|
| +
|
| + def tmax_console_ports(vm, consoles):
|
| + """
|
| + Test maximum count of ports in guest machine.
|
| +
|
| + @param vm: Target virtual machine [vm, session, tmp_dir, ser_session].
|
| + @param consoles: Consoles which should be close before rmmod.
|
| + """
|
| + logging.debug("Count of console ports: 30")
|
| + vm[0].destroy(gracefully = False)
|
| + (vm, consoles) = _vm_create(30, 0, False)
|
| + try:
|
| + init_guest(vm, consoles)
|
| + except error.TestFail as ints:
|
| + logging.info("Count of console ports: 30")
|
| + raise ints
|
| + clean_reload_vm(vm, consoles, expected=True)
|
| +
|
| +
|
| + def tmax_mix_serial_conosle_port(vm, consoles):
|
| + """
|
| + Test maximim count of ports in guest machine.
|
| +
|
| + @param vm: Target virtual machine [vm, session, tmp_dir, ser_session].
|
| + @param consoles: Consoles which should be close before rmmod.
|
| + """
|
| + logging.debug("Count of ports (serial+console): 30")
|
| + vm[0].destroy(gracefully = False)
|
| + (vm, consoles) = _vm_create(15, 15, False)
|
| + try:
|
| + init_guest(vm, consoles)
|
| + except error.TestFail as ints:
|
| + logging.info("Count of ports (serial+console): 30")
|
| + raise ints
|
| + clean_reload_vm(vm, consoles, expected=True)
|
| +
|
| +
|
| + def tshutdown(vm, consoles):
|
| + """
|
| + Try to gently shutdown the machine. Virtio_console shouldn't block this.
|
| +
|
| + @param vm: Target virtual machine [vm, session, tmp_dir, ser_session].
|
| + @param consoles: Consoles which should be close before rmmod.
|
| + """
|
| + ports = []
|
| + for console in consoles[0]:
|
| + ports.append(console)
|
| + for console in consoles[1]:
|
| + ports.append(console)
|
| + for port in ports:
|
| + port.open()
|
| + # If more than one, send data on the other ports
|
| + for port in ports[1:]:
|
| + on_guest("virt.close('%s')" % (port.name), vm, 2)
|
| + on_guest("virt.open('%s')" % (port.name), vm, 2)
|
| + try:
|
| + os.system("dd if=/dev/random of='%s' bs=4096 &>/dev/null &"
|
| + % port.path)
|
| + except:
|
| + pass
|
| + # Just start sending, it won't finish anyway...
|
| + _on_guest("virt.send('%s', 1024**3, True, is_static=True)"
|
| + % ports[0].name, vm, 1)
|
| +
|
| + # Let the computer transfer some bytes :-)
|
| + time.sleep(2)
|
| +
|
| + # Power off the computer
|
| + vm[0].destroy(gracefully=True)
|
| + clean_reload_vm(vm, consoles, expected=True)
|
| +
|
| +
|
| + def tmigrate_offline(vm, consoles):
|
| + """
|
| + Let the machine migrate. Virtio_consoles should survive this.
|
| +
|
| + @param vm: Target virtual machine [vm, session, tmp_dir, ser_session].
|
| + @param consoles: Consoles which should be close before rmmod.
|
| + """
|
| + # Migrate
|
| + vm[1].close()
|
| + dest_vm = kvm_test_utils.migrate(vm[0], env, 3600, "exec", 0, 0)
|
| + vm[1] = kvm_utils.wait_for(dest_vm.remote_login, 30, 0, 2)
|
| + if not vm[1]:
|
| + raise error.TestFail("Could not log into guest after migration")
|
| + logging.info("Logged in after migration")
|
| +
|
| +
|
| def tloopback(vm, consoles, params):
|
| """
|
| Virtio console loopback subtest.
|
| @@ -1167,19 +1442,21 @@ def run_virtio_console(test, params, env):
|
| # Check if python is still alive
|
| print "CLEANING"
|
| match, tmp = _on_guest("is_alive()", vm, 10)
|
| - if (match == None) or (match != 0):
|
| - logging.error("Python died/is stuck/has remaining threads")
|
| + if (match is None) or (match != 0):
|
| + logging.error("Python died/is stucked/have remaining threads")
|
| logging.debug(tmp)
|
| try:
|
| if vm[4] == True:
|
| raise error.TestFail("Kernel crash.")
|
| match, tmp = _on_guest("guest_exit()", vm, 10)
|
| - if (match == None) or (match == 0):
|
| + if (match is None) or (match == 0):
|
| vm[1].close()
|
| - vm[1] = vm[0].wait_for_login(timeout=float(params.get("boot_timeout", 240)))
|
| + vm[1] = kvm_test_utils.wait_for_login(vm[0], 0,
|
| + float(params.get("boot_timeout", 5)),
|
| + 0, 10)
|
| on_guest("killall -9 python "
|
| "&& echo -n PASS: python killed"
|
| - "|| echo -n PASS: python died",
|
| + "|| echo -n PASS: python was death",
|
| vm, 10)
|
|
|
| init_guest(vm, consoles)
|
| @@ -1191,12 +1468,24 @@ def run_virtio_console(test, params, env):
|
| logging.error("Virtio-console driver is irreparably"
|
| " blocked. Every comd end with sig KILL."
|
| "Try reboot vm for continue in testing.")
|
| - vm[1] = vm[0].reboot(vm[1], "system_reset")
|
| + try:
|
| + vm[1] = kvm_test_utils.reboot(vm[0], vm[1], "system_reset")
|
| + except (kvm_monitor.MonitorProtocolError):
|
| + logging.error("Qemu is blocked. Monitor"
|
| + " no longer communicate.")
|
| + vm[0].destroy(gracefully = False)
|
| + os.system("kill -9 %d" % (vm[0].get_pid()))
|
| + (vm[0], vm[1], vm[3]) = _restore_vm()
|
| init_guest(vm, consoles)
|
| + cname = ""
|
| + try:
|
| + cname = consoles[0][0].name
|
| + except (IndexError):
|
| + cname = consoles[1][0].name
|
| match = _on_guest("virt.clean_port('%s'),1024" %
|
| - consoles[0][0].name, vm, 10)[0]
|
| + cname, vm, 10)[0]
|
|
|
| - if (match == None) or (match != 0):
|
| + if (match is None) or (match != 0):
|
| raise error.TestFail("Virtio-console driver is irrepar"
|
| "ably blocked. Every comd end"
|
| " with sig KILL. Neither the "
|
| @@ -1204,6 +1493,25 @@ def run_virtio_console(test, params, env):
|
| _clean_ports(vm, consoles)
|
|
|
|
|
| + def clean_reload_vm(vm, consoles, expected=False):
|
| + """
|
| + Reloads and boots the damaged vm
|
| +
|
| + @param vm: Target virtual machine [vm, session, tmp_dir, ser_session].
|
| + @param consoles: Consoles which should be clean.
|
| + """
|
| + if not expected:
|
| + print "Scheduled vm reboot"
|
| + else:
|
| + print "SCHWARZENEGGER is CLEANING"
|
| + vm[0].destroy(gracefully=False)
|
| + shutil.rmtree(vm[2]) # Remove virtio sockets tmp directory
|
| + (_vm, _consoles) = _vm_create(len(consoles[0]), len(consoles[1]))
|
| + consoles[:] = _consoles[:]
|
| + vm[:] = _vm[:]
|
| + init_guest(vm, consoles)
|
| +
|
| +
|
| def test_smoke(test, vm, consoles, params):
|
| """
|
| Virtio console smoke test.
|
| @@ -1230,17 +1538,23 @@ def run_virtio_console(test, params, env):
|
| param = (param[0] == 'serialport')
|
| send_pt = consoles[param][0]
|
| recv_pt = consoles[param][1]
|
| - test.headline(headline)
|
| - test.do_test(topen, [vm, send_pt], True)
|
| - test.do_test(tclose, [vm, send_pt], True)
|
| - test.do_test(tmulti_open, [vm, send_pt])
|
| - test.do_test(tpooling, [vm, send_pt])
|
| - test.do_test(tsigio, [vm, send_pt])
|
| - test.do_test(tlseek, [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], True)
|
| + subtest.headline(headline)
|
| + subtest.do_test(tcheck_zero_sym, [vm], cleanup=False)
|
| + subtest.do_test(topen, [vm, send_pt], True)
|
| + subtest.do_test(tclose, [vm, send_pt], True)
|
| + subtest.do_test(tmulti_open, [vm, send_pt])
|
| + subtest.do_test(tpooling, [vm, send_pt])
|
| + subtest.do_test(tsigio, [vm, send_pt])
|
| + subtest.do_test(tlseek, [vm, send_pt])
|
| + subtest.do_test(trw_host_offline, [vm, send_pt])
|
| + subtest.do_test(trw_host_offline_big_data, [vm, send_pt],
|
| + cleanup=False)
|
| + subtest.do_test(trw_notconnect_guest,
|
| + [vm, send_pt, consoles])
|
| + subtest.do_test(trw_nonblocking_mode, [vm, send_pt])
|
| + subtest.do_test(trw_blocking_mode, [vm, send_pt])
|
| + subtest.do_test(tbasic_loopback, [vm, send_pt, recv_pt, data],
|
| + True)
|
|
|
|
|
| def test_multiport(test, vm, consoles, params):
|
| @@ -1253,12 +1567,30 @@ def run_virtio_console(test, params, env):
|
| @param consoles: Field of virtio ports with the minimum of 2 items.
|
| @param params: Test parameters '$console_type:$data;...'
|
| """
|
| - test.headline("test_multiport:")
|
| - #Test Loopback
|
| - test.do_test(tloopback, [vm, consoles, params[0]])
|
| + subtest.headline("test_multiport:")
|
| + # Test Loopback
|
| + subtest.do_test(tloopback, [vm, consoles, params[0]])
|
| +
|
| + # Test Performance
|
| + subtest.do_test(tperf, [vm, consoles, params[1]])
|
| +
|
| +
|
| + def test_destructive(test, vm, consoles):
|
| + """
|
| + This is group of test is destructive.
|
|
|
| - #Test Performance
|
| - test.do_test(tperf, [vm, consoles, params[1]])
|
| + @param test: Main test object.
|
| + @param vm: Target virtual machine [vm, session, tmp_dir, ser_session].
|
| + @param consoles: Field of virtio ports with the minimum of 2 items.
|
| + """
|
| + subtest.headline("test_destructive:")
|
| + # Test rmmod
|
| + subtest.do_test(trmmod, [vm, consoles])
|
| + subtest.do_test(tmax_serial_ports, [vm, consoles])
|
| + subtest.do_test(tmax_console_ports, [vm, consoles])
|
| + subtest.do_test(tmax_mix_serial_conosle_port, [vm, consoles])
|
| + subtest.do_test(tshutdown, [vm, consoles])
|
| + subtest.do_test(tmigrate_offline, [vm, consoles])
|
|
|
|
|
| # INITIALIZE
|
| @@ -1270,21 +1602,21 @@ def run_virtio_console(test, params, env):
|
| no_serialports = 0
|
| no_consoles = 0
|
| # consoles required for Smoke test
|
| - if (tsmoke_params.count('serialport')):
|
| + if tsmoke_params.count('serialport'):
|
| no_serialports = max(2, no_serialports)
|
| - if (tsmoke_params.count('console')):
|
| + if tsmoke_params.count('console'):
|
| no_consoles = max(2, no_consoles)
|
| # consoles required for Loopback test
|
| 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 (tperf_params.count('serialport')):
|
| + if tperf_params.count('serialport'):
|
| no_serialports = max(1, no_serialports)
|
| - if (tperf_params.count('console')):
|
| + if tperf_params.count('console'):
|
| no_consoles = max(1, no_consoles)
|
|
|
| - if (no_serialports + no_consoles) == 0:
|
| + if no_serialports + no_consoles == 0:
|
| raise error.TestFail("No tests defined, probably incorrect "
|
| "configuration in tests_base.cfg")
|
|
|
| @@ -1294,26 +1626,35 @@ def run_virtio_console(test, params, env):
|
| pwd = os.path.join(os.environ['AUTODIR'], 'tests/kvm')
|
| vksmd_src = os.path.join(pwd, "scripts/virtio_console_guest.py")
|
| dst_dir = "/tmp"
|
| +
|
| vm[0].copy_files_to(vksmd_src, dst_dir)
|
|
|
| # ACTUAL TESTING
|
| # Defines all available consoles; tests udev and sysfs
|
|
|
| - test = SubTest()
|
| + subtest = SubTest()
|
| try:
|
| init_guest(vm, consoles)
|
|
|
| - test.set_cleanup_func(clean_ports, [vm, consoles])
|
| - #Test Smoke
|
| - test_smoke(test, vm, consoles, tsmoke_params)
|
| + subtest.set_cleanup_func(clean_ports, [vm, consoles])
|
| + # Test Smoke
|
| + test_smoke(subtest, vm, consoles, tsmoke_params)
|
| +
|
| + # Test multiport functionality and performance.
|
| + test_multiport(subtest, vm, consoles, [tloopback_params, tperf_params])
|
|
|
| - #Test multiport functionality and performance.
|
| - test_multiport(test, vm, consoles, [tloopback_params, tperf_params])
|
| + # Test destructive test.
|
| + # Uses stronger clean up function
|
| + (_cleanup_func, _cleanup_args) = subtest.get_cleanup_func()
|
| + subtest.set_cleanup_func(clean_reload_vm, [vm, consoles])
|
| + test_destructive(subtest, vm, consoles)
|
| + subtest.set_cleanup_func(_cleanup_func, _cleanup_args)
|
| finally:
|
| logging.info(("Summary: %d tests passed %d test failed :\n" %
|
| - (test.passed, test.failed)) + test.get_text_result())
|
| + (subtest.passed, subtest.failed)) +
|
| + subtest.get_text_result())
|
|
|
| - if test.is_failed():
|
| + if subtest.is_failed():
|
| raise error.TestFail("Virtio_console test FAILED.")
|
|
|
|
|
|
|