Per discussion in https://github.com/pypa/cibuildwheel/pull/1169, the default installer used for cp38 is an Intel installer. It makes sense to skip testing arm64 wheels in this case. However, if the user choose to manually install the universal2 CPython version, then, tests shall be run on arm64. This allows users that either target 11.0+ on intel, universal2 or only build for arm64 to get the arm64 wheel tested on AppleSilicon.
200 lines
6.8 KiB
Python
200 lines
6.8 KiB
Python
from __future__ import annotations
|
|
|
|
import platform
|
|
import subprocess
|
|
|
|
import pytest
|
|
|
|
from . import test_projects, utils
|
|
|
|
basic_project = test_projects.new_c_project()
|
|
|
|
ALL_MACOS_WHEELS = {
|
|
*utils.expected_wheels("spam", "0.1.0", machine_arch="x86_64"),
|
|
*utils.expected_wheels("spam", "0.1.0", machine_arch="arm64", include_universal2=True),
|
|
}
|
|
|
|
|
|
def get_xcode_version() -> tuple[int, int]:
|
|
output = subprocess.run(
|
|
["xcodebuild", "-version"],
|
|
text=True,
|
|
check=True,
|
|
stdout=subprocess.PIPE,
|
|
).stdout
|
|
lines = output.splitlines()
|
|
_, version_str = lines[0].split()
|
|
|
|
version_parts = version_str.split(".")
|
|
return (int(version_parts[0]), int(version_parts[1]))
|
|
|
|
|
|
def test_cross_compiled_build(tmp_path):
|
|
if utils.platform != "macos":
|
|
pytest.skip("this test is only relevant to macos")
|
|
if get_xcode_version() < (12, 2):
|
|
pytest.skip("this test only works with Xcode 12.2 or greater")
|
|
|
|
project_dir = tmp_path / "project"
|
|
basic_project.generate(project_dir)
|
|
|
|
actual_wheels = utils.cibuildwheel_run(
|
|
project_dir,
|
|
add_env={
|
|
"CIBW_BUILD": "cp39-*",
|
|
"CIBW_ARCHS": "x86_64, universal2, arm64",
|
|
},
|
|
)
|
|
|
|
expected_wheels = [w for w in ALL_MACOS_WHEELS if "cp39" in w]
|
|
assert set(actual_wheels) == set(expected_wheels)
|
|
|
|
|
|
@pytest.mark.parametrize("build_universal2", [False, True])
|
|
def test_cross_compiled_test(tmp_path, capfd, build_universal2):
|
|
if utils.platform != "macos":
|
|
pytest.skip("this test is only relevant to macos")
|
|
if get_xcode_version() < (12, 2):
|
|
pytest.skip("this test only works with Xcode 12.2 or greater")
|
|
|
|
project_dir = tmp_path / "project"
|
|
basic_project.generate(project_dir)
|
|
|
|
actual_wheels = utils.cibuildwheel_run(
|
|
project_dir,
|
|
add_env={
|
|
"CIBW_BUILD": "cp39-*",
|
|
"CIBW_TEST_COMMAND": '''python -c "import platform; print('running tests on ' + platform.machine())"''',
|
|
"CIBW_ARCHS": "universal2" if build_universal2 else "x86_64 arm64",
|
|
},
|
|
)
|
|
|
|
captured = capfd.readouterr()
|
|
|
|
if platform.machine() == "x86_64":
|
|
# ensure that tests were run on only x86_64
|
|
assert "running tests on x86_64" in captured.out
|
|
assert "running tests on arm64" not in captured.out
|
|
if build_universal2:
|
|
assert (
|
|
"While universal2 wheels can be built on x86_64, the arm64 part of them cannot currently be tested"
|
|
in captured.err
|
|
)
|
|
else:
|
|
assert (
|
|
"While arm64 wheels can be built on x86_64, they cannot be tested" in captured.err
|
|
)
|
|
elif platform.machine() == "arm64":
|
|
# ensure that tests were run on both x86_64 and arm64
|
|
assert "running tests on x86_64" in captured.out
|
|
assert "running tests on arm64" in captured.out
|
|
|
|
if build_universal2:
|
|
expected_wheels = [w for w in ALL_MACOS_WHEELS if "cp39" in w and "universal2" in w]
|
|
else:
|
|
expected_wheels = [w for w in ALL_MACOS_WHEELS if "cp39" in w and "universal2" not in w]
|
|
|
|
assert set(actual_wheels) == set(expected_wheels)
|
|
|
|
|
|
@pytest.mark.parametrize("skip_arm64_test", [False, True])
|
|
def test_universal2_testing(tmp_path, capfd, skip_arm64_test):
|
|
if utils.platform != "macos":
|
|
pytest.skip("this test is only relevant to macos")
|
|
if get_xcode_version() < (12, 2):
|
|
pytest.skip("this test only works with Xcode 12.2 or greater")
|
|
if platform.machine() != "x86_64":
|
|
pytest.skip("this test only works on x86_64")
|
|
|
|
project_dir = tmp_path / "project"
|
|
basic_project.generate(project_dir)
|
|
|
|
actual_wheels = utils.cibuildwheel_run(
|
|
project_dir,
|
|
add_env={
|
|
"CIBW_BUILD": "cp39-*",
|
|
"CIBW_TEST_COMMAND": '''python -c "import platform; print('running tests on ' + platform.machine())"''',
|
|
"CIBW_ARCHS": "universal2",
|
|
"CIBW_TEST_SKIP": "*_universal2:arm64" if skip_arm64_test else "",
|
|
},
|
|
)
|
|
|
|
captured = capfd.readouterr()
|
|
|
|
if platform.machine() == "x86_64":
|
|
assert "running tests on x86_64" in captured.out
|
|
assert "running tests on arm64" not in captured.out
|
|
|
|
warning_message = "While universal2 wheels can be built on x86_64, the arm64 part of them cannot currently be tested"
|
|
if skip_arm64_test:
|
|
assert warning_message not in captured.err
|
|
else:
|
|
assert warning_message in captured.err
|
|
|
|
expected_wheels = [w for w in ALL_MACOS_WHEELS if "cp39" in w and "universal2" in w]
|
|
|
|
assert set(actual_wheels) == set(expected_wheels)
|
|
|
|
|
|
def test_cp38_arm64_testing(tmp_path, capfd):
|
|
if utils.platform != "macos":
|
|
pytest.skip("this test is only relevant to macos")
|
|
if get_xcode_version() < (12, 2):
|
|
pytest.skip("this test only works with Xcode 12.2 or greater")
|
|
if platform.machine() != "arm64":
|
|
pytest.skip("this test only works on arm64")
|
|
|
|
project_dir = tmp_path / "project"
|
|
basic_project.generate(project_dir)
|
|
|
|
actual_wheels = utils.cibuildwheel_run(
|
|
project_dir,
|
|
add_env={
|
|
"CIBW_BUILD": "cp38-*",
|
|
"CIBW_TEST_COMMAND": '''python -c "import platform; print('running tests on ' + platform.machine())"''',
|
|
"CIBW_ARCHS": "x86_64,universal2,arm64",
|
|
},
|
|
)
|
|
|
|
captured = capfd.readouterr()
|
|
|
|
assert "running tests on x86_64" in captured.out
|
|
assert "running tests on arm64" not in captured.out
|
|
|
|
warning_message = "While cibuildwheel can build CPython 3.8 universal2/arm64 wheels, we cannot test the arm64 part of them"
|
|
assert warning_message in captured.err
|
|
|
|
expected_wheels = [w for w in ALL_MACOS_WHEELS if "cp38" in w]
|
|
|
|
assert set(actual_wheels) == set(expected_wheels)
|
|
|
|
|
|
def test_cp38_arm64_testing_universal2_installer(tmp_path, capfd, request):
|
|
if not request.config.getoption("--run-cp38-universal2"):
|
|
pytest.skip("needs --run-cp38-universal2 option to run")
|
|
|
|
project_dir = tmp_path / "project"
|
|
basic_project.generate(project_dir)
|
|
|
|
actual_wheels = utils.cibuildwheel_run(
|
|
project_dir,
|
|
add_env={
|
|
"CIBW_BUILD": "cp38-*",
|
|
"CIBW_TEST_COMMAND": '''python -c "import platform; print('running tests on ' + platform.machine())"''',
|
|
"CIBW_ARCHS": "x86_64,universal2,arm64",
|
|
"MACOSX_DEPLOYMENT_TARGET": "11.0",
|
|
},
|
|
)
|
|
|
|
captured = capfd.readouterr()
|
|
|
|
assert "running tests on x86_64" in captured.out
|
|
assert "running tests on arm64" in captured.out
|
|
|
|
warning_message = "While cibuildwheel can build CPython 3.8 universal2/arm64 wheels, we cannot test the arm64 part of them"
|
|
assert warning_message not in captured.err
|
|
|
|
expected_wheels = [w.replace("10_9", "11_0") for w in ALL_MACOS_WHEELS if "cp38" in w]
|
|
|
|
assert set(actual_wheels) == set(expected_wheels)
|