feat: stabilize multi-region runtime sync and worker orchestration

This commit is contained in:
root
2026-04-27 15:48:12 +08:00
parent 7cbde2aa78
commit 215a364891
137 changed files with 31931 additions and 1943 deletions

View File

@@ -0,0 +1,170 @@
import sys
import unittest
from pathlib import Path
from unittest.mock import MagicMock, patch
PROJECT_ROOT = Path(__file__).resolve().parents[2]
DOMAINCHECK_ROOT = PROJECT_ROOT / "domainCheck"
if str(DOMAINCHECK_ROOT) not in sys.path:
sys.path.insert(0, str(DOMAINCHECK_ROOT))
from app.core.detect_engine import DetectEngine
from app.detectors.rdap_detector import RDAPDetector
class DetectEngineOutcomeTests(unittest.TestCase):
def _build_engine(self):
patchers = [
patch("app.core.detect_engine.Database"),
patch("app.core.detect_engine.RDAPDetector"),
patch("app.core.detect_engine.WaybackDetector"),
patch("app.core.detect_engine.BaiduDetector"),
patch("app.core.detect_engine.Qihu360Detector"),
patch("app.core.detect_engine.GoogleDetector"),
patch("app.core.detect_engine.ChinazDetector"),
patch("app.core.detect_engine.AizhanDetector"),
patch("app.core.detect_engine.JuziseoDetector"),
patch("app.core.detect_engine.JuchaDetector"),
]
started = [patcher.start() for patcher in patchers]
self.addCleanup(lambda: [patcher.stop() for patcher in reversed(patchers)])
engine = DetectEngine()
for started_mock in started:
started_mock.return_value = MagicMock()
return engine
def test_process_task_blacklisted_is_completed_without_retry(self):
engine = self._build_engine()
engine.db.get_task_by_id.return_value = {"id": 7, "domain_id": 42, "retry_count": 1}
engine._detect_domain_with_outcome = MagicMock(return_value=engine.OUTCOME_BLACKLISTED)
success = engine.process_task(7)
self.assertTrue(success)
self.assertEqual(
[(7, 1), (7, 2)],
[call.args for call in engine.db.update_task_status.call_args_list],
)
engine.db.update_task_retry_count.assert_not_called()
def test_process_task_failed_requeues_for_retry(self):
engine = self._build_engine()
engine.db.get_task_by_id.return_value = {"id": 9, "domain_id": 99, "retry_count": 0}
engine._detect_domain_with_outcome = MagicMock(return_value=engine.OUTCOME_FAILED)
success = engine.process_task(9)
self.assertFalse(success)
self.assertEqual(
[(9, 1), (9, 0)],
[call.args for call in engine.db.update_task_status.call_args_list],
)
engine.db.update_task_retry_count.assert_called_once_with(9, 1)
def test_deep_detect_fails_when_any_detector_returns_error(self):
engine = self._build_engine()
engine.baidu_detector.check_history.return_value = {"error": "timeout"}
engine.baidu_detector.check_site.return_value = {"has_收录": False, "subdomains": []}
engine.qihu360_detector.check_site.return_value = {"has_收录": False, "subdomains": []}
engine.google_detector.check_site.return_value = {"has_收录": False}
engine.chinaz_detector.check_domain.return_value = {"title": "", "category": "", "has_sensitive": False}
engine.aizhan_detector.check_domain.return_value = {"title": "", "risk": "", "has_sensitive": False}
engine.juziseo_detector.check_domain.return_value = {"history": {}, "backlink": {}}
engine.jucha_detector.check_domain.return_value = {"whois": {}, "beian": {}, "intercept": {"normal": True}}
engine.db.add_detection_result.return_value = True
outcome = engine._deep_detect(1, "example.com")
self.assertEqual(engine.OUTCOME_FAILED, outcome)
engine.db.add_detection_result.assert_not_called()
def test_deep_detect_fails_when_result_persistence_fails(self):
engine = self._build_engine()
engine.baidu_detector.check_history.return_value = {"has_history": False, "has_gray": False}
engine.baidu_detector.check_site.return_value = {"has_收录": False, "subdomains": []}
engine.qihu360_detector.check_site.return_value = {"has_收录": False, "subdomains": []}
engine.google_detector.check_site.return_value = {"has_收录": False}
engine.chinaz_detector.check_domain.return_value = {"title": "", "category": "", "has_sensitive": False}
engine.aizhan_detector.check_domain.return_value = {"title": "", "risk": "", "has_sensitive": False}
engine.juziseo_detector.check_domain.return_value = {"history": {}, "backlink": {}}
engine.jucha_detector.check_domain.return_value = {"whois": {}, "beian": {}, "intercept": {"normal": True}}
engine.db.add_detection_result.return_value = False
outcome = engine._deep_detect(1, "example.com")
self.assertEqual(engine.OUTCOME_FAILED, outcome)
engine.db.add_detection_result.assert_called_once()
def test_deep_detect_normalizes_results_before_persisting(self):
engine = self._build_engine()
engine.baidu_detector.check_history.return_value = {"has_history": True, "has_gray": False}
engine.baidu_detector.check_site.return_value = {"has_收录": True, "subdomains": ["www"]}
engine.qihu360_detector.check_site.return_value = {"has_收录": False, "subdomains": []}
engine.google_detector.check_site.return_value = {"has_收录": False}
engine.chinaz_detector.check_domain.return_value = {"title": "Example", "category": "", "has_sensitive": False}
engine.aizhan_detector.check_domain.return_value = {"title": "Example", "risk": "", "has_sensitive": False}
engine.juziseo_detector.check_domain.return_value = {
"history": {"has_sensitive": False, "has_baidu_history": True, "has_subdomains": False, "is_simplified": True},
"backlink": {"has_sensitive": False, "has_subdomains": False},
}
engine.jucha_detector.check_domain.return_value = {
"whois": {"status": ""},
"beian": {"has_beian": True, "beian_year": "2024", "is_enterprise": True, "beian_match": True},
"intercept": {"normal": True},
}
engine.db.add_detection_result.return_value = True
outcome = engine._deep_detect(1, "example.com")
self.assertEqual(engine.OUTCOME_SUCCESS, outcome)
persisted_args = engine.db.add_detection_result.call_args.args
self.assertTrue(persisted_args[1]["status"])
self.assertTrue(persisted_args[1]["has_history"])
self.assertTrue(persisted_args[2]["status"])
self.assertTrue(persisted_args[2]["has_收录"])
self.assertIn("state", persisted_args[7]["history"])
self.assertTrue(persisted_args[8]["beian"]["status"])
def test_deep_detect_stops_early_after_blacklist_hit(self):
engine = self._build_engine()
engine.baidu_detector.check_history.return_value = {"has_history": True, "has_gray": True}
engine.baidu_detector.check_site.return_value = {"has_收录": False, "subdomains": []}
engine.db.add_detection_result.return_value = True
outcome = engine._deep_detect(1, "example.com")
self.assertEqual(engine.OUTCOME_BLACKLISTED, outcome)
engine.qihu360_detector.check_site.assert_not_called()
engine.google_detector.check_site.assert_not_called()
engine.db.add_detection_result.assert_called_once()
def test_deep_detect_fails_when_nested_detector_returns_error(self):
engine = self._build_engine()
engine.baidu_detector.check_history.return_value = {"has_history": False, "has_gray": False}
engine.baidu_detector.check_site.return_value = {"has_收录": False, "subdomains": []}
engine.qihu360_detector.check_site.return_value = {"has_收录": False, "subdomains": []}
engine.google_detector.check_site.return_value = {"has_收录": False}
engine.chinaz_detector.check_domain.return_value = {"title": "", "category": "", "has_sensitive": False}
engine.aizhan_detector.check_domain.return_value = {"title": "", "risk": "", "has_sensitive": False}
engine.juziseo_detector.check_domain.return_value = {
"history": {"error": "HTTP 429"},
"backlink": {"has_sensitive": False, "has_subdomains": False},
}
engine.jucha_detector.check_domain.return_value = {"whois": {}, "beian": {}, "intercept": {"normal": True}}
outcome = engine._deep_detect(1, "example.com")
self.assertEqual(engine.OUTCOME_FAILED, outcome)
engine.db.add_detection_result.assert_not_called()
class RDAPDetectorStatusMappingTests(unittest.TestCase):
def test_check_register_status_uses_statuses_field(self):
detector = RDAPDetector()
with patch.object(detector, "check_domain", return_value={"statuses": ["clientHold"]}):
status = detector.check_register_status("example.com")
self.assertEqual(7, status)
if __name__ == "__main__":
unittest.main()