From f5d9144ba9547e62e0f8bfdc042fdb646e441262 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Fri, 4 Nov 2016 11:59:34 +0100 Subject: [PATCH] add unit test tracking behavior wrt symlinks --- testing/__init__.py | 19 ++++++++++++---- testing/test_deltatar.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 5 deletions(-) diff --git a/testing/__init__.py b/testing/__init__.py index c538fef..527c751 100644 --- a/testing/__init__.py +++ b/testing/__init__.py @@ -60,12 +60,21 @@ class BaseTest(unittest.TestCase): write_handle.write(data[:remainder]) return self.md5sum(path) - def md5sum(self, filename): + def create_symlink(self, linkname, path): + os.symlink(linkname, path) + return self.md5sum(path, linkname=linkname) + + def md5sum(self, filename, linkname=None): ''' - Returns the md5sum of a file specified by its filename/path + Returns the md5sum of a file specified by its filename/path or, if + ``linkname`` is specified, the hash of both paths (for symlinks). ''' md5 = hashlib.md5() - with open(filename,'rb') as f: - for chunk in iter(lambda: f.read(128*md5.block_size), b''): - md5.update(chunk) + if linkname is None: + with open(filename,'rb') as f: + for chunk in iter(lambda: f.read(128*md5.block_size), b''): + md5.update(chunk) + else: # symlink; hash paths + md5.update(filename.encode("UTF-8")) + md5.update(linkname.encode("UTF-8")) return md5.hexdigest() diff --git a/testing/test_deltatar.py b/testing/test_deltatar.py index 8c8f67b..ca3e8cb 100644 --- a/testing/test_deltatar.py +++ b/testing/test_deltatar.py @@ -16,6 +16,7 @@ # Author: Eduardo Robles Elvira +import errno import os import re import random @@ -34,6 +35,8 @@ import filesplit from . import BaseTest from . import new_volume_handler +SYMLINK_GOOD = 0 +SYMLINK_BAD = 1 class DeltaTarTest(BaseTest): """ @@ -1389,6 +1392,53 @@ class DeltaTarTest(BaseTest): print("TITEM: " + str(titem)) raise e + def test_create_no_symlinks(self): + ''' + Creates a full backup from different varieties of symlinks. The + extracted archive may not contain any symlinks but the file contents + ''' + + os.system("rm -rf source_dir") + os.makedirs("source_dir/symlinks") + fd = os.open("source_dir/symlinks/valid_linkname", + os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o644) + os.write(fd, b"valid link target for symlink tests; please ignore\n") + os.close(fd) + # first one is good, the rest points nowhere + self.create_symlink("valid_linkname", "source_dir/symlinks/whatever") + self.create_symlink("/foo/bar/baz", "source_dir/symlinks/xyzzy") + self.create_symlink("burp/../buzz", "source_dir/symlinks/blup") + self.create_symlink("../../../../biz", "source_dir/symlinks/bleep") + deltatar = DeltaTar(mode=self.MODE, password=self.PASSWORD, + logger=self.consoleLogger) + + # create first backup + deltatar.create_full_backup(source_path="source_dir", + backup_path="backup_dir") + + assert os.path.exists("backup_dir") + shutil.rmtree("source_dir") + assert not os.path.exists("source_dir") + + tar_filename = deltatar.volume_name_func('backup_dir', True, 0) + tar_path = os.path.join("backup_dir", tar_filename) + + deltatar.restore_backup(target_path="source_dir", + backup_tar_path=tar_path) + + for _r, _ds, fs in os.walk("source_dir/symlinks"): + # only the valid link plus the linked file may be found in the + # extracted archive + assert len(fs) == 2 + for f in fs: + # the link must have been resolved and file contents must match + # the linked file + assert not os.path.islink(f) + with open("source_dir/symlinks/valid_linkname") as a: + with open("source_dir/symlinks/whatever") as b: + assert a.read() == b.read() + + class DeltaTar2Test(DeltaTarTest): ''' Same as DeltaTar but with specific ":" mode -- 1.7.1