implement leading garbage test
authorPhilipp Gesang <philipp.gesang@intra2net.com>
Tue, 29 Aug 2017 08:39:22 +0000 (10:39 +0200)
committerThomas Jarosch <thomas.jarosch@intra2net.com>
Mon, 2 Apr 2018 11:34:09 +0000 (13:34 +0200)
Implemented a rescue test since offsets won’t match in this
scenario.

runtests.py
testing/test_recover.py

index a11ecdd..fe313e0 100755 (executable)
@@ -35,13 +35,15 @@ from testing.test_recover import \
     , RecoverCorruptHeaderGZMultiTest \
     , RecoverCorruptHeaderGZAESSingleTest \
     , RecoverCorruptHeaderGZAESMultiTest \
-    , RecoverCorruptHeaderCTSizeGZAESTest \
+    , RescueCorruptHeaderCTSizeGZAESTest \
     , RecoverCorruptEntireHeaderSingleTest \
     , RecoverCorruptEntireHeaderMultiTest \
     , RecoverCorruptEntireHeaderGZSingleTest \
     , RecoverCorruptEntireHeaderGZMultiTest \
     , RecoverCorruptEntireHeaderGZAESSingleTest \
     , RecoverCorruptEntireHeaderGZAESMultiTest \
+    , RescueCorruptLeadingGarbageSingleTest \
+    , RescueCorruptLeadingGarbageMultiTest \
     , RecoverCorruptTrailingDataSingleTest \
     , RecoverCorruptTrailingDataMultiTest \
     , RecoverCorruptTrailingDataGZSingleTest \
@@ -107,13 +109,15 @@ if __name__ == "__main__":
                          , RecoverCorruptHeaderGZMultiTest
                          , RecoverCorruptHeaderGZAESSingleTest
                          , RecoverCorruptHeaderGZAESMultiTest
-                         , RecoverCorruptHeaderCTSizeGZAESTest
+                         , RescueCorruptHeaderCTSizeGZAESTest
                          , RecoverCorruptEntireHeaderSingleTest
                          , RecoverCorruptEntireHeaderMultiTest
                          , RecoverCorruptEntireHeaderGZSingleTest
                          , RecoverCorruptEntireHeaderGZMultiTest
                          , RecoverCorruptEntireHeaderGZAESSingleTest
                          , RecoverCorruptEntireHeaderGZAESMultiTest
+                         , RescueCorruptLeadingGarbageSingleTest
+                         , RescueCorruptLeadingGarbageMultiTest
                          , RecoverCorruptTrailingDataSingleTest
                          , RecoverCorruptTrailingDataMultiTest
                          , RecoverCorruptTrailingDataGZSingleTest
index dbf2608..a769d91 100644 (file)
@@ -146,6 +146,39 @@ def corrupt_payload_start (_, fname, compress, encrypt):
         flip_bits (fname, tarfile.BLOCKSIZE + 1)
 
 
+def corrupt_leading_garbage (_, fname, compress, encrypt):
+    """
+    Prepend junk to file.
+    """
+    aname = os.path.abspath (fname)
+    infd  = os.open (fname, os.O_RDONLY)
+    size  = os.lseek (infd, 0, os.SEEK_END)
+    assert os.lseek (infd, 0, os.SEEK_SET) == 0
+    outfd = os.open (os.path.dirname (aname), os.O_WRONLY | os.O_TMPFILE,
+                     stat.S_IRUSR | stat.S_IWUSR)
+    junk  = os.urandom (512) # tar block sized
+
+    # write new file with garbage prepended
+    done = 0
+    os.write (outfd, junk) # junk first
+    done += len (junk)
+    while done < size:
+        data = os.read (infd, TEST_BLOCKSIZE)
+        os.write (outfd, data)
+        done += len (data)
+
+    assert os.lseek (outfd, 0, os.SEEK_CUR) == done
+
+    # close and free old file
+    os.close (infd)
+    os.unlink (fname)
+
+    # install the new file in its place, atomically
+    path = "/proc/self/fd/%d" % outfd
+    os.link (path, aname, src_dir_fd=0, follow_symlinks=True)
+    os.close (outfd)
+
+
 def corrupt_trailing_data (_, fname, compress, encrypt):
     """
     Modify the byte following the object header structure of the format.
@@ -184,7 +217,6 @@ def corrupt_hole (_, fname, compress, encrypt):
     outfd = os.open (os.path.dirname (aname), os.O_WRONLY | os.O_TMPFILE,
                      stat.S_IRUSR | stat.S_IWUSR)
     
-    zeros = bytes (b'\x00' * TEST_BLOCKSIZE)
     done = 0
     while done < size:
         data = os.read (infd, TEST_BLOCKSIZE)
@@ -778,7 +810,7 @@ class RescueCorruptHoleGZAESTest (RescueCorruptHoleBaseTest):
     FAILURES    = 1
 
 
-class RecoverCorruptHeaderCTSizeGZAESTest (RescueTest):
+class RescueCorruptHeaderCTSizeGZAESTest (RescueTest):
     COMPRESSION = "#gz"
     PASSWORD    = TEST_PASSWORD
     FAILURES    = 0
@@ -786,6 +818,25 @@ class RecoverCorruptHeaderCTSizeGZAESTest (RescueTest):
     MISMATCHES  = 0
 
 
+class RescueCorruptLeadingGarbageTestBase (RescueTest):
+    # plain Tar is indifferent against traling data and the results
+    # are consistent
+    COMPRESSION = None
+    PASSWORD    = None
+    FAILURES    = 0
+    CORRUPT     = corrupt_leading_garbage
+    MISMATCHES  = 0
+
+class RescueCorruptLeadingGarbageSingleTest (RescueCorruptLeadingGarbageTestBase):
+    VOLUMES     = 1
+
+class RescueCorruptLeadingGarbageMultiTest (RescueCorruptLeadingGarbageTestBase):
+    # the last object in first archive has extra bytes somewhere in the
+    # middle because tar itself performs no data checksumming.
+    MISMATCHES  = 2
+    VOLUMES     = 3
+
+
 ###############################################################################
 # index
 ###############################################################################