git_cache_test.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #!/usr/bin/env vpython3
  2. # Copyright 2015 The Chromium Authors. All rights reserved.
  3. # Use of this source code is governed by a BSD-style license that can be
  4. # found in the LICENSE file.
  5. """Unit tests for git_cache.py"""
  6. import os
  7. import shutil
  8. import subprocess
  9. import sys
  10. import tempfile
  11. import unittest
  12. DEPOT_TOOLS_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  13. sys.path.insert(0, DEPOT_TOOLS_ROOT)
  14. from testing_support import coverage_utils
  15. import git_cache
  16. class GitCacheTest(unittest.TestCase):
  17. def setUp(self):
  18. self.cache_dir = tempfile.mkdtemp(prefix='git_cache_test_')
  19. self.addCleanup(shutil.rmtree, self.cache_dir, ignore_errors=True)
  20. self.origin_dir = tempfile.mkdtemp(suffix='origin.git')
  21. self.addCleanup(shutil.rmtree, self.origin_dir, ignore_errors=True)
  22. git_cache.Mirror.SetCachePath(self.cache_dir)
  23. def git(self, cmd, cwd=None):
  24. cwd = cwd or self.origin_dir
  25. git = 'git.bat' if sys.platform == 'win32' else 'git'
  26. subprocess.check_call([git] + cmd, cwd=cwd)
  27. def testParseFetchSpec(self):
  28. testData = [
  29. ([], []),
  30. (['master'], [('+refs/heads/master:refs/heads/master',
  31. r'\+refs/heads/master:.*')]),
  32. (['master/'], [('+refs/heads/master:refs/heads/master',
  33. r'\+refs/heads/master:.*')]),
  34. (['+master'], [('+refs/heads/master:refs/heads/master',
  35. r'\+refs/heads/master:.*')]),
  36. (['refs/heads/*'], [('+refs/heads/*:refs/heads/*',
  37. r'\+refs/heads/\*:.*')]),
  38. (['foo/bar/*', 'baz'], [('+refs/heads/foo/bar/*:refs/heads/foo/bar/*',
  39. r'\+refs/heads/foo/bar/\*:.*'),
  40. ('+refs/heads/baz:refs/heads/baz',
  41. r'\+refs/heads/baz:.*')]),
  42. (['refs/foo/*:refs/bar/*'], [('+refs/foo/*:refs/bar/*',
  43. r'\+refs/foo/\*:.*')])
  44. ]
  45. mirror = git_cache.Mirror('test://phony.example.biz')
  46. for fetch_specs, expected in testData:
  47. mirror = git_cache.Mirror('test://phony.example.biz', refs=fetch_specs)
  48. self.assertEqual(mirror.fetch_specs, set(expected))
  49. def testPopulate(self):
  50. self.git(['init', '-q'])
  51. with open(os.path.join(self.origin_dir, 'foo'), 'w') as f:
  52. f.write('touched\n')
  53. self.git(['add', 'foo'])
  54. self.git(['commit', '-m', 'foo'])
  55. mirror = git_cache.Mirror(self.origin_dir)
  56. mirror.populate()
  57. def testPopulateResetFetchConfig(self):
  58. self.git(['init', '-q'])
  59. with open(os.path.join(self.origin_dir, 'foo'), 'w') as f:
  60. f.write('touched\n')
  61. self.git(['add', 'foo'])
  62. self.git(['commit', '-m', 'foo'])
  63. mirror = git_cache.Mirror(self.origin_dir)
  64. mirror.populate()
  65. # Add a bad refspec to the cache's fetch config.
  66. cache_dir = os.path.join(
  67. self.cache_dir, mirror.UrlToCacheDir(self.origin_dir))
  68. self.git(['config', '--add', 'remote.origin.fetch',
  69. '+refs/heads/foo:refs/heads/foo'],
  70. cwd=cache_dir)
  71. mirror.populate(reset_fetch_config=True)
  72. def testPopulateResetFetchConfigEmptyFetchConfig(self):
  73. self.git(['init', '-q'])
  74. with open(os.path.join(self.origin_dir, 'foo'), 'w') as f:
  75. f.write('touched\n')
  76. self.git(['add', 'foo'])
  77. self.git(['commit', '-m', 'foo'])
  78. mirror = git_cache.Mirror(self.origin_dir)
  79. mirror.populate(reset_fetch_config=True)
  80. class GitCacheDirTest(unittest.TestCase):
  81. def setUp(self):
  82. try:
  83. delattr(git_cache.Mirror, 'cachepath')
  84. except AttributeError:
  85. pass
  86. super(GitCacheDirTest, self).setUp()
  87. def tearDown(self):
  88. try:
  89. delattr(git_cache.Mirror, 'cachepath')
  90. except AttributeError:
  91. pass
  92. super(GitCacheDirTest, self).tearDown()
  93. def test_git_config_read(self):
  94. (fd, tmpFile) = tempfile.mkstemp()
  95. old = git_cache.Mirror._GIT_CONFIG_LOCATION
  96. try:
  97. try:
  98. os.write(fd, b'[cache]\n cachepath="hello world"\n')
  99. finally:
  100. os.close(fd)
  101. git_cache.Mirror._GIT_CONFIG_LOCATION = ['-f', tmpFile]
  102. self.assertEqual(git_cache.Mirror.GetCachePath(), b'hello world')
  103. finally:
  104. git_cache.Mirror._GIT_CONFIG_LOCATION = old
  105. os.remove(tmpFile)
  106. def test_environ_read(self):
  107. path = os.environ.get('GIT_CACHE_PATH')
  108. config = os.environ.get('GIT_CONFIG')
  109. try:
  110. os.environ['GIT_CACHE_PATH'] = 'hello world'
  111. os.environ['GIT_CONFIG'] = 'disabled'
  112. self.assertEqual(git_cache.Mirror.GetCachePath(), 'hello world')
  113. finally:
  114. for name, val in zip(('GIT_CACHE_PATH', 'GIT_CONFIG'), (path, config)):
  115. if val is None:
  116. os.environ.pop(name, None)
  117. else:
  118. os.environ[name] = val
  119. def test_manual_set(self):
  120. git_cache.Mirror.SetCachePath('hello world')
  121. self.assertEqual(git_cache.Mirror.GetCachePath(), 'hello world')
  122. def test_unconfigured(self):
  123. path = os.environ.get('GIT_CACHE_PATH')
  124. config = os.environ.get('GIT_CONFIG')
  125. try:
  126. os.environ.pop('GIT_CACHE_PATH', None)
  127. os.environ['GIT_CONFIG'] = 'disabled'
  128. with self.assertRaisesRegexp(RuntimeError, 'cache\.cachepath'):
  129. git_cache.Mirror.GetCachePath()
  130. # negatively cached value still raises
  131. with self.assertRaisesRegexp(RuntimeError, 'cache\.cachepath'):
  132. git_cache.Mirror.GetCachePath()
  133. finally:
  134. for name, val in zip(('GIT_CACHE_PATH', 'GIT_CONFIG'), (path, config)):
  135. if val is None:
  136. os.environ.pop(name, None)
  137. else:
  138. os.environ[name] = val
  139. class MirrorTest(unittest.TestCase):
  140. def test_same_cache_for_authenticated_and_unauthenticated_urls(self):
  141. # GoB can fetch a repo via two different URLs; if the url contains '/a/'
  142. # it forces authenticated access instead of allowing anonymous access,
  143. # even in the case where a repo is public. We want this in order to make
  144. # sure bots are authenticated and get the right quotas. However, we
  145. # only want to maintain a single cache for the repo.
  146. self.assertEqual(git_cache.Mirror.UrlToCacheDir(
  147. 'https://chromium.googlesource.com/a/chromium/src.git'),
  148. 'chromium.googlesource.com-chromium-src')
  149. if __name__ == '__main__':
  150. sys.exit(coverage_utils.covered_main((
  151. os.path.join(DEPOT_TOOLS_ROOT, 'git_cache.py')
  152. ), required_percentage=0))