From da8996f02dd6cf641611beaf3efcd8b622a2f134 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Fri, 11 Aug 2017 10:53:09 +0200 Subject: [PATCH] add recover tests for completely damaged headers --- runtests.py | 8 +++++++- testing/test_recover.py | 41 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/runtests.py b/runtests.py index 2ed85cb..6e25aba 100755 --- a/runtests.py +++ b/runtests.py @@ -28,7 +28,10 @@ from testing.test_recover import \ , RecoverCorruptPayloadGZAESTest \ , RecoverCorruptHeaderTest \ , RecoverCorruptHeaderGZTest \ - , RecoverCorruptHeaderGZAESTest + , RecoverCorruptHeaderGZAESTest \ + , RecoverCorruptEntireHeaderTest \ + , RecoverCorruptEntireHeaderGZTest \ + , RecoverCorruptEntireHeaderGZAESTest from testing.test_rescue_tar import RescueTarTest from testing.test_encryption import EncryptionTest from testing.test_deltatar import (DeltaTarTest, DeltaTar2Test, @@ -69,6 +72,9 @@ if __name__ == "__main__": , RecoverCorruptHeaderTest , RecoverCorruptHeaderGZTest , RecoverCorruptHeaderGZAESTest + , RecoverCorruptEntireHeaderTest + , RecoverCorruptEntireHeaderGZTest + , RecoverCorruptEntireHeaderGZAESTest ]: try: t = group (n) diff --git a/testing/test_recover.py b/testing/test_recover.py index fd85707..9f584e0 100644 --- a/testing/test_recover.py +++ b/testing/test_recover.py @@ -26,6 +26,8 @@ def flip_bits (fname, off, b=0x01, n=1): assert pos == off chunk = os.read (fd, n) chunk = bytes (map (lambda v: v ^ b, chunk)) + pos = os.lseek (fd, off, os.SEEK_SET) + assert pos == off os.write (fd, chunk) finally: os.close (fd) @@ -54,6 +56,7 @@ def gz_header_size (fname, off=0): return off + def is_pdt_encrypted (fname): """ Returns true if the file contains at least one PDT header plus enough @@ -91,6 +94,18 @@ def corrupt_header (_, fname, compress, encrypt): flip_bits (fname, 100 + 8 + 8 + 8 + 12 + 12 + 1) +def corrupt_entire_header (_, fname, compress, encrypt): + """ + Flip all bits in the first object header. + """ + if encrypt is True: + flip_bits (fname, 0, 0xff, crypto.PDTCRYPT_HDR_SIZE) + elif compress is True: # invalidate magic + flip_bits (fname, 0, 0xff, gz_header_size (fname)) + else: + flip_bits (fname, 0, 0xff, tarfile.BLOCKSIZE) + + def corrupt_payload_start (_, fname, compress, encrypt): """ Modify the byte following the object header structure of the format. @@ -145,9 +160,9 @@ class RecoverTest (BaseTest): os.system("rm -rf source_dir source_dir2 backup_dir*") - def test_recover_corrupt_byte (self): + def test_recover_corrupt (self): """ - Flip a bit in a non-header byte of a backup set, then recover. + Perform various damaging actions that cause unreadable objects. Expects the extraction to fail in normal mode. With disaster recovery, extraction must succeed, and exactly one file must be missing. @@ -224,7 +239,6 @@ class RecoverTest (BaseTest): "%s/%s" % (bak_path, index_file) ]) - print("¤¤¤ failed", failed) assert len (failed) == self.FAILURES # with one file missing @@ -278,3 +292,24 @@ class RecoverCorruptHeaderGZAESTest (RecoverTest): FAILURES = 1 CORRUPT = corrupt_header + +class RecoverCorruptEntireHeaderTest (RecoverTest): + COMPRESSION = None + PASSWORD = None + FAILURES = 1 + CORRUPT = corrupt_entire_header + + +class RecoverCorruptEntireHeaderGZTest (RecoverTest): + COMPRESSION = "#gz" + PASSWORD = None + FAILURES = 1 + CORRUPT = corrupt_entire_header + + +class RecoverCorruptEntireHeaderGZAESTest (RecoverTest): + COMPRESSION = "#gz" + PASSWORD = TEST_PASSWORD + FAILURES = 1 + CORRUPT = corrupt_entire_header + -- 1.7.1