|
1 | 1 | from __future__ import annotations
|
2 | 2 |
|
| 3 | +import json |
3 | 4 | import os
|
4 | 5 | import platform
|
5 | 6 | import random
|
|
13 | 14 |
|
14 | 15 | from cibuildwheel.environment import EnvironmentAssignmentBash
|
15 | 16 | from cibuildwheel.oci_container import OCIContainer, OCIContainerEngineConfig
|
| 17 | +from cibuildwheel.util import detect_ci_provider |
16 | 18 |
|
17 | 19 | # Test utilities
|
18 | 20 |
|
19 | 21 | # for these tests we use manylinux2014 images, because they're available on
|
20 | 22 | # multi architectures and include python3.8
|
| 23 | +DEFAULT_IMAGE_TEMPLATE = "quay.io/pypa/manylinux2014_{machine}:2023-09-04-0828984" |
21 | 24 | pm = platform.machine()
|
22 |
| -if pm == "x86_64": |
23 |
| - DEFAULT_IMAGE = "quay.io/pypa/manylinux2014_x86_64:2020-05-17-2f8ac3b" |
| 25 | +if pm in {"x86_64", "ppc64le", "s390x"}: |
| 26 | + DEFAULT_IMAGE = DEFAULT_IMAGE_TEMPLATE.format(machine=pm) |
24 | 27 | elif pm in {"aarch64", "arm64"}:
|
25 |
| - DEFAULT_IMAGE = "quay.io/pypa/manylinux2014_aarch64:2020-05-17-2f8ac3b" |
26 |
| -elif pm == "ppc64le": |
27 |
| - DEFAULT_IMAGE = "quay.io/pypa/manylinux2014_ppc64le:2020-05-17-2f8ac3b" |
28 |
| -elif pm == "s390x": |
29 |
| - DEFAULT_IMAGE = "quay.io/pypa/manylinux2014_s390x:2020-05-17-2f8ac3b" |
| 28 | + DEFAULT_IMAGE = DEFAULT_IMAGE_TEMPLATE.format(machine="aarch64") |
30 | 29 | else:
|
31 | 30 | DEFAULT_IMAGE = ""
|
32 | 31 |
|
33 | 32 | PODMAN = OCIContainerEngineConfig(name="podman")
|
34 | 33 |
|
35 | 34 |
|
36 |
| -@pytest.fixture(params=["docker", "podman"]) |
| 35 | +@pytest.fixture(params=["docker", "podman"], scope="module") |
37 | 36 | def container_engine(request):
|
38 | 37 | if request.param == "docker" and not request.config.getoption("--run-docker"):
|
39 | 38 | pytest.skip("need --run-docker option to run")
|
40 | 39 | if request.param == "podman" and not request.config.getoption("--run-podman"):
|
41 | 40 | pytest.skip("need --run-podman option to run")
|
42 |
| - return OCIContainerEngineConfig(name=request.param) |
| 41 | + |
| 42 | + def get_images() -> set[str]: |
| 43 | + if detect_ci_provider() is None: |
| 44 | + return set() |
| 45 | + images = subprocess.run( |
| 46 | + [request.param, "image", "ls", "--format", "{{json .ID}}"], |
| 47 | + text=True, |
| 48 | + check=True, |
| 49 | + stdout=subprocess.PIPE, |
| 50 | + ).stdout |
| 51 | + return {json.loads(image.strip()) for image in images.splitlines() if image.strip()} |
| 52 | + |
| 53 | + images_before = get_images() |
| 54 | + try: |
| 55 | + yield OCIContainerEngineConfig(name=request.param) |
| 56 | + finally: |
| 57 | + images_after = get_images() |
| 58 | + for image in images_after - images_before: |
| 59 | + subprocess.run([request.param, "rmi", image], check=False) |
43 | 60 |
|
44 | 61 |
|
45 | 62 | # Tests
|
@@ -232,10 +249,9 @@ def test_environment_executor(container_engine):
|
232 | 249 | assert assignment.evaluated_value({}, container.environment_executor) == "42"
|
233 | 250 |
|
234 | 251 |
|
235 |
| -def test_podman_vfs(tmp_path: Path, monkeypatch, request): |
236 |
| - # Tests podman VFS, for the podman in docker use-case |
237 |
| - if not request.config.getoption("--run-podman"): |
238 |
| - pytest.skip("need --run-podman option to run") |
| 252 | +def test_podman_vfs(tmp_path: Path, monkeypatch, container_engine): |
| 253 | + if container_engine.name != "podman": |
| 254 | + pytest.skip("only runs with podman") |
239 | 255 |
|
240 | 256 | # create the VFS configuration
|
241 | 257 | vfs_path = tmp_path / "podman_vfs"
|
@@ -311,9 +327,9 @@ def test_podman_vfs(tmp_path: Path, monkeypatch, request):
|
311 | 327 | subprocess.run(["podman", "unshare", "rm", "-rf", vfs_path], check=True)
|
312 | 328 |
|
313 | 329 |
|
314 |
| -def test_create_args_volume(tmp_path: Path, request): |
315 |
| - if not request.config.getoption("--run-docker"): |
316 |
| - pytest.skip("need --run-docker option to run") |
| 330 | +def test_create_args_volume(tmp_path: Path, container_engine): |
| 331 | + if container_engine.name != "docker": |
| 332 | + pytest.skip("only runs with docker") |
317 | 333 |
|
318 | 334 | if "CIRCLECI" in os.environ or "GITLAB_CI" in os.environ:
|
319 | 335 | pytest.skip(
|
@@ -378,3 +394,24 @@ def test_parse_engine_config(config, name, create_args):
|
378 | 394 | engine_config = OCIContainerEngineConfig.from_config_string(config)
|
379 | 395 | assert engine_config.name == name
|
380 | 396 | assert engine_config.create_args == create_args
|
| 397 | + |
| 398 | + |
| 399 | +@pytest.mark.skipif(pm != "x86_64", reason="Only runs on x86_64") |
| 400 | +@pytest.mark.parametrize( |
| 401 | + ("image", "shell_args"), |
| 402 | + [ |
| 403 | + (DEFAULT_IMAGE_TEMPLATE.format(machine="i686"), ["/bin/bash"]), |
| 404 | + (DEFAULT_IMAGE_TEMPLATE.format(machine="x86_64"), ["linux32", "/bin/bash"]), |
| 405 | + ], |
| 406 | +) |
| 407 | +def test_enforce_32_bit(container_engine, image, shell_args): |
| 408 | + with OCIContainer(engine=container_engine, image=image, enforce_32_bit=True) as container: |
| 409 | + assert container.call(["uname", "-m"], capture_output=True).strip() == "i686" |
| 410 | + container_args = subprocess.run( |
| 411 | + f"{container.engine.name} inspect -f '{{{{json .Args }}}}' {container.name}", |
| 412 | + shell=True, |
| 413 | + check=True, |
| 414 | + stdout=subprocess.PIPE, |
| 415 | + text=True, |
| 416 | + ).stdout |
| 417 | + assert json.loads(container_args) == shell_args |
0 commit comments