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.
72 lines
2.2 KiB
Python
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
|