from testing.test_crypto import HeaderTest, AESGCMTest
 from testing.test_multivol import MultivolGnuFormatTest, MultivolPaxFormatTest
 from testing.test_concat_compress import ConcatCompressTest
+from testing.test_recover import RecoverTest
 from testing.test_rescue_tar import RescueTarTest
 from testing.test_encryption import EncryptionTest
 from testing.test_deltatar import (DeltaTarTest, DeltaTar2Test,
                          , DeltaTarGzipAes128ConcatTest
                          , DeltaTarAes128ConcatTest
                          , HeaderTest, AESGCMTest
+                         , RecoverTest
                          ]:
                 try:
                     t = group (n)
 
--- /dev/null
+import logging
+import os
+import shutil
+
+import deltatar.deltatar as deltatar
+
+from . import BaseTest
+
+class RecoverTest (BaseTest):
+    """
+    Disaster recovery: restore corrupt backups.
+    """
+
+    GIT_DIR = '.git'
+
+    def setUp(self):
+        '''
+        Create base test data
+        '''
+        self.pwd = os.getcwd()
+        os.system('rm -rf target_dir source_dir* backup_dir* huge')
+        os.makedirs('source_dir/test/test2')
+        self.hash = dict()
+        self.hash["source_dir/test/test2"] = ''
+        self.hash["source_dir/big"]  = self.create_file("source_dir/big", 50000)
+        self.hash["source_dir/small"]  = self.create_file("source_dir/small", 100)
+        self.hash["source_dir/test/huge"]  = self.create_file("source_dir/test/huge", 700000)
+        self.hash["source_dir/test/huge2"]  = self.create_file("source_dir/test/huge2", 800000)
+
+        self.consoleLogger = logging.StreamHandler()
+        self.consoleLogger.setLevel(logging.DEBUG)
+
+        if not os.path.isdir(self.GIT_DIR):
+            # Not running inside git tree, take our
+            # own testing directory as source.
+            self.GIT_DIR = 'testing'
+            if not os.path.isdir(self.GIT_DIR):
+                raise Exception('No input directory found: ' + self.GIT_DIR)
+
+
+    def test_recover_corrupt_byte (self):
+        """
+        Flip a bit in a non-header byte of a backup set, then recover.
+
+        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"
+
+        dtar = deltatar.DeltaTar (mode="#gz",
+                                  logger=self.consoleLogger)
+
+        self.hash = dict ()
+        os.makedirs (src_path)
+        for i in range (5):
+            f = "source_dir2/dummy_%rd" % i
+            self.hash [f] = self.create_file (f, i)
+
+        dtar.create_full_backup \
+            (source_path="source_dir2", backup_path="backup_dir")
+        shutil.rmtree (src_path)
+