blob: 73c62cc1b1fed493edb2d7ac728fd63cdba4d14e [file] [log] [blame]
Mike Frysingerf6013762019-06-13 02:30:51 -04001# -*- coding:utf-8 -*-
Dan Willemsen745b4ad2015-10-06 15:23:19 -07002#
3# Copyright (C) 2015 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
Mike Frysinger87deaef2019-07-26 21:14:55 -040017"""Unittests for the wrapper.py module."""
18
19from __future__ import print_function
20
Dan Willemsen745b4ad2015-10-06 15:23:19 -070021import os
Mike Frysinger84094102020-02-11 02:10:28 -050022import re
Mike Frysingercfc81112020-02-29 02:56:32 -050023import shutil
24import tempfile
Dan Willemsen745b4ad2015-10-06 15:23:19 -070025import unittest
26
Mike Frysinger84094102020-02-11 02:10:28 -050027from pyversion import is_python3
Dan Willemsen745b4ad2015-10-06 15:23:19 -070028import wrapper
29
David Pursehouse819827a2020-02-12 15:20:19 +090030
Mike Frysinger8ddff5c2020-02-09 15:00:25 -050031if is_python3():
32 from unittest import mock
33 from io import StringIO
34else:
35 import mock
36 from StringIO import StringIO
37
38
Dan Willemsen745b4ad2015-10-06 15:23:19 -070039def fixture(*paths):
40 """Return a path relative to tests/fixtures.
41 """
42 return os.path.join(os.path.dirname(__file__), 'fixtures', *paths)
43
David Pursehouse819827a2020-02-12 15:20:19 +090044
Mike Frysinger84094102020-02-11 02:10:28 -050045class RepoWrapperTestCase(unittest.TestCase):
46 """TestCase for the wrapper module."""
David Pursehouse819827a2020-02-12 15:20:19 +090047
Dan Willemsen745b4ad2015-10-06 15:23:19 -070048 def setUp(self):
Mike Frysinger84094102020-02-11 02:10:28 -050049 """Load the wrapper module every time."""
Dan Willemsen745b4ad2015-10-06 15:23:19 -070050 wrapper._wrapper_module = None
51 self.wrapper = wrapper.Wrapper()
52
Mike Frysinger84094102020-02-11 02:10:28 -050053 if not is_python3():
54 self.assertRegex = self.assertRegexpMatches
55
56
57class RepoWrapperUnitTest(RepoWrapperTestCase):
58 """Tests helper functions in the repo wrapper
59 """
60
Mike Frysinger8ddff5c2020-02-09 15:00:25 -050061 def test_version(self):
62 """Make sure _Version works."""
63 with self.assertRaises(SystemExit) as e:
64 with mock.patch('sys.stdout', new_callable=StringIO) as stdout:
65 with mock.patch('sys.stderr', new_callable=StringIO) as stderr:
66 self.wrapper._Version()
67 self.assertEqual(0, e.exception.code)
68 self.assertEqual('', stderr.getvalue())
69 self.assertIn('repo launcher version', stdout.getvalue())
70
Mike Frysingerd8fda902020-02-14 00:24:38 -050071 def test_init_parser(self):
72 """Make sure 'init' GetParser works."""
73 parser = self.wrapper.GetParser(gitc_init=False)
74 opts, args = parser.parse_args([])
75 self.assertEqual([], args)
76 self.assertIsNone(opts.manifest_url)
77
78 def test_gitc_init_parser(self):
79 """Make sure 'gitc-init' GetParser works."""
80 parser = self.wrapper.GetParser(gitc_init=True)
81 opts, args = parser.parse_args([])
82 self.assertEqual([], args)
83 self.assertIsNone(opts.manifest_file)
84
Dan Willemsen745b4ad2015-10-06 15:23:19 -070085 def test_get_gitc_manifest_dir_no_gitc(self):
86 """
87 Test reading a missing gitc config file
88 """
89 self.wrapper.GITC_CONFIG_FILE = fixture('missing_gitc_config')
90 val = self.wrapper.get_gitc_manifest_dir()
91 self.assertEqual(val, '')
92
93 def test_get_gitc_manifest_dir(self):
94 """
95 Test reading the gitc config file and parsing the directory
96 """
97 self.wrapper.GITC_CONFIG_FILE = fixture('gitc_config')
98 val = self.wrapper.get_gitc_manifest_dir()
99 self.assertEqual(val, '/test/usr/local/google/gitc')
100
101 def test_gitc_parse_clientdir_no_gitc(self):
102 """
103 Test parsing the gitc clientdir without gitc running
104 """
105 self.wrapper.GITC_CONFIG_FILE = fixture('missing_gitc_config')
106 self.assertEqual(self.wrapper.gitc_parse_clientdir('/something'), None)
107 self.assertEqual(self.wrapper.gitc_parse_clientdir('/gitc/manifest-rw/test'), 'test')
108
109 def test_gitc_parse_clientdir(self):
110 """
111 Test parsing the gitc clientdir
112 """
113 self.wrapper.GITC_CONFIG_FILE = fixture('gitc_config')
114 self.assertEqual(self.wrapper.gitc_parse_clientdir('/something'), None)
115 self.assertEqual(self.wrapper.gitc_parse_clientdir('/gitc/manifest-rw/test'), 'test')
116 self.assertEqual(self.wrapper.gitc_parse_clientdir('/gitc/manifest-rw/test/'), 'test')
117 self.assertEqual(self.wrapper.gitc_parse_clientdir('/gitc/manifest-rw/test/extra'), 'test')
118 self.assertEqual(self.wrapper.gitc_parse_clientdir('/test/usr/local/google/gitc/test'), 'test')
119 self.assertEqual(self.wrapper.gitc_parse_clientdir('/test/usr/local/google/gitc/test/'), 'test')
David Pursehouse3cda50a2020-02-13 13:17:03 +0900120 self.assertEqual(self.wrapper.gitc_parse_clientdir('/test/usr/local/google/gitc/test/extra'),
121 'test')
Dan Willemsen745b4ad2015-10-06 15:23:19 -0700122 self.assertEqual(self.wrapper.gitc_parse_clientdir('/gitc/manifest-rw/'), None)
123 self.assertEqual(self.wrapper.gitc_parse_clientdir('/test/usr/local/google/gitc/'), None)
124
David Pursehouse819827a2020-02-12 15:20:19 +0900125
Mike Frysinger84094102020-02-11 02:10:28 -0500126class SetGitTrace2ParentSid(RepoWrapperTestCase):
127 """Check SetGitTrace2ParentSid behavior."""
128
129 KEY = 'GIT_TRACE2_PARENT_SID'
130 VALID_FORMAT = re.compile(r'^repo-[0-9]{8}T[0-9]{6}Z-P[0-9a-f]{8}$')
131
132 def test_first_set(self):
133 """Test env var not yet set."""
134 env = {}
135 self.wrapper.SetGitTrace2ParentSid(env)
136 self.assertIn(self.KEY, env)
137 value = env[self.KEY]
138 self.assertRegex(value, self.VALID_FORMAT)
139
140 def test_append(self):
141 """Test env var is appended."""
142 env = {self.KEY: 'pfx'}
143 self.wrapper.SetGitTrace2ParentSid(env)
144 self.assertIn(self.KEY, env)
145 value = env[self.KEY]
146 self.assertTrue(value.startswith('pfx/'))
147 self.assertRegex(value[4:], self.VALID_FORMAT)
148
149 def test_global_context(self):
150 """Check os.environ gets updated by default."""
151 os.environ.pop(self.KEY, None)
152 self.wrapper.SetGitTrace2ParentSid()
153 self.assertIn(self.KEY, os.environ)
154 value = os.environ[self.KEY]
155 self.assertRegex(value, self.VALID_FORMAT)
156
157
Mike Frysinger587f1622020-03-23 16:49:11 -0400158class RunCommand(RepoWrapperTestCase):
159 """Check run_command behavior."""
160
161 def test_capture(self):
162 """Check capture_output handling."""
163 ret = self.wrapper.run_command(['echo', 'hi'], capture_output=True)
164 self.assertEqual(ret.stdout, 'hi\n')
165
166 def test_check(self):
167 """Check check handling."""
168 self.wrapper.run_command(['true'], check=False)
169 self.wrapper.run_command(['true'], check=True)
170 self.wrapper.run_command(['false'], check=False)
171 with self.assertRaises(self.wrapper.RunError):
172 self.wrapper.run_command(['false'], check=True)
173
174
175class RunGit(RepoWrapperTestCase):
176 """Check run_git behavior."""
177
178 def test_capture(self):
179 """Check capture_output handling."""
180 ret = self.wrapper.run_git('--version')
181 self.assertIn('git', ret.stdout)
182
183 def test_check(self):
184 """Check check handling."""
185 with self.assertRaises(self.wrapper.CloneFailure):
186 self.wrapper.run_git('--version-asdfasdf')
187 self.wrapper.run_git('--version-asdfasdf', check=False)
188
189
190class ParseGitVersion(RepoWrapperTestCase):
191 """Check ParseGitVersion behavior."""
192
193 def test_autoload(self):
194 """Check we can load the version from the live git."""
195 ret = self.wrapper.ParseGitVersion()
196 self.assertIsNotNone(ret)
197
198 def test_bad_ver(self):
199 """Check handling of bad git versions."""
200 ret = self.wrapper.ParseGitVersion(ver_str='asdf')
201 self.assertIsNone(ret)
202
203 def test_normal_ver(self):
204 """Check handling of normal git versions."""
205 ret = self.wrapper.ParseGitVersion(ver_str='git version 2.25.1')
206 self.assertEqual(2, ret.major)
207 self.assertEqual(25, ret.minor)
208 self.assertEqual(1, ret.micro)
209 self.assertEqual('2.25.1', ret.full)
210
211 def test_extended_ver(self):
212 """Check handling of extended distro git versions."""
213 ret = self.wrapper.ParseGitVersion(
214 ver_str='git version 1.30.50.696.g5e7596f4ac-goog')
215 self.assertEqual(1, ret.major)
216 self.assertEqual(30, ret.minor)
217 self.assertEqual(50, ret.micro)
218 self.assertEqual('1.30.50.696.g5e7596f4ac-goog', ret.full)
219
220
221class CheckGitVersion(RepoWrapperTestCase):
222 """Check _CheckGitVersion behavior."""
223
224 def test_unknown(self):
225 """Unknown versions should abort."""
226 with mock.patch.object(self.wrapper, 'ParseGitVersion', return_value=None):
227 with self.assertRaises(self.wrapper.CloneFailure):
228 self.wrapper._CheckGitVersion()
229
230 def test_old(self):
231 """Old versions should abort."""
232 with mock.patch.object(
233 self.wrapper, 'ParseGitVersion',
234 return_value=self.wrapper.GitVersion(1, 0, 0, '1.0.0')):
235 with self.assertRaises(self.wrapper.CloneFailure):
236 self.wrapper._CheckGitVersion()
237
238 def test_new(self):
239 """Newer versions should run fine."""
240 with mock.patch.object(
241 self.wrapper, 'ParseGitVersion',
242 return_value=self.wrapper.GitVersion(100, 0, 0, '100.0.0')):
243 self.wrapper._CheckGitVersion()
244
245
Mike Frysingercfc81112020-02-29 02:56:32 -0500246class ResolveRepoRev(RepoWrapperTestCase):
247 """Check resolve_repo_rev behavior."""
248
249 GIT_DIR = None
250 REV_LIST = None
251
252 @classmethod
253 def setUpClass(cls):
254 # Create a repo to operate on, but do it once per-class.
255 cls.GIT_DIR = tempfile.mkdtemp(prefix='repo-rev-tests')
256 run_git = wrapper.Wrapper().run_git
257
258 remote = os.path.join(cls.GIT_DIR, 'remote')
259 os.mkdir(remote)
260 run_git('init', cwd=remote)
261 run_git('commit', '--allow-empty', '-minit', cwd=remote)
262 run_git('branch', 'stable', cwd=remote)
263 run_git('tag', 'v1.0', cwd=remote)
264 run_git('commit', '--allow-empty', '-m2nd commit', cwd=remote)
265 cls.REV_LIST = run_git('rev-list', 'HEAD', cwd=remote).stdout.splitlines()
266
267 run_git('init', cwd=cls.GIT_DIR)
268 run_git('fetch', remote, '+refs/heads/*:refs/remotes/origin/*', cwd=cls.GIT_DIR)
269
270 @classmethod
271 def tearDownClass(cls):
272 if not cls.GIT_DIR:
273 return
274
275 shutil.rmtree(cls.GIT_DIR)
276
277 def test_explicit_branch(self):
278 """Check refs/heads/branch argument."""
279 rrev, lrev = self.wrapper.resolve_repo_rev(self.GIT_DIR, 'refs/heads/stable')
280 self.assertEqual('refs/heads/stable', rrev)
281 self.assertEqual(self.REV_LIST[1], lrev)
282
283 with self.assertRaises(wrapper.CloneFailure):
284 self.wrapper.resolve_repo_rev(self.GIT_DIR, 'refs/heads/unknown')
285
286 def test_explicit_tag(self):
287 """Check refs/tags/tag argument."""
288 rrev, lrev = self.wrapper.resolve_repo_rev(self.GIT_DIR, 'refs/tags/v1.0')
289 self.assertEqual('refs/tags/v1.0', rrev)
290 self.assertEqual(self.REV_LIST[1], lrev)
291
292 with self.assertRaises(wrapper.CloneFailure):
293 self.wrapper.resolve_repo_rev(self.GIT_DIR, 'refs/tags/unknown')
294
295 def test_branch_name(self):
296 """Check branch argument."""
297 rrev, lrev = self.wrapper.resolve_repo_rev(self.GIT_DIR, 'stable')
298 self.assertEqual('refs/heads/stable', rrev)
299 self.assertEqual(self.REV_LIST[1], lrev)
300
301 rrev, lrev = self.wrapper.resolve_repo_rev(self.GIT_DIR, 'master')
302 self.assertEqual('refs/heads/master', rrev)
303 self.assertEqual(self.REV_LIST[0], lrev)
304
305 def test_tag_name(self):
306 """Check tag argument."""
307 rrev, lrev = self.wrapper.resolve_repo_rev(self.GIT_DIR, 'v1.0')
308 self.assertEqual('refs/tags/v1.0', rrev)
309 self.assertEqual(self.REV_LIST[1], lrev)
310
311 def test_full_commit(self):
312 """Check specific commit argument."""
313 commit = self.REV_LIST[0]
314 rrev, lrev = self.wrapper.resolve_repo_rev(self.GIT_DIR, commit)
315 self.assertEqual(commit, rrev)
316 self.assertEqual(commit, lrev)
317
318 def test_partial_commit(self):
319 """Check specific (partial) commit argument."""
320 commit = self.REV_LIST[0][0:20]
321 rrev, lrev = self.wrapper.resolve_repo_rev(self.GIT_DIR, commit)
322 self.assertEqual(self.REV_LIST[0], rrev)
323 self.assertEqual(self.REV_LIST[0], lrev)
324
325 def test_unknown(self):
326 """Check unknown ref/commit argument."""
327 with self.assertRaises(wrapper.CloneFailure):
328 self.wrapper.resolve_repo_rev(self.GIT_DIR, 'boooooooya')
329
330
Dan Willemsen745b4ad2015-10-06 15:23:19 -0700331if __name__ == '__main__':
332 unittest.main()