virt.virt_test_utils: run_autotest - 'tar' needs relative paths to strip the leading '/'
[autotest-zwu.git] / client / setup_modules.py
blob49391200e369a545846b6e954992d2606eeef936
1 __author__ = "jadmanski@google.com (John Admanski)"
3 import os, sys
5 # This must run on Python versions less than 2.4.
6 dirname = os.path.dirname(sys.modules[__name__].__file__)
7 common_dir = os.path.abspath(os.path.join(dirname, "common_lib"))
8 sys.path.insert(0, common_dir)
9 import check_version
10 sys.path.pop(0)
11 check_version.check_python_version()
13 import new, glob, traceback
16 def _create_module(name):
17 """Create a single top-level module"""
18 module = new.module(name)
19 sys.modules[name] = module
20 return module
23 def _create_module_and_parents(name):
24 """Create a module, and all the necessary parents"""
25 parts = name.split(".")
26 # first create the top-level module
27 parent = _create_module(parts[0])
28 created_parts = [parts[0]]
29 parts.pop(0)
30 # now, create any remaining child modules
31 while parts:
32 child_name = parts.pop(0)
33 module = new.module(child_name)
34 setattr(parent, child_name, module)
35 created_parts.append(child_name)
36 sys.modules[".".join(created_parts)] = module
37 parent = module
40 def _import_children_into_module(parent_module_name, path):
41 """Import all the packages on a path into a parent module"""
42 # find all the packages at 'path'
43 names = []
44 for filename in os.listdir(path):
45 full_name = os.path.join(path, filename)
46 if not os.path.isdir(full_name):
47 continue # skip files
48 if "." in filename:
49 continue # if "." is in the name it's not a valid package name
50 if not os.access(full_name, os.R_OK | os.X_OK):
51 continue # need read + exec access to make a dir importable
52 if "__init__.py" in os.listdir(full_name):
53 names.append(filename)
54 # import all the packages and insert them into 'parent_module'
55 sys.path.insert(0, path)
56 for name in names:
57 module = __import__(name)
58 # add the package to the parent
59 parent_module = sys.modules[parent_module_name]
60 setattr(parent_module, name, module)
61 full_name = parent_module_name + "." + name
62 sys.modules[full_name] = module
63 # restore the system path
64 sys.path.pop(0)
67 def import_module(module, from_where):
68 """Equivalent to 'from from_where import module'
69 Returns the corresponding module"""
70 from_module = __import__(from_where, globals(), locals(), [module])
71 return getattr(from_module, module)
74 def _autotest_logging_handle_error(self, record):
75 """Method to monkey patch into logging.Handler to replace handleError."""
76 # The same as the default logging.Handler.handleError but also prints
77 # out the original record causing the error so there is -some- idea
78 # about which call caused the logging error.
79 import logging
80 if logging.raiseExceptions:
81 # Avoid recursion as the below output can end up back in here when
82 # something has *seriously* gone wrong in autotest.
83 logging.raiseExceptions = 0
84 sys.stderr.write('Exception occurred formatting message: '
85 '%r using args %r\n' % (record.msg, record.args))
86 traceback.print_stack()
87 sys.stderr.write('-' * 50 + '\n')
88 traceback.print_exc()
89 sys.stderr.write('Future logging formatting exceptions disabled.\n')
92 def _monkeypatch_logging_handle_error():
93 # Hack out logging.py*
94 logging_py = os.path.join(os.path.dirname(__file__), "common_lib",
95 "logging.py*")
96 if glob.glob(logging_py):
97 os.system("rm -f %s" % logging_py)
99 # Monkey patch our own handleError into the logging module's StreamHandler.
100 # A nicer way of doing this -might- be to have our own logging module define
101 # an autotest Logger instance that added our own Handler subclass with this
102 # handleError method in it. But that would mean modifying tons of code.
103 import logging
104 assert callable(logging.Handler.handleError)
105 logging.Handler.handleError = _autotest_logging_handle_error
108 def setup(base_path, root_module_name=""):
110 Perform all the necessary setup so that all the packages at
111 'base_path' can be imported via "import root_module_name.package".
112 If root_module_name is empty, then all the packages at base_path
113 are inserted as top-level packages.
115 Also, setup all the common.* aliases for modules in the common
116 library.
118 The setup must be different if you are running on an Autotest server
119 or on a test machine that just has the client directories installed.
121 # Hack... Any better ideas?
122 if (root_module_name == 'autotest_lib.client' and
123 os.path.exists(os.path.join(os.path.dirname(__file__),
124 '..', 'server'))):
125 root_module_name = 'autotest_lib'
126 base_path = os.path.abspath(os.path.join(base_path, '..'))
128 _create_module_and_parents(root_module_name)
129 _import_children_into_module(root_module_name, base_path)
131 if root_module_name == 'autotest_lib':
132 # Allow locally installed third party packages to be found
133 # before any that are installed on the system itself when not.
134 # running as a client.
135 # This is primarily for the benefit of frontend and tko so that they
136 # may use libraries other than those available as system packages.
137 sys.path.insert(0, os.path.join(base_path, "site-packages"))
139 _monkeypatch_logging_handle_error()