From 007be7aea734802b6ec865b67b703a3dcb37000a Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Sat, 2 May 2020 22:42:35 +0100 Subject: [PATCH] Ensure tests are up-to-date with master --- test/test_02_testing.py | 61 ++++++++++++++++------------------ test/test_03_before_build.py | 38 ++++++++------------- test/test_04_build_skip.py | 20 +++++------ test/test_05_environment.py | 34 +++++++++++++------ test/test_06_docker_images.py | 27 ++++++--------- test/test_09_cpp_standards.py | 24 +++---------- test/test_10_before_test.py | 2 +- test/test_12_subdir_package.py | 5 ++- 8 files changed, 94 insertions(+), 117 deletions(-) diff --git a/test/test_02_testing.py b/test/test_02_testing.py index 59dda512..369f1505 100644 --- a/test/test_02_testing.py +++ b/test/test_02_testing.py @@ -26,55 +26,52 @@ def test(tmpdir): project_with_a_test.generate(project_dir) # build and test the wheels - actual_wheels = 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. - "CIBW_TEST_COMMAND": "false || nosetests {project}/test", - "CIBW_TEST_COMMAND_WINDOWS": "nosetests {project}/test", - }, - ) + actual_wheels = 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. + 'CIBW_TEST_COMMAND': 'false || nosetests {project}/test', + 'CIBW_TEST_COMMAND_WINDOWS': 'COLOR 00 || nosetests {project}/test', + }) # also check that we got the right wheels - expected_wheels = utils.expected_wheels("spam", "0.1.0") + expected_wheels = utils.expected_wheels('spam', '0.1.0') assert set(actual_wheels) == set(expected_wheels) + def test_extras_require(tmpdir): project_dir = str(tmpdir) project_with_a_test.generate(project_dir) # build and test the wheels - actual_wheels = utils.cibuildwheel_run( - project_dir, - add_env={ - "CIBW_TEST_EXTRAS": "test", - "CIBW_TEST_COMMAND": "nosetests {project}/test", - }, - ) + actual_wheels = utils.cibuildwheel_run(project_dir, add_env={ + 'CIBW_TEST_EXTRAS': 'test', + # 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': 'COLOR 00 || nosetests {project}/test', + }) # also check that we got the right wheels - expected_wheels = utils.expected_wheels("spam", "0.1.0") + expected_wheels = utils.expected_wheels('spam', '0.1.0') assert set(actual_wheels) == set(expected_wheels) -def test_failing_test(tmpdir): +def test_failing_test(tmp_path): """Ensure a failing test causes cibuildwheel to error out and exit""" - project_dir = str(tmpdir) + project_dir = str(tmp_path / 'project') + output_dir = str(tmp_path / 'output') project_with_a_test.generate(project_dir) with pytest.raises(subprocess.CalledProcessError): - utils.cibuildwheel_run( - project_dir, - add_env={ - "CIBW_TEST_COMMAND": "false", - # manylinux1 has a version of bash that's been shown to have - # problems with this, so let's check that. - "CIBW_MANYLINUX_I686_IMAGE": "manylinux1", - "CIBW_MANYLINUX_X86_64_IMAGE": "manylinux1", - }, - ) + utils.cibuildwheel_run(project_dir, output_dir=output_dir, add_env={ + 'CIBW_TEST_COMMAND': 'false', + # manylinux1 has a version of bash that's been shown to have + # problems with this, so let's check that. + 'CIBW_MANYLINUX_I686_IMAGE': 'manylinux1', + 'CIBW_MANYLINUX_X86_64_IMAGE': 'manylinux1', + }) + + assert len(os.listdir(output_dir)) == 0 - assert len(os.listdir("wheelhouse")) diff --git a/test/test_03_before_build.py b/test/test_03_before_build.py index 69b4ff20..58e51b2d 100644 --- a/test/test_03_before_build.py +++ b/test/test_03_before_build.py @@ -9,28 +9,21 @@ project_with_before_build_asserts = CTemplateProject( # assert that the Python version as written to pythonversion.txt in the CIBW_BEFORE_BUILD step # is the same one as is currently running. - version_file = ( - "c:\\pythonversion.txt" if sys.platform == "win32" else "/tmp/pythonversion.txt" - ) + version_file = 'c:\\pythonversion.txt' if sys.platform == 'win32' else '/tmp/pythonversion.txt' with open(version_file) as f: stored_version = f.read() - print("stored_version", stored_version) - print("sys.version", sys.version) + print('stored_version', stored_version) + print('sys.version', sys.version) assert stored_version == sys.version # check that the executable also was written - executable_file = ( - "c:\\pythonexecutable.txt" if sys.platform == "win32" else "/tmp/pythonexecutable.txt" - ) + executable_file = 'c:\\pythonexecutable.txt' if sys.platform == 'win32' else '/tmp/pythonexecutable.txt' with open(executable_file) as f: stored_executable = f.read() - print("stored_executable", stored_executable) - print("sys.executable", sys.executable) + print('stored_executable', stored_executable) + print('sys.executable', sys.executable) # windows/mac are case insensitive - assert ( - os.path.realpath(stored_executable).lower() - == os.path.realpath(sys.executable).lower() - ) + assert os.path.realpath(stored_executable).lower() == os.path.realpath(sys.executable).lower() ''') ) @@ -40,16 +33,13 @@ def test(tmpdir): project_with_before_build_asserts.generate(project_dir) # build the wheels - actual_wheels = 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)"''', - "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)"''', - }, - ) + actual_wheels = 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)"''', + '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)"''', + }) # also check that we got the right wheels - expected_wheels = utils.expected_wheels("spam", "0.1.0") + expected_wheels = utils.expected_wheels('spam', '0.1.0') assert set(actual_wheels) == set(expected_wheels) diff --git a/test/test_04_build_skip.py b/test/test_04_build_skip.py index 0505f20d..73f0de52 100644 --- a/test/test_04_build_skip.py +++ b/test/test_04_build_skip.py @@ -5,11 +5,11 @@ from .template_projects import CTemplateProject project_with_skip_asserts = CTemplateProject( setup_py_add=textwrap.dedent(r''' - # explode if run on Python 2.7 or Python 3.4 (these should be skipped) + # explode if run on Python 2.7 or Python 3.7 (these should be skipped) if sys.version_info[0:2] == (2, 7): raise Exception("Python 2.7 should not be built") - if sys.version_info[0:2] == (3, 4): - raise Exception("Python 3.4 should be skipped") + if sys.version_info[0:2] == (3, 7): + raise Exception("Python 3.7 should be skipped") ''') ) @@ -18,14 +18,12 @@ def test(tmpdir): project_with_skip_asserts.generate(project_dir) # build the wheels - actual_wheels = utils.cibuildwheel_run( - project_dir, add_env={"CIBW_BUILD": "cp3?-*", "CIBW_SKIP": "cp37-*",} - ) + actual_wheels = utils.cibuildwheel_run(project_dir, add_env={ + 'CIBW_BUILD': 'cp3?-*', + 'CIBW_SKIP': 'cp37-*', + }) # check that we got the right wheels. There should be no 2.7 or 3.7. - expected_wheels = [ - w - for w in utils.expected_wheels("spam", "0.1.0") - if ("-cp3" in w) and ("-cp37" not in w) - ] + expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0') + if ('-cp3' in w) and ('-cp37' not in w)] assert set(actual_wheels) == set(expected_wheels) diff --git a/test/test_05_environment.py b/test/test_05_environment.py index 1e6f25b5..5e4b9ee6 100644 --- a/test/test_05_environment.py +++ b/test/test_05_environment.py @@ -1,4 +1,7 @@ -import os, inspect, textwrap +import os +import pytest +import subprocess +import textwrap from . import utils from .template_projects import CTemplateProject @@ -30,15 +33,26 @@ def test(tmpdir): # write some information into the CIBW_ENVIRONMENT, for expansion and # insertion into the environment by cibuildwheel. This is checked - # in setup_py_add - actual_wheels = 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"''', - }, - ) + # in setup.py + actual_wheels = 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"''', + }) # also check that we got the right wheels built - expected_wheels = utils.expected_wheels("spam", "0.1.0") + expected_wheels = utils.expected_wheels('spam', '0.1.0') assert set(actual_wheels) == set(expected_wheels) + + +def test_overridden_path(tmp_path): + project_dir = str(tmp_path / 'project') + output_dir = str(tmp_path / 'output') + CTemplateProject().generate(project_dir) + + # mess up PATH, somehow + with pytest.raises(subprocess.CalledProcessError): + utils.cibuildwheel_run(project_dir, output_dir=output_dir, add_env={ + 'CIBW_ENVIRONMENT': '''SOMETHING="$(mkdir new_path && touch new_path/python)" PATH="$(realpath new_path):$PATH"''', + 'CIBW_ENVIRONMENT_WINDOWS': '''SOMETHING="$(mkdir new_path && type nul > new_path/python.exe)" PATH="$CD\\new_path;$PATH"''', + }) + assert len(os.listdir(output_dir)) == 0 diff --git a/test/test_06_docker_images.py b/test/test_06_docker_images.py index 57a487d3..5a0af5ce 100644 --- a/test/test_06_docker_images.py +++ b/test/test_06_docker_images.py @@ -17,26 +17,21 @@ dockcross_only_project = CTemplateProject( ) def test(tmpdir): - if utils.platform != "linux": - pytest.skip("the test is only relevant to the linux build") + if utils.platform != 'linux': + pytest.skip('the test is only relevant to the linux build') + if platform.machine() not in ['x86_64', 'i686']: + pytest.skip('this test is currently only possible on x86_64/i686 due to availability of alternative images') project_dir = str(tmpdir) dockcross_only_project.generate(project_dir) - actual_wheels = utils.cibuildwheel_run( - project_dir, - add_env={ - "CIBW_MANYLINUX_X86_64_IMAGE": "dockcross/manylinux2010-x64", - "CIBW_MANYLINUX_I686_IMAGE": "dockcross/manylinux1-x86", - "CIBW_BEFORE_BUILD": "/opt/python/cp36-cp36m/bin/pip install -U auditwheel", # Currently necessary on dockcross images to get auditwheel 2.1 supporting AUDITWHEEL_PLAT - "CIBW_ENVIRONMENT": 'AUDITWHEEL_PLAT=`if [ $(uname -i) == "x86_64" ]; then echo "manylinux2010_x86_64"; else echo "manylinux1_i686"; fi`', - }, - ) + actual_wheels = utils.cibuildwheel_run(project_dir, add_env={ + 'CIBW_MANYLINUX_X86_64_IMAGE': 'dockcross/manylinux2010-x64', + 'CIBW_MANYLINUX_I686_IMAGE': 'dockcross/manylinux2010-x86', + 'CIBW_SKIP': 'pp*', + }) # also check that we got the right wheels built - expected_wheels = [ - w - for w in utils.expected_wheels("spam", "0.1.0") - if "-manylinux2010_i686" not in w - ] + expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0') + if '-pp' not in w] assert set(actual_wheels) == set(expected_wheels) diff --git a/test/test_09_cpp_standards.py b/test/test_09_cpp_standards.py index 32719df7..dcf39f72 100644 --- a/test/test_09_cpp_standards.py +++ b/test/test_09_cpp_standards.py @@ -7,14 +7,13 @@ from . import utils from .template_projects import SetuptoolsTemplateProject import jinja2 -# TODO: specify these at runtime according to manylinux_image cpp_project = SetuptoolsTemplateProject( setup_py_add='''ext_modules=[Extension('spam', sources=['spam.cpp'])],''' ) cpp_project.files['spam.cpp'] = jinja2.Template(r''' #include -{{ spam_cpp_add }} +{{ spam_cpp_top_level_add }} static PyObject * spam_system(PyObject *self, PyObject *args) @@ -64,28 +63,13 @@ MOD_INIT(spam) } ''') -spam_cpp_top_level_add = ''' -// Depending on the requested standard, use a modern C++ feature -// that was introduced in that standard. -#if STANDARD == 11 - #include -#elif STANDARD == 14 - int a = 100'000; -#elif STANDARD == 17 - #include - auto a = std::pair(5.0, false); -#else - #error Standard needed -#endif -''' - project_dir = os.path.dirname(__file__) def test_cpp11(tmpdir): # This test checks that the C++11 standard is supported project_dir = str(tmpdir) - cpp_project.template_context['spam_cpp_add'] = '#include ' + cpp_project.template_context['spam_cpp_top_level_add'] = '#include ' cpp_project.generate(project_dir) # VC++ for Python 2.7 does not support modern standards @@ -102,7 +86,7 @@ def test_cpp14(tmpdir): # This test checks that the C++14 standard is supported project_dir = str(tmpdir) - cpp_project.template_context['spam_cpp_add'] = "int a = 100'000;" + cpp_project.template_context['spam_cpp_top_level_add'] = "int a = 100'000;" cpp_project.generate(project_dir) # VC++ for Python 2.7 does not support modern standards @@ -123,7 +107,7 @@ def test_cpp17(tmpdir): # This test checks that the C++17 standard is supported project_dir = str(tmpdir) - cpp_project.template_context['spam_cpp_add'] = textwrap.dedent(''' + cpp_project.template_context['spam_cpp_top_level_add'] = textwrap.dedent(''' #include auto a = std::pair(5.0, false); ''') diff --git a/test/test_10_before_test.py b/test/test_10_before_test.py index 6455ac50..1573fc84 100644 --- a/test/test_10_before_test.py +++ b/test/test_10_before_test.py @@ -1,5 +1,5 @@ import os -import utils +from . import utils from test.template_projects.c import CTemplateProject before_test_project = CTemplateProject() diff --git a/test/test_12_subdir_package.py b/test/test_12_subdir_package.py index bd520110..45a283aa 100644 --- a/test/test_12_subdir_package.py +++ b/test/test_12_subdir_package.py @@ -1,5 +1,5 @@ import os -import utils +from . import utils from .template_projects.c import spam_c_template from .template_projects import TemplateProject @@ -35,8 +35,7 @@ def test(capfd, tmpdir): actual_wheels = utils.cibuildwheel_run(project_dir, package_dir=package_dir, add_env={ 'CIBW_BEFORE_BUILD': 'python {project}/bin/before_build.py', 'CIBW_TEST_COMMAND': 'python {package}/test/run_tests.py', - # this shouldn't depend on the version of python, so build only - # CPython 3.6 + # this shouldn't depend on the version of python, so build only CPython 3.6 'CIBW_BUILD': 'cp36-*', })