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