Import AITURK IDE 1.0.0-beta.1 from Hermes 63279301; preserve MIT license
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
"""Tests for the last_fire_error stamp (missed scheduled fires made visible).
|
||||
|
||||
When the hosted fire path (NAS -> dashboard -> loopback forward to the
|
||||
gateway api_server) cannot reach the gateway, no execution row is ever
|
||||
created — the miss used to be invisible outside gui.log. The dashboard fire
|
||||
webhook now stamps ``last_fire_error`` on the job record via
|
||||
``note_fire_forward_failure`` so `cronjob list`, `hermes cron list`, and the
|
||||
dashboard surface it, and ``mark_job_run`` clears the stamp on the next
|
||||
successful run so it always describes CURRENT auto-fire health.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from cron.jobs import (
|
||||
create_job,
|
||||
get_job,
|
||||
mark_job_run,
|
||||
note_fire_forward_failure,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def tmp_cron_dir(tmp_path, monkeypatch):
|
||||
"""Redirect cron storage to a temp directory."""
|
||||
monkeypatch.setattr("cron.jobs.CRON_DIR", tmp_path / "cron")
|
||||
monkeypatch.setattr("cron.jobs.JOBS_FILE", tmp_path / "cron" / "jobs.json")
|
||||
monkeypatch.setattr("cron.jobs.OUTPUT_DIR", tmp_path / "cron" / "output")
|
||||
return tmp_path
|
||||
|
||||
|
||||
class TestNoteFireForwardFailure:
|
||||
def test_stamps_last_fire_error(self, tmp_cron_dir):
|
||||
job = create_job(prompt="Daily invoice triage", schedule="every 1h")
|
||||
assert note_fire_forward_failure(job["id"], "gateway unreachable") is True
|
||||
|
||||
stamped = get_job(job["id"])
|
||||
err = stamped["last_fire_error"]
|
||||
assert isinstance(err, dict)
|
||||
assert err["detail"] == "gateway unreachable"
|
||||
# Timestamp parses as ISO.
|
||||
from datetime import datetime
|
||||
datetime.fromisoformat(err["at"])
|
||||
|
||||
def test_unknown_job_returns_false(self, tmp_cron_dir):
|
||||
assert note_fire_forward_failure("nope", "gateway unreachable") is False
|
||||
|
||||
def test_repeated_failures_overwrite_latest_wins(self, tmp_cron_dir):
|
||||
job = create_job(prompt="Daily invoice triage", schedule="every 1h")
|
||||
note_fire_forward_failure(job["id"], "first miss")
|
||||
note_fire_forward_failure(job["id"], "second miss")
|
||||
err = get_job(job["id"])["last_fire_error"]
|
||||
assert err["detail"] == "second miss"
|
||||
|
||||
def test_detail_truncated_to_500(self, tmp_cron_dir):
|
||||
job = create_job(prompt="Daily invoice triage", schedule="every 1h")
|
||||
note_fire_forward_failure(job["id"], "x" * 2000)
|
||||
err = get_job(job["id"])["last_fire_error"]
|
||||
assert len(err["detail"]) == 500
|
||||
|
||||
def test_successful_run_clears_stamp(self, tmp_cron_dir):
|
||||
"""The stamp describes CURRENT auto-fire health — a run that made it
|
||||
through the fire path proves the hand-off works again."""
|
||||
job = create_job(prompt="Daily invoice triage", schedule="every 1h")
|
||||
note_fire_forward_failure(job["id"], "gateway unreachable")
|
||||
assert get_job(job["id"])["last_fire_error"] is not None
|
||||
|
||||
assert mark_job_run(job["id"], success=True) is True
|
||||
assert get_job(job["id"]).get("last_fire_error") is None
|
||||
|
||||
def test_failed_run_keeps_stamp(self, tmp_cron_dir):
|
||||
"""An agent-level failure is not proof the fire hand-off healed —
|
||||
only success clears (mirrors preflight_alerted / drift_alerted)."""
|
||||
job = create_job(prompt="Daily invoice triage", schedule="every 1h")
|
||||
note_fire_forward_failure(job["id"], "gateway unreachable")
|
||||
|
||||
assert mark_job_run(job["id"], success=False, error="boom") is True
|
||||
err = get_job(job["id"]).get("last_fire_error")
|
||||
assert isinstance(err, dict)
|
||||
assert err["detail"] == "gateway unreachable"
|
||||
|
||||
|
||||
class TestFormatJobSurfacesFireError:
|
||||
def test_cronjob_list_carries_last_fire_error(self, tmp_cron_dir):
|
||||
from tools.cronjob_tools import _format_job
|
||||
|
||||
job = create_job(prompt="Daily invoice triage", schedule="every 1h")
|
||||
note_fire_forward_failure(job["id"], "gateway unreachable")
|
||||
formatted = _format_job(get_job(job["id"]))
|
||||
assert formatted["last_fire_error"]["detail"] == "gateway unreachable"
|
||||
Reference in New Issue
Block a user