# SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project import pytest from pytest_mock import MockerFixture from vllm_omni.distributed.omni_connectors.connectors.shm_connector import SharedMemoryConnector from vllm_omni.distributed.omni_connectors.factory import OmniConnectorFactory from vllm_omni.distributed.omni_connectors.utils.config import ConnectorSpec from vllm_omni.distributed.omni_connectors.utils.serialization import OmniSerializer pytestmark = [pytest.mark.core_model, pytest.mark.cpu] def test_basic_serialization(): """Test basic msgpack serialization.""" data = {"key": "value", "list": [1, 2, 3]} serialized = OmniSerializer.serialize(data) assert isinstance(serialized, bytes) deserialized = OmniSerializer.deserialize(serialized) assert data == deserialized def test_tensor_serialization(): """Test torch.Tensor serialization.""" import torch tensor = torch.tensor([[1.0, 2.0], [3.0, 4.0]]) serialized = OmniSerializer.serialize(tensor) deserialized = OmniSerializer.deserialize(serialized) assert torch.equal(tensor, deserialized) def test_noncontiguous_tensor_serialization(): """Test torch.Tensor serialization for strided views.""" import torch tensor = torch.arange(40, dtype=torch.long).reshape(4, 10).transpose(0, 1) assert not tensor.is_contiguous() assert tensor.stride(-1) != 1 serialized = OmniSerializer.serialize({"codes": tensor}) deserialized = OmniSerializer.deserialize(serialized) assert torch.equal(tensor, deserialized["codes"]) def test_ndarray_serialization(): """Test numpy.ndarray serialization.""" import numpy as np arr = np.array([[1, 2, 3], [4, 5, 6]]) serialized = OmniSerializer.serialize(arr) deserialized = OmniSerializer.deserialize(serialized) assert np.array_equal(arr, deserialized) def test_create_shm_connector(): """Test creating SharedMemoryConnector via Factory.""" spec = ConnectorSpec(name="SharedMemoryConnector") connector = OmniConnectorFactory.create_connector(spec) assert isinstance(connector, SharedMemoryConnector) def test_create_unknown_connector(): """Test error when creating unknown connector.""" spec = ConnectorSpec(name="UnknownConnector") with pytest.raises(ValueError): OmniConnectorFactory.create_connector(spec) @pytest.fixture def shm_connector(): connector = SharedMemoryConnector({}) yield connector connector.close() def test_put_get_small_payload_uses_shm(shm_connector): """Small payloads use key-addressed SHM; inline metadata is retired.""" data = {"small": "data"} success, size, metadata = shm_connector.put("stage_0", "stage_1", "req_1", data) assert success is True assert "shm" in metadata assert "inline_bytes" not in metadata assert "size" in metadata # Retrieve retrieved_data, ret_size = shm_connector.get("stage_0", "stage_1", "req_1", metadata) assert data == retrieved_data assert size == ret_size def test_put_get_shm(mocker: MockerFixture, shm_connector, monkeypatch: pytest.MonkeyPatch): """Test SHM transfer logic for large data (Mocked).""" # Create data larger than 100 bytes data = {"large": "x" * 200} # Mock SHM return values mock_handle = {"name": "req_2", "size": 200} mock_write = mocker.MagicMock(return_value=mock_handle) monkeypatch.setattr("vllm_omni.distributed.omni_connectors.connectors.shm_connector.shm_write_bytes", mock_write) # When reading, return the serialized bytes of the data serialized_data = shm_connector.serialize_obj(data) mock_read = mocker.MagicMock(return_value=serialized_data) monkeypatch.setattr("vllm_omni.distributed.omni_connectors.connectors.shm_connector.shm_read_bytes", mock_read) # Put success, size, metadata = shm_connector.put("stage_0", "stage_1", "req_2", data) assert success is True # Should use SHM because data > threshold assert "shm" in metadata assert metadata["shm"] == mock_handle assert "inline_bytes" not in metadata mock_write.assert_called_once() # Get retrieved_data, ret_size = shm_connector.get("stage_0", "stage_1", "req_2", metadata) assert data == retrieved_data mock_read.assert_called_once_with(mock_handle) def test_get_invalid_metadata(shm_connector): """Test get with invalid metadata.""" result = shm_connector.get("stage_0", "stage_1", "req_3", {}) assert result is None result = shm_connector.get("stage_0", "stage_1", "req_3", {"unknown": "format"}) assert result is None def test_mooncake_connector_defaults_missing_host_to_detected_ip(monkeypatch: pytest.MonkeyPatch): import vllm_omni.distributed.omni_connectors.connectors.mooncake_transfer_engine_connector as mooncake_module class _FakePool: is_cuda = False def pin_memory(self): return self def data_ptr(self): return 1234 class _FakeTransferEngine: def initialize(self, host, mode, protocol, device_name): self.host = host self.mode = mode self.protocol = protocol self.device_name = device_name return 0 def get_rpc_port(self): return 23456 def register_memory(self, base_ptr, pool_size): del base_ptr, pool_size return 0 def unregister_memory(self, base_ptr): del base_ptr return 0 monkeypatch.setattr(mooncake_module, "TransferEngine", _FakeTransferEngine) monkeypatch.setattr(mooncake_module.torch, "empty", lambda *args, **kwargs: _FakePool()) monkeypatch.setattr( mooncake_module.MooncakeTransferEngineConnector, "_get_local_ip", lambda self: "10.20.30.40", ) monkeypatch.setattr( mooncake_module.MooncakeTransferEngineConnector, "_zmq_listener_loop", lambda self: self._listener_ready.set(), ) connector = mooncake_module.MooncakeTransferEngineConnector( { "zmq_port": 50051, "memory_pool_size": 4096, } ) try: assert connector.host == "10.20.30.40" assert connector.engine.host == "10.20.30.40" assert connector.get_connection_info()["host"] == "10.20.30.40" finally: connector.close() def test_mooncake_get_counts_zmq_timeout_separately(mocker: MockerFixture): import vllm_omni.distributed.omni_connectors.connectors.mooncake_transfer_engine_connector as mooncake_module connector = object.__new__(mooncake_module.MooncakeTransferEngineConnector) connector._closed = False connector._metrics = {"errors": 0, "timeouts": 0} connector._resolve_metadata = mocker.Mock( return_value={"source_host": "127.0.0.1", "source_port": 1234, "data_size": 8} ) recv_buffer = mocker.Mock() connector._alloc_recv_buffer = mocker.Mock(return_value=(recv_buffer, 1000)) connector._request_transfer = mocker.Mock(side_effect=mooncake_module.zmq.Again()) assert connector.get("s0", "s1", "req") is None assert connector._metrics == {"errors": 0, "timeouts": 1} recv_buffer.release.assert_called_once() connector._closed = True def test_mooncake_get_counts_cuda_sync_failure_as_error(mocker: MockerFixture): import vllm_omni.distributed.omni_connectors.connectors.mooncake_transfer_engine_connector as mooncake_module connector = object.__new__(mooncake_module.MooncakeTransferEngineConnector) connector._closed = False connector._metrics = {"errors": 0, "timeouts": 0} connector._resolve_metadata = mocker.Mock( return_value={"source_host": "127.0.0.1", "source_port": 1234, "data_size": 8} ) recv_buffer = mocker.Mock() connector._alloc_recv_buffer = mocker.Mock(return_value=(recv_buffer, 1000)) connector._request_transfer = mocker.Mock(return_value=mooncake_module.TRANS_DONE) connector._sync_receive_buffer_if_needed = mocker.Mock(side_effect=RuntimeError("CUDA sync failed")) assert connector.get("s0", "s1", "req") is None assert connector._metrics == {"errors": 1, "timeouts": 0} recv_buffer.release.assert_called_once() connector._closed = True