test_wheels.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. import os
  2. import sys
  3. import time
  4. import pytest
  5. from unittest.mock import patch
  6. from freezegun import freeze_time
  7. from ray_release.bazel import bazel_runfile
  8. from ray_release.exception import RayWheelsNotFoundError, RayWheelsTimeoutError
  9. from ray_release.util import url_exists
  10. from ray_release.wheels import (
  11. get_ray_version,
  12. DEFAULT_REPO,
  13. get_ray_wheels_url,
  14. find_ray_wheels_url,
  15. find_and_wait_for_ray_wheels_url,
  16. is_wheels_url_matching_ray_verison,
  17. get_wheels_filename,
  18. maybe_rewrite_wheels_url,
  19. parse_commit_from_wheel_url,
  20. )
  21. @pytest.fixture
  22. def remove_buildkite_env():
  23. for key in os.environ:
  24. if key.startswith("BUILDKITE"):
  25. os.environ.pop(key)
  26. def test_get_ray_version(remove_buildkite_env):
  27. init_file = bazel_runfile("python/ray/__init__.py")
  28. with open(init_file, "rt") as fp:
  29. content = [line.encode() for line in fp.readlines()]
  30. with patch("urllib.request.urlopen", lambda _: content):
  31. version = get_ray_version(DEFAULT_REPO, commit="fake")
  32. assert version
  33. with patch("urllib.request.urlopen", lambda _: []), pytest.raises(
  34. RayWheelsNotFoundError
  35. ):
  36. get_ray_version(DEFAULT_REPO, commit="fake")
  37. def test_get_ray_wheels_url(remove_buildkite_env):
  38. url = get_ray_wheels_url(
  39. repo_url="https://github.com/ray-project/ray.git",
  40. branch="master",
  41. commit="1234",
  42. ray_version="3.0.0.dev0",
  43. )
  44. assert (
  45. url == "https://s3-us-west-2.amazonaws.com/ray-wheels/master/1234/"
  46. "ray-3.0.0.dev0-cp39-cp39-manylinux2014_x86_64.whl"
  47. )
  48. @patch("ray_release.wheels.get_ray_version", lambda *a, **kw: "3.0.0.dev0")
  49. def test_find_ray_wheels_buildkite(remove_buildkite_env):
  50. repo = DEFAULT_REPO
  51. branch = "master"
  52. commit = "1234" * 10
  53. version = "3.0.0.dev0"
  54. os.environ["BUILDKITE_COMMIT"] = commit
  55. url = find_ray_wheels_url()
  56. assert url == get_ray_wheels_url(repo, branch, commit, version)
  57. branch = "branched"
  58. os.environ["BUILDKITE_BRANCH"] = branch
  59. url = find_ray_wheels_url()
  60. assert url == get_ray_wheels_url(repo, branch, commit, version)
  61. @patch("ray_release.wheels.get_ray_version", lambda *a, **kw: "3.0.0.dev0")
  62. def test_find_ray_wheels_commit_only(remove_buildkite_env):
  63. repo = DEFAULT_REPO
  64. branch = "master"
  65. commit = "1234" * 10
  66. version = "3.0.0.dev0"
  67. search_str = commit
  68. url = find_ray_wheels_url(search_str)
  69. assert url == get_ray_wheels_url(repo, branch, commit, version)
  70. def _test_find_ray_wheels_checkout(
  71. repo: str, branch: str, commit: str, version: str, search_str: str
  72. ):
  73. with patch(
  74. "ray_release.wheels.get_latest_commits", lambda *a, **kw: [commit]
  75. ), patch("ray_release.wheels.url_exists", lambda *a, **kw: False), pytest.raises(
  76. RayWheelsNotFoundError
  77. ):
  78. # Fails because URL does not exist
  79. find_ray_wheels_url(search_str)
  80. with patch(
  81. "ray_release.wheels.get_latest_commits", lambda *a, **kw: [commit]
  82. ), patch("ray_release.wheels.url_exists", lambda *a, **kw: True):
  83. # Succeeds
  84. url = find_ray_wheels_url(search_str)
  85. assert url == get_ray_wheels_url(repo, branch, commit, version)
  86. @patch("ray_release.wheels.get_ray_version", lambda *a, **kw: "3.0.0.dev0")
  87. def test_find_ray_wheels_branch(remove_buildkite_env):
  88. repo = DEFAULT_REPO
  89. branch = "master"
  90. commit = "1234" * 10
  91. version = "3.0.0.dev0"
  92. search_str = "master"
  93. _test_find_ray_wheels_checkout(repo, branch, commit, version, search_str)
  94. @patch("ray_release.wheels.get_ray_version", lambda *a, **kw: "3.0.0.dev0")
  95. def test_find_ray_wheels_repo_branch(remove_buildkite_env):
  96. repo = DEFAULT_REPO
  97. branch = "master"
  98. commit = "1234" * 10
  99. version = "3.0.0.dev0"
  100. search_str = "ray-project:master"
  101. _test_find_ray_wheels_checkout(repo, branch, commit, version, search_str)
  102. @patch("ray_release.wheels.get_ray_version", lambda *a, **kw: "3.0.0.dev0")
  103. def test_find_ray_wheels_pr_repo_branch(remove_buildkite_env):
  104. repo = "user"
  105. branch = "dev-branch"
  106. commit = "1234" * 10
  107. version = "3.0.0.dev0"
  108. search_str = "user:dev-branch"
  109. _test_find_ray_wheels_checkout(repo, branch, commit, version, search_str)
  110. search_str = "user:dev-branch"
  111. _test_find_ray_wheels_checkout(
  112. f"https://github.com/{repo}/ray-fork.git", branch, commit, version, search_str
  113. )
  114. @patch("time.sleep", lambda *a, **kw: None)
  115. @patch("ray_release.wheels.get_ray_version", lambda *a, **kw: "3.0.0.dev0")
  116. def test_find_and_wait_wheels(remove_buildkite_env):
  117. repo = DEFAULT_REPO
  118. branch = "master"
  119. commit = "1234" * 10
  120. version = "3.0.0.dev0"
  121. class TrueAfter:
  122. def __init__(self, after: float):
  123. self.available_at = time.monotonic() + after
  124. def __call__(self, *args, **kwargs):
  125. if time.monotonic() > self.available_at:
  126. return True
  127. return False
  128. with freeze_time(auto_tick_seconds=10):
  129. with patch("ray_release.wheels.url_exists", TrueAfter(400)):
  130. with pytest.raises(RayWheelsTimeoutError):
  131. find_and_wait_for_ray_wheels_url(commit, timeout=300.0)
  132. with freeze_time(auto_tick_seconds=10):
  133. with patch("ray_release.wheels.url_exists", TrueAfter(200)):
  134. url = find_and_wait_for_ray_wheels_url(commit, timeout=300.0)
  135. assert url == get_ray_wheels_url(repo, branch, commit, version)
  136. def test_matching_ray_wheels_url():
  137. assert not is_wheels_url_matching_ray_verison(
  138. f"http://some/location/{get_wheels_filename('3.0.0dev0', (3, 8))}", (3, 7)
  139. )
  140. assert not is_wheels_url_matching_ray_verison(
  141. f"http://some/location/{get_wheels_filename('3.0.0dev0', (3, 7))}", (3, 8)
  142. )
  143. assert is_wheels_url_matching_ray_verison(
  144. f"http://some/location/{get_wheels_filename('3.0.0dev0', (3, 7))}", (3, 7)
  145. )
  146. @patch("ray_release.wheels.resolve_url", lambda url: url)
  147. def test_rewrite_wheels_url(remove_buildkite_env):
  148. # Do not rewrite if versions match
  149. assert (
  150. maybe_rewrite_wheels_url(
  151. f"http://some/location/{get_wheels_filename('3.0.0dev0', (3, 7))}",
  152. (3, 7),
  153. )
  154. == f"http://some/location/{get_wheels_filename('3.0.0dev0', (3, 7))}"
  155. )
  156. # Do not rewrite if version can't be parsed
  157. assert (
  158. maybe_rewrite_wheels_url("http://some/location/unknown.whl", (3, 7))
  159. == "http://some/location/unknown.whl"
  160. )
  161. # Rewrite when version can be parsed
  162. assert (
  163. maybe_rewrite_wheels_url(
  164. f"http://some/location/{get_wheels_filename('3.0.0dev0', (3, 8))}",
  165. (3, 7),
  166. )
  167. == f"http://some/location/{get_wheels_filename('3.0.0dev0', (3, 7))}"
  168. )
  169. def test_url_exist():
  170. assert url_exists("https://github.com/")
  171. assert not url_exists("invalid://somewhere")
  172. def test_parse_commit_from_wheel_url():
  173. url = (
  174. "https://s3-us-west-2.amazonaws.com/ray-wheels/master/"
  175. "0e0c15065507f01e8bfe78e49b0d0de063f81164/"
  176. "ray-3.0.0.dev0-cp37-cp37m-manylinux2014_x86_64.whl"
  177. )
  178. expected_commit = "0e0c15065507f01e8bfe78e49b0d0de063f81164"
  179. assert parse_commit_from_wheel_url(url) == expected_commit
  180. if __name__ == "__main__":
  181. sys.exit(pytest.main(["-v", __file__]))