summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/git/utils.py5
-rw-r--r--test/git/test_utils.py51
2 files changed, 54 insertions, 2 deletions
diff --git a/lib/git/utils.py b/lib/git/utils.py
index dd1117b6..f188a7a4 100644
--- a/lib/git/utils.py
+++ b/lib/git/utils.py
@@ -205,7 +205,10 @@ class ConcurrentWriteOperation(LockFile):
if successful:
# on windows, rename does not silently overwrite the existing one
if sys.platform == "win32":
- os.remove(self._file_path)
+ if os.path.isfile(self._file_path):
+ os.remove(self._file_path)
+ # END remove if exists
+ # END win32 special handling
os.rename(self._temp_write_fp.name, self._file_path)
else:
# just delete the file so far, we failed
diff --git a/test/git/test_utils.py b/test/git/test_utils.py
index 61527758..029d2054 100644
--- a/test/git/test_utils.py
+++ b/test/git/test_utils.py
@@ -53,5 +53,54 @@ class TestUtils(TestCase):
lock_file._obtain_lock_or_raise()
lock_file._release_lock()
+ def _cmp_contents(self, file_path, data):
+ # raise if data from file at file_path
+ # does not match data string
+ fp = open(file_path, "r")
+ try:
+ assert fp.read() == data
+ finally:
+ fp.close()
+
def test_safe_operation(self):
- self.fail("todo")
+ my_file = tempfile.mktemp()
+ orig_data = "hello"
+ new_data = "world"
+ my_file_fp = open(my_file, "w")
+ my_file_fp.write(orig_data)
+ my_file_fp.close()
+
+ try:
+ cwrite = ConcurrentWriteOperation(my_file)
+
+ # didn't start writing, doesnt matter
+ cwrite._end_writing(False)
+ cwrite._end_writing(True)
+ assert not cwrite._is_writing()
+
+ # write data and fail
+ stream = cwrite._begin_writing()
+ assert cwrite._is_writing()
+ stream.write(new_data)
+ cwrite._end_writing(successful=False)
+ self._cmp_contents(my_file, orig_data)
+ assert not os.path.exists(stream.name)
+
+ # write data - concurrently
+ ocwrite = ConcurrentWriteOperation(my_file)
+ stream = cwrite._begin_writing()
+ self.failUnlessRaises(IOError, ocwrite._begin_writing)
+
+ stream.write("world")
+ cwrite._end_writing(successful=True)
+ self._cmp_contents(my_file, new_data)
+ assert not os.path.exists(stream.name)
+
+ # could test automatic _end_writing on destruction
+ finally:
+ os.remove(my_file)
+ # END final cleanup
+
+
+
+