PyXR

c:\python24\lib \ test \ test_tarfile.py



0001 import sys
0002 import os
0003 import shutil
0004 import tempfile
0005 
0006 import unittest
0007 import tarfile
0008 
0009 from test import test_support
0010 
0011 # Check for our compression modules.
0012 try:
0013     import gzip
0014     gzip.GzipFile
0015 except (ImportError, AttributeError):
0016     gzip = None
0017 try:
0018     import bz2
0019 except ImportError:
0020     bz2 = None
0021 
0022 def path(path):
0023     return test_support.findfile(path)
0024 
0025 testtar = path("testtar.tar")
0026 tempdir = os.path.join(tempfile.gettempdir(), "testtar" + os.extsep + "dir")
0027 tempname = test_support.TESTFN
0028 membercount = 10
0029 
0030 def tarname(comp=""):
0031     if not comp:
0032         return testtar
0033     return os.path.join(tempdir, "%s%s%s" % (testtar, os.extsep, comp))
0034 
0035 def dirname():
0036     if not os.path.exists(tempdir):
0037         os.mkdir(tempdir)
0038     return tempdir
0039 
0040 def tmpname():
0041     return tempname
0042 
0043 
0044 class BaseTest(unittest.TestCase):
0045     comp = ''
0046     mode = 'r'
0047     sep = ':'
0048 
0049     def setUp(self):
0050         mode = self.mode + self.sep + self.comp
0051         self.tar = tarfile.open(tarname(self.comp), mode)
0052 
0053     def tearDown(self):
0054         self.tar.close()
0055 
0056 class ReadTest(BaseTest):
0057 
0058     def test(self):
0059         """Test member extraction.
0060         """
0061         members = 0
0062         for tarinfo in self.tar:
0063             members += 1
0064             if not tarinfo.isreg():
0065                 continue
0066             f = self.tar.extractfile(tarinfo)
0067             self.assert_(len(f.read()) == tarinfo.size,
0068                          "size read does not match expected size")
0069             f.close()
0070 
0071         self.assert_(members == membercount,
0072                      "could not find all members")
0073 
0074     def test_sparse(self):
0075         """Test sparse member extraction.
0076         """
0077         if self.sep != "|":
0078             f1 = self.tar.extractfile("S-SPARSE")
0079             f2 = self.tar.extractfile("S-SPARSE-WITH-NULLS")
0080             self.assert_(f1.read() == f2.read(),
0081                          "_FileObject failed on sparse file member")
0082 
0083     def test_readlines(self):
0084         """Test readlines() method of _FileObject.
0085         """
0086         if self.sep != "|":
0087             filename = "0-REGTYPE-TEXT"
0088             self.tar.extract(filename, dirname())
0089             lines1 = file(os.path.join(dirname(), filename), "rU").readlines()
0090             lines2 = self.tar.extractfile(filename).readlines()
0091             self.assert_(lines1 == lines2,
0092                          "_FileObject.readline() does not work correctly")
0093 
0094     def test_seek(self):
0095         """Test seek() method of _FileObject, incl. random reading.
0096         """
0097         if self.sep != "|":
0098             filename = "0-REGTYPE"
0099             self.tar.extract(filename, dirname())
0100             data = file(os.path.join(dirname(), filename), "rb").read()
0101 
0102             tarinfo = self.tar.getmember(filename)
0103             fobj = self.tar.extractfile(tarinfo)
0104 
0105             text = fobj.read()
0106             fobj.seek(0)
0107             self.assert_(0 == fobj.tell(),
0108                          "seek() to file's start failed")
0109             fobj.seek(2048, 0)
0110             self.assert_(2048 == fobj.tell(),
0111                          "seek() to absolute position failed")
0112             fobj.seek(-1024, 1)
0113             self.assert_(1024 == fobj.tell(),
0114                          "seek() to negative relative position failed")
0115             fobj.seek(1024, 1)
0116             self.assert_(2048 == fobj.tell(),
0117                          "seek() to positive relative position failed")
0118             s = fobj.read(10)
0119             self.assert_(s == data[2048:2058],
0120                          "read() after seek failed")
0121             fobj.seek(0, 2)
0122             self.assert_(tarinfo.size == fobj.tell(),
0123                          "seek() to file's end failed")
0124             self.assert_(fobj.read() == "",
0125                          "read() at file's end did not return empty string")
0126             fobj.seek(-tarinfo.size, 2)
0127             self.assert_(0 == fobj.tell(),
0128                          "relative seek() to file's start failed")
0129             fobj.seek(512)
0130             s1 = fobj.readlines()
0131             fobj.seek(512)
0132             s2 = fobj.readlines()
0133             self.assert_(s1 == s2,
0134                          "readlines() after seek failed")
0135             fobj.close()
0136 
0137 class ReadStreamTest(ReadTest):
0138     sep = "|"
0139 
0140     def test(self):
0141         """Test member extraction, and for StreamError when
0142            seeking backwards.
0143         """
0144         ReadTest.test(self)
0145         tarinfo = self.tar.getmembers()[0]
0146         f = self.tar.extractfile(tarinfo)
0147         self.assertRaises(tarfile.StreamError, f.read)
0148 
0149     def test_stream(self):
0150         """Compare the normal tar and the stream tar.
0151         """
0152         stream = self.tar
0153         tar = tarfile.open(tarname(), 'r')
0154 
0155         while 1:
0156             t1 = tar.next()
0157             t2 = stream.next()
0158             if t1 is None:
0159                 break
0160             self.assert_(t2 is not None, "stream.next() failed.")
0161 
0162             if t2.islnk() or t2.issym():
0163                 self.assertRaises(tarfile.StreamError, stream.extractfile, t2)
0164                 continue
0165             v1 = tar.extractfile(t1)
0166             v2 = stream.extractfile(t2)
0167             if v1 is None:
0168                 continue
0169             self.assert_(v2 is not None, "stream.extractfile() failed")
0170             self.assert_(v1.read() == v2.read(), "stream extraction failed")
0171 
0172         stream.close()
0173 
0174 class WriteTest(BaseTest):
0175     mode = 'w'
0176 
0177     def setUp(self):
0178         mode = self.mode + self.sep + self.comp
0179         self.src = tarfile.open(tarname(self.comp), 'r')
0180         self.dstname = tmpname()
0181         self.dst = tarfile.open(self.dstname, mode)
0182 
0183     def tearDown(self):
0184         self.src.close()
0185         self.dst.close()
0186 
0187     def test_posix(self):
0188         self.dst.posix = 1
0189         self._test()
0190 
0191     def test_nonposix(self):
0192         self.dst.posix = 0
0193         self._test()
0194 
0195     def test_small(self):
0196         self.dst.add(os.path.join(os.path.dirname(__file__),"cfgparser.1"))
0197         self.dst.close()
0198         self.assertNotEqual(os.stat(self.dstname).st_size, 0)
0199 
0200     def _test(self):
0201         for tarinfo in self.src:
0202             if not tarinfo.isreg():
0203                 continue
0204             f = self.src.extractfile(tarinfo)
0205             if self.dst.posix and len(tarinfo.name) > tarfile.LENGTH_NAME:
0206                 self.assertRaises(ValueError, self.dst.addfile,
0207                                  tarinfo, f)
0208             else:
0209                 self.dst.addfile(tarinfo, f)
0210 
0211 class WriteStreamTest(WriteTest):
0212     sep = '|'
0213 
0214 class WriteGNULongTest(unittest.TestCase):
0215     """This testcase checks for correct creation of GNU Longname
0216        and Longlink extensions.
0217 
0218        It creates a tarfile and adds empty members with either
0219        long names, long linknames or both and compares the size
0220        of the tarfile with the expected size.
0221 
0222        It checks for SF bug #812325 in TarFile._create_gnulong().
0223 
0224        While I was writing this testcase, I noticed a second bug
0225        in the same method:
0226        Long{names,links} weren't null-terminated which lead to
0227        bad tarfiles when their length was a multiple of 512. This
0228        is tested as well.
0229     """
0230 
0231     def setUp(self):
0232         self.tar = tarfile.open(tmpname(), "w")
0233         self.tar.posix = False
0234 
0235     def tearDown(self):
0236         self.tar.close()
0237 
0238     def _length(self, s):
0239         blocks, remainder = divmod(len(s) + 1, 512)
0240         if remainder:
0241             blocks += 1
0242         return blocks * 512
0243 
0244     def _calc_size(self, name, link=None):
0245         # initial tar header
0246         count = 512
0247 
0248         if len(name) > tarfile.LENGTH_NAME:
0249             # gnu longname extended header + longname
0250             count += 512
0251             count += self._length(name)
0252 
0253         if link is not None and len(link) > tarfile.LENGTH_LINK:
0254             # gnu longlink extended header + longlink
0255             count += 512
0256             count += self._length(link)
0257 
0258         return count
0259 
0260     def _test(self, name, link=None):
0261         tarinfo = tarfile.TarInfo(name)
0262         if link:
0263             tarinfo.linkname = link
0264             tarinfo.type = tarfile.LNKTYPE
0265 
0266         self.tar.addfile(tarinfo)
0267 
0268         v1 = self._calc_size(name, link)
0269         v2 = self.tar.offset
0270         self.assertEqual(v1, v2, "GNU longname/longlink creation failed")
0271 
0272     def test_longname_1023(self):
0273         self._test(("longnam/" * 127) + "longnam")
0274 
0275     def test_longname_1024(self):
0276         self._test(("longnam/" * 127) + "longname")
0277 
0278     def test_longname_1025(self):
0279         self._test(("longnam/" * 127) + "longname_")
0280 
0281     def test_longlink_1023(self):
0282         self._test("name", ("longlnk/" * 127) + "longlnk")
0283 
0284     def test_longlink_1024(self):
0285         self._test("name", ("longlnk/" * 127) + "longlink")
0286 
0287     def test_longlink_1025(self):
0288         self._test("name", ("longlnk/" * 127) + "longlink_")
0289 
0290     def test_longnamelink_1023(self):
0291         self._test(("longnam/" * 127) + "longnam",
0292                    ("longlnk/" * 127) + "longlnk")
0293 
0294     def test_longnamelink_1024(self):
0295         self._test(("longnam/" * 127) + "longname",
0296                    ("longlnk/" * 127) + "longlink")
0297 
0298     def test_longnamelink_1025(self):
0299         self._test(("longnam/" * 127) + "longname_",
0300                    ("longlnk/" * 127) + "longlink_")
0301 
0302 class ExtractHardlinkTest(BaseTest):
0303 
0304     def test_hardlink(self):
0305         """Test hardlink extraction (bug #857297)
0306         """
0307         # Prevent errors from being caught
0308         self.tar.errorlevel = 1
0309 
0310         self.tar.extract("0-REGTYPE", dirname())
0311         try:
0312             # Extract 1-LNKTYPE which is a hardlink to 0-REGTYPE
0313             self.tar.extract("1-LNKTYPE", dirname())
0314         except EnvironmentError, e:
0315             import errno
0316             if e.errno == errno.ENOENT:
0317                 self.fail("hardlink not extracted properly")
0318 
0319 
0320 # Gzip TestCases
0321 class ReadTestGzip(ReadTest):
0322     comp = "gz"
0323 class ReadStreamTestGzip(ReadStreamTest):
0324     comp = "gz"
0325 class WriteTestGzip(WriteTest):
0326     comp = "gz"
0327 class WriteStreamTestGzip(WriteStreamTest):
0328     comp = "gz"
0329 
0330 # Filemode test cases
0331 
0332 class FileModeTest(unittest.TestCase):
0333     def test_modes(self):
0334         self.assertEqual(tarfile.filemode(0755), '-rwxr-xr-x')
0335         self.assertEqual(tarfile.filemode(07111), '---s--s--t')
0336 
0337 
0338 if bz2:
0339     # Bzip2 TestCases
0340     class ReadTestBzip2(ReadTestGzip):
0341         comp = "bz2"
0342     class ReadStreamTestBzip2(ReadStreamTestGzip):
0343         comp = "bz2"
0344     class WriteTestBzip2(WriteTest):
0345         comp = "bz2"
0346     class WriteStreamTestBzip2(WriteStreamTestGzip):
0347         comp = "bz2"
0348 
0349 # If importing gzip failed, discard the Gzip TestCases.
0350 if not gzip:
0351     del ReadTestGzip
0352     del ReadStreamTestGzip
0353     del WriteTestGzip
0354     del WriteStreamTestGzip
0355 
0356 def test_main():
0357     if gzip:
0358         # create testtar.tar.gz
0359         gzip.open(tarname("gz"), "wb").write(file(tarname(), "rb").read())
0360     if bz2:
0361         # create testtar.tar.bz2
0362         bz2.BZ2File(tarname("bz2"), "wb").write(file(tarname(), "rb").read())
0363 
0364     tests = [
0365         FileModeTest,
0366         ReadTest,
0367         ReadStreamTest,
0368         WriteTest,
0369         WriteStreamTest,
0370         WriteGNULongTest,
0371     ]
0372 
0373     if hasattr(os, "link"):
0374         tests.append(ExtractHardlinkTest)
0375 
0376     if gzip:
0377         tests.extend([
0378             ReadTestGzip, ReadStreamTestGzip,
0379             WriteTestGzip, WriteStreamTestGzip
0380         ])
0381 
0382     if bz2:
0383         tests.extend([
0384             ReadTestBzip2, ReadStreamTestBzip2,
0385             WriteTestBzip2, WriteStreamTestBzip2
0386         ])
0387     try:
0388         test_support.run_unittest(*tests)
0389     finally:
0390         if gzip:
0391             os.remove(tarname("gz"))
0392         if bz2:
0393             os.remove(tarname("bz2"))
0394         if os.path.exists(dirname()):
0395             shutil.rmtree(dirname())
0396         if os.path.exists(tmpname()):
0397             os.remove(tmpname())
0398 
0399 if __name__ == "__main__":
0400     test_main()
0401 

Generated by PyXR 0.9.4
SourceForge.net Logo