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):
'''
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
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):
"""
"""
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