Home | History | Annotate | Download | only in tests
      1 """Tests for distutils.file_util."""
      2 import unittest
      3 import os
      4 import errno
      5 from unittest.mock import patch
      6 
      7 from distutils.file_util import move_file, copy_file
      8 from distutils import log
      9 from distutils.tests import support
     10 from distutils.errors import DistutilsFileError
     11 from test.support import run_unittest
     12 
     13 class FileUtilTestCase(support.TempdirManager, unittest.TestCase):
     14 
     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):
     22         super(FileUtilTestCase, self).setUp()
     23         self._logs = []
     24         self.old_log = log.info
     25         log.info = self._log
     26         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')
     30 
     31     def tearDown(self):
     32         log.info = self.old_log
     33         super(FileUtilTestCase, self).tearDown()
     34 
     35     def test_move_file_verbosity(self):
     36         f = open(self.source, 'w')
     37         try:
     38             f.write('some content')
     39         finally:
     40             f.close()
     41 
     42         move_file(self.source, self.target, verbose=0)
     43         wanted = []
     44         self.assertEqual(self._logs, wanted)
     45 
     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)]
     51         self.assertEqual(self._logs, wanted)
     52 
     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)]
     61         self.assertEqual(self._logs, wanted)
     62 
     63     def test_move_file_exception_unpacking_rename(self):
     64         # see issue 22182
     65         with patch("os.rename", side_effect=OSError("wrong", 1)), \
     66              self.assertRaises(DistutilsFileError):
     67             with open(self.source, 'w') as fobj:
     68                 fobj.write('spam eggs')
     69             move_file(self.source, self.target, verbose=0)
     70 
     71     def test_move_file_exception_unpacking_unlink(self):
     72         # see issue 22182
     73         with patch("os.rename", side_effect=OSError(errno.EXDEV, "wrong")), \
     74              patch("os.unlink", side_effect=OSError("wrong", 1)), \
     75              self.assertRaises(DistutilsFileError):
     76             with open(self.source, 'w') as fobj:
     77                 fobj.write('spam eggs')
     78             move_file(self.source, self.target, verbose=0)
     79 
     80     def test_copy_file_hard_link(self):
     81         with open(self.source, 'w') as f:
     82             f.write('some content')
     83         st = os.stat(self.source)
     84         copy_file(self.source, self.target, link='hard')
     85         st2 = os.stat(self.source)
     86         st3 = os.stat(self.target)
     87         self.assertTrue(os.path.samestat(st, st2), (st, st2))
     88         self.assertTrue(os.path.samestat(st2, st3), (st2, st3))
     89         with open(self.source, 'r') as f:
     90             self.assertEqual(f.read(), 'some content')
     91 
     92     def test_copy_file_hard_link_failure(self):
     93         # If hard linking fails, copy_file() falls back on copying file
     94         # (some special filesystems don't support hard linking even under
     95         #  Unix, see issue #8876).
     96         with open(self.source, 'w') as f:
     97             f.write('some content')
     98         st = os.stat(self.source)
     99         with patch("os.link", side_effect=OSError(0, "linking unsupported")):
    100             copy_file(self.source, self.target, link='hard')
    101         st2 = os.stat(self.source)
    102         st3 = os.stat(self.target)
    103         self.assertTrue(os.path.samestat(st, st2), (st, st2))
    104         self.assertFalse(os.path.samestat(st2, st3), (st2, st3))
    105         for fn in (self.source, self.target):
    106             with open(fn, 'r') as f:
    107                 self.assertEqual(f.read(), 'some content')
    108 
    109 
    110 def test_suite():
    111     return unittest.makeSuite(FileUtilTestCase)
    112 
    113 if __name__ == "__main__":
    114     run_unittest(test_suite())
    115