Files
geMoldInsight/tests/test_lockfile_generation.py
T
cjw 79441a8a87 批次6:D4文档治理收口 + D13锁文件流程固化
D4 文档/规划/历史混放收口:
- docs/TECH_DEBT.md §2 由'按批次回顾'精简为'按主题摘要',
  与§3重复内容(批次0-4详细展开)整体迁入
  docs/archive/2026-09_governance_batches.md
- docs/STATUS.md 顶部 2026-09-17 之前条目迁入
  docs/archive/2026-09_status_history.md,仅保留指针
- D2 历史口径补齐为 2026-09-18 批次4后续专项清偿
- D4 标已清偿
- AGENTS.md / docs/archive/README.md 同步导航

D13 锁文件流程固化(镜像引入主体已清偿,仅剩锁文件落盘):
- 新增 deploy/generate_lockfiles.{sh,bat}:在 moldinsight conda
  环境(仅项目依赖)执行 pip freeze --exclude pythonocc-core,
  产出 deploy/requirements-{base,moldinsight}.lock.txt
- deploy/Dockerfile.moldinsight 注释改为指向生成脚本
- docs/OPERATIONS.md §2.1 增加完整流程说明
- tests/test_lockfile_generation.py 加锁文件存在性+体积契约;
  tests/conftest.py 注册 --run-lockfile-check 选项,
  默认 skip(仓库单测不阻塞),CI 镜像构建 job 显式启用 fail-fast

遗留:锁文件本身尚未落盘(本机Miniforge跨项目开发栈混装,
污染严重不能直接 pip freeze);待 CI / 生产首次构建时按流程落锁。

测试基线:126 passed, 9 skipped(默认4原有skip + D13新增5skip;
启用 --run-lockfile-check 时严格断言2项锁文件契约)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 09:59:02 +08:00

106 lines
4.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""D13:锁文件生成契约(部署侧硬性要求)
锁文件 deploy/requirements-{base,moldinsight}.lock.txt 的存在性 + 体积下限
是部署侧硬性要求:
- 锁文件必须在 moldinsight conda 环境构建成功后落盘(见 deploy/generate_lockfiles.sh/.bat)
- 锁文件必须以 git 跟踪方式提交,CI / 离线构建 / 生产复现部署才能直接 `pip install -r`
- 若 lock.txt 缺失或异常空(仅镜像元数据 < 5 行),说明构建流程未走 D13 流程
CI 门禁建议:
- 仓库侧默认 pytest(`pytest tests/ -q`)**不**强制这些断言——锁文件属"部署侧产物",
首次构建未完成时不应阻塞日常单测
- 部署侧 / CI 镜像构建 job 用 `--run-lockfile-check` 显式开启本套件(见 conftest.py)
"""
from pathlib import Path
import pytest
REPO_ROOT = Path(__file__).resolve().parents[1]
DEPLOY_DIR = REPO_ROOT / "deploy"
LOCK_FILES = [
DEPLOY_DIR / "requirements-base.lock.txt",
DEPLOY_DIR / "requirements-moldinsight.lock.txt",
]
GENERATOR_SCRIPTS = [
DEPLOY_DIR / "generate_lockfiles.sh",
DEPLOY_DIR / "generate_lockfiles.bat",
]
def pytest_collection_modifyitems(config, items):
"""仅在显式传入 --run-lockfile-check 时启用 D13 部署侧契约。"""
if not config.getoption("--run-lockfile-check", default=False):
skip_marker = pytest.mark.skip(
reason="D13 部署侧契约:默认 skip;CI 镜像构建 job 需传入 --run-lockfile-check 启用"
)
for item in items:
if "test_lockfile_generation" in item.nodeid:
item.add_marker(skip_marker)
def pytest_addoption(parser):
parser.addoption(
"--run-lockfile-check",
action="store_true",
default=False,
help="启用 D13 锁文件部署侧契约测试(CI 镜像构建 job 使用)",
)
def pytest_collection_modifyitems(config, items):
"""仅在显式传入 --run-lockfile-check 时启用 D13 部署侧契约。
说明:本钩子保留作为冗余保护(conftest.py 已注册同名钩子),
即便测试单独跑 pytest tests/test_lockfile_generation.py 也能正确跳过。
"""
if not config.getoption("--run-lockfile-check", default=False):
skip_marker = pytest.mark.skip(
reason="D13 部署侧契约:默认 skip;CI 镜像构建 job 需传入 --run-lockfile-check 启用"
)
for item in items:
item.add_marker(skip_marker)
def pytest_addoption(parser):
parser.addoption(
"--run-lockfile-check",
action="store_true",
default=False,
help="启用 D13 锁文件部署侧契约测试(CI 镜像构建 job 使用)",
)
@pytest.mark.parametrize("lock_path", LOCK_FILES)
def test_lockfile_exists_and_is_substantive(lock_path):
"""锁文件必须存在且非空(≥5 行 pip freeze 产物),否则部署侧契约缺失。"""
assert lock_path.exists(), (
f"缺少锁文件 {lock_path.relative_to(REPO_ROOT)};"
f"请在 moldinsight conda 环境执行 deploy/generate_lockfiles.sh/.bat 后提交"
)
line_count = sum(1 for _ in lock_path.open(encoding="utf-8") if _.strip())
assert line_count >= 5, (
f"锁文件 {lock_path.relative_to(REPO_ROOT)} 体积异常(仅 {line_count} 行非空行),"
"可能是构建流程未走通,请重新生成"
)
@pytest.mark.parametrize("script_path", GENERATOR_SCRIPTS)
def test_lockfile_generator_script_present(script_path):
"""锁文件生成脚本必须随仓库分发,否则新机器无法落锁。"""
assert script_path.exists(), (
f"缺少生成脚本 {script_path.relative_to(REPO_ROOT)};"
"D13 流程入口文件缺失"
)
def test_lockfile_dockerfile_comment_points_to_generator():
"""Dockerfile.moldinsight 必须明确指向锁文件生成脚本。"""
dockerfile = (DEPLOY_DIR / "Dockerfile.moldinsight").read_text(encoding="utf-8")
assert "generate_lockfiles" in dockerfile, (
"Dockerfile.moldinsight 应在注释中指向 deploy/generate_lockfiles.sh 以引导锁文件生成流程"
)