blob: 867eca42b67e459edf29af5c6deb44ce56323264 [file] [log] [blame]
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001import sys
2import os
3import shutil
Brett Cannon455ea532003-06-12 08:01:06 +00004import tempfile
Georg Brandl38c6a222006-05-10 16:26:03 +00005import StringIO
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00006
7import unittest
8import tarfile
9
10from test import test_support
11
12# Check for our compression modules.
13try:
14 import gzip
Neal Norwitzae323192003-04-14 01:18:32 +000015 gzip.GzipFile
16except (ImportError, AttributeError):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000017 gzip = None
18try:
19 import bz2
20except ImportError:
21 bz2 = None
22
23def path(path):
24 return test_support.findfile(path)
25
Brett Cannon455ea532003-06-12 08:01:06 +000026testtar = path("testtar.tar")
27tempdir = os.path.join(tempfile.gettempdir(), "testtar" + os.extsep + "dir")
28tempname = test_support.TESTFN
Georg Brandl38c6a222006-05-10 16:26:03 +000029membercount = 12
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000030
31def tarname(comp=""):
32 if not comp:
33 return testtar
Brett Cannon43e559a2003-06-12 19:16:58 +000034 return os.path.join(tempdir, "%s%s%s" % (testtar, os.extsep, comp))
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000035
36def dirname():
37 if not os.path.exists(tempdir):
38 os.mkdir(tempdir)
39 return tempdir
40
41def tmpname():
42 return tempname
43
44
45class BaseTest(unittest.TestCase):
46 comp = ''
47 mode = 'r'
48 sep = ':'
49
50 def setUp(self):
51 mode = self.mode + self.sep + self.comp
52 self.tar = tarfile.open(tarname(self.comp), mode)
53
54 def tearDown(self):
55 self.tar.close()
56
57class ReadTest(BaseTest):
58
59 def test(self):
60 """Test member extraction.
61 """
62 members = 0
63 for tarinfo in self.tar:
64 members += 1
65 if not tarinfo.isreg():
66 continue
67 f = self.tar.extractfile(tarinfo)
68 self.assert_(len(f.read()) == tarinfo.size,
69 "size read does not match expected size")
70 f.close()
71
72 self.assert_(members == membercount,
73 "could not find all members")
74
75 def test_sparse(self):
76 """Test sparse member extraction.
77 """
78 if self.sep != "|":
79 f1 = self.tar.extractfile("S-SPARSE")
Jack Jansen149a8992003-03-07 13:27:53 +000080 f2 = self.tar.extractfile("S-SPARSE-WITH-NULLS")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000081 self.assert_(f1.read() == f2.read(),
82 "_FileObject failed on sparse file member")
83
84 def test_readlines(self):
85 """Test readlines() method of _FileObject.
86 """
87 if self.sep != "|":
Jack Jansen149a8992003-03-07 13:27:53 +000088 filename = "0-REGTYPE-TEXT"
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000089 self.tar.extract(filename, dirname())
Tim Peters02494762006-05-26 14:02:05 +000090 f = open(os.path.join(dirname(), filename), "rU")
91 lines1 = f.readlines()
92 f.close()
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000093 lines2 = self.tar.extractfile(filename).readlines()
94 self.assert_(lines1 == lines2,
95 "_FileObject.readline() does not work correctly")
96
Martin v. Löwisdf241532005-03-03 08:17:42 +000097 def test_iter(self):
98 # Test iteration over ExFileObject.
99 if self.sep != "|":
100 filename = "0-REGTYPE-TEXT"
101 self.tar.extract(filename, dirname())
Tim Peters02494762006-05-26 14:02:05 +0000102 f = open(os.path.join(dirname(), filename), "rU")
103 lines1 = f.readlines()
104 f.close()
Martin v. Löwisdf241532005-03-03 08:17:42 +0000105 lines2 = [line for line in self.tar.extractfile(filename)]
106 self.assert_(lines1 == lines2,
107 "ExFileObject iteration does not work correctly")
108
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000109 def test_seek(self):
110 """Test seek() method of _FileObject, incl. random reading.
111 """
112 if self.sep != "|":
Lars Gustäbel6baa5022006-12-23 16:40:13 +0000113 filename = "0-REGTYPE-TEXT"
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000114 self.tar.extract(filename, dirname())
Tim Peters02494762006-05-26 14:02:05 +0000115 f = open(os.path.join(dirname(), filename), "rb")
116 data = f.read()
117 f.close()
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000118
119 tarinfo = self.tar.getmember(filename)
120 fobj = self.tar.extractfile(tarinfo)
121
122 text = fobj.read()
123 fobj.seek(0)
124 self.assert_(0 == fobj.tell(),
125 "seek() to file's start failed")
126 fobj.seek(2048, 0)
127 self.assert_(2048 == fobj.tell(),
128 "seek() to absolute position failed")
129 fobj.seek(-1024, 1)
130 self.assert_(1024 == fobj.tell(),
131 "seek() to negative relative position failed")
132 fobj.seek(1024, 1)
133 self.assert_(2048 == fobj.tell(),
134 "seek() to positive relative position failed")
135 s = fobj.read(10)
136 self.assert_(s == data[2048:2058],
137 "read() after seek failed")
138 fobj.seek(0, 2)
139 self.assert_(tarinfo.size == fobj.tell(),
140 "seek() to file's end failed")
141 self.assert_(fobj.read() == "",
142 "read() at file's end did not return empty string")
143 fobj.seek(-tarinfo.size, 2)
144 self.assert_(0 == fobj.tell(),
145 "relative seek() to file's start failed")
146 fobj.seek(512)
147 s1 = fobj.readlines()
148 fobj.seek(512)
149 s2 = fobj.readlines()
150 self.assert_(s1 == s2,
151 "readlines() after seek failed")
Lars Gustäbel6baa5022006-12-23 16:40:13 +0000152 fobj.seek(0)
153 self.assert_(len(fobj.readline()) == fobj.tell(),
154 "tell() after readline() failed")
155 fobj.seek(512)
156 self.assert_(len(fobj.readline()) + 512 == fobj.tell(),
157 "tell() after seek() and readline() failed")
158 fobj.seek(0)
159 line = fobj.readline()
160 self.assert_(fobj.read() == data[len(line):],
161 "read() after readline() failed")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000162 fobj.close()
163
Neal Norwitzf3396542005-10-28 05:52:22 +0000164 def test_old_dirtype(self):
165 """Test old style dirtype member (bug #1336623).
166 """
167 # Old tars create directory members using a REGTYPE
168 # header with a "/" appended to the filename field.
169
170 # Create an old tar style directory entry.
171 filename = tmpname()
172 tarinfo = tarfile.TarInfo("directory/")
173 tarinfo.type = tarfile.REGTYPE
174
Tim Petersb1f32512006-05-26 13:39:17 +0000175 fobj = open(filename, "w")
Neal Norwitzf3396542005-10-28 05:52:22 +0000176 fobj.write(tarinfo.tobuf())
177 fobj.close()
178
179 try:
180 # Test if it is still a directory entry when
181 # read back.
182 tar = tarfile.open(filename)
183 tarinfo = tar.getmembers()[0]
184 tar.close()
185
186 self.assert_(tarinfo.type == tarfile.DIRTYPE)
187 self.assert_(tarinfo.name.endswith("/"))
188 finally:
189 try:
190 os.unlink(filename)
191 except:
192 pass
193
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000194class ReadStreamTest(ReadTest):
195 sep = "|"
196
197 def test(self):
198 """Test member extraction, and for StreamError when
199 seeking backwards.
200 """
201 ReadTest.test(self)
202 tarinfo = self.tar.getmembers()[0]
203 f = self.tar.extractfile(tarinfo)
204 self.assertRaises(tarfile.StreamError, f.read)
205
206 def test_stream(self):
207 """Compare the normal tar and the stream tar.
208 """
209 stream = self.tar
210 tar = tarfile.open(tarname(), 'r')
211
212 while 1:
213 t1 = tar.next()
214 t2 = stream.next()
215 if t1 is None:
216 break
217 self.assert_(t2 is not None, "stream.next() failed.")
218
219 if t2.islnk() or t2.issym():
220 self.assertRaises(tarfile.StreamError, stream.extractfile, t2)
221 continue
222 v1 = tar.extractfile(t1)
223 v2 = stream.extractfile(t2)
224 if v1 is None:
225 continue
226 self.assert_(v2 is not None, "stream.extractfile() failed")
227 self.assert_(v1.read() == v2.read(), "stream extraction failed")
228
Tim Peters02494762006-05-26 14:02:05 +0000229 tar.close()
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000230 stream.close()
231
Georg Brandl49c8f4c2006-05-15 19:30:35 +0000232class ReadDetectTest(ReadTest):
233
234 def setUp(self):
235 self.tar = tarfile.open(tarname(self.comp), self.mode)
236
237class ReadDetectFileobjTest(ReadTest):
238
239 def setUp(self):
240 name = tarname(self.comp)
Tim Peters12087ba2006-05-15 20:44:10 +0000241 self.tar = tarfile.open(name, mode=self.mode,
242 fileobj=open(name, "rb"))
Georg Brandl49c8f4c2006-05-15 19:30:35 +0000243
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000244class ReadAsteriskTest(ReadTest):
245
246 def setUp(self):
247 mode = self.mode + self.sep + "*"
248 self.tar = tarfile.open(tarname(self.comp), mode)
249
250class ReadStreamAsteriskTest(ReadStreamTest):
251
252 def setUp(self):
253 mode = self.mode + self.sep + "*"
254 self.tar = tarfile.open(tarname(self.comp), mode)
255
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000256class WriteTest(BaseTest):
257 mode = 'w'
258
259 def setUp(self):
260 mode = self.mode + self.sep + self.comp
261 self.src = tarfile.open(tarname(self.comp), 'r')
Martin v. Löwisc234a522004-08-22 21:28:33 +0000262 self.dstname = tmpname()
263 self.dst = tarfile.open(self.dstname, mode)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000264
265 def tearDown(self):
266 self.src.close()
267 self.dst.close()
268
269 def test_posix(self):
270 self.dst.posix = 1
271 self._test()
272
273 def test_nonposix(self):
274 self.dst.posix = 0
275 self._test()
276
Martin v. Löwisc234a522004-08-22 21:28:33 +0000277 def test_small(self):
278 self.dst.add(os.path.join(os.path.dirname(__file__),"cfgparser.1"))
279 self.dst.close()
280 self.assertNotEqual(os.stat(self.dstname).st_size, 0)
281
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000282 def _test(self):
283 for tarinfo in self.src:
284 if not tarinfo.isreg():
285 continue
286 f = self.src.extractfile(tarinfo)
Georg Brandl38c6a222006-05-10 16:26:03 +0000287 if self.dst.posix and len(tarinfo.name) > tarfile.LENGTH_NAME and "/" not in tarinfo.name:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000288 self.assertRaises(ValueError, self.dst.addfile,
289 tarinfo, f)
290 else:
291 self.dst.addfile(tarinfo, f)
292
Georg Brandla32e0a02006-10-24 16:54:16 +0000293
294class Write100Test(BaseTest):
295 # The name field in a tar header stores strings of at most 100 chars.
296 # If a string is shorter than 100 chars it has to be padded with '\0',
297 # which implies that a string of exactly 100 chars is stored without
298 # a trailing '\0'.
299
300 def setUp(self):
301 self.name = "01234567890123456789012345678901234567890123456789"
302 self.name += "01234567890123456789012345678901234567890123456789"
303
304 self.tar = tarfile.open(tmpname(), "w")
305 t = tarfile.TarInfo(self.name)
306 self.tar.addfile(t)
307 self.tar.close()
308
309 self.tar = tarfile.open(tmpname())
310
311 def tearDown(self):
312 self.tar.close()
313
314 def test(self):
315 self.assertEqual(self.tar.getnames()[0], self.name,
316 "failed to store 100 char filename")
317
318
Martin v. Löwis5dbdc592005-08-27 10:07:56 +0000319class WriteSize0Test(BaseTest):
320 mode = 'w'
321
322 def setUp(self):
323 self.tmpdir = dirname()
324 self.dstname = tmpname()
325 self.dst = tarfile.open(self.dstname, "w")
326
327 def tearDown(self):
328 self.dst.close()
329
330 def test_file(self):
331 path = os.path.join(self.tmpdir, "file")
Tim Peters02494762006-05-26 14:02:05 +0000332 f = open(path, "w")
333 f.close()
Martin v. Löwis5dbdc592005-08-27 10:07:56 +0000334 tarinfo = self.dst.gettarinfo(path)
335 self.assertEqual(tarinfo.size, 0)
Tim Peters02494762006-05-26 14:02:05 +0000336 f = open(path, "w")
337 f.write("aaa")
338 f.close()
Martin v. Löwis5dbdc592005-08-27 10:07:56 +0000339 tarinfo = self.dst.gettarinfo(path)
340 self.assertEqual(tarinfo.size, 3)
341
342 def test_directory(self):
343 path = os.path.join(self.tmpdir, "directory")
Tim Peters4ccc0b72006-05-15 21:32:25 +0000344 if os.path.exists(path):
345 # This shouldn't be necessary, but is <wink> if a previous
346 # run was killed in mid-stream.
347 shutil.rmtree(path)
Martin v. Löwis5dbdc592005-08-27 10:07:56 +0000348 os.mkdir(path)
349 tarinfo = self.dst.gettarinfo(path)
350 self.assertEqual(tarinfo.size, 0)
351
352 def test_symlink(self):
353 if hasattr(os, "symlink"):
354 path = os.path.join(self.tmpdir, "symlink")
355 os.symlink("link_target", path)
356 tarinfo = self.dst.gettarinfo(path)
357 self.assertEqual(tarinfo.size, 0)
358
359
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000360class WriteStreamTest(WriteTest):
361 sep = '|'
362
Neal Norwitz8a519392006-08-21 17:59:46 +0000363 def test_padding(self):
364 self.dst.close()
365
366 if self.comp == "gz":
367 f = gzip.GzipFile(self.dstname)
368 s = f.read()
369 f.close()
370 elif self.comp == "bz2":
371 f = bz2.BZ2Decompressor()
372 s = file(self.dstname).read()
373 s = f.decompress(s)
374 self.assertEqual(len(f.unused_data), 0, "trailing data")
375 else:
376 f = file(self.dstname)
377 s = f.read()
378 f.close()
379
380 self.assertEqual(s.count("\0"), tarfile.RECORDSIZE,
381 "incorrect zero padding")
382
383
Neal Norwitz0662f8a2004-07-20 21:54:18 +0000384class WriteGNULongTest(unittest.TestCase):
385 """This testcase checks for correct creation of GNU Longname
386 and Longlink extensions.
387
388 It creates a tarfile and adds empty members with either
389 long names, long linknames or both and compares the size
390 of the tarfile with the expected size.
391
392 It checks for SF bug #812325 in TarFile._create_gnulong().
393
394 While I was writing this testcase, I noticed a second bug
395 in the same method:
396 Long{names,links} weren't null-terminated which lead to
397 bad tarfiles when their length was a multiple of 512. This
398 is tested as well.
399 """
400
Neal Norwitz0662f8a2004-07-20 21:54:18 +0000401 def _length(self, s):
402 blocks, remainder = divmod(len(s) + 1, 512)
403 if remainder:
404 blocks += 1
405 return blocks * 512
406
407 def _calc_size(self, name, link=None):
408 # initial tar header
409 count = 512
410
411 if len(name) > tarfile.LENGTH_NAME:
412 # gnu longname extended header + longname
413 count += 512
414 count += self._length(name)
415
416 if link is not None and len(link) > tarfile.LENGTH_LINK:
417 # gnu longlink extended header + longlink
418 count += 512
419 count += self._length(link)
420
421 return count
422
423 def _test(self, name, link=None):
424 tarinfo = tarfile.TarInfo(name)
425 if link:
426 tarinfo.linkname = link
427 tarinfo.type = tarfile.LNKTYPE
428
Georg Brandl87fa5592006-12-06 22:21:18 +0000429 tar = tarfile.open(tmpname(), "w")
430 tar.posix = False
431 tar.addfile(tarinfo)
Neal Norwitz0662f8a2004-07-20 21:54:18 +0000432
433 v1 = self._calc_size(name, link)
Georg Brandl87fa5592006-12-06 22:21:18 +0000434 v2 = tar.offset
Neal Norwitz0662f8a2004-07-20 21:54:18 +0000435 self.assertEqual(v1, v2, "GNU longname/longlink creation failed")
436
Georg Brandl87fa5592006-12-06 22:21:18 +0000437 tar.close()
438
439 tar = tarfile.open(tmpname())
440 member = tar.next()
441 self.failIf(member is None, "unable to read longname member")
442 self.assert_(tarinfo.name == member.name and \
443 tarinfo.linkname == member.linkname, \
444 "unable to read longname member")
445
Neal Norwitz0662f8a2004-07-20 21:54:18 +0000446 def test_longname_1023(self):
447 self._test(("longnam/" * 127) + "longnam")
448
449 def test_longname_1024(self):
450 self._test(("longnam/" * 127) + "longname")
451
452 def test_longname_1025(self):
453 self._test(("longnam/" * 127) + "longname_")
454
455 def test_longlink_1023(self):
456 self._test("name", ("longlnk/" * 127) + "longlnk")
457
458 def test_longlink_1024(self):
459 self._test("name", ("longlnk/" * 127) + "longlink")
460
461 def test_longlink_1025(self):
462 self._test("name", ("longlnk/" * 127) + "longlink_")
463
464 def test_longnamelink_1023(self):
465 self._test(("longnam/" * 127) + "longnam",
466 ("longlnk/" * 127) + "longlnk")
467
468 def test_longnamelink_1024(self):
469 self._test(("longnam/" * 127) + "longname",
470 ("longlnk/" * 127) + "longlink")
471
472 def test_longnamelink_1025(self):
473 self._test(("longnam/" * 127) + "longname_",
474 ("longlnk/" * 127) + "longlink_")
475
Georg Brandl38c6a222006-05-10 16:26:03 +0000476class ReadGNULongTest(unittest.TestCase):
477
478 def setUp(self):
479 self.tar = tarfile.open(tarname())
480
481 def tearDown(self):
482 self.tar.close()
483
484 def test_1471427(self):
485 """Test reading of longname (bug #1471427).
486 """
487 name = "test/" * 20 + "0-REGTYPE"
488 try:
489 tarinfo = self.tar.getmember(name)
490 except KeyError:
491 tarinfo = None
492 self.assert_(tarinfo is not None, "longname not found")
493 self.assert_(tarinfo.type != tarfile.DIRTYPE, "read longname as dirtype")
494
495 def test_read_name(self):
496 name = ("0-LONGNAME-" * 10)[:101]
497 try:
498 tarinfo = self.tar.getmember(name)
499 except KeyError:
500 tarinfo = None
501 self.assert_(tarinfo is not None, "longname not found")
502
503 def test_read_link(self):
504 link = ("1-LONGLINK-" * 10)[:101]
505 name = ("0-LONGNAME-" * 10)[:101]
506 try:
507 tarinfo = self.tar.getmember(link)
508 except KeyError:
509 tarinfo = None
510 self.assert_(tarinfo is not None, "longlink not found")
511 self.assert_(tarinfo.linkname == name, "linkname wrong")
512
513 def test_truncated_longname(self):
Tim Peters02494762006-05-26 14:02:05 +0000514 f = open(tarname())
515 fobj = StringIO.StringIO(f.read(1024))
516 f.close()
Georg Brandl38c6a222006-05-10 16:26:03 +0000517 tar = tarfile.open(name="foo.tar", fileobj=fobj)
518 self.assert_(len(tar.getmembers()) == 0, "")
Tim Peters02494762006-05-26 14:02:05 +0000519 tar.close()
Georg Brandl38c6a222006-05-10 16:26:03 +0000520
521
Neal Norwitza4f651a2004-07-20 22:07:44 +0000522class ExtractHardlinkTest(BaseTest):
523
524 def test_hardlink(self):
525 """Test hardlink extraction (bug #857297)
526 """
527 # Prevent errors from being caught
528 self.tar.errorlevel = 1
529
530 self.tar.extract("0-REGTYPE", dirname())
531 try:
532 # Extract 1-LNKTYPE which is a hardlink to 0-REGTYPE
533 self.tar.extract("1-LNKTYPE", dirname())
534 except EnvironmentError, e:
535 import errno
536 if e.errno == errno.ENOENT:
537 self.fail("hardlink not extracted properly")
538
Neal Norwitzb0e32e22005-10-20 04:50:13 +0000539class CreateHardlinkTest(BaseTest):
540 """Test the creation of LNKTYPE (hardlink) members in an archive.
541 In this respect tarfile.py mimics the behaviour of GNU tar: If
542 a file has a st_nlink > 1, it will be added a REGTYPE member
543 only the first time.
544 """
545
546 def setUp(self):
547 self.tar = tarfile.open(tmpname(), "w")
548
549 self.foo = os.path.join(dirname(), "foo")
550 self.bar = os.path.join(dirname(), "bar")
551
552 if os.path.exists(self.foo):
553 os.remove(self.foo)
554 if os.path.exists(self.bar):
555 os.remove(self.bar)
556
Tim Peters02494762006-05-26 14:02:05 +0000557 f = open(self.foo, "w")
558 f.write("foo")
559 f.close()
Neal Norwitzb0e32e22005-10-20 04:50:13 +0000560 self.tar.add(self.foo)
561
562 def test_add_twice(self):
563 # If st_nlink == 1 then the same file will be added as
564 # REGTYPE every time.
565 tarinfo = self.tar.gettarinfo(self.foo)
566 self.assertEqual(tarinfo.type, tarfile.REGTYPE,
567 "add file as regular failed")
568
569 def test_add_hardlink(self):
570 # If st_nlink > 1 then the same file will be added as
571 # LNKTYPE.
572 os.link(self.foo, self.bar)
573 tarinfo = self.tar.gettarinfo(self.foo)
574 self.assertEqual(tarinfo.type, tarfile.LNKTYPE,
575 "add file as hardlink failed")
576
577 tarinfo = self.tar.gettarinfo(self.bar)
578 self.assertEqual(tarinfo.type, tarfile.LNKTYPE,
579 "add file as hardlink failed")
580
581 def test_dereference_hardlink(self):
582 self.tar.dereference = True
583 os.link(self.foo, self.bar)
584 tarinfo = self.tar.gettarinfo(self.bar)
585 self.assertEqual(tarinfo.type, tarfile.REGTYPE,
586 "dereferencing hardlink failed")
587
Neal Norwitza4f651a2004-07-20 22:07:44 +0000588
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000589# Gzip TestCases
590class ReadTestGzip(ReadTest):
591 comp = "gz"
592class ReadStreamTestGzip(ReadStreamTest):
593 comp = "gz"
594class WriteTestGzip(WriteTest):
595 comp = "gz"
596class WriteStreamTestGzip(WriteStreamTest):
597 comp = "gz"
Georg Brandl49c8f4c2006-05-15 19:30:35 +0000598class ReadDetectTestGzip(ReadDetectTest):
599 comp = "gz"
600class ReadDetectFileobjTestGzip(ReadDetectFileobjTest):
601 comp = "gz"
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000602class ReadAsteriskTestGzip(ReadAsteriskTest):
603 comp = "gz"
604class ReadStreamAsteriskTestGzip(ReadStreamAsteriskTest):
605 comp = "gz"
606
Andrew M. Kuchlingd4f25522004-10-20 11:47:01 +0000607# Filemode test cases
608
609class FileModeTest(unittest.TestCase):
610 def test_modes(self):
611 self.assertEqual(tarfile.filemode(0755), '-rwxr-xr-x')
612 self.assertEqual(tarfile.filemode(07111), '---s--s--t')
613
Georg Brandlded1c4d2006-12-20 11:55:16 +0000614class HeaderErrorTest(unittest.TestCase):
615
616 def test_truncated_header(self):
617 self.assertRaises(tarfile.HeaderError, tarfile.TarInfo.frombuf, "")
618 self.assertRaises(tarfile.HeaderError, tarfile.TarInfo.frombuf, "filename\0")
619 self.assertRaises(tarfile.HeaderError, tarfile.TarInfo.frombuf, "\0" * 511)
620 self.assertRaises(tarfile.HeaderError, tarfile.TarInfo.frombuf, "\0" * 513)
621
622 def test_empty_header(self):
623 self.assertRaises(tarfile.HeaderError, tarfile.TarInfo.frombuf, "\0" * 512)
624
625 def test_invalid_header(self):
626 buf = tarfile.TarInfo("filename").tobuf()
627 buf = buf[:148] + "foo\0\0\0\0\0" + buf[156:] # invalid number field.
628 self.assertRaises(tarfile.HeaderError, tarfile.TarInfo.frombuf, buf)
629
630 def test_bad_checksum(self):
631 buf = tarfile.TarInfo("filename").tobuf()
632 b = buf[:148] + " " + buf[156:] # clear the checksum field.
633 self.assertRaises(tarfile.HeaderError, tarfile.TarInfo.frombuf, b)
634 b = "a" + buf[1:] # manipulate the buffer, so checksum won't match.
635 self.assertRaises(tarfile.HeaderError, tarfile.TarInfo.frombuf, b)
Tim Peters8ceefc52004-10-25 03:19:41 +0000636
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000637if bz2:
638 # Bzip2 TestCases
639 class ReadTestBzip2(ReadTestGzip):
640 comp = "bz2"
641 class ReadStreamTestBzip2(ReadStreamTestGzip):
642 comp = "bz2"
643 class WriteTestBzip2(WriteTest):
644 comp = "bz2"
645 class WriteStreamTestBzip2(WriteStreamTestGzip):
646 comp = "bz2"
Georg Brandl49c8f4c2006-05-15 19:30:35 +0000647 class ReadDetectTestBzip2(ReadDetectTest):
648 comp = "bz2"
649 class ReadDetectFileobjTestBzip2(ReadDetectFileobjTest):
650 comp = "bz2"
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000651 class ReadAsteriskTestBzip2(ReadAsteriskTest):
652 comp = "bz2"
653 class ReadStreamAsteriskTestBzip2(ReadStreamAsteriskTest):
654 comp = "bz2"
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000655
656# If importing gzip failed, discard the Gzip TestCases.
657if not gzip:
658 del ReadTestGzip
659 del ReadStreamTestGzip
660 del WriteTestGzip
661 del WriteStreamTestGzip
662
Neal Norwitz996acf12003-02-17 14:51:41 +0000663def test_main():
Tim Peters02494762006-05-26 14:02:05 +0000664 # Create archive.
665 f = open(tarname(), "rb")
666 fguts = f.read()
667 f.close()
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000668 if gzip:
669 # create testtar.tar.gz
Tim Peters02494762006-05-26 14:02:05 +0000670 tar = gzip.open(tarname("gz"), "wb")
671 tar.write(fguts)
672 tar.close()
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000673 if bz2:
674 # create testtar.tar.bz2
Tim Peters02494762006-05-26 14:02:05 +0000675 tar = bz2.BZ2File(tarname("bz2"), "wb")
676 tar.write(fguts)
677 tar.close()
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000678
Walter Dörwald21d3a322003-05-01 17:45:56 +0000679 tests = [
Andrew M. Kuchlingd4f25522004-10-20 11:47:01 +0000680 FileModeTest,
Georg Brandlded1c4d2006-12-20 11:55:16 +0000681 HeaderErrorTest,
Walter Dörwald21d3a322003-05-01 17:45:56 +0000682 ReadTest,
683 ReadStreamTest,
Georg Brandl49c8f4c2006-05-15 19:30:35 +0000684 ReadDetectTest,
685 ReadDetectFileobjTest,
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000686 ReadAsteriskTest,
687 ReadStreamAsteriskTest,
Walter Dörwald21d3a322003-05-01 17:45:56 +0000688 WriteTest,
Georg Brandla32e0a02006-10-24 16:54:16 +0000689 Write100Test,
Martin v. Löwis5dbdc592005-08-27 10:07:56 +0000690 WriteSize0Test,
Neal Norwitz0662f8a2004-07-20 21:54:18 +0000691 WriteStreamTest,
692 WriteGNULongTest,
Georg Brandl38c6a222006-05-10 16:26:03 +0000693 ReadGNULongTest,
Walter Dörwald21d3a322003-05-01 17:45:56 +0000694 ]
695
Neal Norwitza4f651a2004-07-20 22:07:44 +0000696 if hasattr(os, "link"):
697 tests.append(ExtractHardlinkTest)
Neal Norwitzb0e32e22005-10-20 04:50:13 +0000698 tests.append(CreateHardlinkTest)
Neal Norwitza4f651a2004-07-20 22:07:44 +0000699
Walter Dörwald21d3a322003-05-01 17:45:56 +0000700 if gzip:
701 tests.extend([
702 ReadTestGzip, ReadStreamTestGzip,
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000703 WriteTestGzip, WriteStreamTestGzip,
Georg Brandl49c8f4c2006-05-15 19:30:35 +0000704 ReadDetectTestGzip, ReadDetectFileobjTestGzip,
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000705 ReadAsteriskTestGzip, ReadStreamAsteriskTestGzip
Walter Dörwald21d3a322003-05-01 17:45:56 +0000706 ])
707
708 if bz2:
709 tests.extend([
710 ReadTestBzip2, ReadStreamTestBzip2,
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000711 WriteTestBzip2, WriteStreamTestBzip2,
Georg Brandl49c8f4c2006-05-15 19:30:35 +0000712 ReadDetectTestBzip2, ReadDetectFileobjTestBzip2,
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000713 ReadAsteriskTestBzip2, ReadStreamAsteriskTestBzip2
Walter Dörwald21d3a322003-05-01 17:45:56 +0000714 ])
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000715 try:
Walter Dörwald21d3a322003-05-01 17:45:56 +0000716 test_support.run_unittest(*tests)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000717 finally:
718 if gzip:
719 os.remove(tarname("gz"))
720 if bz2:
Tim Peters4e306172006-05-27 14:13:13 +0000721 os.remove(tarname("bz2"))
Brett Cannon455ea532003-06-12 08:01:06 +0000722 if os.path.exists(dirname()):
723 shutil.rmtree(dirname())
724 if os.path.exists(tmpname()):
725 os.remove(tmpname())
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000726
Neal Norwitz996acf12003-02-17 14:51:41 +0000727if __name__ == "__main__":
728 test_main()