From 1fdb0668d862ef5aa04f635aa478e2b2e8ff7a27 Mon Sep 17 00:00:00 2001 From: nulano Date: Sun, 1 Jan 2023 03:18:30 +0100 Subject: [PATCH] test cibuildwheel wheels in Docker on Windows --- .github/workflows/wheels-test.ps1 | 22 ++++++++++++++++++ .github/workflows/wheels-test.sh | 22 +----------------- .github/workflows/wheels.yml | 12 ++++++---- Tests/check_wheel.py | 38 +++++++++++++++++++++++++++++++ Tests/helper.py | 15 ++++++++++-- Tests/test_imagegrab.py | 2 ++ pyproject.toml | 2 +- 7 files changed, 85 insertions(+), 28 deletions(-) create mode 100644 .github/workflows/wheels-test.ps1 create mode 100644 Tests/check_wheel.py diff --git a/.github/workflows/wheels-test.ps1 b/.github/workflows/wheels-test.ps1 new file mode 100644 index 000000000..f593c7228 --- /dev/null +++ b/.github/workflows/wheels-test.ps1 @@ -0,0 +1,22 @@ +param ([string]$venv, [string]$pillow="C:\pillow") +$ErrorActionPreference = 'Stop' +$ProgressPreference = 'SilentlyContinue' +Set-PSDebug -Trace 1 +if ("$venv" -like "*\cibw-run-*\pp*-win_amd64\*") { + # unlike CPython, PyPy requires Visual C++ Redistributable to be installed + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + Invoke-WebRequest -Uri 'https://aka.ms/vs/15/release/vc_redist.x64.exe' -OutFile 'vc_redist.x64.exe' + C:\vc_redist.x64.exe /install /quiet /norestart | Out-Null +} +$env:path += ";$pillow\winbuild\build\bin\" +& "$venv\Scripts\activate.ps1" +& reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\python.exe" /v "GlobalFlag" /t REG_SZ /d "0x02000000" /f +cd $pillow +& python -VV +if (!$?) { exit $LASTEXITCODE } +& python selftest.py +if (!$?) { exit $LASTEXITCODE } +& python -m pytest -vx Tests\check_wheel.py +if (!$?) { exit $LASTEXITCODE } +& python -m pytest -vx Tests +if (!$?) { exit $LASTEXITCODE } diff --git a/.github/workflows/wheels-test.sh b/.github/workflows/wheels-test.sh index 34dfeaf14..207ec1567 100755 --- a/.github/workflows/wheels-test.sh +++ b/.github/workflows/wheels-test.sh @@ -1,10 +1,6 @@ #!/bin/bash set -e -EXP_CODECS="jpg jpg_2000 libtiff zlib" -EXP_MODULES="freetype2 littlecms2 pil tkinter webp" -EXP_FEATURES="fribidi harfbuzz libjpeg_turbo raqm transp_webp webp_anim webp_mux xcb" - if [[ "$OSTYPE" == "darwin"* ]]; then brew install fribidi export PKG_CONFIG_PATH="/usr/local/opt/openblas/lib/pkgconfig" @@ -25,21 +21,5 @@ fi # Runs tests python3 selftest.py +python3 -m pytest Tests/check_wheel.py python3 -m pytest - -# Test against expected codecs, modules and features -codecs=$(python3 -c 'from PIL.features import *; print(" ".join(sorted(get_supported_codecs())))') -if [ "$codecs" != "$EXP_CODECS" ]; then - echo "Codecs should be: '$EXP_CODECS'; but are '$codecs'" - exit 1 -fi -modules=$(python3 -c 'from PIL.features import *; print(" ".join(sorted(get_supported_modules())))') -if [ "$modules" != "$EXP_MODULES" ]; then - echo "Modules should be: '$EXP_MODULES'; but are '$modules'" - exit 1 -fi -features=$(python3 -c 'from PIL.features import *; print(" ".join(sorted(get_supported_features())))') -if [ "$features" != "$EXP_FEATURES" ]; then - echo "Features should be: '$EXP_FEATURES'; but are '$features'" - exit 1 -fi diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 1634c7834..cbe7eac12 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -148,12 +148,16 @@ jobs: env: CIBW_ARCHS: ${{ matrix.cibw_arch }} CIBW_BEFORE_ALL: "{package}\\winbuild\\build\\build_dep_all.cmd" + CIBW_CACHE_PATH: "C:\\cibw" CIBW_TEST_SKIP: "*-win_arm64" CIBW_TEST_COMMAND: >- - reg.exe add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\python.exe" /v "GlobalFlag" /t REG_SZ /d "0x02000000" /f && - cd /d {project} && - python.exe selftest.py && - python.exe -m pytest -vx -W always Tests + docker run --rm + -v {project}:C:\pillow + -v C:\cibw:C:\cibw + -v %CD%\..\venv-test:%CD%\..\venv-test + -e CI -e GITHUB_ACTIONS + mcr.microsoft.com/windows/servercore:ltsc2022 + powershell C:\pillow\.github\workflows\wheels-test.ps1 %CD%\..\venv-test shell: cmd - uses: actions/upload-artifact@v3 diff --git a/Tests/check_wheel.py b/Tests/check_wheel.py new file mode 100644 index 000000000..38ec9c5d4 --- /dev/null +++ b/Tests/check_wheel.py @@ -0,0 +1,38 @@ +import importlib.util +import sys + +from PIL import features + + +def test_wheel_modules(): + expected_modules = {"pil", "tkinter", "freetype2", "littlecms2", "webp"} + + # tkinter is not available in cibuildwheel installed CPython on Windows + if not importlib.util.find_spec("tkinter"): + expected_modules.remove("tkinter") + + assert set(features.get_supported_modules()) == expected_modules + + +def test_wheel_codecs(): + expected_codecs = {"jpg", "jpg_2000", "zlib", "libtiff"} + + assert set(features.get_supported_codecs()) == expected_codecs + + +def test_wheel_features(): + expected_features = { + "webp_anim", + "webp_mux", + "transp_webp", + "raqm", + "fribidi", + "harfbuzz", + "libjpeg_turbo", + "xcb", + } + + if sys.platform == "win32": + expected_features.remove("xcb") + + assert set(features.get_supported_features()) == expected_features diff --git a/Tests/helper.py b/Tests/helper.py index aacd95564..b985a571d 100644 --- a/Tests/helper.py +++ b/Tests/helper.py @@ -5,6 +5,7 @@ Helper functions. import logging import os import shutil +import subprocess import sys import sysconfig import tempfile @@ -258,11 +259,21 @@ def hopper(mode=None, cache={}): def djpeg_available(): - return bool(shutil.which("djpeg")) + if shutil.which("djpeg"): + try: + subprocess.check_call(["djpeg", "-version"]) + return True + except subprocess.CalledProcessError: + return False def cjpeg_available(): - return bool(shutil.which("cjpeg")) + if shutil.which("cjpeg"): + try: + subprocess.check_call(["cjpeg", "-version"]) + return True + except subprocess.CalledProcessError: + return False def netpbm_available(): diff --git a/Tests/test_imagegrab.py b/Tests/test_imagegrab.py index f8059eca4..d230b9d81 100644 --- a/Tests/test_imagegrab.py +++ b/Tests/test_imagegrab.py @@ -15,6 +15,8 @@ class TestImageGrab: sys.platform not in ("win32", "darwin"), reason="requires Windows or macOS" ) def test_grab(self): + if os.environ.get("USERNAME") == "ContainerAdministrator": + pytest.skip("can't grab screen when running in Docker") ImageGrab.grab() ImageGrab.grab(include_layered_windows=True) ImageGrab.grab(all_screens=True) diff --git a/pyproject.toml b/pyproject.toml index f55651c44..aff97a3cb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -88,7 +88,7 @@ version = {attr = "PIL.__version__"} [tool.cibuildwheel] before-all = ".github/workflows/wheels-dependencies.sh" -config-settings = "raqm=enable raqm=vendor fribidi=vendor" +config-settings = "raqm=enable raqm=vendor fribidi=vendor imagequant=disable" test-command = "cd {project} && .github/workflows/wheels-test.sh" test-extras = "tests"