Skip to content

Commit

Permalink
Add Python3 testing support
Browse files Browse the repository at this point in the history
Conditionally runs the tests depending on the availability of Python
versions (because Travis is the worst).
  • Loading branch information
soltanmm committed Jul 9, 2015
1 parent 743c10c commit e5f7002
Show file tree
Hide file tree
Showing 8 changed files with 164 additions and 57 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ gens
libs
objs

# Python virtual environment (pre-3.4 only)
python2.7_virtual_environment
# Python virtual environments
python*_virtual_environment

# gcov coverage data
coverage
Expand Down
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ before_install:
- echo "deb http://download.mono-project.com/repo/debian wheezy main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list
- echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" | sudo tee -a /etc/apt/sources.list.d/mono-xamarin.list
- sudo apt-get update -qq
- sudo apt-get install -qq libgtest-dev libgflags-dev python-virtualenv clang-3.5
- sudo apt-get install -qq libgtest-dev libgflags-dev python-virtualenv python-dev python3-dev clang-3.5
- sudo pip install --upgrade virtualenv
- sudo pip install cpp-coveralls mako simplejson
- sudo apt-get install -qq mono-devel nunit
- wget www.nuget.org/NuGet.exe -O nuget.exe
Expand Down
7 changes: 6 additions & 1 deletion src/python/src/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,12 @@ def cython_extensions(package_names, module_names, include_dirs, libraries,
list(_EXTENSION_INCLUDE_DIRECTORIES), list(_EXTENSION_LIBRARIES),
bool(_BUILD_WITH_CYTHON))

_EXTENSION_MODULES = _C_EXTENSION_MODULES + _CYTHON_EXTENSION_MODULES
# TODO(atash): We shouldn't need to gate any C code based on the python version
# from the distutils build system. Remove this hackery once we're on Cython and
# 3.x C API compliant.
_EXTENSION_MODULES = list(_CYTHON_EXTENSION_MODULES)
if sys.version_info[0:2] <= (2, 7):
_EXTENSION_MODULES += _C_EXTENSION_MODULES


_PACKAGES = (
Expand Down
45 changes: 28 additions & 17 deletions tools/run_tests/build_python.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,31 @@ cd $(dirname $0)/../..

root=`pwd`

if [ ! -d 'python2.7_virtual_environment' ]
then
# Build the entire virtual environment
virtualenv -p /usr/bin/python2.7 python2.7_virtual_environment
source python2.7_virtual_environment/bin/activate
pip install -r src/python/requirements.txt
else
source python2.7_virtual_environment/bin/activate
# Uninstall and re-install the packages we care about. Don't use
# --force-reinstall or --ignore-installed to avoid propagating this
# unnecessarily to dependencies. Don't use --no-deps to avoid missing
# dependency upgrades.
(yes | pip uninstall grpcio) || true
(yes | pip uninstall interop) || true
fi
CFLAGS="-I$root/include -std=c89" LDFLAGS=-L$root/libs/$CONFIG GRPC_PYTHON_BUILD_WITH_CYTHON=1 pip install src/python/src
pip install src/python/interop
make_virtualenv() {
virtualenv_name="python"$1"_virtual_environment"
if [ ! -d $virtualenv_name ]
then
# Build the entire virtual environment
virtualenv -p `which "python"$1` $virtualenv_name
source $virtualenv_name/bin/activate
pip install -r src/python/requirements.txt
CFLAGS="-I$root/include -std=c89" LDFLAGS=-L$root/libs/$CONFIG GRPC_PYTHON_BUILD_WITH_CYTHON=1 pip install src/python/src
pip install src/python/interop
else
source $virtualenv_name/bin/activate
# Uninstall and re-install the packages we care about. Don't use
# --force-reinstall or --ignore-installed to avoid propagating this
# unnecessarily to dependencies. Don't use --no-deps to avoid missing
# dependency upgrades.
(yes | pip uninstall grpcio) || true
(yes | pip uninstall interop) || true
(CFLAGS="-I$root/include -std=c89" LDFLAGS=-L$root/libs/$CONFIG GRPC_PYTHON_BUILD_WITH_CYTHON=1 pip install src/python/src) || (
# Fall back to rebuilding the entire environment
rm -rf $virtualenv_name
make_virtualenv $1
)
pip install src/python/interop
fi
}

make_virtualenv $1
1 change: 1 addition & 0 deletions tools/run_tests/jobset.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def alarm_handler(unused_signum, unused_frame):

_TAG_COLOR = {
'FAILED': 'red',
'WARNING': 'yellow',
'TIMEOUT': 'red',
'PASSED': 'green',
'START': 'gray',
Expand Down
101 changes: 81 additions & 20 deletions tools/run_tests/python_tests.json
Original file line number Diff line number Diff line change
@@ -1,62 +1,123 @@
[
{
"module": "grpc._cython.cygrpc_test"
"module": "grpc._cython.cygrpc_test",
"pythonVersions": [
"2.7",
"3.4"
]
},
{
"module": "grpc._cython.adapter_low_test"
"module": "grpc._cython.adapter_low_test",
"pythonVersions": [
"2.7"
]
},
{
"module": "grpc._adapter._c_test"
"module": "grpc._adapter._c_test",
"pythonVersions": [
"2.7"
]
},
{
"module": "grpc._adapter._low_test"
"module": "grpc._adapter._low_test",
"pythonVersions": [
"2.7"
]
},
{
"module": "grpc._adapter._intermediary_low_test"
"module": "grpc._adapter._intermediary_low_test",
"pythonVersions": [
"2.7"
]
},
{
"module": "grpc._adapter._links_test"
"module": "grpc._adapter._links_test",
"pythonVersions": [
"2.7"
]
},
{
"module": "grpc._adapter._lonely_rear_link_test"
"module": "grpc._adapter._lonely_rear_link_test",
"pythonVersions": [
"2.7"
]
},
{
"module": "grpc._adapter._blocking_invocation_inline_service_test"
"module": "grpc._adapter._blocking_invocation_inline_service_test",
"pythonVersions": [
"2.7"
]
},
{
"module": "grpc._adapter._event_invocation_synchronous_event_service_test"
"module": "grpc._adapter._event_invocation_synchronous_event_service_test",
"pythonVersions": [
"2.7"
]
},
{
"module": "grpc._adapter._future_invocation_asynchronous_event_service_test"
"module": "grpc._adapter._future_invocation_asynchronous_event_service_test",
"pythonVersions": [
"2.7"
]
},
{
"module": "grpc.early_adopter.implementations_test"
"module": "grpc.early_adopter.implementations_test",
"pythonVersions": [
"2.7"
]
},
{
"module": "grpc.framework.base.implementations_test"
"module": "grpc.framework.base.implementations_test",
"pythonVersions": [
"2.7"
]
},
{
"module": "grpc.framework.face.blocking_invocation_inline_service_test"
"module": "grpc.framework.face.blocking_invocation_inline_service_test",
"pythonVersions": [
"2.7"
]
},
{
"module": "grpc.framework.face.event_invocation_synchronous_event_service_test"
"module": "grpc.framework.face.event_invocation_synchronous_event_service_test",
"pythonVersions": [
"2.7"
]
},
{
"module": "grpc.framework.face.future_invocation_asynchronous_event_service_test"
"module": "grpc.framework.face.future_invocation_asynchronous_event_service_test",
"pythonVersions": [
"2.7"
]
},
{
"module": "grpc.framework.foundation._later_test"
"module": "grpc.framework.foundation._later_test",
"pythonVersions": [
"2.7"
]
},
{
"module": "grpc.framework.foundation._logging_pool_test"
"module": "grpc.framework.foundation._logging_pool_test",
"pythonVersions": [
"2.7"
]
},
{
"module": "interop._insecure_interop_test"
"module": "interop._insecure_interop_test",
"pythonVersions": [
"2.7"
]
},
{
"module": "interop._secure_interop_test"
"module": "interop._secure_interop_test",
"pythonVersions": [
"2.7"
]
},
{
"file": "test/compiler/python_plugin_test.py"
"file": "test/compiler/python_plugin_test.py",
"pythonVersions": [
"2.7"
]
}
]
4 changes: 2 additions & 2 deletions tools/run_tests/run_python.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,5 @@ cd $(dirname $0)/../..
root=`pwd`
export LD_LIBRARY_PATH=$root/libs/$CONFIG
export DYLD_LIBRARY_PATH=$root/libs/$CONFIG
source python2.7_virtual_environment/bin/activate
python2.7 -B $*
source "python"$PYVER"_virtual_environment"/bin/activate
"python"$PYVER -B $*
56 changes: 42 additions & 14 deletions tools/run_tests/run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,27 +189,55 @@ class PythonLanguage(object):
def __init__(self):
with open('tools/run_tests/python_tests.json') as f:
self._tests = json.load(f)
self._build_python_versions = set([
python_version
for test in self._tests
for python_version in test['pythonVersions']])
self._has_python_versions = []

def test_specs(self, config, travis):
modules = [config.job_spec(['tools/run_tests/run_python.sh', '-m',
test['module']],
None,
environ=_FORCE_ENVIRON_FOR_WRAPPERS,
shortname=test['module'])
for test in self._tests if 'module' in test]
files = [config.job_spec(['tools/run_tests/run_python.sh',
test['file']],
None,
environ=_FORCE_ENVIRON_FOR_WRAPPERS,
shortname=test['file'])
for test in self._tests if 'file' in test]
return files + modules
job_specifications = []
for test in self._tests:
command = None
short_name = None
if 'module' in test:
command = ['tools/run_tests/run_python.sh', '-m', test['module']]
short_name = test['module']
elif 'file' in test:
command = ['tools/run_tests/run_python.sh', test['file']]
short_name = test['file']
else:
raise ValueError('expected input to be a module or file to run '
'unittests from')
for python_version in test['pythonVersions']:
if python_version in self._has_python_versions:
environment = dict(_FORCE_ENVIRON_FOR_WRAPPERS)
environment['PYVER'] = python_version
job_specifications.append(config.job_spec(
command, None, environ=environment, shortname=short_name))
else:
jobset.message(
'WARNING',
'Could not find Python {}; skipping test'.format(python_version),
'{}\n'.format(command), do_newline=True)
return job_specifications

def make_targets(self):
return ['static_c', 'grpc_python_plugin', 'shared_c']

def build_steps(self):
return [['tools/run_tests/build_python.sh']]
commands = []
for python_version in self._build_python_versions:
try:
with open(os.devnull, 'w') as output:
subprocess.check_call(['which', 'python' + python_version],
stdout=output, stderr=output)
commands.append(['tools/run_tests/build_python.sh', python_version])
self._has_python_versions.append(python_version)
except:
jobset.message('WARNING', 'Missing Python ' + python_version,
do_newline=True)
return commands

def supports_multi_config(self):
return False
Expand Down

0 comments on commit e5f7002

Please sign in to comment.