You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
3.2KB

  1. # Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors
  2. #
  3. # This module is part of GitDB and is released under
  4. # the New BSD License: http://www.opensource.org/licenses/bsd-license.php
  5. """Test for object db"""
  6. import tempfile
  7. import os
  8. from gitdb.test.lib import TestBase
  9. from gitdb.util import (
  10. to_hex_sha,
  11. to_bin_sha,
  12. NULL_HEX_SHA,
  13. LockedFD
  14. )
  15. class TestUtils(TestBase):
  16. def test_basics(self):
  17. assert to_hex_sha(NULL_HEX_SHA) == NULL_HEX_SHA
  18. assert len(to_bin_sha(NULL_HEX_SHA)) == 20
  19. assert to_hex_sha(to_bin_sha(NULL_HEX_SHA)) == NULL_HEX_SHA.encode("ascii")
  20. def _cmp_contents(self, file_path, data):
  21. # raise if data from file at file_path
  22. # does not match data string
  23. with open(file_path, "rb") as fp:
  24. assert fp.read() == data.encode("ascii")
  25. def test_lockedfd(self):
  26. my_file = tempfile.mktemp()
  27. orig_data = "hello"
  28. new_data = "world"
  29. with open(my_file, "wb") as my_file_fp:
  30. my_file_fp.write(orig_data.encode("ascii"))
  31. try:
  32. lfd = LockedFD(my_file)
  33. lockfilepath = lfd._lockfilepath()
  34. # cannot end before it was started
  35. self.failUnlessRaises(AssertionError, lfd.rollback)
  36. self.failUnlessRaises(AssertionError, lfd.commit)
  37. # open for writing
  38. assert not os.path.isfile(lockfilepath)
  39. wfd = lfd.open(write=True)
  40. assert lfd._fd is wfd
  41. assert os.path.isfile(lockfilepath)
  42. # write data and fail
  43. os.write(wfd, new_data.encode("ascii"))
  44. lfd.rollback()
  45. assert lfd._fd is None
  46. self._cmp_contents(my_file, orig_data)
  47. assert not os.path.isfile(lockfilepath)
  48. # additional call doesn't fail
  49. lfd.commit()
  50. lfd.rollback()
  51. # test reading
  52. lfd = LockedFD(my_file)
  53. rfd = lfd.open(write=False)
  54. assert os.read(rfd, len(orig_data)) == orig_data.encode("ascii")
  55. assert os.path.isfile(lockfilepath)
  56. # deletion rolls back
  57. del(lfd)
  58. assert not os.path.isfile(lockfilepath)
  59. # write data - concurrently
  60. lfd = LockedFD(my_file)
  61. olfd = LockedFD(my_file)
  62. assert not os.path.isfile(lockfilepath)
  63. wfdstream = lfd.open(write=True, stream=True) # this time as stream
  64. assert os.path.isfile(lockfilepath)
  65. # another one fails
  66. self.failUnlessRaises(IOError, olfd.open)
  67. wfdstream.write(new_data.encode("ascii"))
  68. lfd.commit()
  69. assert not os.path.isfile(lockfilepath)
  70. self._cmp_contents(my_file, new_data)
  71. # could test automatic _end_writing on destruction
  72. finally:
  73. os.remove(my_file)
  74. # END final cleanup
  75. # try non-existing file for reading
  76. lfd = LockedFD(tempfile.mktemp())
  77. try:
  78. lfd.open(write=False)
  79. except OSError:
  80. assert not os.path.exists(lfd._lockfilepath())
  81. else:
  82. self.fail("expected OSError")
  83. # END handle exceptions