mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-08-11 00:25:36 +08:00
117 lines
3.8 KiB
Python
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
|