2022-05-23 20:55:04 +05:30
|
|
|
from pathlib import Path
|
|
|
|
import tempfile
|
|
|
|
import time
|
2022-02-08 09:22:28 -08:00
|
|
|
import pytest
|
2022-05-20 14:10:36 -05:00
|
|
|
import sys
|
2022-02-08 09:22:28 -08:00
|
|
|
from typing import Dict, Optional, Tuple
|
|
|
|
from unittest.mock import Mock, patch
|
2022-05-23 20:55:04 +05:30
|
|
|
from ray._private.test_utils import (
|
|
|
|
format_web_url,
|
|
|
|
wait_for_condition,
|
|
|
|
wait_until_server_available,
|
|
|
|
)
|
2022-02-08 09:22:28 -08:00
|
|
|
|
2022-05-20 14:10:36 -05:00
|
|
|
from ray.dashboard.modules.dashboard_sdk import (
|
|
|
|
ClusterInfo,
|
|
|
|
DEFAULT_DASHBOARD_ADDRESS,
|
|
|
|
parse_cluster_info,
|
|
|
|
)
|
2022-05-23 20:55:04 +05:30
|
|
|
from ray.dashboard.modules.job.sdk import JobSubmissionClient
|
|
|
|
from ray.tests.conftest import _ray_start
|
|
|
|
import ray.experimental.internal_kv as kv
|
|
|
|
|
|
|
|
|
|
|
|
def check_internal_kv_gced():
|
|
|
|
return len(kv._internal_kv_list("gcs://")) == 0
|
2022-02-08 09:22:28 -08:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"address_param",
|
|
|
|
[
|
|
|
|
("ray://1.2.3.4:10001", "ray", "1.2.3.4:10001"),
|
|
|
|
("other_module://", "other_module", ""),
|
|
|
|
("other_module://address", "other_module", "address"),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
@pytest.mark.parametrize("create_cluster_if_needed", [True, False])
|
|
|
|
@pytest.mark.parametrize("cookies", [None, {"test_cookie_key": "test_cookie_val"}])
|
|
|
|
@pytest.mark.parametrize("metadata", [None, {"test_metadata_key": "test_metadata_val"}])
|
|
|
|
@pytest.mark.parametrize("headers", [None, {"test_headers_key": "test_headers_val"}])
|
|
|
|
def test_parse_cluster_info(
|
|
|
|
address_param: Tuple[str, str, str],
|
|
|
|
create_cluster_if_needed: bool,
|
|
|
|
cookies: Optional[Dict[str, str]],
|
|
|
|
metadata: Optional[Dict[str, str]],
|
|
|
|
headers: Optional[Dict[str, str]],
|
|
|
|
):
|
|
|
|
"""
|
2022-03-09 21:31:23 -08:00
|
|
|
Test ray.dashboard.modules.dashboard_sdk.parse_cluster_info for different
|
2022-02-08 09:22:28 -08:00
|
|
|
format of addresses.
|
|
|
|
"""
|
2022-03-09 17:04:46 +00:00
|
|
|
mock_get_job_submission_client_cluster = Mock(return_value="Ray ClusterInfo")
|
2022-02-08 09:22:28 -08:00
|
|
|
mock_module = Mock()
|
2022-03-09 17:04:46 +00:00
|
|
|
mock_module.get_job_submission_client_cluster_info = Mock(
|
2022-02-08 09:22:28 -08:00
|
|
|
return_value="Other module ClusterInfo"
|
|
|
|
)
|
|
|
|
mock_import_module = Mock(return_value=mock_module)
|
|
|
|
|
|
|
|
address, module_string, inner_address = address_param
|
|
|
|
|
|
|
|
with patch.multiple(
|
2022-03-09 21:31:23 -08:00
|
|
|
"ray.dashboard.modules.dashboard_sdk",
|
2022-03-09 17:04:46 +00:00
|
|
|
get_job_submission_client_cluster_info=mock_get_job_submission_client_cluster,
|
2022-02-08 09:22:28 -08:00
|
|
|
), patch.multiple("importlib", import_module=mock_import_module):
|
|
|
|
if module_string == "ray":
|
2022-05-20 14:10:36 -05:00
|
|
|
with pytest.raises(ValueError, match="ray://"):
|
2022-02-08 09:22:28 -08:00
|
|
|
parse_cluster_info(
|
|
|
|
address,
|
|
|
|
create_cluster_if_needed=create_cluster_if_needed,
|
|
|
|
cookies=cookies,
|
|
|
|
metadata=metadata,
|
|
|
|
headers=headers,
|
|
|
|
)
|
|
|
|
elif module_string == "other_module":
|
|
|
|
assert (
|
|
|
|
parse_cluster_info(
|
|
|
|
address,
|
|
|
|
create_cluster_if_needed=create_cluster_if_needed,
|
|
|
|
cookies=cookies,
|
|
|
|
metadata=metadata,
|
|
|
|
headers=headers,
|
|
|
|
)
|
|
|
|
== "Other module ClusterInfo"
|
|
|
|
)
|
|
|
|
mock_import_module.assert_called_once_with(module_string)
|
2022-03-09 17:04:46 +00:00
|
|
|
mock_module.get_job_submission_client_cluster_info.assert_called_once_with(
|
2022-02-08 09:22:28 -08:00
|
|
|
inner_address,
|
|
|
|
create_cluster_if_needed=create_cluster_if_needed,
|
|
|
|
cookies=cookies,
|
|
|
|
metadata=metadata,
|
|
|
|
headers=headers,
|
|
|
|
)
|
2022-05-20 14:10:36 -05:00
|
|
|
|
|
|
|
|
|
|
|
def test_parse_cluster_info_default_address():
|
|
|
|
assert (
|
|
|
|
parse_cluster_info(
|
|
|
|
address=None,
|
|
|
|
)
|
|
|
|
== ClusterInfo(address=DEFAULT_DASHBOARD_ADDRESS)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2022-05-23 20:55:04 +05:30
|
|
|
@pytest.mark.parametrize("expiration_s", [0, 10])
|
|
|
|
def test_temporary_uri_reference(monkeypatch, expiration_s):
|
|
|
|
"""Test that temporary GCS URI references are deleted after expiration_s."""
|
|
|
|
monkeypatch.setenv(
|
|
|
|
"RAY_RUNTIME_ENV_TEMPORARY_REFERENCE_EXPIRATION_S", str(expiration_s)
|
|
|
|
)
|
|
|
|
# We can't use a fixture with a shared Ray runtime because we need to set the
|
|
|
|
# expiration_s env var before Ray starts.
|
|
|
|
with _ray_start(include_dashboard=True, num_cpus=1) as ctx:
|
|
|
|
headers = {"Connection": "keep-alive", "Authorization": "TOK:<MY_TOKEN>"}
|
|
|
|
address = ctx.address_info["webui_url"]
|
|
|
|
assert wait_until_server_available(address)
|
|
|
|
client = JobSubmissionClient(format_web_url(address), headers=headers)
|
|
|
|
with tempfile.TemporaryDirectory() as tmp_dir:
|
|
|
|
path = Path(tmp_dir)
|
|
|
|
|
|
|
|
hello_file = path / "hi.txt"
|
|
|
|
with hello_file.open(mode="w") as f:
|
|
|
|
f.write("hi\n")
|
|
|
|
|
|
|
|
start = time.time()
|
|
|
|
|
|
|
|
client.submit_job(
|
|
|
|
entrypoint="echo hi", runtime_env={"working_dir": tmp_dir}
|
|
|
|
)
|
|
|
|
|
|
|
|
# Give time for deletion to occur if expiration_s is 0.
|
|
|
|
time.sleep(2)
|
|
|
|
# Need to connect to Ray to check internal_kv.
|
|
|
|
# ray.init(address="auto")
|
|
|
|
|
|
|
|
print("Starting Internal KV checks at time ", time.time() - start)
|
|
|
|
if expiration_s > 0:
|
|
|
|
assert not check_internal_kv_gced()
|
|
|
|
wait_for_condition(check_internal_kv_gced, timeout=2 * expiration_s)
|
|
|
|
assert expiration_s < time.time() - start < 2 * expiration_s
|
|
|
|
print("Internal KV was GC'ed at time ", time.time() - start)
|
|
|
|
else:
|
|
|
|
wait_for_condition(check_internal_kv_gced)
|
|
|
|
print("Internal KV was GC'ed at time ", time.time() - start)
|
|
|
|
|
|
|
|
|
2022-05-20 14:10:36 -05:00
|
|
|
if __name__ == "__main__":
|
|
|
|
sys.exit(pytest.main(["-v", __file__]))
|