From c2d3dc3b0f0d314a130829aaf47e686ec1a5fc5e Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Fri, 5 Apr 2019 21:31:50 +0100 Subject: [PATCH 01/18] Update README.md Fix #133. Thanks @zackw for the report! --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2fc0699c..3130b8f6 100644 --- a/README.md +++ b/README.md @@ -381,6 +381,7 @@ If your wheel didn't compile, check the list below for some debugging tips. - A mistake in your config. To quickly test your config without doing a git push and waiting for your code to build on CI, you can run the Linux build in a Docker container. On Mac or Linux, with Docker running, try `cibuildwheel --platform linux`. You'll have to bring your config into the current environment first. - Missing dependency. You might need to install something on the build machine. You can do this in `.travis.yml`, `appveyor.yml`, or `.circleci/config.yml`, with apt-get, brew or whatever Windows uses :P . Given how the Linux build works, we'll probably have to build something into `cibuildwheel`. Let's chat about that over in the issues! - Windows: missing C feature. The Windows C compiler doesn't support C language features invented after 1990, so you'll have to backport your C code to C90. For me, this mostly involved putting my variable declarations at the top of the function like an animal. +- MacOS: calling cibuildwheel from a python3 script and getting a `ModuleNotFoundError`? Due to a [bug](https://bugs.python.org/issue22490) in CPython, you'll need to [unset the `__PYVENV_LAUNCHER__` variable](https://github.com/joerick/cibuildwheel/issues/133#issuecomment-478288597) before activating a venv. Working examples ---------------- From 52e8f41b5c2f7d1ad339158078d0dc2ec53a3218 Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Sat, 20 Apr 2019 18:52:01 +0200 Subject: [PATCH 02/18] Added --print-build-identifiers command line option --- cibuildwheel/__main__.py | 24 ++++++++++++++++++++++++ cibuildwheel/linux.py | 25 ++++++++++++++----------- cibuildwheel/macos.py | 13 ++++++++----- cibuildwheel/windows.py | 37 ++++++++++++++++++++----------------- 4 files changed, 66 insertions(+), 33 deletions(-) diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index 6d0b1c94..8a926c60 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -48,6 +48,10 @@ def main(): help=('Path to the project that you want wheels for. Default: the current ' 'directory.')) + parser.add_argument('--print-build-identifiers', + action='store_true', + help='Print the build identifiers matched by the current invocation and exit.') + args = parser.parse_args() if args.platform != 'auto': @@ -109,6 +113,10 @@ def main(): print('cibuildwheel: Could not find setup.py at root of project', file=sys.stderr) exit(2) + if args.print_build_identifiers: + print_build_identifiers(platform, build_selector) + exit(0) + build_options = dict( project_dir=project_dir, output_dir=output_dir, @@ -149,6 +157,7 @@ def main(): else: raise Exception('Unsupported platform') + def print_preamble(platform, build_options): print(textwrap.dedent(''' _ _ _ _ _ _ _ @@ -173,6 +182,21 @@ def print_preamble(platform, build_options): print('\nHere we go!\n') + +def print_build_identifiers(platform, build_selector): + if platform == 'linux': + python_configurations = cibuildwheel.linux.get_python_configurations(build_selector) + elif platform == 'windows': + python_configurations = cibuildwheel.windows.get_python_configurations(build_selector) + elif platform == 'macos': + python_configurations = cibuildwheel.macos.get_python_configurations(build_selector) + else: + python_configurations = [] + + for config in python_configurations: + print(config.identifier) + + def detect_warnings(platform, build_options): warnings = [] diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index 027fed8f..a43d47dc 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -9,16 +9,7 @@ except ImportError: from pipes import quote as shlex_quote -def build(project_dir, output_dir, test_command, test_requires, before_build, build_verbosity, build_selector, environment, manylinux1_images): - try: - subprocess.check_call(['docker', '--version']) - except: - print('cibuildwheel: Docker not found. Docker is required to run Linux builds. ' - 'If you\'re building on Travis CI, add `services: [docker]` to your .travis.yml.' - 'If you\'re building on Circle CI in Linux, add a `setup_remote_docker` step to your .circleci/config.yml', - file=sys.stderr) - exit(2) - +def get_python_configurations(build_selector): PythonConfiguration = namedtuple('PythonConfiguration', ['identifier', 'path']) python_configurations = [ PythonConfiguration(identifier='cp27-manylinux1_x86_64', path='/opt/python/cp27-cp27m'), @@ -36,8 +27,20 @@ def build(project_dir, output_dir, test_command, test_requires, before_build, bu ] # skip builds as required - python_configurations = [c for c in python_configurations if build_selector(c.identifier)] + return [c for c in python_configurations if build_selector(c.identifier)] + +def build(project_dir, output_dir, test_command, test_requires, before_build, build_verbosity, build_selector, environment, manylinux1_images): + try: + subprocess.check_call(['docker', '--version']) + except: + print('cibuildwheel: Docker not found. Docker is required to run Linux builds. ' + 'If you\'re building on Travis CI, add `services: [docker]` to your .travis.yml.' + 'If you\'re building on Circle CI in Linux, add a `setup_remote_docker` step to your .circleci/config.yml', + file=sys.stderr) + exit(2) + + python_configurations = get_python_configurations(build_selector) platforms = [ ('manylinux1_x86_64', manylinux1_images.get('x86_64') or 'quay.io/pypa/manylinux1_x86_64'), ('manylinux1_i686', manylinux1_images.get('i686') or 'quay.io/pypa/manylinux1_i686'), diff --git a/cibuildwheel/macos.py b/cibuildwheel/macos.py index 8d873c42..d5f428d6 100644 --- a/cibuildwheel/macos.py +++ b/cibuildwheel/macos.py @@ -10,7 +10,7 @@ except ImportError: from .util import prepare_command, get_build_verbosity_extra_flags -def build(project_dir, output_dir, test_command, test_requires, before_build, build_verbosity, build_selector, environment): +def get_python_configurations(build_selector): PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'identifier', 'url']) python_configurations = [ PythonConfiguration(version='2.7', identifier='cp27-macosx_10_6_intel', url='https://www.python.org/ftp/python/2.7.16/python-2.7.16-macosx10.6.pkg'), @@ -19,6 +19,13 @@ def build(project_dir, output_dir, test_command, test_requires, before_build, bu PythonConfiguration(version='3.6', identifier='cp36-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.6.8/python-3.6.8-macosx10.6.pkg'), PythonConfiguration(version='3.7', identifier='cp37-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.7.2/python-3.7.2-macosx10.6.pkg'), ] + + # skip builds as required + return [c for c in python_configurations if build_selector(c.identifier)] + + +def build(project_dir, output_dir, test_command, test_requires, before_build, build_verbosity, build_selector, environment): + python_configurations = get_python_configurations(build_selector) get_pip_url = 'https://bootstrap.pypa.io/get-pip.py' get_pip_script = '/tmp/get-pip.py' @@ -42,10 +49,6 @@ def build(project_dir, output_dir, test_command, test_requires, before_build, bu call(['curl', '-L', '-o', get_pip_script, get_pip_url]) for config in python_configurations: - if not build_selector(config.identifier): - print('cibuildwheel: Skipping build %s' % config.identifier, file=sys.stderr) - continue - # if this version of python isn't installed, get it from python.org and install python_package_identifier = 'org.python.Python.PythonFramework-%s' % config.version if python_package_identifier not in installed_system_packages: diff --git a/cibuildwheel/windows.py b/cibuildwheel/windows.py index f5a4ffb8..0748b278 100644 --- a/cibuildwheel/windows.py +++ b/cibuildwheel/windows.py @@ -10,6 +10,25 @@ from glob import glob from .util import prepare_command, get_build_verbosity_extra_flags +def get_python_configurations(build_selector): + PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'arch', 'identifier', 'path']) + python_configurations = [ + PythonConfiguration(version='2.7.x', arch="32", identifier='cp27-win32', path='C:\Python27'), + PythonConfiguration(version='2.7.x', arch="64", identifier='cp27-win_amd64', path='C:\Python27-x64'), + PythonConfiguration(version='3.4.x', arch="32", identifier='cp34-win32', path='C:\Python34'), + PythonConfiguration(version='3.4.x', arch="64", identifier='cp34-win_amd64', path='C:\Python34-x64'), + PythonConfiguration(version='3.5.x', arch="32", identifier='cp35-win32', path='C:\Python35'), + PythonConfiguration(version='3.5.x', arch="64", identifier='cp35-win_amd64', path='C:\Python35-x64'), + PythonConfiguration(version='3.6.x', arch="32", identifier='cp36-win32', path='C:\Python36'), + PythonConfiguration(version='3.6.x', arch="64", identifier='cp36-win_amd64', path='C:\Python36-x64'), + PythonConfiguration(version='3.7.x', arch="32", identifier='cp37-win32', path='C:\Python37'), + PythonConfiguration(version='3.7.x', arch="64", identifier='cp37-win_amd64', path='C:\Python37-x64'), + ] + + # skip builds as required + return [c for c in python_configurations if build_selector(c.identifier)] + + def build(project_dir, output_dir, test_command, test_requires, before_build, build_verbosity, build_selector, environment): # run_with_env is a cmd file that sets the right environment variables to run_with_env = os.path.join(tempfile.gettempdir(), 'appveyor_run_with_env.cmd') @@ -24,29 +43,13 @@ def build(project_dir, output_dir, test_command, test_requires, before_build, bu args = ['cmd', '/E:ON', '/V:ON', '/C', run_with_env] + args return subprocess.check_call(' '.join(args), env=env, cwd=cwd) - PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'arch', 'identifier', 'path']) - python_configurations = [ - PythonConfiguration(version='2.7.x', arch="32", identifier='cp27-win32', path='C:\Python27'), - PythonConfiguration(version='2.7.x', arch="64", identifier='cp27-win_amd64', path='C:\Python27-x64'), - PythonConfiguration(version='3.4.x', arch="32", identifier='cp34-win32', path='C:\Python34'), - PythonConfiguration(version='3.4.x', arch="64", identifier='cp34-win_amd64', path='C:\Python34-x64'), - PythonConfiguration(version='3.5.x', arch="32", identifier='cp35-win32', path='C:\Python35'), - PythonConfiguration(version='3.5.x', arch="64", identifier='cp35-win_amd64', path='C:\Python35-x64'), - PythonConfiguration(version='3.6.x', arch="32", identifier='cp36-win32', path='C:\Python36'), - PythonConfiguration(version='3.6.x', arch="64", identifier='cp36-win_amd64', path='C:\Python36-x64'), - PythonConfiguration(version='3.7.x', arch="32", identifier='cp37-win32', path='C:\Python37'), - PythonConfiguration(version='3.7.x', arch="64", identifier='cp37-win_amd64', path='C:\Python37-x64'), - ] + python_configurations = get_python_configurations(build_selector) abs_project_dir = os.path.abspath(project_dir) temp_dir = tempfile.mkdtemp(prefix='cibuildwheel') built_wheel_dir = os.path.join(temp_dir, 'built_wheel') for config in python_configurations: - if not build_selector(config.identifier): - print('cibuildwheel: Skipping build %s' % config.identifier, file=sys.stderr) - continue - # check python & pip exist for this configuration assert os.path.exists(os.path.join(config.path, 'python.exe')) assert os.path.exists(os.path.join(config.path, 'Scripts', 'pip.exe')) From 95d2086cedf9375757a91808649564957c04e574 Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Sat, 20 Apr 2019 20:06:43 +0200 Subject: [PATCH 03/18] Adding check.py to tests, rather than a simple generic assert on number of wheels --- bin/run_test.py | 2 +- bin/run_tests.py | 2 +- test/01_basic/check.py | 9 +++++++++ test/02_test/check.py | 9 +++++++++ test/03_before_build/check.py | 9 +++++++++ test/04_build_skip/check.py | 9 +++++++++ test/05_environment/check.py | 9 +++++++++ test/06_docker_images/check.py | 9 +++++++++ test/07_ssl/check.py | 9 +++++++++ 9 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 test/01_basic/check.py create mode 100644 test/02_test/check.py create mode 100644 test/03_before_build/check.py create mode 100644 test/04_build_skip/check.py create mode 100644 test/05_environment/check.py create mode 100644 test/06_docker_images/check.py create mode 100644 test/07_ssl/check.py diff --git a/bin/run_test.py b/bin/run_test.py index 94db6512..af361a65 100755 --- a/bin/run_test.py +++ b/bin/run_test.py @@ -22,7 +22,7 @@ def single_run(test_project): print('%s built successfully. %i wheels built.' % (test_project, len(wheels))) # check some wheels were actually built - assert len(wheels) >= 3 + subprocess.check_call([sys.executable, os.path.join(test_project, 'check.py')]) # clean up shutil.rmtree('wheelhouse') diff --git a/bin/run_tests.py b/bin/run_tests.py index bcae61c5..b39999f6 100755 --- a/bin/run_tests.py +++ b/bin/run_tests.py @@ -14,7 +14,7 @@ if __name__ == '__main__': ### run the integration tests - test_projects = glob('test/??_*') + test_projects = sorted(glob('test/??_*')) if len(test_projects) == 0: print('No test projects found. Aborting.', file=sys.stderr) diff --git a/test/01_basic/check.py b/test/01_basic/check.py new file mode 100644 index 00000000..bec98563 --- /dev/null +++ b/test/01_basic/check.py @@ -0,0 +1,9 @@ +import glob +import subprocess +import sys + +build_identifiers = subprocess.check_output([sys.executable, '-m', 'cibuildwheel', '--print-build-identifiers'], universal_newlines=True).strip().split('\n') +expected_identifiers = build_identifiers +built_wheels = glob.glob('wheelhouse/*.whl') + +assert len(built_wheels) == len(expected_identifiers) diff --git a/test/02_test/check.py b/test/02_test/check.py new file mode 100644 index 00000000..bec98563 --- /dev/null +++ b/test/02_test/check.py @@ -0,0 +1,9 @@ +import glob +import subprocess +import sys + +build_identifiers = subprocess.check_output([sys.executable, '-m', 'cibuildwheel', '--print-build-identifiers'], universal_newlines=True).strip().split('\n') +expected_identifiers = build_identifiers +built_wheels = glob.glob('wheelhouse/*.whl') + +assert len(built_wheels) == len(expected_identifiers) diff --git a/test/03_before_build/check.py b/test/03_before_build/check.py new file mode 100644 index 00000000..bec98563 --- /dev/null +++ b/test/03_before_build/check.py @@ -0,0 +1,9 @@ +import glob +import subprocess +import sys + +build_identifiers = subprocess.check_output([sys.executable, '-m', 'cibuildwheel', '--print-build-identifiers'], universal_newlines=True).strip().split('\n') +expected_identifiers = build_identifiers +built_wheels = glob.glob('wheelhouse/*.whl') + +assert len(built_wheels) == len(expected_identifiers) diff --git a/test/04_build_skip/check.py b/test/04_build_skip/check.py new file mode 100644 index 00000000..6f199b0e --- /dev/null +++ b/test/04_build_skip/check.py @@ -0,0 +1,9 @@ +import glob +import subprocess +import sys + +build_identifiers = subprocess.check_output([sys.executable, '-m', 'cibuildwheel', '--print-build-identifiers'], universal_newlines=True).strip().split('\n') +expected_identifiers = [identifier for identifier in build_identifiers if "cp3" in identifier and "cp34" not in identifier] +built_wheels = glob.glob('wheelhouse/*.whl') + +assert len(built_wheels) == len(expected_identifiers) diff --git a/test/05_environment/check.py b/test/05_environment/check.py new file mode 100644 index 00000000..bec98563 --- /dev/null +++ b/test/05_environment/check.py @@ -0,0 +1,9 @@ +import glob +import subprocess +import sys + +build_identifiers = subprocess.check_output([sys.executable, '-m', 'cibuildwheel', '--print-build-identifiers'], universal_newlines=True).strip().split('\n') +expected_identifiers = build_identifiers +built_wheels = glob.glob('wheelhouse/*.whl') + +assert len(built_wheels) == len(expected_identifiers) diff --git a/test/06_docker_images/check.py b/test/06_docker_images/check.py new file mode 100644 index 00000000..bec98563 --- /dev/null +++ b/test/06_docker_images/check.py @@ -0,0 +1,9 @@ +import glob +import subprocess +import sys + +build_identifiers = subprocess.check_output([sys.executable, '-m', 'cibuildwheel', '--print-build-identifiers'], universal_newlines=True).strip().split('\n') +expected_identifiers = build_identifiers +built_wheels = glob.glob('wheelhouse/*.whl') + +assert len(built_wheels) == len(expected_identifiers) diff --git a/test/07_ssl/check.py b/test/07_ssl/check.py new file mode 100644 index 00000000..bec98563 --- /dev/null +++ b/test/07_ssl/check.py @@ -0,0 +1,9 @@ +import glob +import subprocess +import sys + +build_identifiers = subprocess.check_output([sys.executable, '-m', 'cibuildwheel', '--print-build-identifiers'], universal_newlines=True).strip().split('\n') +expected_identifiers = build_identifiers +built_wheels = glob.glob('wheelhouse/*.whl') + +assert len(built_wheels) == len(expected_identifiers) From 3f7a4d753f7fa571830189f00886fb054d50dee5 Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Sat, 20 Apr 2019 20:59:27 +0200 Subject: [PATCH 04/18] Skip non-linux builds for 06_docker_images test, now that we have custom checks --- test/06_docker_images/check.py | 2 +- test/06_docker_images/environment.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/06_docker_images/check.py b/test/06_docker_images/check.py index bec98563..d2061288 100644 --- a/test/06_docker_images/check.py +++ b/test/06_docker_images/check.py @@ -3,7 +3,7 @@ import subprocess import sys build_identifiers = subprocess.check_output([sys.executable, '-m', 'cibuildwheel', '--print-build-identifiers'], universal_newlines=True).strip().split('\n') -expected_identifiers = build_identifiers +expected_identifiers = [identifier for identifier in build_identifiers if 'macos' not in identifier and 'win' not in identifier] built_wheels = glob.glob('wheelhouse/*.whl') assert len(built_wheels) == len(expected_identifiers) diff --git a/test/06_docker_images/environment.json b/test/06_docker_images/environment.json index bd3ceda8..e5e73cc8 100644 --- a/test/06_docker_images/environment.json +++ b/test/06_docker_images/environment.json @@ -1,5 +1,5 @@ { "CIBW_MANYLINUX1_X86_64_IMAGE": "dockcross/manylinux-x64", "CIBW_MANYLINUX1_I686_IMAGE": "dockcross/manylinux-x86", - "CIBW_SKIP": "cp37-manylinux*" + "CIBW_SKIP": "*macos* *win*" } From ac4b62ca07840e3972da75b6bb64a93a582018d9 Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Mon, 22 Apr 2019 16:15:47 +0200 Subject: [PATCH 05/18] Update README.md with --print-build-identifiers switch --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3130b8f6..fec41842 100644 --- a/README.md +++ b/README.md @@ -152,9 +152,8 @@ Options ------- ``` -usage: cibuildwheel [-h] - [--output-dir OUTPUT_DIR] - [--platform PLATFORM] +usage: cibuildwheel [-h] [--platform {auto,linux,macos,windows}] + [--output-dir OUTPUT_DIR] [--print-build-identifiers] [project_dir] Build wheels for all the platforms. @@ -174,7 +173,10 @@ optional arguments: you need to run in Windows, and it will build and test for all versions of Python at C:\PythonXX[-x64]. --output-dir OUTPUT_DIR - Destination folder for the wheels. + Destination folder for the wheels. + --print-build-identifiers + Print the build identifiers matched by the current + invocation and exit. ``` From 21fb27faf79c5aa81966e9498c3ab6fee4d16d09 Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Mon, 22 Apr 2019 18:22:43 +0100 Subject: [PATCH 06/18] Rework custom test machinery to give the individual tests more control on how they're run, and combine environment.json and check.py --- bin/run_test.py | 27 +++--------- test/01_basic/check.py | 9 ---- test/01_basic/cibuildwheel_test.py | 50 ++++++++++++++++++++++ test/02_test/check.py | 9 ---- test/02_test/cibuildwheel_test.py | 23 ++++++++++ test/02_test/environment.json | 6 --- test/03_before_build/check.py | 9 ---- test/03_before_build/cibuildwheel_test.py | 22 ++++++++++ test/03_before_build/environment.json | 4 -- test/03_before_build/version.txt | 2 - test/04_build_skip/check.py | 9 ---- test/04_build_skip/cibuildwheel_test.py | 49 +++++++++++++++++++++ test/04_build_skip/environment.json | 4 -- test/04_build_skip/version.txt | 2 - test/05_environment/check.py | 9 ---- test/05_environment/cibuildwheel_test.py | 22 ++++++++++ test/05_environment/environment.json | 4 -- test/05_environment/version.txt | 2 - test/06_docker_images/check.py | 9 ---- test/06_docker_images/cibuildwheel_test.py | 24 +++++++++++ test/06_docker_images/environment.json | 5 --- test/07_ssl/check.py | 9 ---- test/07_ssl/cibuildwheel_test.py | 17 ++++++++ test/shared/utils.py | 25 +++++++++++ 24 files changed, 237 insertions(+), 114 deletions(-) delete mode 100644 test/01_basic/check.py create mode 100644 test/01_basic/cibuildwheel_test.py delete mode 100644 test/02_test/check.py create mode 100644 test/02_test/cibuildwheel_test.py delete mode 100644 test/02_test/environment.json delete mode 100644 test/03_before_build/check.py create mode 100644 test/03_before_build/cibuildwheel_test.py delete mode 100644 test/03_before_build/environment.json delete mode 100644 test/03_before_build/version.txt delete mode 100644 test/04_build_skip/check.py create mode 100644 test/04_build_skip/cibuildwheel_test.py delete mode 100644 test/04_build_skip/environment.json delete mode 100644 test/04_build_skip/version.txt delete mode 100644 test/05_environment/check.py create mode 100644 test/05_environment/cibuildwheel_test.py delete mode 100644 test/05_environment/environment.json delete mode 100644 test/05_environment/version.txt delete mode 100644 test/06_docker_images/check.py create mode 100644 test/06_docker_images/cibuildwheel_test.py delete mode 100644 test/06_docker_images/environment.json delete mode 100644 test/07_ssl/check.py create mode 100644 test/07_ssl/cibuildwheel_test.py create mode 100644 test/shared/utils.py diff --git a/bin/run_test.py b/bin/run_test.py index af361a65..bb5cd6db 100755 --- a/bin/run_test.py +++ b/bin/run_test.py @@ -1,28 +1,13 @@ #!/usr/bin/python from __future__ import print_function -import os, sys, subprocess, shutil, json -from glob import glob +import os, sys, subprocess, shutil def single_run(test_project): - # load project settings into environment - env_file = os.path.join(test_project, 'environment.json') - project_env = {} - if os.path.exists(env_file): - with open(env_file) as f: - project_env = json.load(f) - - # run the build - env = os.environ.copy() - project_env = {str(k): str(v) for k, v in project_env.items()} # unicode not allowed in env - env.update(project_env) - print('Building %s with environment %s' % (test_project, project_env)) - subprocess.check_call([sys.executable, '-m', 'cibuildwheel', test_project], env=env) - wheels = glob('wheelhouse/*.whl') - print('%s built successfully. %i wheels built.' % (test_project, len(wheels))) - - # check some wheels were actually built - subprocess.check_call([sys.executable, os.path.join(test_project, 'check.py')]) + # run the test + subprocess.check_call( + [sys.executable, '-m', 'pytest', '-v', os.path.join(test_project, 'cibuildwheel_test.py')] + ) # clean up shutil.rmtree('wheelhouse') @@ -41,5 +26,3 @@ if __name__ == '__main__': exit(2) single_run(project_path) - - print('Project built successfully.') diff --git a/test/01_basic/check.py b/test/01_basic/check.py deleted file mode 100644 index bec98563..00000000 --- a/test/01_basic/check.py +++ /dev/null @@ -1,9 +0,0 @@ -import glob -import subprocess -import sys - -build_identifiers = subprocess.check_output([sys.executable, '-m', 'cibuildwheel', '--print-build-identifiers'], universal_newlines=True).strip().split('\n') -expected_identifiers = build_identifiers -built_wheels = glob.glob('wheelhouse/*.whl') - -assert len(built_wheels) == len(expected_identifiers) diff --git a/test/01_basic/cibuildwheel_test.py b/test/01_basic/cibuildwheel_test.py new file mode 100644 index 00000000..28b83184 --- /dev/null +++ b/test/01_basic/cibuildwheel_test.py @@ -0,0 +1,50 @@ +import subprocess, sys, os +from glob import glob +project_dir = os.path.dirname(__file__) +sys.path.append(os.path.join(os.path.dirname(project_dir), 'shared')) + +import utils + +def test(): + # build the wheels + subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir]) + + # check that every wheel is produced + if utils.platform == 'linux': + assert glob('wheelhouse/*-cp27-cp27m-manylinux1_x86_64.whl') + assert glob('wheelhouse/*-cp27-cp27mu-manylinux1_x86_64.whl') + assert glob('wheelhouse/*-cp34-cp34m-manylinux1_x86_64.whl') + assert glob('wheelhouse/*-cp35-cp35m-manylinux1_x86_64.whl') + assert glob('wheelhouse/*-cp36-cp36m-manylinux1_x86_64.whl') + assert glob('wheelhouse/*-cp37-cp37m-manylinux1_x86_64.whl') + assert glob('wheelhouse/*-cp27-cp27m-manylinux1_i686.whl') + assert glob('wheelhouse/*-cp27-cp27mu-manylinux1_i686.whl') + assert glob('wheelhouse/*-cp34-cp34m-manylinux1_i686.whl') + assert glob('wheelhouse/*-cp35-cp35m-manylinux1_i686.whl') + assert glob('wheelhouse/*-cp36-cp36m-manylinux1_i686.whl') + assert glob('wheelhouse/*-cp37-cp37m-manylinux1_i686.whl') + + if utils.platform == 'windows': + assert glob('wheelhouse/*-cp27-*-win32.whl') + assert glob('wheelhouse/*-cp34-*-win32.whl') + assert glob('wheelhouse/*-cp35-*-win32.whl') + assert glob('wheelhouse/*-cp36-*-win32.whl') + assert glob('wheelhouse/*-cp37-*-win32.whl') + assert glob('wheelhouse/*-cp27-*-win_amd64.whl') + assert glob('wheelhouse/*-cp34-*-win_amd64.whl') + assert glob('wheelhouse/*-cp35-*-win_amd64.whl') + assert glob('wheelhouse/*-cp36-*-win_amd64.whl') + assert glob('wheelhouse/*-cp37-*-win_amd64.whl') + + if utils.platform == 'macos': + assert glob('wheelhouse/*-cp27-*-macosx_10_6_intel.whl') + assert glob('wheelhouse/*-cp34-*-macosx_10_6_intel.whl') + assert glob('wheelhouse/*-cp35-*-macosx_10_6_intel.whl') + assert glob('wheelhouse/*-cp36-*-macosx_10_6_intel.whl') + assert glob('wheelhouse/*-cp37-*-macosx_10_6_intel.whl') + + # also check that the number of built wheels matches the number of build + # identifiers + expected_identifiers = utils.cibuildwheel_get_build_identifiers(project_dir) + built_wheels = glob('wheelhouse/*.whl') + assert len(built_wheels) == len(expected_identifiers) diff --git a/test/02_test/check.py b/test/02_test/check.py deleted file mode 100644 index bec98563..00000000 --- a/test/02_test/check.py +++ /dev/null @@ -1,9 +0,0 @@ -import glob -import subprocess -import sys - -build_identifiers = subprocess.check_output([sys.executable, '-m', 'cibuildwheel', '--print-build-identifiers'], universal_newlines=True).strip().split('\n') -expected_identifiers = build_identifiers -built_wheels = glob.glob('wheelhouse/*.whl') - -assert len(built_wheels) == len(expected_identifiers) diff --git a/test/02_test/cibuildwheel_test.py b/test/02_test/cibuildwheel_test.py new file mode 100644 index 00000000..82f314c8 --- /dev/null +++ b/test/02_test/cibuildwheel_test.py @@ -0,0 +1,23 @@ +import subprocess, sys, os +from glob import glob +project_dir = os.path.dirname(__file__) +sys.path.append(os.path.join(os.path.dirname(project_dir), 'shared')) + +import utils + +def test(): + # set up the environment + env = os.environ.copy() + env["CIBW_TEST_REQUIRES"] = "nose", + # the 'false ||' bit is to ensure this command runs in a shell on + # mac/linux. + env["CIBW_TEST_COMMAND"] = "false || nosetests {project}/test", + env["CIBW_TEST_COMMAND_WINDOWS"] = "nosetests {project}/test" + + # build & test the wheels + subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir], env=env) + + # also check that we got the right number of built wheels + expected_identifiers = utils.cibuildwheel_get_build_identifiers(project_dir) + built_wheels = glob('wheelhouse/*.whl') + assert len(built_wheels) == len(expected_identifiers) diff --git a/test/02_test/environment.json b/test/02_test/environment.json deleted file mode 100644 index 3a541dd4..00000000 --- a/test/02_test/environment.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "CIBW_TEST_REQUIRES": "nose", - "CIBW_TEST_COMMAND": "false || nosetests {project}/test", - "comment": "The 'false ||' bit is to ensure this command runs in a shell on Mac and Linux", - "CIBW_TEST_COMMAND_WINDOWS": "nosetests {project}/test" -} diff --git a/test/03_before_build/check.py b/test/03_before_build/check.py deleted file mode 100644 index bec98563..00000000 --- a/test/03_before_build/check.py +++ /dev/null @@ -1,9 +0,0 @@ -import glob -import subprocess -import sys - -build_identifiers = subprocess.check_output([sys.executable, '-m', 'cibuildwheel', '--print-build-identifiers'], universal_newlines=True).strip().split('\n') -expected_identifiers = build_identifiers -built_wheels = glob.glob('wheelhouse/*.whl') - -assert len(built_wheels) == len(expected_identifiers) diff --git a/test/03_before_build/cibuildwheel_test.py b/test/03_before_build/cibuildwheel_test.py new file mode 100644 index 00000000..92013a16 --- /dev/null +++ b/test/03_before_build/cibuildwheel_test.py @@ -0,0 +1,22 @@ +import subprocess, sys, os +from glob import glob +project_dir = os.path.dirname(__file__) +sys.path.append(os.path.join(os.path.dirname(project_dir), 'shared')) + +import utils + +def test(): + # set up the environment + env = os.environ.copy() + # write python version information to a temporary file, this is checked + # in setup.py + env["CIBW_BEFORE_BUILD"] = "python -c \"import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)\" && python -c \"import sys; open('/tmp/pythonexecutable.txt', 'w').write(sys.executable)\"", + env["CIBW_BEFORE_BUILD_WINDOWS"] = "python -c \"import sys; open('c:\\pythonversion.txt', 'w').write(sys.version)\" && python -c \"import sys; open('c:\\pythonexecutable.txt', 'w').write(sys.executable)\"" + + # build the wheels + subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir], env=env) + + # check that we got the right number of built wheels + expected_identifiers = utils.cibuildwheel_get_build_identifiers(project_dir) + built_wheels = glob('wheelhouse/*.whl') + assert len(built_wheels) == len(expected_identifiers) diff --git a/test/03_before_build/environment.json b/test/03_before_build/environment.json deleted file mode 100644 index 3e9108ea..00000000 --- a/test/03_before_build/environment.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "CIBW_BEFORE_BUILD": "python -c \"import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)\" && python -c \"import sys; open('/tmp/pythonexecutable.txt', 'w').write(sys.executable)\"", - "CIBW_BEFORE_BUILD_WINDOWS": "python -c \"import sys; open('c:\\pythonversion.txt', 'w').write(sys.version)\" && python -c \"import sys; open('c:\\pythonexecutable.txt', 'w').write(sys.executable)\"" -} diff --git a/test/03_before_build/version.txt b/test/03_before_build/version.txt deleted file mode 100644 index 3e4354cb..00000000 --- a/test/03_before_build/version.txt +++ /dev/null @@ -1,2 +0,0 @@ -3.6.0 (default, Feb 7 2017, 23:55:32) -[GCC 4.8.2 20140120 (Red Hat 4.8.2-15)] \ No newline at end of file diff --git a/test/04_build_skip/check.py b/test/04_build_skip/check.py deleted file mode 100644 index 6f199b0e..00000000 --- a/test/04_build_skip/check.py +++ /dev/null @@ -1,9 +0,0 @@ -import glob -import subprocess -import sys - -build_identifiers = subprocess.check_output([sys.executable, '-m', 'cibuildwheel', '--print-build-identifiers'], universal_newlines=True).strip().split('\n') -expected_identifiers = [identifier for identifier in build_identifiers if "cp3" in identifier and "cp34" not in identifier] -built_wheels = glob.glob('wheelhouse/*.whl') - -assert len(built_wheels) == len(expected_identifiers) diff --git a/test/04_build_skip/cibuildwheel_test.py b/test/04_build_skip/cibuildwheel_test.py new file mode 100644 index 00000000..570ceec7 --- /dev/null +++ b/test/04_build_skip/cibuildwheel_test.py @@ -0,0 +1,49 @@ +import subprocess, sys, os +from glob import glob +project_dir = os.path.dirname(__file__) +sys.path.append(os.path.join(os.path.dirname(project_dir), 'shared')) + +import utils + +def test(): + # set up the environment + env = os.environ.copy() + env["CIBW_BUILD"] = "cp3?-*", + env["CIBW_SKIP"] = "cp34-*" + + # build the wheels + subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir], env=env) + + # check that we got the right wheels. There should be no 2.7 or 3.4. + if utils.platform == 'linux': + assert not glob('wheelhouse/*-cp27-cp27m-manylinux1_x86_64.whl') + assert not glob('wheelhouse/*-cp27-cp27mu-manylinux1_x86_64.whl') + assert not glob('wheelhouse/*-cp34-cp34m-manylinux1_x86_64.whl') + assert glob('wheelhouse/*-cp35-cp35m-manylinux1_x86_64.whl') + assert glob('wheelhouse/*-cp36-cp36m-manylinux1_x86_64.whl') + assert glob('wheelhouse/*-cp37-cp37m-manylinux1_x86_64.whl') + assert not glob('wheelhouse/*-cp27-cp27m-manylinux1_i686.whl') + assert not glob('wheelhouse/*-cp27-cp27mu-manylinux1_i686.whl') + assert not glob('wheelhouse/*-cp34-cp34m-manylinux1_i686.whl') + assert glob('wheelhouse/*-cp35-cp35m-manylinux1_i686.whl') + assert glob('wheelhouse/*-cp36-cp36m-manylinux1_i686.whl') + assert glob('wheelhouse/*-cp37-cp37m-manylinux1_i686.whl') + + if utils.platform == 'windows': + assert not glob('wheelhouse/*-cp27-*-win32.whl') + assert not glob('wheelhouse/*-cp34-*-win32.whl') + assert glob('wheelhouse/*-cp35-*-win32.whl') + assert glob('wheelhouse/*-cp36-*-win32.whl') + assert glob('wheelhouse/*-cp37-*-win32.whl') + assert not glob('wheelhouse/*-cp27-*-win_amd64.whl') + assert not glob('wheelhouse/*-cp34-*-win_amd64.whl') + assert glob('wheelhouse/*-cp35-*-win_amd64.whl') + assert glob('wheelhouse/*-cp36-*-win_amd64.whl') + assert glob('wheelhouse/*-cp37-*-win_amd64.whl') + + if utils.platform == 'macos': + assert not glob('wheelhouse/*-cp27-*-macosx_10_6_intel.whl') + assert not glob('wheelhouse/*-cp34-*-macosx_10_6_intel.whl') + assert glob('wheelhouse/*-cp35-*-macosx_10_6_intel.whl') + assert glob('wheelhouse/*-cp36-*-macosx_10_6_intel.whl') + assert glob('wheelhouse/*-cp37-*-macosx_10_6_intel.whl') diff --git a/test/04_build_skip/environment.json b/test/04_build_skip/environment.json deleted file mode 100644 index a47c85d2..00000000 --- a/test/04_build_skip/environment.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "CIBW_BUILD": "cp3?-*", - "CIBW_SKIP": "cp34-*" -} diff --git a/test/04_build_skip/version.txt b/test/04_build_skip/version.txt deleted file mode 100644 index 3e4354cb..00000000 --- a/test/04_build_skip/version.txt +++ /dev/null @@ -1,2 +0,0 @@ -3.6.0 (default, Feb 7 2017, 23:55:32) -[GCC 4.8.2 20140120 (Red Hat 4.8.2-15)] \ No newline at end of file diff --git a/test/05_environment/check.py b/test/05_environment/check.py deleted file mode 100644 index bec98563..00000000 --- a/test/05_environment/check.py +++ /dev/null @@ -1,9 +0,0 @@ -import glob -import subprocess -import sys - -build_identifiers = subprocess.check_output([sys.executable, '-m', 'cibuildwheel', '--print-build-identifiers'], universal_newlines=True).strip().split('\n') -expected_identifiers = build_identifiers -built_wheels = glob.glob('wheelhouse/*.whl') - -assert len(built_wheels) == len(expected_identifiers) diff --git a/test/05_environment/cibuildwheel_test.py b/test/05_environment/cibuildwheel_test.py new file mode 100644 index 00000000..90d66288 --- /dev/null +++ b/test/05_environment/cibuildwheel_test.py @@ -0,0 +1,22 @@ +import subprocess, sys, os +from glob import glob +project_dir = os.path.dirname(__file__) +sys.path.append(os.path.join(os.path.dirname(project_dir), 'shared')) +import utils + +def test(): + # set up the environment + env = os.environ.copy() + # write some information into the CIBW_ENVIRONMENT, for expansion and + # insertion into the environment by cibuildwheel. This is checked + # in setup.py + env['CIBW_ENVIRONMENT'] = 'CIBW_TEST_VAR="a b c" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3="$(echo \'test string 3\')" PATH=$PATH:/opt/cibw_test_path', + env['CIBW_ENVIRONMENT_WINDOWS'] = 'CIBW_TEST_VAR="a b c" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3="$(echo \'test string 3\')" PATH="$PATH;/opt/cibw_test_path"' + + # build the wheels + subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir], env=env) + + # check that we got the right number of built wheels + expected_identifiers = utils.cibuildwheel_get_build_identifiers(project_dir) + built_wheels = glob('wheelhouse/*.whl') + assert len(built_wheels) == len(expected_identifiers) diff --git a/test/05_environment/environment.json b/test/05_environment/environment.json deleted file mode 100644 index 9ae227bd..00000000 --- a/test/05_environment/environment.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "CIBW_ENVIRONMENT": "CIBW_TEST_VAR=\"a b c\" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3=\"$(echo 'test string 3')\" PATH=$PATH:/opt/cibw_test_path", - "CIBW_ENVIRONMENT_WINDOWS": "CIBW_TEST_VAR=\"a b c\" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3=\"$(echo 'test string 3')\" PATH=\"$PATH;/opt/cibw_test_path\"" -} diff --git a/test/05_environment/version.txt b/test/05_environment/version.txt deleted file mode 100644 index 3e4354cb..00000000 --- a/test/05_environment/version.txt +++ /dev/null @@ -1,2 +0,0 @@ -3.6.0 (default, Feb 7 2017, 23:55:32) -[GCC 4.8.2 20140120 (Red Hat 4.8.2-15)] \ No newline at end of file diff --git a/test/06_docker_images/check.py b/test/06_docker_images/check.py deleted file mode 100644 index d2061288..00000000 --- a/test/06_docker_images/check.py +++ /dev/null @@ -1,9 +0,0 @@ -import glob -import subprocess -import sys - -build_identifiers = subprocess.check_output([sys.executable, '-m', 'cibuildwheel', '--print-build-identifiers'], universal_newlines=True).strip().split('\n') -expected_identifiers = [identifier for identifier in build_identifiers if 'macos' not in identifier and 'win' not in identifier] -built_wheels = glob.glob('wheelhouse/*.whl') - -assert len(built_wheels) == len(expected_identifiers) diff --git a/test/06_docker_images/cibuildwheel_test.py b/test/06_docker_images/cibuildwheel_test.py new file mode 100644 index 00000000..cc7ad968 --- /dev/null +++ b/test/06_docker_images/cibuildwheel_test.py @@ -0,0 +1,24 @@ +import subprocess, sys, os, pytest +from glob import glob +project_dir = os.path.dirname(__file__) +sys.path.append(os.path.join(os.path.dirname(project_dir), 'shared')) +import utils + +def test(): + if not sys.platform.startswith('linux'): + pytest.skip('the docker test is only relevant to the linux build') + + # set up the environment + env = os.environ.copy() + # change the docker images to use. The docker image is tested in setup.py + # during the build + env["CIBW_MANYLINUX1_X86_64_IMAGE"] = "dockcross/manylinux-x64" + env["CIBW_MANYLINUX1_I686_IMAGE"] = "dockcross/manylinux-x86" + + # build the wheels + subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir], env=env) + + # check that we got the right number of built wheels + expected_identifiers = utils.cibuildwheel_get_build_identifiers(project_dir) + built_wheels = glob('wheelhouse/*.whl') + assert len(built_wheels) == len(expected_identifiers) diff --git a/test/06_docker_images/environment.json b/test/06_docker_images/environment.json deleted file mode 100644 index e5e73cc8..00000000 --- a/test/06_docker_images/environment.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "CIBW_MANYLINUX1_X86_64_IMAGE": "dockcross/manylinux-x64", - "CIBW_MANYLINUX1_I686_IMAGE": "dockcross/manylinux-x86", - "CIBW_SKIP": "*macos* *win*" -} diff --git a/test/07_ssl/check.py b/test/07_ssl/check.py deleted file mode 100644 index bec98563..00000000 --- a/test/07_ssl/check.py +++ /dev/null @@ -1,9 +0,0 @@ -import glob -import subprocess -import sys - -build_identifiers = subprocess.check_output([sys.executable, '-m', 'cibuildwheel', '--print-build-identifiers'], universal_newlines=True).strip().split('\n') -expected_identifiers = build_identifiers -built_wheels = glob.glob('wheelhouse/*.whl') - -assert len(built_wheels) == len(expected_identifiers) diff --git a/test/07_ssl/cibuildwheel_test.py b/test/07_ssl/cibuildwheel_test.py new file mode 100644 index 00000000..ec3cc1aa --- /dev/null +++ b/test/07_ssl/cibuildwheel_test.py @@ -0,0 +1,17 @@ +import subprocess, sys, os +from glob import glob +project_dir = os.path.dirname(__file__) +sys.path.append(os.path.join(os.path.dirname(project_dir), 'shared')) +import utils + +def test(): + # this test checks that SSL is working in the build environment using + # some checks in setup.py. + + # build the wheels + subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir]) + + # check that we got the right number of built wheels + expected_identifiers = utils.cibuildwheel_get_build_identifiers(project_dir) + built_wheels = glob('wheelhouse/*.whl') + assert len(built_wheels) == len(expected_identifiers) diff --git a/test/shared/utils.py b/test/shared/utils.py new file mode 100644 index 00000000..e4eca4cb --- /dev/null +++ b/test/shared/utils.py @@ -0,0 +1,25 @@ +import subprocess, sys + +def cibuildwheel_get_build_identifiers(project_path, env=None): + ''' + Returns the list of build identifiers that cibuildwheel will try to build + for the current platform. + ''' + cmd_output = subprocess.check_output( + [sys.executable, '-m', 'cibuildwheel', '--print-build-identifiers', project_path], + universal_newlines=True, + env=env, + ) + + return cmd_output.strip().split('\n') + +platform = None + +if sys.platform.startswith('linux'): + platform = 'linux' +elif sys.platform.startswith('darwin'): + platform = 'macos' +elif sys.platform in ['win32', 'cygwin']: + platform = 'windows' +else: + raise Exception('Unsupported platform') From f410fbdd03213225c9eae11545a286f5477c0525 Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Mon, 22 Apr 2019 18:33:03 +0100 Subject: [PATCH 07/18] Remove trailing commas from environment declarations --- test/02_test/cibuildwheel_test.py | 2 +- test/04_build_skip/cibuildwheel_test.py | 2 +- test/05_environment/cibuildwheel_test.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/02_test/cibuildwheel_test.py b/test/02_test/cibuildwheel_test.py index 82f314c8..bda4131e 100644 --- a/test/02_test/cibuildwheel_test.py +++ b/test/02_test/cibuildwheel_test.py @@ -11,7 +11,7 @@ def test(): env["CIBW_TEST_REQUIRES"] = "nose", # the 'false ||' bit is to ensure this command runs in a shell on # mac/linux. - env["CIBW_TEST_COMMAND"] = "false || nosetests {project}/test", + env["CIBW_TEST_COMMAND"] = "false || nosetests {project}/test" env["CIBW_TEST_COMMAND_WINDOWS"] = "nosetests {project}/test" # build & test the wheels diff --git a/test/04_build_skip/cibuildwheel_test.py b/test/04_build_skip/cibuildwheel_test.py index 570ceec7..7be8d7e7 100644 --- a/test/04_build_skip/cibuildwheel_test.py +++ b/test/04_build_skip/cibuildwheel_test.py @@ -8,7 +8,7 @@ import utils def test(): # set up the environment env = os.environ.copy() - env["CIBW_BUILD"] = "cp3?-*", + env["CIBW_BUILD"] = "cp3?-*" env["CIBW_SKIP"] = "cp34-*" # build the wheels diff --git a/test/05_environment/cibuildwheel_test.py b/test/05_environment/cibuildwheel_test.py index 90d66288..3303aaff 100644 --- a/test/05_environment/cibuildwheel_test.py +++ b/test/05_environment/cibuildwheel_test.py @@ -10,7 +10,7 @@ def test(): # write some information into the CIBW_ENVIRONMENT, for expansion and # insertion into the environment by cibuildwheel. This is checked # in setup.py - env['CIBW_ENVIRONMENT'] = 'CIBW_TEST_VAR="a b c" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3="$(echo \'test string 3\')" PATH=$PATH:/opt/cibw_test_path', + env['CIBW_ENVIRONMENT'] = 'CIBW_TEST_VAR="a b c" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3="$(echo \'test string 3\')" PATH=$PATH:/opt/cibw_test_path' env['CIBW_ENVIRONMENT_WINDOWS'] = 'CIBW_TEST_VAR="a b c" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3="$(echo \'test string 3\')" PATH="$PATH;/opt/cibw_test_path"' # build the wheels From 0ed37f268a03a8df5a78f92d9503a7887fddc725 Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Mon, 22 Apr 2019 18:35:57 +0100 Subject: [PATCH 08/18] In general, prefer single quotes --- test/02_test/cibuildwheel_test.py | 6 +++--- test/03_before_build/cibuildwheel_test.py | 4 ++-- test/04_build_skip/cibuildwheel_test.py | 4 ++-- test/06_docker_images/cibuildwheel_test.py | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/test/02_test/cibuildwheel_test.py b/test/02_test/cibuildwheel_test.py index bda4131e..55d5ada3 100644 --- a/test/02_test/cibuildwheel_test.py +++ b/test/02_test/cibuildwheel_test.py @@ -8,11 +8,11 @@ import utils def test(): # set up the environment env = os.environ.copy() - env["CIBW_TEST_REQUIRES"] = "nose", + env['CIBW_TEST_REQUIRES'] = 'nose', # the 'false ||' bit is to ensure this command runs in a shell on # mac/linux. - env["CIBW_TEST_COMMAND"] = "false || nosetests {project}/test" - env["CIBW_TEST_COMMAND_WINDOWS"] = "nosetests {project}/test" + env['CIBW_TEST_COMMAND'] = 'false || nosetests {project}/test' + env['CIBW_TEST_COMMAND_WINDOWS'] = 'nosetests {project}/test' # build & test the wheels subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir], env=env) diff --git a/test/03_before_build/cibuildwheel_test.py b/test/03_before_build/cibuildwheel_test.py index 92013a16..9caec0a8 100644 --- a/test/03_before_build/cibuildwheel_test.py +++ b/test/03_before_build/cibuildwheel_test.py @@ -10,8 +10,8 @@ def test(): env = os.environ.copy() # write python version information to a temporary file, this is checked # in setup.py - env["CIBW_BEFORE_BUILD"] = "python -c \"import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)\" && python -c \"import sys; open('/tmp/pythonexecutable.txt', 'w').write(sys.executable)\"", - env["CIBW_BEFORE_BUILD_WINDOWS"] = "python -c \"import sys; open('c:\\pythonversion.txt', 'w').write(sys.version)\" && python -c \"import sys; open('c:\\pythonexecutable.txt', 'w').write(sys.executable)\"" + env['CIBW_BEFORE_BUILD'] = "python -c \"import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)\" && python -c \"import sys; open('/tmp/pythonexecutable.txt', 'w').write(sys.executable)\"" + env['CIBW_BEFORE_BUILD_WINDOWS'] = "python -c \"import sys; open('c:\\pythonversion.txt', 'w').write(sys.version)\" && python -c \"import sys; open('c:\\pythonexecutable.txt', 'w').write(sys.executable)\"" # build the wheels subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir], env=env) diff --git a/test/04_build_skip/cibuildwheel_test.py b/test/04_build_skip/cibuildwheel_test.py index 7be8d7e7..5cecd275 100644 --- a/test/04_build_skip/cibuildwheel_test.py +++ b/test/04_build_skip/cibuildwheel_test.py @@ -8,8 +8,8 @@ import utils def test(): # set up the environment env = os.environ.copy() - env["CIBW_BUILD"] = "cp3?-*" - env["CIBW_SKIP"] = "cp34-*" + env['CIBW_BUILD'] = 'cp3?-*' + env['CIBW_SKIP'] = 'cp34-*' # build the wheels subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir], env=env) diff --git a/test/06_docker_images/cibuildwheel_test.py b/test/06_docker_images/cibuildwheel_test.py index cc7ad968..51686c78 100644 --- a/test/06_docker_images/cibuildwheel_test.py +++ b/test/06_docker_images/cibuildwheel_test.py @@ -12,8 +12,8 @@ def test(): env = os.environ.copy() # change the docker images to use. The docker image is tested in setup.py # during the build - env["CIBW_MANYLINUX1_X86_64_IMAGE"] = "dockcross/manylinux-x64" - env["CIBW_MANYLINUX1_I686_IMAGE"] = "dockcross/manylinux-x86" + env['CIBW_MANYLINUX1_X86_64_IMAGE'] = 'dockcross/manylinux-x64' + env['CIBW_MANYLINUX1_I686_IMAGE'] = 'dockcross/manylinux-x86' # build the wheels subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir], env=env) From 364fc5220ecdc58192380b3412cd8e2f65604f51 Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Mon, 22 Apr 2019 18:44:09 +0100 Subject: [PATCH 09/18] another trailing comma --- test/02_test/cibuildwheel_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/02_test/cibuildwheel_test.py b/test/02_test/cibuildwheel_test.py index 55d5ada3..b6518cb1 100644 --- a/test/02_test/cibuildwheel_test.py +++ b/test/02_test/cibuildwheel_test.py @@ -8,7 +8,7 @@ import utils def test(): # set up the environment env = os.environ.copy() - env['CIBW_TEST_REQUIRES'] = 'nose', + env['CIBW_TEST_REQUIRES'] = 'nose' # the 'false ||' bit is to ensure this command runs in a shell on # mac/linux. env['CIBW_TEST_COMMAND'] = 'false || nosetests {project}/test' From 8b632bcb6dee34bf840155e0d219cae72b452bc0 Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Mon, 22 Apr 2019 18:55:55 +0100 Subject: [PATCH 10/18] Skip cleanup if its not needed (when a test is skipped) --- bin/run_test.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/run_test.py b/bin/run_test.py index bb5cd6db..746061c4 100755 --- a/bin/run_test.py +++ b/bin/run_test.py @@ -10,7 +10,8 @@ def single_run(test_project): ) # clean up - shutil.rmtree('wheelhouse') + if os.path.exists('wheelhouse'): + shutil.rmtree('wheelhouse') if __name__ == '__main__': import argparse From 857aafbd3f3e2cbfe7141367d1345c24f93232a0 Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Mon, 22 Apr 2019 23:13:34 +0100 Subject: [PATCH 11/18] Move the pythonpath fiddling to the test runner instead of including it in every test --- bin/run_test.py | 12 +++++++++++- test/01_basic/cibuildwheel_test.py | 5 ++--- test/02_test/cibuildwheel_test.py | 4 +--- test/03_before_build/cibuildwheel_test.py | 4 +--- test/04_build_skip/cibuildwheel_test.py | 5 ++--- test/05_environment/cibuildwheel_test.py | 4 ++-- test/06_docker_images/cibuildwheel_test.py | 3 +-- test/07_ssl/cibuildwheel_test.py | 3 +-- test/shared/utils.py | 6 ++++++ 9 files changed, 27 insertions(+), 19 deletions(-) diff --git a/bin/run_test.py b/bin/run_test.py index 746061c4..cbf8bee3 100755 --- a/bin/run_test.py +++ b/bin/run_test.py @@ -3,10 +3,20 @@ from __future__ import print_function import os, sys, subprocess, shutil +project_root = os.path.dirname(os.path.dirname(__file__)) +test_utils_dir = os.path.join(project_root, 'test', 'shared') + def single_run(test_project): + # set up an environment that gives access to the test utils + env = os.environ.copy() + env.update({ + 'PYTHONPATH': test_utils_dir, + }) + # run the test subprocess.check_call( - [sys.executable, '-m', 'pytest', '-v', os.path.join(test_project, 'cibuildwheel_test.py')] + [sys.executable, '-m', 'pytest', '-v', os.path.join(test_project, 'cibuildwheel_test.py')], + env=env, ) # clean up diff --git a/test/01_basic/cibuildwheel_test.py b/test/01_basic/cibuildwheel_test.py index 28b83184..008b8086 100644 --- a/test/01_basic/cibuildwheel_test.py +++ b/test/01_basic/cibuildwheel_test.py @@ -1,11 +1,10 @@ import subprocess, sys, os from glob import glob -project_dir = os.path.dirname(__file__) -sys.path.append(os.path.join(os.path.dirname(project_dir), 'shared')) - import utils def test(): + project_dir = os.path.dirname(__file__) + # build the wheels subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir]) diff --git a/test/02_test/cibuildwheel_test.py b/test/02_test/cibuildwheel_test.py index b6518cb1..9ec4fa56 100644 --- a/test/02_test/cibuildwheel_test.py +++ b/test/02_test/cibuildwheel_test.py @@ -1,11 +1,9 @@ import subprocess, sys, os from glob import glob -project_dir = os.path.dirname(__file__) -sys.path.append(os.path.join(os.path.dirname(project_dir), 'shared')) - import utils def test(): + project_dir = os.path.dirname(__file__) # set up the environment env = os.environ.copy() env['CIBW_TEST_REQUIRES'] = 'nose' diff --git a/test/03_before_build/cibuildwheel_test.py b/test/03_before_build/cibuildwheel_test.py index 9caec0a8..5ce69243 100644 --- a/test/03_before_build/cibuildwheel_test.py +++ b/test/03_before_build/cibuildwheel_test.py @@ -1,11 +1,9 @@ import subprocess, sys, os from glob import glob -project_dir = os.path.dirname(__file__) -sys.path.append(os.path.join(os.path.dirname(project_dir), 'shared')) - import utils def test(): + project_dir = os.path.dirname(__file__) # set up the environment env = os.environ.copy() # write python version information to a temporary file, this is checked diff --git a/test/04_build_skip/cibuildwheel_test.py b/test/04_build_skip/cibuildwheel_test.py index 5cecd275..db8d4e9a 100644 --- a/test/04_build_skip/cibuildwheel_test.py +++ b/test/04_build_skip/cibuildwheel_test.py @@ -1,11 +1,10 @@ import subprocess, sys, os from glob import glob -project_dir = os.path.dirname(__file__) -sys.path.append(os.path.join(os.path.dirname(project_dir), 'shared')) - import utils def test(): + project_dir = os.path.dirname(__file__) + # set up the environment env = os.environ.copy() env['CIBW_BUILD'] = 'cp3?-*' diff --git a/test/05_environment/cibuildwheel_test.py b/test/05_environment/cibuildwheel_test.py index 3303aaff..7a707d91 100644 --- a/test/05_environment/cibuildwheel_test.py +++ b/test/05_environment/cibuildwheel_test.py @@ -1,10 +1,10 @@ import subprocess, sys, os from glob import glob -project_dir = os.path.dirname(__file__) -sys.path.append(os.path.join(os.path.dirname(project_dir), 'shared')) import utils def test(): + project_dir = os.path.dirname(__file__) + # set up the environment env = os.environ.copy() # write some information into the CIBW_ENVIRONMENT, for expansion and diff --git a/test/06_docker_images/cibuildwheel_test.py b/test/06_docker_images/cibuildwheel_test.py index 51686c78..de65c0e6 100644 --- a/test/06_docker_images/cibuildwheel_test.py +++ b/test/06_docker_images/cibuildwheel_test.py @@ -1,10 +1,9 @@ import subprocess, sys, os, pytest from glob import glob -project_dir = os.path.dirname(__file__) -sys.path.append(os.path.join(os.path.dirname(project_dir), 'shared')) import utils def test(): + project_dir = os.path.dirname(__file__) if not sys.platform.startswith('linux'): pytest.skip('the docker test is only relevant to the linux build') diff --git a/test/07_ssl/cibuildwheel_test.py b/test/07_ssl/cibuildwheel_test.py index ec3cc1aa..97676b3a 100644 --- a/test/07_ssl/cibuildwheel_test.py +++ b/test/07_ssl/cibuildwheel_test.py @@ -1,10 +1,9 @@ import subprocess, sys, os from glob import glob -project_dir = os.path.dirname(__file__) -sys.path.append(os.path.join(os.path.dirname(project_dir), 'shared')) import utils def test(): + project_dir = os.path.dirname(__file__) # this test checks that SSL is working in the build environment using # some checks in setup.py. diff --git a/test/shared/utils.py b/test/shared/utils.py index e4eca4cb..fe5c1743 100644 --- a/test/shared/utils.py +++ b/test/shared/utils.py @@ -1,3 +1,9 @@ +''' +Utility functions used by the cibuildwheel tests. + +This file is added to the PYTHONPATH in the test runner at bin/run_test.py. +''' + import subprocess, sys def cibuildwheel_get_build_identifiers(project_path, env=None): From 9050137d2b78ac5c5374bd51e923f7b8a43798ab Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Mon, 22 Apr 2019 23:23:49 +0100 Subject: [PATCH 12/18] Neaten the environment modification using triple-quotes and dict.update --- test/02_test/cibuildwheel_test.py | 12 +++++++----- test/03_before_build/cibuildwheel_test.py | 6 ++++-- test/04_build_skip/cibuildwheel_test.py | 6 ++++-- test/05_environment/cibuildwheel_test.py | 6 ++++-- test/06_docker_images/cibuildwheel_test.py | 6 ++++-- 5 files changed, 23 insertions(+), 13 deletions(-) diff --git a/test/02_test/cibuildwheel_test.py b/test/02_test/cibuildwheel_test.py index 9ec4fa56..e70b0172 100644 --- a/test/02_test/cibuildwheel_test.py +++ b/test/02_test/cibuildwheel_test.py @@ -6,11 +6,13 @@ def test(): project_dir = os.path.dirname(__file__) # set up the environment env = os.environ.copy() - env['CIBW_TEST_REQUIRES'] = 'nose' - # the 'false ||' bit is to ensure this command runs in a shell on - # mac/linux. - env['CIBW_TEST_COMMAND'] = 'false || nosetests {project}/test' - env['CIBW_TEST_COMMAND_WINDOWS'] = 'nosetests {project}/test' + env.update({ + 'CIBW_TEST_REQUIRES': 'nose', + # the 'false ||' bit is to ensure this command runs in a shell on + # mac/linux. + 'CIBW_TEST_COMMAND': 'false || nosetests {project}/test', + 'CIBW_TEST_COMMAND_WINDOWS': 'nosetests {project}/test', + }) # build & test the wheels subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir], env=env) diff --git a/test/03_before_build/cibuildwheel_test.py b/test/03_before_build/cibuildwheel_test.py index 5ce69243..cbf902b4 100644 --- a/test/03_before_build/cibuildwheel_test.py +++ b/test/03_before_build/cibuildwheel_test.py @@ -8,8 +8,10 @@ def test(): env = os.environ.copy() # write python version information to a temporary file, this is checked # in setup.py - env['CIBW_BEFORE_BUILD'] = "python -c \"import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)\" && python -c \"import sys; open('/tmp/pythonexecutable.txt', 'w').write(sys.executable)\"" - env['CIBW_BEFORE_BUILD_WINDOWS'] = "python -c \"import sys; open('c:\\pythonversion.txt', 'w').write(sys.version)\" && python -c \"import sys; open('c:\\pythonexecutable.txt', 'w').write(sys.executable)\"" + env.update({ + 'CIBW_BEFORE_BUILD': '''python -c "import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('/tmp/pythonexecutable.txt', 'w').write(sys.executable)"''', + 'CIBW_BEFORE_BUILD_WINDOWS': '''python -c "import sys; open('c:\\pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('c:\\pythonexecutable.txt', 'w').write(sys.executable)"''', + }) # build the wheels subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir], env=env) diff --git a/test/04_build_skip/cibuildwheel_test.py b/test/04_build_skip/cibuildwheel_test.py index db8d4e9a..961d6e2d 100644 --- a/test/04_build_skip/cibuildwheel_test.py +++ b/test/04_build_skip/cibuildwheel_test.py @@ -7,8 +7,10 @@ def test(): # set up the environment env = os.environ.copy() - env['CIBW_BUILD'] = 'cp3?-*' - env['CIBW_SKIP'] = 'cp34-*' + env.update({ + 'CIBW_BUILD': 'cp3?-*', + 'CIBW_SKIP': 'cp34-*', + }) # build the wheels subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir], env=env) diff --git a/test/05_environment/cibuildwheel_test.py b/test/05_environment/cibuildwheel_test.py index 7a707d91..78e43482 100644 --- a/test/05_environment/cibuildwheel_test.py +++ b/test/05_environment/cibuildwheel_test.py @@ -10,8 +10,10 @@ def test(): # write some information into the CIBW_ENVIRONMENT, for expansion and # insertion into the environment by cibuildwheel. This is checked # in setup.py - env['CIBW_ENVIRONMENT'] = 'CIBW_TEST_VAR="a b c" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3="$(echo \'test string 3\')" PATH=$PATH:/opt/cibw_test_path' - env['CIBW_ENVIRONMENT_WINDOWS'] = 'CIBW_TEST_VAR="a b c" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3="$(echo \'test string 3\')" PATH="$PATH;/opt/cibw_test_path"' + env.update({ + 'CIBW_ENVIRONMENT': '''CIBW_TEST_VAR="a b c" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3="$(echo 'test string 3')" PATH=$PATH:/opt/cibw_test_path''', + 'CIBW_ENVIRONMENT_WINDOWS': '''CIBW_TEST_VAR="a b c" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3="$(echo 'test string 3')" PATH="$PATH;/opt/cibw_test_path"''', + }) # build the wheels subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir], env=env) diff --git a/test/06_docker_images/cibuildwheel_test.py b/test/06_docker_images/cibuildwheel_test.py index de65c0e6..7d326806 100644 --- a/test/06_docker_images/cibuildwheel_test.py +++ b/test/06_docker_images/cibuildwheel_test.py @@ -11,8 +11,10 @@ def test(): env = os.environ.copy() # change the docker images to use. The docker image is tested in setup.py # during the build - env['CIBW_MANYLINUX1_X86_64_IMAGE'] = 'dockcross/manylinux-x64' - env['CIBW_MANYLINUX1_I686_IMAGE'] = 'dockcross/manylinux-x86' + env.update({ + 'CIBW_MANYLINUX1_X86_64_IMAGE': 'dockcross/manylinux-x64', + 'CIBW_MANYLINUX1_I686_IMAGE': 'dockcross/manylinux-x86', + }) # build the wheels subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir], env=env) From e360a04dc1d0db8afd0244678d8eff0fdf20f177 Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Mon, 22 Apr 2019 23:25:14 +0100 Subject: [PATCH 13/18] Use utils.platform for platform checks --- test/06_docker_images/cibuildwheel_test.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/06_docker_images/cibuildwheel_test.py b/test/06_docker_images/cibuildwheel_test.py index 7d326806..428debbc 100644 --- a/test/06_docker_images/cibuildwheel_test.py +++ b/test/06_docker_images/cibuildwheel_test.py @@ -4,7 +4,8 @@ import utils def test(): project_dir = os.path.dirname(__file__) - if not sys.platform.startswith('linux'): + + if utils.platform != 'linux': pytest.skip('the docker test is only relevant to the linux build') # set up the environment From e87032c830fc65bd25465565b96400618b3ed7d8 Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Tue, 23 Apr 2019 22:14:17 +0100 Subject: [PATCH 14/18] Rework tests check all wheels produced against a reference list Also, wrap the cibuildwheel call to make building env easier --- test/01_basic/cibuildwheel_test.py | 55 +++++----------- test/02_test/cibuildwheel_test.py | 20 +++--- test/03_before_build/cibuildwheel_test.py | 24 +++---- test/04_build_skip/cibuildwheel_test.py | 49 +++------------ test/05_environment/cibuildwheel_test.py | 20 +++--- test/06_docker_images/cibuildwheel_test.py | 20 ++---- test/07_ssl/cibuildwheel_test.py | 11 +--- test/shared/utils.py | 73 +++++++++++++++++++++- 8 files changed, 126 insertions(+), 146 deletions(-) diff --git a/test/01_basic/cibuildwheel_test.py b/test/01_basic/cibuildwheel_test.py index 008b8086..93c67829 100644 --- a/test/01_basic/cibuildwheel_test.py +++ b/test/01_basic/cibuildwheel_test.py @@ -1,49 +1,22 @@ -import subprocess, sys, os -from glob import glob +import os import utils + +project_dir = os.path.dirname(__file__) + def test(): - project_dir = os.path.dirname(__file__) - # build the wheels - subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir]) - - # check that every wheel is produced - if utils.platform == 'linux': - assert glob('wheelhouse/*-cp27-cp27m-manylinux1_x86_64.whl') - assert glob('wheelhouse/*-cp27-cp27mu-manylinux1_x86_64.whl') - assert glob('wheelhouse/*-cp34-cp34m-manylinux1_x86_64.whl') - assert glob('wheelhouse/*-cp35-cp35m-manylinux1_x86_64.whl') - assert glob('wheelhouse/*-cp36-cp36m-manylinux1_x86_64.whl') - assert glob('wheelhouse/*-cp37-cp37m-manylinux1_x86_64.whl') - assert glob('wheelhouse/*-cp27-cp27m-manylinux1_i686.whl') - assert glob('wheelhouse/*-cp27-cp27mu-manylinux1_i686.whl') - assert glob('wheelhouse/*-cp34-cp34m-manylinux1_i686.whl') - assert glob('wheelhouse/*-cp35-cp35m-manylinux1_i686.whl') - assert glob('wheelhouse/*-cp36-cp36m-manylinux1_i686.whl') - assert glob('wheelhouse/*-cp37-cp37m-manylinux1_i686.whl') + utils.cibuildwheel_run(project_dir) - if utils.platform == 'windows': - assert glob('wheelhouse/*-cp27-*-win32.whl') - assert glob('wheelhouse/*-cp34-*-win32.whl') - assert glob('wheelhouse/*-cp35-*-win32.whl') - assert glob('wheelhouse/*-cp36-*-win32.whl') - assert glob('wheelhouse/*-cp37-*-win32.whl') - assert glob('wheelhouse/*-cp27-*-win_amd64.whl') - assert glob('wheelhouse/*-cp34-*-win_amd64.whl') - assert glob('wheelhouse/*-cp35-*-win_amd64.whl') - assert glob('wheelhouse/*-cp36-*-win_amd64.whl') - assert glob('wheelhouse/*-cp37-*-win_amd64.whl') + # check that the expected wheels are produced + expected_wheels = utils.expected_wheels('spam', '0.1.0') + actual_wheels = os.listdir('wheelhouse') + assert set(actual_wheels) == set(expected_wheels) - if utils.platform == 'macos': - assert glob('wheelhouse/*-cp27-*-macosx_10_6_intel.whl') - assert glob('wheelhouse/*-cp34-*-macosx_10_6_intel.whl') - assert glob('wheelhouse/*-cp35-*-macosx_10_6_intel.whl') - assert glob('wheelhouse/*-cp36-*-macosx_10_6_intel.whl') - assert glob('wheelhouse/*-cp37-*-macosx_10_6_intel.whl') - # also check that the number of built wheels matches the number of build +def test_build_identifiers(): + # check that the number of expected wheels matches the number of build # identifiers - expected_identifiers = utils.cibuildwheel_get_build_identifiers(project_dir) - built_wheels = glob('wheelhouse/*.whl') - assert len(built_wheels) == len(expected_identifiers) + expected_wheels = utils.expected_wheels('spam', '0.1.0') + build_identifiers = utils.cibuildwheel_get_build_identifiers(project_dir) + assert len(expected_wheels) == len(build_identifiers) diff --git a/test/02_test/cibuildwheel_test.py b/test/02_test/cibuildwheel_test.py index e70b0172..005ee68b 100644 --- a/test/02_test/cibuildwheel_test.py +++ b/test/02_test/cibuildwheel_test.py @@ -1,23 +1,19 @@ -import subprocess, sys, os -from glob import glob +import os import utils def test(): project_dir = os.path.dirname(__file__) - # set up the environment - env = os.environ.copy() - env.update({ + + # build and test the wheels + utils.run_cibuildwheel(project_dir, add_env={ 'CIBW_TEST_REQUIRES': 'nose', # the 'false ||' bit is to ensure this command runs in a shell on # mac/linux. 'CIBW_TEST_COMMAND': 'false || nosetests {project}/test', 'CIBW_TEST_COMMAND_WINDOWS': 'nosetests {project}/test', }) - - # build & test the wheels - subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir], env=env) - # also check that we got the right number of built wheels - expected_identifiers = utils.cibuildwheel_get_build_identifiers(project_dir) - built_wheels = glob('wheelhouse/*.whl') - assert len(built_wheels) == len(expected_identifiers) + # also check that we got the right wheels + expected_wheels = utils.expected_wheels('spam', '0.1.0') + actual_wheels = os.listdir('wheelhouse') + assert set(actual_wheels) == set(expected_wheels) diff --git a/test/03_before_build/cibuildwheel_test.py b/test/03_before_build/cibuildwheel_test.py index cbf902b4..6bb0872f 100644 --- a/test/03_before_build/cibuildwheel_test.py +++ b/test/03_before_build/cibuildwheel_test.py @@ -1,22 +1,18 @@ -import subprocess, sys, os -from glob import glob +import os import utils def test(): project_dir = os.path.dirname(__file__) - # set up the environment - env = os.environ.copy() - # write python version information to a temporary file, this is checked - # in setup.py - env.update({ + + # build the wheels + utils.run_cibuildwheel(project_dir, add_env={ + # write python version information to a temporary file, this is + # checked in setup.py 'CIBW_BEFORE_BUILD': '''python -c "import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('/tmp/pythonexecutable.txt', 'w').write(sys.executable)"''', 'CIBW_BEFORE_BUILD_WINDOWS': '''python -c "import sys; open('c:\\pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('c:\\pythonexecutable.txt', 'w').write(sys.executable)"''', }) - - # build the wheels - subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir], env=env) - # check that we got the right number of built wheels - expected_identifiers = utils.cibuildwheel_get_build_identifiers(project_dir) - built_wheels = glob('wheelhouse/*.whl') - assert len(built_wheels) == len(expected_identifiers) + # also check that we got the right wheels + expected_wheels = utils.expected_wheels('spam', '0.1.0') + actual_wheels = os.listdir('wheelhouse') + assert set(actual_wheels) == set(expected_wheels) diff --git a/test/04_build_skip/cibuildwheel_test.py b/test/04_build_skip/cibuildwheel_test.py index 961d6e2d..06c7e41e 100644 --- a/test/04_build_skip/cibuildwheel_test.py +++ b/test/04_build_skip/cibuildwheel_test.py @@ -1,50 +1,17 @@ -import subprocess, sys, os -from glob import glob +import os import utils def test(): project_dir = os.path.dirname(__file__) - - # set up the environment - env = os.environ.copy() - env.update({ + + # build the wheels + utils.run_cibuildwheel(project_dir, add_env={ 'CIBW_BUILD': 'cp3?-*', 'CIBW_SKIP': 'cp34-*', }) - # build the wheels - subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir], env=env) - # check that we got the right wheels. There should be no 2.7 or 3.4. - if utils.platform == 'linux': - assert not glob('wheelhouse/*-cp27-cp27m-manylinux1_x86_64.whl') - assert not glob('wheelhouse/*-cp27-cp27mu-manylinux1_x86_64.whl') - assert not glob('wheelhouse/*-cp34-cp34m-manylinux1_x86_64.whl') - assert glob('wheelhouse/*-cp35-cp35m-manylinux1_x86_64.whl') - assert glob('wheelhouse/*-cp36-cp36m-manylinux1_x86_64.whl') - assert glob('wheelhouse/*-cp37-cp37m-manylinux1_x86_64.whl') - assert not glob('wheelhouse/*-cp27-cp27m-manylinux1_i686.whl') - assert not glob('wheelhouse/*-cp27-cp27mu-manylinux1_i686.whl') - assert not glob('wheelhouse/*-cp34-cp34m-manylinux1_i686.whl') - assert glob('wheelhouse/*-cp35-cp35m-manylinux1_i686.whl') - assert glob('wheelhouse/*-cp36-cp36m-manylinux1_i686.whl') - assert glob('wheelhouse/*-cp37-cp37m-manylinux1_i686.whl') - - if utils.platform == 'windows': - assert not glob('wheelhouse/*-cp27-*-win32.whl') - assert not glob('wheelhouse/*-cp34-*-win32.whl') - assert glob('wheelhouse/*-cp35-*-win32.whl') - assert glob('wheelhouse/*-cp36-*-win32.whl') - assert glob('wheelhouse/*-cp37-*-win32.whl') - assert not glob('wheelhouse/*-cp27-*-win_amd64.whl') - assert not glob('wheelhouse/*-cp34-*-win_amd64.whl') - assert glob('wheelhouse/*-cp35-*-win_amd64.whl') - assert glob('wheelhouse/*-cp36-*-win_amd64.whl') - assert glob('wheelhouse/*-cp37-*-win_amd64.whl') - - if utils.platform == 'macos': - assert not glob('wheelhouse/*-cp27-*-macosx_10_6_intel.whl') - assert not glob('wheelhouse/*-cp34-*-macosx_10_6_intel.whl') - assert glob('wheelhouse/*-cp35-*-macosx_10_6_intel.whl') - assert glob('wheelhouse/*-cp36-*-macosx_10_6_intel.whl') - assert glob('wheelhouse/*-cp37-*-macosx_10_6_intel.whl') + expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0') + if ('-cp3' in w) and ('-cp34' not in w)] + actual_wheels = os.listdir('wheelhouse') + assert set(actual_wheels) == set(expected_wheels) diff --git a/test/05_environment/cibuildwheel_test.py b/test/05_environment/cibuildwheel_test.py index 78e43482..c5b5aad5 100644 --- a/test/05_environment/cibuildwheel_test.py +++ b/test/05_environment/cibuildwheel_test.py @@ -1,24 +1,18 @@ -import subprocess, sys, os -from glob import glob +import os import utils def test(): project_dir = os.path.dirname(__file__) - - # set up the environment - env = os.environ.copy() + # write some information into the CIBW_ENVIRONMENT, for expansion and # insertion into the environment by cibuildwheel. This is checked # in setup.py - env.update({ + utils.run_cibuildwheel(project_dir, add_env={ 'CIBW_ENVIRONMENT': '''CIBW_TEST_VAR="a b c" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3="$(echo 'test string 3')" PATH=$PATH:/opt/cibw_test_path''', 'CIBW_ENVIRONMENT_WINDOWS': '''CIBW_TEST_VAR="a b c" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3="$(echo 'test string 3')" PATH="$PATH;/opt/cibw_test_path"''', }) - # build the wheels - subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir], env=env) - - # check that we got the right number of built wheels - expected_identifiers = utils.cibuildwheel_get_build_identifiers(project_dir) - built_wheels = glob('wheelhouse/*.whl') - assert len(built_wheels) == len(expected_identifiers) + # also check that we got the right wheels built + expected_wheels = utils.expected_wheels('spam', '0.1.0') + actual_wheels = os.listdir('wheelhouse') + assert set(actual_wheels) == set(expected_wheels) diff --git a/test/06_docker_images/cibuildwheel_test.py b/test/06_docker_images/cibuildwheel_test.py index 428debbc..0d425b03 100644 --- a/test/06_docker_images/cibuildwheel_test.py +++ b/test/06_docker_images/cibuildwheel_test.py @@ -1,5 +1,4 @@ -import subprocess, sys, os, pytest -from glob import glob +import os, pytest import utils def test(): @@ -8,19 +7,12 @@ def test(): if utils.platform != 'linux': pytest.skip('the docker test is only relevant to the linux build') - # set up the environment - env = os.environ.copy() - # change the docker images to use. The docker image is tested in setup.py - # during the build - env.update({ + utils.run_cibuildwheel(project_dir, add_env={ 'CIBW_MANYLINUX1_X86_64_IMAGE': 'dockcross/manylinux-x64', 'CIBW_MANYLINUX1_I686_IMAGE': 'dockcross/manylinux-x86', }) - # build the wheels - subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir], env=env) - - # check that we got the right number of built wheels - expected_identifiers = utils.cibuildwheel_get_build_identifiers(project_dir) - built_wheels = glob('wheelhouse/*.whl') - assert len(built_wheels) == len(expected_identifiers) + # also check that we got the right wheels built + expected_wheels = utils.expected_wheels('spam', '0.1.0') + actual_wheels = os.listdir('wheelhouse') + assert set(actual_wheels) == set(expected_wheels) diff --git a/test/07_ssl/cibuildwheel_test.py b/test/07_ssl/cibuildwheel_test.py index 97676b3a..fd3fff87 100644 --- a/test/07_ssl/cibuildwheel_test.py +++ b/test/07_ssl/cibuildwheel_test.py @@ -1,5 +1,4 @@ -import subprocess, sys, os -from glob import glob +import os import utils def test(): @@ -7,10 +6,4 @@ def test(): # this test checks that SSL is working in the build environment using # some checks in setup.py. - # build the wheels - subprocess.check_call([sys.executable, '-m', 'cibuildwheel', project_dir]) - - # check that we got the right number of built wheels - expected_identifiers = utils.cibuildwheel_get_build_identifiers(project_dir) - built_wheels = glob('wheelhouse/*.whl') - assert len(built_wheels) == len(expected_identifiers) + utils.cibuildwheel_run(project_dir) diff --git a/test/shared/utils.py b/test/shared/utils.py index fe5c1743..b6a720f5 100644 --- a/test/shared/utils.py +++ b/test/shared/utils.py @@ -4,7 +4,8 @@ Utility functions used by the cibuildwheel tests. This file is added to the PYTHONPATH in the test runner at bin/run_test.py. ''' -import subprocess, sys +import subprocess, sys, os + def cibuildwheel_get_build_identifiers(project_path, env=None): ''' @@ -19,9 +20,77 @@ def cibuildwheel_get_build_identifiers(project_path, env=None): return cmd_output.strip().split('\n') + +def cibuildwheel_run(project_path, env=None, add_env=None): + ''' + Runs cibuildwheel as a subprocess, building the project at project_path. + + Uses the current Python interpreter. + Configure settings using env. + ''' + if env is None: + env = os.environ.copy() + + if add_env is not None: + env.update(add_env) + + subprocess.check_call( + [sys.executable, '-m', 'cibuildwheel', project_path], + env=env, + ) + + +def expected_wheels(package_name, package_version): + ''' + Returns a list of expected wheels from a run of cibuildwheel. + ''' + if platform == 'linux': + templates = [ + '{package_name}-{package_version}-cp27-cp27m-manylinux1_x86_64.whl', + '{package_name}-{package_version}-cp27-cp27mu-manylinux1_x86_64.whl', + '{package_name}-{package_version}-cp34-cp34m-manylinux1_x86_64.whl', + '{package_name}-{package_version}-cp35-cp35m-manylinux1_x86_64.whl', + '{package_name}-{package_version}-cp36-cp36m-manylinux1_x86_64.whl', + '{package_name}-{package_version}-cp37-cp37m-manylinux1_x86_64.whl', + '{package_name}-{package_version}-cp27-cp27m-manylinux1_i686.whl', + '{package_name}-{package_version}-cp27-cp27mu-manylinux1_i686.whl', + '{package_name}-{package_version}-cp34-cp34m-manylinux1_i686.whl', + '{package_name}-{package_version}-cp35-cp35m-manylinux1_i686.whl', + '{package_name}-{package_version}-cp36-cp36m-manylinux1_i686.whl', + '{package_name}-{package_version}-cp37-cp37m-manylinux1_i686.whl', + ] + elif platform == 'windows': + templates = [ + '{package_name}-{package_version}-cp27-cp27m-win32.whl', + '{package_name}-{package_version}-cp34-cp34m-win32.whl', + '{package_name}-{package_version}-cp35-cp35m-win32.whl', + '{package_name}-{package_version}-cp36-cp36m-win32.whl', + '{package_name}-{package_version}-cp37-cp37m-win32.whl', + '{package_name}-{package_version}-cp27-cp27m-win_amd64.whl', + '{package_name}-{package_version}-cp34-cp34m-win_amd64.whl', + '{package_name}-{package_version}-cp35-cp35m-win_amd64.whl', + '{package_name}-{package_version}-cp36-cp36m-win_amd64.whl', + '{package_name}-{package_version}-cp37-cp37m-win_amd64.whl', + ] + elif platform == 'macos': + templates = [ + '{package_name}-{package_version}-cp27-cp27m-macosx_10_6_intel.whl', + '{package_name}-{package_version}-cp34-cp34m-macosx_10_6_intel.whl', + '{package_name}-{package_version}-cp35-cp35m-macosx_10_6_intel.whl', + '{package_name}-{package_version}-cp36-cp36m-macosx_10_6_intel.whl', + '{package_name}-{package_version}-cp37-cp37m-macosx_10_6_intel.whl', + ] + else: + raise Exception('unsupported platform') + + return [filename.format(package_name=package_name, package_version=package_version) + for filename in templates] + platform = None -if sys.platform.startswith('linux'): +if 'CIBW_PLATFORM' in os.environ: + platform = os.environ['CIBW_PLATFORM'] +elif sys.platform.startswith('linux'): platform = 'linux' elif sys.platform.startswith('darwin'): platform = 'macos' From f29697d623b19dad7b9684c28b3388b02c384e15 Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Tue, 23 Apr 2019 22:17:03 +0100 Subject: [PATCH 15/18] Retain PYTHONPATH if already in env --- bin/run_test.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/bin/run_test.py b/bin/run_test.py index cbf8bee3..801aed0e 100755 --- a/bin/run_test.py +++ b/bin/run_test.py @@ -9,9 +9,11 @@ test_utils_dir = os.path.join(project_root, 'test', 'shared') def single_run(test_project): # set up an environment that gives access to the test utils env = os.environ.copy() - env.update({ - 'PYTHONPATH': test_utils_dir, - }) + + if 'PYTHONPATH' in env: + env['PYTHONPATH'] += os.pathsep + test_utils_dir + else: + env['PYTHONPATH'] = test_utils_dir # run the test subprocess.check_call( From bab8b6668e680f2bc3fc4082433c0ac0f661b2ef Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Tue, 23 Apr 2019 22:17:25 +0100 Subject: [PATCH 16/18] Full error output during pytest fails --- bin/run_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/run_test.py b/bin/run_test.py index 801aed0e..b9abde02 100755 --- a/bin/run_test.py +++ b/bin/run_test.py @@ -17,7 +17,7 @@ def single_run(test_project): # run the test subprocess.check_call( - [sys.executable, '-m', 'pytest', '-v', os.path.join(test_project, 'cibuildwheel_test.py')], + [sys.executable, '-m', 'pytest', '-vv', os.path.join(test_project, 'cibuildwheel_test.py')], env=env, ) From 3f5572e956242fb8b2eed0c4624fbc4f1d3f6da3 Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Tue, 23 Apr 2019 22:17:59 +0100 Subject: [PATCH 17/18] Make included scripts virtualenv-friendly --- bin/run_test.py | 2 +- bin/run_tests.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/run_test.py b/bin/run_test.py index b9abde02..4891d783 100755 --- a/bin/run_test.py +++ b/bin/run_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python from __future__ import print_function import os, sys, subprocess, shutil diff --git a/bin/run_tests.py b/bin/run_tests.py index b39999f6..279a992c 100755 --- a/bin/run_tests.py +++ b/bin/run_tests.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python from __future__ import print_function import os, sys, subprocess, shutil, json From f7d93cc9e471b0be0d0110aaff6e9b6275bb0f68 Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Tue, 23 Apr 2019 22:23:54 +0100 Subject: [PATCH 18/18] Fix function name --- test/02_test/cibuildwheel_test.py | 2 +- test/03_before_build/cibuildwheel_test.py | 2 +- test/04_build_skip/cibuildwheel_test.py | 2 +- test/05_environment/cibuildwheel_test.py | 2 +- test/06_docker_images/cibuildwheel_test.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/02_test/cibuildwheel_test.py b/test/02_test/cibuildwheel_test.py index 005ee68b..aa1de0fd 100644 --- a/test/02_test/cibuildwheel_test.py +++ b/test/02_test/cibuildwheel_test.py @@ -5,7 +5,7 @@ def test(): project_dir = os.path.dirname(__file__) # build and test the wheels - utils.run_cibuildwheel(project_dir, add_env={ + utils.cibuildwheel_run(project_dir, add_env={ 'CIBW_TEST_REQUIRES': 'nose', # the 'false ||' bit is to ensure this command runs in a shell on # mac/linux. diff --git a/test/03_before_build/cibuildwheel_test.py b/test/03_before_build/cibuildwheel_test.py index 6bb0872f..a9d7614d 100644 --- a/test/03_before_build/cibuildwheel_test.py +++ b/test/03_before_build/cibuildwheel_test.py @@ -5,7 +5,7 @@ def test(): project_dir = os.path.dirname(__file__) # build the wheels - utils.run_cibuildwheel(project_dir, add_env={ + utils.cibuildwheel_run(project_dir, add_env={ # write python version information to a temporary file, this is # checked in setup.py 'CIBW_BEFORE_BUILD': '''python -c "import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('/tmp/pythonexecutable.txt', 'w').write(sys.executable)"''', diff --git a/test/04_build_skip/cibuildwheel_test.py b/test/04_build_skip/cibuildwheel_test.py index 06c7e41e..98333fd2 100644 --- a/test/04_build_skip/cibuildwheel_test.py +++ b/test/04_build_skip/cibuildwheel_test.py @@ -5,7 +5,7 @@ def test(): project_dir = os.path.dirname(__file__) # build the wheels - utils.run_cibuildwheel(project_dir, add_env={ + utils.cibuildwheel_run(project_dir, add_env={ 'CIBW_BUILD': 'cp3?-*', 'CIBW_SKIP': 'cp34-*', }) diff --git a/test/05_environment/cibuildwheel_test.py b/test/05_environment/cibuildwheel_test.py index c5b5aad5..3b0a0678 100644 --- a/test/05_environment/cibuildwheel_test.py +++ b/test/05_environment/cibuildwheel_test.py @@ -7,7 +7,7 @@ def test(): # write some information into the CIBW_ENVIRONMENT, for expansion and # insertion into the environment by cibuildwheel. This is checked # in setup.py - utils.run_cibuildwheel(project_dir, add_env={ + utils.cibuildwheel_run(project_dir, add_env={ 'CIBW_ENVIRONMENT': '''CIBW_TEST_VAR="a b c" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3="$(echo 'test string 3')" PATH=$PATH:/opt/cibw_test_path''', 'CIBW_ENVIRONMENT_WINDOWS': '''CIBW_TEST_VAR="a b c" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3="$(echo 'test string 3')" PATH="$PATH;/opt/cibw_test_path"''', }) diff --git a/test/06_docker_images/cibuildwheel_test.py b/test/06_docker_images/cibuildwheel_test.py index 0d425b03..a5448485 100644 --- a/test/06_docker_images/cibuildwheel_test.py +++ b/test/06_docker_images/cibuildwheel_test.py @@ -7,7 +7,7 @@ def test(): if utils.platform != 'linux': pytest.skip('the docker test is only relevant to the linux build') - utils.run_cibuildwheel(project_dir, add_env={ + utils.cibuildwheel_run(project_dir, add_env={ 'CIBW_MANYLINUX1_X86_64_IMAGE': 'dockcross/manylinux-x64', 'CIBW_MANYLINUX1_I686_IMAGE': 'dockcross/manylinux-x86', })