You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
iTi-Flask/tests/test_tasks.py

72 lines
2.2 KiB
Python

from __future__ import annotations
import threading
import time
import pytest
from iti.tasks.registry import TaskRegistry
from iti.tasks.runner import TaskRunner, _parse_interval, _parse_simple_cron
def test_task_registry_triggers_success_and_failure_runs():
registry = TaskRegistry()
registry.register(name="success", handler=lambda: {"ok": True})
registry.register(name="failure", handler=lambda: 1 / 0)
success = registry.trigger("success")
failure = registry.trigger("failure")
assert success.status == "success"
assert success.result == {"ok": True}
assert success.finished_at is not None
assert failure.status == "failed"
assert "ZeroDivisionError" in failure.error
def test_task_registry_rejects_duplicate_names():
registry = TaskRegistry()
registry.register(name="sync", handler=lambda: None)
with pytest.raises(ValueError, match="task already registered"):
registry.register(name="sync", handler=lambda: None)
def test_task_registry_skips_when_same_task_is_running():
started = threading.Event()
release = threading.Event()
registry = TaskRegistry()
def blocking_handler():
started.set()
release.wait(timeout=2)
registry.register(name="sync", handler=blocking_handler)
worker = threading.Thread(target=registry.trigger, args=("sync",))
worker.start()
assert started.wait(timeout=1)
skipped = registry.trigger("sync")
release.set()
worker.join(timeout=2)
assert skipped.status == "skipped"
assert skipped.error == "task already running"
def test_task_schedule_parsers_and_due_check():
runner = TaskRunner(TaskRegistry())
now = time.time()
assert _parse_interval("interval:60") == 60
assert _parse_interval("interval:0") == 1
assert _parse_interval("bad") is None
assert _parse_simple_cron("cron:*/5 * * * *") == 300
assert _parse_simple_cron("* * * * *") == 60
assert _parse_simple_cron("0 * * * *") is None
assert runner._due("interval:10", "sync", now) is True
runner._last_run["sync"] = now
assert runner._due("interval:10", "sync", now + 5) is False
assert runner._due("interval:10", "sync", now + 10) is True