test_release_version.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. """Tests for repository-owned Python release versions."""
  2. from __future__ import annotations
  3. import json
  4. import runpy
  5. import stat
  6. from pathlib import Path
  7. from types import SimpleNamespace
  8. import pytest
  9. ROOT = Path(__file__).resolve().parents[3]
  10. SCRIPT = ROOT / "scripts" / "build-python-release.py"
  11. build_python_release = SimpleNamespace(**runpy.run_path(str(SCRIPT)))
  12. def helper_header(target: str) -> bytes:
  13. header = bytearray(20)
  14. if target.startswith("linux-"):
  15. header[:6] = b"\x7fELF\x02\x01"
  16. machine = 62 if target == "linux-x64" else 183
  17. header[18:20] = machine.to_bytes(2, "little")
  18. else:
  19. header[:4] = b"\xcf\xfa\xed\xfe"
  20. header[4:8] = (0x0100000C).to_bytes(4, "little")
  21. return bytes(header)
  22. def test_repository_version_matches_root_package_json() -> None:
  23. expected = json.loads((ROOT / "package.json").read_text())["version"]
  24. assert build_python_release.repository_version() == expected
  25. def test_release_tag_is_optional_for_non_release_builds() -> None:
  26. build_python_release.validate_release_tag(None, "1.2.3")
  27. def test_release_tag_must_match_repository_version() -> None:
  28. build_python_release.validate_release_tag("python-v1.2.3", "1.2.3")
  29. with pytest.raises(ValueError, match="expected 'python-v1.2.3'"):
  30. build_python_release.validate_release_tag("python-v1.2.4", "1.2.3")
  31. def test_repository_version_rejects_non_stable_versions(tmp_path: Path) -> None:
  32. (tmp_path / "package.json").write_text('{"version":"1.2.3-dev"}\n')
  33. with pytest.raises(ValueError, match="must be stable X.Y.Z"):
  34. build_python_release.repository_version(tmp_path)
  35. def test_stage_runtime_copies_executable_and_spawn_helper(tmp_path: Path) -> None:
  36. executable = tmp_path / "dsh-jsonrpc-agent-pkg-macos-arm64"
  37. executable.write_bytes(b"runtime")
  38. executable.chmod(0o755)
  39. spawn_helper = Path(f"{executable}-spawn-helper")
  40. spawn_helper.write_bytes(helper_header("macos-arm64"))
  41. spawn_helper.chmod(0o751)
  42. destination = tmp_path / "staging"
  43. build_python_release.stage_runtime(
  44. destination,
  45. "1.2.3",
  46. executable,
  47. executable.name,
  48. )
  49. runtime_dir = destination / "src" / "deepseek_harness_runtime" / "runtime"
  50. assert (runtime_dir / executable.name).read_bytes() == b"runtime"
  51. copied_helper = runtime_dir / spawn_helper.name
  52. assert copied_helper.read_bytes() == helper_header("macos-arm64")
  53. assert copied_helper.stat().st_mode & stat.S_IXUSR
  54. def test_stage_runtime_rejects_missing_spawn_helper(tmp_path: Path) -> None:
  55. executable = tmp_path / "dsh-jsonrpc-agent-pkg-linux-x64"
  56. executable.write_bytes(b"runtime")
  57. executable.chmod(0o755)
  58. with pytest.raises(FileNotFoundError, match="spawn helper"):
  59. build_python_release.stage_runtime(
  60. tmp_path / "staging",
  61. "1.2.3",
  62. executable,
  63. executable.name,
  64. )
  65. @pytest.mark.parametrize("target", ["linux-x64", "linux-arm64", "macos-arm64"])
  66. def test_spawn_helper_binary_target(target: str) -> None:
  67. assert build_python_release.spawn_helper_binary_target(helper_header(target)) == target
  68. def test_stage_runtime_rejects_mismatched_spawn_helper(tmp_path: Path) -> None:
  69. executable = tmp_path / "dsh-jsonrpc-agent-pkg-linux-x64"
  70. executable.write_bytes(b"runtime")
  71. executable.chmod(0o755)
  72. spawn_helper = Path(f"{executable}-spawn-helper")
  73. spawn_helper.write_bytes(helper_header("linux-arm64"))
  74. spawn_helper.chmod(0o755)
  75. with pytest.raises(ValueError, match="expected linux-x64, found linux-arm64"):
  76. build_python_release.stage_runtime(
  77. tmp_path / "staging",
  78. "1.2.3",
  79. executable,
  80. executable.name,
  81. )
  82. def test_stage_runtime_rejects_non_binary_spawn_helper(tmp_path: Path) -> None:
  83. executable = tmp_path / "dsh-jsonrpc-agent-pkg-macos-arm64"
  84. executable.write_bytes(b"runtime")
  85. executable.chmod(0o755)
  86. spawn_helper = Path(f"{executable}-spawn-helper")
  87. spawn_helper.write_bytes(b"helper")
  88. spawn_helper.chmod(0o755)
  89. with pytest.raises(ValueError, match="unsupported format or architecture"):
  90. build_python_release.stage_runtime(
  91. tmp_path / "staging",
  92. "1.2.3",
  93. executable,
  94. executable.name,
  95. )