import shutil
import deltatar.deltatar as deltatar
+import deltatar.crypto as crypto
from . import BaseTest
+def flip_bits (fname, off, b=0x01, n=1):
+ """
+ Open file *fname* at offset *off*, replacing the next *n* bytes with
+ their values xor’ed with *b*.
+ """
+ fd = os.open (fname, os.O_RDWR)
+ try:
+ pos = os.lseek (fd, off, os.SEEK_SET)
+ assert pos == off
+ chunk = os.read (fd, n)
+ chunk = bytes (map (lambda v: v ^ b, chunk))
+ os.write (fd, chunk)
+ finally:
+ os.close (fd)
+
class RecoverTest (BaseTest):
"""
Disaster recovery: restore corrupt backups.
Expects the extraction to fail in normal mode. With disaster recovery,
extraction must succeed, and exactly one file must be missing.
"""
- src_path = "source_dir2"
+ src_path = "source_dir2"
+ dst_path = "backup_dir"
+ backup_file = "the_full_backup.gz"
+ backup_full = "%s/%s" % (dst_path, backup_file)
+
+ fulldiff = lambda f: f and "full" or "diff"
+
+ def vname (*a, **kwa):
+ return backup_file
dtar = deltatar.DeltaTar (mode="#gz",
- logger=self.consoleLogger)
+ logger=self.consoleLogger,
+ index_name_func=lambda f: \
+ "the_%s_index" % fulldiff (f),
+ volume_name_func=vname)
self.hash = dict ()
os.makedirs (src_path)
self.hash [f] = self.create_file (f, i)
dtar.create_full_backup \
- (source_path="source_dir2", backup_path="backup_dir")
+ (source_path=src_path, backup_path=dst_path)
+
+ # damage byte just after first object header
+ flip_bits (backup_full, crypto.PDTCRYPT_HDR_SIZE + 1)
shutil.rmtree (src_path)