Continue guest-update rollback after individual restore failures

This commit is contained in:
Codex
2026-10-13 15:29:28 +03:00
parent dcf1fbae40
commit 61a5628f9e
3 changed files with 111 additions and 16 deletions
+39
View File
@@ -143,3 +143,42 @@ class GuestUpdateTests(unittest.TestCase):
self.assertEqual(self.old.read_text(), 'OLD = True\n')
self.assertFalse((self.root / 'etc/motd').exists())
self.assertFalse((self.root / 'usr/lib/hydra/bin/hydra').exists())
def test_persistent_restore_failures_attempt_all_cleanup_and_preserve_apply_error(self):
import contextlib
import io
launcher = self.root / 'usr/lib/hydra/bin/hydra'
launcher.parent.mkdir(parents=True)
launcher.write_text('OLD LAUNCHER\n')
self.build()
actual_write = self.mod.atomic_write
original_error = OSError('original apply failure: disk remains full')
calls = 0
def persistent_failure(*args):
nonlocal calls
calls += 1
if calls == 5:
raise original_error
if calls > 5:
raise OSError('persistent restore failure: disk remains full')
return actual_write(*args)
errors = io.StringIO()
with contextlib.redirect_stderr(errors), patch.object(self.mod, 'atomic_write', side_effect=persistent_failure):
with self.assertRaises(OSError) as raised:
self.mod.apply_bundle(self.bundle, self.root, execute=True)
self.assertIs(raised.exception, original_error)
self.assertEqual(self.old.read_text(), 'NEW = True\n')
self.assertFalse((self.root / 'etc/motd').exists())
self.assertFalse((self.root / 'usr/lib/hydra/hydra/__init__.py').exists())
backups = list((self.root / 'var/lib/hydra/updates').iterdir())
self.assertEqual(len(backups), 1)
backup = backups[0]
self.assertEqual((backup / 'usr/lib/hydra/hydra/cli.py').read_text(), 'OLD = True\n')
self.assertEqual((backup / 'usr/lib/hydra/bin/hydra').read_text(), 'OLD LAUNCHER\n')
self.assertIn(str(backup), errors.getvalue())
self.assertIn('rollback incomplete', errors.getvalue().lower())
self.assertIn('usr/lib/hydra/hydra/cli.py', errors.getvalue())
self.assertIn('usr/lib/hydra/bin/hydra', errors.getvalue())
self.assertIn('persistent restore failure', errors.getvalue())