[PATCH 2/5] virt.virt_env_process: fail tests due to guest screen inactivity

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

 



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


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