hashindex.py 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import hashlib
  2. import os
  3. import tempfile
  4. from attic.hashindex import NSIndex, ChunkIndex
  5. from attic.testsuite import AtticTestCase
  6. class HashIndexTestCase(AtticTestCase):
  7. def _generic_test(self, cls, make_value, sha):
  8. idx_name = tempfile.NamedTemporaryFile()
  9. idx = cls.create(idx_name.name)
  10. self.assert_equal(len(idx), 0)
  11. # Test set
  12. for x in range(100):
  13. idx[bytes('%-32d' % x, 'ascii')] = make_value(x)
  14. self.assert_equal(len(idx), 100)
  15. for x in range(100):
  16. self.assert_equal(idx[bytes('%-32d' % x, 'ascii')], make_value(x))
  17. # Test update
  18. for x in range(100):
  19. idx[bytes('%-32d' % x, 'ascii')] = make_value(x * 2)
  20. self.assert_equal(len(idx), 100)
  21. for x in range(100):
  22. self.assert_equal(idx[bytes('%-32d' % x, 'ascii')], make_value(x * 2))
  23. # Test delete
  24. for x in range(50):
  25. del idx[bytes('%-32d' % x, 'ascii')]
  26. self.assert_equal(len(idx), 50)
  27. del idx
  28. # Verify file contents
  29. with open(idx_name.name, 'rb') as fd:
  30. self.assert_equal(hashlib.sha256(fd.read()).hexdigest(), sha)
  31. # Make sure we can open the file
  32. idx = cls(idx_name.name)
  33. self.assert_equal(len(idx), 50)
  34. for x in range(50, 100):
  35. self.assert_equal(idx[bytes('%-32d' % x, 'ascii')], make_value(x * 2))
  36. idx.clear()
  37. self.assert_equal(len(idx), 0)
  38. del idx
  39. self.assert_equal(len(cls(idx_name.name)), 0)
  40. def test_nsindex(self):
  41. self._generic_test(NSIndex, lambda x: (x, x), '369a18ae6a52524eb2884a3c0fdc2824947edd017a2688c5d4d7b3510c245ab9')
  42. def test_chunkindex(self):
  43. self._generic_test(ChunkIndex, lambda x: (x, x, x), 'ed22e8a883400453c0ee79a06c54df72c994a54eeefdc6c0989efdc5ee6d07b7')
  44. def test_resize(self):
  45. n = 2000 # Must be >= MIN_BUCKETS
  46. idx_name = tempfile.NamedTemporaryFile()
  47. idx = NSIndex.create(idx_name.name)
  48. initial_size = os.path.getsize(idx_name.name)
  49. self.assert_equal(len(idx), 0)
  50. for x in range(n):
  51. idx[bytes('%-32d' % x, 'ascii')] = x, x
  52. idx.flush()
  53. self.assert_true(initial_size < os.path.getsize(idx_name.name))
  54. for x in range(n):
  55. del idx[bytes('%-32d' % x, 'ascii')]
  56. self.assert_equal(len(idx), 0)
  57. idx.flush()
  58. self.assert_equal(initial_size, os.path.getsize(idx_name.name))
  59. def test_read_only(self):
  60. """Make sure read_only indices work even they contain a lot of tombstones
  61. """
  62. idx_name = tempfile.NamedTemporaryFile()
  63. idx = NSIndex.create(idx_name.name)
  64. for x in range(100):
  65. idx[bytes('%-0.32d' % x, 'ascii')] = x, x
  66. for x in range(99):
  67. del idx[bytes('%-0.32d' % x, 'ascii')]
  68. idx.flush()
  69. idx2 = NSIndex(idx_name.name, readonly=True)
  70. self.assert_equal(idx2[bytes('%-0.32d' % 99, 'ascii')], (99, 99))
  71. def test_iteritems(self):
  72. idx_name = tempfile.NamedTemporaryFile()
  73. idx = NSIndex.create(idx_name.name)
  74. for x in range(100):
  75. idx[bytes('%-0.32d' % x, 'ascii')] = x, x
  76. all = list(idx.iteritems())
  77. self.assert_equal(len(all), 100)
  78. second_half = list(idx.iteritems(marker=all[49][0]))
  79. self.assert_equal(len(second_half), 50)
  80. self.assert_equal(second_half, all[50:])