test(artifact-archive): make the archive suite platform-correct on Windows (#5365)

Two tests in this suite failed on Windows hosts for POSIX-shaped reasons:

- test_archive_download_contains_only_presented_files wrote its CSV fixture
  with write_text(), so Windows text mode translated the literal "\n" bytes to
  CRLF; the archive then legitimately contained CRLF while the assertion
  compared against the LF spelling.
- test_archive_rejects_a_path_replaced_during_read swaps the source file with
  os.replace() while the archive still holds it open, which Windows refuses
  with WinError 5, so that rename-under-read race is POSIX-only.

Write the fixture as bytes so its content is platform-independent, and skip
only the rename-based race on Windows: the same-size content change during
read (test_archive_rejects_same_size_content_change_with_restored_mtime) still
runs there and exercises the same mid-read revalidation.

Verified on Windows: both tests red on upstream main, green after the change
(one skipped); ruff check/format clean; the file is 28 passed, 7 skipped.
This commit is contained in:
Shxiao 2026-09-12 08:12:37 +09:00 committed by GitHub
parent 3f0b6ecc81
commit e20b36b3c7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -101,7 +101,10 @@ def test_archive_download_contains_only_presented_files(tmp_path, monkeypatch) -
outputs = tmp_path / "outputs"
(outputs / "reports").mkdir(parents=True)
(outputs / "reports" / "summary.txt").write_text("summary", encoding="utf-8")
(outputs / "data.csv").write_text("a,b\n1,2\n", encoding="utf-8")
# Written as bytes on purpose: text mode translates "\n" to "\r\n" on
# Windows, so the archive would legitimately contain CRLF bytes while the
# assertion below compares against this literal LF spelling.
(outputs / "data.csv").write_bytes(b"a,b\n1,2\n")
(outputs / "not-presented.txt").write_text("secret", encoding="utf-8")
paths = [
"/mnt/user-data/outputs/reports/summary.txt",
@ -451,6 +454,12 @@ def test_archive_rejects_internal_output_names(
)
# The swap the test performs is os.replace() while the archive still holds the
# source file open. Windows refuses that rename with WinError 5, so the race is
# only reproducible on POSIX; the same-size content change covered by
# test_archive_rejects_same_size_content_change_with_restored_mtime still runs
# on Windows and exercises the same mid-read revalidation.
@pytest.mark.skipif(os.name == "nt", reason="os.replace() cannot rename over a file the archive still holds open on Windows (WinError 5)")
def test_archive_rejects_a_path_replaced_during_read(tmp_path, monkeypatch) -> None:
outputs = tmp_path / "outputs"
outputs.mkdir()