Files
modulus/tests/test_filesystem.py
T
khodowany 3efbe5020a
publish / publish (push) Successful in 10m29s
Package
2026-09-30 19:45:17 -05:00

59 lines
2.8 KiB
Python

import pathlib
import tempfile
import unittest
import unittest.mock
import modulus.filesystem
class PublicationTests(unittest.TestCase):
def setUp(self):
self.temporary = tempfile.TemporaryDirectory()
self.addCleanup(self.temporary.cleanup)
self.root = pathlib.Path(self.temporary.name)
self.source, self.target = self.root / 'new', self.root / 'installed'
for path, text in ((self.source, 'new'), (self.target, 'old')):
path.mkdir()
(path / 'content').write_text(text)
def test_publish_replaces_complete_directory(self):
with modulus.filesystem.publish_directories([(self.source, self.target)]):
self.assertEqual((self.target / 'content').read_text(), 'new')
self.assertFalse(self.source.exists())
self.assertEqual(list(self.root.iterdir()), [self.target])
def test_failure_restores_previous_directory(self):
with self.assertRaisesRegex(RuntimeError, 'failed'):
with modulus.filesystem.publish_directories([(self.source, self.target)]):
raise RuntimeError('failed')
self.assertEqual((self.target / 'content').read_text(), 'old')
self.assertFalse(list(self.root.glob('.publish_*')))
def test_failed_second_replacement_rolls_back_first(self):
second = self.root / 'second'
second.mkdir()
rename = pathlib.Path.rename
def fail(path, destination):
if path == second:
raise OSError('failed')
return rename(path, destination)
with unittest.mock.patch.object(pathlib.Path, 'rename', fail), self.assertRaises(OSError):
with modulus.filesystem.publish_directories([(self.source, self.target), (second, self.root / 'last')]):
pass
self.assertEqual((self.target / 'content').read_text(), 'old')
def test_overlaps_and_symlinks_rejected_before_replacement(self):
link = self.root / 'link'
link.symlink_to(self.target, target_is_directory=True)
for target in (self.source, self.source / 'child', self.source / '..' / 'new', self.root, link, link / 'child'):
with self.subTest(target=target), self.assertRaises(ValueError):
with modulus.filesystem.publish_directories([(self.source, target)]):
pass
self.assertEqual((self.target / 'content').read_text(), 'old')
def test_failed_rollback_retains_the_previous_directory_for_recovery(self):
rename = pathlib.Path.rename
def fail(path, destination):
if path.name == 'previous':
raise OSError('restore failed')
return rename(path, destination)
with unittest.mock.patch.object(pathlib.Path, 'rename', fail), self.assertRaisesRegex(RuntimeError, 'recovery directories retained'):
with modulus.filesystem.publish_directories([(self.source, self.target)]):
raise RuntimeError('publication failed')
backup = next(self.root.glob('.publish_*/previous/content'))
self.assertEqual(backup.read_text(), 'old')