In a very specific test (unattended_install), all OEM installer mechanism will present intense guest screen activity, so screen inactivity for a relatively long time almost always mean something went very wrong and the installer is stuck. So create a mechanism to detect screen inactivity for any vm that takes place in the test - have a timer for each vm that is reset only if the next screenshot is different than the previous. So, if the vm got stuck somewhere at the install process, for example: * Wrong Windows CD Key * Guest OS does not see a disk controller due to lack of drivers * BIOS got stuck And other similar cases, we'll have a test failure before the full test timeout (that for Windows may be up to 3 hours). So we save time and know about such situations earlier. The patch introduces the parameters on base.cfg, subtests.cfg, and also introduces a sensible default for inactivity treshold (30 min). Signed-off-by: Lucas Meneghel Rodrigues <lmr@xxxxxxxxxx> --- client/virt/tests/unattended_install.py | 1 + client/virt/virt_env_process.py | 39 +++++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/client/virt/tests/unattended_install.py b/client/virt/tests/unattended_install.py index a78e2bc..57161a8 100644 --- a/client/virt/tests/unattended_install.py +++ b/client/virt/tests/unattended_install.py @@ -800,6 +800,7 @@ def run_unattended_install(test, params, env): else: raise e vm.verify_kernel_crash() + test.verify_background_errors() if params.get("wait_no_ack", "no") == "no": client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: diff --git a/client/virt/virt_env_process.py b/client/virt/virt_env_process.py index 27a60d3..5f33606 100644 --- a/client/virt/virt_env_process.py +++ b/client/virt/virt_env_process.py @@ -1,4 +1,4 @@ -import os, time, commands, re, logging, glob, threading, shutil +import os, time, commands, re, logging, glob, threading, shutil, sys from autotest_lib.client.bin import utils from autotest_lib.client.common_lib import error import aexpect, virt_utils, kvm_monitor, ppm_utils, virt_test_setup @@ -16,6 +16,18 @@ _screendump_thread = None _screendump_thread_termination_event = None +class VMScreenInactiveError(virt_vm.VMError): + def __init__(self, vm, inactive_time): + virt_vm.VMError.__init__(self) + self.vm = vm + self.inactive_time = inactive_time + + def __str__(self): + msg = ("%s screen is inactive for %d s (%d min)" % + (self.vm.name, self.inactive_time, self.inactive_time/60)) + return msg + + def ffmpeg_path(): try: return virt_utils.find_command("ffmpeg") @@ -491,14 +503,19 @@ def _take_screendumps(test, params, env): virt_utils.generate_random_string(6)) delay = float(params.get("screendump_delay", 5)) quality = int(params.get("screendump_quality", 30)) + inactivity_treshold = float(params.get("inactivity_treshold", 1800)) + inactivity_watcher = params.get("inactivity_watcher", "log") cache = {} counter = {} + inactivity = {} while True: for vm in env.get_all_vms(): if vm not in counter.keys(): counter[vm] = 0 + if vm not in inactivity.keys(): + inactivity[vm] = time.time() if not vm.is_alive(): continue try: @@ -524,17 +541,29 @@ def _take_screendumps(test, params, env): counter[vm] += 1 screendump_filename = os.path.join(screendump_dir, "%04d.jpg" % counter[vm]) - hash = utils.hash_file(temp_filename) - if hash in cache: + image_hash = utils.hash_file(temp_filename) + if image_hash in cache: + time_inactive = time.time() - inactivity[vm] + if time_inactive > inactivity_treshold: + if inactivity_watcher == "error": + try: + raise VMScreenInactiveError(vm, time_inactive) + except VMScreenInactiveError: + test.background_errors.put(sys.exc_info()) + else: + logging.debug("%s screen is inactive for more than " + "%d s (%d min)", vm.name, time_inactive, + time_inactive/60) try: - os.link(cache[hash], screendump_filename) + os.link(cache[image_hash], screendump_filename) except OSError: pass else: + inactivity[vm] = time.time() try: image = PIL.Image.open(temp_filename) image.save(screendump_filename, format="JPEG", quality=quality) - cache[hash] = screendump_filename + cache[image_hash] = screendump_filename except NameError: pass os.unlink(temp_filename) -- 1.7.7 -- 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