blob: f3b5a2329d0ec004a5e8aa245f38f08e0fbdb1be [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
Edward Lesmes34f71ab2020-03-25 21:24:00 +000087 def testPopulateTwice(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
94 mirror = git_cache.Mirror(self.origin_dir)
95 mirror.populate()
96
97 mirror.populate()
98
danakjc41f72c2019-11-05 17:12:01 +000099 def _makeGitRepoWithTag(self):
100 self.git(['init', '-q'])
101 with open(os.path.join(self.origin_dir, 'foo'), 'w') as f:
102 f.write('touched\n')
103 self.git(['add', 'foo'])
104 self.git(['commit', '-m', 'foo'])
105 self.git(['tag', 'TAG'])
106 self.git(['pack-refs'])
107
108 def testPopulateFetchTagsByDefault(self):
109 self._makeGitRepoWithTag()
110
111 # Default behaviour includes tags.
112 mirror = git_cache.Mirror(self.origin_dir)
113 mirror.populate()
114
115 cache_dir = os.path.join(self.cache_dir,
116 mirror.UrlToCacheDir(self.origin_dir))
117 self.assertTrue(os.path.exists(cache_dir + '/refs/tags/TAG'))
118
119 def testPopulateFetchWithoutTags(self):
120 self._makeGitRepoWithTag()
121
122 # Ask to not include tags.
123 mirror = git_cache.Mirror(self.origin_dir)
124 mirror.populate(no_fetch_tags=True)
125
126 cache_dir = os.path.join(self.cache_dir,
127 mirror.UrlToCacheDir(self.origin_dir))
128 self.assertFalse(os.path.exists(cache_dir + '/refs/tags/TAG'))
Edward Lemura11fc9b2018-07-17 22:35:47 +0000129
130 def testPopulateResetFetchConfigEmptyFetchConfig(self):
131 self.git(['init', '-q'])
132 with open(os.path.join(self.origin_dir, 'foo'), 'w') as f:
133 f.write('touched\n')
134 self.git(['add', 'foo'])
135 self.git(['commit', '-m', 'foo'])
136
137 mirror = git_cache.Mirror(self.origin_dir)
138 mirror.populate(reset_fetch_config=True)
139
Robert Iannuccia19649b2018-06-29 16:31:45 +0000140
141class GitCacheDirTest(unittest.TestCase):
142 def setUp(self):
143 try:
144 delattr(git_cache.Mirror, 'cachepath')
145 except AttributeError:
146 pass
147 super(GitCacheDirTest, self).setUp()
148
149 def tearDown(self):
150 try:
151 delattr(git_cache.Mirror, 'cachepath')
152 except AttributeError:
153 pass
154 super(GitCacheDirTest, self).tearDown()
155
156 def test_git_config_read(self):
157 (fd, tmpFile) = tempfile.mkstemp()
158 old = git_cache.Mirror._GIT_CONFIG_LOCATION
159 try:
160 try:
Edward Lemurdf746d02019-07-27 00:42:46 +0000161 os.write(fd, b'[cache]\n cachepath="hello world"\n')
Robert Iannuccia19649b2018-06-29 16:31:45 +0000162 finally:
163 os.close(fd)
164
165 git_cache.Mirror._GIT_CONFIG_LOCATION = ['-f', tmpFile]
166
Edward Lesmes4c3eb702020-03-25 21:09:30 +0000167 self.assertEqual(git_cache.Mirror.GetCachePath(), 'hello world')
Robert Iannuccia19649b2018-06-29 16:31:45 +0000168 finally:
169 git_cache.Mirror._GIT_CONFIG_LOCATION = old
170 os.remove(tmpFile)
171
172 def test_environ_read(self):
173 path = os.environ.get('GIT_CACHE_PATH')
174 config = os.environ.get('GIT_CONFIG')
175 try:
176 os.environ['GIT_CACHE_PATH'] = 'hello world'
177 os.environ['GIT_CONFIG'] = 'disabled'
178
179 self.assertEqual(git_cache.Mirror.GetCachePath(), 'hello world')
180 finally:
181 for name, val in zip(('GIT_CACHE_PATH', 'GIT_CONFIG'), (path, config)):
182 if val is None:
183 os.environ.pop(name, None)
184 else:
185 os.environ[name] = val
186
187 def test_manual_set(self):
188 git_cache.Mirror.SetCachePath('hello world')
189 self.assertEqual(git_cache.Mirror.GetCachePath(), 'hello world')
190
191 def test_unconfigured(self):
192 path = os.environ.get('GIT_CACHE_PATH')
193 config = os.environ.get('GIT_CONFIG')
194 try:
195 os.environ.pop('GIT_CACHE_PATH', None)
196 os.environ['GIT_CONFIG'] = 'disabled'
197
198 with self.assertRaisesRegexp(RuntimeError, 'cache\.cachepath'):
199 git_cache.Mirror.GetCachePath()
200
201 # negatively cached value still raises
202 with self.assertRaisesRegexp(RuntimeError, 'cache\.cachepath'):
203 git_cache.Mirror.GetCachePath()
204 finally:
205 for name, val in zip(('GIT_CACHE_PATH', 'GIT_CONFIG'), (path, config)):
206 if val is None:
207 os.environ.pop(name, None)
208 else:
209 os.environ[name] = val
210
211
Dirk Prankedb589542019-04-12 21:07:01 +0000212class MirrorTest(unittest.TestCase):
213 def test_same_cache_for_authenticated_and_unauthenticated_urls(self):
214 # GoB can fetch a repo via two different URLs; if the url contains '/a/'
215 # it forces authenticated access instead of allowing anonymous access,
216 # even in the case where a repo is public. We want this in order to make
217 # sure bots are authenticated and get the right quotas. However, we
218 # only want to maintain a single cache for the repo.
219 self.assertEqual(git_cache.Mirror.UrlToCacheDir(
220 'https://chromium.googlesource.com/a/chromium/src.git'),
221 'chromium.googlesource.com-chromium-src')
222
223
szager@chromium.org66c8b852015-09-22 23:19:07 +0000224if __name__ == '__main__':
225 sys.exit(coverage_utils.covered_main((
226 os.path.join(DEPOT_TOOLS_ROOT, 'git_cache.py')
227 ), required_percentage=0))