blob: a4e2d025f9661587c904b441e6370e941df97903 [file] [log] [blame]
Tarek Ziadé70a74eb2009-02-06 00:38:35 +00001"""Tests for distutils.file_util."""
2import unittest
3import os
Berker Peksag66858832014-08-29 07:07:35 +03004import errno
5from unittest.mock import patch
Tarek Ziadé70a74eb2009-02-06 00:38:35 +00006
Antoine Pitroued14c862014-10-30 19:37:07 +01007from distutils.file_util import move_file, copy_file
Tarek Ziadé70a74eb2009-02-06 00:38:35 +00008from distutils import log
Tarek Ziadéc1375d52009-02-14 14:35:51 +00009from distutils.tests import support
Berker Peksag66858832014-08-29 07:07:35 +030010from distutils.errors import DistutilsFileError
xdegayed34d8fc2017-11-18 18:17:16 +010011from test.support import run_unittest, unlink
Tarek Ziadé70a74eb2009-02-06 00:38:35 +000012
Tarek Ziadéc1375d52009-02-14 14:35:51 +000013class FileUtilTestCase(support.TempdirManager, unittest.TestCase):
Tarek Ziadé70a74eb2009-02-06 00:38:35 +000014
15 def _log(self, msg, *args):
16 if len(args) > 0:
17 self._logs.append(msg % args)
18 else:
19 self._logs.append(msg)
20
21 def setUp(self):
Hirokazu Yamamoto2703fd92009-05-29 09:14:04 +000022 super(FileUtilTestCase, self).setUp()
Tarek Ziadé70a74eb2009-02-06 00:38:35 +000023 self._logs = []
24 self.old_log = log.info
25 log.info = self._log
Tarek Ziadéc1375d52009-02-14 14:35:51 +000026 tmp_dir = self.mkdtemp()
27 self.source = os.path.join(tmp_dir, 'f1')
28 self.target = os.path.join(tmp_dir, 'f2')
29 self.target_dir = os.path.join(tmp_dir, 'd1')
Tarek Ziadé70a74eb2009-02-06 00:38:35 +000030
31 def tearDown(self):
32 log.info = self.old_log
Hirokazu Yamamoto2703fd92009-05-29 09:14:04 +000033 super(FileUtilTestCase, self).tearDown()
Tarek Ziadé70a74eb2009-02-06 00:38:35 +000034
35 def test_move_file_verbosity(self):
Tarek Ziadé70a74eb2009-02-06 00:38:35 +000036 f = open(self.source, 'w')
Éric Araujobee5cef2010-11-05 23:51:56 +000037 try:
38 f.write('some content')
39 finally:
40 f.close()
Tarek Ziadé70a74eb2009-02-06 00:38:35 +000041
42 move_file(self.source, self.target, verbose=0)
43 wanted = []
Ezio Melottib3aedd42010-11-20 19:04:17 +000044 self.assertEqual(self._logs, wanted)
Tarek Ziadé70a74eb2009-02-06 00:38:35 +000045
46 # back to original state
47 move_file(self.target, self.source, verbose=0)
48
49 move_file(self.source, self.target, verbose=1)
50 wanted = ['moving %s -> %s' % (self.source, self.target)]
Ezio Melottib3aedd42010-11-20 19:04:17 +000051 self.assertEqual(self._logs, wanted)
Tarek Ziadé70a74eb2009-02-06 00:38:35 +000052
53 # back to original state
54 move_file(self.target, self.source, verbose=0)
55
56 self._logs = []
57 # now the target is a dir
58 os.mkdir(self.target_dir)
59 move_file(self.source, self.target_dir, verbose=1)
60 wanted = ['moving %s -> %s' % (self.source, self.target_dir)]
Ezio Melottib3aedd42010-11-20 19:04:17 +000061 self.assertEqual(self._logs, wanted)
Tarek Ziadé70a74eb2009-02-06 00:38:35 +000062
Benjamin Peterson9833fcb2014-09-20 11:53:12 -040063 def test_move_file_exception_unpacking_rename(self):
Berker Peksag66858832014-08-29 07:07:35 +030064 # see issue 22182
Benjamin Peterson9833fcb2014-09-20 11:53:12 -040065 with patch("os.rename", side_effect=OSError("wrong", 1)), \
66 self.assertRaises(DistutilsFileError):
Berker Peksag66858832014-08-29 07:07:35 +030067 with open(self.source, 'w') as fobj:
68 fobj.write('spam eggs')
69 move_file(self.source, self.target, verbose=0)
70
Benjamin Peterson9833fcb2014-09-20 11:53:12 -040071 def test_move_file_exception_unpacking_unlink(self):
Berker Peksag66858832014-08-29 07:07:35 +030072 # see issue 22182
Benjamin Peterson9833fcb2014-09-20 11:53:12 -040073 with patch("os.rename", side_effect=OSError(errno.EXDEV, "wrong")), \
74 patch("os.unlink", side_effect=OSError("wrong", 1)), \
75 self.assertRaises(DistutilsFileError):
Berker Peksag66858832014-08-29 07:07:35 +030076 with open(self.source, 'w') as fobj:
77 fobj.write('spam eggs')
78 move_file(self.source, self.target, verbose=0)
79
Antoine Pitroued14c862014-10-30 19:37:07 +010080 def test_copy_file_hard_link(self):
81 with open(self.source, 'w') as f:
82 f.write('some content')
xdegayed34d8fc2017-11-18 18:17:16 +010083 # Check first that copy_file() will not fall back on copying the file
84 # instead of creating the hard link.
85 try:
86 os.link(self.source, self.target)
87 except OSError as e:
88 self.skipTest('os.link: %s' % e)
89 else:
90 unlink(self.target)
Antoine Pitroued14c862014-10-30 19:37:07 +010091 st = os.stat(self.source)
92 copy_file(self.source, self.target, link='hard')
93 st2 = os.stat(self.source)
94 st3 = os.stat(self.target)
95 self.assertTrue(os.path.samestat(st, st2), (st, st2))
96 self.assertTrue(os.path.samestat(st2, st3), (st2, st3))
97 with open(self.source, 'r') as f:
98 self.assertEqual(f.read(), 'some content')
99
100 def test_copy_file_hard_link_failure(self):
101 # If hard linking fails, copy_file() falls back on copying file
102 # (some special filesystems don't support hard linking even under
103 # Unix, see issue #8876).
104 with open(self.source, 'w') as f:
105 f.write('some content')
106 st = os.stat(self.source)
107 with patch("os.link", side_effect=OSError(0, "linking unsupported")):
108 copy_file(self.source, self.target, link='hard')
109 st2 = os.stat(self.source)
110 st3 = os.stat(self.target)
111 self.assertTrue(os.path.samestat(st, st2), (st, st2))
112 self.assertFalse(os.path.samestat(st2, st3), (st2, st3))
113 for fn in (self.source, self.target):
114 with open(fn, 'r') as f:
115 self.assertEqual(f.read(), 'some content')
116
117
Tarek Ziadé70a74eb2009-02-06 00:38:35 +0000118def test_suite():
119 return unittest.makeSuite(FileUtilTestCase)
120
121if __name__ == "__main__":
Éric Araujo70ec44a2010-11-06 02:44:43 +0000122 run_unittest(test_suite())