补齐源快照、资料预演、正式导入及工资核算的依赖链路。 新增版本化输入、逐段 FIFO、生成锁和结构化当月调整, 并提供默认关闭的周期采集、有限重试及 Windows 托管。 原始客户资料、私有配置及首页改动不纳入本次提交。 BREAKING CHANGE: 升级前需应用新增迁移,并通过 PAYROLL_MAKER_USER_ID 绑定实际工资制作人,否则业务只读。 旧单批次核算默认关闭;历史兼容需显式启用 PAYROLL_ALLOW_LEGACY_CALCULATION。生产启用和真实金额待验收。
52 lines
2.3 KiB
Python
52 lines
2.3 KiB
Python
"""使用唯一的本地测试库运行迁移和集成测试,绝不清理原业务库。"""
|
|
|
|
import os
|
|
import argparse
|
|
import re
|
|
import secrets
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('--reuse-database')
|
|
parser.add_argument('--migration-roundtrip', action='store_true')
|
|
parsed, test_args = parser.parse_known_args()
|
|
if parsed.reuse_database and not re.fullmatch(r'payroll_test_[0-9a-f]{12}', parsed.reuse_database):
|
|
raise SystemExit('只允许复用本运行器创建的隔离测试库')
|
|
root = Path(__file__).resolve().parents[1]
|
|
python = root / "backend/.venv-workbench/Scripts/python.exe"
|
|
if not python.exists():
|
|
python = Path(sys.executable)
|
|
suffix = secrets.token_hex(6)
|
|
database, username = parsed.reuse_database or "payroll_test_" + suffix, "pytest_" + suffix
|
|
password = secrets.token_urlsafe(30)
|
|
sql = ("" if parsed.reuse_database else f"CREATE DATABASE `{database}` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; ") + f"CREATE USER '{username}'@'%' IDENTIFIED BY '{password}'; GRANT ALL PRIVILEGES ON `{database}`.* TO '{username}'@'%';"
|
|
setup = subprocess.run(
|
|
["docker", "exec", "-i", "ys-mysql-dev", "sh", "-c", 'export MYSQL_PWD="$MYSQL_ROOT_PASSWORD"; exec mysql -uroot'],
|
|
input=sql.encode(), capture_output=True,
|
|
)
|
|
if setup.returncode:
|
|
raise SystemExit("隔离库创建失败,未执行迁移或测试")
|
|
env = os.environ | {
|
|
"MYSQL_DATABASE": database, "MYSQL_USER": username, "MYSQL_PASSWORD": password,
|
|
"PAYROLL_TEST_DATABASE": database, "REDIS_DB": "15", "PYTHONIOENCODING": "utf-8",
|
|
}
|
|
print("独立测试库:" + database, flush=True)
|
|
commands = [["-m", "alembic", "upgrade", "head"]]
|
|
if parsed.migration_roundtrip:
|
|
commands += [["-m", "alembic", "downgrade", "07b8c9d0e1f2"], ["-m", "alembic", "upgrade", "head"]]
|
|
args = test_args
|
|
commands.append(["-m", "pytest", *(args or ["tests/integration"]), "-q", "--tb=short"])
|
|
for args in commands:
|
|
result = subprocess.run([str(python), *args], cwd=root / "backend", env=env)
|
|
if result.returncode:
|
|
return result.returncode
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|