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
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.
-rw-r--r--DEVELOPING2
-rwxr-xr-xruntests156
-rwxr-xr-xruntests.sh109
3 files changed, 157 insertions, 110 deletions
diff --git a/DEVELOPING b/DEVELOPING
index 0b0bb60bd..31b559402 100644
--- a/DEVELOPING
+++ b/DEVELOPING
@@ -225,7 +225,7 @@ Second create a git tag for this release:
Then create the tarball and run the tests:
./mkrelease.sh --changelog-rev v2.2.7 --tag --runtests 2.2.8
Make sure you have all supported python versions installed first
-(see PYTHON_SUPPORTED_VERSIONS in runtests.sh).
+(see PYTHON_SUPPORTED_VERSIONS in runtests).
Version bump the ebuild and verify it can re-install itself:
emerge portage
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)
diff --git a/runtests.sh b/runtests.sh
deleted file mode 100755
index a7ca101b8..000000000
--- a/runtests.sh
+++ /dev/null
@@ -1,109 +0,0 @@
-#!/bin/bash
-# Copyright 2010-2014 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-
-# These are the versions we care about. The rest are just "nice to have".
-PYTHON_SUPPORTED_VERSIONS="2.7 3.3 3.4"
-PYTHON_VERSIONS="2.7 pypy 3.3 3.4 3.5"
-
-# has to be run from portage root dir
-cd "${0%/*}" || exit 1
-
-case "${NOCOLOR:-false}" in
- yes|true)
- GOOD=
- BAD=
- NORMAL=
- ;;
- no|false)
- GOOD=$'\e[1;32m'
- BAD=$'\e[1;31m'
- NORMAL=$'\e[0m'
- ;;
-esac
-
-interrupted() {
- echo "interrupted." >&2
- exit 1
-}
-
-trap interrupted SIGINT
-
-unused_args=()
-IGNORE_MISSING_VERSIONS=true
-
-while [ $# -gt 0 ] ; do
- case "$1" in
- --python-versions=*)
- PYTHON_VERSIONS=${1#--python-versions=}
- IGNORE_MISSING_VERSIONS=false
- ;;
- --python-versions)
- shift
- PYTHON_VERSIONS=$1
- IGNORE_MISSING_VERSIONS=false
- ;;
- *)
- unused_args[${#unused_args[@]}]=$1
- ;;
- esac
- shift
-done
-if [[ ${PYTHON_VERSIONS} == "supported" ]] ; then
- PYTHON_VERSIONS=${PYTHON_SUPPORTED_VERSIONS}
-fi
-
-set -- "${unused_args[@]}"
-
-eprefix=${PORTAGE_OVERRIDE_EPREFIX}
-exit_status="0"
-found_versions=()
-status_array=()
-for version in ${PYTHON_VERSIONS}; do
- if [[ $version = 'pypy' ]] ; then
- executable=${eprefix}/usr/bin/pypy
- else
- executable=${eprefix}/usr/bin/python${version}
- fi
- if [[ -x "${executable}" ]]; then
- echo -e "${GOOD}Testing with Python ${version}...${NORMAL}"
- "${executable}" -b -Wd pym/portage/tests/runTests.py "$@"
- status=$?
- status_array[${#status_array[@]}]=${status}
- found_versions[${#found_versions[@]}]=${version}
- if [ ${status} -ne 0 ] ; then
- echo -e "${BAD}Testing with Python ${version} failed${NORMAL}"
- exit_status="1"
- fi
- echo
- elif [[ ${IGNORE_MISSING_VERSIONS} != "true" ]] ; then
- echo -e "${BAD}Could not find requested Python ${version}${NORMAL}"
- exit_status="1"
- fi
-done
-
-if [ ${#status_array[@]} -gt 0 ] ; then
- max_len=0
- for version in ${found_versions[@]} ; do
- [ ${#version} -gt ${max_len} ] && max_len=${#version}
- done
- (( columns = max_len + 2 ))
- (( columns >= 7 )) || columns=7
- printf "\nSummary:\n\n"
- printf "| %-${columns}s | %s\n|" "Version" "Status"
- (( total_cols = columns + 11 ))
- eval "printf -- '-%.0s' {1..${total_cols}}"
- printf "\n"
- row=0
- for version in ${found_versions[@]} ; do
- if [ ${status_array[${row}]} -eq 0 ] ; then
- status="success"
- else
- status="fail"
- fi
- printf "| %-${columns}s | %s\n" "${version}" "${status}"
- (( row++ ))
- done
-fi
-
-exit ${exit_status}