feat(shop-role): 实现店铺角色继承功能和权限检查优化
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m39s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m39s
- 新增店铺角色管理 API 和数据模型 - 实现角色继承和权限检查逻辑 - 添加流程测试框架和集成测试 - 更新权限服务和账号管理逻辑 - 添加数据库迁移脚本 - 归档 OpenSpec 变更文档 Ultraworked with Sisyphus
This commit is contained in:
99
flow_tests/core/wait.py
Normal file
99
flow_tests/core/wait.py
Normal file
@@ -0,0 +1,99 @@
|
||||
import logging
|
||||
import time
|
||||
from typing import Any, Callable, Optional
|
||||
|
||||
from .database import Database
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TimeoutError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def wait_for_condition(
|
||||
condition: Callable[[], bool],
|
||||
timeout: float = 30,
|
||||
poll_interval: float = 1,
|
||||
message: str = "等待条件满足",
|
||||
) -> bool:
|
||||
start = time.time()
|
||||
|
||||
while time.time() - start < timeout:
|
||||
try:
|
||||
if condition():
|
||||
logger.info(f"{message}: 成功 (耗时 {time.time() - start:.1f}s)")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.debug(f"{message}: 检查失败 - {e}")
|
||||
|
||||
time.sleep(poll_interval)
|
||||
|
||||
raise TimeoutError(f"{message}: 超时 ({timeout}s)")
|
||||
|
||||
|
||||
def wait_for_task(
|
||||
task_type: str,
|
||||
task_id: int,
|
||||
timeout: float = 60,
|
||||
poll_interval: float = 2,
|
||||
db: Optional[Database] = None,
|
||||
) -> dict:
|
||||
db = db or Database()
|
||||
start = time.time()
|
||||
|
||||
while time.time() - start < timeout:
|
||||
row = db.query_one(
|
||||
"SELECT status, result, error FROM tb_async_task WHERE task_type = %s AND id = %s",
|
||||
(task_type, task_id)
|
||||
)
|
||||
|
||||
if not row:
|
||||
raise ValueError(f"任务不存在: {task_type}#{task_id}")
|
||||
|
||||
if row["status"] in ("completed", "failed"):
|
||||
logger.info(f"任务完成: {task_type}#{task_id}, status={row['status']}, 耗时 {time.time() - start:.1f}s")
|
||||
return dict(row)
|
||||
|
||||
logger.debug(f"等待任务: {task_type}#{task_id}, 当前状态={row['status']}")
|
||||
time.sleep(poll_interval)
|
||||
|
||||
raise TimeoutError(f"任务超时: {task_type}#{task_id} ({timeout}s)")
|
||||
|
||||
|
||||
def wait_for_db_condition(
|
||||
sql: str,
|
||||
params: tuple = (),
|
||||
expected: Any = True,
|
||||
timeout: float = 30,
|
||||
poll_interval: float = 1,
|
||||
db: Optional[Database] = None,
|
||||
) -> Any:
|
||||
db = db or Database()
|
||||
|
||||
def check():
|
||||
result = db.scalar(sql, params)
|
||||
if callable(expected):
|
||||
return expected(result)
|
||||
return result == expected
|
||||
|
||||
wait_for_condition(check, timeout, poll_interval, f"等待 SQL 条件: {sql[:50]}...")
|
||||
return db.scalar(sql, params)
|
||||
|
||||
|
||||
def wait_for_record_count(
|
||||
table: str,
|
||||
where_clause: str,
|
||||
expected_count: int,
|
||||
timeout: float = 30,
|
||||
db: Optional[Database] = None,
|
||||
) -> int:
|
||||
db = db or Database()
|
||||
sql = f"SELECT COUNT(*) FROM {table} WHERE {where_clause}"
|
||||
|
||||
def check():
|
||||
count = db.scalar(sql)
|
||||
return count >= expected_count
|
||||
|
||||
wait_for_condition(check, timeout, 1, f"等待 {table} 记录数 >= {expected_count}")
|
||||
return db.scalar(sql)
|
||||
Reference in New Issue
Block a user