public inbox for gentoo-portage-dev@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-portage-dev] [PATCH] runtests: rewrite in python
@ 2015-05-30 16:29 Mike Frysinger
  2015-05-30 17:18 ` Brian Dolbec
  0 siblings, 1 reply; 9+ messages in thread
From: Mike Frysinger @ 2015-05-30 16:29 UTC (permalink / raw
  To: gentoo-portage-dev

The bash was getting ugly, and this allows us to add more smarts sanely
to the main script.
---
 DEVELOPING  |   2 +-
 runtests    | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 runtests.sh | 109 ------------------------------------------
 3 files changed, 157 insertions(+), 110 deletions(-)
 create mode 100755 runtests
 delete mode 100755 runtests.sh

diff --git a/DEVELOPING b/DEVELOPING
index 0b0bb60..31b5594 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 0000000..d1f7b6f
--- /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 a7ca101..0000000
--- 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}
-- 
2.4.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2015-06-11  7:12 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-30 16:29 [gentoo-portage-dev] [PATCH] runtests: rewrite in python Mike Frysinger
2015-05-30 17:18 ` Brian Dolbec
2015-05-30 18:27   ` Mike Frysinger
2015-05-30 19:30     ` Brian Dolbec
2015-06-04  4:26       ` Mike Frysinger
2015-06-01 21:16     ` Alexander Berntsen
2015-06-11  7:12       ` Brian Dolbec
2015-05-30 18:42   ` Mike Gilbert
2015-05-30 19:16     ` Mike Frysinger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox