PageRenderTime 24ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/Lib/test/test_shutil.py

https://bitbucket.org/glix/python
Python | 371 lines | 286 code | 49 blank | 36 comment | 55 complexity | d542f414d0a1458c90d228ef39333bd5 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 test import test_support
  10. from test.test_support import TESTFN
  11. class TestShutil(unittest.TestCase):
  12. def test_rmtree_errors(self):
  13. # filename is guaranteed not to exist
  14. filename = tempfile.mktemp()
  15. self.assertRaises(OSError, shutil.rmtree, filename)
  16. # See bug #1071513 for why we don't run this on cygwin
  17. # and bug #1076467 for why we don't run this as root.
  18. if (hasattr(os, 'chmod') and sys.platform[:6] != 'cygwin'
  19. and not (hasattr(os, 'geteuid') and os.geteuid() == 0)):
  20. def test_on_error(self):
  21. self.errorState = 0
  22. os.mkdir(TESTFN)
  23. self.childpath = os.path.join(TESTFN, 'a')
  24. f = open(self.childpath, 'w')
  25. f.close()
  26. old_dir_mode = os.stat(TESTFN).st_mode
  27. old_child_mode = os.stat(self.childpath).st_mode
  28. # Make unwritable.
  29. os.chmod(self.childpath, stat.S_IREAD)
  30. os.chmod(TESTFN, stat.S_IREAD)
  31. shutil.rmtree(TESTFN, onerror=self.check_args_to_onerror)
  32. # Test whether onerror has actually been called.
  33. self.assertEqual(self.errorState, 2,
  34. "Expected call to onerror function did not happen.")
  35. # Make writable again.
  36. os.chmod(TESTFN, old_dir_mode)
  37. os.chmod(self.childpath, old_child_mode)
  38. # Clean up.
  39. shutil.rmtree(TESTFN)
  40. def check_args_to_onerror(self, func, arg, exc):
  41. if self.errorState == 0:
  42. self.assertEqual(func, os.remove)
  43. self.assertEqual(arg, self.childpath)
  44. self.failUnless(issubclass(exc[0], OSError))
  45. self.errorState = 1
  46. else:
  47. self.assertEqual(func, os.rmdir)
  48. self.assertEqual(arg, TESTFN)
  49. self.failUnless(issubclass(exc[0], OSError))
  50. self.errorState = 2
  51. def test_rmtree_dont_delete_file(self):
  52. # When called on a file instead of a directory, don't delete it.
  53. handle, path = tempfile.mkstemp()
  54. os.fdopen(handle).close()
  55. self.assertRaises(OSError, shutil.rmtree, path)
  56. os.remove(path)
  57. def test_copytree_simple(self):
  58. def write_data(path, data):
  59. f = open(path, "w")
  60. f.write(data)
  61. f.close()
  62. def read_data(path):
  63. f = open(path)
  64. data = f.read()
  65. f.close()
  66. return data
  67. src_dir = tempfile.mkdtemp()
  68. dst_dir = os.path.join(tempfile.mkdtemp(), 'destination')
  69. write_data(os.path.join(src_dir, 'test.txt'), '123')
  70. os.mkdir(os.path.join(src_dir, 'test_dir'))
  71. write_data(os.path.join(src_dir, 'test_dir', 'test.txt'), '456')
  72. try:
  73. shutil.copytree(src_dir, dst_dir)
  74. self.assertTrue(os.path.isfile(os.path.join(dst_dir, 'test.txt')))
  75. self.assertTrue(os.path.isdir(os.path.join(dst_dir, 'test_dir')))
  76. self.assertTrue(os.path.isfile(os.path.join(dst_dir, 'test_dir',
  77. 'test.txt')))
  78. actual = read_data(os.path.join(dst_dir, 'test.txt'))
  79. self.assertEqual(actual, '123')
  80. actual = read_data(os.path.join(dst_dir, 'test_dir', 'test.txt'))
  81. self.assertEqual(actual, '456')
  82. finally:
  83. for path in (
  84. os.path.join(src_dir, 'test.txt'),
  85. os.path.join(dst_dir, 'test.txt'),
  86. os.path.join(src_dir, 'test_dir', 'test.txt'),
  87. os.path.join(dst_dir, 'test_dir', 'test.txt'),
  88. ):
  89. if os.path.exists(path):
  90. os.remove(path)
  91. for path in (src_dir,
  92. os.path.abspath(os.path.join(dst_dir, os.path.pardir))
  93. ):
  94. if os.path.exists(path):
  95. shutil.rmtree(path)
  96. def test_copytree_with_exclude(self):
  97. def write_data(path, data):
  98. f = open(path, "w")
  99. f.write(data)
  100. f.close()
  101. def read_data(path):
  102. f = open(path)
  103. data = f.read()
  104. f.close()
  105. return data
  106. # creating data
  107. join = os.path.join
  108. exists = os.path.exists
  109. src_dir = tempfile.mkdtemp()
  110. dst_dir = join(tempfile.mkdtemp(), 'destination')
  111. write_data(join(src_dir, 'test.txt'), '123')
  112. write_data(join(src_dir, 'test.tmp'), '123')
  113. os.mkdir(join(src_dir, 'test_dir'))
  114. write_data(join(src_dir, 'test_dir', 'test.txt'), '456')
  115. os.mkdir(join(src_dir, 'test_dir2'))
  116. write_data(join(src_dir, 'test_dir2', 'test.txt'), '456')
  117. os.mkdir(join(src_dir, 'test_dir2', 'subdir'))
  118. os.mkdir(join(src_dir, 'test_dir2', 'subdir2'))
  119. write_data(join(src_dir, 'test_dir2', 'subdir', 'test.txt'), '456')
  120. write_data(join(src_dir, 'test_dir2', 'subdir2', 'test.py'), '456')
  121. # testing glob-like patterns
  122. try:
  123. patterns = shutil.ignore_patterns('*.tmp', 'test_dir2')
  124. shutil.copytree(src_dir, dst_dir, ignore=patterns)
  125. # checking the result: some elements should not be copied
  126. self.assert_(exists(join(dst_dir, 'test.txt')))
  127. self.assert_(not exists(join(dst_dir, 'test.tmp')))
  128. self.assert_(not exists(join(dst_dir, 'test_dir2')))
  129. finally:
  130. if os.path.exists(dst_dir):
  131. shutil.rmtree(dst_dir)
  132. try:
  133. patterns = shutil.ignore_patterns('*.tmp', 'subdir*')
  134. shutil.copytree(src_dir, dst_dir, ignore=patterns)
  135. # checking the result: some elements should not be copied
  136. self.assert_(not exists(join(dst_dir, 'test.tmp')))
  137. self.assert_(not exists(join(dst_dir, 'test_dir2', 'subdir2')))
  138. self.assert_(not exists(join(dst_dir, 'test_dir2', 'subdir')))
  139. finally:
  140. if os.path.exists(dst_dir):
  141. shutil.rmtree(dst_dir)
  142. # testing callable-style
  143. try:
  144. def _filter(src, names):
  145. res = []
  146. for name in names:
  147. path = os.path.join(src, name)
  148. if (os.path.isdir(path) and
  149. path.split()[-1] == 'subdir'):
  150. res.append(name)
  151. elif os.path.splitext(path)[-1] in ('.py'):
  152. res.append(name)
  153. return res
  154. shutil.copytree(src_dir, dst_dir, ignore=_filter)
  155. # checking the result: some elements should not be copied
  156. self.assert_(not exists(join(dst_dir, 'test_dir2', 'subdir2',
  157. 'test.py')))
  158. self.assert_(not exists(join(dst_dir, 'test_dir2', 'subdir')))
  159. finally:
  160. if os.path.exists(dst_dir):
  161. shutil.rmtree(dst_dir)
  162. if hasattr(os, "symlink"):
  163. def test_dont_copy_file_onto_link_to_itself(self):
  164. # bug 851123.
  165. os.mkdir(TESTFN)
  166. src = os.path.join(TESTFN, 'cheese')
  167. dst = os.path.join(TESTFN, 'shop')
  168. try:
  169. f = open(src, 'w')
  170. f.write('cheddar')
  171. f.close()
  172. os.link(src, dst)
  173. self.assertRaises(shutil.Error, shutil.copyfile, src, dst)
  174. self.assertEqual(open(src,'r').read(), 'cheddar')
  175. os.remove(dst)
  176. # Using `src` here would mean we end up with a symlink pointing
  177. # to TESTFN/TESTFN/cheese, while it should point at
  178. # TESTFN/cheese.
  179. os.symlink('cheese', dst)
  180. self.assertRaises(shutil.Error, shutil.copyfile, src, dst)
  181. self.assertEqual(open(src,'r').read(), 'cheddar')
  182. os.remove(dst)
  183. finally:
  184. try:
  185. shutil.rmtree(TESTFN)
  186. except OSError:
  187. pass
  188. def test_rmtree_on_symlink(self):
  189. # bug 1669.
  190. os.mkdir(TESTFN)
  191. try:
  192. src = os.path.join(TESTFN, 'cheese')
  193. dst = os.path.join(TESTFN, 'shop')
  194. os.mkdir(src)
  195. os.symlink(src, dst)
  196. self.assertRaises(OSError, shutil.rmtree, dst)
  197. finally:
  198. shutil.rmtree(TESTFN, ignore_errors=True)
  199. class TestMove(unittest.TestCase):
  200. def setUp(self):
  201. filename = "foo"
  202. self.src_dir = tempfile.mkdtemp()
  203. self.dst_dir = tempfile.mkdtemp()
  204. self.src_file = os.path.join(self.src_dir, filename)
  205. self.dst_file = os.path.join(self.dst_dir, filename)
  206. # Try to create a dir in the current directory, hoping that it is
  207. # not located on the same filesystem as the system tmp dir.
  208. try:
  209. self.dir_other_fs = tempfile.mkdtemp(
  210. dir=os.path.dirname(__file__))
  211. self.file_other_fs = os.path.join(self.dir_other_fs,
  212. filename)
  213. except OSError:
  214. self.dir_other_fs = None
  215. with open(self.src_file, "wb") as f:
  216. f.write("spam")
  217. def tearDown(self):
  218. for d in (self.src_dir, self.dst_dir, self.dir_other_fs):
  219. try:
  220. if d:
  221. shutil.rmtree(d)
  222. except:
  223. pass
  224. def _check_move_file(self, src, dst, real_dst):
  225. contents = open(src, "rb").read()
  226. shutil.move(src, dst)
  227. self.assertEqual(contents, open(real_dst, "rb").read())
  228. self.assertFalse(os.path.exists(src))
  229. def _check_move_dir(self, src, dst, real_dst):
  230. contents = sorted(os.listdir(src))
  231. shutil.move(src, dst)
  232. self.assertEqual(contents, sorted(os.listdir(real_dst)))
  233. self.assertFalse(os.path.exists(src))
  234. def test_move_file(self):
  235. # Move a file to another location on the same filesystem.
  236. self._check_move_file(self.src_file, self.dst_file, self.dst_file)
  237. def test_move_file_to_dir(self):
  238. # Move a file inside an existing dir on the same filesystem.
  239. self._check_move_file(self.src_file, self.dst_dir, self.dst_file)
  240. def test_move_file_other_fs(self):
  241. # Move a file to an existing dir on another filesystem.
  242. if not self.dir_other_fs:
  243. # skip
  244. return
  245. self._check_move_file(self.src_file, self.file_other_fs,
  246. self.file_other_fs)
  247. def test_move_file_to_dir_other_fs(self):
  248. # Move a file to another location on another filesystem.
  249. if not self.dir_other_fs:
  250. # skip
  251. return
  252. self._check_move_file(self.src_file, self.dir_other_fs,
  253. self.file_other_fs)
  254. def test_move_dir(self):
  255. # Move a dir to another location on the same filesystem.
  256. dst_dir = tempfile.mktemp()
  257. try:
  258. self._check_move_dir(self.src_dir, dst_dir, dst_dir)
  259. finally:
  260. try:
  261. shutil.rmtree(dst_dir)
  262. except:
  263. pass
  264. def test_move_dir_other_fs(self):
  265. # Move a dir to another location on another filesystem.
  266. if not self.dir_other_fs:
  267. # skip
  268. return
  269. dst_dir = tempfile.mktemp(dir=self.dir_other_fs)
  270. try:
  271. self._check_move_dir(self.src_dir, dst_dir, dst_dir)
  272. finally:
  273. try:
  274. shutil.rmtree(dst_dir)
  275. except:
  276. pass
  277. def test_move_dir_to_dir(self):
  278. # Move a dir inside an existing dir on the same filesystem.
  279. self._check_move_dir(self.src_dir, self.dst_dir,
  280. os.path.join(self.dst_dir, os.path.basename(self.src_dir)))
  281. def test_move_dir_to_dir_other_fs(self):
  282. # Move a dir inside an existing dir on another filesystem.
  283. if not self.dir_other_fs:
  284. # skip
  285. return
  286. self._check_move_dir(self.src_dir, self.dir_other_fs,
  287. os.path.join(self.dir_other_fs, os.path.basename(self.src_dir)))
  288. def test_existing_file_inside_dest_dir(self):
  289. # A file with the same name inside the destination dir already exists.
  290. with open(self.dst_file, "wb"):
  291. pass
  292. self.assertRaises(shutil.Error, shutil.move, self.src_file, self.dst_dir)
  293. def test_dont_move_dir_in_itself(self):
  294. # Moving a dir inside itself raises an Error.
  295. dst = os.path.join(self.src_dir, "bar")
  296. self.assertRaises(shutil.Error, shutil.move, self.src_dir, dst)
  297. def test_destinsrc_false_negative(self):
  298. os.mkdir(TESTFN)
  299. try:
  300. for src, dst in [('srcdir', 'srcdir/dest')]:
  301. src = os.path.join(TESTFN, src)
  302. dst = os.path.join(TESTFN, dst)
  303. self.assert_(shutil._destinsrc(src, dst),
  304. msg='_destinsrc() wrongly concluded that '
  305. 'dst (%s) is not in src (%s)' % (dst, src))
  306. finally:
  307. shutil.rmtree(TESTFN, ignore_errors=True)
  308. def test_destinsrc_false_positive(self):
  309. os.mkdir(TESTFN)
  310. try:
  311. for src, dst in [('srcdir', 'src/dest'), ('srcdir', 'srcdir.new')]:
  312. src = os.path.join(TESTFN, src)
  313. dst = os.path.join(TESTFN, dst)
  314. self.failIf(shutil._destinsrc(src, dst),
  315. msg='_destinsrc() wrongly concluded that '
  316. 'dst (%s) is in src (%s)' % (dst, src))
  317. finally:
  318. shutil.rmtree(TESTFN, ignore_errors=True)
  319. def test_main():
  320. test_support.run_unittest(TestShutil, TestMove)
  321. if __name__ == '__main__':
  322. test_main()