1 # Copyright (C) 2003 Python Software Foundation
10 from test
import test_support
11 from test
.test_support
import TESTFN
13 class TestShutil(unittest
.TestCase
):
14 def test_rmtree_errors(self
):
15 # filename is guaranteed not to exist
16 filename
= tempfile
.mktemp()
17 self
.assertRaises(OSError, shutil
.rmtree
, filename
)
19 # See bug #1071513 for why we don't run this on cygwin
20 # and bug #1076467 for why we don't run this as root.
21 if (hasattr(os
, 'chmod') and sys
.platform
[:6] != 'cygwin'
22 and not (hasattr(os
, 'geteuid') and os
.geteuid() == 0)):
23 def test_on_error(self
):
26 self
.childpath
= os
.path
.join(TESTFN
, 'a')
27 f
= open(self
.childpath
, 'w')
29 old_dir_mode
= os
.stat(TESTFN
).st_mode
30 old_child_mode
= os
.stat(self
.childpath
).st_mode
32 os
.chmod(self
.childpath
, stat
.S_IREAD
)
33 os
.chmod(TESTFN
, stat
.S_IREAD
)
35 shutil
.rmtree(TESTFN
, onerror
=self
.check_args_to_onerror
)
36 # Test whether onerror has actually been called.
37 self
.assertEqual(self
.errorState
, 2,
38 "Expected call to onerror function did not happen.")
40 # Make writable again.
41 os
.chmod(TESTFN
, old_dir_mode
)
42 os
.chmod(self
.childpath
, old_child_mode
)
47 def check_args_to_onerror(self
, func
, arg
, exc
):
48 if self
.errorState
== 0:
49 self
.assertEqual(func
, os
.remove
)
50 self
.assertEqual(arg
, self
.childpath
)
51 self
.failUnless(issubclass(exc
[0], OSError))
54 self
.assertEqual(func
, os
.rmdir
)
55 self
.assertEqual(arg
, TESTFN
)
56 self
.failUnless(issubclass(exc
[0], OSError))
59 def test_rmtree_dont_delete_file(self
):
60 # When called on a file instead of a directory, don't delete it.
61 handle
, path
= tempfile
.mkstemp()
62 os
.fdopen(handle
).close()
63 self
.assertRaises(OSError, shutil
.rmtree
, path
)
66 def test_copytree_simple(self
):
67 def write_data(path
, data
):
78 src_dir
= tempfile
.mkdtemp()
79 dst_dir
= os
.path
.join(tempfile
.mkdtemp(), 'destination')
81 write_data(os
.path
.join(src_dir
, 'test.txt'), '123')
83 os
.mkdir(os
.path
.join(src_dir
, 'test_dir'))
84 write_data(os
.path
.join(src_dir
, 'test_dir', 'test.txt'), '456')
87 shutil
.copytree(src_dir
, dst_dir
)
88 self
.assertTrue(os
.path
.isfile(os
.path
.join(dst_dir
, 'test.txt')))
89 self
.assertTrue(os
.path
.isdir(os
.path
.join(dst_dir
, 'test_dir')))
90 self
.assertTrue(os
.path
.isfile(os
.path
.join(dst_dir
, 'test_dir',
92 actual
= read_data(os
.path
.join(dst_dir
, 'test.txt'))
93 self
.assertEqual(actual
, '123')
94 actual
= read_data(os
.path
.join(dst_dir
, 'test_dir', 'test.txt'))
95 self
.assertEqual(actual
, '456')
98 os
.path
.join(src_dir
, 'test.txt'),
99 os
.path
.join(dst_dir
, 'test.txt'),
100 os
.path
.join(src_dir
, 'test_dir', 'test.txt'),
101 os
.path
.join(dst_dir
, 'test_dir', 'test.txt'),
103 if os
.path
.exists(path
):
105 for path
in (src_dir
,
106 os
.path
.abspath(os
.path
.join(dst_dir
, os
.path
.pardir
))
108 if os
.path
.exists(path
):
111 def test_copytree_with_exclude(self
):
113 def write_data(path
, data
):
126 exists
= os
.path
.exists
127 src_dir
= tempfile
.mkdtemp()
128 dst_dir
= join(tempfile
.mkdtemp(), 'destination')
129 write_data(join(src_dir
, 'test.txt'), '123')
130 write_data(join(src_dir
, 'test.tmp'), '123')
131 os
.mkdir(join(src_dir
, 'test_dir'))
132 write_data(join(src_dir
, 'test_dir', 'test.txt'), '456')
133 os
.mkdir(join(src_dir
, 'test_dir2'))
134 write_data(join(src_dir
, 'test_dir2', 'test.txt'), '456')
135 os
.mkdir(join(src_dir
, 'test_dir2', 'subdir'))
136 os
.mkdir(join(src_dir
, 'test_dir2', 'subdir2'))
137 write_data(join(src_dir
, 'test_dir2', 'subdir', 'test.txt'), '456')
138 write_data(join(src_dir
, 'test_dir2', 'subdir2', 'test.py'), '456')
141 # testing glob-like patterns
143 patterns
= shutil
.ignore_patterns('*.tmp', 'test_dir2')
144 shutil
.copytree(src_dir
, dst_dir
, ignore
=patterns
)
145 # checking the result: some elements should not be copied
146 self
.assert_(exists(join(dst_dir
, 'test.txt')))
147 self
.assert_(not exists(join(dst_dir
, 'test.tmp')))
148 self
.assert_(not exists(join(dst_dir
, 'test_dir2')))
150 if os
.path
.exists(dst_dir
):
151 shutil
.rmtree(dst_dir
)
153 patterns
= shutil
.ignore_patterns('*.tmp', 'subdir*')
154 shutil
.copytree(src_dir
, dst_dir
, ignore
=patterns
)
155 # checking the result: some elements should not be copied
156 self
.assert_(not exists(join(dst_dir
, 'test.tmp')))
157 self
.assert_(not exists(join(dst_dir
, 'test_dir2', 'subdir2')))
158 self
.assert_(not exists(join(dst_dir
, 'test_dir2', 'subdir')))
160 if os
.path
.exists(dst_dir
):
161 shutil
.rmtree(dst_dir
)
163 # testing callable-style
165 def _filter(src
, names
):
168 path
= os
.path
.join(src
, name
)
170 if (os
.path
.isdir(path
) and
171 path
.split()[-1] == 'subdir'):
173 elif os
.path
.splitext(path
)[-1] in ('.py'):
177 shutil
.copytree(src_dir
, dst_dir
, ignore
=_filter
)
179 # checking the result: some elements should not be copied
180 self
.assert_(not exists(join(dst_dir
, 'test_dir2', 'subdir2',
182 self
.assert_(not exists(join(dst_dir
, 'test_dir2', 'subdir')))
185 if os
.path
.exists(dst_dir
):
186 shutil
.rmtree(dst_dir
)
188 if hasattr(os
, "symlink"):
189 def test_dont_copy_file_onto_link_to_itself(self
):
192 src
= os
.path
.join(TESTFN
, 'cheese')
193 dst
= os
.path
.join(TESTFN
, 'shop')
200 self
.assertRaises(shutil
.Error
, shutil
.copyfile
, src
, dst
)
201 self
.assertEqual(open(src
,'r').read(), 'cheddar')
204 # Using `src` here would mean we end up with a symlink pointing
205 # to TESTFN/TESTFN/cheese, while it should point at
207 os
.symlink('cheese', dst
)
208 self
.assertRaises(shutil
.Error
, shutil
.copyfile
, src
, dst
)
209 self
.assertEqual(open(src
,'r').read(), 'cheddar')
213 shutil
.rmtree(TESTFN
)
217 def test_rmtree_on_symlink(self
):
221 src
= os
.path
.join(TESTFN
, 'cheese')
222 dst
= os
.path
.join(TESTFN
, 'shop')
225 self
.assertRaises(OSError, shutil
.rmtree
, dst
)
227 shutil
.rmtree(TESTFN
, ignore_errors
=True)
230 class TestMove(unittest
.TestCase
):
234 self
.src_dir
= tempfile
.mkdtemp()
235 self
.dst_dir
= tempfile
.mkdtemp()
236 self
.src_file
= os
.path
.join(self
.src_dir
, filename
)
237 self
.dst_file
= os
.path
.join(self
.dst_dir
, filename
)
238 # Try to create a dir in the current directory, hoping that it is
239 # not located on the same filesystem as the system tmp dir.
241 self
.dir_other_fs
= tempfile
.mkdtemp(
242 dir=os
.path
.dirname(__file__
))
243 self
.file_other_fs
= os
.path
.join(self
.dir_other_fs
,
246 self
.dir_other_fs
= None
247 with
open(self
.src_file
, "wb") as f
:
251 for d
in (self
.src_dir
, self
.dst_dir
, self
.dir_other_fs
):
258 def _check_move_file(self
, src
, dst
, real_dst
):
259 contents
= open(src
, "rb").read()
260 shutil
.move(src
, dst
)
261 self
.assertEqual(contents
, open(real_dst
, "rb").read())
262 self
.assertFalse(os
.path
.exists(src
))
264 def _check_move_dir(self
, src
, dst
, real_dst
):
265 contents
= sorted(os
.listdir(src
))
266 shutil
.move(src
, dst
)
267 self
.assertEqual(contents
, sorted(os
.listdir(real_dst
)))
268 self
.assertFalse(os
.path
.exists(src
))
270 def test_move_file(self
):
271 # Move a file to another location on the same filesystem.
272 self
._check
_move
_file
(self
.src_file
, self
.dst_file
, self
.dst_file
)
274 def test_move_file_to_dir(self
):
275 # Move a file inside an existing dir on the same filesystem.
276 self
._check
_move
_file
(self
.src_file
, self
.dst_dir
, self
.dst_file
)
278 def test_move_file_other_fs(self
):
279 # Move a file to an existing dir on another filesystem.
280 if not self
.dir_other_fs
:
283 self
._check
_move
_file
(self
.src_file
, self
.file_other_fs
,
286 def test_move_file_to_dir_other_fs(self
):
287 # Move a file to another location on another filesystem.
288 if not self
.dir_other_fs
:
291 self
._check
_move
_file
(self
.src_file
, self
.dir_other_fs
,
294 def test_move_dir(self
):
295 # Move a dir to another location on the same filesystem.
296 dst_dir
= tempfile
.mktemp()
298 self
._check
_move
_dir
(self
.src_dir
, dst_dir
, dst_dir
)
301 shutil
.rmtree(dst_dir
)
305 def test_move_dir_other_fs(self
):
306 # Move a dir to another location on another filesystem.
307 if not self
.dir_other_fs
:
310 dst_dir
= tempfile
.mktemp(dir=self
.dir_other_fs
)
312 self
._check
_move
_dir
(self
.src_dir
, dst_dir
, dst_dir
)
315 shutil
.rmtree(dst_dir
)
319 def test_move_dir_to_dir(self
):
320 # Move a dir inside an existing dir on the same filesystem.
321 self
._check
_move
_dir
(self
.src_dir
, self
.dst_dir
,
322 os
.path
.join(self
.dst_dir
, os
.path
.basename(self
.src_dir
)))
324 def test_move_dir_to_dir_other_fs(self
):
325 # Move a dir inside an existing dir on another filesystem.
326 if not self
.dir_other_fs
:
329 self
._check
_move
_dir
(self
.src_dir
, self
.dir_other_fs
,
330 os
.path
.join(self
.dir_other_fs
, os
.path
.basename(self
.src_dir
)))
332 def test_existing_file_inside_dest_dir(self
):
333 # A file with the same name inside the destination dir already exists.
334 with
open(self
.dst_file
, "wb"):
336 self
.assertRaises(shutil
.Error
, shutil
.move
, self
.src_file
, self
.dst_dir
)
338 def test_dont_move_dir_in_itself(self
):
339 # Moving a dir inside itself raises an Error.
340 dst
= os
.path
.join(self
.src_dir
, "bar")
341 self
.assertRaises(shutil
.Error
, shutil
.move
, self
.src_dir
, dst
)
346 test_support
.run_unittest(TestShutil
, TestMove
)
348 if __name__
== '__main__':