9c951e9d3c
补齐全部架构的运行证据、GitHub 发布说明和 PyPI 逐文件下载核验。已通过 161 项测试、代码和文档门禁、九个 wheel 的本地索引下载核验,以及 ARM 三个 ABI 的 40 帧 CPU 检查。
149 lines
4.8 KiB
Python
149 lines
4.8 KiB
Python
"""Release verification must cover each staged architecture and Python ABI."""
|
|
|
|
import json
|
|
import subprocess
|
|
from pathlib import Path
|
|
from types import SimpleNamespace
|
|
|
|
import pytest
|
|
|
|
from release import preflight, runtime
|
|
|
|
|
|
def test_all_wheel_pythons_selects_all_nine_wheels(tmp_path, monkeypatch):
|
|
check = preflight.Preflight(
|
|
preflight.PreflightOptions(version="1.2.3", all_wheel_pythons=True),
|
|
repo_root=tmp_path,
|
|
)
|
|
check.wheels = [
|
|
tmp_path / f"orisys-1.2.3-{abi}-{abi}-{platform}.whl"
|
|
for abi in ("cp310", "cp311", "cp312")
|
|
for platform in ("win_amd64", "manylinux_2_28_x86_64", "manylinux_2_28_aarch64")
|
|
]
|
|
monkeypatch.setattr(preflight.sys, "platform", "win32")
|
|
monkeypatch.setattr(
|
|
preflight.version_mod, "python_for_tag", lambda tag: Path(f"{tag}/python.exe")
|
|
)
|
|
assert {wheel for _, wheel, _ in check._runtime_targets()} == set(check.wheels)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"architecture,platform,image",
|
|
[
|
|
("x86_64", "linux/amd64", "orisys-manylinux"),
|
|
("aarch64", "linux/arm64", "orisys-manylinux-aarch64"),
|
|
],
|
|
)
|
|
def test_manylinux_verifier_uses_matching_container(
|
|
tmp_path, monkeypatch, architecture, platform, image
|
|
):
|
|
wheel = tmp_path / f"orisys-1.2.3-cp311-cp311-manylinux_2_28_{architecture}.whl"
|
|
wheel.touch()
|
|
video = tmp_path / "sample.mp4"
|
|
video.touch()
|
|
record = {
|
|
"wheel": wheel.name,
|
|
"assets": "OK",
|
|
"imports": "OK",
|
|
"frames": 40,
|
|
"flow_shape": [1, 2],
|
|
}
|
|
calls = []
|
|
|
|
def run(argv, **kwargs):
|
|
calls.append(argv)
|
|
return subprocess.CompletedProcess(
|
|
argv, 0, "progress\nORISYS_RUNTIME_RESULT=" + json.dumps(record), ""
|
|
)
|
|
|
|
monkeypatch.setattr(runtime.subprocess, "run", run)
|
|
assert (
|
|
runtime.verify_manylinux_wheel(
|
|
wheel, repo_root=tmp_path, video=video, config_name="box", frames=40
|
|
)
|
|
== record
|
|
)
|
|
argv = calls[0]
|
|
assert argv[argv.index("--platform") + 1] == platform
|
|
assert image in argv
|
|
assert "/opt/python/cp311-cp311/bin/python" in argv
|
|
assert any(
|
|
str(tmp_path.resolve()) in arg and arg.endswith(":/src:ro") for arg in argv
|
|
)
|
|
|
|
|
|
def test_manylinux_verifier_propagates_container_failure(tmp_path, monkeypatch):
|
|
monkeypatch.setattr(
|
|
runtime.subprocess,
|
|
"run",
|
|
lambda argv, **kwargs: subprocess.CompletedProcess(
|
|
argv, 1, "", "ARM import failed"
|
|
),
|
|
)
|
|
with pytest.raises(RuntimeError, match="ARM import failed"):
|
|
runtime.verify_manylinux_wheel(
|
|
tmp_path / "orisys-1.2.3-cp312-cp312-manylinux_2_28_aarch64.whl",
|
|
repo_root=tmp_path,
|
|
video=tmp_path / "sample.mp4",
|
|
config_name="box",
|
|
frames=40,
|
|
)
|
|
|
|
|
|
def test_runtime_step_records_hashes_for_windows_and_arm(tmp_path, monkeypatch):
|
|
video = tmp_path / "sample.mp4"
|
|
video.touch()
|
|
check = preflight.Preflight(
|
|
preflight.PreflightOptions(
|
|
version="1.2.3", all_wheel_pythons=True, video=video
|
|
),
|
|
repo_root=tmp_path,
|
|
)
|
|
check.wheels = [
|
|
tmp_path / f"orisys-1.2.3-cp311-cp311-{target}.whl"
|
|
for target in ("win_amd64", "manylinux_2_28_aarch64")
|
|
]
|
|
for wheel in check.wheels:
|
|
wheel.write_bytes(b"wheel")
|
|
monkeypatch.setattr(preflight.sys, "platform", "win32")
|
|
monkeypatch.setattr(
|
|
preflight.version_mod, "python_for_tag", lambda tag: Path("python.exe")
|
|
)
|
|
seen = []
|
|
|
|
def verify(wheel, **kwargs):
|
|
seen.append(wheel)
|
|
return {"wheel": wheel.name, "assets": "OK", "frames": 40, "flow_shape": [1, 2]}
|
|
|
|
monkeypatch.setattr(preflight, "verify_wheel", verify)
|
|
monkeypatch.setattr(preflight, "verify_manylinux_wheel", verify)
|
|
step = check._wheel_runtime()
|
|
assert step.ok, step.detail
|
|
assert set(seen) == set(check.wheels)
|
|
assert all(
|
|
record["sha256"] == preflight._sha256_file(check.wheels[0])
|
|
for record in step.data["records"]
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"name",
|
|
[
|
|
"orisys-1.2.3-cp311-cp311-manylinux_2_28_aarch64.whl",
|
|
"orisys-1.2.3-cp311-cp311-manylinux_2_28_x86_64.whl",
|
|
],
|
|
)
|
|
def test_native_linux_selection_matches_machine(tmp_path, monkeypatch, name):
|
|
check = preflight.Preflight(
|
|
preflight.PreflightOptions(version="1.2.3"), repo_root=tmp_path
|
|
)
|
|
check.wheels = [tmp_path / name]
|
|
monkeypatch.setattr(preflight.sys, "platform", "linux")
|
|
monkeypatch.setattr(preflight.sys, "version_info", SimpleNamespace(major=3, minor=11))
|
|
monkeypatch.setattr(preflight.platform, "machine", lambda: "aarch64")
|
|
if "aarch64" in name:
|
|
assert check._runtime_targets()[0][1].name == name
|
|
else:
|
|
with pytest.raises(RuntimeError, match="no cp311 aarch64 wheel"):
|
|
check._runtime_targets()
|