96 lines
3.8 KiB
Python
96 lines
3.8 KiB
Python
"""验证迁移前状态证据采集器只读取 Git 元数据。"""
|
|
|
|
# 导入测试所需的标准库 JSON、路径和子进程结果类型。
|
|
import json
|
|
from pathlib import Path
|
|
from subprocess import CompletedProcess
|
|
|
|
# 导入 pytest 补丁类型以及待验证的预检工具接口。
|
|
from pytest import MonkeyPatch
|
|
|
|
from tools.foundation_migration_preflight import (
|
|
collect_workspace_state,
|
|
run_git,
|
|
write_preflight_report,
|
|
)
|
|
|
|
|
|
# 验证未跟踪客服文件会被记录,且采集结果不含环境变量名称或值。
|
|
def test_collect_workspace_state_records_untracked_paths_without_environment_values(
|
|
tmp_path: Path,
|
|
) -> None:
|
|
# 构造确定性的 Git 命令替身,不调用真实 Git 或环境变量。
|
|
def fake_git_runner(_worktree: Path, *args: str) -> str:
|
|
# 为分支查询返回客服功能分支名称。
|
|
if args == ("branch", "--show-current"):
|
|
return "feature/customer-service-rag\n"
|
|
# 为提交查询返回固定的非敏感提交标识。
|
|
if args == ("rev-parse", "HEAD"):
|
|
return "abc123\n"
|
|
# 为状态查询返回一个未跟踪客服文件。
|
|
if args == ("status", "--short"):
|
|
return "?? app/service/agent/customer_service_agent.py\n"
|
|
# 防止测试静默接受未定义的 Git 查询。
|
|
raise AssertionError(f"unexpected git arguments: {args}")
|
|
|
|
# 使用替身采集临时工作区的只读状态。
|
|
state = collect_workspace_state(tmp_path, runner=fake_git_runner)
|
|
|
|
# 断言采集到预期的分支名称。
|
|
assert state["branch"] == "feature/customer-service-rag"
|
|
# 断言未跟踪客服文件完整保留在状态清单中。
|
|
assert state["status"] == ["?? app/service/agent/customer_service_agent.py"]
|
|
# 断言序列化结果不包含任何环境变量敏感字段。
|
|
assert "MYSQL_PASSWORD" not in json.dumps(state)
|
|
|
|
|
|
# 验证报告写入器只输出传入的非敏感 Git 状态结构。
|
|
def test_write_preflight_report_persists_utf8_json(tmp_path: Path) -> None:
|
|
# 指定临时报告文件,避免写入任何真实工作目录。
|
|
report_path = tmp_path / "preflight.json"
|
|
# 构造只含安全 Git 元数据的状态条目。
|
|
states = [{"path": "D:/workspace", "branch": "develop", "head": "abc123", "status": []}]
|
|
|
|
# 写入迁移前报告。
|
|
write_preflight_report(report_path, states)
|
|
|
|
# 以 UTF-8 读取并解析报告正文。
|
|
report = json.loads(report_path.read_text(encoding="utf-8"))
|
|
# 断言报告保留原始状态条目。
|
|
assert report == states
|
|
|
|
|
|
# 验证每次 Git 查询只信任当前显式工作区,而不写入全局 Git 配置。
|
|
def test_run_git_scopes_safe_directory_to_the_requested_worktree(
|
|
tmp_path: Path,
|
|
monkeypatch: MonkeyPatch,
|
|
) -> None:
|
|
# 保存被测函数交给子进程层的命令参数。
|
|
captured_commands: list[list[str]] = []
|
|
|
|
# 构造返回固定分支名的无副作用子进程替身。
|
|
def fake_run(command: list[str], **_kwargs: object) -> CompletedProcess[str]:
|
|
# 记录命令以便后续断言安全目录范围。
|
|
captured_commands.append(command)
|
|
# 返回模拟的 Git 成功结果。
|
|
return CompletedProcess(command, 0, "develop\n", "")
|
|
|
|
# 让测试不执行真实 Git。
|
|
monkeypatch.setattr("tools.foundation_migration_preflight.subprocess.run", fake_run)
|
|
|
|
# 执行一个受限 Git 分支查询。
|
|
output = run_git(tmp_path, "branch", "--show-current")
|
|
|
|
# 断言调用仍返回 Git 输出。
|
|
assert output == "develop\n"
|
|
# 断言命令仅为该临时工作区附加安全目录。
|
|
assert captured_commands == [[
|
|
"git",
|
|
"-c",
|
|
f"safe.directory={tmp_path.resolve().as_posix()}",
|
|
"-C",
|
|
str(tmp_path.resolve()),
|
|
"branch",
|
|
"--show-current",
|
|
]]
|