chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,412 @@
|
||||
import pytest
|
||||
|
||||
from ray.serve._private.config import DeploymentConfig
|
||||
from ray.serve._private.deployment_state import DeploymentVersion
|
||||
|
||||
|
||||
def test_validation():
|
||||
# Code version must be a string.
|
||||
with pytest.raises(TypeError):
|
||||
DeploymentVersion(123, DeploymentConfig(), {})
|
||||
|
||||
|
||||
def test_other_type_equality():
|
||||
v = DeploymentVersion("1", DeploymentConfig(), {})
|
||||
|
||||
assert v is not None
|
||||
assert v != "1"
|
||||
assert v != None # noqa: E711
|
||||
|
||||
|
||||
def test_code_version():
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(), {})
|
||||
v2 = DeploymentVersion("1", DeploymentConfig(), {})
|
||||
v3 = DeploymentVersion("2", DeploymentConfig(), {})
|
||||
|
||||
assert v1 == v2
|
||||
assert hash(v1) == hash(v2)
|
||||
assert v1 != v3
|
||||
assert hash(v1) != hash(v3)
|
||||
|
||||
|
||||
def test_deployment_config_basic():
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(user_config="1"), {})
|
||||
v2 = DeploymentVersion("1", DeploymentConfig(user_config="1"), {})
|
||||
v3 = DeploymentVersion("1", DeploymentConfig(user_config="2"), {})
|
||||
|
||||
assert v1 == v2
|
||||
assert hash(v1) == hash(v2)
|
||||
assert v1 != v3
|
||||
assert hash(v1) != hash(v3)
|
||||
|
||||
|
||||
def test_user_config_hashable():
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(user_config=("1", "2")), {})
|
||||
v2 = DeploymentVersion("1", DeploymentConfig(user_config=("1", "2")), {})
|
||||
v3 = DeploymentVersion("1", DeploymentConfig(user_config=("1", "3")), {})
|
||||
|
||||
assert v1 == v2
|
||||
assert hash(v1) == hash(v2)
|
||||
assert v1 != v3
|
||||
assert hash(v1) != hash(v3)
|
||||
|
||||
|
||||
def test_user_config_list():
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(user_config=["1", "2"]), {})
|
||||
v2 = DeploymentVersion("1", DeploymentConfig(user_config=["1", "2"]), {})
|
||||
v3 = DeploymentVersion("1", DeploymentConfig(user_config=["1", "3"]), {})
|
||||
|
||||
assert v1 == v2
|
||||
assert hash(v1) == hash(v2)
|
||||
assert v1 != v3
|
||||
assert hash(v1) != hash(v3)
|
||||
|
||||
|
||||
def test_user_config_dict_keys():
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(user_config={"1": "1"}), {})
|
||||
v2 = DeploymentVersion("1", DeploymentConfig(user_config={"1": "1"}), {})
|
||||
v3 = DeploymentVersion("1", DeploymentConfig(user_config={"2": "1"}), {})
|
||||
|
||||
assert v1 == v2
|
||||
assert hash(v1) == hash(v2)
|
||||
assert v1 != v3
|
||||
assert hash(v1) != hash(v3)
|
||||
|
||||
|
||||
def test_user_config_dict_vals():
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(user_config={"1": "1"}), {})
|
||||
v2 = DeploymentVersion("1", DeploymentConfig(user_config={"1": "1"}), {})
|
||||
v3 = DeploymentVersion("1", DeploymentConfig(user_config={"1": "2"}), {})
|
||||
|
||||
assert v1 == v2
|
||||
assert hash(v1) == hash(v2)
|
||||
assert v1 != v3
|
||||
assert hash(v1) != hash(v3)
|
||||
|
||||
|
||||
def test_user_config_nested():
|
||||
v1 = DeploymentVersion(
|
||||
"1", DeploymentConfig(user_config=[{"1": "2"}, {"1": "2"}]), {}
|
||||
)
|
||||
v2 = DeploymentVersion(
|
||||
"1", DeploymentConfig(user_config=[{"1": "2"}, {"1": "2"}]), {}
|
||||
)
|
||||
v3 = DeploymentVersion(
|
||||
"1", DeploymentConfig(user_config=[{"1": "2"}, {"1": "3"}]), {}
|
||||
)
|
||||
|
||||
assert v1 == v2
|
||||
assert hash(v1) == hash(v2)
|
||||
assert v1 != v3
|
||||
assert hash(v1) != hash(v3)
|
||||
|
||||
|
||||
def test_user_config_nested_in_hashable():
|
||||
v1 = DeploymentVersion(
|
||||
"1", DeploymentConfig(user_config=([{"1": "2"}, {"1": "2"}])), {}
|
||||
)
|
||||
v2 = DeploymentVersion(
|
||||
"1", DeploymentConfig(user_config=([{"1": "2"}, {"1": "2"}])), {}
|
||||
)
|
||||
v3 = DeploymentVersion(
|
||||
"1", DeploymentConfig(user_config=([{"1": "2"}, {"1": "3"}])), {}
|
||||
)
|
||||
|
||||
assert v1 == v2
|
||||
assert hash(v1) == hash(v2)
|
||||
assert v1 != v3
|
||||
assert hash(v1) != hash(v3)
|
||||
|
||||
|
||||
def test_num_replicas():
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(num_replicas=1), {})
|
||||
v2 = DeploymentVersion("1", DeploymentConfig(num_replicas=2), {})
|
||||
|
||||
assert v1 == v2
|
||||
assert hash(v1) == hash(v2)
|
||||
|
||||
|
||||
def test_autoscaling_config():
|
||||
v1 = DeploymentVersion(
|
||||
"1",
|
||||
DeploymentConfig(
|
||||
autoscaling_config={"max_replicas": 2, "metrics_interval_s": 10}
|
||||
),
|
||||
{},
|
||||
)
|
||||
v2 = DeploymentVersion(
|
||||
"1",
|
||||
DeploymentConfig(
|
||||
autoscaling_config={"max_replicas": 5, "metrics_interval_s": 10}
|
||||
),
|
||||
{},
|
||||
)
|
||||
v3 = DeploymentVersion(
|
||||
"1",
|
||||
DeploymentConfig(
|
||||
autoscaling_config={"max_replicas": 2, "metrics_interval_s": 3}
|
||||
),
|
||||
{},
|
||||
)
|
||||
|
||||
assert v1 == v2
|
||||
assert hash(v1) == hash(v2)
|
||||
assert v1 != v3
|
||||
assert hash(v1) != hash(v3)
|
||||
|
||||
|
||||
def test_max_ongoing_requests():
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(max_ongoing_requests=5), {})
|
||||
v2 = DeploymentVersion("1", DeploymentConfig(max_ongoing_requests=5), {})
|
||||
v3 = DeploymentVersion("1", DeploymentConfig(max_ongoing_requests=10), {})
|
||||
|
||||
assert v1 == v2
|
||||
assert hash(v1) == hash(v2)
|
||||
assert not v1.requires_actor_reconfigure(v2)
|
||||
assert v1 != v3
|
||||
assert hash(v1) != hash(v3)
|
||||
assert v1.requires_actor_reconfigure(v3)
|
||||
|
||||
|
||||
def test_health_check_period_s():
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(health_check_period_s=5), {})
|
||||
v2 = DeploymentVersion("1", DeploymentConfig(health_check_period_s=5), {})
|
||||
v3 = DeploymentVersion("1", DeploymentConfig(health_check_period_s=10), {})
|
||||
|
||||
assert v1 == v2
|
||||
assert hash(v1) == hash(v2)
|
||||
assert v1 != v3
|
||||
assert hash(v1) != hash(v3)
|
||||
|
||||
|
||||
def test_health_check_timeout_s():
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(health_check_timeout_s=5), {})
|
||||
v2 = DeploymentVersion("1", DeploymentConfig(health_check_timeout_s=5), {})
|
||||
v3 = DeploymentVersion("1", DeploymentConfig(health_check_timeout_s=10), {})
|
||||
|
||||
assert v1 == v2
|
||||
assert hash(v1) == hash(v2)
|
||||
assert v1 != v3
|
||||
assert hash(v1) != hash(v3)
|
||||
|
||||
|
||||
def test_graceful_shutdown_timeout_s():
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(graceful_shutdown_timeout_s=5), {})
|
||||
v2 = DeploymentVersion("1", DeploymentConfig(graceful_shutdown_timeout_s=5), {})
|
||||
v3 = DeploymentVersion("1", DeploymentConfig(graceful_shutdown_timeout_s=10), {})
|
||||
|
||||
assert v1 == v2
|
||||
assert hash(v1) == hash(v2)
|
||||
assert v1 != v3
|
||||
assert hash(v1) != hash(v3)
|
||||
|
||||
|
||||
def test_graceful_shutdown_wait_loop_s():
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(graceful_shutdown_wait_loop_s=5), {})
|
||||
v2 = DeploymentVersion("1", DeploymentConfig(graceful_shutdown_wait_loop_s=5), {})
|
||||
v3 = DeploymentVersion("1", DeploymentConfig(graceful_shutdown_wait_loop_s=10), {})
|
||||
|
||||
assert v1 == v2
|
||||
assert hash(v1) == hash(v2)
|
||||
assert v1 != v3
|
||||
assert hash(v1) != hash(v3)
|
||||
|
||||
|
||||
def test_ray_actor_options():
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(), {"num_cpus": 0.1})
|
||||
v2 = DeploymentVersion("1", DeploymentConfig(), {"num_cpus": 0.1})
|
||||
v3 = DeploymentVersion("1", DeploymentConfig(), {"num_gpus": 0.1})
|
||||
|
||||
assert v1 == v2
|
||||
assert hash(v1) == hash(v2)
|
||||
assert v1 != v3
|
||||
assert hash(v1) != hash(v3)
|
||||
|
||||
|
||||
def test_max_replicas_per_node():
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(), {"num_cpus": 0.1})
|
||||
v2 = DeploymentVersion(
|
||||
"1",
|
||||
DeploymentConfig(),
|
||||
{"num_cpus": 0.1},
|
||||
max_replicas_per_node=1,
|
||||
)
|
||||
v3 = DeploymentVersion(
|
||||
"1",
|
||||
DeploymentConfig(),
|
||||
{"num_cpus": 0.1},
|
||||
max_replicas_per_node=1,
|
||||
)
|
||||
v4 = DeploymentVersion(
|
||||
"1",
|
||||
DeploymentConfig(),
|
||||
{"num_cpus": 0.1},
|
||||
max_replicas_per_node=2,
|
||||
)
|
||||
|
||||
assert v1 != v2
|
||||
assert hash(v1) != hash(v2)
|
||||
assert v1.requires_actor_restart(v2)
|
||||
|
||||
assert v2 == v3
|
||||
assert hash(v2) == hash(v3)
|
||||
assert not v2.requires_actor_restart(v3)
|
||||
|
||||
assert v3 != v4
|
||||
assert hash(v3) != hash(v4)
|
||||
assert v3.requires_actor_restart(v4)
|
||||
|
||||
|
||||
def test_placement_group_options():
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(), {"num_cpus": 0.1})
|
||||
v2 = DeploymentVersion(
|
||||
"1",
|
||||
DeploymentConfig(),
|
||||
{"num_cpus": 0.1},
|
||||
placement_group_bundles=[{"CPU": 0.1}],
|
||||
)
|
||||
v3 = DeploymentVersion(
|
||||
"1",
|
||||
DeploymentConfig(),
|
||||
{"num_cpus": 0.1},
|
||||
placement_group_bundles=[{"CPU": 0.1}],
|
||||
)
|
||||
v4 = DeploymentVersion(
|
||||
"1",
|
||||
DeploymentConfig(),
|
||||
{"num_cpus": 0.1},
|
||||
placement_group_bundles=[{"GPU": 0.1}],
|
||||
)
|
||||
|
||||
assert v1 != v2
|
||||
assert hash(v1) != hash(v2)
|
||||
assert v1.requires_actor_restart(v2)
|
||||
|
||||
assert v2 == v3
|
||||
assert hash(v2) == hash(v3)
|
||||
assert not v2.requires_actor_restart(v3)
|
||||
|
||||
assert v3 != v4
|
||||
assert hash(v3) != hash(v4)
|
||||
assert v3.requires_actor_restart(v4)
|
||||
|
||||
v5 = DeploymentVersion(
|
||||
"1",
|
||||
DeploymentConfig(),
|
||||
{"num_cpus": 0.1},
|
||||
placement_group_bundles=[{"CPU": 0.1}],
|
||||
placement_group_strategy="PACK",
|
||||
)
|
||||
v6 = DeploymentVersion(
|
||||
"1",
|
||||
DeploymentConfig(),
|
||||
{"num_cpus": 0.1},
|
||||
placement_group_bundles=[{"CPU": 0.1}],
|
||||
placement_group_strategy="PACK",
|
||||
)
|
||||
v7 = DeploymentVersion(
|
||||
"1",
|
||||
DeploymentConfig(),
|
||||
{"num_cpus": 0.1},
|
||||
placement_group_bundles=[{"CPU": 0.1}],
|
||||
placement_group_strategy="SPREAD",
|
||||
)
|
||||
|
||||
assert v5 == v6
|
||||
assert hash(v5) == hash(v6)
|
||||
assert not v5.requires_actor_restart(v6)
|
||||
|
||||
assert v6 != v7
|
||||
assert hash(v6) != hash(v7)
|
||||
assert v6.requires_actor_restart(v7)
|
||||
|
||||
|
||||
def test_requires_actor_restart():
|
||||
# Code version different
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(), {"num_cpus": 0.1})
|
||||
v2 = DeploymentVersion("2", DeploymentConfig(), {"num_cpus": 0.1})
|
||||
assert v1.requires_actor_restart(v2)
|
||||
|
||||
# Runtime env different
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(), {"num_cpus": 0.1})
|
||||
v2 = DeploymentVersion("1", DeploymentConfig(), {"num_cpus": 0.2})
|
||||
assert v1.requires_actor_restart(v2)
|
||||
|
||||
# Placement group bundles different
|
||||
v1 = DeploymentVersion(
|
||||
"1", DeploymentConfig(), {}, placement_group_bundles=[{"CPU": 0.1}]
|
||||
)
|
||||
v2 = DeploymentVersion(
|
||||
"1", DeploymentConfig(), {}, placement_group_bundles=[{"CPU": 0.2}]
|
||||
)
|
||||
assert v1.requires_actor_restart(v2)
|
||||
|
||||
# Placement group strategy different
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(), {}, placement_group_strategy="PACK")
|
||||
v2 = DeploymentVersion(
|
||||
"1", DeploymentConfig(), {}, placement_group_strategy="SPREAD"
|
||||
)
|
||||
assert v1.requires_actor_restart(v2)
|
||||
|
||||
# Both code version and runtime env different
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(), {"num_cpus": 0.1})
|
||||
v2 = DeploymentVersion("2", DeploymentConfig(), {"num_cpus": 0.2})
|
||||
assert v1.requires_actor_restart(v2)
|
||||
|
||||
# Num replicas is different
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(num_replicas=1), {})
|
||||
v2 = DeploymentVersion("1", DeploymentConfig(num_replicas=2), {})
|
||||
assert not v1.requires_actor_restart(v2)
|
||||
|
||||
# Graceful shutdown timeout is different
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(graceful_shutdown_timeout_s=5), {})
|
||||
v2 = DeploymentVersion("1", DeploymentConfig(graceful_shutdown_timeout_s=10), {})
|
||||
assert not v1.requires_actor_restart(v2)
|
||||
|
||||
|
||||
def test_requires_actor_reconfigure():
|
||||
# Replicas need the updated user config to call the user-defined
|
||||
# reconfigure method
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(user_config=1), {})
|
||||
v2 = DeploymentVersion("1", DeploymentConfig(user_config=2), {})
|
||||
assert v1.requires_actor_reconfigure(v2)
|
||||
|
||||
# Graceful shutdown loop requires actor reconfigure, since the
|
||||
# replica needs the updated value to correctly execute graceful
|
||||
# shutdown.
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(graceful_shutdown_wait_loop_s=1), {})
|
||||
v2 = DeploymentVersion("1", DeploymentConfig(graceful_shutdown_wait_loop_s=2), {})
|
||||
assert v1.requires_actor_reconfigure(v2)
|
||||
|
||||
# Graceful shutdown timeout shouldn't require actor reconfigure, as
|
||||
# it's only used by the controller to decide when to force-kill a
|
||||
# replica
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(graceful_shutdown_timeout_s=5), {})
|
||||
v2 = DeploymentVersion("1", DeploymentConfig(graceful_shutdown_timeout_s=10), {})
|
||||
assert not v1.requires_actor_reconfigure(v2)
|
||||
|
||||
# Num replicas shouldn't require actor reconfigure, as it's only
|
||||
# by the controller to decide when to start or stop replicas.
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(num_replicas=1), {})
|
||||
v2 = DeploymentVersion("1", DeploymentConfig(num_replicas=2), {})
|
||||
assert not v1.requires_actor_reconfigure(v2)
|
||||
|
||||
|
||||
def test_requires_long_poll_broadcast():
|
||||
# If max concurrent queries is updated, it needs to be broadcasted
|
||||
# to all routers.
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(max_ongoing_requests=5), {})
|
||||
v2 = DeploymentVersion("1", DeploymentConfig(max_ongoing_requests=10), {})
|
||||
assert v1.requires_long_poll_broadcast(v2)
|
||||
|
||||
# Something random like health check timeout doesn't require updating
|
||||
# any info on routers.
|
||||
v1 = DeploymentVersion("1", DeploymentConfig(health_check_timeout_s=5), {})
|
||||
v2 = DeploymentVersion("1", DeploymentConfig(health_check_timeout_s=10), {})
|
||||
assert not v1.requires_long_poll_broadcast(v2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
|
||||
sys.exit(pytest.main(["-v", "-s", __file__]))
|
||||
Reference in New Issue
Block a user