chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,267 @@
|
||||
import os
|
||||
import platform
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
from contextlib import contextmanager
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
import ray
|
||||
from ray._common.test_utils import wait_for_condition
|
||||
from ray.util.state import list_cluster_events
|
||||
|
||||
|
||||
def calculate_capacity_threshold(disk_capacity_in_bytes):
|
||||
usage = shutil.disk_usage("/tmp")
|
||||
threshold = min(1, 1.0 - 1.0 * (usage.free - disk_capacity_in_bytes) / usage.total)
|
||||
return threshold
|
||||
|
||||
|
||||
def get_current_usage():
|
||||
usage = shutil.disk_usage("/tmp")
|
||||
print(f"free: {usage.free} ")
|
||||
usage_percentage = 1.0 - 1.0 * usage.free / usage.total
|
||||
print(f"current usage: {usage_percentage}")
|
||||
return usage_percentage
|
||||
|
||||
|
||||
@contextmanager
|
||||
def create_tmp_file(n):
|
||||
tmp_dir = tempfile.mkdtemp(dir="/tmp")
|
||||
tmp_path = os.path.join(tmp_dir, "test.txt")
|
||||
with open(tmp_path, "wb") as f:
|
||||
f.write(os.urandom(n))
|
||||
try:
|
||||
yield tmp_path
|
||||
finally:
|
||||
os.remove(tmp_path)
|
||||
|
||||
|
||||
@pytest.mark.skipif(platform.system() == "Windows", reason="Not targeting Windows")
|
||||
def test_put_out_of_disk(shutdown_only):
|
||||
local_fs_capacity_threshold = calculate_capacity_threshold(200 * 1024 * 1024)
|
||||
ray.init(
|
||||
num_cpus=1,
|
||||
object_store_memory=80 * 1024 * 1024,
|
||||
_system_config={
|
||||
"local_fs_capacity_threshold": local_fs_capacity_threshold,
|
||||
"local_fs_monitor_interval_ms": 10,
|
||||
},
|
||||
)
|
||||
assert get_current_usage() < local_fs_capacity_threshold
|
||||
ref = ray.put(np.random.rand(20 * 1024 * 1024))
|
||||
del ref
|
||||
# create a temp file so that the disk size is over the threshold.
|
||||
# ray.put doesn't work is that fallback allocation uses mmaped file
|
||||
# that doesn't neccssary allocate disk spaces.
|
||||
with create_tmp_file(250 * 1024 * 1024):
|
||||
wait_for_condition(lambda: get_current_usage() > local_fs_capacity_threshold)
|
||||
with pytest.raises(ray.exceptions.OutOfDiskError):
|
||||
ray.put(np.random.rand(20 * 1024 * 1024))
|
||||
# delete tmp file to reclaim space back.
|
||||
|
||||
# Ideally get_current_usage() should immediately reflect the latest disk usage
|
||||
# after the tmp file is deleted, but somehow there is some delays on CI machines
|
||||
# so I use wait_for_condition here.
|
||||
wait_for_condition(lambda: get_current_usage() < local_fs_capacity_threshold)
|
||||
ray.put(np.random.rand(20 * 1024 * 1024))
|
||||
|
||||
|
||||
@pytest.mark.skipif(platform.system() == "Windows", reason="Not targeting Windows")
|
||||
def test_task_returns(shutdown_only):
|
||||
local_fs_capacity_threshold = calculate_capacity_threshold(10 * 1024 * 1024)
|
||||
ray.init(
|
||||
num_cpus=1,
|
||||
object_store_memory=80 * 1024 * 1024,
|
||||
_system_config={
|
||||
"local_fs_capacity_threshold": local_fs_capacity_threshold,
|
||||
"local_fs_monitor_interval_ms": 10,
|
||||
},
|
||||
)
|
||||
|
||||
# create a temp file so that the disk size is over the threshold.
|
||||
# ray.put doesn't work is that fallback allocation uses mmaped file
|
||||
# that doesn't neccssary allocate disk spaces.
|
||||
with create_tmp_file(250 * 1024 * 1024):
|
||||
assert get_current_usage() > local_fs_capacity_threshold
|
||||
time.sleep(1)
|
||||
|
||||
@ray.remote
|
||||
def foo():
|
||||
time.sleep(1)
|
||||
return np.random.rand(20 * 1024 * 1024) # 160 MB data
|
||||
|
||||
try:
|
||||
ray.get(foo.remote())
|
||||
except ray.exceptions.RayTaskError as e:
|
||||
assert isinstance(e.cause, ray.exceptions.OutOfDiskError)
|
||||
|
||||
|
||||
@pytest.mark.skipif(platform.system() == "Windows", reason="Not targeting Windows")
|
||||
def test_task_put(shutdown_only):
|
||||
local_fs_capacity_threshold = calculate_capacity_threshold(1 * 1024 * 1024)
|
||||
ray.init(
|
||||
num_cpus=1,
|
||||
object_store_memory=80 * 1024 * 1024,
|
||||
_system_config={
|
||||
"local_fs_capacity_threshold": local_fs_capacity_threshold,
|
||||
"local_fs_monitor_interval_ms": 10,
|
||||
},
|
||||
)
|
||||
|
||||
# create a temp file so that the disk size is over the threshold.
|
||||
# ray.put doesn't work is that fallback allocation uses mmaped file
|
||||
# that doesn't neccssary allocate disk spaces.
|
||||
with create_tmp_file(250 * 1024 * 1024):
|
||||
assert get_current_usage() > local_fs_capacity_threshold
|
||||
time.sleep(1)
|
||||
|
||||
@ray.remote
|
||||
def foo():
|
||||
ref = ray.put(np.random.rand(20 * 1024 * 1024)) # 160 MB data
|
||||
return ref
|
||||
|
||||
try:
|
||||
ray.get(foo.remote())
|
||||
except ray.exceptions.RayTaskError as e:
|
||||
assert isinstance(e.cause, ray.exceptions.OutOfDiskError)
|
||||
|
||||
|
||||
@pytest.mark.skipif(platform.system() == "Windows", reason="Not targeting Windows")
|
||||
def test_task_args(ray_start_cluster):
|
||||
cluster = ray_start_cluster
|
||||
cluster.add_node(
|
||||
num_cpus=1,
|
||||
object_store_memory=80 * 1024 * 1024,
|
||||
_system_config={
|
||||
"local_fs_capacity_threshold": 0,
|
||||
},
|
||||
resources={"out_of_memory": 1},
|
||||
)
|
||||
cluster.add_node(
|
||||
num_cpus=1,
|
||||
object_store_memory=200 * 1024 * 1024,
|
||||
resources={"sufficient_memory": 1},
|
||||
)
|
||||
cluster.wait_for_nodes()
|
||||
ray.init(address=cluster.address)
|
||||
|
||||
@ray.remote
|
||||
def foo():
|
||||
return np.random.rand(20 * 1024 * 1024) # 160 MB data
|
||||
|
||||
@ray.remote
|
||||
def bar(obj):
|
||||
print(obj)
|
||||
|
||||
ref = foo.options(resources={"sufficient_memory": 1}).remote()
|
||||
try:
|
||||
ray.get(bar.options(resources={"out_of_memory": 1}).remote(ref))
|
||||
except ray.exceptions.RayTaskError as e:
|
||||
assert isinstance(e.cause, ray.exceptions.OutOfDiskError)
|
||||
|
||||
|
||||
@pytest.mark.skipif(platform.system() == "Windows", reason="Not targeting Windows")
|
||||
def test_actor(ray_start_cluster):
|
||||
cluster = ray_start_cluster
|
||||
cluster.add_node(
|
||||
num_cpus=1,
|
||||
object_store_memory=80 * 1024 * 1024,
|
||||
_system_config={
|
||||
"local_fs_capacity_threshold": 0,
|
||||
},
|
||||
resources={"out_of_memory": 1},
|
||||
)
|
||||
cluster.add_node(
|
||||
num_cpus=1,
|
||||
object_store_memory=200 * 1024 * 1024,
|
||||
resources={"sufficient_memory": 1},
|
||||
)
|
||||
cluster.wait_for_nodes()
|
||||
ray.init(address=cluster.address)
|
||||
|
||||
@ray.remote
|
||||
def foo():
|
||||
return np.random.rand(20 * 1024 * 1024) # 160 MB data
|
||||
|
||||
@ray.remote
|
||||
class Actor:
|
||||
def __init__(self, obj):
|
||||
self._obj = obj
|
||||
|
||||
def foo(self):
|
||||
print(self._obj)
|
||||
|
||||
def args_ood(self, obj):
|
||||
print(obj)
|
||||
|
||||
def return_ood(self):
|
||||
return np.random.rand(20 * 1024 * 1024)
|
||||
|
||||
ref = foo.options(resources={"sufficient_memory": 1}).remote()
|
||||
with pytest.raises(ray.exceptions.RayActorError):
|
||||
a = Actor.options(resources={"out_of_memory": 0.001}).remote(ref)
|
||||
ray.get(a.foo.remote())
|
||||
|
||||
a = Actor.options(resources={"out_of_memory": 1}).remote(1)
|
||||
ray.get(a.foo.remote())
|
||||
try:
|
||||
ray.get(a.args_ood.remote(ref))
|
||||
except ray.exceptions.RayTaskError as e:
|
||||
assert isinstance(e.cause, ray.exceptions.OutOfDiskError)
|
||||
|
||||
ray.get(a.foo.remote())
|
||||
try:
|
||||
ray.get(a.return_ood.remote())
|
||||
except ray.exceptions.RayTaskError as e:
|
||||
assert isinstance(e.cause, ray.exceptions.OutOfDiskError)
|
||||
|
||||
|
||||
@pytest.mark.skipif(platform.system() == "Windows", reason="Not targeting Windows")
|
||||
def test_ood_events(shutdown_only):
|
||||
local_fs_capacity_threshold = calculate_capacity_threshold(200 * 1024 * 1024)
|
||||
ray.init(
|
||||
num_cpus=1,
|
||||
object_store_memory=80 * 1024 * 1024,
|
||||
_system_config={
|
||||
"local_fs_capacity_threshold": local_fs_capacity_threshold,
|
||||
"local_fs_monitor_interval_ms": 10,
|
||||
},
|
||||
)
|
||||
|
||||
# create a temp file so that the disk size is over the threshold.
|
||||
# ray.put doesn't work is that fallback allocation uses mmaped file
|
||||
# that doesn't neccssary allocate disk spaces.
|
||||
with create_tmp_file(250 * 1024 * 1024):
|
||||
assert get_current_usage() > local_fs_capacity_threshold
|
||||
time.sleep(1)
|
||||
|
||||
@ray.remote
|
||||
def foo():
|
||||
ref = ray.put(np.random.rand(20 * 1024 * 1024)) # 160 MB data
|
||||
return ref
|
||||
|
||||
try:
|
||||
ray.get(foo.remote())
|
||||
except ray.exceptions.RayTaskError as e:
|
||||
assert isinstance(e.cause, ray.exceptions.OutOfDiskError)
|
||||
|
||||
# Give it some time for events to appear.
|
||||
# TODO(core-team): provide some way to wait for events to be flushed.
|
||||
time.sleep(2)
|
||||
|
||||
events = list_cluster_events()
|
||||
print(events)
|
||||
# There could be more than 1 event depending on the test timing.
|
||||
assert len(events) >= 1
|
||||
assert (
|
||||
"Object creation will fail if spilling is required" in events[0]["message"]
|
||||
) # noqa
|
||||
assert events[0]["severity"] == "ERROR"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(pytest.main(["-sv", __file__]))
|
||||
Reference in New Issue
Block a user