实现侧: - 上下文:任务范围拆分为 范围校验/范围授权;索引按可发现口径重建、索引新鲜度改对称差;依赖校验统一快照漂移说明。 - 知识方法:方法与材料读取口径统一;超限方法材料按可选省略,核对路径不再二次计费;删除无合同的读时重算。 - 任务运行:新增 context.usage/tool.denied 事件类型;连接池常驻并在装配生命周期内开关;调用结算与核对分列。 - 效果评测/审校修订/交付连载/作者经验/作品规划:凭据冻结、标定消费、导出补证、事实引文核对等收尾修复。 - 资源加载:能力正文不再夹带索引用的导航注记(该注记此前进入角色与技能的模型提示)。 - 元数据:受保护骨架与代码保护属性对齐;字段校验与内置结构口径同步。 - 基础设施:环境预检进入装配生命周期;数据库连接运行期字段不参与相等比较;索引指纹归一化 jsonb 浮点。 - 删除被替代实现:7 份旧提示词模板与空壳 资料来源 读取器。 用例侧: - 用例身份与导航元信息迁移;夹具补生命周期、同库暴露与模板封存; - 本轮定向修复:方法材料省略、事实引文、迁移回执、额度与暂停用例、慢用例超时预算等。
99 lines
4.2 KiB
Python
99 lines
4.2 KiB
Python
"""备份恢复不因迁移集相同就接受另一程序资源构建。"""
|
||
|
||
import configparser
|
||
import subprocess
|
||
from dataclasses import replace
|
||
from pathlib import Path
|
||
|
||
import pytest
|
||
|
||
from muse.共享.调用身份 import 用途
|
||
from muse.基础设施 import 备份恢复
|
||
from muse.基础设施.备份恢复 import 创建备份, 备份恢复错误, 恢复备份
|
||
from muse.配置 import 应用配置, 数据库引用
|
||
|
||
|
||
@pytest.mark.case_id(
|
||
"NC-w29-29a011",
|
||
environment="离线",
|
||
given="显式隔离配置、合成数据与已知发布构建",
|
||
when="经真实维护、业务或浏览器入口执行并读取持久结果",
|
||
then=["相同发布标签不能掩盖不同构建且拒绝发生在目标连接前"],
|
||
contract="docs/系统架构/新版设计/迁移与验收.md#备份与恢复入口",
|
||
)
|
||
def test_相同发布标签不能掩盖不同构建且拒绝发生在目标连接前__29a011(monkeypatch, tmp_path):
|
||
installed = {"发布身份": "synthetic-release", "构建身份": "a" * 64, "代码哈希": "b" * 64}
|
||
monkeypatch.setattr(备份恢复, "核对资源", lambda: dict(installed))
|
||
monkeypatch.setattr(备份恢复, "运行代码哈希", lambda: "b" * 64)
|
||
config = 应用配置(
|
||
数据库引用("受控存储", str(tmp_path / "missing")), installed["构建身份"], 运行用途=用途.维护
|
||
)
|
||
monkeypatch.setattr(
|
||
备份恢复,
|
||
"核对备份",
|
||
lambda _: {
|
||
"backup_id": "chosen",
|
||
"resource_release": installed["发布身份"],
|
||
"resource_build_id": "0" * 64,
|
||
},
|
||
)
|
||
with pytest.raises(备份恢复错误, match="构建身份"):
|
||
恢复备份(tmp_path / "backup", config, "chosen")
|
||
with pytest.raises(备份恢复错误, match="程序、资源或配置"):
|
||
创建备份(replace(config, 资源发布身份="wrong-release"), tmp_path / "new")
|
||
assert not (tmp_path / "new").exists()
|
||
|
||
|
||
@pytest.mark.case_id(
|
||
"NC-w30-c0f001",
|
||
environment="离线单元;客户端替身,不证明真实PG备份成功",
|
||
given="受控连接含 keepalives 参数,外部环境含不可信 PGSERVICE",
|
||
when="备份客户端成功或超时退出",
|
||
then=[
|
||
"保活参数通过0600临时服务文件传递,凭据不进入命令行或临时服务文件",
|
||
"成功与异常路径均清理临时文件,不继承外部服务选择",
|
||
],
|
||
contract="docs/系统架构/新版设计/迁移与验收.md#备份与恢复入口",
|
||
)
|
||
@pytest.mark.parametrize("失败", [False, True])
|
||
def test_备份客户端保活参数传递且临时配置总被清理__c0f001(monkeypatch, tmp_path, 失败):
|
||
凭据 = tmp_path / "连接.txt"
|
||
凭据.write_text(
|
||
"host=127.0.0.1 dbname=muse user=muse_maint password=test-secret "
|
||
"keepalives=1 keepalives_idle=15 keepalives_interval=5 keepalives_count=3"
|
||
)
|
||
凭据.chmod(0o600)
|
||
引用 = 数据库引用("受控存储", str(凭据))
|
||
临时文件 = []
|
||
monkeypatch.setenv("PGSERVICE", "untrusted")
|
||
|
||
def 执行(命令, **参数):
|
||
环境 = 参数["env"]
|
||
文件 = Path(环境["PGSERVICEFILE"])
|
||
临时文件.append(文件)
|
||
assert 文件.stat().st_mode & 0o777 == 0o600
|
||
配置 = configparser.ConfigParser()
|
||
配置.read(文件)
|
||
assert dict(配置[环境["PGSERVICE"]]) == {
|
||
"keepalives": "1",
|
||
"keepalives_idle": "15",
|
||
"keepalives_interval": "5",
|
||
"keepalives_count": "3",
|
||
}
|
||
assert 环境["PGUSER"] == "muse_maint"
|
||
assert 环境["PGPASSWORD"] == "test-secret"
|
||
assert "test-secret" not in " ".join(命令)
|
||
assert "test-secret" not in 文件.read_text()
|
||
if 失败:
|
||
raise subprocess.TimeoutExpired(命令, 300)
|
||
return subprocess.CompletedProcess(命令, 0, stderr=b"")
|
||
|
||
monkeypatch.setattr(备份恢复.subprocess, "run", 执行)
|
||
if 失败:
|
||
with pytest.raises(备份恢复错误, match="客户端无法完成"):
|
||
备份恢复._运行客户端("pg_dump", (), 引用, "数据库备份")
|
||
else:
|
||
备份恢复._运行客户端("pg_dump", (), 引用, "数据库备份")
|
||
assert len(临时文件) == 1
|
||
assert not 临时文件[0].exists()
|