Files
MoviePilot/tests/test_transfer_stale_tasks.py

117 lines
3.8 KiB
Python

"""整理任务失活收敛行为测试。"""
from app.chain import transfer
from app.chain.transfer import JobManager
from app.schemas import FileItem, TransferTask
from app.schemas.types import MediaType
class _FakeMeta:
"""提供整理任务分组需要的最小元数据。"""
def __init__(self):
self.name = "Test Show"
self.title = "Test Show S01E01"
self.year = "2026"
self.type = MediaType.TV
self.begin_season = 1
self.end_season = None
self.total_season = 1
self.begin_episode = 1
self.end_episode = None
self.total_episode = 1
self.episode_list = [1]
self.season_episode = "S01E01"
self.part = None
def to_dict(self):
"""返回 TransferJobTask 所需的元数据字典。"""
return {
"title": self.title,
"name": self.name,
"year": self.year,
"type": self.type.value,
"begin_season": self.begin_season,
"end_season": self.end_season,
"total_season": self.total_season,
"begin_episode": self.begin_episode,
"end_episode": self.end_episode,
"total_episode": self.total_episode,
"season_episode": self.season_episode,
"episode_list": self.episode_list,
"part": self.part,
}
def _make_task(name: str = "Test.Show.S01E01.mkv") -> TransferTask:
"""创建失活检测使用的整理任务。"""
return TransferTask(
fileitem=FileItem(
storage="local",
path=f"/downloads/{name}",
type="file",
name=name,
basename=name.removesuffix(".mkv"),
extension="mkv",
size=1024,
),
meta=_FakeMeta(),
)
def test_external_running_task_expires_without_heartbeat(monkeypatch):
"""外部接管的运行中任务超过心跳期限后应被标记失败并清理。"""
clock = [100.0]
monkeypatch.setattr(transfer, "monotonic", lambda: clock[0])
manager = JobManager()
task = _make_task()
assert manager.add_task(task)
manager.running_task(task)
clock[0] = 221.0
expired = manager.expire_stale_running_tasks(timeout_seconds=120)
assert expired == [(task.fileitem, 121)]
assert manager.list_jobs() == []
def test_main_thread_execution_is_not_expired(monkeypatch):
"""主程序整理线程仍在执行的任务不应被失活检测伪清理。"""
clock = [100.0]
monkeypatch.setattr(transfer, "monotonic", lambda: clock[0])
manager = JobManager()
task = _make_task()
assert manager.add_task(task)
manager.start_execution(task)
manager.running_task(task)
clock[0] = 500.0
assert manager.expire_stale_running_tasks(timeout_seconds=120) == []
assert manager.total() == 1
manager.finish_execution(task)
expired = manager.expire_stale_running_tasks(timeout_seconds=120)
assert expired == [(task.fileitem, 400)]
assert manager.list_jobs() == []
def test_waiting_task_and_refreshed_heartbeat_do_not_expire(monkeypatch):
"""等待中任务不受失活期限影响,重复运行状态更新可刷新外部心跳。"""
clock = [100.0]
monkeypatch.setattr(transfer, "monotonic", lambda: clock[0])
manager = JobManager()
waiting_task = _make_task("Test.Show.S01E01.waiting.mkv")
running_task = _make_task("Test.Show.S01E02.running.mkv")
running_task.meta.begin_episode = 2
running_task.meta.episode_list = [2]
assert manager.add_task(waiting_task)
assert manager.add_task(running_task)
manager.running_task(running_task)
clock[0] = 180.0
manager.running_task(running_task)
clock[0] = 250.0
assert manager.expire_stale_running_tasks(timeout_seconds=120) == []
assert manager.total() == 2