generated from mononoki/pyproj
[+] mvp1
basic working mvp
This commit is contained in:
92
tests/test_router.py
Normal file
92
tests/test_router.py
Normal file
@@ -0,0 +1,92 @@
|
||||
"""Инварианты графа маршрутов и выбор полезной нагрузки при пересылке."""
|
||||
|
||||
import asyncio
|
||||
from copy import deepcopy
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def router():
|
||||
"""Создаёт настоящий Router независимо от менеджера и сессий."""
|
||||
from router import Router
|
||||
return Router()
|
||||
|
||||
|
||||
class Node:
|
||||
def __init__(self, last_data=None):
|
||||
self.last_data = last_data or {}
|
||||
self.sent = []
|
||||
|
||||
def send(self, packet):
|
||||
self.sent.append(deepcopy(packet))
|
||||
|
||||
|
||||
def test_add_creates_empty_routes_and_preserves_existing_edges(router):
|
||||
"""Проверяет создание множества маршрутов и сохранение связей при повторном add."""
|
||||
router.add(1)
|
||||
assert router.session_routes[1] == set()
|
||||
router.session_routes[1].add(2)
|
||||
router.add(1)
|
||||
assert router.session_routes[1] == {2}
|
||||
|
||||
|
||||
def test_move_rewrites_only_edges_pointing_to_old_uid(router):
|
||||
"""Проверяет перенос исходящих/входящих связей без изменения несвязанных маршрутов."""
|
||||
router.session_routes = {1: {2}, 2: {1, 4}, 3: set(), 4: {2}, 5: set()}
|
||||
router.move(1, 5)
|
||||
assert router.session_routes == {2: {5, 4}, 3: set(), 4: {2}, 5: {2}}
|
||||
|
||||
|
||||
def test_move_handles_self_route(router):
|
||||
"""Проверяет замену UID в маршруте, который указывал на собственную сессию."""
|
||||
router.session_routes = {1: {1, 2}, 2: {1}}
|
||||
router.move(1, 3)
|
||||
assert router.session_routes == {2: {3}, 3: {3, 2}}
|
||||
|
||||
|
||||
def test_move_missing_uid_does_not_change_graph(router):
|
||||
"""Проверяет безопасный перенос отсутствующего UID без добавления новых связей."""
|
||||
router.session_routes = {1: {2}, 2: set()}
|
||||
before = deepcopy(router.session_routes)
|
||||
router.move(99, 100)
|
||||
assert router.session_routes == before
|
||||
|
||||
|
||||
def test_remove_clears_outgoing_and_incoming_edges(router):
|
||||
"""Проверяет удаление узла и всех ссылок на него после окончательной очистки."""
|
||||
router.session_routes = {1: {2}, 2: {1, 3}, 3: {1}, 4: set()}
|
||||
router.remove(1)
|
||||
assert router.session_routes == {2: {3}, 3: set(), 4: set()}
|
||||
|
||||
|
||||
def test_remove_missing_uid_is_safe(router):
|
||||
"""Проверяет повторное удаление уже отсутствующего UID."""
|
||||
router.session_routes = {1: set()}
|
||||
router.remove(99)
|
||||
assert router.session_routes == {1: set()}
|
||||
|
||||
|
||||
def test_process_delivers_source_payload_to_each_target(router):
|
||||
"""Проверяет fan-out, данные отправителя и отсутствие доставки несвязанным узлам."""
|
||||
nodes = {
|
||||
1: Node({"telemetry": {"battery": 87}}),
|
||||
2: Node({"telemetry": {"battery": 1}}),
|
||||
3: Node(),
|
||||
4: Node(),
|
||||
}
|
||||
router.sessions = nodes
|
||||
router.session_routes = {1: {2, 3}, 2: set(), 3: set(), 4: set()}
|
||||
asyncio.run(router.process(1, "telemetry"))
|
||||
expected = [{"command": "telemetry", "payload": {"battery": 87}}]
|
||||
assert nodes[2].sent == expected
|
||||
assert nodes[3].sent == expected
|
||||
assert nodes[1].sent == nodes[4].sent == []
|
||||
|
||||
|
||||
def test_process_with_no_routes_sends_nothing(router):
|
||||
"""Проверяет отсутствие доставки при пустом множестве получателей."""
|
||||
router.sessions = {1: Node({"telemetry": {"battery": 87}}), 2: Node()}
|
||||
router.session_routes = {1: set(), 2: set()}
|
||||
asyncio.run(router.process(1, "telemetry"))
|
||||
assert router.sessions[1].sent == router.sessions[2].sent == []
|
||||
Reference in New Issue
Block a user