"""采集与业务接入分别记录结果。""" from contextlib import nullcontext from datetime import date from types import SimpleNamespace import pytest from sqlalchemy.exc import IntegrityError from app.core.exceptions import BadRequestError, ConflictError from app.services.tplus import business_sync_control, worker def test_自动接入排队失败不改变成功采集状态(monkeypatch): batch = SimpleNamespace(requested_by=None, source_database="test_source", sync_mode="FULL", status="RUNNING") session = SimpleNamespace(rollback=lambda: None) failures = [] schedule_failures = [] monkeypatch.setattr(worker.task_service, "get_settings", lambda: object()) monkeypatch.setattr(worker, "resolve_tplus_settings", lambda _: SimpleNamespace(t_plus_database="test_source")) monkeypatch.setattr(worker.task_service, "fail_batch", lambda *args: failures.append(args)) class SyncService: def __init__(self, source, target): pass def execute_claimed(self, task): task.status = "SUCCEEDED" def fail_schedule(session): raise RuntimeError("排队失败") monkeypatch.setattr(worker, "TPlusSyncService", SyncService) monkeypatch.setattr(business_sync_control, "schedule", fail_schedule) monkeypatch.setattr(business_sync_control, "record_schedule_failure", lambda session, source: schedule_failures.append(source)) worker._execute(session, batch, lambda: nullcontext(object())) assert batch.status == "SUCCEEDED" assert failures == [] assert schedule_failures == ["test_source"] @pytest.mark.parametrize("race", ["same", "different", "unrelated"]) def test_业务接入排队完整性错误只核对一次既有任务(monkeypatch, race): found = SimpleNamespace(kind="BUSINESS_SYNC", requested_by=1, source_database="test_source", input_json={"start_date": "2026-03-01"}) if race == "different": found.requested_by = 2 results = iter([None, found if race != "unrelated" else None]) rollbacks = [] class Session: def get(self, *_args): return object() def scalar(self, _query): return next(results) def begin_nested(self): return nullcontext() def add(self, _row): pass def flush(self): raise IntegrityError("insert", {}, Exception()) def rollback(self): rollbacks.append(True) monkeypatch.setattr(business_sync_control, "require_permission", lambda *_args: None) monkeypatch.setattr(business_sync_control, "history_source_database", lambda _session: "test_source") monkeypatch.setattr(business_sync_control, "work_out", lambda row: row) args = (Session(), 1, date(2026, 3, 1), "same-key") if race == "same": assert business_sync_control.queue(*args) is found else: with pytest.raises(BadRequestError if race == "different" else ConflictError): business_sync_control.queue(*args) assert rollbacks == [True]