]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.2/Lib/test/test_tarfile.py
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Lib / test / test_tarfile.py
CommitLineData
4710c53d 1# -*- coding: iso-8859-15 -*-\r
2\r
3import sys\r
4import os\r
5import shutil\r
6import StringIO\r
7from hashlib import md5\r
8import errno\r
9\r
10import unittest\r
11import tarfile\r
12\r
13from test import test_support\r
14\r
15# Check for our compression modules.\r
16try:\r
17 import gzip\r
18 gzip.GzipFile\r
19except (ImportError, AttributeError):\r
20 gzip = None\r
21try:\r
22 import bz2\r
23except ImportError:\r
24 bz2 = None\r
25\r
26def md5sum(data):\r
27 return md5(data).hexdigest()\r
28\r
29TEMPDIR = os.path.abspath(test_support.TESTFN)\r
30tarname = test_support.findfile("testtar.tar")\r
31gzipname = os.path.join(TEMPDIR, "testtar.tar.gz")\r
32bz2name = os.path.join(TEMPDIR, "testtar.tar.bz2")\r
33tmpname = os.path.join(TEMPDIR, "tmp.tar")\r
34\r
35md5_regtype = "65f477c818ad9e15f7feab0c6d37742f"\r
36md5_sparse = "a54fbc4ca4f4399a90e1b27164012fc6"\r
37\r
38\r
39class ReadTest(unittest.TestCase):\r
40\r
41 tarname = tarname\r
42 mode = "r:"\r
43\r
44 def setUp(self):\r
45 self.tar = tarfile.open(self.tarname, mode=self.mode, encoding="iso8859-1")\r
46\r
47 def tearDown(self):\r
48 self.tar.close()\r
49\r
50\r
51class UstarReadTest(ReadTest):\r
52\r
53 def test_fileobj_regular_file(self):\r
54 tarinfo = self.tar.getmember("ustar/regtype")\r
55 fobj = self.tar.extractfile(tarinfo)\r
56 data = fobj.read()\r
57 self.assertTrue((len(data), md5sum(data)) == (tarinfo.size, md5_regtype),\r
58 "regular file extraction failed")\r
59\r
60 def test_fileobj_readlines(self):\r
61 self.tar.extract("ustar/regtype", TEMPDIR)\r
62 tarinfo = self.tar.getmember("ustar/regtype")\r
63 fobj1 = open(os.path.join(TEMPDIR, "ustar/regtype"), "rU")\r
64 fobj2 = self.tar.extractfile(tarinfo)\r
65\r
66 lines1 = fobj1.readlines()\r
67 lines2 = fobj2.readlines()\r
68 self.assertTrue(lines1 == lines2,\r
69 "fileobj.readlines() failed")\r
70 self.assertTrue(len(lines2) == 114,\r
71 "fileobj.readlines() failed")\r
72 self.assertTrue(lines2[83] ==\r
73 "I will gladly admit that Python is not the fastest running scripting language.\n",\r
74 "fileobj.readlines() failed")\r
75\r
76 def test_fileobj_iter(self):\r
77 self.tar.extract("ustar/regtype", TEMPDIR)\r
78 tarinfo = self.tar.getmember("ustar/regtype")\r
79 fobj1 = open(os.path.join(TEMPDIR, "ustar/regtype"), "rU")\r
80 fobj2 = self.tar.extractfile(tarinfo)\r
81 lines1 = fobj1.readlines()\r
82 lines2 = [line for line in fobj2]\r
83 self.assertTrue(lines1 == lines2,\r
84 "fileobj.__iter__() failed")\r
85\r
86 def test_fileobj_seek(self):\r
87 self.tar.extract("ustar/regtype", TEMPDIR)\r
88 fobj = open(os.path.join(TEMPDIR, "ustar/regtype"), "rb")\r
89 data = fobj.read()\r
90 fobj.close()\r
91\r
92 tarinfo = self.tar.getmember("ustar/regtype")\r
93 fobj = self.tar.extractfile(tarinfo)\r
94\r
95 text = fobj.read()\r
96 fobj.seek(0)\r
97 self.assertTrue(0 == fobj.tell(),\r
98 "seek() to file's start failed")\r
99 fobj.seek(2048, 0)\r
100 self.assertTrue(2048 == fobj.tell(),\r
101 "seek() to absolute position failed")\r
102 fobj.seek(-1024, 1)\r
103 self.assertTrue(1024 == fobj.tell(),\r
104 "seek() to negative relative position failed")\r
105 fobj.seek(1024, 1)\r
106 self.assertTrue(2048 == fobj.tell(),\r
107 "seek() to positive relative position failed")\r
108 s = fobj.read(10)\r
109 self.assertTrue(s == data[2048:2058],\r
110 "read() after seek failed")\r
111 fobj.seek(0, 2)\r
112 self.assertTrue(tarinfo.size == fobj.tell(),\r
113 "seek() to file's end failed")\r
114 self.assertTrue(fobj.read() == "",\r
115 "read() at file's end did not return empty string")\r
116 fobj.seek(-tarinfo.size, 2)\r
117 self.assertTrue(0 == fobj.tell(),\r
118 "relative seek() to file's start failed")\r
119 fobj.seek(512)\r
120 s1 = fobj.readlines()\r
121 fobj.seek(512)\r
122 s2 = fobj.readlines()\r
123 self.assertTrue(s1 == s2,\r
124 "readlines() after seek failed")\r
125 fobj.seek(0)\r
126 self.assertTrue(len(fobj.readline()) == fobj.tell(),\r
127 "tell() after readline() failed")\r
128 fobj.seek(512)\r
129 self.assertTrue(len(fobj.readline()) + 512 == fobj.tell(),\r
130 "tell() after seek() and readline() failed")\r
131 fobj.seek(0)\r
132 line = fobj.readline()\r
133 self.assertTrue(fobj.read() == data[len(line):],\r
134 "read() after readline() failed")\r
135 fobj.close()\r
136\r
137 # Test if symbolic and hard links are resolved by extractfile(). The\r
138 # test link members each point to a regular member whose data is\r
139 # supposed to be exported.\r
140 def _test_fileobj_link(self, lnktype, regtype):\r
141 a = self.tar.extractfile(lnktype)\r
142 b = self.tar.extractfile(regtype)\r
143 self.assertEqual(a.name, b.name)\r
144\r
145 def test_fileobj_link1(self):\r
146 self._test_fileobj_link("ustar/lnktype", "ustar/regtype")\r
147\r
148 def test_fileobj_link2(self):\r
149 self._test_fileobj_link("./ustar/linktest2/lnktype", "ustar/linktest1/regtype")\r
150\r
151 def test_fileobj_symlink1(self):\r
152 self._test_fileobj_link("ustar/symtype", "ustar/regtype")\r
153\r
154 def test_fileobj_symlink2(self):\r
155 self._test_fileobj_link("./ustar/linktest2/symtype", "ustar/linktest1/regtype")\r
156\r
157\r
158class CommonReadTest(ReadTest):\r
159\r
160 def test_empty_tarfile(self):\r
161 # Test for issue6123: Allow opening empty archives.\r
162 # This test checks if tarfile.open() is able to open an empty tar\r
163 # archive successfully. Note that an empty tar archive is not the\r
164 # same as an empty file!\r
165 tarfile.open(tmpname, self.mode.replace("r", "w")).close()\r
166 try:\r
167 tar = tarfile.open(tmpname, self.mode)\r
168 tar.getnames()\r
169 except tarfile.ReadError:\r
170 self.fail("tarfile.open() failed on empty archive")\r
171 self.assertListEqual(tar.getmembers(), [])\r
172\r
173 def test_null_tarfile(self):\r
174 # Test for issue6123: Allow opening empty archives.\r
175 # This test guarantees that tarfile.open() does not treat an empty\r
176 # file as an empty tar archive.\r
177 open(tmpname, "wb").close()\r
178 self.assertRaises(tarfile.ReadError, tarfile.open, tmpname, self.mode)\r
179 self.assertRaises(tarfile.ReadError, tarfile.open, tmpname)\r
180\r
181 def test_ignore_zeros(self):\r
182 # Test TarFile's ignore_zeros option.\r
183 if self.mode.endswith(":gz"):\r
184 _open = gzip.GzipFile\r
185 elif self.mode.endswith(":bz2"):\r
186 _open = bz2.BZ2File\r
187 else:\r
188 _open = open\r
189\r
190 for char in ('\0', 'a'):\r
191 # Test if EOFHeaderError ('\0') and InvalidHeaderError ('a')\r
192 # are ignored correctly.\r
193 fobj = _open(tmpname, "wb")\r
194 fobj.write(char * 1024)\r
195 fobj.write(tarfile.TarInfo("foo").tobuf())\r
196 fobj.close()\r
197\r
198 tar = tarfile.open(tmpname, mode="r", ignore_zeros=True)\r
199 self.assertListEqual(tar.getnames(), ["foo"],\r
200 "ignore_zeros=True should have skipped the %r-blocks" % char)\r
201 tar.close()\r
202\r
203\r
204class MiscReadTest(CommonReadTest):\r
205\r
206 def test_no_name_argument(self):\r
207 fobj = open(self.tarname, "rb")\r
208 tar = tarfile.open(fileobj=fobj, mode=self.mode)\r
209 self.assertEqual(tar.name, os.path.abspath(fobj.name))\r
210\r
211 def test_no_name_attribute(self):\r
212 data = open(self.tarname, "rb").read()\r
213 fobj = StringIO.StringIO(data)\r
214 self.assertRaises(AttributeError, getattr, fobj, "name")\r
215 tar = tarfile.open(fileobj=fobj, mode=self.mode)\r
216 self.assertEqual(tar.name, None)\r
217\r
218 def test_empty_name_attribute(self):\r
219 data = open(self.tarname, "rb").read()\r
220 fobj = StringIO.StringIO(data)\r
221 fobj.name = ""\r
222 tar = tarfile.open(fileobj=fobj, mode=self.mode)\r
223 self.assertEqual(tar.name, None)\r
224\r
225 def test_fileobj_with_offset(self):\r
226 # Skip the first member and store values from the second member\r
227 # of the testtar.\r
228 tar = tarfile.open(self.tarname, mode=self.mode)\r
229 tar.next()\r
230 t = tar.next()\r
231 name = t.name\r
232 offset = t.offset\r
233 data = tar.extractfile(t).read()\r
234 tar.close()\r
235\r
236 # Open the testtar and seek to the offset of the second member.\r
237 if self.mode.endswith(":gz"):\r
238 _open = gzip.GzipFile\r
239 elif self.mode.endswith(":bz2"):\r
240 _open = bz2.BZ2File\r
241 else:\r
242 _open = open\r
243 fobj = _open(self.tarname, "rb")\r
244 fobj.seek(offset)\r
245\r
246 # Test if the tarfile starts with the second member.\r
247 tar = tar.open(self.tarname, mode="r:", fileobj=fobj)\r
248 t = tar.next()\r
249 self.assertEqual(t.name, name)\r
250 # Read to the end of fileobj and test if seeking back to the\r
251 # beginning works.\r
252 tar.getmembers()\r
253 self.assertEqual(tar.extractfile(t).read(), data,\r
254 "seek back did not work")\r
255 tar.close()\r
256\r
257 def test_fail_comp(self):\r
258 # For Gzip and Bz2 Tests: fail with a ReadError on an uncompressed file.\r
259 if self.mode == "r:":\r
260 return\r
261 self.assertRaises(tarfile.ReadError, tarfile.open, tarname, self.mode)\r
262 fobj = open(tarname, "rb")\r
263 self.assertRaises(tarfile.ReadError, tarfile.open, fileobj=fobj, mode=self.mode)\r
264\r
265 def test_v7_dirtype(self):\r
266 # Test old style dirtype member (bug #1336623):\r
267 # Old V7 tars create directory members using an AREGTYPE\r
268 # header with a "/" appended to the filename field.\r
269 tarinfo = self.tar.getmember("misc/dirtype-old-v7")\r
270 self.assertTrue(tarinfo.type == tarfile.DIRTYPE,\r
271 "v7 dirtype failed")\r
272\r
273 def test_xstar_type(self):\r
274 # The xstar format stores extra atime and ctime fields inside the\r
275 # space reserved for the prefix field. The prefix field must be\r
276 # ignored in this case, otherwise it will mess up the name.\r
277 try:\r
278 self.tar.getmember("misc/regtype-xstar")\r
279 except KeyError:\r
280 self.fail("failed to find misc/regtype-xstar (mangled prefix?)")\r
281\r
282 def test_check_members(self):\r
283 for tarinfo in self.tar:\r
284 self.assertTrue(int(tarinfo.mtime) == 07606136617,\r
285 "wrong mtime for %s" % tarinfo.name)\r
286 if not tarinfo.name.startswith("ustar/"):\r
287 continue\r
288 self.assertTrue(tarinfo.uname == "tarfile",\r
289 "wrong uname for %s" % tarinfo.name)\r
290\r
291 def test_find_members(self):\r
292 self.assertTrue(self.tar.getmembers()[-1].name == "misc/eof",\r
293 "could not find all members")\r
294\r
295 def test_extract_hardlink(self):\r
296 # Test hardlink extraction (e.g. bug #857297).\r
297 tar = tarfile.open(tarname, errorlevel=1, encoding="iso8859-1")\r
298\r
299 tar.extract("ustar/regtype", TEMPDIR)\r
300 try:\r
301 tar.extract("ustar/lnktype", TEMPDIR)\r
302 except EnvironmentError, e:\r
303 if e.errno == errno.ENOENT:\r
304 self.fail("hardlink not extracted properly")\r
305\r
306 data = open(os.path.join(TEMPDIR, "ustar/lnktype"), "rb").read()\r
307 self.assertEqual(md5sum(data), md5_regtype)\r
308\r
309 try:\r
310 tar.extract("ustar/symtype", TEMPDIR)\r
311 except EnvironmentError, e:\r
312 if e.errno == errno.ENOENT:\r
313 self.fail("symlink not extracted properly")\r
314\r
315 data = open(os.path.join(TEMPDIR, "ustar/symtype"), "rb").read()\r
316 self.assertEqual(md5sum(data), md5_regtype)\r
317\r
318 def test_extractall(self):\r
319 # Test if extractall() correctly restores directory permissions\r
320 # and times (see issue1735).\r
321 tar = tarfile.open(tarname, encoding="iso8859-1")\r
322 directories = [t for t in tar if t.isdir()]\r
323 tar.extractall(TEMPDIR, directories)\r
324 for tarinfo in directories:\r
325 path = os.path.join(TEMPDIR, tarinfo.name)\r
326 if sys.platform != "win32":\r
327 # Win32 has no support for fine grained permissions.\r
328 self.assertEqual(tarinfo.mode & 0777, os.stat(path).st_mode & 0777)\r
329 self.assertEqual(tarinfo.mtime, os.path.getmtime(path))\r
330 tar.close()\r
331\r
332 def test_init_close_fobj(self):\r
333 # Issue #7341: Close the internal file object in the TarFile\r
334 # constructor in case of an error. For the test we rely on\r
335 # the fact that opening an empty file raises a ReadError.\r
336 empty = os.path.join(TEMPDIR, "empty")\r
337 open(empty, "wb").write("")\r
338\r
339 try:\r
340 tar = object.__new__(tarfile.TarFile)\r
341 try:\r
342 tar.__init__(empty)\r
343 except tarfile.ReadError:\r
344 self.assertTrue(tar.fileobj.closed)\r
345 else:\r
346 self.fail("ReadError not raised")\r
347 finally:\r
348 os.remove(empty)\r
349\r
350\r
351class StreamReadTest(CommonReadTest):\r
352\r
353 mode="r|"\r
354\r
355 def test_fileobj_regular_file(self):\r
356 tarinfo = self.tar.next() # get "regtype" (can't use getmember)\r
357 fobj = self.tar.extractfile(tarinfo)\r
358 data = fobj.read()\r
359 self.assertTrue((len(data), md5sum(data)) == (tarinfo.size, md5_regtype),\r
360 "regular file extraction failed")\r
361\r
362 def test_provoke_stream_error(self):\r
363 tarinfos = self.tar.getmembers()\r
364 f = self.tar.extractfile(tarinfos[0]) # read the first member\r
365 self.assertRaises(tarfile.StreamError, f.read)\r
366\r
367 def test_compare_members(self):\r
368 tar1 = tarfile.open(tarname, encoding="iso8859-1")\r
369 tar2 = self.tar\r
370\r
371 while True:\r
372 t1 = tar1.next()\r
373 t2 = tar2.next()\r
374 if t1 is None:\r
375 break\r
376 self.assertTrue(t2 is not None, "stream.next() failed.")\r
377\r
378 if t2.islnk() or t2.issym():\r
379 self.assertRaises(tarfile.StreamError, tar2.extractfile, t2)\r
380 continue\r
381\r
382 v1 = tar1.extractfile(t1)\r
383 v2 = tar2.extractfile(t2)\r
384 if v1 is None:\r
385 continue\r
386 self.assertTrue(v2 is not None, "stream.extractfile() failed")\r
387 self.assertTrue(v1.read() == v2.read(), "stream extraction failed")\r
388\r
389 tar1.close()\r
390\r
391\r
392class DetectReadTest(unittest.TestCase):\r
393\r
394 def _testfunc_file(self, name, mode):\r
395 try:\r
396 tarfile.open(name, mode)\r
397 except tarfile.ReadError:\r
398 self.fail()\r
399\r
400 def _testfunc_fileobj(self, name, mode):\r
401 try:\r
402 tarfile.open(name, mode, fileobj=open(name, "rb"))\r
403 except tarfile.ReadError:\r
404 self.fail()\r
405\r
406 def _test_modes(self, testfunc):\r
407 testfunc(tarname, "r")\r
408 testfunc(tarname, "r:")\r
409 testfunc(tarname, "r:*")\r
410 testfunc(tarname, "r|")\r
411 testfunc(tarname, "r|*")\r
412\r
413 if gzip:\r
414 self.assertRaises(tarfile.ReadError, tarfile.open, tarname, mode="r:gz")\r
415 self.assertRaises(tarfile.ReadError, tarfile.open, tarname, mode="r|gz")\r
416 self.assertRaises(tarfile.ReadError, tarfile.open, gzipname, mode="r:")\r
417 self.assertRaises(tarfile.ReadError, tarfile.open, gzipname, mode="r|")\r
418\r
419 testfunc(gzipname, "r")\r
420 testfunc(gzipname, "r:*")\r
421 testfunc(gzipname, "r:gz")\r
422 testfunc(gzipname, "r|*")\r
423 testfunc(gzipname, "r|gz")\r
424\r
425 if bz2:\r
426 self.assertRaises(tarfile.ReadError, tarfile.open, tarname, mode="r:bz2")\r
427 self.assertRaises(tarfile.ReadError, tarfile.open, tarname, mode="r|bz2")\r
428 self.assertRaises(tarfile.ReadError, tarfile.open, bz2name, mode="r:")\r
429 self.assertRaises(tarfile.ReadError, tarfile.open, bz2name, mode="r|")\r
430\r
431 testfunc(bz2name, "r")\r
432 testfunc(bz2name, "r:*")\r
433 testfunc(bz2name, "r:bz2")\r
434 testfunc(bz2name, "r|*")\r
435 testfunc(bz2name, "r|bz2")\r
436\r
437 def test_detect_file(self):\r
438 self._test_modes(self._testfunc_file)\r
439\r
440 def test_detect_fileobj(self):\r
441 self._test_modes(self._testfunc_fileobj)\r
442\r
443\r
444class MemberReadTest(ReadTest):\r
445\r
446 def _test_member(self, tarinfo, chksum=None, **kwargs):\r
447 if chksum is not None:\r
448 self.assertTrue(md5sum(self.tar.extractfile(tarinfo).read()) == chksum,\r
449 "wrong md5sum for %s" % tarinfo.name)\r
450\r
451 kwargs["mtime"] = 07606136617\r
452 kwargs["uid"] = 1000\r
453 kwargs["gid"] = 100\r
454 if "old-v7" not in tarinfo.name:\r
455 # V7 tar can't handle alphabetic owners.\r
456 kwargs["uname"] = "tarfile"\r
457 kwargs["gname"] = "tarfile"\r
458 for k, v in kwargs.iteritems():\r
459 self.assertTrue(getattr(tarinfo, k) == v,\r
460 "wrong value in %s field of %s" % (k, tarinfo.name))\r
461\r
462 def test_find_regtype(self):\r
463 tarinfo = self.tar.getmember("ustar/regtype")\r
464 self._test_member(tarinfo, size=7011, chksum=md5_regtype)\r
465\r
466 def test_find_conttype(self):\r
467 tarinfo = self.tar.getmember("ustar/conttype")\r
468 self._test_member(tarinfo, size=7011, chksum=md5_regtype)\r
469\r
470 def test_find_dirtype(self):\r
471 tarinfo = self.tar.getmember("ustar/dirtype")\r
472 self._test_member(tarinfo, size=0)\r
473\r
474 def test_find_dirtype_with_size(self):\r
475 tarinfo = self.tar.getmember("ustar/dirtype-with-size")\r
476 self._test_member(tarinfo, size=255)\r
477\r
478 def test_find_lnktype(self):\r
479 tarinfo = self.tar.getmember("ustar/lnktype")\r
480 self._test_member(tarinfo, size=0, linkname="ustar/regtype")\r
481\r
482 def test_find_symtype(self):\r
483 tarinfo = self.tar.getmember("ustar/symtype")\r
484 self._test_member(tarinfo, size=0, linkname="regtype")\r
485\r
486 def test_find_blktype(self):\r
487 tarinfo = self.tar.getmember("ustar/blktype")\r
488 self._test_member(tarinfo, size=0, devmajor=3, devminor=0)\r
489\r
490 def test_find_chrtype(self):\r
491 tarinfo = self.tar.getmember("ustar/chrtype")\r
492 self._test_member(tarinfo, size=0, devmajor=1, devminor=3)\r
493\r
494 def test_find_fifotype(self):\r
495 tarinfo = self.tar.getmember("ustar/fifotype")\r
496 self._test_member(tarinfo, size=0)\r
497\r
498 def test_find_sparse(self):\r
499 tarinfo = self.tar.getmember("ustar/sparse")\r
500 self._test_member(tarinfo, size=86016, chksum=md5_sparse)\r
501\r
502 def test_find_umlauts(self):\r
503