From af5c50e72f4e661b8f408f34593ec9dd89d44e94 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Mon, 7 Sep 2026 08:33:49 +0900 Subject: [PATCH 1/2] test(fixtures): stop stamping a clock into the uv archive fixture ``_trusted_uv_archive`` is documented as building "a deterministic uv tar archive", but ``tarfile.open(mode="w:gz")`` writes the *current* time into the gzip header, so it was not. Its bytes feed a ``pytest.mark.parametrize`` value directly, so pytest derives three test ids from them, and two of the three changed on every collection: test_verified_uv_binary_rejects_invalid_archives[\x1f\x8b\x08\x00\xbb\xf6\x9dj...] \x1f\x8b\x08\x00\xcc\xf6\x9dj... Bytes 4:8 there are the gzip MTIME field. Collecting the same tree twice produced 4 differing lines: 2 ids "disappeared" and 2 "appeared". That breaks a technique this repository relies on. Diffing collected test ids between two commits is how a conflict resolution is checked for silently dropped assertions -- deleting an assertion makes tests pass, so no gate can see the loss. A peer session applying it across two heads of #1986 read those two unstable ids as "2 tests vanished"; a control run of the same tree twice is what caught it. The rule was sound and the instrument was not. ``TarInfo.mtime`` already defaults to 0, so the gzip header was the only clock left, and writing that layer explicitly with ``mtime=0`` makes the helper match its own docstring. The accompanying test asserts the MTIME header field is zero rather than building the archive twice and comparing. The build-twice version is the obvious check and it is vacuous: gzip MTIME has one-second resolution, so two back-to-back builds agree even with the clock restored. It was written that way first and passed against the unfixed helper -- the mutation control is what exposed it, not review. Co-Authored-By: Claude Opus 5 --- ...st_materialize_base_python_requirements.py | 47 +++++++++++++++---- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/tests/test_materialize_base_python_requirements.py b/tests/test_materialize_base_python_requirements.py index a2da04ae25..869382b62b 100644 --- a/tests/test_materialize_base_python_requirements.py +++ b/tests/test_materialize_base_python_requirements.py @@ -1,5 +1,6 @@ from __future__ import annotations +import gzip import hashlib import io import json @@ -719,16 +720,29 @@ def _trusted_uv_archive( member_name: str = materializer.TRUSTED_UV_ARCHIVE_MEMBER, regular: bool = True, ) -> bytes: - """Build a deterministic uv tar archive for supply-chain boundary tests.""" + """Build a deterministic uv tar archive for supply-chain boundary tests. + + The gzip layer is written explicitly with ``mtime=0`` because + ``tarfile.open(mode="w:gz")`` stamps the *current* time into the gzip + header instead, which made this helper's output -- and so this docstring -- + non-deterministic. Three call sites feed the result straight into a + ``pytest.mark.parametrize`` value, so pytest derived the test id from those + bytes and two of the three ids changed on every collection. Any comparison + of collected test ids across two runs then reported phantom disappearances: + a peer session diffing id sets across two commits saw "2 tests vanished" + that had not moved at all. ``TarInfo.mtime`` already defaults to 0, so the + gzip header was the only clock left in the archive. + """ payload = io.BytesIO() - with tarfile.open(fileobj=payload, mode="w:gz") as bundle: - member = tarfile.TarInfo(member_name) - if regular: - member.size = len(binary) - bundle.addfile(member, io.BytesIO(binary)) - else: - member.type = tarfile.DIRTYPE - bundle.addfile(member) + with gzip.GzipFile(fileobj=payload, mode="wb", mtime=0) as compressed: + with tarfile.open(fileobj=compressed, mode="w") as bundle: + member = tarfile.TarInfo(member_name) + if regular: + member.size = len(binary) + bundle.addfile(member, io.BytesIO(binary)) + else: + member.type = tarfile.DIRTYPE + bundle.addfile(member) return payload.getvalue() @@ -811,6 +825,21 @@ def test_download_trusted_uv_archive_rejects_network_and_size_failures( materializer._download_trusted_uv_archive() +def test_trusted_uv_archive_bytes_are_stable_across_builds() -> None: + """The helper's output must not carry a clock, or test ids drift. + + Its bytes reach ``pytest.mark.parametrize`` directly, so pytest names three + tests after them. Without this, two collections of the same tree produce + different ids for two of those three, and every technique that compares + collected ids between two commits -- the one this repository uses to check + that a conflict resolution dropped no assertions -- reports losses that + never happened. Building twice is the whole check: a clock in the archive + fails it, and nothing else here can. + """ + for kwargs in ({}, {"member_name": "wrong/uv"}, {"regular": False}): + assert _trusted_uv_archive(**kwargs) == _trusted_uv_archive(**kwargs) + + def test_verified_uv_binary_accepts_exact_archive( monkeypatch: pytest.MonkeyPatch, ) -> None: From 10192de781f4c986b6455d408aa1aad2fcbbafdb Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Mon, 7 Sep 2026 11:02:55 +0900 Subject: [PATCH 2/2] test(fixtures): assert deterministic gzip header --- .../test_materialize_base_python_requirements.py | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/tests/test_materialize_base_python_requirements.py b/tests/test_materialize_base_python_requirements.py index 869382b62b..6f3894f12c 100644 --- a/tests/test_materialize_base_python_requirements.py +++ b/tests/test_materialize_base_python_requirements.py @@ -825,19 +825,10 @@ def test_download_trusted_uv_archive_rejects_network_and_size_failures( materializer._download_trusted_uv_archive() -def test_trusted_uv_archive_bytes_are_stable_across_builds() -> None: - """The helper's output must not carry a clock, or test ids drift. - - Its bytes reach ``pytest.mark.parametrize`` directly, so pytest names three - tests after them. Without this, two collections of the same tree produce - different ids for two of those three, and every technique that compares - collected ids between two commits -- the one this repository uses to check - that a conflict resolution dropped no assertions -- reports losses that - never happened. Building twice is the whole check: a clock in the archive - fails it, and nothing else here can. - """ +def test_trusted_uv_archive_carries_no_clock() -> None: + """The gzip header must pin MTIME to zero so parametrized test ids do not drift.""" for kwargs in ({}, {"member_name": "wrong/uv"}, {"regular": False}): - assert _trusted_uv_archive(**kwargs) == _trusted_uv_archive(**kwargs) + assert _trusted_uv_archive(**kwargs)[4:8] == b"\x00\x00\x00\x00" def test_verified_uv_binary_accepts_exact_archive(