blob: 539ab2629dc759daf482a260ab3c106994d5b147 [file] [log] [blame]
Edward Lemurf417d3a2019-10-02 20:28:59 +00001#!/usr/bin/env vpython3
szager@chromium.org66c8b852015-09-22 23:19:07 +00002# 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
6"""Unit tests for git_cache.py"""
7
8import os
9import shutil
Edward Lemura11fc9b2018-07-17 22:35:47 +000010import subprocess
szager@chromium.org66c8b852015-09-22 23:19:07 +000011import sys
12import tempfile
13import unittest
14
15DEPOT_TOOLS_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
16sys.path.insert(0, DEPOT_TOOLS_ROOT)
17
18from testing_support import coverage_utils
19import git_cache
20
21class GitCacheTest(unittest.TestCase):
Edward Lemura11fc9b2018-07-17 22:35:47 +000022 def setUp(self):
23 self.cache_dir = tempfile.mkdtemp(prefix='git_cache_test_')
24 self.addCleanup(shutil.rmtree, self.cache_dir, ignore_errors=True)
25 self.origin_dir = tempfile.mkdtemp(suffix='origin.git')
26 self.addCleanup(shutil.rmtree, self.origin_dir, ignore_errors=True)
27 git_cache.Mirror.SetCachePath(self.cache_dir)
szager@chromium.org66c8b852015-09-22 23:19:07 +000028
Edward Lemura11fc9b2018-07-17 22:35:47 +000029 def git(self, cmd, cwd=None):
30 cwd = cwd or self.origin_dir
Edward Lesmesab517542019-10-07 23:16:21 +000031 git = 'git.bat' if sys.platform == 'win32' else 'git'
32 subprocess.check_call([git] + cmd, cwd=cwd)
szager@chromium.org66c8b852015-09-22 23:19:07 +000033
34 def testParseFetchSpec(self):
35 testData = [
36 ([], []),
37 (['master'], [('+refs/heads/master:refs/heads/master',
38 r'\+refs/heads/master:.*')]),
39 (['master/'], [('+refs/heads/master:refs/heads/master',
40 r'\+refs/heads/master:.*')]),
41 (['+master'], [('+refs/heads/master:refs/heads/master',
42 r'\+refs/heads/master:.*')]),
43 (['refs/heads/*'], [('+refs/heads/*:refs/heads/*',
44 r'\+refs/heads/\*:.*')]),
45 (['foo/bar/*', 'baz'], [('+refs/heads/foo/bar/*:refs/heads/foo/bar/*',
46 r'\+refs/heads/foo/bar/\*:.*'),
47 ('+refs/heads/baz:refs/heads/baz',
48 r'\+refs/heads/baz:.*')]),
49 (['refs/foo/*:refs/bar/*'], [('+refs/foo/*:refs/bar/*',
50 r'\+refs/foo/\*:.*')])
51 ]
52
53 mirror = git_cache.Mirror('test://phony.example.biz')
54 for fetch_specs, expected in testData:
55 mirror = git_cache.Mirror('test://phony.example.biz', refs=fetch_specs)
Edward Lemurdf746d02019-07-27 00:42:46 +000056 self.assertEqual(mirror.fetch_specs, set(expected))
szager@chromium.org66c8b852015-09-22 23:19:07 +000057
Edward Lemura11fc9b2018-07-17 22:35:47 +000058 def testPopulate(self):
59 self.git(['init', '-q'])
60 with open(os.path.join(self.origin_dir, 'foo'), 'w') as f:
61 f.write('touched\n')
62 self.git(['add', 'foo'])
63 self.git(['commit', '-m', 'foo'])
64
65 mirror = git_cache.Mirror(self.origin_dir)
66 mirror.populate()
67
68 def testPopulateResetFetchConfig(self):
69 self.git(['init', '-q'])
70 with open(os.path.join(self.origin_dir, 'foo'), 'w') as f:
71 f.write('touched\n')
72 self.git(['add', 'foo'])
73 self.git(['commit', '-m', 'foo'])
74
75 mirror = git_cache.Mirror(self.origin_dir)
76 mirror.populate()
77
78 # Add a bad refspec to the cache's fetch config.
79 cache_dir = os.path.join(
80 self.cache_dir, mirror.UrlToCacheDir(self.origin_dir))
81 self.git(['config', '--add', 'remote.origin.fetch',
82 '+refs/heads/foo:refs/heads/foo'],
83 cwd=cache_dir)
84
85 mirror.populate(reset_fetch_config=True)
86
danakjc41f72c2019-11-05 17:12:01 +000087 def _makeGitRepoWithTag(self):
88 self.git(['init', '-q'])
89 with open(os.path.join(self.origin_dir, 'foo'), 'w') as f:
90 f.write('touched\n')
91 self.git(['add', 'foo'])
92 self.git(['commit', '-m', 'foo'])
93 self.git(['tag', 'TAG'])
94 self.git(['pack-refs'])
95
96 def testPopulateFetchTagsByDefault(self):
97 self._makeGitRepoWithTag()
98
99 # Default behaviour includes tags.
100 mirror = git_cache.Mirror(self.origin_dir)
101 mirror.populate()
102
103 cache_dir = os.path.join(self.cache_dir,
104 mirror.UrlToCacheDir(self.origin_dir))
105 self.assertTrue(os.path.exists(cache_dir + '/refs/tags/TAG'))
106
107 def testPopulateFetchWithoutTags(self):
108 self._makeGitRepoWithTag()
109
110 # Ask to not include tags.
111 mirror = git_cache.Mirror(self.origin_dir)
112 mirror.populate(no_fetch_tags=True)
113
114 cache_dir = os.path.join(self.cache_dir,
115 mirror.UrlToCacheDir(self.origin_dir))
116 self.assertFalse(os.path.exists(cache_dir + '/refs/tags/TAG'))
Edward Lemura11fc9b2018-07-17 22:35:47 +0000117
118 def testPopulateResetFetchConfigEmptyFetchConfig(self):
119 self.git(['init', '-q'])
120 with open(os.path.join(self.origin_dir, 'foo'), 'w') as f:
121 f.write('touched\n')
122 self.git(['add', 'foo'])
123 self.git(['commit', '-m', 'foo'])
124
125 mirror = git_cache.Mirror(self.origin_dir)
126 mirror.populate(reset_fetch_config=True)
127
Robert Iannuccia19649b2018-06-29 16:31:45 +0000128
129class GitCacheDirTest(unittest.TestCase):
130 def setUp(self):
131 try:
132 delattr(git_cache.Mirror, 'cachepath')
133 except AttributeError:
134 pass
135 super(GitCacheDirTest, self).setUp()
136
137 def tearDown(self):
138 try:
139 delattr(git_cache.Mirror, 'cachepath')
140 except AttributeError:
141 pass
142 super(GitCacheDirTest, self).tearDown()
143
144 def test_git_config_read(self):
145 (fd, tmpFile) = tempfile.mkstemp()
146 old = git_cache.Mirror._GIT_CONFIG_LOCATION
147 try:
148 try:
Edward Lemurdf746d02019-07-27 00:42:46 +0000149 os.write(fd, b'[cache]\n cachepath="hello world"\n')
Robert Iannuccia19649b2018-06-29 16:31:45 +0000150 finally:
151 os.close(fd)
152
153 git_cache.Mirror._GIT_CONFIG_LOCATION = ['-f', tmpFile]
154
Edward Lesmes4c3eb702020-03-25 21:09:30 +0000155 self.assertEqual(git_cache.Mirror.GetCachePath(), 'hello world')
Robert Iannuccia19649b2018-06-29 16:31:45 +0000156 finally:
157 git_cache.Mirror._GIT_CONFIG_LOCATION = old
158 os.remove(tmpFile)
159
160 def test_environ_read(self):
161 path = os.environ.get('GIT_CACHE_PATH')
162 config = os.environ.get('GIT_CONFIG')
163 try:
164 os.environ['GIT_CACHE_PATH'] = 'hello world'
165 os.environ['GIT_CONFIG'] = 'disabled'
166
167 self.assertEqual(git_cache.Mirror.GetCachePath(), 'hello world')
168 finally:
169 for name, val in zip(('GIT_CACHE_PATH', 'GIT_CONFIG'), (path, config)):
170 if val is None:
171 os.environ.pop(name, None)
172 else:
173 os.environ[name] = val
174
175 def test_manual_set(self):
176 git_cache.Mirror.SetCachePath('hello world')
177 self.assertEqual(git_cache.Mirror.GetCachePath(), 'hello world')
178
179 def test_unconfigured(self):
180 path = os.environ.get('GIT_CACHE_PATH')
181 config = os.environ.get('GIT_CONFIG')
182 try:
183 os.environ.pop('GIT_CACHE_PATH', None)
184 os.environ['GIT_CONFIG'] = 'disabled'
185
186 with self.assertRaisesRegexp(RuntimeError, 'cache\.cachepath'):
187 git_cache.Mirror.GetCachePath()
188
189 # negatively cached value still raises
190 with self.assertRaisesRegexp(RuntimeError, 'cache\.cachepath'):
191 git_cache.Mirror.GetCachePath()
192 finally:
193 for name, val in zip(('GIT_CACHE_PATH', 'GIT_CONFIG'), (path, config)):
194 if val is None:
195 os.environ.pop(name, None)
196 else:
197 os.environ[name] = val
198
199
Dirk Prankedb589542019-04-12 21:07:01 +0000200class MirrorTest(unittest.TestCase):
201 def test_same_cache_for_authenticated_and_unauthenticated_urls(self):
202 # GoB can fetch a repo via two different URLs; if the url contains '/a/'
203 # it forces authenticated access instead of allowing anonymous access,
204 # even in the case where a repo is public. We want this in order to make
205 # sure bots are authenticated and get the right quotas. However, we
206 # only want to maintain a single cache for the repo.
207 self.assertEqual(git_cache.Mirror.UrlToCacheDir(
208 'https://chromium.googlesource.com/a/chromium/src.git'),
209 'chromium.googlesource.com-chromium-src')
210
211
szager@chromium.org66c8b852015-09-22 23:19:07 +0000212if __name__ == '__main__':
213 sys.exit(coverage_utils.covered_main((
214 os.path.join(DEPOT_TOOLS_ROOT, 'git_cache.py')
215 ), required_percentage=0))