1import os, logging, imp
2from autotest_lib.client.bin import test
3from autotest_lib.client.common_lib import error
4from autotest_lib.client.virt import virt_utils, virt_env_process
5
6
7class kvm(test.test):
8    """
9    Suite of KVM virtualization functional tests.
10    Contains tests for testing both KVM kernel code and userspace code.
11
12    @copyright: Red Hat 2008-2009
13    @author: Uri Lublin (uril@redhat.com)
14    @author: Dror Russo (drusso@redhat.com)
15    @author: Michael Goldish (mgoldish@redhat.com)
16    @author: David Huff (dhuff@redhat.com)
17    @author: Alexey Eromenko (aeromenk@redhat.com)
18    @author: Mike Burns (mburns@redhat.com)
19
20    @see: http://www.linux-kvm.org/page/KVM-Autotest/Client_Install
21            (Online doc - Getting started with KVM testing)
22    """
23    version = 1
24    env_version = 1
25
26
27    def initialize(self, params):
28        # Change the value of the preserve_srcdir attribute according to
29        # the value present on the configuration file (defaults to yes)
30        if params.get("preserve_srcdir", "yes") == "yes":
31            self.preserve_srcdir = True
32
33
34    def run_once(self, params):
35        # Convert params to a Params object
36        params = virt_utils.Params(params)
37
38        # If a dependency test prior to this test has failed, let's fail
39        # it right away as TestNA.
40        if params.get("dependency_failed") == 'yes':
41            raise error.TestNAError("Test dependency failed")
42
43        # Report the parameters we've received and write them as keyvals
44        logging.debug("Test parameters:")
45        keys = params.keys()
46        keys.sort()
47        for key in keys:
48            logging.debug("    %s = %s", key, params[key])
49            self.write_test_keyval({key: params[key]})
50
51        # Set the log file dir for the logging mechanism used by kvm_subprocess
52        # (this must be done before unpickling env)
53        virt_utils.set_log_file_dir(self.debugdir)
54
55        # Open the environment file
56        env_filename = os.path.join(self.bindir, params.get("env", "env"))
57        env = virt_utils.Env(env_filename, self.env_version)
58
59        test_passed = False
60
61        try:
62            try:
63                try:
64                    # Get the test routine corresponding to the specified
65                    # test type
66                    t_type = params.get("type")
67                    # Verify if we have the correspondent source file for it
68                    virt_dir = os.path.dirname(virt_utils.__file__)
69                    subtest_dir_virt = os.path.join(virt_dir, "tests")
70                    subtest_dir_kvm = os.path.join(self.bindir, "tests")
71                    subtest_dir = None
72                    for d in [subtest_dir_kvm, subtest_dir_virt]:
73                        module_path = os.path.join(d, "%s.py" % t_type)
74                        if os.path.isfile(module_path):
75                            subtest_dir = d
76                            break
77                    if subtest_dir is None:
78                        raise error.TestError("Could not find test file %s.py "
79                                              "on either %s or %s directory" %
80                                              (t_type, subtest_dir_kvm,
81                                              subtest_dir_virt))
82                    # Load the test module
83                    f, p, d = imp.find_module(t_type, [subtest_dir])
84                    test_module = imp.load_module(t_type, f, p, d)
85                    f.close()
86
87                    # Preprocess
88                    try:
89                        virt_env_process.preprocess(self, params, env)
90                    finally:
91                        env.save()
92                    # Run the test function
93                    run_func = getattr(test_module, "run_%s" % t_type)
94                    try:
95                        run_func(self, params, env)
96                    finally:
97                        env.save()
98                    test_passed = True
99
100                except Exception, e:
101                    logging.error("Test failed: %s: %s",
102                                  e.__class__.__name__, e)
103                    try:
104                        virt_env_process.postprocess_on_error(
105                            self, params, env)
106                    finally:
107                        env.save()
108                    raise
109
110            finally:
111                # Postprocess
112                try:
113                    try:
114                        virt_env_process.postprocess(self, params, env)
115                    except Exception, e:
116                        if test_passed:
117                            raise
118                        logging.error("Exception raised during "
119                                      "postprocessing: %s", e)
120                finally:
121                    env.save()
122
123        except Exception, e:
124            if params.get("abort_on_error") != "yes":
125                raise
126            # Abort on error
127            logging.info("Aborting job (%s)", e)
128            for vm in env.get_all_vms():
129                if vm.is_dead():
130                    continue
131                logging.info("VM '%s' is alive.", vm.name)
132                for m in vm.monitors:
133                    logging.info("'%s' has a %s monitor unix socket at: %s",
134                                 vm.name, m.protocol, m.filename)
135                logging.info("The command line used to start '%s' was:\n%s",
136                             vm.name, vm.make_qemu_command())
137            raise error.JobError("Abort requested (%s)" % e)
138