chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
import pytest
|
||||
import requests
|
||||
|
||||
import ray
|
||||
from ray._common.test_utils import (
|
||||
run_string_as_driver,
|
||||
wait_for_condition,
|
||||
)
|
||||
from ray._private import ray_constants
|
||||
|
||||
import psutil
|
||||
|
||||
|
||||
def search_agents(cluster):
|
||||
all_processes = cluster.head_node.all_processes
|
||||
raylet_proc_info = all_processes[ray_constants.PROCESS_TYPE_RAYLET][0]
|
||||
raylet_proc = psutil.Process(raylet_proc_info.process.pid)
|
||||
|
||||
def _search_agent(processes):
|
||||
for p in processes:
|
||||
try:
|
||||
for c in p.cmdline():
|
||||
if ray_constants.AGENT_PROCESS_TYPE_DASHBOARD_AGENT[:15] in c:
|
||||
return p
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
agent_proc = _search_agent(raylet_proc.children())
|
||||
return agent_proc
|
||||
|
||||
|
||||
def test_ray_start_default_port_conflict(call_ray_stop_only, shutdown_only):
|
||||
subprocess.check_call(["ray", "start", "--head"])
|
||||
ray.init(address="auto")
|
||||
assert (
|
||||
str(ray_constants.DEFAULT_DASHBOARD_PORT)
|
||||
in ray._private.worker.get_dashboard_url()
|
||||
)
|
||||
|
||||
error_raised = False
|
||||
try:
|
||||
subprocess.check_output(
|
||||
[
|
||||
"ray",
|
||||
"start",
|
||||
"--head",
|
||||
"--port",
|
||||
"9999", # use a different gcs port
|
||||
"--include-dashboard=True",
|
||||
],
|
||||
stderr=subprocess.PIPE,
|
||||
)
|
||||
except subprocess.CalledProcessError as e:
|
||||
assert b"already occupied" in e.stderr
|
||||
error_raised = True
|
||||
|
||||
assert error_raised, "ray start should cause a conflict error"
|
||||
|
||||
|
||||
def test_port_auto_increment(shutdown_only):
|
||||
ray.init()
|
||||
url = ray._private.worker.get_dashboard_url()
|
||||
|
||||
def dashboard_available():
|
||||
try:
|
||||
requests.get("http://" + url).status_code == 200
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
wait_for_condition(dashboard_available)
|
||||
|
||||
run_string_as_driver(
|
||||
f"""
|
||||
import ray
|
||||
from ray._common.test_utils import wait_for_condition
|
||||
import requests
|
||||
ray.init()
|
||||
url = ray._private.worker.get_dashboard_url()
|
||||
assert url != "{url}"
|
||||
def dashboard_available():
|
||||
try:
|
||||
requests.get("http://"+url).status_code == 200
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
wait_for_condition(dashboard_available)
|
||||
ray.shutdown()
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"listen_port",
|
||||
[9999],
|
||||
indirect=True,
|
||||
)
|
||||
def test_port_conflict(listen_port, call_ray_stop_only, shutdown_only):
|
||||
try:
|
||||
subprocess.check_output(
|
||||
[
|
||||
"ray",
|
||||
"start",
|
||||
"--head",
|
||||
"--port",
|
||||
"9989",
|
||||
"--dashboard-port",
|
||||
"9999",
|
||||
"--include-dashboard=True",
|
||||
],
|
||||
stderr=subprocess.PIPE,
|
||||
)
|
||||
except subprocess.CalledProcessError as e:
|
||||
assert b"already occupied" in e.stderr
|
||||
|
||||
with pytest.raises(ValueError, match="already occupied"):
|
||||
ray.init(dashboard_port=9999, include_dashboard=True)
|
||||
|
||||
|
||||
def test_dashboard(shutdown_only):
|
||||
addresses = ray.init(include_dashboard=True, num_cpus=1)
|
||||
dashboard_url = addresses["webui_url"]
|
||||
assert ray._private.worker.get_dashboard_url() == dashboard_url
|
||||
|
||||
assert re.match(r"^(localhost|\d+\.\d+\.\d+\.\d+):\d+$", dashboard_url)
|
||||
|
||||
start_time = time.time()
|
||||
while True:
|
||||
try:
|
||||
node_info_url = f"http://{dashboard_url}/nodes"
|
||||
resp = requests.get(node_info_url, params={"view": "summary"})
|
||||
resp.raise_for_status()
|
||||
summaries = resp.json()
|
||||
assert summaries["result"] is True
|
||||
assert "msg" in summaries
|
||||
break
|
||||
except (requests.exceptions.ConnectionError, AssertionError):
|
||||
if time.time() > start_time + 30:
|
||||
out_log = None
|
||||
with open(
|
||||
"{}/logs/dashboard.log".format(addresses["session_dir"]), "r"
|
||||
) as f:
|
||||
out_log = f.read()
|
||||
raise Exception(
|
||||
"Timed out while waiting for dashboard to start. "
|
||||
f"Dashboard output log: {out_log}\n"
|
||||
)
|
||||
|
||||
|
||||
conflict_port = 34567
|
||||
configured_test_port = 34568
|
||||
|
||||
|
||||
def run_tasks_without_runtime_env():
|
||||
assert ray.is_initialized()
|
||||
|
||||
@ray.remote
|
||||
def f():
|
||||
pass
|
||||
|
||||
for _ in range(10):
|
||||
time.sleep(1)
|
||||
ray.get(f.remote())
|
||||
|
||||
|
||||
def run_tasks_with_runtime_env():
|
||||
assert ray.is_initialized()
|
||||
|
||||
@ray.remote(runtime_env={"pip": ["pip-install-test==0.5"]})
|
||||
def f():
|
||||
import pip_install_test # noqa
|
||||
|
||||
pass
|
||||
|
||||
for _ in range(3):
|
||||
time.sleep(1)
|
||||
ray.get(f.remote())
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
sys.platform == "win32", reason="`runtime_env` with `pip` not supported on Windows."
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"listen_port",
|
||||
[conflict_port],
|
||||
indirect=True,
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"call_ray_start",
|
||||
[
|
||||
f"ray start --head --num-cpus=1 --metrics-export-port={conflict_port}",
|
||||
f"ray start --head --num-cpus=1 --dashboard-agent-listen-port={conflict_port}",
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
def test_dashboard_agent_metrics_or_http_port_conflict(listen_port, call_ray_start):
|
||||
address = call_ray_start
|
||||
ray.init(address=address)
|
||||
# Tasks with runtime env still work when other agent port conflicts,
|
||||
# except grpc port.
|
||||
run_tasks_with_runtime_env()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(pytest.main(["-sv", __file__]))
|
||||
Reference in New Issue
Block a user