feat(tplus): 新增 T+ 只读同步服务与同步管理
This commit is contained in:
1 parent
78bef43c06
commit
4fe5916c2c
43 files changed
+3309
-388
No files matched your search
@@ -0,0 +1,93 @@
|
||||
"""同一意图不可重复排队,重试必须保留原始批次和范围。"""
|
||||
|
||||
from uuid import uuid4
|
||||
|
||||
import pytest
|
||||
from sqlalchemy import func, select
|
||||
|
||||
from app.core.exceptions import BadRequestError
|
||||
from app.models import TPlusSyncBatch, TPlusSyncError
|
||||
from app.schemas.tplus import TPlusCreateIn, TPlusRetryIn
|
||||
from app.services.tplus import task_service
|
||||
|
||||
|
||||
def _create(**kwargs):
|
||||
return TPlusCreateIn(request_key=uuid4(), entity_types=["products"], **kwargs)
|
||||
|
||||
|
||||
def test_同键同意图复用同一批次(tplus_session):
|
||||
request = _create()
|
||||
first = task_service.create_task(tplus_session, request)
|
||||
second = task_service.create_task(tplus_session, request)
|
||||
assert first.id == second.id
|
||||
assert first.status == "QUEUED"
|
||||
assert first.started_at is None
|
||||
assert first.entity_types_json == ["products"]
|
||||
assert tplus_session.scalar(select(func.count()).select_from(TPlusSyncBatch)) == 1
|
||||
|
||||
|
||||
def test_同键不同范围拒绝(tplus_session):
|
||||
request = _create()
|
||||
task_service.create_task(tplus_session, request)
|
||||
changed = TPlusCreateIn(request_key=request.request_key, entity_types=["personnel"])
|
||||
with pytest.raises(BadRequestError, match="幂等"):
|
||||
task_service.create_task(tplus_session, changed)
|
||||
|
||||
|
||||
def test_失败重试创建新批次并保留原错误(tplus_session):
|
||||
parent = task_service.create_task(tplus_session, _create())
|
||||
parent.status = "FAILED"
|
||||
tplus_session.add(
|
||||
TPlusSyncError(
|
||||
batch_no=parent.batch_no,
|
||||
entity_type="products",
|
||||
source_table="AA_Inventory",
|
||||
error_code="READ_ERROR",
|
||||
error_message="读取失败",
|
||||
)
|
||||
)
|
||||
tplus_session.commit()
|
||||
retry = TPlusRetryIn(request_key=uuid4())
|
||||
child = task_service.retry_task(tplus_session, parent.batch_no, retry)
|
||||
replay = task_service.retry_task(tplus_session, parent.batch_no, retry)
|
||||
assert child.id == replay.id and child.id != parent.id
|
||||
assert child.parent_batch_no == parent.batch_no
|
||||
assert parent.status == "FAILED"
|
||||
assert tplus_session.scalar(select(TPlusSyncError.retry_count)) == 1
|
||||
|
||||
|
||||
def test_已有未完成重试时不重复排队(tplus_session):
|
||||
parent = task_service.create_task(tplus_session, _create())
|
||||
parent.status = "FAILED"
|
||||
tplus_session.commit()
|
||||
task_service.retry_task(tplus_session, parent.batch_no, TPlusRetryIn(request_key=uuid4()))
|
||||
with pytest.raises(BadRequestError, match="重试任务"):
|
||||
task_service.retry_task(tplus_session, parent.batch_no, TPlusRetryIn(request_key=uuid4()))
|
||||
|
||||
|
||||
def test_成功或未知历史范围不能自动重试(tplus_session):
|
||||
parent = task_service.create_task(tplus_session, _create())
|
||||
parent.status = "SUCCEEDED"
|
||||
tplus_session.commit()
|
||||
with pytest.raises(BadRequestError):
|
||||
task_service.retry_task(tplus_session, parent.batch_no, TPlusRetryIn(request_key=uuid4()))
|
||||
parent.status, parent.entity_types_json = "FAILED", None
|
||||
tplus_session.commit()
|
||||
with pytest.raises(BadRequestError, match="范围"):
|
||||
task_service.retry_task(tplus_session, parent.batch_no, TPlusRetryIn(request_key=uuid4()))
|
||||
|
||||
|
||||
def test_关联核验不需要读取实体范围(tplus_session):
|
||||
batch = task_service.create_task(
|
||||
tplus_session, TPlusCreateIn(task_type="AUDIT", request_key=uuid4())
|
||||
)
|
||||
assert batch.sync_mode == "AUDIT"
|
||||
assert batch.entity_types_json == []
|
||||
|
||||
|
||||
def test_预留增量批次不得静默改为全量重试(tplus_session):
|
||||
batch = task_service.create_task(tplus_session, _create())
|
||||
batch.status, batch.sync_mode = "FAILED", "INCREMENTAL"
|
||||
tplus_session.commit()
|
||||
with pytest.raises(BadRequestError, match="方式"):
|
||||
task_service.retry_task(tplus_session, batch.batch_no, TPlusRetryIn(request_key=uuid4()))
|
||||
Reference in new issue
Block a user