Files
getDomain/domain-api/tests/test_detect_service_status_fallback.py
Your Name 7cbde2aa78 d
2026-04-22 14:13:21 +08:00

70 lines
4.3 KiB
Python

import unittest
from unittest.mock import patch
from app.services import detect_service
class DetectServiceStatusFallbackTests(unittest.TestCase):
def test_get_detect_status_keeps_runtime_snapshot_when_db_is_unreachable(self) -> None:
runtime_state = {
"service_running": True,
"detecting": True,
"active_threads": 7,
"max_threads": 120,
"phase": "running",
"detail": "Worker 正在处理 7 个检测任务",
"updated_at": "2026-04-20 23:59:00",
"available_proxy_count": 18,
}
with patch("app.services.detect_service.ensure_runtime_schema"), \
patch("app.services.detect_service.get_db", side_effect=RuntimeError("db down")), \
patch("app.services.detect_service.get_settings_payload", return_value={"proxy_config": {"proxy_enable": True, "allow_direct": False, "proxy_urls": ["a"]}}), \
patch("app.services.detect_service.get_runtime_settings", return_value={"worker_log_sync_enabled": False, "worker_log_sync_mode": "full"}), \
patch("app.services.detect_service._load_recent_worker_lines", return_value=(True, "", [])), \
patch("app.services.detect_service.detect_worker_runtime", return_value={"mode": "linux-systemd", "running": True, "process_count": 1, "latest_start_time": "2026-04-20 23:58:00", "message": "active/running"}), \
patch("app.services.detect_service._load_runtime_state", return_value=runtime_state), \
patch("app.services.detect_service._load_runtime_state_from_cluster_node", return_value={}), \
patch("app.services.detect_service._extract_available_proxy_count", return_value=0), \
patch("app.services.detect_service._extract_active_thread_snapshot", return_value={"active": 0, "max": 0}), \
patch("app.services.detect_service._normalize_recent_warning", return_value=""), \
patch("app.services.detect_service._build_proxy_runtime_snapshot", return_value={"state": "healthy", "label": "代理正常", "detail": "healthy", "direct_fallback_active": False, "reason": "healthy", "last_refresh_status": "ok", "last_refresh_time": "", "source_count": 2, "raw_items": 18, "validated_count": 18, "available_count": 18, "source_stats": [], "supplier_empty": False}), \
patch("app.services.detect_service.resolve_thread_count", return_value={"effective_thread_count": 120, "default_thread_count": 5, "source": "node_override", "override_thread_count": 120, "node_code": "mainland-worker-01"}), \
patch("app.services.detect_service.get_active_detect_job_summary", side_effect=RuntimeError("db down")), \
patch("app.services.detect_service.sync_detect_runs", return_value=[]), \
patch("app.services.detect_service._resolve_remote_log_snapshot", return_value={}), \
patch("app.services.detect_service._extract_dependency_alerts", return_value=[]), \
patch("app.services.detect_service.append_detect_result_projection_if_changed"):
payload = detect_service.get_detect_status()
self.assertTrue(payload["worker_online"])
self.assertTrue(payload["detecting"])
self.assertEqual(7, payload["active_thread_count"])
self.assertEqual(120, payload["max_thread_count"])
self.assertEqual(0, payload["progress"]["pending"])
self.assertEqual(0, payload["progress"]["completed"])
def test_filter_lines_since_supports_journalctl_syslog_timestamps(self) -> None:
lines = [
"Apr 21 20:12:42 mainland-controller python[1]: 当前实际线程数量: 323/4",
"Apr 21 20:17:20 mainland-controller python[2]: Worker 已启动,等待检测指令",
]
filtered = detect_service._filter_lines_since(lines, "2026-04-21 20:17:00")
self.assertEqual(
["Apr 21 20:17:20 mainland-controller python[2]: Worker 已启动,等待检测指令"],
filtered,
)
def test_filter_lines_since_falls_back_when_no_timestamp_is_parseable(self) -> None:
lines = ["no timestamp line 1", "no timestamp line 2"]
filtered = detect_service._filter_lines_since(lines, "2026-04-21 20:17:00")
self.assertEqual(lines, filtered)
if __name__ == "__main__":
unittest.main()