47 lines
2.0 KiB
Python
47 lines
2.0 KiB
Python
import importlib.util
|
|
import json
|
|
from pathlib import Path
|
|
import subprocess
|
|
import tempfile
|
|
import unittest
|
|
from unittest.mock import patch
|
|
|
|
spec=importlib.util.spec_from_file_location('backup',Path(__file__).parents[1]/'scripts/backup.py')
|
|
b=importlib.util.module_from_spec(spec); spec.loader.exec_module(b)
|
|
|
|
|
|
class BackupTests(unittest.TestCase):
|
|
def test_restores_original_file_and_removes_new_file(self):
|
|
with tempfile.TemporaryDirectory() as d:
|
|
base=Path(d); original=base/'old.conf'; new=base/'new.conf'
|
|
original.write_text('original')
|
|
def ctl(*args): return subprocess.CompletedProcess(args, 1, stdout='')
|
|
with patch.object(b,'PATHS',[str(original),str(new)]), patch.object(b,'ctl',side_effect=ctl):
|
|
b.snapshot(base/'backup')
|
|
original.write_text('changed'); new.write_text('new')
|
|
b.restore(base/'backup')
|
|
self.assertEqual(original.read_text(),'original')
|
|
self.assertFalse(new.exists())
|
|
|
|
def test_preserves_symlinks(self):
|
|
with tempfile.TemporaryDirectory() as d:
|
|
base=Path(d); link=base/'service'; original=base/'target'
|
|
original.write_text('original'); link.symlink_to(original)
|
|
def ctl(*args): return subprocess.CompletedProcess(args, 1, stdout='')
|
|
with patch.object(b,'PATHS',[str(link)]), patch.object(b,'ctl',side_effect=ctl):
|
|
b.snapshot(base/'backup')
|
|
link.unlink(); link.write_text('replaced')
|
|
b.restore(base/'backup')
|
|
self.assertTrue(link.is_symlink())
|
|
self.assertEqual(link.read_text(),'original')
|
|
|
|
def test_rejects_snapshot_with_unexpected_file(self):
|
|
with tempfile.TemporaryDirectory() as d:
|
|
base=Path(d)
|
|
(base/'manifest.json').write_text(json.dumps({'files':{'/unexpected':True},'units':{}}))
|
|
with patch.object(b,'ctl') as ctl, self.assertRaises(ValueError): b.restore(base)
|
|
ctl.assert_not_called()
|
|
|
|
|
|
if __name__=='__main__': unittest.main()
|