blob: a6b833971fa72fa1e2c661a72072e6d7226ddd11 [file] [log] [blame]
Don Garrettc4114cc2016-11-01 20:04:06 -07001# Copyright 2016 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Unit tests for chromite.lib.git and helpers for testing that module."""
6
7from __future__ import print_function
8
Don Garrett86881cb2017-02-15 15:41:55 -08009import mock
Don Garrett7ade05a2017-02-17 13:31:47 -080010import os
Don Garrett86881cb2017-02-15 15:41:55 -080011
12from chromite.cbuildbot import repository
Don Garrett861e9182017-05-15 15:30:23 -070013from chromite.lib import constants
Don Garrett597ddff2017-02-17 18:29:37 -080014from chromite.lib import cros_build_lib
Don Garrettc4114cc2016-11-01 20:04:06 -070015from chromite.lib import cros_build_lib_unittest
Don Garrett7ade05a2017-02-17 13:31:47 -080016from chromite.lib import cros_test_lib
Don Garrett86881cb2017-02-15 15:41:55 -080017from chromite.lib import osutils
Don Garrett0c54ed72017-03-03 11:18:57 -080018from chromite.scripts import cbuildbot_launch
Don Garrett86881cb2017-02-15 15:41:55 -080019
Don Garrett60967922017-04-12 18:51:44 -070020
Don Garrett86881cb2017-02-15 15:41:55 -080021EXPECTED_MANIFEST_URL = 'https://chrome-internal-review.googlesource.com/chromeos/manifest-internal' # pylint: disable=line-too-long
Don Garrettc4114cc2016-11-01 20:04:06 -070022
23
Don Garrett8d314792017-05-18 13:11:42 -070024class FakeException(Exception):
25 """Test exception to raise during tests."""
26
27
Don Garrett0c54ed72017-03-03 11:18:57 -080028class CbuildbotLaunchTest(cros_test_lib.MockTestCase):
29 """Tests for cbuildbot_launch script."""
Don Garrettc4114cc2016-11-01 20:04:06 -070030
Don Garrett86881cb2017-02-15 15:41:55 -080031 def testPreParseArguments(self):
Don Garrettc4114cc2016-11-01 20:04:06 -070032 """Test that we can correctly extract branch values from cbuildbot args."""
Don Garrett597ddff2017-02-17 18:29:37 -080033 CASES = (
34 (['--buildroot', '/buildroot', 'daisy-incremental'],
35 (None, '/buildroot', None)),
36
37 (['--buildbot', '--buildroot', '/buildroot',
38 '--git-cache-dir', '/git-cache',
39 '-b', 'release-R57-9202.B',
40 'daisy-incremental'],
41 ('release-R57-9202.B', '/buildroot', '/git-cache')),
42
43 (['--debug', '--buildbot', '--notests',
44 '--buildroot', '/buildroot',
45 '--git-cache-dir', '/git-cache',
46 '--branch', 'release-R57-9202.B',
47 'daisy-incremental'],
48 ('release-R57-9202.B', '/buildroot', '/git-cache')),
Don Garrettc4114cc2016-11-01 20:04:06 -070049 )
50
Don Garrett597ddff2017-02-17 18:29:37 -080051 for cmd_args, expected in CASES:
52 expected_branch, expected_buildroot, expected_cache_dir = expected
53
Don Garrett0c54ed72017-03-03 11:18:57 -080054 options = cbuildbot_launch.PreParseArguments(cmd_args)
Don Garrett597ddff2017-02-17 18:29:37 -080055
56 self.assertEqual(options.branch, expected_branch)
57 self.assertEqual(options.buildroot, expected_buildroot)
58 self.assertEqual(options.git_cache_dir, expected_cache_dir)
Don Garrett86881cb2017-02-15 15:41:55 -080059
Don Garrettf324bc32017-05-23 14:00:53 -070060 def testInitialCheckout(self):
Don Garrett86881cb2017-02-15 15:41:55 -080061 """Test InitialCheckout with minimum settings."""
Don Garrettf324bc32017-05-23 14:00:53 -070062 mock_repo = mock.MagicMock()
63 mock_repo.branch = 'branch'
Don Garrett86881cb2017-02-15 15:41:55 -080064
Don Garrettf324bc32017-05-23 14:00:53 -070065 cbuildbot_launch.InitialCheckout(mock_repo)
Don Garrett86881cb2017-02-15 15:41:55 -080066
67 self.assertEqual(mock_repo.mock_calls, [
Don Garrettf324bc32017-05-23 14:00:53 -070068 mock.call.Sync(detach=True),
Don Garrett8d314792017-05-18 13:11:42 -070069 ])
70
Don Garrettf15d65b2017-04-12 12:39:55 -070071 def testConfigureGlobalEnvironment(self):
Don Garrett60967922017-04-12 18:51:44 -070072 """Ensure that we can setup our global runtime environment correctly."""
Don Garrett86fec482017-05-17 18:13:33 -070073
74 os.environ.pop('LANG', None)
75 os.environ['LC_MONETARY'] = 'bad'
76
Don Garrettf15d65b2017-04-12 12:39:55 -070077 cbuildbot_launch.ConfigureGlobalEnvironment()
78
Don Garrett86fec482017-05-17 18:13:33 -070079 # Verify umask is updated.
Don Garrettf15d65b2017-04-12 12:39:55 -070080 self.assertEqual(os.umask(0), 0o22)
81
Don Garrett86fec482017-05-17 18:13:33 -070082 # Verify ENVs are cleaned up.
83 self.assertEqual(os.environ['LANG'], 'en_US.UTF-8')
84 self.assertNotIn('LC_MONETARY', os.environ)
85
Don Garrettf15d65b2017-04-12 12:39:55 -070086
Don Garrett597ddff2017-02-17 18:29:37 -080087class RunTests(cros_build_lib_unittest.RunCommandTestCase):
Don Garrett0c54ed72017-03-03 11:18:57 -080088 """Tests for cbuildbot_launch script."""
Don Garrett597ddff2017-02-17 18:29:37 -080089
90 ARGS_BASE = ['--buildroot', '/buildroot']
91 ARGS_GIT_CACHE = ['--git-cache-dir', '/git-cache']
92 ARGS_CONFIG = ['config']
93 CMD = ['/buildroot/chromite/bin/cbuildbot']
94
95 def verifyRunCbuildbot(self, args, expected_cmd, version):
Don Garrett86881cb2017-02-15 15:41:55 -080096 """Ensure we invoke cbuildbot correctly."""
Don Garrett0c54ed72017-03-03 11:18:57 -080097 options = cbuildbot_launch.PreParseArguments(args)
Don Garrett597ddff2017-02-17 18:29:37 -080098
99 self.PatchObject(
100 cros_build_lib, 'GetTargetChromiteApiVersion', autospec=True,
101 return_value=version)
102
Don Garrett0c54ed72017-03-03 11:18:57 -0800103 cbuildbot_launch.RunCbuildbot(options)
Don Garrett597ddff2017-02-17 18:29:37 -0800104
105 self.assertCommandCalled(
Don Garrett125d4dc2017-04-25 16:26:03 -0700106 expected_cmd, cwd=options.buildroot)
Don Garrett597ddff2017-02-17 18:29:37 -0800107
108 def testRunCbuildbotSimple(self):
109 """Ensure we invoke cbuildbot correctly."""
110 self.verifyRunCbuildbot(
111 self.ARGS_BASE + self.ARGS_CONFIG,
112 self.CMD + self.ARGS_CONFIG + self.ARGS_BASE,
113 (0, 4))
114
115 def testRunCbuildbotNotFiltered(self):
116 """Ensure we invoke cbuildbot correctly."""
117 self.verifyRunCbuildbot(
118 self.ARGS_BASE + self.ARGS_CONFIG + self.ARGS_GIT_CACHE,
119 self.CMD + self.ARGS_CONFIG + self.ARGS_BASE + self.ARGS_GIT_CACHE,
120 (0, 4))
121
122 def testRunCbuildbotFiltered(self):
123 """Ensure we invoke cbuildbot correctly."""
124 self.verifyRunCbuildbot(
125 self.ARGS_BASE + self.ARGS_CONFIG + self.ARGS_GIT_CACHE,
126 self.CMD + self.ARGS_CONFIG + self.ARGS_BASE,
127 (0, 2))
Don Garrettc4114cc2016-11-01 20:04:06 -0700128
Don Garrett86881cb2017-02-15 15:41:55 -0800129 def testMainMin(self):
130 """Test a minimal set of command line options."""
Don Garrett597ddff2017-02-17 18:29:37 -0800131 self.PatchObject(osutils, 'SafeMakedirs', autospec=True)
132 self.PatchObject(cros_build_lib, 'GetTargetChromiteApiVersion',
Don Garrett861e9182017-05-15 15:30:23 -0700133 autospec=True, return_value=(constants.REEXEC_API_MAJOR,
134 constants.REEXEC_API_MINOR))
Don Garrettf324bc32017-05-23 14:00:53 -0700135 mock_repo = mock.MagicMock()
136 mock_repo.branch = 'master'
137 mock_repo_create = self.PatchObject(repository, 'RepoRepository',
138 autospec=True, return_value=mock_repo)
Don Garrett0c54ed72017-03-03 11:18:57 -0800139 mock_clean = self.PatchObject(cbuildbot_launch, 'CleanBuildroot',
140 autospec=True)
141 mock_checkout = self.PatchObject(cbuildbot_launch, 'InitialCheckout',
Don Garrett86881cb2017-02-15 15:41:55 -0800142 autospec=True)
Don Garrett7ade05a2017-02-17 13:31:47 -0800143
Don Garrett0c54ed72017-03-03 11:18:57 -0800144 cbuildbot_launch.main(['--buildroot', '/buildroot', 'config'])
Don Garrettc4114cc2016-11-01 20:04:06 -0700145
Don Garrettf324bc32017-05-23 14:00:53 -0700146 # Did we create the repo instance correctly?
147 self.assertEqual(mock_repo_create.mock_calls,
148 [mock.call(EXPECTED_MANIFEST_URL, '/buildroot',
149 git_cache_dir=None, branch='master')])
150
Don Garrett7ade05a2017-02-17 13:31:47 -0800151 # Ensure we clean, as expected.
152 self.assertEqual(mock_clean.mock_calls,
Don Garrettf324bc32017-05-23 14:00:53 -0700153 [mock.call('/buildroot', mock_repo)])
Don Garrett7ade05a2017-02-17 13:31:47 -0800154
Don Garrett86881cb2017-02-15 15:41:55 -0800155 # Ensure we checkout, as expected.
156 self.assertEqual(mock_checkout.mock_calls,
Don Garrettf324bc32017-05-23 14:00:53 -0700157 [mock.call(mock_repo)])
Don Garrettc4114cc2016-11-01 20:04:06 -0700158
Don Garrett86881cb2017-02-15 15:41:55 -0800159 # Ensure we invoke cbuildbot, as expected.
160 self.assertCommandCalled(
161 ['/buildroot/chromite/bin/cbuildbot',
Don Garrett597ddff2017-02-17 18:29:37 -0800162 'config', '--buildroot', '/buildroot'],
Don Garrett125d4dc2017-04-25 16:26:03 -0700163 cwd='/buildroot')
Don Garrettc4114cc2016-11-01 20:04:06 -0700164
Don Garrett86881cb2017-02-15 15:41:55 -0800165 def testMainMax(self):
Don Garrett597ddff2017-02-17 18:29:37 -0800166 """Test a larger set of command line options."""
167 self.PatchObject(osutils, 'SafeMakedirs', autospec=True)
168 self.PatchObject(cros_build_lib, 'GetTargetChromiteApiVersion',
Don Garrett861e9182017-05-15 15:30:23 -0700169 autospec=True, return_value=(constants.REEXEC_API_MAJOR,
170 constants.REEXEC_API_MINOR))
Don Garrettf324bc32017-05-23 14:00:53 -0700171 mock_repo = mock.MagicMock()
172 mock_repo.branch = 'branch'
173 mock_repo_create = self.PatchObject(repository, 'RepoRepository',
174 autospec=True, return_value=mock_repo)
Don Garrett0c54ed72017-03-03 11:18:57 -0800175 mock_clean = self.PatchObject(cbuildbot_launch, 'CleanBuildroot',
176 autospec=True)
177 mock_checkout = self.PatchObject(cbuildbot_launch, 'InitialCheckout',
Don Garrett86881cb2017-02-15 15:41:55 -0800178 autospec=True)
Don Garrettc4114cc2016-11-01 20:04:06 -0700179
Don Garrett0c54ed72017-03-03 11:18:57 -0800180 cbuildbot_launch.main(['--buildroot', '/buildroot',
Don Garrett125d4dc2017-04-25 16:26:03 -0700181 '--branch', 'branch',
Don Garrett0c54ed72017-03-03 11:18:57 -0800182 '--git-cache-dir', '/git-cache',
183 'config'])
Don Garrettc4114cc2016-11-01 20:04:06 -0700184
Don Garrettf324bc32017-05-23 14:00:53 -0700185 # Did we create the repo instance correctly?
186 self.assertEqual(mock_repo_create.mock_calls,
187 [mock.call(EXPECTED_MANIFEST_URL, '/buildroot',
188 git_cache_dir='/git-cache', branch='branch')])
189
Don Garrett7ade05a2017-02-17 13:31:47 -0800190 # Ensure we clean, as expected.
191 self.assertEqual(mock_clean.mock_calls,
Don Garrettf324bc32017-05-23 14:00:53 -0700192 [mock.call('/buildroot', mock_repo)])
Don Garrett7ade05a2017-02-17 13:31:47 -0800193
Don Garrett86881cb2017-02-15 15:41:55 -0800194 # Ensure we checkout, as expected.
195 self.assertEqual(mock_checkout.mock_calls,
Don Garrettf324bc32017-05-23 14:00:53 -0700196 [mock.call(mock_repo)])
Don Garrett86881cb2017-02-15 15:41:55 -0800197
198 # Ensure we invoke cbuildbot, as expected.
199 self.assertCommandCalled(
200 ['/buildroot/chromite/bin/cbuildbot',
Don Garrett597ddff2017-02-17 18:29:37 -0800201 'config',
202 '--buildroot', '/buildroot',
Don Garrett125d4dc2017-04-25 16:26:03 -0700203 '--branch', 'branch',
Don Garrett597ddff2017-02-17 18:29:37 -0800204 '--git-cache-dir', '/git-cache'],
Don Garrett125d4dc2017-04-25 16:26:03 -0700205 cwd='/buildroot')
Don Garrett7ade05a2017-02-17 13:31:47 -0800206
207
Don Garrett60967922017-04-12 18:51:44 -0700208class CleanBuildrootTest(cros_test_lib.MockTempDirTestCase):
Don Garrett7ade05a2017-02-17 13:31:47 -0800209 """Tests for CleanBuildroot method."""
210
211 def setUp(self):
212 """Create standard buildroot contents for cleanup."""
Don Garrette17e1d92017-04-12 15:28:19 -0700213 self.root = os.path.join(self.tempdir, 'buildroot')
214 self.state = os.path.join(self.root, '.cbuildbot_launch_state')
215 self.repo = os.path.join(self.root, '.repo/repo')
216 self.chroot = os.path.join(self.root, 'chroot/chroot')
217 self.general = os.path.join(self.root, 'general/general')
Don Garrett39963602017-02-27 14:41:58 -0800218 # TODO: Add .cache, and distfiles.
Don Garrett7ade05a2017-02-17 13:31:47 -0800219
Don Garrettf324bc32017-05-23 14:00:53 -0700220 self.mock_repo = mock.MagicMock()
221
Don Garrett60967922017-04-12 18:51:44 -0700222 def populateBuildroot(self, state=None):
Don Garrett7ade05a2017-02-17 13:31:47 -0800223 """Create standard buildroot contents for cleanup."""
Don Garrett60967922017-04-12 18:51:44 -0700224 osutils.SafeMakedirs(self.root)
Don Garrette17e1d92017-04-12 15:28:19 -0700225
Don Garrett7ade05a2017-02-17 13:31:47 -0800226 if state:
227 osutils.WriteFile(self.state, state)
228
229 # Create files.
230 for f in (self.repo, self.chroot, self.general):
Don Garrette17e1d92017-04-12 15:28:19 -0700231 osutils.Touch(f, makedirs=True)
Don Garrett7ade05a2017-02-17 13:31:47 -0800232
Don Garrette17e1d92017-04-12 15:28:19 -0700233 def testNoBuildroot(self):
Don Garrett7ade05a2017-02-17 13:31:47 -0800234 """Test CleanBuildroot with no history."""
Don Garrettf324bc32017-05-23 14:00:53 -0700235 self.mock_repo.branch = 'master'
236
237 cbuildbot_launch.CleanBuildroot(self.root, self.mock_repo)
Don Garrett7ade05a2017-02-17 13:31:47 -0800238
Don Garrett125d4dc2017-04-25 16:26:03 -0700239 self.assertEqual(osutils.ReadFile(self.state), '1 master')
Don Garrett7ade05a2017-02-17 13:31:47 -0800240
241 def testBuildrootNoState(self):
242 """Test CleanBuildroot with no state information."""
243 self.populateBuildroot()
Don Garrettf324bc32017-05-23 14:00:53 -0700244 self.mock_repo.branch = 'master'
Don Garrett7ade05a2017-02-17 13:31:47 -0800245
Don Garrettf324bc32017-05-23 14:00:53 -0700246 cbuildbot_launch.CleanBuildroot(self.root, self.mock_repo)
Don Garrett7ade05a2017-02-17 13:31:47 -0800247
Don Garrett125d4dc2017-04-25 16:26:03 -0700248 self.assertEqual(osutils.ReadFile(self.state), '1 master')
Don Garrett60967922017-04-12 18:51:44 -0700249 self.assertNotExists(self.repo)
Don Garrett7ade05a2017-02-17 13:31:47 -0800250 self.assertNotExists(self.chroot)
Don Garrett60967922017-04-12 18:51:44 -0700251 self.assertNotExists(self.general)
252
253 def testBuildrootFormatMismatch(self):
254 """Test CleanBuildroot with no state information."""
Don Garrett125d4dc2017-04-25 16:26:03 -0700255 self.populateBuildroot('0 master')
Don Garrettf324bc32017-05-23 14:00:53 -0700256 self.mock_repo.branch = 'master'
Don Garrett60967922017-04-12 18:51:44 -0700257
Don Garrettf324bc32017-05-23 14:00:53 -0700258 cbuildbot_launch.CleanBuildroot(self.root, self.mock_repo)
Don Garrett60967922017-04-12 18:51:44 -0700259
Don Garrett125d4dc2017-04-25 16:26:03 -0700260 self.assertEqual(osutils.ReadFile(self.state), '1 master')
Don Garrett60967922017-04-12 18:51:44 -0700261 self.assertNotExists(self.repo)
262 self.assertNotExists(self.chroot)
263 self.assertNotExists(self.general)
Don Garrett7ade05a2017-02-17 13:31:47 -0800264
265 def testBuildrootBranchChange(self):
266 """Test CleanBuildroot with a change in branches."""
Don Garrett60967922017-04-12 18:51:44 -0700267 self.populateBuildroot('1 branchA')
Don Garrettf324bc32017-05-23 14:00:53 -0700268 self.mock_repo.branch = 'branchB'
Don Garrett7ade05a2017-02-17 13:31:47 -0800269
Don Garrettf324bc32017-05-23 14:00:53 -0700270 cbuildbot_launch.CleanBuildroot(self.root, self.mock_repo)
Don Garrett7ade05a2017-02-17 13:31:47 -0800271
Don Garrett60967922017-04-12 18:51:44 -0700272 self.assertEqual(osutils.ReadFile(self.state), '1 branchB')
Don Garrett7ade05a2017-02-17 13:31:47 -0800273 self.assertExists(self.repo)
274 self.assertNotExists(self.chroot)
275 self.assertExists(self.general)
276
277 def testBuildrootBranchMatch(self):
278 """Test CleanBuildroot with no change in branch."""
Don Garrett60967922017-04-12 18:51:44 -0700279 self.populateBuildroot('1 branchA')
Don Garrettf324bc32017-05-23 14:00:53 -0700280 self.mock_repo.branch = 'branchA'
Don Garrett7ade05a2017-02-17 13:31:47 -0800281
Don Garrettf324bc32017-05-23 14:00:53 -0700282 cbuildbot_launch.CleanBuildroot(self.root, self.mock_repo)
Don Garrett7ade05a2017-02-17 13:31:47 -0800283
Don Garrett60967922017-04-12 18:51:44 -0700284 self.assertEqual(osutils.ReadFile(self.state), '1 branchA')
Don Garrett7ade05a2017-02-17 13:31:47 -0800285 self.assertExists(self.repo)
286 self.assertExists(self.chroot)
287 self.assertExists(self.general)
Don Garrette17e1d92017-04-12 15:28:19 -0700288
Don Garrettf324bc32017-05-23 14:00:53 -0700289 def testBuildrootRepoCleanFailure(self):
290 """Test CleanBuildroot with repo checkout failure."""
291 self.populateBuildroot('1 branchA')
292 self.mock_repo.branch = 'branchA'
293 self.mock_repo.BuildRootGitCleanup.side_effect = Exception
294
295 cbuildbot_launch.CleanBuildroot(self.root, self.mock_repo)
296
297 self.assertEqual(osutils.ReadFile(self.state), '1 branchA')
298 self.assertNotExists(self.repo)
299 self.assertNotExists(self.chroot)
300 self.assertNotExists(self.general)
301
Don Garrett60967922017-04-12 18:51:44 -0700302 def testGetBuildrootState(self):
303 """Test GetBuildrootState."""
304 # No root dir.
305 results = cbuildbot_launch.GetBuildrootState(self.root)
306 self.assertEqual(results, (0, ''))
307
308 # Empty root dir.
309 osutils.SafeMakedirs(self.root)
310 results = cbuildbot_launch.GetBuildrootState(self.root)
311 self.assertEqual(results, (0, ''))
312
313 # Empty Contents
314 osutils.WriteFile(self.state, '')
315 results = cbuildbot_launch.GetBuildrootState(self.root)
316 self.assertEqual(results, (0, ''))
317
318 # Old Format Contents
319 osutils.WriteFile(self.state, 'happy-branch')
320 results = cbuildbot_launch.GetBuildrootState(self.root)
321 self.assertEqual(results, (0, ''))
322
323 # Expected Contents
324 osutils.WriteFile(self.state, '1 happy-branch')
325 results = cbuildbot_launch.GetBuildrootState(self.root)
326 self.assertEqual(results, (1, 'happy-branch'))
327
328 # Future Contents
329 osutils.WriteFile(self.state, '22 master')
330 results = cbuildbot_launch.GetBuildrootState(self.root)
331 self.assertEqual(results, (22, 'master'))
332
333 # Read Write
334 cbuildbot_launch.SetBuildrootState('happy-branch', self.root)
335 results = cbuildbot_launch.GetBuildrootState(self.root)
336 self.assertEqual(results, (1, 'happy-branch'))
337
338 def testSetBuildrootState(self):
339 """Test SetBuildrootState."""
340 # Write out a state file.
341 osutils.SafeMakedirs(self.root)
342 cbuildbot_launch.SetBuildrootState('happy-branch', self.root)
343 self.assertEqual(osutils.ReadFile(self.state), '1 happy-branch')
344
345 # Change to a future version.
346 self.PatchObject(cbuildbot_launch, 'BUILDROOT_BUILDROOT_LAYOUT', 22)
347 cbuildbot_launch.SetBuildrootState('happy-branch', self.root)
348 self.assertEqual(osutils.ReadFile(self.state), '22 happy-branch')