aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2015-05-30 12:16:07 -0400
committerMike Frysinger <vapier@gentoo.org>2015-06-03 22:50:39 -0400
commitc17e9074f2853e54fc7fb08049453d54a1b6cb8b (patch)
tree41ca38d1e50a4bc0d8169e1224ad071aa4b3d937 /runtests
parentofficially drop support for python 2.6, 3.1, and 3.2 (diff)
downloadportage-c17e9074f2853e54fc7fb08049453d54a1b6cb8b.tar.gz
portage-c17e9074f2853e54fc7fb08049453d54a1b6cb8b.tar.bz2
portage-c17e9074f2853e54fc7fb08049453d54a1b6cb8b.zip
runtests: rewrite in python
The bash was getting ugly, and this allows us to add more smarts sanely to the main script.
Diffstat (limited to 'runtests')
-rwxr-xr-xruntests156
1 files changed, 156 insertions, 0 deletions
diff --git a/runtests b/runtests
new file mode 100755
index 000000000..d1f7b6f5a
--- /dev/null
+++ b/runtests
@@ -0,0 +1,156 @@
+#!/usr/bin/python
+# Copyright 2010-2015 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+#
+# Note: We don't want to import portage modules directly because we do things
+# like run the testsuite through multiple versions of python.
+
+"""Helper script to run portage unittests against different python versions.
+
+Note: Any additional arguments will be passed down directly to the underlying
+unittest runner. This lets you select specific tests to execute.
+"""
+
+from __future__ import print_function
+
+import argparse
+import os
+import sys
+import subprocess
+
+
+# These are the versions we fully support and require to pass tests.
+PYTHON_SUPPORTED_VERSIONS = [
+ '2.7',
+ '3.3',
+ '3.4',
+]
+# The rest are just "nice to have".
+PYTHON_NICE_VERSIONS = [
+ 'pypy',
+ '3.5',
+]
+
+EPREFIX = os.environ.get('PORTAGE_OVERRIDE_EPREFIX', '/')
+
+
+class Colors(object):
+ """Simple object holding color constants."""
+
+ _COLORS_YES = ('y', 'yes', 'true')
+ _COLORS_NO = ('n', 'no', 'false')
+
+ GOOD = BAD = NORMAL = ''
+
+ def __init__(self, colorize=None):
+ if colorize is None:
+ nocolors = os.environ.get('NOCOLOR', 'false')
+ # Ugh, look away, for here we invert the world!
+ if nocolors in self._COLORS_YES:
+ colorize = False
+ elif nocolors in self._COLORS_NO:
+ colorize = True
+ else:
+ raise ValueError('$NOCOLORS is invalid: %s' % nocolors)
+ else:
+ if colorize in self._COLORS_YES:
+ colorize = True
+ elif colorize in self._COLORS_NO:
+ colorize = False
+ else:
+ raise ValueError('--colors is invalid: %s' % colorize)
+
+ if colorize:
+ self.GOOD = '\033[1;32m'
+ self.BAD = '\033[1;31m'
+ self.NORMAL = '\033[0m'
+
+
+def get_python_executable(ver):
+ """Find the right python executable for |ver|"""
+ if ver == 'pypy':
+ prog = 'pypy'
+ else:
+ prog = 'python' + ver
+ return os.path.join(EPREFIX, 'usr', 'bin', prog)
+
+
+def get_parser():
+ """Return a argument parser for this module"""
+ epilog = """Examples:
+List all the available unittests.
+$ %(prog)s --list
+
+Run against specific versions of python.
+$ %(prog)s --python-version '2.7 3.3'
+
+Run just one unittest.
+$ %(prog)s pym/portage/tests/xpak/test_decodeint.py
+"""
+ parser = argparse.ArgumentParser(
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ epilog=epilog)
+ parser.add_argument('--color', type=str, default=None,
+ help='Whether to use colorized output (default is auto)')
+ parser.add_argument('--python-versions', action='append',
+ help='Versions of python to test (default is test available)')
+ return parser
+
+
+def main(argv):
+ parser = get_parser()
+ opts, args = parser.parse_known_args(argv)
+ colors = Colors(colorize=opts.color)
+
+ # Figure out all the versions we want to test.
+ if opts.python_versions is None:
+ ignore_missing = True
+ pyversions = PYTHON_SUPPORTED_VERSIONS + PYTHON_NICE_VERSIONS
+ else:
+ ignore_missing = False
+ pyversions = []
+ for ver in opts.python_versions:
+ if ver == 'supported':
+ pyversions.extend(PYTHON_SUPPORTED_VERSIONS)
+ else:
+ pyversions.extend(ver.split())
+
+ # Actually test those versions now.
+ statuses = []
+ for ver in pyversions:
+ prog = get_python_executable(ver)
+ cmd = [prog, '-b', '-Wd', 'pym/portage/tests/runTests.py'] + args
+ if os.access(prog, os.X_OK):
+ print('%sTesting with Python %s...%s' %
+ (colors.GOOD, ver, colors.NORMAL))
+ statuses.append(subprocess.call(cmd))
+ elif not ignore_missing:
+ print('%sCould not find requested Python %s%s' %
+ (colors.BAD, ver, colors.NORMAL))
+ statuses.append(1)
+ print()
+
+ # Then summarize it all.
+ print('\nSummary:\n')
+ width = 10
+ header = '| %-*s | %s' % (width, 'Version', 'Status')
+ print('%s\n|%s' % (header, '-' * (len(header) - 1)))
+ for ver, status in zip(pyversions, statuses):
+ if status:
+ color = colors.BAD
+ msg = 'FAIL'
+ else:
+ color = colors.GOOD
+ msg = 'PASS'
+ print('| %s%-*s%s | %s%s%s' %
+ (color, width, ver, colors.NORMAL, color, msg, colors.NORMAL))
+ exit(sum(statuses))
+
+
+if __name__ == '__main__':
+ try:
+ main(sys.argv[1:])
+ except KeyboardInterrupt:
+ print('interrupted ...', file=sys.stderr)
+ exit(1)