PageRenderTime 41ms CodeModel.GetById 7ms RepoModel.GetById 0ms app.codeStats 1ms

/lib-python/2.7/test/test_shutil.py

https://bitbucket.org/dac_io/pypy
Python | 831 lines | 638 code | 119 blank | 74 comment | 119 complexity | 75f50d0e8dcd41f099cc1afd77e4f814 MD5 | raw file
  1. # Copyright (C) 2003 Python Software Foundation
  2. import unittest
  3. import shutil
  4. import tempfile
  5. import sys
  6. import stat
  7. import os
  8. import os.path
  9. from os.path import splitdrive
  10. from distutils.spawn import find_executable, spawn
  11. from shutil import (_make_tarball, _make_zipfile, make_archive,
  12. register_archive_format, unregister_archive_format,
  13. get_archive_formats)
  14. import tarfile
  15. import warnings
  16. from test import test_support
  17. from test.test_support import TESTFN, check_warnings, captured_stdout
  18. TESTFN2 = TESTFN + "2"
  19. try:
  20. import grp
  21. import pwd
  22. UID_GID_SUPPORT = True
  23. except ImportError:
  24. UID_GID_SUPPORT = False
  25. try:
  26. import zlib
  27. except ImportError:
  28. zlib = None
  29. try:
  30. import zipfile
  31. ZIP_SUPPORT = True
  32. except ImportError:
  33. ZIP_SUPPORT = find_executable('zip')
  34. class TestShutil(unittest.TestCase):
  35. def setUp(self):
  36. super(TestShutil, self).setUp()
  37. self.tempdirs = []
  38. def tearDown(self):
  39. super(TestShutil, self).tearDown()
  40. while self.tempdirs:
  41. d = self.tempdirs.pop()
  42. shutil.rmtree(d, os.name in ('nt', 'cygwin'))
  43. def write_file(self, path, content='xxx'):
  44. """Writes a file in the given path.
  45. path can be a string or a sequence.
  46. """
  47. if isinstance(path, (list, tuple)):
  48. path = os.path.join(*path)
  49. f = open(path, 'w')
  50. try:
  51. f.write(content)
  52. finally:
  53. f.close()
  54. def mkdtemp(self):
  55. """Create a temporary directory that will be cleaned up.
  56. Returns the path of the directory.
  57. """
  58. d = tempfile.mkdtemp()
  59. self.tempdirs.append(d)
  60. return d
  61. def test_rmtree_errors(self):
  62. # filename is guaranteed not to exist
  63. filename = tempfile.mktemp()
  64. self.assertRaises(OSError, shutil.rmtree, filename)
  65. # See bug #1071513 for why we don't run this on cygwin
  66. # and bug #1076467 for why we don't run this as root.
  67. if (hasattr(os, 'chmod') and sys.platform[:6] != 'cygwin'
  68. and not (hasattr(os, 'geteuid') and os.geteuid() == 0)):
  69. def test_on_error(self):
  70. self.errorState = 0
  71. os.mkdir(TESTFN)
  72. self.childpath = os.path.join(TESTFN, 'a')
  73. f = open(self.childpath, 'w')
  74. f.close()
  75. old_dir_mode = os.stat(TESTFN).st_mode
  76. old_child_mode = os.stat(self.childpath).st_mode
  77. # Make unwritable.
  78. os.chmod(self.childpath, stat.S_IREAD)
  79. os.chmod(TESTFN, stat.S_IREAD)
  80. shutil.rmtree(TESTFN, onerror=self.check_args_to_onerror)
  81. # Test whether onerror has actually been called.
  82. self.assertEqual(self.errorState, 2,
  83. "Expected call to onerror function did not happen.")
  84. # Make writable again.
  85. os.chmod(TESTFN, old_dir_mode)
  86. os.chmod(self.childpath, old_child_mode)
  87. # Clean up.
  88. shutil.rmtree(TESTFN)
  89. def check_args_to_onerror(self, func, arg, exc):
  90. # test_rmtree_errors deliberately runs rmtree
  91. # on a directory that is chmod 400, which will fail.
  92. # This function is run when shutil.rmtree fails.
  93. # 99.9% of the time it initially fails to remove
  94. # a file in the directory, so the first time through
  95. # func is os.remove.
  96. # However, some Linux machines running ZFS on
  97. # FUSE experienced a failure earlier in the process
  98. # at os.listdir. The first failure may legally
  99. # be either.
  100. if self.errorState == 0:
  101. if func is os.remove:
  102. self.assertEqual(arg, self.childpath)
  103. else:
  104. self.assertIs(func, os.listdir,
  105. "func must be either os.remove or os.listdir")
  106. self.assertEqual(arg, TESTFN)
  107. self.assertTrue(issubclass(exc[0], OSError))
  108. self.errorState = 1
  109. else:
  110. self.assertEqual(func, os.rmdir)
  111. self.assertEqual(arg, TESTFN)
  112. self.assertTrue(issubclass(exc[0], OSError))
  113. self.errorState = 2
  114. def test_rmtree_dont_delete_file(self):
  115. # When called on a file instead of a directory, don't delete it.
  116. handle, path = tempfile.mkstemp()
  117. os.fdopen(handle).close()
  118. self.assertRaises(OSError, shutil.rmtree, path)
  119. os.remove(path)
  120. def test_copytree_simple(self):
  121. def write_data(path, data):
  122. f = open(path, "w")
  123. f.write(data)
  124. f.close()
  125. def read_data(path):
  126. f = open(path)
  127. data = f.read()
  128. f.close()
  129. return data
  130. src_dir = tempfile.mkdtemp()
  131. dst_dir = os.path.join(tempfile.mkdtemp(), 'destination')
  132. write_data(os.path.join(src_dir, 'test.txt'), '123')
  133. os.mkdir(os.path.join(src_dir, 'test_dir'))
  134. write_data(os.path.join(src_dir, 'test_dir', 'test.txt'), '456')
  135. try:
  136. shutil.copytree(src_dir, dst_dir)
  137. self.assertTrue(os.path.isfile(os.path.join(dst_dir, 'test.txt')))
  138. self.assertTrue(os.path.isdir(os.path.join(dst_dir, 'test_dir')))
  139. self.assertTrue(os.path.isfile(os.path.join(dst_dir, 'test_dir',
  140. 'test.txt')))
  141. actual = read_data(os.path.join(dst_dir, 'test.txt'))
  142. self.assertEqual(actual, '123')
  143. actual = read_data(os.path.join(dst_dir, 'test_dir', 'test.txt'))
  144. self.assertEqual(actual, '456')
  145. finally:
  146. for path in (
  147. os.path.join(src_dir, 'test.txt'),
  148. os.path.join(dst_dir, 'test.txt'),
  149. os.path.join(src_dir, 'test_dir', 'test.txt'),
  150. os.path.join(dst_dir, 'test_dir', 'test.txt'),
  151. ):
  152. if os.path.exists(path):
  153. os.remove(path)
  154. for path in (src_dir,
  155. os.path.dirname(dst_dir)
  156. ):
  157. if os.path.exists(path):
  158. shutil.rmtree(path)
  159. def test_copytree_with_exclude(self):
  160. def write_data(path, data):
  161. f = open(path, "w")
  162. f.write(data)
  163. f.close()
  164. def read_data(path):
  165. f = open(path)
  166. data = f.read()
  167. f.close()
  168. return data
  169. # creating data
  170. join = os.path.join
  171. exists = os.path.exists
  172. src_dir = tempfile.mkdtemp()
  173. try:
  174. dst_dir = join(tempfile.mkdtemp(), 'destination')
  175. write_data(join(src_dir, 'test.txt'), '123')
  176. write_data(join(src_dir, 'test.tmp'), '123')
  177. os.mkdir(join(src_dir, 'test_dir'))
  178. write_data(join(src_dir, 'test_dir', 'test.txt'), '456')
  179. os.mkdir(join(src_dir, 'test_dir2'))
  180. write_data(join(src_dir, 'test_dir2', 'test.txt'), '456')
  181. os.mkdir(join(src_dir, 'test_dir2', 'subdir'))
  182. os.mkdir(join(src_dir, 'test_dir2', 'subdir2'))
  183. write_data(join(src_dir, 'test_dir2', 'subdir', 'test.txt'), '456')
  184. write_data(join(src_dir, 'test_dir2', 'subdir2', 'test.py'), '456')
  185. # testing glob-like patterns
  186. try:
  187. patterns = shutil.ignore_patterns('*.tmp', 'test_dir2')
  188. shutil.copytree(src_dir, dst_dir, ignore=patterns)
  189. # checking the result: some elements should not be copied
  190. self.assertTrue(exists(join(dst_dir, 'test.txt')))
  191. self.assertTrue(not exists(join(dst_dir, 'test.tmp')))
  192. self.assertTrue(not exists(join(dst_dir, 'test_dir2')))
  193. finally:
  194. if os.path.exists(dst_dir):
  195. shutil.rmtree(dst_dir)
  196. try:
  197. patterns = shutil.ignore_patterns('*.tmp', 'subdir*')
  198. shutil.copytree(src_dir, dst_dir, ignore=patterns)
  199. # checking the result: some elements should not be copied
  200. self.assertTrue(not exists(join(dst_dir, 'test.tmp')))
  201. self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2')))
  202. self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir')))
  203. finally:
  204. if os.path.exists(dst_dir):
  205. shutil.rmtree(dst_dir)
  206. # testing callable-style
  207. try:
  208. def _filter(src, names):
  209. res = []
  210. for name in names:
  211. path = os.path.join(src, name)
  212. if (os.path.isdir(path) and
  213. path.split()[-1] == 'subdir'):
  214. res.append(name)
  215. elif os.path.splitext(path)[-1] in ('.py'):
  216. res.append(name)
  217. return res
  218. shutil.copytree(src_dir, dst_dir, ignore=_filter)
  219. # checking the result: some elements should not be copied
  220. self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2',
  221. 'test.py')))
  222. self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir')))
  223. finally:
  224. if os.path.exists(dst_dir):
  225. shutil.rmtree(dst_dir)
  226. finally:
  227. shutil.rmtree(src_dir)
  228. shutil.rmtree(os.path.dirname(dst_dir))
  229. if hasattr(os, "symlink"):
  230. def test_dont_copy_file_onto_link_to_itself(self):
  231. # bug 851123.
  232. os.mkdir(TESTFN)
  233. src = os.path.join(TESTFN, 'cheese')
  234. dst = os.path.join(TESTFN, 'shop')
  235. try:
  236. f = open(src, 'w')
  237. f.write('cheddar')
  238. f.close()
  239. os.link(src, dst)
  240. self.assertRaises(shutil.Error, shutil.copyfile, src, dst)
  241. with open(src, 'r') as f:
  242. self.assertEqual(f.read(), 'cheddar')
  243. os.remove(dst)
  244. # Using `src` here would mean we end up with a symlink pointing
  245. # to TESTFN/TESTFN/cheese, while it should point at
  246. # TESTFN/cheese.
  247. os.symlink('cheese', dst)
  248. self.assertRaises(shutil.Error, shutil.copyfile, src, dst)
  249. with open(src, 'r') as f:
  250. self.assertEqual(f.read(), 'cheddar')
  251. os.remove(dst)
  252. finally:
  253. try:
  254. shutil.rmtree(TESTFN)
  255. except OSError:
  256. pass
  257. def test_rmtree_on_symlink(self):
  258. # bug 1669.
  259. os.mkdir(TESTFN)
  260. try:
  261. src = os.path.join(TESTFN, 'cheese')
  262. dst = os.path.join(TESTFN, 'shop')
  263. os.mkdir(src)
  264. os.symlink(src, dst)
  265. self.assertRaises(OSError, shutil.rmtree, dst)
  266. finally:
  267. shutil.rmtree(TESTFN, ignore_errors=True)
  268. if hasattr(os, "mkfifo"):
  269. # Issue #3002: copyfile and copytree block indefinitely on named pipes
  270. def test_copyfile_named_pipe(self):
  271. os.mkfifo(TESTFN)
  272. try:
  273. self.assertRaises(shutil.SpecialFileError,
  274. shutil.copyfile, TESTFN, TESTFN2)
  275. self.assertRaises(shutil.SpecialFileError,
  276. shutil.copyfile, __file__, TESTFN)
  277. finally:
  278. os.remove(TESTFN)
  279. def test_copytree_named_pipe(self):
  280. os.mkdir(TESTFN)
  281. try:
  282. subdir = os.path.join(TESTFN, "subdir")
  283. os.mkdir(subdir)
  284. pipe = os.path.join(subdir, "mypipe")
  285. os.mkfifo(pipe)
  286. try:
  287. shutil.copytree(TESTFN, TESTFN2)
  288. except shutil.Error as e:
  289. errors = e.args[0]
  290. self.assertEqual(len(errors), 1)
  291. src, dst, error_msg = errors[0]
  292. self.assertEqual("`%s` is a named pipe" % pipe, error_msg)
  293. else:
  294. self.fail("shutil.Error should have been raised")
  295. finally:
  296. shutil.rmtree(TESTFN, ignore_errors=True)
  297. shutil.rmtree(TESTFN2, ignore_errors=True)
  298. @unittest.skipUnless(zlib, "requires zlib")
  299. def test_make_tarball(self):
  300. # creating something to tar
  301. tmpdir = self.mkdtemp()
  302. self.write_file([tmpdir, 'file1'], 'xxx')
  303. self.write_file([tmpdir, 'file2'], 'xxx')
  304. os.mkdir(os.path.join(tmpdir, 'sub'))
  305. self.write_file([tmpdir, 'sub', 'file3'], 'xxx')
  306. tmpdir2 = self.mkdtemp()
  307. unittest.skipUnless(splitdrive(tmpdir)[0] == splitdrive(tmpdir2)[0],
  308. "source and target should be on same drive")
  309. base_name = os.path.join(tmpdir2, 'archive')
  310. # working with relative paths to avoid tar warnings
  311. old_dir = os.getcwd()
  312. os.chdir(tmpdir)
  313. try:
  314. _make_tarball(splitdrive(base_name)[1], '.')
  315. finally:
  316. os.chdir(old_dir)
  317. # check if the compressed tarball was created
  318. tarball = base_name + '.tar.gz'
  319. self.assertTrue(os.path.exists(tarball))
  320. # trying an uncompressed one
  321. base_name = os.path.join(tmpdir2, 'archive')
  322. old_dir = os.getcwd()
  323. os.chdir(tmpdir)
  324. try:
  325. _make_tarball(splitdrive(base_name)[1], '.', compress=None)
  326. finally:
  327. os.chdir(old_dir)
  328. tarball = base_name + '.tar'
  329. self.assertTrue(os.path.exists(tarball))
  330. def _tarinfo(self, path):
  331. tar = tarfile.open(path)
  332. try:
  333. names = tar.getnames()
  334. names.sort()
  335. return tuple(names)
  336. finally:
  337. tar.close()
  338. def _create_files(self):
  339. # creating something to tar
  340. tmpdir = self.mkdtemp()
  341. dist = os.path.join(tmpdir, 'dist')
  342. os.mkdir(dist)
  343. self.write_file([dist, 'file1'], 'xxx')
  344. self.write_file([dist, 'file2'], 'xxx')
  345. os.mkdir(os.path.join(dist, 'sub'))
  346. self.write_file([dist, 'sub', 'file3'], 'xxx')
  347. os.mkdir(os.path.join(dist, 'sub2'))
  348. tmpdir2 = self.mkdtemp()
  349. base_name = os.path.join(tmpdir2, 'archive')
  350. return tmpdir, tmpdir2, base_name
  351. @unittest.skipUnless(zlib, "Requires zlib")
  352. @unittest.skipUnless(find_executable('tar') and find_executable('gzip'),
  353. 'Need the tar command to run')
  354. def test_tarfile_vs_tar(self):
  355. tmpdir, tmpdir2, base_name = self._create_files()
  356. old_dir = os.getcwd()
  357. os.chdir(tmpdir)
  358. try:
  359. _make_tarball(base_name, 'dist')
  360. finally:
  361. os.chdir(old_dir)
  362. # check if the compressed tarball was created
  363. tarball = base_name + '.tar.gz'
  364. self.assertTrue(os.path.exists(tarball))
  365. # now create another tarball using `tar`
  366. tarball2 = os.path.join(tmpdir, 'archive2.tar.gz')
  367. tar_cmd = ['tar', '-cf', 'archive2.tar', 'dist']
  368. gzip_cmd = ['gzip', '-f9', 'archive2.tar']
  369. old_dir = os.getcwd()
  370. os.chdir(tmpdir)
  371. try:
  372. with captured_stdout() as s:
  373. spawn(tar_cmd)
  374. spawn(gzip_cmd)
  375. finally:
  376. os.chdir(old_dir)
  377. self.assertTrue(os.path.exists(tarball2))
  378. # let's compare both tarballs
  379. self.assertEqual(self._tarinfo(tarball), self._tarinfo(tarball2))
  380. # trying an uncompressed one
  381. base_name = os.path.join(tmpdir2, 'archive')
  382. old_dir = os.getcwd()
  383. os.chdir(tmpdir)
  384. try:
  385. _make_tarball(base_name, 'dist', compress=None)
  386. finally:
  387. os.chdir(old_dir)
  388. tarball = base_name + '.tar'
  389. self.assertTrue(os.path.exists(tarball))
  390. # now for a dry_run
  391. base_name = os.path.join(tmpdir2, 'archive')
  392. old_dir = os.getcwd()
  393. os.chdir(tmpdir)
  394. try:
  395. _make_tarball(base_name, 'dist', compress=None, dry_run=True)
  396. finally:
  397. os.chdir(old_dir)
  398. tarball = base_name + '.tar'
  399. self.assertTrue(os.path.exists(tarball))
  400. @unittest.skipUnless(zlib, "Requires zlib")
  401. @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run')
  402. def test_make_zipfile(self):
  403. # creating something to tar
  404. tmpdir = self.mkdtemp()
  405. self.write_file([tmpdir, 'file1'], 'xxx')
  406. self.write_file([tmpdir, 'file2'], 'xxx')
  407. tmpdir2 = self.mkdtemp()
  408. base_name = os.path.join(tmpdir2, 'archive')
  409. _make_zipfile(base_name, tmpdir)
  410. # check if the compressed tarball was created
  411. tarball = base_name + '.zip'
  412. self.assertTrue(os.path.exists(tarball))
  413. def test_make_archive(self):
  414. tmpdir = self.mkdtemp()
  415. base_name = os.path.join(tmpdir, 'archive')
  416. self.assertRaises(ValueError, make_archive, base_name, 'xxx')
  417. @unittest.skipUnless(zlib, "Requires zlib")
  418. def test_make_archive_owner_group(self):
  419. # testing make_archive with owner and group, with various combinations
  420. # this works even if there's not gid/uid support
  421. if UID_GID_SUPPORT:
  422. group = grp.getgrgid(0)[0]
  423. owner = pwd.getpwuid(0)[0]
  424. else:
  425. group = owner = 'root'
  426. base_dir, root_dir, base_name = self._create_files()
  427. base_name = os.path.join(self.mkdtemp() , 'archive')
  428. res = make_archive(base_name, 'zip', root_dir, base_dir, owner=owner,
  429. group=group)
  430. self.assertTrue(os.path.exists(res))
  431. res = make_archive(base_name, 'zip', root_dir, base_dir)
  432. self.assertTrue(os.path.exists(res))
  433. res = make_archive(base_name, 'tar', root_dir, base_dir,
  434. owner=owner, group=group)
  435. self.assertTrue(os.path.exists(res))
  436. res = make_archive(base_name, 'tar', root_dir, base_dir,
  437. owner='kjhkjhkjg', group='oihohoh')
  438. self.assertTrue(os.path.exists(res))
  439. @unittest.skipUnless(zlib, "Requires zlib")
  440. @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support")
  441. def test_tarfile_root_owner(self):
  442. tmpdir, tmpdir2, base_name = self._create_files()
  443. old_dir = os.getcwd()
  444. os.chdir(tmpdir)
  445. group = grp.getgrgid(0)[0]
  446. owner = pwd.getpwuid(0)[0]
  447. try:
  448. archive_name = _make_tarball(base_name, 'dist', compress=None,
  449. owner=owner, group=group)
  450. finally:
  451. os.chdir(old_dir)
  452. # check if the compressed tarball was created
  453. self.assertTrue(os.path.exists(archive_name))
  454. # now checks the rights
  455. archive = tarfile.open(archive_name)
  456. try:
  457. for member in archive.getmembers():
  458. self.assertEqual(member.uid, 0)
  459. self.assertEqual(member.gid, 0)
  460. finally:
  461. archive.close()
  462. def test_make_archive_cwd(self):
  463. current_dir = os.getcwd()
  464. def _breaks(*args, **kw):
  465. raise RuntimeError()
  466. register_archive_format('xxx', _breaks, [], 'xxx file')
  467. try:
  468. try:
  469. make_archive('xxx', 'xxx', root_dir=self.mkdtemp())
  470. except Exception:
  471. pass
  472. self.assertEqual(os.getcwd(), current_dir)
  473. finally:
  474. unregister_archive_format('xxx')
  475. def test_register_archive_format(self):
  476. self.assertRaises(TypeError, register_archive_format, 'xxx', 1)
  477. self.assertRaises(TypeError, register_archive_format, 'xxx', lambda: x,
  478. 1)
  479. self.assertRaises(TypeError, register_archive_format, 'xxx', lambda: x,
  480. [(1, 2), (1, 2, 3)])
  481. register_archive_format('xxx', lambda: x, [(1, 2)], 'xxx file')
  482. formats = [name for name, params in get_archive_formats()]
  483. self.assertIn('xxx', formats)
  484. unregister_archive_format('xxx')
  485. formats = [name for name, params in get_archive_formats()]
  486. self.assertNotIn('xxx', formats)
  487. class TestMove(unittest.TestCase):
  488. def setUp(self):
  489. filename = "foo"
  490. self.src_dir = tempfile.mkdtemp()
  491. self.dst_dir = tempfile.mkdtemp()
  492. self.src_file = os.path.join(self.src_dir, filename)
  493. self.dst_file = os.path.join(self.dst_dir, filename)
  494. # Try to create a dir in the current directory, hoping that it is
  495. # not located on the same filesystem as the system tmp dir.
  496. try:
  497. self.dir_other_fs = tempfile.mkdtemp(
  498. dir=os.path.dirname(__file__))
  499. self.file_other_fs = os.path.join(self.dir_other_fs,
  500. filename)
  501. except OSError:
  502. self.dir_other_fs = None
  503. with open(self.src_file, "wb") as f:
  504. f.write("spam")
  505. def tearDown(self):
  506. for d in (self.src_dir, self.dst_dir, self.dir_other_fs):
  507. try:
  508. if d:
  509. shutil.rmtree(d)
  510. except:
  511. pass
  512. def _check_move_file(self, src, dst, real_dst):
  513. with open(src, "rb") as f:
  514. contents = f.read()
  515. shutil.move(src, dst)
  516. with open(real_dst, "rb") as f:
  517. self.assertEqual(contents, f.read())
  518. self.assertFalse(os.path.exists(src))
  519. def _check_move_dir(self, src, dst, real_dst):
  520. contents = sorted(os.listdir(src))
  521. shutil.move(src, dst)
  522. self.assertEqual(contents, sorted(os.listdir(real_dst)))
  523. self.assertFalse(os.path.exists(src))
  524. def test_move_file(self):
  525. # Move a file to another location on the same filesystem.
  526. self._check_move_file(self.src_file, self.dst_file, self.dst_file)
  527. def test_move_file_to_dir(self):
  528. # Move a file inside an existing dir on the same filesystem.
  529. self._check_move_file(self.src_file, self.dst_dir, self.dst_file)
  530. def test_move_file_other_fs(self):
  531. # Move a file to an existing dir on another filesystem.
  532. if not self.dir_other_fs:
  533. # skip
  534. return
  535. self._check_move_file(self.src_file, self.file_other_fs,
  536. self.file_other_fs)
  537. def test_move_file_to_dir_other_fs(self):
  538. # Move a file to another location on another filesystem.
  539. if not self.dir_other_fs:
  540. # skip
  541. return
  542. self._check_move_file(self.src_file, self.dir_other_fs,
  543. self.file_other_fs)
  544. def test_move_dir(self):
  545. # Move a dir to another location on the same filesystem.
  546. dst_dir = tempfile.mktemp()
  547. try:
  548. self._check_move_dir(self.src_dir, dst_dir, dst_dir)
  549. finally:
  550. try:
  551. shutil.rmtree(dst_dir)
  552. except:
  553. pass
  554. def test_move_dir_other_fs(self):
  555. # Move a dir to another location on another filesystem.
  556. if not self.dir_other_fs:
  557. # skip
  558. return
  559. dst_dir = tempfile.mktemp(dir=self.dir_other_fs)
  560. try:
  561. self._check_move_dir(self.src_dir, dst_dir, dst_dir)
  562. finally:
  563. try:
  564. shutil.rmtree(dst_dir)
  565. except:
  566. pass
  567. def test_move_dir_to_dir(self):
  568. # Move a dir inside an existing dir on the same filesystem.
  569. self._check_move_dir(self.src_dir, self.dst_dir,
  570. os.path.join(self.dst_dir, os.path.basename(self.src_dir)))
  571. def test_move_dir_to_dir_other_fs(self):
  572. # Move a dir inside an existing dir on another filesystem.
  573. if not self.dir_other_fs:
  574. # skip
  575. return
  576. self._check_move_dir(self.src_dir, self.dir_other_fs,
  577. os.path.join(self.dir_other_fs, os.path.basename(self.src_dir)))
  578. def test_existing_file_inside_dest_dir(self):
  579. # A file with the same name inside the destination dir already exists.
  580. with open(self.dst_file, "wb"):
  581. pass
  582. self.assertRaises(shutil.Error, shutil.move, self.src_file, self.dst_dir)
  583. def test_dont_move_dir_in_itself(self):
  584. # Moving a dir inside itself raises an Error.
  585. dst = os.path.join(self.src_dir, "bar")
  586. self.assertRaises(shutil.Error, shutil.move, self.src_dir, dst)
  587. def test_destinsrc_false_negative(self):
  588. os.mkdir(TESTFN)
  589. try:
  590. for src, dst in [('srcdir', 'srcdir/dest')]:
  591. src = os.path.join(TESTFN, src)
  592. dst = os.path.join(TESTFN, dst)
  593. self.assertTrue(shutil._destinsrc(src, dst),
  594. msg='_destinsrc() wrongly concluded that '
  595. 'dst (%s) is not in src (%s)' % (dst, src))
  596. finally:
  597. shutil.rmtree(TESTFN, ignore_errors=True)
  598. def test_destinsrc_false_positive(self):
  599. os.mkdir(TESTFN)
  600. try:
  601. for src, dst in [('srcdir', 'src/dest'), ('srcdir', 'srcdir.new')]:
  602. src = os.path.join(TESTFN, src)
  603. dst = os.path.join(TESTFN, dst)
  604. self.assertFalse(shutil._destinsrc(src, dst),
  605. msg='_destinsrc() wrongly concluded that '
  606. 'dst (%s) is in src (%s)' % (dst, src))
  607. finally:
  608. shutil.rmtree(TESTFN, ignore_errors=True)
  609. class TestCopyFile(unittest.TestCase):
  610. _delete = False
  611. class Faux(object):
  612. _entered = False
  613. _exited_with = None
  614. _raised = False
  615. def __init__(self, raise_in_exit=False, suppress_at_exit=True):
  616. self._raise_in_exit = raise_in_exit
  617. self._suppress_at_exit = suppress_at_exit
  618. def read(self, *args):
  619. return ''
  620. def __enter__(self):
  621. self._entered = True
  622. def __exit__(self, exc_type, exc_val, exc_tb):
  623. self._exited_with = exc_type, exc_val, exc_tb
  624. if self._raise_in_exit:
  625. self._raised = True
  626. raise IOError("Cannot close")
  627. return self._suppress_at_exit
  628. def tearDown(self):
  629. if self._delete:
  630. del shutil.open
  631. def _set_shutil_open(self, func):
  632. shutil.open = func
  633. self._delete = True
  634. def test_w_source_open_fails(self):
  635. def _open(filename, mode='r'):
  636. if filename == 'srcfile':
  637. raise IOError('Cannot open "srcfile"')
  638. assert 0 # shouldn't reach here.
  639. self._set_shutil_open(_open)
  640. self.assertRaises(IOError, shutil.copyfile, 'srcfile', 'destfile')
  641. def test_w_dest_open_fails(self):
  642. srcfile = self.Faux()
  643. def _open(filename, mode='r'):
  644. if filename == 'srcfile':
  645. return srcfile
  646. if filename == 'destfile':
  647. raise IOError('Cannot open "destfile"')
  648. assert 0 # shouldn't reach here.
  649. self._set_shutil_open(_open)
  650. shutil.copyfile('srcfile', 'destfile')
  651. self.assertTrue(srcfile._entered)
  652. self.assertTrue(srcfile._exited_with[0] is IOError)
  653. self.assertEqual(srcfile._exited_with[1].args,
  654. ('Cannot open "destfile"',))
  655. def test_w_dest_close_fails(self):
  656. srcfile = self.Faux()
  657. destfile = self.Faux(True)
  658. def _open(filename, mode='r'):
  659. if filename == 'srcfile':
  660. return srcfile
  661. if filename == 'destfile':
  662. return destfile
  663. assert 0 # shouldn't reach here.
  664. self._set_shutil_open(_open)
  665. shutil.copyfile('srcfile', 'destfile')
  666. self.assertTrue(srcfile._entered)
  667. self.assertTrue(destfile._entered)
  668. self.assertTrue(destfile._raised)
  669. self.assertTrue(srcfile._exited_with[0] is IOError)
  670. self.assertEqual(srcfile._exited_with[1].args,
  671. ('Cannot close',))
  672. def test_w_source_close_fails(self):
  673. srcfile = self.Faux(True)
  674. destfile = self.Faux()
  675. def _open(filename, mode='r'):
  676. if filename == 'srcfile':
  677. return srcfile
  678. if filename == 'destfile':
  679. return destfile
  680. assert 0 # shouldn't reach here.
  681. self._set_shutil_open(_open)
  682. self.assertRaises(IOError,
  683. shutil.copyfile, 'srcfile', 'destfile')
  684. self.assertTrue(srcfile._entered)
  685. self.assertTrue(destfile._entered)
  686. self.assertFalse(destfile._raised)
  687. self.assertTrue(srcfile._exited_with[0] is None)
  688. self.assertTrue(srcfile._raised)
  689. def test_move_dir_caseinsensitive(self):
  690. # Renames a folder to the same name
  691. # but a different case.
  692. self.src_dir = tempfile.mkdtemp()
  693. dst_dir = os.path.join(
  694. os.path.dirname(self.src_dir),
  695. os.path.basename(self.src_dir).upper())
  696. self.assertNotEqual(self.src_dir, dst_dir)
  697. try:
  698. shutil.move(self.src_dir, dst_dir)
  699. self.assertTrue(os.path.isdir(dst_dir))
  700. finally:
  701. if os.path.exists(dst_dir):
  702. os.rmdir(dst_dir)
  703. def test_main():
  704. test_support.run_unittest(TestShutil, TestMove, TestCopyFile)
  705. if __name__ == '__main__':
  706. test_main()