"""正式提交原子性:章后派生登记与正文写入同事务,失败一起回滚。""" import pytest from muse.任务运行.角色策略 import 角色策略目录 from muse.共享.错误 import Muse错误 from muse.启动 import 构建 from muse.正文写作.接口 import 文本节点, 正文草稿, 段落 from muse.配置 import 应用配置 pytestmark = pytest.mark.数据库 @pytest.mark.case_id( "NC-w16-w16a01", environment="真实隔离 PG", given="隔离数据库中的作品与已采纳正文", when="派生登记失败时正文、命令占用与任务一同回滚", then=["正文不存在", "命令未占用", "成功路径同事务可见"], contract="docs/系统架构/新版设计/功能规格/P05-章后处理与事实复核.md", ) def test_章后登记失败回滚整个正文提交__16a01e(章后环境, 章后工具): 环境 = 章后环境 # 用一个未装配章后处理器的同名装配发起保存:流程计划已在库,参与者创建任务时 # 处理器合同核对失败,整个 S01 事务回滚——正文不能只写一半。 孤儿装配 = 构建( 应用配置( 环境["库"].引用, 角色策略目录.从发布包().资源发布身份, 运行用途=环境["库"].用途, 原文暂存=None, ) ) with 孤儿装配.生命周期(): with pytest.raises((Muse错误, RuntimeError, OSError)): 孤儿装配.要求正文().保存人工( 环境["作者"], "atomic-rollback-1", "ch-1", 0, 正文草稿((段落("p1", (文本节点("不会被保存的一章。"),)),)), ) # 正文未写入、命令未占用、章后任务未登记:三者同生共死。 with 环境["库"].连接(只读=True) as 连: 占用 = 连.execute( "SELECT count(*) FROM muse_change_command WHERE command_id=%s", ("atomic-rollback-1",), ).fetchone()[0] assert 占用 == 0 assert 孤儿装配.任务运行.列出任务(环境["作者"].作者) == [] # 正常装配下保存成功:正文与章后任务同事务落地,回执同时呈现两者。 环境["剧本"].append(章后工具.抽取输出("原子性摘要。", [])) 任务1, 回执 = 章后工具.保存一章("ch-1", "林深在码头。", 命令="atomic-ok-1") 登记结果 = [r.get("章后任务") for r in 回执["results"] if isinstance(r, dict)] assert 任务1 in 登记结果 正文 = 环境["装配"].要求正文().读取正文(环境["作者"], "ch-1") assert 正文["revision"] == 1 @pytest.mark.case_id( "NC-w16-w16a02", environment="真实隔离 PG", given="隔离数据库中的作品与已采纳正文", when="候选采纳回执同事务呈现正文写入与章后任务登记", then=["回执含任务", "正文版本前进"], contract="docs/系统架构/新版设计/功能规格/P05-章后处理与事实复核.md", ) def test_采纳候选与派生登记原子可见__16a02f(章后环境, 章后工具): 环境 = 章后环境 from muse.正式变更.接口 import 作者动作 from muse.正文写作.接口 import 候选定位 作者 = 环境["作者"] 候选 = ( 环境["装配"] .要求正文() .创建人工候选( 作者, "atomic-cand-1", "ch-1", 0, 正文草稿((段落("p1", (文本节点("林深在码头整理行装。"),)),)), ) ) 候选ID = next( r["candidate_id"] for r in 候选["results"] if isinstance(r, dict) and "candidate_id" in r ) 候选行 = 环境["装配"].要求正文().读取候选(作者, 候选ID) 定位 = 候选定位( 候选行["candidate_id"], 候选行["revision"], 候选行["candidate_hash"], 候选行["document_id"], 候选行["current_document_revision"], ) 审阅 = 环境["装配"].要求正文().打开候选审阅(作者, 定位) 回执 = ( 环境["装配"] .要求正文() .决定候选( 作者, "atomic-adopt-1", 定位, 作者动作.采纳, 审阅["review_id"], 审阅["review_hash"], ("document",), ) ) 登记结果 = [r.get("章后任务") for r in 回执["results"] if isinstance(r, dict)] assert any(登记结果), 回执["results"] 正文 = 环境["装配"].要求正文().读取正文(作者, "ch-1") assert 正文["revision"] == 1