adding corner case size test
authorEduardo Robles Elvira <edulix@wadobo.com>
Wed, 26 Jun 2013 10:02:27 +0000 (12:02 +0200)
committerEduardo Robles Elvira <edulix@wadobo.com>
Wed, 26 Jun 2013 10:02:27 +0000 (12:02 +0200)
testing/test_multivol.py

index 2d4dd53..7399b72 100644 (file)
@@ -1,6 +1,6 @@
 import os, unittest, hashlib, string
 
-from deltatar.tarfile import TarFile, PAX_FORMAT, GNU_FORMAT
+from deltatar.tarfile import TarFile, PAX_FORMAT, GNU_FORMAT, BLOCKSIZE
 
 def new_volume_handler(tarobj, base_name, volume_number):
     '''
@@ -15,9 +15,24 @@ class MultivolGnuFormatTest(unittest.TestCase):
     Test multivolume support in tarfile. Tar Format is specified at class level.
     """
 
+    # used as the --format argument to tar command on tar file creation
     tar_command_format = "gnu"
+
+    # used as Tarfile.open format option argument for tar file creation
     tarfile_format = GNU_FORMAT
 
+    # overhead size used to calculate the exact maximum size of a tar file with
+    # no extra volume that stores only one file. In case of GNU format this is
+    # the size of three blocks:
+    # * 1 block used to store the header information of the stored file
+    # * 2 blocks used to mark the end of the tar file
+    tarfile_overhead = 3*BLOCKSIZE
+
+    # overhead size used to calculate the exact maximum size of a tar volume,
+    # corresponding with a multivolume tar file storing a single file. In the
+    # case of GNU format this is the same as tarfile_overhead.
+    tarvol_overhead = 3*BLOCKSIZE
+
     def tearDown(self):
         '''
         Remove temporal files created by unit tests
@@ -317,6 +332,73 @@ class MultivolGnuFormatTest(unittest.TestCase):
             assert os.path.exists(key)
             assert value == self.md5sum(key)
 
+    def test_corner_case_split_size1(self):
+        '''
+        Creates a tar file with a single file inside that contains the maximum
+        size allowed in one volume.
+        '''
+        hash = self.create_file("big", 5*1024*1024)
+
+        # create the tar file with volumes
+        tarobj = TarFile.open("sample.tar",
+                              mode="w",
+                              format=self.tarfile_format,
+                              # see tarfile_overhead description for details
+                              max_volume_size=5*1024*1024 + self.tarfile_overhead,
+                              new_volume_handler=new_volume_handler)
+        tarobj.add("big")
+        tarobj.close()
+
+        # check that the tar volumes were correctly created
+        assert os.path.exists("sample.tar")
+        assert not os.path.exists("sample.tar.1")
+
+        os.unlink("big")
+        assert not os.path.exists("big")
+
+        # extract and check output
+        tarobj = TarFile.open("sample.tar",
+                              mode="r",
+                              new_volume_handler=new_volume_handler)
+        tarobj.extractall()
+        tarobj.close()
+        assert os.path.exists("big")
+        assert hash == self.md5sum("big")
+
+
+    def test_corner_case_split_size2(self):
+        '''
+        Creates a tar file with a single file inside that contains the maximum
+        size allowed in one volume.
+        '''
+        hash = self.create_file("big", 4*1024*1024)
+
+        # create the tar file with volumes
+        tarobj = TarFile.open("sample.tar",
+                              mode="w",
+                              format=self.tarfile_format,
+                              # see tarvol_overhead description for details
+                              max_volume_size=2*1024*1024 + self.tarvol_overhead,
+                              new_volume_handler=new_volume_handler)
+        tarobj.add("big")
+        tarobj.close()
+
+        # check that the tar volumes were correctly created
+        assert os.path.exists("sample.tar")
+        assert os.path.exists("sample.tar.1")
+        assert not os.path.exists("sample.tar.2")
+
+        os.unlink("big")
+        assert not os.path.exists("big")
+
+        # extract and check output
+        tarobj = TarFile.open("sample.tar",
+                              mode="r",
+                              new_volume_handler=new_volume_handler)
+        tarobj.extractall()
+        tarobj.close()
+        assert os.path.exists("big")
+        assert hash == self.md5sum("big")
 
 class MultivolPaxFormatTest(MultivolGnuFormatTest):
     """
@@ -324,4 +406,21 @@ class MultivolPaxFormatTest(MultivolGnuFormatTest):
     """
 
     tar_command_format = "pax"
-    tarfile_format = PAX_FORMAT
\ No newline at end of file
+
+    tarfile_format = PAX_FORMAT
+
+    # overhead size used to calculate the exact maximum size of a tar file with
+    # no extra volume that stores only one file. In case of GNU format this is
+    # the size of three blocks:
+    # * 1 block used to store the header information of the stored file
+    # * 1 block used to store the header information of the pax header
+    # * 1 block used to store the pax header
+    # * 2 blocks used to mark the end of the tar file
+    tarfile_overhead = 5*BLOCKSIZE
+
+
+    # overhead size used to calculate the exact maximum size of a tar volume,
+    # corresponding with a multivolume tar file storing a single file. In the
+    # case of Pax format, it's the same as tarfile_overhead plus a block for
+    # the global header
+    tarvol_overhead = 6*BLOCKSIZE