您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

165 行
5.6KB

  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. from gitdb.test.lib import (
  7. TestBase,
  8. DummyStream,
  9. make_bytes,
  10. make_object,
  11. fixture_path
  12. )
  13. from gitdb import (
  14. DecompressMemMapReader,
  15. FDCompressedSha1Writer,
  16. LooseObjectDB,
  17. Sha1Writer,
  18. MemoryDB,
  19. IStream,
  20. )
  21. from gitdb.util import hex_to_bin
  22. import zlib
  23. from gitdb.typ import (
  24. str_blob_type
  25. )
  26. import tempfile
  27. import os
  28. from io import BytesIO
  29. class TestStream(TestBase):
  30. """Test stream classes"""
  31. data_sizes = (15, 10000, 1000 * 1024 + 512)
  32. def _assert_stream_reader(self, stream, cdata, rewind_stream=lambda s: None):
  33. """Make stream tests - the orig_stream is seekable, allowing it to be
  34. rewound and reused
  35. :param cdata: the data we expect to read from stream, the contents
  36. :param rewind_stream: function called to rewind the stream to make it ready
  37. for reuse"""
  38. ns = 10
  39. assert len(cdata) > ns - 1, "Data must be larger than %i, was %i" % (ns, len(cdata))
  40. # read in small steps
  41. ss = len(cdata) // ns
  42. for i in range(ns):
  43. data = stream.read(ss)
  44. chunk = cdata[i * ss:(i + 1) * ss]
  45. assert data == chunk
  46. # END for each step
  47. rest = stream.read()
  48. if rest:
  49. assert rest == cdata[-len(rest):]
  50. # END handle rest
  51. if isinstance(stream, DecompressMemMapReader):
  52. assert len(stream.data()) == stream.compressed_bytes_read()
  53. # END handle special type
  54. rewind_stream(stream)
  55. # read everything
  56. rdata = stream.read()
  57. assert rdata == cdata
  58. if isinstance(stream, DecompressMemMapReader):
  59. assert len(stream.data()) == stream.compressed_bytes_read()
  60. # END handle special type
  61. def test_decompress_reader(self):
  62. for close_on_deletion in range(2):
  63. for with_size in range(2):
  64. for ds in self.data_sizes:
  65. cdata = make_bytes(ds, randomize=False)
  66. # zdata = zipped actual data
  67. # cdata = original content data
  68. # create reader
  69. if with_size:
  70. # need object data
  71. zdata = zlib.compress(make_object(str_blob_type, cdata))
  72. typ, size, reader = DecompressMemMapReader.new(zdata, close_on_deletion)
  73. assert size == len(cdata)
  74. assert typ == str_blob_type
  75. # even if we don't set the size, it will be set automatically on first read
  76. test_reader = DecompressMemMapReader(zdata, close_on_deletion=False)
  77. assert test_reader._s == len(cdata)
  78. else:
  79. # here we need content data
  80. zdata = zlib.compress(cdata)
  81. reader = DecompressMemMapReader(zdata, close_on_deletion, len(cdata))
  82. assert reader._s == len(cdata)
  83. # END get reader
  84. self._assert_stream_reader(reader, cdata, lambda r: r.seek(0))
  85. # put in a dummy stream for closing
  86. dummy = DummyStream()
  87. reader._m = dummy
  88. assert not dummy.closed
  89. del(reader)
  90. assert dummy.closed == close_on_deletion
  91. # END for each datasize
  92. # END whether size should be used
  93. # END whether stream should be closed when deleted
  94. def test_sha_writer(self):
  95. writer = Sha1Writer()
  96. assert 2 == writer.write("hi".encode("ascii"))
  97. assert len(writer.sha(as_hex=1)) == 40
  98. assert len(writer.sha(as_hex=0)) == 20
  99. # make sure it does something ;)
  100. prev_sha = writer.sha()
  101. writer.write("hi again".encode("ascii"))
  102. assert writer.sha() != prev_sha
  103. def test_compressed_writer(self):
  104. for ds in self.data_sizes:
  105. fd, path = tempfile.mkstemp()
  106. ostream = FDCompressedSha1Writer(fd)
  107. data = make_bytes(ds, randomize=False)
  108. # for now, just a single write, code doesn't care about chunking
  109. assert len(data) == ostream.write(data)
  110. ostream.close()
  111. # its closed already
  112. self.failUnlessRaises(OSError, os.close, fd)
  113. # read everything back, compare to data we zip
  114. fd = os.open(path, os.O_RDONLY | getattr(os, 'O_BINARY', 0))
  115. written_data = os.read(fd, os.path.getsize(path))
  116. assert len(written_data) == os.path.getsize(path)
  117. os.close(fd)
  118. assert written_data == zlib.compress(data, 1) # best speed
  119. os.remove(path)
  120. # END for each os
  121. def test_decompress_reader_special_case(self):
  122. odb = LooseObjectDB(fixture_path('objects'))
  123. mdb = MemoryDB()
  124. for sha in (b'888401851f15db0eed60eb1bc29dec5ddcace911',
  125. b'7bb839852ed5e3a069966281bb08d50012fb309b',):
  126. ostream = odb.stream(hex_to_bin(sha))
  127. # if there is a bug, we will be missing one byte exactly !
  128. data = ostream.read()
  129. assert len(data) == ostream.size
  130. # Putting it back in should yield nothing new - after all, we have
  131. dump = mdb.store(IStream(ostream.type, ostream.size, BytesIO(data)))
  132. assert dump.hexsha == sha
  133. # end for each loose object sha to test