ytptube/app/tests/test_backgroundworker.py
2025-09-14 01:30:34 +03:00

91 lines
2.6 KiB
Python

import threading
from typing import Any
from aiohttp import web
from app.library.BackgroundWorker import BackgroundWorker
class TestBackgroundWorker:
def setup_method(self) -> None:
BackgroundWorker._reset_singleton()
def teardown_method(self) -> None:
# Attempt to stop any running worker thread
try:
worker = BackgroundWorker()
if worker.thread and worker.thread.is_alive():
worker.running = False
worker.queue.put((BackgroundWorker, (), {}))
worker.thread.join(timeout=2)
except Exception:
pass
BackgroundWorker._reset_singleton()
def test_attach_starts_and_shutdown_stops(self) -> None:
app = web.Application()
worker = BackgroundWorker()
worker.attach(app)
assert worker.thread is not None
assert worker.thread.is_alive() is True
# Shutdown should stop the worker thread
# on_shutdown is async; call via event loop runner
# Using a small helper to run the coroutine
import asyncio
try:
asyncio.set_event_loop(asyncio.new_event_loop())
except RuntimeError:
pass
asyncio.get_event_loop().run_until_complete(worker.on_shutdown(app))
# Give a short moment for the background thread to exit
worker.thread.join(timeout=2)
assert worker.thread.is_alive() is False
def test_submit_executes_sync_function(self) -> None:
app = web.Application()
worker = BackgroundWorker()
worker.attach(app)
done = threading.Event()
received: dict[str, Any] = {}
def job(x: int, y: int) -> None:
received["sum"] = x + y
done.set()
worker.submit(job, 2, 3)
assert done.wait(timeout=2.0) is True
assert received["sum"] == 5
# Cleanup
import asyncio
asyncio.get_event_loop().run_until_complete(worker.on_shutdown(app))
def test_submit_executes_async_coroutine(self) -> None:
app = web.Application()
worker = BackgroundWorker()
worker.attach(app)
done = threading.Event()
async def coro_task(flag: threading.Event) -> None:
# Simulate a small async operation
await asyncio.sleep(0)
flag.set()
# Submit coroutine factory
import asyncio
worker.submit(coro_task, done)
assert done.wait(timeout=2.0) is True
# Cleanup
asyncio.get_event_loop().run_until_complete(worker.on_shutdown(app))