With this module, tests can define multiple clean up functions which will
be called after tests termination inside the tests scripts. These will help
tests which need complex host enviroment setup and clean up.

The clean up function can be defined in tests and will be register to a
global list named with exithandlers of the test. You can register the
clean up functions right after the set up operation finished. And they
will be executed no matter the test is failed or not after the test finished.
And the execution order will be the backward of the register order.

Signed-off-by: Yiqiao Pu <[email protected]>
---
 virt.py                |    8 +++++-
 virttest/funcatexit.py |   68 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+), 1 deletions(-)
 create mode 100644 virttest/funcatexit.py

diff --git a/virt.py b/virt.py
index 9fbea49..0240996 100644
--- a/virt.py
+++ b/virt.py
@@ -2,7 +2,7 @@ import os, sys, logging, imp, Queue
 from autotest.client import test
 from autotest.client.shared import error
 from virttest import utils_misc, utils_params, utils_env, env_process
-from virttest import data_dir, bootstrap
+from virttest import data_dir, bootstrap, funcatexit
 
 
 class virt(test.test):
@@ -132,8 +132,14 @@ class virt(test.test):
                         finally:
                             env.save()
                     test_passed = True
+                    error_message = funcatexit.run_exitfuncs(env, t_type)
+                    if error_message:
+                        logging.error(error_message)
 
                 except Exception, e:
+                    error_message = funcatexit.run_exitfuncs(env, t_type)
+                    if error_message:
+                        logging.error(error_message)
                     logging.error("Test failed: %s: %s",
                                   e.__class__.__name__, e)
                     try:
diff --git a/virttest/funcatexit.py b/virttest/funcatexit.py
new file mode 100644
index 0000000..d9b903c
--- /dev/null
+++ b/virttest/funcatexit.py
@@ -0,0 +1,68 @@
+"""
+funcatexit.py - allow programmer to define multiple exit functions to be
+executed upon normal cases termination. Can be used for the environment clean
+up functions. The basic idea is like atexit from python libs.
+"""
+
+__all__ = ["register", "run_exitfuncs", "unregister"]
+
+import logging, traceback
+
+def run_exitfuncs(env, test_type):
+    """
+    Run any registered exit functions.
+    exithandlers is traversed in reverse order so functions are executed
+    last in, first out.
+
+    param env: the global objects used by tests
+    param test_type: test type mark for exit functions 
+    """
+    error_message = ""
+    if env.data.get("exithandlers__%s" % test_type):
+        exithandlers = env.data.get("exithandlers__%s" % test_type)
+        while exithandlers:
+            func, targs, kargs = exithandlers.pop()
+            try:
+                func(*targs, **kargs)
+            except Exception, details:
+                error_message += "Error in %s:" % func.func_name
+                error_message += " %s\n" % details
+                traceback.print_exc()
+
+    return error_message
+
+
+def register(env, test_type, func, *targs, **kargs):
+    """
+    Register a function to be executed upon case termination.
+    func is returned to facilitate usage as a decorator.
+
+    param env: the global objects used by tests
+    param test_type: test type mark for exit functions 
+    param func: function to be called at exit
+    param targs: optional arguments to pass to func
+    param kargs: optional keyword arguments to pass to func
+    """
+    exithandlers = "exithandlers__%s" % test_type
+    if not env.data.get(exithandlers):
+        env.data[exithandlers] = []
+
+    env.data[exithandlers].append((func, targs, kargs))
+    return func
+
+
+def unregister(env, test_type, func, *targs, **kargs):
+    """
+    Unregister a function to be executed upon case termination.
+    func is returned to facilitate usage as a decorator.
+
+    param env: the global objects used by tests
+    param test_type: test type mark for exit functions 
+    param func: function to be called at exit
+    param targs: optional arguments to pass to func
+    param kargs: optional keyword arguments to pass to func
+    """
+    exithandlers = "exithandlers__%s" % test_type
+    if env.data.get(exithandlers):
+        env.data[exhandlers].remove((func, targs, kargs))
+    return func
-- 
1.7.7.6

_______________________________________________
Virt-test-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/virt-test-devel

Reply via email to