forked from numpy/numpy
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ENH: Add a runtests.py script for running the test suite
The script builds Numpy and runs the test suite of the built version. This is useful for development.
- Loading branch information
Showing
1 changed file
with
197 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
#!/usr/bin/env python | ||
""" | ||
runtests.py [OPTIONS] [-- ARGS] | ||
Run tests, building the project first. | ||
Examples:: | ||
$ python runtests.py | ||
$ python runtests.py -s {SAMPLE_SUBMODULE} | ||
$ python runtests.py -t {SAMPLE_TEST} | ||
$ python runtests.py --ipython | ||
""" | ||
|
||
# | ||
# This is a generic test runner script for projects using Numpy's test | ||
# framework. Change the following values to adapt to your project: | ||
# | ||
|
||
PROJECT_MODULE = "numpy" | ||
PROJECT_ROOT_FILES = ['numpy', 'LICENSE.txt', 'setup.py'] | ||
SAMPLE_TEST = "numpy/linalg/tests/test_linalg.py:test_byteorder_check" | ||
SAMPLE_SUBMODULE = "linalg" | ||
|
||
# --------------------------------------------------------------------- | ||
|
||
__doc__ = __doc__.format(**globals()) | ||
|
||
import sys | ||
import os | ||
|
||
# In case we are run from the source directory, we don't want to import the | ||
# project from there: | ||
sys.path.pop(0) | ||
|
||
import shutil | ||
import subprocess | ||
from argparse import ArgumentParser, REMAINDER | ||
|
||
def main(argv): | ||
parser = ArgumentParser(usage=__doc__.lstrip()) | ||
parser.add_argument("--verbose", "-v", action="count", default=1, | ||
help="more verbosity") | ||
parser.add_argument("--no-build", "-n", action="store_true", default=False, | ||
help="do not build the project (use system installed version)") | ||
parser.add_argument("--build-only", "-b", action="store_true", default=False, | ||
help="just build, do not run any tests") | ||
parser.add_argument("--doctests", action="store_true", default=False, | ||
help="Run doctests in module") | ||
parser.add_argument("--coverage", action="store_true", default=False, | ||
help=("report coverage of project code. HTML output goes " | ||
"under build/coverage")) | ||
parser.add_argument("--mode", "-m", default="fast", | ||
help="'fast', 'full', or something that could be " | ||
"passed to nosetests -A [default: fast]") | ||
parser.add_argument("--submodule", "-s", default=None, | ||
help="Submodule whose tests to run (cluster, constants, ...)") | ||
parser.add_argument("--pythonpath", "-p", default=None, | ||
help="Paths to prepend to PYTHONPATH") | ||
parser.add_argument("--tests", "-t", action='append', | ||
help="Specify tests to run") | ||
parser.add_argument("--python", action="store_true", | ||
help="Start a Python shell with PYTHONPATH set") | ||
parser.add_argument("--ipython", "-i", action="store_true", | ||
help="Start IPython shell with PYTHONPATH set") | ||
parser.add_argument("--shell", action="store_true", | ||
help="Start Unix shell with PYTHONPATH set") | ||
parser.add_argument("--debug", "-g", action="store_true", | ||
help="Debug build") | ||
parser.add_argument("args", metavar="ARGS", default=[], nargs=REMAINDER, | ||
help="Arguments to pass to Nose") | ||
args = parser.parse_args(argv) | ||
|
||
if args.pythonpath: | ||
for p in reversed(args.pythonpath.split(os.pathsep)): | ||
sys.path.insert(0, p) | ||
|
||
if not args.no_build: | ||
site_dir = build_project(args) | ||
sys.path.insert(0, site_dir) | ||
os.environ['PYTHONPATH'] = site_dir | ||
|
||
if args.python: | ||
import code | ||
code.interact() | ||
sys.exit(0) | ||
|
||
if args.ipython: | ||
import IPython | ||
IPython.embed() | ||
sys.exit(0) | ||
|
||
if args.shell: | ||
shell = os.environ.get('SHELL', 'sh') | ||
print("Spawning a Unix shell...") | ||
os.execv(shell, [shell]) | ||
sys.exit(1) | ||
|
||
extra_argv = args.args | ||
|
||
if args.coverage: | ||
dst_dir = os.path.join('build', 'coverage') | ||
fn = os.path.join(dst_dir, 'coverage_html.js') | ||
if os.path.isdir(dst_dir) and os.path.isfile(fn): | ||
shutil.rmtree(dst_dir) | ||
extra_argv += ['--cover-html', | ||
'--cover-html-dir='+dst_dir] | ||
|
||
if args.build_only: | ||
sys.exit(0) | ||
elif args.submodule: | ||
modname = PROJECT_MODULE + '.' + args.submodule | ||
try: | ||
__import__(modname) | ||
test = sys.modules[modname].test | ||
except (ImportError, KeyError, AttributeError): | ||
print("Cannot run tests for %s" % modname) | ||
sys.exit(2) | ||
elif args.tests: | ||
def test(*a, **kw): | ||
extra_argv = kw.pop('extra_argv', ()) | ||
extra_argv = extra_argv + args.tests[1:] | ||
kw['extra_argv'] = extra_argv | ||
from numpy.testing import Tester | ||
return Tester(args.tests[0]).test(*a, **kw) | ||
else: | ||
__import__(PROJECT_MODULE) | ||
test = sys.modules[PROJECT_MODULE].test | ||
|
||
result = test(args.mode, | ||
verbose=args.verbose, | ||
extra_argv=args.args, | ||
doctests=args.doctests, | ||
coverage=args.coverage) | ||
|
||
if result.wasSuccessful(): | ||
sys.exit(0) | ||
else: | ||
sys.exit(1) | ||
|
||
def build_project(args): | ||
""" | ||
Build a dev version of the project. | ||
Returns | ||
------- | ||
site_dir | ||
site-packages directory where it was installed | ||
""" | ||
|
||
root_dir = os.path.abspath(os.path.join(os.path.dirname(__file__))) | ||
root_ok = [os.path.exists(os.path.join(root_dir, fn)) | ||
for fn in PROJECT_ROOT_FILES] | ||
if not all(root_ok): | ||
print("To build the project, run runtests.py in " | ||
"git checkout or unpacked source") | ||
sys.exit(1) | ||
|
||
dst_dir = os.path.join(root_dir, 'build', 'testenv') | ||
|
||
env = dict(os.environ) | ||
cmd = [sys.executable, 'setup.py'] | ||
|
||
# Always use ccache, if installed | ||
env['PATH'] = os.pathsep.join(['/usr/lib/ccache'] | ||
+ env.get('PATH', '').split(os.pathsep)) | ||
|
||
if args.debug: | ||
# assume everyone uses gcc/gfortran | ||
env['OPT'] = '-O0 -ggdb' | ||
env['FOPT'] = '-O0 -ggdb' | ||
cmd += ["build", "--debug"] | ||
|
||
cmd += ['install', '--prefix=' + dst_dir] | ||
|
||
print("Building, see build.log...") | ||
with open('build.log', 'w') as log: | ||
ret = subprocess.call(cmd, env=env, stdout=log, stderr=log, | ||
cwd=root_dir) | ||
|
||
if ret == 0: | ||
print("Build OK") | ||
else: | ||
with open('build.log', 'r') as f: | ||
print(f.read()) | ||
print("Build failed!") | ||
sys.exit(1) | ||
|
||
from distutils.sysconfig import get_python_lib | ||
site_dir = get_python_lib(prefix=dst_dir) | ||
|
||
return site_dir | ||
|
||
if __name__ == "__main__": | ||
main(argv=sys.argv[1:]) |