Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(184)

Side by Side Diff: recipe_engine/third_party/setuptools/command/test.py

Issue 1344583003: Recipe package system. (Closed) Base URL: git@github.com:luci/recipes-py.git@master
Patch Set: Recompiled proto Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 from distutils.errors import DistutilsOptionError
2 from unittest import TestLoader
3 import unittest
4 import sys
5
6 from pkg_resources import (resource_listdir, resource_exists, normalize_path,
7 working_set, _namespace_packages,
8 add_activation_listener, require, EntryPoint)
9 from setuptools import Command
10 from setuptools.compat import PY3
11 from setuptools.py31compat import unittest_main
12
13
14 class ScanningLoader(TestLoader):
15 def loadTestsFromModule(self, module):
16 """Return a suite of all tests cases contained in the given module
17
18 If the module is a package, load tests from all the modules in it.
19 If the module has an ``additional_tests`` function, call it and add
20 the return value to the tests.
21 """
22 tests = []
23 tests.append(TestLoader.loadTestsFromModule(self, module))
24
25 if hasattr(module, "additional_tests"):
26 tests.append(module.additional_tests())
27
28 if hasattr(module, '__path__'):
29 for file in resource_listdir(module.__name__, ''):
30 if file.endswith('.py') and file != '__init__.py':
31 submodule = module.__name__ + '.' + file[:-3]
32 else:
33 if resource_exists(module.__name__, file + '/__init__.py'):
34 submodule = module.__name__ + '.' + file
35 else:
36 continue
37 tests.append(self.loadTestsFromName(submodule))
38
39 if len(tests) != 1:
40 return self.suiteClass(tests)
41 else:
42 return tests[0] # don't create a nested suite for only one return
43
44
45 class test(Command):
46 """Command to run unit tests after in-place build"""
47
48 description = "run unit tests after in-place build"
49
50 user_options = [
51 ('test-module=', 'm', "Run 'test_suite' in specified module"),
52 ('test-suite=', 's',
53 "Test suite to run (e.g. 'some_module.test_suite')"),
54 ('test-runner=', 'r', "Test runner to use"),
55 ]
56
57 def initialize_options(self):
58 self.test_suite = None
59 self.test_module = None
60 self.test_loader = None
61 self.test_runner = None
62
63 def finalize_options(self):
64
65 if self.test_suite is None:
66 if self.test_module is None:
67 self.test_suite = self.distribution.test_suite
68 else:
69 self.test_suite = self.test_module + ".test_suite"
70 elif self.test_module:
71 raise DistutilsOptionError(
72 "You may specify a module or a suite, but not both"
73 )
74
75 self.test_args = [self.test_suite]
76
77 if self.verbose:
78 self.test_args.insert(0, '--verbose')
79 if self.test_loader is None:
80 self.test_loader = getattr(self.distribution, 'test_loader', None)
81 if self.test_loader is None:
82 self.test_loader = "setuptools.command.test:ScanningLoader"
83 if self.test_runner is None:
84 self.test_runner = getattr(self.distribution, 'test_runner', None)
85
86 def with_project_on_sys_path(self, func):
87 with_2to3 = PY3 and getattr(self.distribution, 'use_2to3', False)
88
89 if with_2to3:
90 # If we run 2to3 we can not do this inplace:
91
92 # Ensure metadata is up-to-date
93 self.reinitialize_command('build_py', inplace=0)
94 self.run_command('build_py')
95 bpy_cmd = self.get_finalized_command("build_py")
96 build_path = normalize_path(bpy_cmd.build_lib)
97
98 # Build extensions
99 self.reinitialize_command('egg_info', egg_base=build_path)
100 self.run_command('egg_info')
101
102 self.reinitialize_command('build_ext', inplace=0)
103 self.run_command('build_ext')
104 else:
105 # Without 2to3 inplace works fine:
106 self.run_command('egg_info')
107
108 # Build extensions in-place
109 self.reinitialize_command('build_ext', inplace=1)
110 self.run_command('build_ext')
111
112 ei_cmd = self.get_finalized_command("egg_info")
113
114 old_path = sys.path[:]
115 old_modules = sys.modules.copy()
116
117 try:
118 sys.path.insert(0, normalize_path(ei_cmd.egg_base))
119 working_set.__init__()
120 add_activation_listener(lambda dist: dist.activate())
121 require('%s==%s' % (ei_cmd.egg_name, ei_cmd.egg_version))
122 func()
123 finally:
124 sys.path[:] = old_path
125 sys.modules.clear()
126 sys.modules.update(old_modules)
127 working_set.__init__()
128
129 def run(self):
130 if self.distribution.install_requires:
131 self.distribution.fetch_build_eggs(
132 self.distribution.install_requires)
133 if self.distribution.tests_require:
134 self.distribution.fetch_build_eggs(self.distribution.tests_require)
135
136 if self.test_suite:
137 cmd = ' '.join(self.test_args)
138 if self.dry_run:
139 self.announce('skipping "unittest %s" (dry run)' % cmd)
140 else:
141 self.announce('running "unittest %s"' % cmd)
142 self.with_project_on_sys_path(self.run_tests)
143
144 def run_tests(self):
145 # Purge modules under test from sys.modules. The test loader will
146 # re-import them from the build location. Required when 2to3 is used
147 # with namespace packages.
148 if PY3 and getattr(self.distribution, 'use_2to3', False):
149 module = self.test_args[-1].split('.')[0]
150 if module in _namespace_packages:
151 del_modules = []
152 if module in sys.modules:
153 del_modules.append(module)
154 module += '.'
155 for name in sys.modules:
156 if name.startswith(module):
157 del_modules.append(name)
158 list(map(sys.modules.__delitem__, del_modules))
159
160 unittest_main(
161 None, None, [unittest.__file__] + self.test_args,
162 testLoader=self._resolve_as_ep(self.test_loader),
163 testRunner=self._resolve_as_ep(self.test_runner),
164 )
165
166 @staticmethod
167 def _resolve_as_ep(val):
168 """
169 Load the indicated attribute value, called, as a as if it were
170 specified as an entry point.
171 """
172 if val is None:
173 return
174 parsed = EntryPoint.parse("x=" + val)
175 return parsed.load(require=False)()
OLDNEW
« no previous file with comments | « recipe_engine/third_party/setuptools/command/setopt.py ('k') | recipe_engine/third_party/setuptools/command/upload_docs.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698