Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(197521)

Delta Between Two Patch Sets: Lib/test/test_shutil.py

Issue 16510: Using appropriate checks in tests
Left Patch Set: Created 6 years, 3 months ago
Right Patch Set: Created 5 years, 10 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Lib/test/test_selectors.py ('k') | Lib/test/test_slice.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # Copyright (C) 2003 Python Software Foundation 1 # Copyright (C) 2003 Python Software Foundation
2 2
3 import unittest 3 import unittest
4 import shutil 4 import shutil
5 import tempfile 5 import tempfile
6 import sys 6 import sys
7 import stat 7 import stat
8 import os 8 import os
9 import os.path 9 import os.path
10 import errno 10 import errno
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 self.assertIs(errors[0][0], os.listdir) 188 self.assertIs(errors[0][0], os.listdir)
189 self.assertEqual(errors[0][1], filename) 189 self.assertEqual(errors[0][1], filename)
190 self.assertIsInstance(errors[0][2][1], NotADirectoryError) 190 self.assertIsInstance(errors[0][2][1], NotADirectoryError)
191 self.assertIn(errors[0][2][1].filename, possible_args) 191 self.assertIn(errors[0][2][1].filename, possible_args)
192 self.assertIs(errors[1][0], os.rmdir) 192 self.assertIs(errors[1][0], os.rmdir)
193 self.assertEqual(errors[1][1], filename) 193 self.assertEqual(errors[1][1], filename)
194 self.assertIsInstance(errors[1][2][1], NotADirectoryError) 194 self.assertIsInstance(errors[1][2][1], NotADirectoryError)
195 self.assertIn(errors[1][2][1].filename, possible_args) 195 self.assertIn(errors[1][2][1].filename, possible_args)
196 196
197 197
198 # See bug #1071513 for why we don't run this on cygwin 198 @unittest.skipUnless(hasattr(os, 'chmod'), 'requires os.chmod()')
199 # and bug #1076467 for why we don't run this as root. 199 @unittest.skipIf(sys.platform[:6] == 'cygwin',
200 if (hasattr(os, 'chmod') and sys.platform[:6] != 'cygwin' 200 "This test can't be run on Cygwin (issue #1071513).")
201 and not (hasattr(os, 'geteuid') and os.geteuid() == 0)): 201 @unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0,
202 def test_on_error(self): 202 "This test can't be run reliably as root (issue #1076467)." )
203 self.errorState = 0 203 def test_on_error(self):
204 os.mkdir(TESTFN) 204 self.errorState = 0
205 self.addCleanup(shutil.rmtree, TESTFN) 205 os.mkdir(TESTFN)
206 206 self.addCleanup(shutil.rmtree, TESTFN)
207 self.child_file_path = os.path.join(TESTFN, 'a') 207
208 self.child_dir_path = os.path.join(TESTFN, 'b') 208 self.child_file_path = os.path.join(TESTFN, 'a')
209 support.create_empty_file(self.child_file_path) 209 self.child_dir_path = os.path.join(TESTFN, 'b')
210 os.mkdir(self.child_dir_path) 210 support.create_empty_file(self.child_file_path)
211 old_dir_mode = os.stat(TESTFN).st_mode 211 os.mkdir(self.child_dir_path)
212 old_child_file_mode = os.stat(self.child_file_path).st_mode 212 old_dir_mode = os.stat(TESTFN).st_mode
213 old_child_dir_mode = os.stat(self.child_dir_path).st_mode 213 old_child_file_mode = os.stat(self.child_file_path).st_mode
214 # Make unwritable. 214 old_child_dir_mode = os.stat(self.child_dir_path).st_mode
215 new_mode = stat.S_IREAD|stat.S_IEXEC 215 # Make unwritable.
216 os.chmod(self.child_file_path, new_mode) 216 new_mode = stat.S_IREAD|stat.S_IEXEC
217 os.chmod(self.child_dir_path, new_mode) 217 os.chmod(self.child_file_path, new_mode)
218 os.chmod(TESTFN, new_mode) 218 os.chmod(self.child_dir_path, new_mode)
219 219 os.chmod(TESTFN, new_mode)
220 self.addCleanup(os.chmod, TESTFN, old_dir_mode) 220
221 self.addCleanup(os.chmod, self.child_file_path, old_child_file_mode) 221 self.addCleanup(os.chmod, TESTFN, old_dir_mode)
222 self.addCleanup(os.chmod, self.child_dir_path, old_child_dir_mode) 222 self.addCleanup(os.chmod, self.child_file_path, old_child_file_mode)
223 223 self.addCleanup(os.chmod, self.child_dir_path, old_child_dir_mode)
224 shutil.rmtree(TESTFN, onerror=self.check_args_to_onerror) 224
225 # Test whether onerror has actually been called. 225 shutil.rmtree(TESTFN, onerror=self.check_args_to_onerror)
226 self.assertEqual(self.errorState, 3, 226 # Test whether onerror has actually been called.
227 "Expected call to onerror function did not " 227 self.assertEqual(self.errorState, 3,
228 "happen.") 228 "Expected call to onerror function did not happen.")
229 229
230 def check_args_to_onerror(self, func, arg, exc): 230 def check_args_to_onerror(self, func, arg, exc):
231 # test_rmtree_errors deliberately runs rmtree 231 # test_rmtree_errors deliberately runs rmtree
232 # on a directory that is chmod 500, which will fail. 232 # on a directory that is chmod 500, which will fail.
233 # This function is run when shutil.rmtree fails. 233 # This function is run when shutil.rmtree fails.
234 # 99.9% of the time it initially fails to remove 234 # 99.9% of the time it initially fails to remove
235 # a file in the directory, so the first time through 235 # a file in the directory, so the first time through
236 # func is os.remove. 236 # func is os.remove.
237 # However, some Linux machines running ZFS on 237 # However, some Linux machines running ZFS on
238 # FUSE experienced a failure earlier in the process 238 # FUSE experienced a failure earlier in the process
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 write_file(src, 'foo') 281 write_file(src, 'foo')
282 write_file(dst, 'foo') 282 write_file(dst, 'foo')
283 os.symlink(src, src_link) 283 os.symlink(src, src_link)
284 os.symlink(dst, dst_link) 284 os.symlink(dst, dst_link)
285 os.chmod(src, stat.S_IRWXU|stat.S_IRWXG) 285 os.chmod(src, stat.S_IRWXU|stat.S_IRWXG)
286 # file to file 286 # file to file
287 os.chmod(dst, stat.S_IRWXO) 287 os.chmod(dst, stat.S_IRWXO)
288 self.assertNotEqual(os.stat(src).st_mode, os.stat(dst).st_mode) 288 self.assertNotEqual(os.stat(src).st_mode, os.stat(dst).st_mode)
289 shutil.copymode(src, dst) 289 shutil.copymode(src, dst)
290 self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode) 290 self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode)
291 # follow src link 291 # On Windows, os.chmod does not follow symlinks (issue #15411)
292 os.chmod(dst, stat.S_IRWXO) 292 if os.name != 'nt':
293 shutil.copymode(src_link, dst) 293 # follow src link
294 self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode) 294 os.chmod(dst, stat.S_IRWXO)
295 # follow dst link 295 shutil.copymode(src_link, dst)
296 os.chmod(dst, stat.S_IRWXO) 296 self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode)
297 shutil.copymode(src, dst_link) 297 # follow dst link
298 self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode) 298 os.chmod(dst, stat.S_IRWXO)
299 # follow both links 299 shutil.copymode(src, dst_link)
300 os.chmod(dst, stat.S_IRWXO) 300 self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode)
301 shutil.copymode(src_link, dst) 301 # follow both links
302 self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode) 302 os.chmod(dst, stat.S_IRWXO)
303 shutil.copymode(src_link, dst_link)
304 self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode)
303 305
304 @unittest.skipUnless(hasattr(os, 'lchmod'), 'requires os.lchmod') 306 @unittest.skipUnless(hasattr(os, 'lchmod'), 'requires os.lchmod')
305 @support.skip_unless_symlink 307 @support.skip_unless_symlink
306 def test_copymode_symlink_to_symlink(self): 308 def test_copymode_symlink_to_symlink(self):
307 tmp_dir = self.mkdtemp() 309 tmp_dir = self.mkdtemp()
308 src = os.path.join(tmp_dir, 'foo') 310 src = os.path.join(tmp_dir, 'foo')
309 dst = os.path.join(tmp_dir, 'bar') 311 dst = os.path.join(tmp_dir, 'bar')
310 src_link = os.path.join(tmp_dir, 'baz') 312 src_link = os.path.join(tmp_dir, 'baz')
311 dst_link = os.path.join(tmp_dir, 'quux') 313 dst_link = os.path.join(tmp_dir, 'quux')
312 write_file(src, 'foo') 314 write_file(src, 'foo')
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 write_file(src, 'foo') 424 write_file(src, 'foo')
423 dst = os.path.join(tmp_dir, 'bar') 425 dst = os.path.join(tmp_dir, 'bar')
424 write_file(dst, 'bar') 426 write_file(dst, 'bar')
425 427
426 # no xattr == no problem 428 # no xattr == no problem
427 shutil._copyxattr(src, dst) 429 shutil._copyxattr(src, dst)
428 # common case 430 # common case
429 os.setxattr(src, 'user.foo', b'42') 431 os.setxattr(src, 'user.foo', b'42')
430 os.setxattr(src, 'user.bar', b'43') 432 os.setxattr(src, 'user.bar', b'43')
431 shutil._copyxattr(src, dst) 433 shutil._copyxattr(src, dst)
432 self.assertEqual(os.listxattr(src), os.listxattr(dst)) 434 self.assertEqual(sorted(os.listxattr(src)), sorted(os.listxattr(dst)))
433 self.assertEqual( 435 self.assertEqual(
434 os.getxattr(src, 'user.foo'), 436 os.getxattr(src, 'user.foo'),
435 os.getxattr(dst, 'user.foo')) 437 os.getxattr(dst, 'user.foo'))
436 # check errors don't affect other attrs 438 # check errors don't affect other attrs
437 os.remove(dst) 439 os.remove(dst)
438 write_file(dst, 'bar') 440 write_file(dst, 'bar')
439 os_error = OSError(errno.EPERM, 'EPERM') 441 os_error = OSError(errno.EPERM, 'EPERM')
440 442
441 def _raise_on_user_foo(fname, attr, val, **kwargs): 443 def _raise_on_user_foo(fname, attr, val, **kwargs):
442 if attr == 'user.foo': 444 if attr == 'user.foo':
443 raise os_error 445 raise os_error
444 else: 446 else:
445 orig_setxattr(fname, attr, val, **kwargs) 447 orig_setxattr(fname, attr, val, **kwargs)
446 try: 448 try:
447 orig_setxattr = os.setxattr 449 orig_setxattr = os.setxattr
448 os.setxattr = _raise_on_user_foo 450 os.setxattr = _raise_on_user_foo
449 shutil._copyxattr(src, dst) 451 shutil._copyxattr(src, dst)
450 self.assertIn('user.bar', os.listxattr(dst)) 452 self.assertIn('user.bar', os.listxattr(dst))
451 finally: 453 finally:
452 os.setxattr = orig_setxattr 454 os.setxattr = orig_setxattr
455 # the source filesystem not supporting xattrs should be ok, too.
456 def _raise_on_src(fname, *, follow_symlinks=True):
457 if fname == src:
458 raise OSError(errno.ENOTSUP, 'Operation not supported')
459 return orig_listxattr(fname, follow_symlinks=follow_symlinks)
460 try:
461 orig_listxattr = os.listxattr
462 os.listxattr = _raise_on_src
463 shutil._copyxattr(src, dst)
464 finally:
465 os.listxattr = orig_listxattr
453 466
454 # test that shutil.copystat copies xattrs 467 # test that shutil.copystat copies xattrs
455 src = os.path.join(tmp_dir, 'the_original') 468 src = os.path.join(tmp_dir, 'the_original')
456 write_file(src, src) 469 write_file(src, src)
457 os.setxattr(src, 'user.the_value', b'fiddly') 470 os.setxattr(src, 'user.the_value', b'fiddly')
458 dst = os.path.join(tmp_dir, 'the_copy') 471 dst = os.path.join(tmp_dir, 'the_copy')
459 write_file(dst, dst) 472 write_file(dst, dst)
460 shutil.copystat(src, dst) 473 shutil.copystat(src, dst)
461 self.assertEqual(os.getxattr(dst, 'user.the_value'), b'fiddly') 474 self.assertEqual(os.getxattr(dst, 'user.the_value'), b'fiddly')
462 475
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 self.assertFalse(exists(join(dst_dir, 'test_dir2', 'subdir2', 722 self.assertFalse(exists(join(dst_dir, 'test_dir2', 'subdir2',
710 'test.py'))) 723 'test.py')))
711 self.assertFalse(exists(join(dst_dir, 'test_dir2', 'subdir'))) 724 self.assertFalse(exists(join(dst_dir, 'test_dir2', 'subdir')))
712 725
713 finally: 726 finally:
714 shutil.rmtree(dst_dir) 727 shutil.rmtree(dst_dir)
715 finally: 728 finally:
716 shutil.rmtree(src_dir) 729 shutil.rmtree(src_dir)
717 shutil.rmtree(os.path.dirname(dst_dir)) 730 shutil.rmtree(os.path.dirname(dst_dir))
718 731
732 def test_copytree_retains_permissions(self):
733 tmp_dir = tempfile.mkdtemp()
734 src_dir = os.path.join(tmp_dir, 'source')
735 os.mkdir(src_dir)
736 dst_dir = os.path.join(tmp_dir, 'destination')
737 self.addCleanup(shutil.rmtree, tmp_dir)
738
739 os.chmod(src_dir, 0o777)
740 write_file((src_dir, 'permissive.txt'), '123')
741 os.chmod(os.path.join(src_dir, 'permissive.txt'), 0o777)
742 write_file((src_dir, 'restrictive.txt'), '456')
743 os.chmod(os.path.join(src_dir, 'restrictive.txt'), 0o600)
744 restrictive_subdir = tempfile.mkdtemp(dir=src_dir)
745 os.chmod(restrictive_subdir, 0o600)
746
747 shutil.copytree(src_dir, dst_dir)
748 self.assertEqual(os.stat(src_dir).st_mode, os.stat(dst_dir).st_mode)
749 self.assertEqual(os.stat(os.path.join(src_dir, 'permissive.txt')).st_mod e,
750 os.stat(os.path.join(dst_dir, 'permissive.txt')).st_mo de)
751 self.assertEqual(os.stat(os.path.join(src_dir, 'restrictive.txt')).st_mo de,
752 os.stat(os.path.join(dst_dir, 'restrictive.txt')).st_m ode)
753 restrictive_subdir_dst = os.path.join(dst_dir,
754 os.path.split(restrictive_subdir)[ 1])
755 self.assertEqual(os.stat(restrictive_subdir).st_mode,
756 os.stat(restrictive_subdir_dst).st_mode)
757
758 @unittest.skipIf(os.name == 'nt', 'temporarily disabled on Windows')
719 @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link') 759 @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link')
720 def test_dont_copy_file_onto_link_to_itself(self): 760 def test_dont_copy_file_onto_link_to_itself(self):
721 # Temporarily disable test on Windows.
722 if os.name == 'nt':
723 return
724 # bug 851123. 761 # bug 851123.
725 os.mkdir(TESTFN) 762 os.mkdir(TESTFN)
726 src = os.path.join(TESTFN, 'cheese') 763 src = os.path.join(TESTFN, 'cheese')
727 dst = os.path.join(TESTFN, 'shop') 764 dst = os.path.join(TESTFN, 'shop')
728 try: 765 try:
729 with open(src, 'w') as f: 766 with open(src, 'w') as f:
730 f.write('cheddar') 767 f.write('cheddar')
731 os.link(src, dst) 768 os.link(src, dst)
732 self.assertRaises(shutil.SameFileError, shutil.copyfile, src, dst) 769 self.assertRaises(shutil.SameFileError, shutil.copyfile, src, dst)
733 with open(src, 'r') as f: 770 with open(src, 'r') as f:
(...skipping 29 matching lines...) Expand all
763 try: 800 try:
764 src = os.path.join(TESTFN, 'cheese') 801 src = os.path.join(TESTFN, 'cheese')
765 dst = os.path.join(TESTFN, 'shop') 802 dst = os.path.join(TESTFN, 'shop')
766 os.mkdir(src) 803 os.mkdir(src)
767 os.symlink(src, dst) 804 os.symlink(src, dst)
768 self.assertRaises(OSError, shutil.rmtree, dst) 805 self.assertRaises(OSError, shutil.rmtree, dst)
769 shutil.rmtree(dst, ignore_errors=True) 806 shutil.rmtree(dst, ignore_errors=True)
770 finally: 807 finally:
771 shutil.rmtree(TESTFN, ignore_errors=True) 808 shutil.rmtree(TESTFN, ignore_errors=True)
772 809
773 if hasattr(os, "mkfifo"): 810 # Issue #3002: copyfile and copytree block indefinitely on named pipes
774 # Issue #3002: copyfile and copytree block indefinitely on named pipes 811 @unittest.skipUnless(hasattr(os, "mkfifo"), 'requires os.mkfifo()')
775 def test_copyfile_named_pipe(self): 812 def test_copyfile_named_pipe(self):
776 os.mkfifo(TESTFN) 813 os.mkfifo(TESTFN)
814 try:
815 self.assertRaises(shutil.SpecialFileError,
816 shutil.copyfile, TESTFN, TESTFN2)
817 self.assertRaises(shutil.SpecialFileError,
818 shutil.copyfile, __file__, TESTFN)
819 finally:
820 os.remove(TESTFN)
821
822 @unittest.skipUnless(hasattr(os, "mkfifo"), 'requires os.mkfifo()')
823 @support.skip_unless_symlink
824 def test_copytree_named_pipe(self):
825 os.mkdir(TESTFN)
826 try:
827 subdir = os.path.join(TESTFN, "subdir")
828 os.mkdir(subdir)
829 pipe = os.path.join(subdir, "mypipe")
830 os.mkfifo(pipe)
777 try: 831 try:
778 self.assertRaises(shutil.SpecialFileError, 832 shutil.copytree(TESTFN, TESTFN2)
779 shutil.copyfile, TESTFN, TESTFN2) 833 except shutil.Error as e:
780 self.assertRaises(shutil.SpecialFileError, 834 errors = e.args[0]
781 shutil.copyfile, __file__, TESTFN) 835 self.assertEqual(len(errors), 1)
782 finally: 836 src, dst, error_msg = errors[0]
783 os.remove(TESTFN) 837 self.assertEqual("`%s` is a named pipe" % pipe, error_msg)
784 838 else:
785 @support.skip_unless_symlink 839 self.fail("shutil.Error should have been raised")
786 def test_copytree_named_pipe(self): 840 finally:
787 os.mkdir(TESTFN) 841 shutil.rmtree(TESTFN, ignore_errors=True)
788 try: 842 shutil.rmtree(TESTFN2, ignore_errors=True)
789 subdir = os.path.join(TESTFN, "subdir")
790 os.mkdir(subdir)
791 pipe = os.path.join(subdir, "mypipe")
792 os.mkfifo(pipe)
793 try:
794 shutil.copytree(TESTFN, TESTFN2)
795 except shutil.Error as e:
796 errors = e.args[0]
797 self.assertEqual(len(errors), 1)
798 src, dst, error_msg = errors[0]
799 self.assertEqual("`%s` is a named pipe" % pipe, error_msg)
800 else:
801 self.fail("shutil.Error should have been raised")
802 finally:
803 shutil.rmtree(TESTFN, ignore_errors=True)
804 shutil.rmtree(TESTFN2, ignore_errors=True)
805 843
806 def test_copytree_special_func(self): 844 def test_copytree_special_func(self):
807 845
808 src_dir = self.mkdtemp() 846 src_dir = self.mkdtemp()
809 dst_dir = os.path.join(self.mkdtemp(), 'destination') 847 dst_dir = os.path.join(self.mkdtemp(), 'destination')
810 write_file((src_dir, 'test.txt'), '123') 848 write_file((src_dir, 'test.txt'), '123')
811 os.mkdir(os.path.join(src_dir, 'test_dir')) 849 os.mkdir(os.path.join(src_dir, 'test_dir'))
812 write_file((src_dir, 'test_dir', 'test.txt'), '456') 850 write_file((src_dir, 'test_dir', 'test.txt'), '456')
813 851
814 copied = [] 852 copied = []
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
1273 self.addCleanup(shutil.rmtree, dst_dir, True) 1311 self.addCleanup(shutil.rmtree, dst_dir, True)
1274 src = os.path.join(src_dir, 'foo') 1312 src = os.path.join(src_dir, 'foo')
1275 write_file(src, 'foo') 1313 write_file(src, 'foo')
1276 rv = shutil.copytree(src_dir, dst_dir) 1314 rv = shutil.copytree(src_dir, dst_dir)
1277 self.assertEqual(['foo'], os.listdir(rv)) 1315 self.assertEqual(['foo'], os.listdir(rv))
1278 1316
1279 1317
1280 class TestWhich(unittest.TestCase): 1318 class TestWhich(unittest.TestCase):
1281 1319
1282 def setUp(self): 1320 def setUp(self):
1283 self.temp_dir = tempfile.mkdtemp() 1321 self.temp_dir = tempfile.mkdtemp(prefix="Tmp")
1284 self.addCleanup(shutil.rmtree, self.temp_dir, True) 1322 self.addCleanup(shutil.rmtree, self.temp_dir, True)
1285 # Give the temp_file an ".exe" suffix for all. 1323 # Give the temp_file an ".exe" suffix for all.
1286 # It's needed on Windows and not harmful on other platforms. 1324 # It's needed on Windows and not harmful on other platforms.
1287 self.temp_file = tempfile.NamedTemporaryFile(dir=self.temp_dir, 1325 self.temp_file = tempfile.NamedTemporaryFile(dir=self.temp_dir,
1288 suffix=".exe") 1326 prefix="Tmp",
1327 suffix=".Exe")
1289 os.chmod(self.temp_file.name, stat.S_IXUSR) 1328 os.chmod(self.temp_file.name, stat.S_IXUSR)
1290 self.addCleanup(self.temp_file.close) 1329 self.addCleanup(self.temp_file.close)
1291 self.dir, self.file = os.path.split(self.temp_file.name) 1330 self.dir, self.file = os.path.split(self.temp_file.name)
1292 1331
1293 def test_basic(self): 1332 def test_basic(self):
1294 # Given an EXE in a directory, it should be returned. 1333 # Given an EXE in a directory, it should be returned.
1295 rv = shutil.which(self.file, path=self.dir) 1334 rv = shutil.which(self.file, path=self.dir)
1296 self.assertEqual(rv, self.temp_file.name) 1335 self.assertEqual(rv, self.temp_file.name)
1297 1336
1298 def test_full_path_short_circuit(self): 1337 def test_absolute_cmd(self):
1299 # When given the fully qualified path to an executable that exists, 1338 # When given the fully qualified path to an executable that exists,
1300 # it should be returned. 1339 # it should be returned.
1301 rv = shutil.which(self.temp_file.name, path=self.temp_dir) 1340 rv = shutil.which(self.temp_file.name, path=self.temp_dir)
1302 self.assertEqual(self.temp_file.name, rv) 1341 self.assertEqual(rv, self.temp_file.name)
1303 1342
1343 def test_relative_cmd(self):
1344 # When given the relative path with a directory part to an executable
1345 # that exists, it should be returned.
1346 base_dir, tail_dir = os.path.split(self.dir)
1347 relpath = os.path.join(tail_dir, self.file)
1348 with support.change_cwd(path=base_dir):
1349 rv = shutil.which(relpath, path=self.temp_dir)
1350 self.assertEqual(rv, relpath)
1351 # But it shouldn't be searched in PATH directories (issue #16957).
1352 with support.change_cwd(path=self.dir):
1353 rv = shutil.which(relpath, path=base_dir)
1354 self.assertIsNone(rv)
1355
1356 def test_cwd(self):
1357 # Issue #16957
1358 base_dir = os.path.dirname(self.dir)
1359 with support.change_cwd(path=self.dir):
1360 rv = shutil.which(self.file, path=base_dir)
1361 if sys.platform == "win32":
1362 # Windows: current directory implicitly on PATH
1363 self.assertEqual(rv, os.path.join(os.curdir, self.file))
1364 else:
1365 # Other platforms: shouldn't match in the current directory.
1366 self.assertIsNone(rv)
1367
1368 @unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0,
1369 'non-root user required')
1304 def test_non_matching_mode(self): 1370 def test_non_matching_mode(self):
1305 # Set the file read-only and ask for writeable files. 1371 # Set the file read-only and ask for writeable files.
1306 os.chmod(self.temp_file.name, stat.S_IREAD) 1372 os.chmod(self.temp_file.name, stat.S_IREAD)
1373 if os.access(self.temp_file.name, os.W_OK):
1374 self.skipTest("can't set the file read-only")
1307 rv = shutil.which(self.file, path=self.dir, mode=os.W_OK) 1375 rv = shutil.which(self.file, path=self.dir, mode=os.W_OK)
1308 self.assertIsNone(rv) 1376 self.assertIsNone(rv)
1309 1377
1310 def test_relative(self): 1378 def test_relative_path(self):
1311 old_cwd = os.getcwd()
1312 base_dir, tail_dir = os.path.split(self.dir) 1379 base_dir, tail_dir = os.path.split(self.dir)
1313 os.chdir(base_dir) 1380 with support.change_cwd(path=base_dir):
1314 try:
1315 rv = shutil.which(self.file, path=tail_dir) 1381 rv = shutil.which(self.file, path=tail_dir)
1316 self.assertEqual(rv, os.path.join(tail_dir, self.file)) 1382 self.assertEqual(rv, os.path.join(tail_dir, self.file))
1317 finally:
1318 os.chdir(old_cwd)
1319 1383
1320 def test_nonexistent_file(self): 1384 def test_nonexistent_file(self):
1321 # Return None when no matching executable file is found on the path. 1385 # Return None when no matching executable file is found on the path.
1322 rv = shutil.which("foo.exe", path=self.dir) 1386 rv = shutil.which("foo.exe", path=self.dir)
1323 self.assertIsNone(rv) 1387 self.assertIsNone(rv)
1324 1388
1325 @unittest.skipUnless(sys.platform == "win32", 1389 @unittest.skipUnless(sys.platform == "win32",
1326 "pathext check is Windows-only") 1390 "pathext check is Windows-only")
1327 def test_pathext_checking(self): 1391 def test_pathext_checking(self):
1328 # Ask for the file without the ".exe" extension, then ensure that 1392 # Ask for the file without the ".exe" extension, then ensure that
1329 # it gets found properly with the extension. 1393 # it gets found properly with the extension.
1330 rv = shutil.which(self.temp_file.name[:-4], path=self.dir) 1394 rv = shutil.which(self.file[:-4], path=self.dir)
1331 self.assertEqual(self.temp_file.name, rv) 1395 self.assertEqual(rv, self.temp_file.name[:-4] + ".EXE")
1396
1397 def test_environ_path(self):
1398 with support.EnvironmentVarGuard() as env:
1399 env['PATH'] = self.dir
1400 rv = shutil.which(self.file)
1401 self.assertEqual(rv, self.temp_file.name)
1402
1403 def test_empty_path(self):
1404 base_dir = os.path.dirname(self.dir)
1405 with support.change_cwd(path=self.dir), \
1406 support.EnvironmentVarGuard() as env:
1407 env['PATH'] = self.dir
1408 rv = shutil.which(self.file, path='')
1409 self.assertIsNone(rv)
1410
1411 def test_empty_path_no_PATH(self):
1412 with support.EnvironmentVarGuard() as env:
1413 env.pop('PATH', None)
1414 rv = shutil.which(self.file)
1415 self.assertIsNone(rv)
1332 1416
1333 1417
1334 class TestMove(unittest.TestCase): 1418 class TestMove(unittest.TestCase):
1335 1419
1336 def setUp(self): 1420 def setUp(self):
1337 filename = "foo" 1421 filename = "foo"
1338 self.src_dir = tempfile.mkdtemp() 1422 self.src_dir = tempfile.mkdtemp()
1339 self.dst_dir = tempfile.mkdtemp() 1423 self.dst_dir = tempfile.mkdtemp()
1340 self.src_file = os.path.join(self.src_dir, filename) 1424 self.src_file = os.path.join(self.src_dir, filename)
1341 self.dst_file = os.path.join(self.dst_dir, filename) 1425 self.dst_file = os.path.join(self.dst_dir, filename)
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1465 1549
1466 @support.skip_unless_symlink 1550 @support.skip_unless_symlink
1467 @mock_rename 1551 @mock_rename
1468 def test_move_dangling_symlink(self): 1552 def test_move_dangling_symlink(self):
1469 src = os.path.join(self.src_dir, 'baz') 1553 src = os.path.join(self.src_dir, 'baz')
1470 dst = os.path.join(self.src_dir, 'bar') 1554 dst = os.path.join(self.src_dir, 'bar')
1471 os.symlink(src, dst) 1555 os.symlink(src, dst)
1472 dst_link = os.path.join(self.dst_dir, 'quux') 1556 dst_link = os.path.join(self.dst_dir, 'quux')
1473 shutil.move(dst, dst_link) 1557 shutil.move(dst, dst_link)
1474 self.assertTrue(os.path.islink(dst_link)) 1558 self.assertTrue(os.path.islink(dst_link))
1475 self.assertEqual(os.path.realpath(src), os.path.realpath(dst_link)) 1559 # On Windows, os.path.realpath does not follow symlinks (issue #9949)
1560 if os.name == 'nt':
1561 self.assertEqual(os.path.realpath(src), os.readlink(dst_link))
1562 else:
1563 self.assertEqual(os.path.realpath(src), os.path.realpath(dst_link))
1476 1564
1477 @support.skip_unless_symlink 1565 @support.skip_unless_symlink
1478 @mock_rename 1566 @mock_rename
1479 def test_move_dir_symlink(self): 1567 def test_move_dir_symlink(self):
1480 src = os.path.join(self.src_dir, 'baz') 1568 src = os.path.join(self.src_dir, 'baz')
1481 dst = os.path.join(self.src_dir, 'bar') 1569 dst = os.path.join(self.src_dir, 'bar')
1482 os.mkdir(src) 1570 os.mkdir(src)
1483 os.symlink(src, dst) 1571 os.symlink(src, dst)
1484 dst_link = os.path.join(self.dst_dir, 'quux') 1572 dst_link = os.path.join(self.dst_dir, 'quux')
1485 shutil.move(dst, dst_link) 1573 shutil.move(dst, dst_link)
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1655 expected = (int(size[1]), int(size[0])) # reversed order 1743 expected = (int(size[1]), int(size[0])) # reversed order
1656 1744
1657 with support.EnvironmentVarGuard() as env: 1745 with support.EnvironmentVarGuard() as env:
1658 del env['LINES'] 1746 del env['LINES']
1659 del env['COLUMNS'] 1747 del env['COLUMNS']
1660 actual = shutil.get_terminal_size() 1748 actual = shutil.get_terminal_size()
1661 1749
1662 self.assertEqual(expected, actual) 1750 self.assertEqual(expected, actual)
1663 1751
1664 1752
1665 def test_main():
1666 support.run_unittest(TestShutil, TestMove, TestCopyFile,
1667 TermsizeTests, TestWhich)
1668
1669 if __name__ == '__main__': 1753 if __name__ == '__main__':
1670 test_main() 1754 unittest.main()
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+