blob: f3c090d4cbba1998d2c6f6c610f8b8280523bc66 [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äbelaedb92e2006-12-23 16:51:47 +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äbelaedb92e2006-12-23 16:51:47 +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
Lars Gustäbeld2201442007-04-20 14:49:02 +0000194 def test_dirtype(self):
195 for tarinfo in self.tar:
196 if tarinfo.isdir():
197 self.assert_(tarinfo.name.endswith("/"))
198 self.assert_(not tarinfo.name[:-1].endswith("/"))
199
200
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000201class ReadStreamTest(ReadTest):
202 sep = "|"
203
204 def test(self):
205 """Test member extraction, and for StreamError when
206 seeking backwards.
207 """
208 ReadTest.test(self)
209 tarinfo = self.tar.getmembers()[0]
210 f = self.tar.extractfile(tarinfo)
211 self.assertRaises(tarfile.StreamError, f.read)
212
213 def test_stream(self):
214 """Compare the normal tar and the stream tar.
215 """
216 stream = self.tar
217 tar = tarfile.open(tarname(), 'r')
218
219 while 1:
220 t1 = tar.next()
221 t2 = stream.next()
222 if t1 is None:
223 break
224 self.assert_(t2 is not None, "stream.next() failed.")
225
226 if t2.islnk() or t2.issym():
227 self.assertRaises(tarfile.StreamError, stream.extractfile, t2)
228 continue
229 v1 = tar.extractfile(t1)
230 v2 = stream.extractfile(t2)
231 if v1 is None:
232 continue
233 self.assert_(v2 is not None, "stream.extractfile() failed")
234 self.assert_(v1.read() == v2.read(), "stream extraction failed")
235
Tim Peters02494762006-05-26 14:02:05 +0000236 tar.close()
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000237 stream.close()
238
Georg Brandl49c8f4c2006-05-15 19:30:35 +0000239class ReadDetectTest(ReadTest):
240
241 def setUp(self):
242 self.tar = tarfile.open(tarname(self.comp), self.mode)
243
244class ReadDetectFileobjTest(ReadTest):
245
246 def setUp(self):
247 name = tarname(self.comp)
Tim Peters12087ba2006-05-15 20:44:10 +0000248 self.tar = tarfile.open(name, mode=self.mode,
249 fileobj=open(name, "rb"))
Georg Brandl49c8f4c2006-05-15 19:30:35 +0000250
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000251class ReadAsteriskTest(ReadTest):
252
253 def setUp(self):
254 mode = self.mode + self.sep + "*"
255 self.tar = tarfile.open(tarname(self.comp), mode)
256
257class ReadStreamAsteriskTest(ReadStreamTest):
258
259 def setUp(self):
260 mode = self.mode + self.sep + "*"
261 self.tar = tarfile.open(tarname(self.comp), mode)
262
Lars Gustäbel7cc9c8b2007-12-01 21:06:06 +0000263class ReadFileobjTest(BaseTest):
264
265 def test_fileobj_with_offset(self):
266 # Skip the first member and store values from the second member
267 # of the testtar.
268 self.tar.next()
269 t = self.tar.next()
270 name = t.name
271 offset = t.offset
272 data = self.tar.extractfile(t).read()
273 self.tar.close()
274
275 # Open the testtar and seek to the offset of the second member.
276 if self.comp == "gz":
277 _open = gzip.GzipFile
278 elif self.comp == "bz2":
279 _open = bz2.BZ2File
280 else:
281 _open = open
282 fobj = _open(tarname(self.comp), "rb")
283 fobj.seek(offset)
284
285 # Test if the tarfile starts with the second member.
286 self.tar = tarfile.open(tarname(self.comp), "r:", fileobj=fobj)
287 t = self.tar.next()
288 self.assertEqual(t.name, name)
289 # Read to the end of fileobj and test if seeking back to the
290 # beginning works.
291 self.tar.getmembers()
292 self.assertEqual(self.tar.extractfile(t).read(), data,
293 "seek back did not work")
294
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000295class WriteTest(BaseTest):
296 mode = 'w'
297
298 def setUp(self):
299 mode = self.mode + self.sep + self.comp
300 self.src = tarfile.open(tarname(self.comp), 'r')
Martin v. Löwisc234a522004-08-22 21:28:33 +0000301 self.dstname = tmpname()
302 self.dst = tarfile.open(self.dstname, mode)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000303
304 def tearDown(self):
305 self.src.close()
306 self.dst.close()
307
308 def test_posix(self):
309 self.dst.posix = 1
310 self._test()
311
312 def test_nonposix(self):
313 self.dst.posix = 0
314 self._test()
315
Martin v. Löwisc234a522004-08-22 21:28:33 +0000316 def test_small(self):
317 self.dst.add(os.path.join(os.path.dirname(__file__),"cfgparser.1"))
318 self.dst.close()
319 self.assertNotEqual(os.stat(self.dstname).st_size, 0)
320
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000321 def _test(self):
322 for tarinfo in self.src:
323 if not tarinfo.isreg():
324 continue
325 f = self.src.extractfile(tarinfo)
Georg Brandl38c6a222006-05-10 16:26:03 +0000326 if self.dst.posix and len(tarinfo.name) > tarfile.LENGTH_NAME and "/" not in tarinfo.name:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000327 self.assertRaises(ValueError, self.dst.addfile,
328 tarinfo, f)
329 else:
330 self.dst.addfile(tarinfo, f)
331
Lars Gustäbel12e087a2006-12-23 18:13:57 +0000332 def test_add_self(self):
333 dstname = os.path.abspath(self.dstname)
334
335 self.assertEqual(self.dst.name, dstname, "archive name must be absolute")
336
337 self.dst.add(dstname)
338 self.assertEqual(self.dst.getnames(), [], "added the archive to itself")
339
340 cwd = os.getcwd()
341 os.chdir(dirname())
342 self.dst.add(dstname)
343 os.chdir(cwd)
344 self.assertEqual(self.dst.getnames(), [], "added the archive to itself")
345
Georg Brandlee23f4b2006-10-24 16:54:23 +0000346
347class Write100Test(BaseTest):
348 # The name field in a tar header stores strings of at most 100 chars.
349 # If a string is shorter than 100 chars it has to be padded with '\0',
350 # which implies that a string of exactly 100 chars is stored without
351 # a trailing '\0'.
352
353 def setUp(self):
354 self.name = "01234567890123456789012345678901234567890123456789"
355 self.name += "01234567890123456789012345678901234567890123456789"
356
357 self.tar = tarfile.open(tmpname(), "w")
358 t = tarfile.TarInfo(self.name)
359 self.tar.addfile(t)
360 self.tar.close()
361
362 self.tar = tarfile.open(tmpname())
363
364 def tearDown(self):
365 self.tar.close()
366
367 def test(self):
368 self.assertEqual(self.tar.getnames()[0], self.name,
369 "failed to store 100 char filename")
370
371
Martin v. Löwis5dbdc592005-08-27 10:07:56 +0000372class WriteSize0Test(BaseTest):
373 mode = 'w'
374
375 def setUp(self):
376 self.tmpdir = dirname()
377 self.dstname = tmpname()
378 self.dst = tarfile.open(self.dstname, "w")
379
380 def tearDown(self):
381 self.dst.close()
382
383 def test_file(self):
384 path = os.path.join(self.tmpdir, "file")
Tim Peters02494762006-05-26 14:02:05 +0000385 f = open(path, "w")
386 f.close()
Martin v. Löwis5dbdc592005-08-27 10:07:56 +0000387 tarinfo = self.dst.gettarinfo(path)
388 self.assertEqual(tarinfo.size, 0)
Tim Peters02494762006-05-26 14:02:05 +0000389 f = open(path, "w")
390 f.write("aaa")
391 f.close()
Martin v. Löwis5dbdc592005-08-27 10:07:56 +0000392 tarinfo = self.dst.gettarinfo(path)
393 self.assertEqual(tarinfo.size, 3)
394
395 def test_directory(self):
396 path = os.path.join(self.tmpdir, "directory")
Tim Peters4ccc0b72006-05-15 21:32:25 +0000397 if os.path.exists(path):
398 # This shouldn't be necessary, but is <wink> if a previous
399 # run was killed in mid-stream.
400 shutil.rmtree(path)
Martin v. Löwis5dbdc592005-08-27 10:07:56 +0000401 os.mkdir(path)
402 tarinfo = self.dst.gettarinfo(path)
403 self.assertEqual(tarinfo.size, 0)
404
405 def test_symlink(self):
406 if hasattr(os, "symlink"):
407 path = os.path.join(self.tmpdir, "symlink")
408 os.symlink("link_target", path)
409 tarinfo = self.dst.gettarinfo(path)
410 self.assertEqual(tarinfo.size, 0)
411
412
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000413class WriteStreamTest(WriteTest):
414 sep = '|'
415
Neal Norwitz7443b802006-08-21 18:43:51 +0000416 def test_padding(self):
417 self.dst.close()
418
419 if self.comp == "gz":
420 f = gzip.GzipFile(self.dstname)
421 s = f.read()
422 f.close()
423 elif self.comp == "bz2":
424 f = bz2.BZ2Decompressor()
425 s = file(self.dstname).read()
426 s = f.decompress(s)
427 self.assertEqual(len(f.unused_data), 0, "trailing data")
428 else:
429 f = file(self.dstname)
430 s = f.read()
431 f.close()
432
433 self.assertEqual(s.count("\0"), tarfile.RECORDSIZE,
434 "incorrect zero padding")
435
436
Neal Norwitz0662f8a2004-07-20 21:54:18 +0000437class WriteGNULongTest(unittest.TestCase):
438 """This testcase checks for correct creation of GNU Longname
439 and Longlink extensions.
440
441 It creates a tarfile and adds empty members with either
442 long names, long linknames or both and compares the size
443 of the tarfile with the expected size.
444
445 It checks for SF bug #812325 in TarFile._create_gnulong().
446
447 While I was writing this testcase, I noticed a second bug
448 in the same method:
449 Long{names,links} weren't null-terminated which lead to
450 bad tarfiles when their length was a multiple of 512. This
451 is tested as well.
452 """
453
Neal Norwitz0662f8a2004-07-20 21:54:18 +0000454 def _length(self, s):
455 blocks, remainder = divmod(len(s) + 1, 512)
456 if remainder:
457 blocks += 1
458 return blocks * 512
459
460 def _calc_size(self, name, link=None):
461 # initial tar header
462 count = 512
463
464 if len(name) > tarfile.LENGTH_NAME:
465 # gnu longname extended header + longname
466 count += 512
467 count += self._length(name)
468
469 if link is not None and len(link) > tarfile.LENGTH_LINK:
470 # gnu longlink extended header + longlink
471 count += 512
472 count += self._length(link)
473
474 return count
475
476 def _test(self, name, link=None):
477 tarinfo = tarfile.TarInfo(name)
478 if link:
479 tarinfo.linkname = link
480 tarinfo.type = tarfile.LNKTYPE
481
Georg Brandl25f58f62006-12-06 22:21:23 +0000482 tar = tarfile.open(tmpname(), "w")
483 tar.posix = False
484 tar.addfile(tarinfo)
Neal Norwitz0662f8a2004-07-20 21:54:18 +0000485
486 v1 = self._calc_size(name, link)
Georg Brandl25f58f62006-12-06 22:21:23 +0000487 v2 = tar.offset
Neal Norwitz0662f8a2004-07-20 21:54:18 +0000488 self.assertEqual(v1, v2, "GNU longname/longlink creation failed")
489
Georg Brandl25f58f62006-12-06 22:21:23 +0000490 tar.close()
491
492 tar = tarfile.open(tmpname())
493 member = tar.next()
494 self.failIf(member is None, "unable to read longname member")
495 self.assert_(tarinfo.name == member.name and \
496 tarinfo.linkname == member.linkname, \
497 "unable to read longname member")
498
Neal Norwitz0662f8a2004-07-20 21:54:18 +0000499 def test_longname_1023(self):
500 self._test(("longnam/" * 127) + "longnam")
501
502 def test_longname_1024(self):
503 self._test(("longnam/" * 127) + "longname")
504
505 def test_longname_1025(self):
506 self._test(("longnam/" * 127) + "longname_")
507
508 def test_longlink_1023(self):
509 self._test("name", ("longlnk/" * 127) + "longlnk")
510
511 def test_longlink_1024(self):
512 self._test("name", ("longlnk/" * 127) + "longlink")
513
514 def test_longlink_1025(self):
515 self._test("name", ("longlnk/" * 127) + "longlink_")
516
517 def test_longnamelink_1023(self):
518 self._test(("longnam/" * 127) + "longnam",
519 ("longlnk/" * 127) + "longlnk")
520
521 def test_longnamelink_1024(self):
522 self._test(("longnam/" * 127) + "longname",
523 ("longlnk/" * 127) + "longlink")
524
525 def test_longnamelink_1025(self):
526 self._test(("longnam/" * 127) + "longname_",
527 ("longlnk/" * 127) + "longlink_")
528
Georg Brandl38c6a222006-05-10 16:26:03 +0000529class ReadGNULongTest(unittest.TestCase):
530
531 def setUp(self):
532 self.tar = tarfile.open(tarname())
533
534 def tearDown(self):
535 self.tar.close()
536
537 def test_1471427(self):
538 """Test reading of longname (bug #1471427).
539 """
540 name = "test/" * 20 + "0-REGTYPE"
541 try:
542 tarinfo = self.tar.getmember(name)
543 except KeyError:
544 tarinfo = None
545 self.assert_(tarinfo is not None, "longname not found")
546 self.assert_(tarinfo.type != tarfile.DIRTYPE, "read longname as dirtype")
547
548 def test_read_name(self):
549 name = ("0-LONGNAME-" * 10)[:101]
550 try:
551 tarinfo = self.tar.getmember(name)
552 except KeyError:
553 tarinfo = None
554 self.assert_(tarinfo is not None, "longname not found")
555
556 def test_read_link(self):
557 link = ("1-LONGLINK-" * 10)[:101]
558 name = ("0-LONGNAME-" * 10)[:101]
559 try:
560 tarinfo = self.tar.getmember(link)
561 except KeyError:
562 tarinfo = None
563 self.assert_(tarinfo is not None, "longlink not found")
564 self.assert_(tarinfo.linkname == name, "linkname wrong")
565
566 def test_truncated_longname(self):
Tim Peters02494762006-05-26 14:02:05 +0000567 f = open(tarname())
568 fobj = StringIO.StringIO(f.read(1024))
569 f.close()
Georg Brandl38c6a222006-05-10 16:26:03 +0000570 tar = tarfile.open(name="foo.tar", fileobj=fobj)
571 self.assert_(len(tar.getmembers()) == 0, "")
Tim Peters02494762006-05-26 14:02:05 +0000572 tar.close()
Georg Brandl38c6a222006-05-10 16:26:03 +0000573
574
Neal Norwitza4f651a2004-07-20 22:07:44 +0000575class ExtractHardlinkTest(BaseTest):
576
577 def test_hardlink(self):
578 """Test hardlink extraction (bug #857297)
579 """
580 # Prevent errors from being caught
581 self.tar.errorlevel = 1
582
583 self.tar.extract("0-REGTYPE", dirname())
584 try:
585 # Extract 1-LNKTYPE which is a hardlink to 0-REGTYPE
586 self.tar.extract("1-LNKTYPE", dirname())
587 except EnvironmentError, e:
588 import errno
589 if e.errno == errno.ENOENT:
590 self.fail("hardlink not extracted properly")
591
Neal Norwitzb0e32e22005-10-20 04:50:13 +0000592class CreateHardlinkTest(BaseTest):
593 """Test the creation of LNKTYPE (hardlink) members in an archive.
594 In this respect tarfile.py mimics the behaviour of GNU tar: If
595 a file has a st_nlink > 1, it will be added a REGTYPE member
596 only the first time.
597 """
598
599 def setUp(self):
600 self.tar = tarfile.open(tmpname(), "w")
601
602 self.foo = os.path.join(dirname(), "foo")
603 self.bar = os.path.join(dirname(), "bar")
604
605 if os.path.exists(self.foo):
606 os.remove(self.foo)
607 if os.path.exists(self.bar):
608 os.remove(self.bar)
609
Tim Peters02494762006-05-26 14:02:05 +0000610 f = open(self.foo, "w")
611 f.write("foo")
612 f.close()
Neal Norwitzb0e32e22005-10-20 04:50:13 +0000613 self.tar.add(self.foo)
614
615 def test_add_twice(self):
616 # If st_nlink == 1 then the same file will be added as
617 # REGTYPE every time.
618 tarinfo = self.tar.gettarinfo(self.foo)
619 self.assertEqual(tarinfo.type, tarfile.REGTYPE,
620 "add file as regular failed")
621
622 def test_add_hardlink(self):
623 # If st_nlink > 1 then the same file will be added as
624 # LNKTYPE.
625 os.link(self.foo, self.bar)
626 tarinfo = self.tar.gettarinfo(self.foo)
627 self.assertEqual(tarinfo.type, tarfile.LNKTYPE,
628 "add file as hardlink failed")
629
630 tarinfo = self.tar.gettarinfo(self.bar)
631 self.assertEqual(tarinfo.type, tarfile.LNKTYPE,
632 "add file as hardlink failed")
633
634 def test_dereference_hardlink(self):
635 self.tar.dereference = True
636 os.link(self.foo, self.bar)
637 tarinfo = self.tar.gettarinfo(self.bar)
638 self.assertEqual(tarinfo.type, tarfile.REGTYPE,
639 "dereferencing hardlink failed")
640
Neal Norwitza4f651a2004-07-20 22:07:44 +0000641
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000642# Gzip TestCases
643class ReadTestGzip(ReadTest):
644 comp = "gz"
645class ReadStreamTestGzip(ReadStreamTest):
646 comp = "gz"
647class WriteTestGzip(WriteTest):
648 comp = "gz"
649class WriteStreamTestGzip(WriteStreamTest):
650 comp = "gz"
Georg Brandl49c8f4c2006-05-15 19:30:35 +0000651class ReadDetectTestGzip(ReadDetectTest):
652 comp = "gz"
653class ReadDetectFileobjTestGzip(ReadDetectFileobjTest):
654 comp = "gz"
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000655class ReadAsteriskTestGzip(ReadAsteriskTest):
656 comp = "gz"
657class ReadStreamAsteriskTestGzip(ReadStreamAsteriskTest):
658 comp = "gz"
Lars Gustäbel7cc9c8b2007-12-01 21:06:06 +0000659class ReadFileobjTestGzip(ReadFileobjTest):
660 comp = "gz"
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000661
Andrew M. Kuchlingd4f25522004-10-20 11:47:01 +0000662# Filemode test cases
663
664class FileModeTest(unittest.TestCase):
665 def test_modes(self):
666 self.assertEqual(tarfile.filemode(0755), '-rwxr-xr-x')
667 self.assertEqual(tarfile.filemode(07111), '---s--s--t')
668
Lars Gustäbelf9a2c632006-12-27 10:36:58 +0000669class OpenFileobjTest(BaseTest):
Lars Gustäbelf9a2c632006-12-27 10:36:58 +0000670
671 def test_opener(self):
Lars Gustäbel9319e432007-04-20 20:10:59 +0000672 # Test for SF bug #1496501.
Lars Gustäbelf9a2c632006-12-27 10:36:58 +0000673 fobj = StringIO.StringIO("foo\n")
674 try:
Lars Gustäbel9319e432007-04-20 20:10:59 +0000675 tarfile.open("", mode="r", fileobj=fobj)
Lars Gustäbelf9a2c632006-12-27 10:36:58 +0000676 except tarfile.ReadError:
677 self.assertEqual(fobj.tell(), 0, "fileobj's position has moved")
Tim Peters8ceefc52004-10-25 03:19:41 +0000678
Lars Gustäbela9bad982007-08-28 12:33:15 +0000679 def test_no_name_argument(self):
680 fobj = open(testtar, "rb")
681 tar = tarfile.open(fileobj=fobj, mode="r")
682 self.assertEqual(tar.name, os.path.abspath(fobj.name))
683
684 def test_no_name_attribute(self):
685 data = open(testtar, "rb").read()
686 fobj = StringIO.StringIO(data)
687 self.assertRaises(AttributeError, getattr, fobj, "name")
688 tar = tarfile.open(fileobj=fobj, mode="r")
689 self.assertEqual(tar.name, None)
690
691 def test_empty_name_attribute(self):
692 data = open(testtar, "rb").read()
693 fobj = StringIO.StringIO(data)
694 fobj.name = ""
695 tar = tarfile.open(fileobj=fobj, mode="r")
696 self.assertEqual(tar.name, None)
697
Lars Gustäbel9319e432007-04-20 20:10:59 +0000698
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000699if bz2:
700 # Bzip2 TestCases
701 class ReadTestBzip2(ReadTestGzip):
702 comp = "bz2"
703 class ReadStreamTestBzip2(ReadStreamTestGzip):
704 comp = "bz2"
705 class WriteTestBzip2(WriteTest):
706 comp = "bz2"
707 class WriteStreamTestBzip2(WriteStreamTestGzip):
708 comp = "bz2"
Georg Brandl49c8f4c2006-05-15 19:30:35 +0000709 class ReadDetectTestBzip2(ReadDetectTest):
710 comp = "bz2"
711 class ReadDetectFileobjTestBzip2(ReadDetectFileobjTest):
712 comp = "bz2"
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000713 class ReadAsteriskTestBzip2(ReadAsteriskTest):
714 comp = "bz2"
715 class ReadStreamAsteriskTestBzip2(ReadStreamAsteriskTest):
716 comp = "bz2"
Lars Gustäbel7cc9c8b2007-12-01 21:06:06 +0000717 class ReadFileobjTestBzip2(ReadFileobjTest):
718 comp = "bz2"
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000719
720# If importing gzip failed, discard the Gzip TestCases.
721if not gzip:
722 del ReadTestGzip
723 del ReadStreamTestGzip
724 del WriteTestGzip
725 del WriteStreamTestGzip
726
Neal Norwitz996acf12003-02-17 14:51:41 +0000727def test_main():
Tim Peters02494762006-05-26 14:02:05 +0000728 # Create archive.
729 f = open(tarname(), "rb")
730 fguts = f.read()
731 f.close()
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000732 if gzip:
733 # create testtar.tar.gz
Tim Peters02494762006-05-26 14:02:05 +0000734 tar = gzip.open(tarname("gz"), "wb")
735 tar.write(fguts)
736 tar.close()
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000737 if bz2:
738 # create testtar.tar.bz2
Tim Peters02494762006-05-26 14:02:05 +0000739 tar = bz2.BZ2File(tarname("bz2"), "wb")
740 tar.write(fguts)
741 tar.close()
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000742
Walter Dörwald21d3a322003-05-01 17:45:56 +0000743 tests = [
Andrew M. Kuchlingd4f25522004-10-20 11:47:01 +0000744 FileModeTest,
Lars Gustäbelf9a2c632006-12-27 10:36:58 +0000745 OpenFileobjTest,
Walter Dörwald21d3a322003-05-01 17:45:56 +0000746 ReadTest,
747 ReadStreamTest,
Georg Brandl49c8f4c2006-05-15 19:30:35 +0000748 ReadDetectTest,
749 ReadDetectFileobjTest,
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000750 ReadAsteriskTest,
751 ReadStreamAsteriskTest,
Lars Gustäbel7cc9c8b2007-12-01 21:06:06 +0000752 ReadFileobjTest,
Walter Dörwald21d3a322003-05-01 17:45:56 +0000753 WriteTest,
Georg Brandlee23f4b2006-10-24 16:54:23 +0000754 Write100Test,
Martin v. Löwis5dbdc592005-08-27 10:07:56 +0000755 WriteSize0Test,
Neal Norwitz0662f8a2004-07-20 21:54:18 +0000756 WriteStreamTest,
757 WriteGNULongTest,
Georg Brandl38c6a222006-05-10 16:26:03 +0000758 ReadGNULongTest,
Walter Dörwald21d3a322003-05-01 17:45:56 +0000759 ]
760
Neal Norwitza4f651a2004-07-20 22:07:44 +0000761 if hasattr(os, "link"):
762 tests.append(ExtractHardlinkTest)
Neal Norwitzb0e32e22005-10-20 04:50:13 +0000763 tests.append(CreateHardlinkTest)
Neal Norwitza4f651a2004-07-20 22:07:44 +0000764
Walter Dörwald21d3a322003-05-01 17:45:56 +0000765 if gzip:
766 tests.extend([
767 ReadTestGzip, ReadStreamTestGzip,
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000768 WriteTestGzip, WriteStreamTestGzip,
Georg Brandl49c8f4c2006-05-15 19:30:35 +0000769 ReadDetectTestGzip, ReadDetectFileobjTestGzip,
Lars Gustäbel7cc9c8b2007-12-01 21:06:06 +0000770 ReadAsteriskTestGzip, ReadStreamAsteriskTestGzip,
771 ReadFileobjTestGzip
Walter Dörwald21d3a322003-05-01 17:45:56 +0000772 ])
773
774 if bz2:
775 tests.extend([
776 ReadTestBzip2, ReadStreamTestBzip2,
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000777 WriteTestBzip2, WriteStreamTestBzip2,
Georg Brandl49c8f4c2006-05-15 19:30:35 +0000778 ReadDetectTestBzip2, ReadDetectFileobjTestBzip2,
Lars Gustäbel7cc9c8b2007-12-01 21:06:06 +0000779 ReadAsteriskTestBzip2, ReadStreamAsteriskTestBzip2,
780 ReadFileobjTestBzip2
Walter Dörwald21d3a322003-05-01 17:45:56 +0000781 ])
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000782 try:
Walter Dörwald21d3a322003-05-01 17:45:56 +0000783 test_support.run_unittest(*tests)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000784 finally:
785 if gzip:
786 os.remove(tarname("gz"))
787 if bz2:
Tim Peters4e306172006-05-27 14:13:13 +0000788 os.remove(tarname("bz2"))
Brett Cannon455ea532003-06-12 08:01:06 +0000789 if os.path.exists(dirname()):
790 shutil.rmtree(dirname())
791 if os.path.exists(tmpname()):
792 os.remove(tmpname())
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000793
Neal Norwitz996acf12003-02-17 14:51:41 +0000794if __name__ == "__main__":
795 test_main()