[verified] Canonicalize native review publication journals

This commit is contained in:
2026-10-11 09:51:49 +00:00
parent 18222f2ca8
commit 17751f65fe
12 changed files with 1444 additions and 57 deletions
+36 -24
View File
@@ -121,7 +121,18 @@ class FakeLease:
class NativeReviewTests(unittest.TestCase):
def module(self):
self.assertTrue(SCRIPT.is_file(), 'shared native review adapter is missing')
return load(SCRIPT, 'native_review_test')
m = load(SCRIPT, 'native_review_test_' + str(id(self)))
# Every test gets a private registry root; production has no test-only
# root override, so isolate through the journal module seam.
private_root = tempfile.TemporaryDirectory()
self.addCleanup(private_root.cleanup)
root = Path(private_root.name) / 'native-review-journals'
m._journal.root_for = lambda anchor, root=root: root
return m
@staticmethod
def canonical(m, plan):
return m.canonical_journal_path(plan)
def test_payload_is_exact_bound_native_create(self):
m = self.module()
@@ -159,22 +170,23 @@ class NativeReviewTests(unittest.TestCase):
p, before, after, exact = publication_fixture()
api = FakeAPI(p, before, after, exact); lease = FakeLease()
with tempfile.TemporaryDirectory() as td:
result = m.publish(p, before, api, lease, td, declaration={'mode': 'none'})
result = m.publish(p, before, api, lease, self.canonical(m, p), declaration={'mode': 'none'})
self.assertEqual(result['mode'], 'created')
self.assertEqual(api.posts, 1)
self.assertEqual(m.publish(p, before, api, lease, td, declaration={'mode': 'none'})['mode'], 'no_op')
self.assertEqual(m.publish(p, before, api, lease, self.canonical(m, p), declaration={'mode': 'none'})['mode'], 'no_op')
self.assertEqual(api.posts, 1)
self.assertNotIn('body', json.loads((Path(td) / 'intent.json').read_text()))
self.assertNotIn('body', json.loads((self.canonical(m, p) / 'intent.json').read_text()))
for applies in [True, False]:
m = self.module(); p, before, after, exact = publication_fixture()
api = FakeAPI(p, before, after, exact); api.timeout = True; api.apply = applies
with self.subTest(applies=applies), tempfile.TemporaryDirectory() as td:
if applies:
self.assertEqual(m.publish(p, before, api, lease, td, declaration={'mode': 'none'})['mode'], 'reconciled')
self.assertEqual(m.publish(p, before, api, lease, td, declaration={'mode': 'none'})['mode'], 'no_op')
self.assertEqual(m.publish(p, before, api, lease, self.canonical(m, p), declaration={'mode': 'none'})['mode'], 'reconciled')
self.assertEqual(m.publish(p, before, api, lease, self.canonical(m, p), declaration={'mode': 'none'})['mode'], 'no_op')
else:
for _ in range(2):
with self.assertRaises(m.UncertainPublication) as error:
m.publish(p, before, api, lease, td, declaration={'mode': 'none'})
m.publish(p, before, api, lease, self.canonical(m, p), declaration={'mode': 'none'})
self.assertNotIn('secret transport detail', str(error.exception))
self.assertEqual(api.posts, 1)
def test_api_adapter_checks_identity_first_and_collects_all_pages(self):
@@ -333,9 +345,9 @@ class NativeReviewTests(unittest.TestCase):
p, before, after, exact = publication_fixture(); api = FakeAPI(p, before, after, exact); lease = FakeLease()
if kind == 'expired': lease.valid = False
else: api.identity = lambda: p['spec_reviewer']
with self.assertRaises(m.ValidationError): m.publish(p, before, api, lease, td, declaration={'mode': 'none'})
with self.assertRaises(m.ValidationError): m.publish(p, before, api, lease, self.canonical(m, p), declaration={'mode': 'none'})
self.assertEqual(api.posts, 0)
self.assertFalse((Path(td) / 'intent.json').exists())
self.assertFalse((self.canonical(m, p) / 'intent.json').exists())
def test_fresh_head_contract_and_source_linkage_drift_prevent_post(self):
m = self.module()
@@ -348,7 +360,7 @@ class NativeReviewTests(unittest.TestCase):
with self.subTest(case=i), tempfile.TemporaryDirectory() as td:
p, before, after, exact = publication_fixture(); api = FakeAPI(p, copy.deepcopy(before), after, exact)
change(api.before)
with self.assertRaises(m.ValidationError): m.publish(p, before, api, FakeLease(), td, declaration={'mode': 'none'})
with self.assertRaises(m.ValidationError): m.publish(p, before, api, FakeLease(), self.canonical(m, p), declaration={'mode': 'none'})
self.assertEqual(api.posts, 0)
def test_pagination_total_duplicate_and_truncation_are_hard_errors(self):
@@ -424,10 +436,10 @@ class NativeReviewTests(unittest.TestCase):
m = self.module(); p, before, after, exact = publication_fixture()
api = FakeAPI(p, before, after, exact); api.created = True
with tempfile.TemporaryDirectory() as td:
result = m.publish(p, after, api, FakeLease(), td, declaration={'mode': 'none'})
result = m.publish(p, after, api, FakeLease(), self.canonical(m, p), declaration={'mode': 'none'})
self.assertEqual(result['mode'], 'no_op'); self.assertFalse(result['wrote'])
self.assertEqual(api.posts, 0)
self.assertFalse((Path(td) / 'intent.json').exists())
self.assertFalse((self.canonical(m, p) / 'intent.json').exists())
def test_duplicate_or_conflicting_canonical_review_is_not_reposted(self):
m = self.module()
@@ -441,7 +453,7 @@ class NativeReviewTests(unittest.TestCase):
after['pagination']['reviews'][0].update(count=4, declared_total=4)
after['pagination']['review_comments_11'] = [{'page': 1, 'count': 0, 'declared_total': 0, 'link': None}]
api = FakeAPI(p, before, after, exact); api.created = True
with self.assertRaises(m.ValidationError): m.publish(p, before, api, FakeLease(), td, declaration={'mode': 'none'})
with self.assertRaises(m.ValidationError): m.publish(p, before, api, FakeLease(), self.canonical(m, p), declaration={'mode': 'none'})
self.assertEqual(api.posts, 0)
def test_readback_failure_and_changed_journal_plan_never_retry_post(self):
@@ -449,7 +461,7 @@ class NativeReviewTests(unittest.TestCase):
api.read_review = lambda target, rid: (_ for _ in ()).throw(TimeoutError('DO_NOT_ECHO_TRANSPORT_SECRET'))
with tempfile.TemporaryDirectory() as td:
for _ in range(2):
with self.assertRaises(Exception) as raised: m.publish(p, before, api, FakeLease(), td, declaration={'mode': 'none'})
with self.assertRaises(Exception) as raised: m.publish(p, before, api, FakeLease(), self.canonical(m, p), declaration={'mode': 'none'})
self.assertNotIn('DO_NOT_ECHO_TRANSPORT_SECRET', str(raised.exception))
self.assertEqual(api.posts, 1)
different = copy.deepcopy(p); different['body'] += 'different'
@@ -462,15 +474,15 @@ class NativeReviewTests(unittest.TestCase):
root = Path(td); link = root / 'link'; link.symlink_to(root, target_is_directory=True)
with self.assertRaises(m.ValidationError): m.Journal(link)
api = FakeAPI(p, before, after, exact); api.timeout = True; api.apply = False
journal = root / 'journal'
journal = self.canonical(m, p)
with self.assertRaises(m.UncertainPublication): m.publish(p, before, api, FakeLease(), journal, declaration={'mode': 'none'})
saved = json.loads((journal / 'before.json').read_text()); saved['issue']['body'] = 'changed'
(journal / 'before.json').write_text(json.dumps(saved))
with self.assertRaises(m.ValidationError): m.publish(p, before, api, FakeLease(), journal, declaration={'mode': 'none'})
self.assertEqual(api.posts, 1)
with m.Journal(root / 'hardlinks') as j:
j.write('a.json', {'safe': True}); os.link(j.path / 'a.json', j.path / 'b.json')
with self.assertRaises(m.ValidationError): j.read('a.json')
j.write('before.json', {'safe': True}); os.link(j.path / 'before.json', j.path / 'b.json')
with self.assertRaises(m.ValidationError): j.read('before.json')
def test_transport_origin_credential_source_and_exception_text_are_guarded(self):
m = self.module()
@@ -485,7 +497,7 @@ class NativeReviewTests(unittest.TestCase):
m = self.module(); p, before, after, exact = publication_fixture(); api = FakeAPI(p, before, after, exact)
lease = FakeLease(); lease.check = lambda plan: False
with tempfile.TemporaryDirectory() as td:
with self.assertRaises(m.ValidationError): m.publish(p, before, api, lease, td, declaration={'mode': 'none'})
with self.assertRaises(m.ValidationError): m.publish(p, before, api, lease, self.canonical(m, p), declaration={'mode': 'none'})
self.assertEqual(api.posts, 0)
def test_live_rest_bridge_over_loopback_publishes_once_then_no_ops(self):
import threading
@@ -533,10 +545,10 @@ class NativeReviewTests(unittest.TestCase):
api = m.ApiAdapter(request, origin=m.ORIGIN + '/api/v1', credential_source='$HERMES_HOME/.env:GITEA_TOKEN')
baseline = api.snapshot(p['target'])
with tempfile.TemporaryDirectory() as td:
result = m.publish(p, baseline, api, FakeLease(), td, declaration={'mode': 'none'})
result = m.publish(p, baseline, api, FakeLease(), self.canonical(m, p), declaration={'mode': 'none'})
self.assertEqual(result['mode'], 'created'); self.assertEqual(result['projected_review_ids'], [8])
self.assertTrue(result['commit_file_order_normalized'])
second = m.publish(p, baseline, api, FakeLease(), td, declaration={'mode': 'none'})
second = m.publish(p, baseline, api, FakeLease(), self.canonical(m, p), declaration={'mode': 'none'})
self.assertEqual(second['mode'], 'no_op'); self.assertFalse(second['wrote'])
self.assertEqual(state['posts'], 1); self.assertEqual(server.received, m.build_payload(p))
finally:
@@ -586,15 +598,15 @@ class NativeReviewTests(unittest.TestCase):
source.assert_not_called()
def test_journal_intent_fields_are_validated_on_resume(self):
m = self.module()
for field in ['schema', 'head', 'event', 'body_sha256']:
m = self.module()
with self.subTest(field=field), tempfile.TemporaryDirectory() as td:
p, before, after, exact = publication_fixture(); api = FakeAPI(p, before, after, exact)
api.timeout = True; api.apply = False
with self.assertRaises(m.UncertainPublication): m.publish(p, before, api, FakeLease(), td, declaration={'mode': 'none'})
path = Path(td) / 'intent.json'; intent = json.loads(path.read_text()); intent[field] = 'corrupt'
with self.assertRaises(m.ValidationError): m.publish(p, before, api, FakeLease(), self.canonical(m, p), declaration={'mode': 'none'})
path = self.canonical(m, p) / 'intent.json'; intent = json.loads(path.read_text()); intent[field] = 'corrupt'
path.write_text(json.dumps(intent)); api.created = True
with self.assertRaises(m.ValidationError): m.publish(p, before, api, FakeLease(), td, declaration={'mode': 'none'})
with self.assertRaises(m.ValidationError): m.publish(p, before, api, FakeLease(), self.canonical(m, p), declaration={'mode': 'none'})
self.assertEqual(api.posts, 1)
def test_issue_repository_mismatch_is_not_accepted(self):