__init__.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import filecmp
  2. import os
  3. import posix
  4. import sys
  5. import sysconfig
  6. import time
  7. import unittest
  8. from attic.helpers import st_mtime_ns
  9. from attic.xattr import get_all
  10. try:
  11. import llfuse
  12. # Does this version of llfuse support ns precision?
  13. have_fuse_mtime_ns = hasattr(llfuse.EntryAttributes, 'st_mtime_ns')
  14. except ImportError:
  15. have_fuse_mtime_ns = False
  16. has_lchflags = hasattr(os, 'lchflags')
  17. # The mtime get/set precison varies on different OS and Python versions
  18. if 'HAVE_FUTIMENS' in getattr(posix, '_have_functions', []):
  19. st_mtime_ns_round = 0
  20. elif 'HAVE_UTIMES' in sysconfig.get_config_vars():
  21. st_mtime_ns_round = -6
  22. else:
  23. st_mtime_ns_round = -9
  24. has_mtime_ns = sys.version >= '3.3'
  25. utime_supports_fd = os.utime in getattr(os, 'supports_fd', {})
  26. class AtticTestCase(unittest.TestCase):
  27. """
  28. """
  29. assert_in = unittest.TestCase.assertIn
  30. assert_not_in = unittest.TestCase.assertNotIn
  31. assert_equal = unittest.TestCase.assertEqual
  32. assert_not_equal = unittest.TestCase.assertNotEqual
  33. assert_raises = unittest.TestCase.assertRaises
  34. assert_true = unittest.TestCase.assertTrue
  35. def assert_dirs_equal(self, dir1, dir2):
  36. diff = filecmp.dircmp(dir1, dir2)
  37. self._assert_dirs_equal_cmp(diff)
  38. def _assert_dirs_equal_cmp(self, diff):
  39. self.assert_equal(diff.left_only, [])
  40. self.assert_equal(diff.right_only, [])
  41. self.assert_equal(diff.diff_files, [])
  42. self.assert_equal(diff.funny_files, [])
  43. for filename in diff.common:
  44. path1 = os.path.join(diff.left, filename)
  45. path2 = os.path.join(diff.right, filename)
  46. s1 = os.lstat(path1)
  47. s2 = os.lstat(path2)
  48. # Assume path2 is on FUSE if st_dev is different
  49. fuse = s1.st_dev != s2.st_dev
  50. attrs = ['st_mode', 'st_uid', 'st_gid', 'st_rdev']
  51. if has_lchflags:
  52. attrs.append('st_flags')
  53. if not fuse or not os.path.isdir(path1):
  54. # dir nlink is always 1 on our fuse fileystem
  55. attrs.append('st_nlink')
  56. d1 = [filename] + [getattr(s1, a) for a in attrs]
  57. d2 = [filename] + [getattr(s2, a) for a in attrs]
  58. if not os.path.islink(path1) or utime_supports_fd:
  59. # Older versions of llfuse does not support ns precision properly
  60. if fuse and not have_fuse_mtime_ns:
  61. d1.append(round(st_mtime_ns(s1), -4))
  62. d2.append(round(st_mtime_ns(s2), -4))
  63. d1.append(round(st_mtime_ns(s1), st_mtime_ns_round))
  64. d2.append(round(st_mtime_ns(s2), st_mtime_ns_round))
  65. d1.append(get_all(path1, follow_symlinks=False))
  66. d2.append(get_all(path2, follow_symlinks=False))
  67. self.assert_equal(d1, d2)
  68. for sub_diff in diff.subdirs.values():
  69. self._assert_dirs_equal_cmp(sub_diff)
  70. def wait_for_mount(self, path, timeout=5):
  71. """Wait until a filesystem is mounted on `path`
  72. """
  73. timeout += time.time()
  74. while timeout > time.time():
  75. if os.path.ismount(path):
  76. return
  77. time.sleep(.1)
  78. raise Exception('wait_for_mount(%s) timeout' % path)
  79. def get_tests(suite):
  80. """Generates a sequence of tests from a test suite
  81. """
  82. for item in suite:
  83. try:
  84. # TODO: This could be "yield from..." with Python 3.3+
  85. for i in get_tests(item):
  86. yield i
  87. except TypeError:
  88. yield item
  89. class TestLoader(unittest.TestLoader):
  90. """A customzied test loader that properly detects and filters our test cases
  91. """
  92. def loadTestsFromName(self, pattern, module=None):
  93. suite = self.discover('attic.testsuite', '*.py')
  94. tests = unittest.TestSuite()
  95. for test in get_tests(suite):
  96. if pattern.lower() in test.id().lower():
  97. tests.addTest(test)
  98. return tests