Message231463
> Would it be possible to write a unit test, maybe using unittest.mock to
> mock most parts?
Good idea! Turns out this was quite straightforward. The test patch is:
--- a/Lib/test/test_shutil.py
+++ b/Lib/test/test_shutil.py
@@ -1,6 +1,7 @@
# Copyright (C) 2003 Python Software Foundation
import unittest
+import unittest.mock
import shutil
import tempfile
import sys
@@ -758,6 +759,20 @@
self.assertEqual(os.stat(restrictive_subdir).st_mode,
os.stat(restrictive_subdir_dst).st_mode)
+ @unittest.mock.patch('os.chmod')
+ def test_copytree_winerror(self, mock_patch):
+ # When copying to VFAT, copystat() raises OSError. On Windows, the
+ # exception object has a meaningful 'winerror' attribute, but not
+ # on other operating systems. Do not assume 'winerror' is set.
+ src_dir = tempfile.mkdtemp()
+ dst_dir = os.path.join(tempfile.mkdtemp(), 'destination')
+ self.addCleanup(shutil.rmtree, src_dir)
+ self.addCleanup(shutil.rmtree, os.path.dirname(dst_dir))
+
+ mock_patch.side_effect = PermissionError('ka-boom')
+ with self.assertRaises(shutil.Error):
+ shutil.copytree(src_dir, dst_dir)
+
@unittest.skipIf(os.name == 'nt', 'temporarily disabled on Windows')
@unittest.skipUnless(hasattr(os, 'link'), 'requires os.link')
def test_dont_copy_file_onto_link_to_itself(self):
When run without the bug fix, this reproduces my original failure nicely:
$ ./python Lib/test/test_shutil.py
................s........................s.s........E..s..............................s..
======================================================================
ERROR: test_copytree_winerror (__main__.TestShutil)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/data/src/cpython/3.4/Lib/shutil.py", line 337, in copytree
copystat(src, dst)
File "/data/src/cpython/3.4/Lib/shutil.py", line 191, in copystat
lookup("chmod")(dst, mode, follow_symlinks=follow)
File "/data/src/cpython/3.4/Lib/unittest/mock.py", line 896, in __call__
return _mock_self._mock_call(*args, **kwargs)
File "/data/src/cpython/3.4/Lib/unittest/mock.py", line 952, in _mock_call
raise effect
PermissionError: ka-boom
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/data/src/cpython/3.4/Lib/unittest/mock.py", line 1136, in patched
return func(*args, **keywargs)
File "Lib/test/test_shutil.py", line 774, in test_copytree_winerror
shutil.copytree(src_dir, dst_dir)
File "/data/src/cpython/3.4/Lib/shutil.py", line 340, in copytree
if why.winerror is None:
AttributeError: 'PermissionError' object has no attribute 'winerror'
----------------------------------------------------------------------
Ran 89 tests in 0.095s
FAILED (errors=1, skipped=5)
Excellent! No need for root privs, and the bug is quite obvious.
Apply my getattr() fix, and the test passes.
I'll commit on branch 3.4 and merge to default. |
|
Date |
User |
Action |
Args |
2014-11-21 01:37:31 | gward | set | recipients:
+ gward, vstinner, serhiy.storchaka |
2014-11-21 01:37:31 | gward | set | messageid: <1416533851.02.0.242709851165.issue21775@psf.upfronthosting.co.za> |
2014-11-21 01:37:30 | gward | link | issue21775 messages |
2014-11-21 01:37:29 | gward | create | |
|