from __future__ import annotations import tempfile import unittest from pathlib import Path from unittest.mock import patch import app.services.import_task_service as import_task_service class _TraceLock: def __init__(self, order: list[str]) -> None: self.order = order def __enter__(self): self.order.append("enter") return self def __exit__(self, exc_type, exc, tb): self.order.append("exit") return False class ImportTaskServiceTests(unittest.TestCase): @patch("app.services.import_task_service.import_domains_from_path") @patch("app.services.import_task_service._update_task_with_log") def test_run_import_task_acquires_execution_lock_before_marking_running( self, mock_update_task_with_log, mock_import_domains_from_path, ) -> None: order: list[str] = [] mock_update_task_with_log.side_effect = lambda *args, **kwargs: order.append("update") mock_import_domains_from_path.return_value = { "source_label": "TXT 导入", "stats": {"total": 1, "valid": 1, "added": 1, "exists": 0, "invalid": 0}, } with tempfile.TemporaryDirectory() as tmpdir: path = Path(tmpdir) / "domains.txt" path.write_text("a.com\n", encoding="utf-8") with patch.object(import_task_service, "_IMPORT_EXECUTION_LOCK", _TraceLock(order)): import_task_service._run_import_task("task-1", str(path), source_type=7) self.assertEqual("enter", order[0]) self.assertIn("update", order[1:]) self.assertEqual("exit", order[-1]) if __name__ == "__main__": unittest.main()