tests: fix and enable doctests (#2546)
* fix doctest * Update cibuildwheel/oci_container.py Co-authored-by: Joe Rickerby <joerick@mac.com> * Update cibuildwheel/oci_container.py Co-authored-by: Joe Rickerby <joerick@mac.com> * Update cibuildwheel/oci_container.py Co-authored-by: Joe Rickerby <joerick@mac.com> * Add xdoctest to CI * Add doctests to run tests * Replace test map with new native method * Forgot key for arm64 * Allow doctests to be filtered on circleci --------- Co-authored-by: Joe Rickerby <joerick@mac.com>
This commit is contained in:
co-authored by
Joe Rickerby
parent
8db3538534
commit
5952330610
@@ -32,6 +32,23 @@ if __name__ == "__main__":
|
||||
# move cwd to the project root
|
||||
os.chdir(Path(__file__).resolve().parents[1])
|
||||
|
||||
# doc tests
|
||||
doc_test_args = [sys.executable, "-m", "pytest", "cibuildwheel"]
|
||||
|
||||
print(
|
||||
"\n\n================================== DOC TESTS ==================================",
|
||||
flush=True,
|
||||
)
|
||||
result = subprocess.run(doc_test_args, check=False)
|
||||
if result.returncode not in (0, 5):
|
||||
# Allow case where no doctests are collected (returncode 5) because
|
||||
# circleci sets an explicit "-k" filter that disables doctests. There
|
||||
# isn't a pattern that will only select doctests. This can be removed
|
||||
# and have check=True if the circleci PYTEST_ADDOPTS is removed.
|
||||
raise subprocess.CalledProcessError(
|
||||
result.returncode, result.args, output=result.stdout, stderr=result.stderr
|
||||
)
|
||||
|
||||
# unit tests
|
||||
unit_test_args = [sys.executable, "-m", "pytest", "unit_test"]
|
||||
|
||||
|
||||
@@ -36,6 +36,28 @@ class OCIPlatform(Enum):
|
||||
RISCV64 = "linux/riscv64"
|
||||
S390X = "linux/s390x"
|
||||
|
||||
@classmethod
|
||||
def native(cls) -> "OCIPlatform":
|
||||
"""Return the current OCI platform, or raise ValueError if unknown."""
|
||||
arch = platform.machine().lower()
|
||||
mapping = {
|
||||
"i386": cls.i386,
|
||||
"i686": cls.i386,
|
||||
"x86_64": cls.AMD64,
|
||||
"amd64": cls.AMD64,
|
||||
"armv7l": cls.ARMV7,
|
||||
"aarch64": cls.ARM64,
|
||||
"arm64": cls.ARM64,
|
||||
"ppc64le": cls.PPC64LE,
|
||||
"riscv64": cls.RISCV64,
|
||||
"s390x": cls.S390X,
|
||||
}
|
||||
try:
|
||||
return mapping[arch]
|
||||
except KeyError as ex:
|
||||
msg = f"Unsupported platform architecture: {arch}"
|
||||
raise OSError(msg) from ex
|
||||
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class OCIContainerEngineConfig:
|
||||
@@ -152,11 +174,19 @@ class OCIContainer:
|
||||
back to cibuildwheel.
|
||||
|
||||
Example:
|
||||
>>> # xdoctest: +REQUIRES(LINUX)
|
||||
>>> from cibuildwheel.oci_container import * # NOQA
|
||||
>>> from cibuildwheel.options import _get_pinned_container_images
|
||||
>>> import pytest
|
||||
>>> try:
|
||||
... oci_platform = OCIPlatform.native()
|
||||
... except OSError as ex:
|
||||
... pytest.skip(str(ex))
|
||||
>>> if oci_platform != OCIPlatform.AMD64:
|
||||
... pytest.skip('only runs on amd64')
|
||||
>>> image = _get_pinned_container_images()['x86_64']['manylinux2014']
|
||||
>>> # Test the default container
|
||||
>>> with OCIContainer(image=image) as self:
|
||||
>>> with OCIContainer(image=image, oci_platform=oci_platform) as self:
|
||||
... self.call(["echo", "hello world"])
|
||||
... self.call(["cat", "/proc/1/cgroup"])
|
||||
... print(self.get_environment())
|
||||
|
||||
@@ -391,6 +391,7 @@ class OptionsReader:
|
||||
by the platform.
|
||||
|
||||
Example:
|
||||
>>> # xdoctest: +SKIP
|
||||
>>> options_reader = OptionsReader(config_file, platform='macos')
|
||||
>>> options_reader.get('cool-color')
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ def format_safe(template: str, **kwargs: str | os.PathLike[str]) -> str:
|
||||
>>> format_safe('{a} {b[4]:3f}', a='123')
|
||||
'123 {b[4]:3f}'
|
||||
|
||||
To avoid variable expansion, precede with a single backslash e.g.
|
||||
>>> format_safe('\\{a} {b}', a='123')
|
||||
To avoid variable expansion, precede with a single hash e.g.
|
||||
>>> format_safe('#{a} {b}', a='123')
|
||||
'{a} {b}'
|
||||
"""
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ def tests(session: nox.Session) -> None:
|
||||
session.run("pytest", *session.posargs)
|
||||
else:
|
||||
unit_test_args = ["--run-docker"] if sys.platform.startswith("linux") else []
|
||||
session.run("pytest", "cibuildwheel") # run doctests
|
||||
session.run("pytest", "unit_test", *unit_test_args)
|
||||
session.run("pytest", "test", "-x", "--durations", "0", "--timeout=2400", "test")
|
||||
|
||||
|
||||
+2
-1
@@ -93,6 +93,7 @@ test = [
|
||||
"setuptools",
|
||||
"tomli_w",
|
||||
"validate-pyproject",
|
||||
"xdoctest",
|
||||
]
|
||||
dev = [
|
||||
{include-group = "bin"},
|
||||
@@ -103,7 +104,7 @@ dev = [
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
minversion = "6.0"
|
||||
addopts = ["-ra", "--showlocals", "--strict-markers", "--strict-config"]
|
||||
addopts = ["-ra", "--showlocals", "--strict-markers", "--strict-config", "--xdoctest", "--ignore-glob=*venv*"]
|
||||
junit_family = "xunit2"
|
||||
xfail_strict = true
|
||||
filterwarnings = ["error"]
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import json
|
||||
import os
|
||||
import platform
|
||||
import random
|
||||
import shutil
|
||||
import subprocess
|
||||
@@ -29,16 +28,7 @@ from cibuildwheel.oci_container import (
|
||||
# for these tests we use manylinux2014 images, because they're available on
|
||||
# multi architectures and include python3.8
|
||||
DEFAULT_IMAGE = "quay.io/pypa/manylinux2014:2025.03.08-1"
|
||||
pm = platform.machine()
|
||||
DEFAULT_OCI_PLATFORM = {
|
||||
"AMD64": OCIPlatform.AMD64,
|
||||
"x86_64": OCIPlatform.AMD64,
|
||||
"ppc64le": OCIPlatform.PPC64LE,
|
||||
"s390x": OCIPlatform.S390X,
|
||||
"aarch64": OCIPlatform.ARM64,
|
||||
"arm64": OCIPlatform.ARM64,
|
||||
"ARM64": OCIPlatform.ARM64,
|
||||
}[pm]
|
||||
DEFAULT_OCI_PLATFORM = OCIPlatform.native()
|
||||
|
||||
PODMAN = OCIContainerEngineConfig(name="podman")
|
||||
|
||||
@@ -494,7 +484,7 @@ def test_parse_engine_config(config, name, create_args, capsys):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.skipif(pm != "x86_64", reason="Only runs on x86_64")
|
||||
@pytest.mark.skipif(DEFAULT_OCI_PLATFORM != OCIPlatform.AMD64, reason="Only runs on x86_64")
|
||||
def test_enforce_32_bit(container_engine):
|
||||
with OCIContainer(
|
||||
engine=container_engine, image=DEFAULT_IMAGE, oci_platform=OCIPlatform.i386
|
||||
@@ -551,7 +541,7 @@ def test_local_image(
|
||||
) -> None:
|
||||
if (
|
||||
detect_ci_provider() == CIProvider.travis_ci
|
||||
and pm != "x86_64"
|
||||
and DEFAULT_OCI_PLATFORM != OCIPlatform.AMD64
|
||||
and platform != DEFAULT_OCI_PLATFORM
|
||||
):
|
||||
pytest.skip("Skipping test because docker on this platform does not support QEMU")
|
||||
@@ -581,7 +571,7 @@ def test_local_image(
|
||||
def test_multiarch_image(container_engine, platform):
|
||||
if (
|
||||
detect_ci_provider() == CIProvider.travis_ci
|
||||
and pm != "x86_64"
|
||||
and DEFAULT_OCI_PLATFORM != OCIPlatform.AMD64
|
||||
and platform != DEFAULT_OCI_PLATFORM
|
||||
):
|
||||
pytest.skip("Skipping test because docker on this platform does not support QEMU")
|
||||
|
||||
Reference in New Issue
Block a user