Harden canonical publication against races
This commit is contained in:
parent
8919e2af32
commit
a901c9705b
8 changed files with 1059 additions and 78 deletions
|
|
@ -4,6 +4,7 @@ import contextlib
|
|||
import hashlib
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
import unittest
|
||||
|
|
@ -302,6 +303,49 @@ class DocForgeRenderingTests(unittest.TestCase):
|
|||
self.assertEqual(committed_before, committed_output.read_bytes())
|
||||
self.assertEqual("current", service.status("manual")["state"])
|
||||
|
||||
def test_manual_and_preview_publication_fsync_their_directories(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
root = self.copy_fixture("alpha", Path(directory))
|
||||
project = Project.open(root)
|
||||
changesets = ChangesetStore(project, "alpha-editor")
|
||||
service = RenderService(project, changesets)
|
||||
proposal = changesets.create("durable-preview")
|
||||
proposal = changesets.propose_update(
|
||||
changeset_id="durable-preview",
|
||||
expected_changeset_hash=str(proposal["changeset_hash"]),
|
||||
node_id="guide.workflow",
|
||||
expected_content_hash=self.node_hash(project, "guide.workflow"),
|
||||
metadata={"summary": "Durable preview output."},
|
||||
content=None,
|
||||
relationship_changes=[],
|
||||
rationale="Exercise durable preview publication.",
|
||||
)
|
||||
del proposal
|
||||
real_fsync = os.fsync
|
||||
fsynced_directories: set[Path] = set()
|
||||
|
||||
def record_fsync(descriptor: int) -> None:
|
||||
try:
|
||||
path = Path(os.readlink(f"/proc/self/fd/{descriptor}"))
|
||||
if path.is_dir():
|
||||
fsynced_directories.add(path)
|
||||
except OSError:
|
||||
pass
|
||||
real_fsync(descriptor)
|
||||
|
||||
with mock.patch(
|
||||
"docforge._fs_safety.os.fsync",
|
||||
side_effect=record_fsync,
|
||||
):
|
||||
service.render("manual")
|
||||
service.preview("durable-preview", "manual")
|
||||
|
||||
self.assertIn(root / ".docforge/rendered", fsynced_directories)
|
||||
self.assertIn(
|
||||
root / ".docforge/previews/durable-preview",
|
||||
fsynced_directories,
|
||||
)
|
||||
|
||||
def test_failed_and_mid_input_renders_preserve_previous_outputs(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
root = self.copy_fixture("alpha", Path(directory))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue