mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-08-01 19:06:01 +00:00
All 102 domain cases were green, and four of them would have stayed green through the exact regression they were named after. Assertions that could not fail ------------------------------ `test_a_claimed_task_is_marked_running_before_dispatch` asserted the lease was released *after* dispatch -- the opposite of the ordering its name and docstring describe. The claim is what makes a task uneditable while it is being dispatched, so the only place that ordering is observable is inside the launch; the launcher double now reads the repository from there. `test_active_statuses_are_exactly_queued_and_running` restated the constant it was checking, so editing the constant edits the assertion with it. Replaced by `is_active` over all six statuses, which also covers `RUNNING` and the two terminal statuses that had none. `test_reuse_thread_with_an_empty_thread_falls_back_to_a_fresh_one` compared its result against `task.thread_id`, which is `None` on the default task -- it asserted "not None" against a method whose body is `str(uuid.uuid4())`. Now asserts the fresh-thread semantics it is named for: a real uuid, distinct per call. `test_a_task_deleted_mid_flight_is_not_an_error` had no assert at all. That path does have observable behaviour: the hook writes the run record before it reads the task, so a task deleted mid-flight must still leave a finalized record and a freed active slot. Contracts stated in a docstring and nowhere else ------------------------------------------------ - a cron overlap must not leave `last_error` behind (service.py:455 branches on it; only the `once` half was covered, so dropping the branch was free) - a failed launch replaces the launch bookkeeping instead of carrying it over the way a skip does -- which is what `last_run_id=None` in `_fail` means for a task that had already run successfully - `SchedulePolicy`'s defaults are the permissive ones, so a deployment that configured no policy cannot have a business constraint invented for it - transitions leave `updated_at` to the repository, rather than becoming a second source of truth for the same column ACTIVE_RUN_STATUSES' promised assertion --------------------------------------- Its docstring says the check that it stays in lockstep with the partial unique index's predicate "lives in a separate test module rather than the domain tests". It did not exist, in that module or any other. `test_scheduled_task_ models.py` now reads both dialect predicates off `__table_args__` and compares the values it extracts against the constant. The domain suite cannot do this -- it is deliberately dependency-free and cannot import an ORM model -- so the new domain case names where the other half of the rule lives. Removed ------- Three duplicates: an `INTERRUPTED -> CANCELLED` case the parametrize directly above it already made, a trailing-Z case identical in path to the aware-run_at case beside it (the `from_primitives` one is the real one, because it parses a string), and an `ensure_launchable == next_after` case whose value another case already asserts outright. Their reasoning moved into comments where it still applies. The second copy of the tautology, in `test_schedule_fakes.py`, goes with it. Verification ------------ A green run is not evidence for this kind of change, so every new or rewritten assertion was checked by mutation -- break the production rule, confirm the guarding test fails. All nine caught, re-run after `ruff format` to confirm the reformat did not soften any of them. Net +207/-31 across four test files; 425 passed, 3 skipped for the schedule and composition suites. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
59 lines
2.5 KiB
Python
59 lines
2.5 KiB
Python
import re
|
|
|
|
from sqlalchemy import Index
|
|
|
|
from deerflow.config.app_config import AppConfig
|
|
from deerflow.domain.schedule.model import ACTIVE_RUN_STATUSES
|
|
from deerflow.persistence.models import ScheduledTaskRow, ScheduledTaskRunRow
|
|
|
|
|
|
def test_app_config_exposes_scheduler_section():
|
|
config = AppConfig.model_validate(
|
|
{
|
|
"models": [],
|
|
"sandbox": {"use": "local"},
|
|
}
|
|
)
|
|
assert config.scheduler.enabled is False
|
|
assert config.scheduler.poll_interval_seconds == 5
|
|
assert config.scheduler.lease_seconds == 120
|
|
|
|
|
|
def test_scheduled_task_models_registered():
|
|
assert ScheduledTaskRow.__tablename__ == "scheduled_tasks"
|
|
assert ScheduledTaskRunRow.__tablename__ == "scheduled_task_runs"
|
|
|
|
|
|
def _active_run_index() -> Index:
|
|
return next(arg for arg in ScheduledTaskRunRow.__table_args__ if isinstance(arg, Index) and arg.name == "uq_scheduled_task_run_active")
|
|
|
|
|
|
def test_active_run_index_arbitrates_one_active_run_per_task():
|
|
"""The index is the atomic arbiter of the overlap rule, so its shape is a
|
|
contract, not a detail: unique, keyed on `task_id` alone."""
|
|
index = _active_run_index()
|
|
assert index.unique is True
|
|
assert [column.name for column in index.expressions] == ["task_id"]
|
|
|
|
|
|
def test_active_run_index_predicate_matches_the_domain_constant():
|
|
"""`ACTIVE_RUN_STATUSES` and this predicate must stay in lockstep.
|
|
|
|
The domain's fast path (`has_active`) and the index disagree the moment
|
|
they drift, which silently decouples the overlap check from its arbiter.
|
|
The domain tests cannot assert this -- they are deliberately
|
|
dependency-free and cannot import an ORM model -- so the assertion the
|
|
`ACTIVE_RUN_STATUSES` docstring promises lives here.
|
|
|
|
Both dialect predicates are checked: `create_all` renders the SQLite one
|
|
and production renders the Postgres one, so a drift in either is real.
|
|
"""
|
|
index = _active_run_index()
|
|
expected = {str(status) for status in ACTIVE_RUN_STATUSES}
|
|
assert expected == {"queued", "running"}, "domain constant changed -- update the ORM predicates below"
|
|
|
|
predicates = {key: str(value) for key, value in index.dialect_kwargs.items() if key.endswith("_where")}
|
|
assert set(predicates) == {"sqlite_where", "postgresql_where"}, "a dialect lost its partial-index predicate"
|
|
for dialect, predicate in predicates.items():
|
|
assert set(re.findall(r"'([^']+)'", predicate)) == expected, f"{dialect} predicate drifted from ACTIVE_RUN_STATUSES"
|