chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:17:40 +08:00
commit f1825c8ceb
10096 changed files with 2364182 additions and 0 deletions
@@ -0,0 +1,191 @@
"""Unit tests for KubernetesEventProvider.
Tests verify that raw Kubernetes events are correctly parsed, translated,
and mapped to standardized RayEvent protobuf structures.
"""
from datetime import datetime, timezone
from unittest.mock import MagicMock
import pytest
from ray.core.generated.events_base_event_pb2 import RayEvent
from ray.core.generated.platform_event_pb2 import Source
from ray.dashboard.modules.platform_events.providers.k8s_provider import (
KubernetesEventProvider,
)
def _make_k8s_event(
uid: str = "uid-abc-123",
kind: str = "RayCluster",
name: str = "my-cluster",
message: str = "Pod started",
reason: str = "Started",
event_type: str = "Normal",
namespace: str = "default",
count: int = 1,
last_timestamp: datetime = None,
first_timestamp: datetime = None,
component: str = "kubelet",
) -> MagicMock:
evt = MagicMock()
evt.metadata.uid = uid
evt.metadata.namespace = namespace
evt.metadata.resource_version = "12345"
evt.involved_object.kind = kind
evt.involved_object.name = name
evt.message = message
evt.reason = reason
evt.type = event_type
evt.count = count
evt.last_timestamp = last_timestamp
evt.first_timestamp = first_timestamp
evt.source.component = component
return evt
@pytest.mark.asyncio
async def test_init_k8s_client_missing_cluster_name():
provider = KubernetesEventProvider(lambda e: None)
result = await provider._init_k8s_client()
assert result is False
@pytest.mark.asyncio
async def test_init_k8s_client_missing_cluster_namespace(monkeypatch):
monkeypatch.setenv("RAY_CLUSTER_NAME", "my-cluster")
monkeypatch.delenv("RAY_CLUSTER_NAMESPACE", raising=False)
provider = KubernetesEventProvider(lambda e: None)
result = await provider._init_k8s_client()
assert result is False
def test_proto_event_type_and_source_type():
delivered_event = None
def callback(event: RayEvent):
nonlocal delivered_event
delivered_event = event
provider = KubernetesEventProvider(callback)
provider._cluster_name = "my-cluster"
evt = _make_k8s_event()
provider._process_k8s_event(evt)
assert delivered_event is not None
assert delivered_event.event_type == RayEvent.EventType.PLATFORM_EVENT
assert delivered_event.source_type == RayEvent.SourceType.CLUSTER_LIFECYCLE
def test_platform_source_is_kubernetes():
delivered_event = None
def callback(event: RayEvent):
nonlocal delivered_event
delivered_event = event
provider = KubernetesEventProvider(callback)
provider._cluster_name = "prod-cluster"
evt = _make_k8s_event(component="kubelet", namespace="my-namespace")
provider._process_k8s_event(evt)
assert delivered_event is not None
source = delivered_event.platform_event.source
assert source.platform == Source.Platform.KUBERNETES
assert source.component == "kubelet"
assert source.metadata["namespace"] == "my-namespace"
assert source.metadata["ray_cluster_name"] == "prod-cluster"
def test_platform_event_object_fields():
delivered_event = None
def callback(event: RayEvent):
nonlocal delivered_event
delivered_event = event
provider = KubernetesEventProvider(callback)
evt = _make_k8s_event(
uid="uid-abc-123",
kind="RayJob",
name="my-job",
message="Job failed",
reason="BackoffLimitExceeded",
)
provider._process_k8s_event(evt)
assert delivered_event is not None
assert delivered_event.event_id == b"uid-abc-123"
pe = delivered_event.platform_event
assert pe.object_kind == "RayJob"
assert pe.object_name == "my-job"
assert pe.message == "Job failed"
assert pe.reason == "BackoffLimitExceeded"
@pytest.mark.parametrize(
"event_type,expected_severity",
[
("Warning", RayEvent.Severity.WARNING),
("Normal", RayEvent.Severity.INFO),
(None, RayEvent.Severity.INFO),
],
)
def test_severity_mapping(event_type, expected_severity):
delivered_event = None
def callback(event: RayEvent):
nonlocal delivered_event
delivered_event = event
provider = KubernetesEventProvider(callback)
evt = _make_k8s_event(event_type=event_type)
provider._process_k8s_event(evt)
assert delivered_event is not None
assert delivered_event.severity == expected_severity
def test_timestamp_uses_last_timestamp():
delivered_event = None
def callback(event: RayEvent):
nonlocal delivered_event
delivered_event = event
provider = KubernetesEventProvider(callback)
ts = datetime(2025, 6, 1, 12, 0, 0, tzinfo=timezone.utc)
evt = _make_k8s_event(
last_timestamp=ts, first_timestamp=datetime(2025, 1, 1, tzinfo=timezone.utc)
)
provider._process_k8s_event(evt)
assert delivered_event is not None
assert delivered_event.timestamp.seconds == int(ts.timestamp())
def test_timestamp_falls_back_to_first_timestamp():
delivered_event = None
def callback(event: MagicMock):
nonlocal delivered_event
delivered_event = event
provider = KubernetesEventProvider(callback)
ts = datetime(2025, 3, 15, 8, 30, 0, tzinfo=timezone.utc)
evt = _make_k8s_event(last_timestamp=None, first_timestamp=ts)
provider._process_k8s_event(evt)
assert delivered_event is not None
assert delivered_event.timestamp.seconds == int(ts.timestamp())
if __name__ == "__main__":
import sys
sys.exit(pytest.main(["-v", __file__]))
@@ -0,0 +1,166 @@
"""Unit tests for PlatformEventsHead module.
Tests verify the core caching, deduplication, eviction, and REST API
logic inside the central PlatformEventsHead controller.
"""
import sys
from unittest.mock import MagicMock, patch
import pytest
from ray._private import ray_constants
from ray.core.generated.events_base_event_pb2 import RayEvent
from ray.core.generated.platform_event_pb2 import PlatformEvent, Source
from ray.dashboard.modules.platform_events.platform_event_head import (
MAX_EVENTS_TO_CACHE,
PlatformEventsHead,
)
from ray.dashboard.utils import DashboardHeadModuleConfig
def _make_config() -> DashboardHeadModuleConfig:
return DashboardHeadModuleConfig(
minimal=False,
cluster_id_hex="deadbeef",
session_name="test_session",
gcs_address="127.0.0.1:6379",
log_dir="/tmp",
temp_dir="/tmp",
session_dir="/tmp",
ip="127.0.0.1",
http_host="127.0.0.1",
http_port=8265,
)
def _make_head(**kwargs) -> PlatformEventsHead:
head = PlatformEventsHead(_make_config())
for k, v in kwargs.items():
setattr(head, k, v)
return head
def test_head_event_caching_and_update():
head = _make_head()
# Deliver a brand new RayEvent
ray_event = RayEvent(
event_id=b"test_uid",
message="some message",
)
ray_event.platform_event.message = "some message"
ray_event.platform_event.custom_fields["count"] = "1"
head._process_event_callback(ray_event)
assert len(head._events) == 1
cached_event = next(iter(head._events.values()))
assert cached_event.message == "some message"
assert cached_event.platform_event.custom_fields["count"] == "1"
# Deliver an updated RayEvent with same event_id
updated_ray_event = RayEvent(
event_id=b"test_uid",
message="updated message",
)
updated_ray_event.platform_event.message = "updated message"
updated_ray_event.platform_event.custom_fields["count"] = "5"
head._process_event_callback(updated_ray_event)
assert len(head._events) == 1
cached_event_updated = next(iter(head._events.values()))
assert cached_event_updated.message == "updated message"
assert cached_event_updated.platform_event.custom_fields["count"] == "5"
def test_dedup_suppresses_repeated_uid():
head = _make_head()
ray_event = RayEvent(event_id=b"uid-repeated")
head._process_event_callback(ray_event)
head._process_event_callback(ray_event)
assert len(head._events) == 1
def test_dedup_uid_eviction_keeps_recent():
"""Verify that cache size does not exceed MAX_EVENTS_TO_CACHE and keeps recent items."""
head = _make_head()
total = MAX_EVENTS_TO_CACHE + 10
for i in range(total):
ray_event = RayEvent(event_id=f"uid-{i}".encode())
head._process_event_callback(ray_event)
assert len(head._events) == MAX_EVENTS_TO_CACHE
# Oldest UIDs should be gone
assert "uid-0" not in head._events
# Newest should still be there
assert f"uid-{total - 1}" in head._events
def test_head_event_emission_via_event_recorder(monkeypatch):
head = _make_head()
ray_event = RayEvent(
event_id=b"test_uid_emission",
message="test emission message",
severity=RayEvent.Severity.WARNING,
)
ray_event.platform_event.message = "test emission message"
ray_event.platform_event.source.platform = Source.Platform.KUBERNETES
ray_event.platform_event.source.component = "kubelet"
ray_event.platform_event.source.metadata["namespace"] = "default"
ray_event.platform_event.object_kind = "Pod"
ray_event.platform_event.object_name = "test-pod"
ray_event.platform_event.reason = "OOMKilled"
ray_event.platform_event.custom_fields["count"] = "3"
monkeypatch.setattr(
ray_constants,
"RAY_ENABLE_PYTHON_RAY_EVENT_TYPES",
frozenset({"PLATFORM_EVENT"}),
)
captured = {}
def fake_ray_event_ctor(**kwargs):
captured.update(kwargs)
return MagicMock(name="cython_ray_event")
mock_recorder = MagicMock()
with (
patch(
"ray._common.observability.internal_event.RayEvent",
side_effect=fake_ray_event_ctor,
),
patch.dict(
sys.modules, {"ray._raylet": MagicMock(EventRecorder=mock_recorder)}
),
):
head._process_event_callback(ray_event)
mock_recorder.emit.assert_called_once()
assert captured["entity_id"] == "test_uid_emission"
assert captured["event_id"] == b"test_uid_emission"
assert captured["source_type"] == RayEvent.SourceType.CLUSTER_LIFECYCLE
assert captured["event_type"] == RayEvent.EventType.PLATFORM_EVENT
assert captured["severity"] == RayEvent.Severity.WARNING
assert captured["nested_event_field_number"] == (
RayEvent.PLATFORM_EVENT_FIELD_NUMBER
)
nested = PlatformEvent()
nested.ParseFromString(captured["serialized_data"])
assert nested.source.platform == Source.Platform.KUBERNETES
assert nested.source.component == "kubelet"
assert nested.source.metadata["namespace"] == "default"
assert nested.object_kind == "Pod"
assert nested.object_name == "test-pod"
assert nested.reason == "OOMKilled"
assert nested.message == "test emission message"
assert nested.custom_fields["count"] == "3"
if __name__ == "__main__":
import sys
sys.exit(pytest.main(["-v", __file__]))