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

243 lines
8.1 KiB
Python

import unittest
from unittest.mock import patch
from app.services.sync_push_service import (
_build_task_pull_backlog_limits,
_extract_detect_result_projection_events,
_resolve_detect_result_target_job_id,
_should_throttle_task_pull,
ingest_runtime_projection,
)
class _FakeCursor:
def __init__(self, rows):
self._rows = list(rows)
self.executed = []
def execute(self, sql, params=None):
self.executed.append((sql, params))
def fetchone(self):
if self._rows:
return self._rows.pop(0)
return None
def __enter__(self):
return self
def __exit__(self, exc_type, exc, tb):
return False
class _FakeConnection:
def __init__(self, rows):
self.cursor_obj = _FakeCursor(rows)
self.committed = False
def cursor(self):
return self.cursor_obj
def commit(self):
self.committed = True
def __enter__(self):
return self
def __exit__(self, exc_type, exc, tb):
return False
class SyncPushServiceTests(unittest.TestCase):
def test_build_task_pull_backlog_limits_scales_with_thread_configuration(self) -> None:
limits = _build_task_pull_backlog_limits(
5000,
settings_payload={
"thread_count": 100,
"node_thread_counts": {
"mainland-controller-01": 2000,
"mainland-worker-01": 1200,
},
},
)
self.assertEqual(3200, limits["estimated_total_threads"])
self.assertEqual(6400, limits["max_pending_total"])
self.assertEqual(3200, limits["max_register_pending"])
self.assertEqual(800, limits["max_downstream_pending"])
def test_should_throttle_task_pull_when_register_backlog_overwhelms_downstream(self) -> None:
should_throttle, reason = _should_throttle_task_pull(
{
"pending_total": 9438,
"claimed_total": 410,
"running_total": 15,
"register_pending": 8487,
"downstream_pending": 951,
},
{
"max_pending_total": 12000,
"max_register_pending": 3200,
"max_downstream_pending": 800,
},
)
self.assertTrue(should_throttle)
self.assertEqual("register_pending", reason)
def test_should_not_throttle_task_pull_when_backlog_is_within_limits(self) -> None:
should_throttle, reason = _should_throttle_task_pull(
{
"pending_total": 1800,
"claimed_total": 100,
"running_total": 300,
"register_pending": 600,
"downstream_pending": 120,
},
{
"max_pending_total": 6400,
"max_register_pending": 3200,
"max_downstream_pending": 800,
},
)
self.assertFalse(should_throttle)
self.assertEqual("", reason)
def test_extract_detect_result_projection_events_adds_import_metadata(self) -> None:
projection = {
"job": {
"job_id": 12,
"job_code": "detect-local-001",
},
"recent_domain_events": [
{
"node_code": "mainland-worker-01",
"event_type": "domain_completed",
"level": "info",
"message": "完成 a.com",
"created_at": "2026-04-19 01:05:00",
"payload": {"domain": "a.com", "domain_id": 101, "cycle_token": "cycle-1"},
}
],
}
events = _extract_detect_result_projection_events(
source_region="mainland",
source_record_id=88,
projection=projection,
)
self.assertEqual(1, len(events))
event = events[0]
self.assertEqual("domain_completed", event["event_type"])
self.assertEqual("mainland", event["payload"]["import_source_region"])
self.assertEqual(88, event["payload"]["import_source_record_id"])
self.assertEqual("detect-local-001", event["payload"]["import_source_job_code"])
self.assertTrue(event["payload"]["imported_from_projection"])
self.assertTrue(event["payload"]["import_fingerprint"])
@patch("app.services.sync_push_service.get_db")
def test_resolve_detect_result_target_job_id_prefers_matching_job_code(self, mock_get_db) -> None:
fake_conn = _FakeConnection(rows=[(456,)])
mock_get_db.return_value = fake_conn
target_job_id = _resolve_detect_result_target_job_id(
projection={
"job": {
"job_code": "sync-mainland-123",
}
}
)
self.assertEqual(456, target_job_id)
self.assertIn("WHERE job_code = %s", fake_conn.cursor_obj.executed[0][0])
@patch("app.services.detect_job_service.get_active_detect_job_summary")
@patch("app.services.sync_push_service.get_db")
def test_resolve_detect_result_target_job_id_falls_back_to_active_job(
self,
mock_get_db,
mock_get_active_detect_job_summary,
) -> None:
fake_conn = _FakeConnection(rows=[None])
mock_get_db.return_value = fake_conn
mock_get_active_detect_job_summary.return_value = {"job_id": 789}
target_job_id = _resolve_detect_result_target_job_id(
projection={
"job": {
"job_code": "sync-mainland-999",
}
}
)
self.assertEqual(789, target_job_id)
@patch("app.services.sync_push_service._import_detect_result_projection_events")
@patch("app.services.sync_push_service.get_db")
def test_ingest_runtime_projection_imports_detect_result_events_on_new_record(
self,
mock_get_db,
mock_import_events,
) -> None:
fake_conn = _FakeConnection(rows=[None, (321,)])
mock_get_db.return_value = fake_conn
mock_import_events.return_value = {"imported_count": 2, "deduplicated_count": 0, "target_job_id": 9}
ok, message, data = ingest_runtime_projection(
{
"sync_type": "detect_result_projection",
"source_region": "mainland",
"source_record_id": 66,
"projection_hash": "hash-001",
"projection": {"recent_domain_events": []},
}
)
self.assertTrue(ok)
self.assertEqual("同步投影接收成功", message)
self.assertEqual(321, data["record_id"])
self.assertEqual(2, data["event_import"]["imported_count"])
mock_import_events.assert_called_once_with(
source_region="mainland",
source_record_id=66,
projection={"recent_domain_events": []},
)
self.assertTrue(fake_conn.committed)
@patch("app.services.sync_push_service._import_detect_result_projection_events")
@patch("app.services.sync_push_service.get_db")
def test_ingest_runtime_projection_imports_detect_result_events_on_deduplicated_record(
self,
mock_get_db,
mock_import_events,
) -> None:
fake_conn = _FakeConnection(rows=[(777,)])
mock_get_db.return_value = fake_conn
mock_import_events.return_value = {"imported_count": 0, "deduplicated_count": 3, "target_job_id": 9}
ok, message, data = ingest_runtime_projection(
{
"sync_type": "detect_result_projection",
"source_region": "mainland",
"source_record_id": 66,
"projection_hash": "hash-001",
"projection": {"recent_domain_events": []},
}
)
self.assertTrue(ok)
self.assertEqual("同步投影已存在,已按幂等处理", message)
self.assertTrue(data["deduplicated"])
self.assertEqual(3, data["event_import"]["deduplicated_count"])
mock_import_events.assert_called_once_with(
source_region="mainland",
source_record_id=66,
projection={"recent_domain_events": []},
)
if __name__ == "__main__":
unittest.main()