feat(plugin): persist declared metadata snapshots (#6467)

This commit is contained in:
InfinityPacer
2026-08-26 13:15:12 +08:00
committed by GitHub
parent bd0795082a
commit ac2a2b1129
26 changed files with 1374 additions and 147 deletions
+35 -3
View File
@@ -14,6 +14,7 @@ from app.application.plugin.admission import (
PluginInstallAdmissionRequest,
admit_plugin_install,
)
from app.application.plugin.declaration import PluginDeclaredMetadata
from app.application.plugin.identity import (
PluginBindingBasis,
PluginIdentity,
@@ -56,9 +57,11 @@ def _identity(*, version: str = "1.0.0", revision: int = 1) -> PluginIdentity:
payload_source_key=SOURCE_KEY,
declared_version=version,
package_generation="v3",
system_version=None,
supports_v3=True,
supports_v3t=False,
declared_metadata=PluginDeclaredMetadata.from_package(
{"name": "Demo", "v3": True, "v3t": False},
declaration_version=version,
manifest_matches_payload=True,
),
payload_receipt=RECEIPT,
revision=revision,
created_at=NOW,
@@ -197,6 +200,8 @@ class _PersistenceSpy:
self.calls.append("journal_commit")
if self.commit_error:
raise self.commit_error
if identity_target is not None:
self.identity = identity_target
record = self.records[transaction_id]
record = replace(
record,
@@ -624,6 +629,33 @@ async def test_precommit_failure_restores_files_and_runtime(
rollback_reloader.assert_not_awaited()
@pytest.mark.asyncio
async def test_precommit_failure_keeps_previous_declared_metadata_snapshot():
"""提交前失败不得把新声明快照写成当前身份事实。"""
previous = _identity(version="1.0.0", revision=3)
persistence = _PersistenceSpy([], identity=previous)
rollback_reloader = AsyncMock()
target_reloader = AsyncMock(side_effect=RuntimeError("reload failed"))
command, _, _ = _command(
persistence=persistence,
target_reloader=target_reloader,
rollback_reloader=rollback_reloader,
)
result = await _execute(
command,
admission=_admission(identity=previous),
)
assert result.success is False
assert result.failure_stage == "runtime_reload"
assert result.rollback.journal_deleted is True
assert persistence.identity is previous
assert persistence.identity.declared_version == "1.0.0"
assert persistence.identity.declared_metadata is previous.declared_metadata
rollback_reloader.assert_awaited_once_with("DemoPlugin")
@pytest.mark.asyncio
async def test_database_commit_failure_restores_runtime_before_deleting_journal():
"""数据库最终提交失败时,文件、运行态和 PREPARED journal 必须一起补偿。"""