Files

90 lines
2.5 KiB
Python

import asyncio
from typing import Any
from unittest.mock import AsyncMock
import pytest
from fastapi import FastAPI
from app import main
from app.config import Settings
class FakeBroker:
instance: "FakeBroker"
def __init__(self, *_: Any, **__: Any) -> None:
type(self).instance = self
self.started = False
self.stopped = False
async def start(self) -> None:
self.started = True
async def stop(self) -> None:
self.stopped = True
class CooperativePublisher:
instance: "CooperativePublisher"
def __init__(self, *_: Any, **__: Any) -> None:
type(self).instance = self
self.stopped = False
async def run(self, stop_event: asyncio.Event) -> None:
await stop_event.wait()
self.stopped = True
class StuckPublisher:
instance: "StuckPublisher"
def __init__(self, *_: Any, **__: Any) -> None:
type(self).instance = self
self.cancelled = False
async def run(self, _: asyncio.Event) -> None:
try:
await asyncio.Event().wait()
finally:
self.cancelled = True
async def test_lifespan_starts_and_stops_resources(
monkeypatch: pytest.MonkeyPatch,
) -> None:
declare_topology = AsyncMock()
close_database = AsyncMock()
monkeypatch.setattr(main, "RabbitBroker", FakeBroker)
monkeypatch.setattr(main, "OutboxPublisher", CooperativePublisher)
monkeypatch.setattr(main, "declare_topology", declare_topology)
monkeypatch.setattr(main, "close_database", close_database)
async with main.lifespan(FastAPI()):
assert FakeBroker.instance.started is True
assert CooperativePublisher.instance.stopped is True
assert FakeBroker.instance.stopped is True
declare_topology.assert_awaited_once_with(FakeBroker.instance)
close_database.assert_awaited_once_with()
async def test_lifespan_cancels_stuck_publisher(
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr(main, "RabbitBroker", FakeBroker)
monkeypatch.setattr(main, "OutboxPublisher", StuckPublisher)
monkeypatch.setattr(main, "declare_topology", AsyncMock())
monkeypatch.setattr(main, "close_database", AsyncMock())
monkeypatch.setattr(
main,
"settings",
Settings(outbox_publish_timeout=0.001, outbox_poll_interval=0.001),
)
async with main.lifespan(FastAPI()):
pass
assert StuckPublisher.instance.cancelled is True
assert FakeBroker.instance.stopped is True