Files
MoviePilot/tests/test_global_event_loop.py
T
2026-08-23 21:40:23 +08:00

80 lines
2.3 KiB
Python

import asyncio
import pytest
from app.runtime.config import GlobalVar
def test_global_loop_requires_lifecycle_owner() -> None:
"""启动前读取主循环不得隐式创建一个无法执行任务的循环。"""
runtime = GlobalVar()
runtime.CURRENT_EVENT_LOOP = None
with pytest.raises(RuntimeError, match="主事件循环尚未启动或已经停止"):
_ = runtime.loop
assert runtime.CURRENT_EVENT_LOOP is None
def test_global_loop_rejects_closed_owner() -> None:
"""已关闭的生命周期 owner 不得继续接收跨线程任务。"""
runtime = GlobalVar()
loop = asyncio.new_event_loop()
runtime.set_loop(loop)
loop.close()
with pytest.raises(RuntimeError, match="主事件循环尚未启动或已经停止"):
_ = runtime.loop
def test_global_loop_rejects_owner_that_is_not_running() -> None:
"""未运行的循环不得成为跨线程任务投递目标。"""
runtime = GlobalVar()
loop = asyncio.new_event_loop()
try:
runtime.set_loop(loop)
with pytest.raises(RuntimeError, match="主事件循环尚未启动或已经停止"):
_ = runtime.loop
finally:
loop.close()
def test_clear_global_loop_preserves_new_owner() -> None:
"""迟到的旧生命周期清理不得清除后来登记的循环。"""
runtime = GlobalVar()
previous = asyncio.new_event_loop()
async def verify() -> None:
current = asyncio.get_running_loop()
previous_owner = runtime.set_loop(previous)
current_owner = runtime.set_loop(current)
runtime.clear_loop(previous_owner)
assert runtime.loop is current
runtime.clear_loop(current_owner)
assert runtime.CURRENT_EVENT_LOOP is None
try:
asyncio.run(verify())
finally:
previous.close()
def test_nested_owner_release_restores_same_event_loop() -> None:
"""同一循环上的内层生命周期退出后,外层 owner 仍保持登记。"""
runtime = GlobalVar()
async def verify() -> None:
loop = asyncio.get_running_loop()
outer_owner = runtime.set_loop(loop)
inner_owner = runtime.set_loop(loop)
runtime.clear_loop(inner_owner)
assert runtime.loop is loop
runtime.clear_loop(outer_owner)
assert runtime.CURRENT_EVENT_LOOP is None
asyncio.run(verify())