summaryrefslogtreecommitdiff
path: root/runtests.py
diff options
context:
space:
mode:
Diffstat (limited to 'runtests.py')
-rwxr-xr-xruntests.py197
1 files changed, 197 insertions, 0 deletions
diff --git a/runtests.py b/runtests.py
new file mode 100755
index 000000000..7660546c8
--- /dev/null
+++ b/runtests.py
@@ -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:])