mirror of https://github.com/Nezreka/SoulSync.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
85 lines
2.8 KiB
85 lines
2.8 KiB
"""Tests for the DB-update / deep-scan monitor decision (stall-based timeout).
|
|
|
|
Regression: a large library can deep-scan for many hours while progressing
|
|
fine. The old monitor used a hard 2-hour TOTAL cap, so it falsely marked a
|
|
healthy, still-running scan 'error' (the scan thread kept going uncancelled).
|
|
The decision now keys off STALL (no progress), so an actively-progressing scan
|
|
never times out no matter how long the whole library takes.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from core.automation.handlers.database_update import (
|
|
scan_wait_action,
|
|
_STALL_WARNING_SECONDS,
|
|
_STALL_TIMEOUT_SECONDS,
|
|
_ABSOLUTE_CAP_SECONDS,
|
|
)
|
|
|
|
|
|
# --- the headline regression -------------------------------------------------
|
|
|
|
|
|
def test_long_but_progressing_scan_never_times_out():
|
|
# 5 hours elapsed total, but progress moved 5s ago -> keep waiting, NOT error.
|
|
assert scan_wait_action(
|
|
status='running', idle_seconds=5, total_seconds=5 * 3600,
|
|
) == 'continue'
|
|
|
|
|
|
def test_very_long_progressing_scan_still_continues():
|
|
# 12h total, just progressed — old code would have failed at 2h.
|
|
assert scan_wait_action(
|
|
status='running', idle_seconds=2, total_seconds=12 * 3600,
|
|
) == 'continue'
|
|
|
|
|
|
# --- finished / not-running --------------------------------------------------
|
|
|
|
|
|
def test_finished_when_not_running():
|
|
for st in ('completed', 'error', 'idle', 'finished'):
|
|
assert scan_wait_action(status=st, idle_seconds=0, total_seconds=0) == 'finished'
|
|
|
|
|
|
def test_finished_takes_precedence_even_if_stalled():
|
|
# Task already ended — don't report a stall.
|
|
assert scan_wait_action(
|
|
status='completed', idle_seconds=_STALL_TIMEOUT_SECONDS + 1, total_seconds=10,
|
|
) == 'finished'
|
|
|
|
|
|
# --- stall warning vs stall timeout ------------------------------------------
|
|
|
|
|
|
def test_warns_after_stall_warning_threshold():
|
|
assert scan_wait_action(
|
|
status='running', idle_seconds=_STALL_WARNING_SECONDS + 1, total_seconds=1000,
|
|
) == 'warn'
|
|
|
|
|
|
def test_stall_timeout_after_no_progress():
|
|
assert scan_wait_action(
|
|
status='running', idle_seconds=_STALL_TIMEOUT_SECONDS + 1, total_seconds=2000,
|
|
) == 'stall_timeout'
|
|
|
|
|
|
def test_just_below_warning_keeps_going():
|
|
assert scan_wait_action(
|
|
status='running', idle_seconds=_STALL_WARNING_SECONDS - 1, total_seconds=1000,
|
|
) == 'continue'
|
|
|
|
|
|
# --- absolute backstop -------------------------------------------------------
|
|
|
|
|
|
def test_absolute_cap_is_last_resort():
|
|
# Even if somehow progressing, a 24h+ wait trips the runaway-loop backstop.
|
|
assert scan_wait_action(
|
|
status='running', idle_seconds=1, total_seconds=_ABSOLUTE_CAP_SECONDS + 1,
|
|
) == 'abs_timeout'
|
|
|
|
|
|
def test_thresholds_are_ordered_sensibly():
|
|
assert _STALL_WARNING_SECONDS < _STALL_TIMEOUT_SECONDS < _ABSOLUTE_CAP_SECONDS
|