test_file.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. # test_file.py -- Test for git files
  2. # Copyright (C) 2010 Google, Inc.
  3. #
  4. # This program is free software; you can redistribute it and/or
  5. # modify it under the terms of the GNU General Public License
  6. # as published by the Free Software Foundation; version 2
  7. # of the License or (at your option) a later version of the License.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  17. # MA 02110-1301, USA.
  18. import errno
  19. import os
  20. import shutil
  21. import sys
  22. import tempfile
  23. from dulwich.file import GitFile, fancy_rename
  24. from dulwich.tests import (
  25. SkipTest,
  26. TestCase,
  27. )
  28. class FancyRenameTests(TestCase):
  29. def setUp(self):
  30. super(FancyRenameTests, self).setUp()
  31. self._tempdir = tempfile.mkdtemp()
  32. self.foo = self.path('foo')
  33. self.bar = self.path('bar')
  34. self.create(self.foo, 'foo contents')
  35. def tearDown(self):
  36. shutil.rmtree(self._tempdir)
  37. super(FancyRenameTests, self).tearDown()
  38. def path(self, filename):
  39. return os.path.join(self._tempdir, filename)
  40. def create(self, path, contents):
  41. f = open(path, 'wb')
  42. f.write(contents)
  43. f.close()
  44. def test_no_dest_exists(self):
  45. self.assertFalse(os.path.exists(self.bar))
  46. fancy_rename(self.foo, self.bar)
  47. self.assertFalse(os.path.exists(self.foo))
  48. new_f = open(self.bar, 'rb')
  49. self.assertEqual('foo contents', new_f.read())
  50. new_f.close()
  51. def test_dest_exists(self):
  52. self.create(self.bar, 'bar contents')
  53. fancy_rename(self.foo, self.bar)
  54. self.assertFalse(os.path.exists(self.foo))
  55. new_f = open(self.bar, 'rb')
  56. self.assertEqual('foo contents', new_f.read())
  57. new_f.close()
  58. def test_dest_opened(self):
  59. if sys.platform != "win32":
  60. raise SkipTest("platform allows overwriting open files")
  61. self.create(self.bar, 'bar contents')
  62. dest_f = open(self.bar, 'rb')
  63. self.assertRaises(OSError, fancy_rename, self.foo, self.bar)
  64. dest_f.close()
  65. self.assertTrue(os.path.exists(self.path('foo')))
  66. new_f = open(self.foo, 'rb')
  67. self.assertEqual('foo contents', new_f.read())
  68. new_f.close()
  69. new_f = open(self.bar, 'rb')
  70. self.assertEqual('bar contents', new_f.read())
  71. new_f.close()
  72. class GitFileTests(TestCase):
  73. def setUp(self):
  74. super(GitFileTests, self).setUp()
  75. self._tempdir = tempfile.mkdtemp()
  76. f = open(self.path('foo'), 'wb')
  77. f.write('foo contents')
  78. f.close()
  79. def tearDown(self):
  80. shutil.rmtree(self._tempdir)
  81. super(GitFileTests, self).tearDown()
  82. def path(self, filename):
  83. return os.path.join(self._tempdir, filename)
  84. def test_invalid(self):
  85. foo = self.path('foo')
  86. self.assertRaises(IOError, GitFile, foo, mode='r')
  87. self.assertRaises(IOError, GitFile, foo, mode='ab')
  88. self.assertRaises(IOError, GitFile, foo, mode='r+b')
  89. self.assertRaises(IOError, GitFile, foo, mode='w+b')
  90. self.assertRaises(IOError, GitFile, foo, mode='a+bU')
  91. def test_readonly(self):
  92. f = GitFile(self.path('foo'), 'rb')
  93. self.assertTrue(isinstance(f, file))
  94. self.assertEqual('foo contents', f.read())
  95. self.assertEqual('', f.read())
  96. f.seek(4)
  97. self.assertEqual('contents', f.read())
  98. f.close()
  99. def test_default_mode(self):
  100. f = GitFile(self.path('foo'))
  101. self.assertEqual('foo contents', f.read())
  102. f.close()
  103. def test_write(self):
  104. foo = self.path('foo')
  105. foo_lock = '%s.lock' % foo
  106. orig_f = open(foo, 'rb')
  107. self.assertEqual(orig_f.read(), 'foo contents')
  108. orig_f.close()
  109. self.assertFalse(os.path.exists(foo_lock))
  110. f = GitFile(foo, 'wb')
  111. self.assertFalse(f.closed)
  112. self.assertRaises(AttributeError, getattr, f, 'not_a_file_property')
  113. self.assertTrue(os.path.exists(foo_lock))
  114. f.write('new stuff')
  115. f.seek(4)
  116. f.write('contents')
  117. f.close()
  118. self.assertFalse(os.path.exists(foo_lock))
  119. new_f = open(foo, 'rb')
  120. self.assertEqual('new contents', new_f.read())
  121. new_f.close()
  122. def test_open_twice(self):
  123. foo = self.path('foo')
  124. f1 = GitFile(foo, 'wb')
  125. f1.write('new')
  126. try:
  127. f2 = GitFile(foo, 'wb')
  128. self.fail()
  129. except OSError as e:
  130. self.assertEqual(errno.EEXIST, e.errno)
  131. f1.write(' contents')
  132. f1.close()
  133. # Ensure trying to open twice doesn't affect original.
  134. f = open(foo, 'rb')
  135. self.assertEqual('new contents', f.read())
  136. f.close()
  137. def test_abort(self):
  138. foo = self.path('foo')
  139. foo_lock = '%s.lock' % foo
  140. orig_f = open(foo, 'rb')
  141. self.assertEqual(orig_f.read(), 'foo contents')
  142. orig_f.close()
  143. f = GitFile(foo, 'wb')
  144. f.write('new contents')
  145. f.abort()
  146. self.assertTrue(f.closed)
  147. self.assertFalse(os.path.exists(foo_lock))
  148. new_orig_f = open(foo, 'rb')
  149. self.assertEqual(new_orig_f.read(), 'foo contents')
  150. new_orig_f.close()
  151. def test_abort_close(self):
  152. foo = self.path('foo')
  153. f = GitFile(foo, 'wb')
  154. f.abort()
  155. try:
  156. f.close()
  157. except (IOError, OSError):
  158. self.fail()
  159. f = GitFile(foo, 'wb')
  160. f.close()
  161. try:
  162. f.abort()
  163. except (IOError, OSError):
  164. self.fail()
  165. def test_abort_close_removed(self):
  166. foo = self.path('foo')
  167. f = GitFile(foo, 'wb')
  168. f._file.close()
  169. os.remove(foo+".lock")
  170. f.abort()
  171. self.assertTrue(f._closed)