deer-flow/backend/tests/test_atomic_cleanup_census.py

72 lines
2.2 KiB
Python

"""Staged-write cleanup at the two persistence writers must not replace the outcome.
Each writer stages a temporary file and discards it in a ``finally`` that also
runs when the publish itself failed. Before this change a failing discard
replaced that error with its own.
"""
from __future__ import annotations
from pathlib import Path
import pytest
@pytest.fixture
def real_unlink():
return Path.unlink
def _fail_unlink_on(monkeypatch, predicate, real_unlink):
"""Make ``Path.unlink`` raise for the paths a test owns."""
def unlink(self, *args, **kwargs):
if predicate(self):
raise PermissionError("temporary unlink failed")
return real_unlink(self, *args, **kwargs)
monkeypatch.setattr(Path, "unlink", unlink)
def _is_staged(path: Path) -> bool:
return path.suffix == ".tmp"
def test_managed_subagent_write_keeps_the_replace_error_when_cleanup_fails(tmp_path, monkeypatch, real_unlink):
from deerflow.persistence.managed_subagents import file as store_module
from deerflow.persistence.managed_subagents.base import ManagedSubagentDefinition
definition = ManagedSubagentDefinition(
name="planner",
description="plans",
system_prompt="plan things",
)
target = tmp_path / "planner.json"
def _failing_replace(*_args, **_kwargs):
raise OSError("replace failed")
monkeypatch.setattr(store_module.os, "replace", _failing_replace)
_fail_unlink_on(monkeypatch, _is_staged, real_unlink)
with pytest.raises(OSError, match="replace failed"):
store_module.FileManagedSubagentStore._atomic_write(target, definition)
assert not target.exists()
def test_agent_store_write_keeps_the_publish_error_when_cleanup_fails(tmp_path, monkeypatch, real_unlink):
from deerflow.persistence.agents.file import FileAgentStore
agent_dir = tmp_path / "agents"
agent_dir.mkdir()
def _failing_replace(self, target, *args, **kwargs):
raise OSError("replace failed")
monkeypatch.setattr(Path, "replace", _failing_replace)
_fail_unlink_on(monkeypatch, _is_staged, real_unlink)
with pytest.raises(OSError, match="replace failed"):
FileAgentStore._write(agent_dir, {"name": "planner"}, "# SOUL")