From e2f0815a81412b9df90c6ac8418792cf3736e297 Mon Sep 17 00:00:00 2001 From: Jeremy Volkman Date: Tue, 18 Apr 2023 11:21:27 -0700 Subject: [PATCH] Add test for SOURCE_DATE_EPOCH --- tests/conftest.py | 43 +------------------------------------------ tests/test_common.py | 18 +++++++++++++++++- tests/util.py | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 43 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 511ac82..8d757d0 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,50 +1,9 @@ -from dataclasses import dataclass -import os -import subprocess -import sys import tempfile from pathlib import Path -from typing import Optional import pytest - -@dataclass -class TestWheel: - tag: str - wheel: Path - lib_dir: Optional[Path] = None - - -def patch_wheel(wheel: Path, lib_dir: Optional[Path], out_dir: Path) -> None: - subprocess.check_call( - [ - sys.executable, - "-m", - "repairwheel", - str(wheel), - "--output-dir", - str(out_dir), - ] - + ( - [ - "--lib-dir", - str(lib_dir), - ] - if lib_dir - else [] - ), - env=os.environ, - ) - - -def get_patched_wheel(testwheel: TestWheel, patched_wheel_area: Path) -> Path: - out_dir = patched_wheel_area / testwheel.tag - out_dir.mkdir(parents=True, exist_ok=True) - patch_wheel(testwheel.wheel, testwheel.lib_dir, out_dir) - files = list(out_dir.glob("*.whl")) - assert len(files) == 1, f"Found {len(files)} wheels in {out_dir}" - return files[0] +from .util import get_patched_wheel, TestWheel @pytest.fixture(scope="session") diff --git a/tests/test_common.py b/tests/test_common.py index 1b1d0c3..a712f2e 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -1,10 +1,14 @@ import platform +import tempfile import zipfile +from datetime import datetime from pathlib import Path import pytest -from .util import check_wheel_installs_and_runs, is_wheel_compatible +from .util import check_wheel_installs_and_runs, get_patched_wheel, is_wheel_compatible, TestWheel + +TEST_SOURCE_DATE_EPOCH = 1234567890 def test_wheel_contains_testdep(patched_wheel: Path) -> None: @@ -22,3 +26,15 @@ def test_wheel_installs_and_runs(patched_wheel: Path) -> None: if not is_wheel_compatible(patched_wheel): pytest.skip(f"Wheel not installable on {platform.platform()}: {patched_wheel.name}") check_wheel_installs_and_runs(patched_wheel) + + +def test_source_date_epoch(orig_py3_none_any_wheel: TestWheel) -> None: + expected_zip_time = datetime.utcfromtimestamp(TEST_SOURCE_DATE_EPOCH).timetuple()[:6] + with tempfile.TemporaryDirectory(prefix="testwheel") as temp_dir: + temp_dir = Path(temp_dir) + patched_wheel = get_patched_wheel( + orig_py3_none_any_wheel, temp_dir, {"SOURCE_DATE_EPOCH": str(TEST_SOURCE_DATE_EPOCH)} + ) + with zipfile.ZipFile(patched_wheel) as zf: + for zi in zf.infolist(): + assert zi.date_time == expected_zip_time diff --git a/tests/util.py b/tests/util.py index 25f0ec4..b9fab5e 100644 --- a/tests/util.py +++ b/tests/util.py @@ -3,12 +3,53 @@ import sys import tempfile import venv +from dataclasses import dataclass from pathlib import Path +from typing import Dict, Optional from packaging.tags import sys_tags from packaging.utils import parse_wheel_filename +@dataclass +class TestWheel: + __test__ = False # Tell pytest to ignore this + tag: str + wheel: Path + lib_dir: Optional[Path] = None + + +def patch_wheel(wheel: Path, lib_dir: Optional[Path], out_dir: Path, env: Optional[Dict[str, str]] = None) -> None: + subprocess.check_call( + [ + sys.executable, + "-m", + "repairwheel", + str(wheel), + "--output-dir", + str(out_dir), + ] + + ( + [ + "--lib-dir", + str(lib_dir), + ] + if lib_dir + else [] + ), + env=dict(os.environ, **(env or {})), + ) + + +def get_patched_wheel(testwheel: TestWheel, patched_wheel_area: Path, env: Optional[Dict[str, str]] = None) -> Path: + out_dir = patched_wheel_area / testwheel.tag + out_dir.mkdir(parents=True, exist_ok=True) + patch_wheel(testwheel.wheel, testwheel.lib_dir, out_dir, env) + files = list(out_dir.glob("*.whl")) + assert len(files) == 1, f"Found {len(files)} wheels in {out_dir}" + return files[0] + + def _call_new_python(context, *py_args, **kwargs) -> bytes: # Copied from stdlib venv module, but this version returns the output. env_exec_cmd = context.env_exe