blob: 4d3eed251efa3c3c901853e43f8b25a1b2aaf941 [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
60 def testInitialCheckoutMin(self):
61 """Test InitialCheckout with minimum settings."""
62 mock_repo = self.PatchObject(repository, 'RepoRepository', autospec=True)
Don Garrett86881cb2017-02-15 15:41:55 -080063
Don Garrett0c54ed72017-03-03 11:18:57 -080064 cbuildbot_launch.InitialCheckout(None, '/buildroot', None)
Don Garrett86881cb2017-02-15 15:41:55 -080065
66 self.assertEqual(mock_repo.mock_calls, [
67 mock.call(EXPECTED_MANIFEST_URL, '/buildroot',
68 branch=None, git_cache_dir=None),
Don Garrett76496912017-05-11 16:59:11 -070069 mock.call().BuildRootGitCleanup(prune_all=True),
70 mock.call().Sync(detach=True),
Don Garrett86881cb2017-02-15 15:41:55 -080071 ])
72
73 def testInitialCheckoutMax(self):
74 """Test InitialCheckout with all settings."""
75 mock_repo = self.PatchObject(repository, 'RepoRepository', autospec=True)
Don Garrett86881cb2017-02-15 15:41:55 -080076
Don Garrett0c54ed72017-03-03 11:18:57 -080077 cbuildbot_launch.InitialCheckout(
78 'release-R56-9000.B', '/buildroot', '/git-cache')
Don Garrett86881cb2017-02-15 15:41:55 -080079
80 self.assertEqual(mock_repo.mock_calls, [
81 mock.call(EXPECTED_MANIFEST_URL, '/buildroot',
82 branch='release-R56-9000.B', git_cache_dir='/git-cache'),
Don Garrett76496912017-05-11 16:59:11 -070083 mock.call().BuildRootGitCleanup(prune_all=True),
84 mock.call().Sync(detach=True),
Don Garrett86881cb2017-02-15 15:41:55 -080085 ])
Don Garrettc4114cc2016-11-01 20:04:06 -070086
Don Garrett8d314792017-05-18 13:11:42 -070087 def testInitialCheckoutCleanupError(self):
88 """Test we wipe buildroot when cleanup fails."""
89 mock_clean = self.PatchObject(
90 repository.RepoRepository, 'BuildRootGitCleanup', autospec=True,
91 side_effect=FakeException)
92 mock_sync = self.PatchObject(
93 repository.RepoRepository, 'Sync', autospec=True)
94 mock_remove = self.PatchObject(
95 repository, 'ClearBuildRoot', autospec=True)
96
97 cbuildbot_launch.InitialCheckout('master', '/buildroot', None)
98
99 self.assertEqual(mock_clean.mock_calls, [
100 mock.call(mock.ANY, prune_all=True),
101 ])
102 self.assertEqual(mock_sync.mock_calls, [
103 mock.call(mock.ANY, detach=True),
104 ])
105 self.assertEqual(mock_remove.mock_calls, [
106 mock.call('/buildroot'),
107 ])
108
Don Garrettf15d65b2017-04-12 12:39:55 -0700109 def testConfigureGlobalEnvironment(self):
Don Garrett60967922017-04-12 18:51:44 -0700110 """Ensure that we can setup our global runtime environment correctly."""
Don Garrett86fec482017-05-17 18:13:33 -0700111
112 os.environ.pop('LANG', None)
113 os.environ['LC_MONETARY'] = 'bad'
114
Don Garrettf15d65b2017-04-12 12:39:55 -0700115 cbuildbot_launch.ConfigureGlobalEnvironment()
116
Don Garrett86fec482017-05-17 18:13:33 -0700117 # Verify umask is updated.
Don Garrettf15d65b2017-04-12 12:39:55 -0700118 self.assertEqual(os.umask(0), 0o22)
119
Don Garrett86fec482017-05-17 18:13:33 -0700120 # Verify ENVs are cleaned up.
121 self.assertEqual(os.environ['LANG'], 'en_US.UTF-8')
122 self.assertNotIn('LC_MONETARY', os.environ)
123
Don Garrettf15d65b2017-04-12 12:39:55 -0700124
Don Garrett597ddff2017-02-17 18:29:37 -0800125class RunTests(cros_build_lib_unittest.RunCommandTestCase):
Don Garrett0c54ed72017-03-03 11:18:57 -0800126 """Tests for cbuildbot_launch script."""
Don Garrett597ddff2017-02-17 18:29:37 -0800127
128 ARGS_BASE = ['--buildroot', '/buildroot']
129 ARGS_GIT_CACHE = ['--git-cache-dir', '/git-cache']
130 ARGS_CONFIG = ['config']
131 CMD = ['/buildroot/chromite/bin/cbuildbot']
132
133 def verifyRunCbuildbot(self, args, expected_cmd, version):
Don Garrett86881cb2017-02-15 15:41:55 -0800134 """Ensure we invoke cbuildbot correctly."""
Don Garrett0c54ed72017-03-03 11:18:57 -0800135 options = cbuildbot_launch.PreParseArguments(args)
Don Garrett597ddff2017-02-17 18:29:37 -0800136
137 self.PatchObject(
138 cros_build_lib, 'GetTargetChromiteApiVersion', autospec=True,
139 return_value=version)
140
Don Garrett0c54ed72017-03-03 11:18:57 -0800141 cbuildbot_launch.RunCbuildbot(options)
Don Garrett597ddff2017-02-17 18:29:37 -0800142
143 self.assertCommandCalled(
Don Garrett125d4dc2017-04-25 16:26:03 -0700144 expected_cmd, cwd=options.buildroot)
Don Garrett597ddff2017-02-17 18:29:37 -0800145
146 def testRunCbuildbotSimple(self):
147 """Ensure we invoke cbuildbot correctly."""
148 self.verifyRunCbuildbot(
149 self.ARGS_BASE + self.ARGS_CONFIG,
150 self.CMD + self.ARGS_CONFIG + self.ARGS_BASE,
151 (0, 4))
152
153 def testRunCbuildbotNotFiltered(self):
154 """Ensure we invoke cbuildbot correctly."""
155 self.verifyRunCbuildbot(
156 self.ARGS_BASE + self.ARGS_CONFIG + self.ARGS_GIT_CACHE,
157 self.CMD + self.ARGS_CONFIG + self.ARGS_BASE + self.ARGS_GIT_CACHE,
158 (0, 4))
159
160 def testRunCbuildbotFiltered(self):
161 """Ensure we invoke cbuildbot correctly."""
162 self.verifyRunCbuildbot(
163 self.ARGS_BASE + self.ARGS_CONFIG + self.ARGS_GIT_CACHE,
164 self.CMD + self.ARGS_CONFIG + self.ARGS_BASE,
165 (0, 2))
Don Garrettc4114cc2016-11-01 20:04:06 -0700166
Don Garrett86881cb2017-02-15 15:41:55 -0800167 def testMainMin(self):
168 """Test a minimal set of command line options."""
Don Garrett597ddff2017-02-17 18:29:37 -0800169 self.PatchObject(osutils, 'SafeMakedirs', autospec=True)
170 self.PatchObject(cros_build_lib, 'GetTargetChromiteApiVersion',
Don Garrett861e9182017-05-15 15:30:23 -0700171 autospec=True, return_value=(constants.REEXEC_API_MAJOR,
172 constants.REEXEC_API_MINOR))
Don Garrett0c54ed72017-03-03 11:18:57 -0800173 mock_clean = self.PatchObject(cbuildbot_launch, 'CleanBuildroot',
174 autospec=True)
175 mock_checkout = self.PatchObject(cbuildbot_launch, 'InitialCheckout',
Don Garrett86881cb2017-02-15 15:41:55 -0800176 autospec=True)
Don Garrett7ade05a2017-02-17 13:31:47 -0800177
Don Garrett0c54ed72017-03-03 11:18:57 -0800178 cbuildbot_launch.main(['--buildroot', '/buildroot', 'config'])
Don Garrettc4114cc2016-11-01 20:04:06 -0700179
Don Garrett7ade05a2017-02-17 13:31:47 -0800180 # Ensure we clean, as expected.
181 self.assertEqual(mock_clean.mock_calls,
Don Garrett125d4dc2017-04-25 16:26:03 -0700182 [mock.call('master', '/buildroot')])
Don Garrett7ade05a2017-02-17 13:31:47 -0800183
Don Garrett86881cb2017-02-15 15:41:55 -0800184 # Ensure we checkout, as expected.
185 self.assertEqual(mock_checkout.mock_calls,
Don Garrett125d4dc2017-04-25 16:26:03 -0700186 [mock.call('master', '/buildroot', None)])
Don Garrettc4114cc2016-11-01 20:04:06 -0700187
Don Garrett86881cb2017-02-15 15:41:55 -0800188 # Ensure we invoke cbuildbot, as expected.
189 self.assertCommandCalled(
190 ['/buildroot/chromite/bin/cbuildbot',
Don Garrett597ddff2017-02-17 18:29:37 -0800191 'config', '--buildroot', '/buildroot'],
Don Garrett125d4dc2017-04-25 16:26:03 -0700192 cwd='/buildroot')
Don Garrettc4114cc2016-11-01 20:04:06 -0700193
Don Garrett86881cb2017-02-15 15:41:55 -0800194 def testMainMax(self):
Don Garrett597ddff2017-02-17 18:29:37 -0800195 """Test a larger set of command line options."""
196 self.PatchObject(osutils, 'SafeMakedirs', autospec=True)
197 self.PatchObject(cros_build_lib, 'GetTargetChromiteApiVersion',
Don Garrett861e9182017-05-15 15:30:23 -0700198 autospec=True, return_value=(constants.REEXEC_API_MAJOR,
199 constants.REEXEC_API_MINOR))
Don Garrett0c54ed72017-03-03 11:18:57 -0800200 mock_clean = self.PatchObject(cbuildbot_launch, 'CleanBuildroot',
201 autospec=True)
202 mock_checkout = self.PatchObject(cbuildbot_launch, 'InitialCheckout',
Don Garrett86881cb2017-02-15 15:41:55 -0800203 autospec=True)
Don Garrettc4114cc2016-11-01 20:04:06 -0700204
Don Garrett0c54ed72017-03-03 11:18:57 -0800205 cbuildbot_launch.main(['--buildroot', '/buildroot',
Don Garrett125d4dc2017-04-25 16:26:03 -0700206 '--branch', 'branch',
Don Garrett0c54ed72017-03-03 11:18:57 -0800207 '--git-cache-dir', '/git-cache',
208 'config'])
Don Garrettc4114cc2016-11-01 20:04:06 -0700209
Don Garrett7ade05a2017-02-17 13:31:47 -0800210 # Ensure we clean, as expected.
211 self.assertEqual(mock_clean.mock_calls,
Don Garrett125d4dc2017-04-25 16:26:03 -0700212 [mock.call('branch', '/buildroot')])
Don Garrett7ade05a2017-02-17 13:31:47 -0800213
Don Garrett86881cb2017-02-15 15:41:55 -0800214 # Ensure we checkout, as expected.
215 self.assertEqual(mock_checkout.mock_calls,
Don Garrett125d4dc2017-04-25 16:26:03 -0700216 [mock.call('branch', '/buildroot', '/git-cache')])
Don Garrett86881cb2017-02-15 15:41:55 -0800217
218 # Ensure we invoke cbuildbot, as expected.
219 self.assertCommandCalled(
220 ['/buildroot/chromite/bin/cbuildbot',
Don Garrett597ddff2017-02-17 18:29:37 -0800221 'config',
222 '--buildroot', '/buildroot',
Don Garrett125d4dc2017-04-25 16:26:03 -0700223 '--branch', 'branch',
Don Garrett597ddff2017-02-17 18:29:37 -0800224 '--git-cache-dir', '/git-cache'],
Don Garrett125d4dc2017-04-25 16:26:03 -0700225 cwd='/buildroot')
Don Garrett7ade05a2017-02-17 13:31:47 -0800226
227
Don Garrett60967922017-04-12 18:51:44 -0700228class CleanBuildrootTest(cros_test_lib.MockTempDirTestCase):
Don Garrett7ade05a2017-02-17 13:31:47 -0800229 """Tests for CleanBuildroot method."""
230
231 def setUp(self):
232 """Create standard buildroot contents for cleanup."""
Don Garrette17e1d92017-04-12 15:28:19 -0700233 self.root = os.path.join(self.tempdir, 'buildroot')
234 self.state = os.path.join(self.root, '.cbuildbot_launch_state')
235 self.repo = os.path.join(self.root, '.repo/repo')
236 self.chroot = os.path.join(self.root, 'chroot/chroot')
237 self.general = os.path.join(self.root, 'general/general')
Don Garrett39963602017-02-27 14:41:58 -0800238 # TODO: Add .cache, and distfiles.
Don Garrett7ade05a2017-02-17 13:31:47 -0800239
Don Garrett60967922017-04-12 18:51:44 -0700240 def populateBuildroot(self, state=None):
Don Garrett7ade05a2017-02-17 13:31:47 -0800241 """Create standard buildroot contents for cleanup."""
Don Garrett60967922017-04-12 18:51:44 -0700242 osutils.SafeMakedirs(self.root)
Don Garrette17e1d92017-04-12 15:28:19 -0700243
Don Garrett7ade05a2017-02-17 13:31:47 -0800244 if state:
245 osutils.WriteFile(self.state, state)
246
247 # Create files.
248 for f in (self.repo, self.chroot, self.general):
Don Garrette17e1d92017-04-12 15:28:19 -0700249 osutils.Touch(f, makedirs=True)
Don Garrett7ade05a2017-02-17 13:31:47 -0800250
Don Garrette17e1d92017-04-12 15:28:19 -0700251 def testNoBuildroot(self):
Don Garrett7ade05a2017-02-17 13:31:47 -0800252 """Test CleanBuildroot with no history."""
Don Garrett125d4dc2017-04-25 16:26:03 -0700253 cbuildbot_launch.CleanBuildroot('master', self.root)
Don Garrett7ade05a2017-02-17 13:31:47 -0800254
Don Garrett125d4dc2017-04-25 16:26:03 -0700255 self.assertEqual(osutils.ReadFile(self.state), '1 master')
Don Garrett7ade05a2017-02-17 13:31:47 -0800256
257 def testBuildrootNoState(self):
258 """Test CleanBuildroot with no state information."""
259 self.populateBuildroot()
260
Don Garrett125d4dc2017-04-25 16:26:03 -0700261 cbuildbot_launch.CleanBuildroot('master', self.root)
Don Garrett7ade05a2017-02-17 13:31:47 -0800262
Don Garrett125d4dc2017-04-25 16:26:03 -0700263 self.assertEqual(osutils.ReadFile(self.state), '1 master')
Don Garrett60967922017-04-12 18:51:44 -0700264 self.assertNotExists(self.repo)
Don Garrett7ade05a2017-02-17 13:31:47 -0800265 self.assertNotExists(self.chroot)
Don Garrett60967922017-04-12 18:51:44 -0700266 self.assertNotExists(self.general)
267
268 def testBuildrootFormatMismatch(self):
269 """Test CleanBuildroot with no state information."""
Don Garrett125d4dc2017-04-25 16:26:03 -0700270 self.populateBuildroot('0 master')
Don Garrett60967922017-04-12 18:51:44 -0700271
Don Garrett125d4dc2017-04-25 16:26:03 -0700272 cbuildbot_launch.CleanBuildroot('master', self.root)
Don Garrett60967922017-04-12 18:51:44 -0700273
Don Garrett125d4dc2017-04-25 16:26:03 -0700274 self.assertEqual(osutils.ReadFile(self.state), '1 master')
Don Garrett60967922017-04-12 18:51:44 -0700275 self.assertNotExists(self.repo)
276 self.assertNotExists(self.chroot)
277 self.assertNotExists(self.general)
Don Garrett7ade05a2017-02-17 13:31:47 -0800278
279 def testBuildrootBranchChange(self):
280 """Test CleanBuildroot with a change in branches."""
Don Garrett60967922017-04-12 18:51:44 -0700281 self.populateBuildroot('1 branchA')
Don Garrett7ade05a2017-02-17 13:31:47 -0800282
Don Garrette17e1d92017-04-12 15:28:19 -0700283 cbuildbot_launch.CleanBuildroot('branchB', self.root)
Don Garrett7ade05a2017-02-17 13:31:47 -0800284
Don Garrett60967922017-04-12 18:51:44 -0700285 self.assertEqual(osutils.ReadFile(self.state), '1 branchB')
Don Garrett7ade05a2017-02-17 13:31:47 -0800286 self.assertExists(self.repo)
287 self.assertNotExists(self.chroot)
288 self.assertExists(self.general)
289
290 def testBuildrootBranchMatch(self):
291 """Test CleanBuildroot with no change in branch."""
Don Garrett60967922017-04-12 18:51:44 -0700292 self.populateBuildroot('1 branchA')
Don Garrett7ade05a2017-02-17 13:31:47 -0800293
Don Garrette17e1d92017-04-12 15:28:19 -0700294 cbuildbot_launch.CleanBuildroot('branchA', self.root)
Don Garrett7ade05a2017-02-17 13:31:47 -0800295
Don Garrett60967922017-04-12 18:51:44 -0700296 self.assertEqual(osutils.ReadFile(self.state), '1 branchA')
Don Garrett7ade05a2017-02-17 13:31:47 -0800297 self.assertExists(self.repo)
298 self.assertExists(self.chroot)
299 self.assertExists(self.general)
Don Garrette17e1d92017-04-12 15:28:19 -0700300
Don Garrett60967922017-04-12 18:51:44 -0700301 def testGetBuildrootState(self):
302 """Test GetBuildrootState."""
303 # No root dir.
304 results = cbuildbot_launch.GetBuildrootState(self.root)
305 self.assertEqual(results, (0, ''))
306
307 # Empty root dir.
308 osutils.SafeMakedirs(self.root)
309 results = cbuildbot_launch.GetBuildrootState(self.root)
310 self.assertEqual(results, (0, ''))
311
312 # Empty Contents
313 osutils.WriteFile(self.state, '')
314 results = cbuildbot_launch.GetBuildrootState(self.root)
315 self.assertEqual(results, (0, ''))
316
317 # Old Format Contents
318 osutils.WriteFile(self.state, 'happy-branch')
319 results = cbuildbot_launch.GetBuildrootState(self.root)
320 self.assertEqual(results, (0, ''))
321
322 # Expected Contents
323 osutils.WriteFile(self.state, '1 happy-branch')
324 results = cbuildbot_launch.GetBuildrootState(self.root)
325 self.assertEqual(results, (1, 'happy-branch'))
326
327 # Future Contents
328 osutils.WriteFile(self.state, '22 master')
329 results = cbuildbot_launch.GetBuildrootState(self.root)
330 self.assertEqual(results, (22, 'master'))
331
332 # Read Write
333 cbuildbot_launch.SetBuildrootState('happy-branch', self.root)
334 results = cbuildbot_launch.GetBuildrootState(self.root)
335 self.assertEqual(results, (1, 'happy-branch'))
336
337 def testSetBuildrootState(self):
338 """Test SetBuildrootState."""
339 # Write out a state file.
340 osutils.SafeMakedirs(self.root)
341 cbuildbot_launch.SetBuildrootState('happy-branch', self.root)
342 self.assertEqual(osutils.ReadFile(self.state), '1 happy-branch')
343
344 # Change to a future version.
345 self.PatchObject(cbuildbot_launch, 'BUILDROOT_BUILDROOT_LAYOUT', 22)
346 cbuildbot_launch.SetBuildrootState('happy-branch', self.root)
347 self.assertEqual(osutils.ReadFile(self.state), '22 happy-branch')