blob: 3adbb3b76770be2f54fb0d822fc5b015fcad0dad [file] [log] [blame]
Mike Frysingere58c0e22017-10-04 15:43:30 -04001# -*- coding: utf-8 -*-
Don Garrettc4114cc2016-11-01 20:04:06 -07002# Copyright 2016 The Chromium OS 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
Prathmesh Prabhuc41a0f52018-04-03 13:26:52 -07006"""Unit tests for chromite.scripts.cbuildbot_launch."""
Don Garrettc4114cc2016-11-01 20:04:06 -07007
8from __future__ import print_function
9
Don Garrett86881cb2017-02-15 15:41:55 -080010import mock
Don Garrett7ade05a2017-02-17 13:31:47 -080011import os
Prathmesh Prabhuc41a0f52018-04-03 13:26:52 -070012import time
Don Garrett86881cb2017-02-15 15:41:55 -080013
14from chromite.cbuildbot import repository
Benjamin Gordon90b2dd92018-04-12 14:04:21 -060015from chromite.lib import build_summary
Don Garrett861e9182017-05-15 15:30:23 -070016from chromite.lib import constants
Don Garrett597ddff2017-02-17 18:29:37 -080017from chromite.lib import cros_build_lib
Benjamin Gordon74645232018-05-04 17:40:42 -060018from chromite.lib import cros_sdk_lib
Don Garrett7ade05a2017-02-17 13:31:47 -080019from chromite.lib import cros_test_lib
Don Garrett86881cb2017-02-15 15:41:55 -080020from chromite.lib import osutils
Don Garrett0c54ed72017-03-03 11:18:57 -080021from chromite.scripts import cbuildbot_launch
Don Garrett86881cb2017-02-15 15:41:55 -080022
Don Garrett86881cb2017-02-15 15:41:55 -080023EXPECTED_MANIFEST_URL = 'https://chrome-internal-review.googlesource.com/chromeos/manifest-internal' # pylint: disable=line-too-long
Don Garrettc4114cc2016-11-01 20:04:06 -070024
25
Don Garrettacbb2392017-05-11 18:27:41 -070026# It's reasonable for unittests to look at internals.
27# pylint: disable=protected-access
28
29
Don Garrett8d314792017-05-18 13:11:42 -070030class FakeException(Exception):
31 """Test exception to raise during tests."""
32
33
Don Garrett0c54ed72017-03-03 11:18:57 -080034class CbuildbotLaunchTest(cros_test_lib.MockTestCase):
35 """Tests for cbuildbot_launch script."""
Don Garrettc4114cc2016-11-01 20:04:06 -070036
Don Garrett86881cb2017-02-15 15:41:55 -080037 def testPreParseArguments(self):
Don Garrettc4114cc2016-11-01 20:04:06 -070038 """Test that we can correctly extract branch values from cbuildbot args."""
Don Garrett597ddff2017-02-17 18:29:37 -080039 CASES = (
40 (['--buildroot', '/buildroot', 'daisy-incremental'],
41 (None, '/buildroot', None)),
42
43 (['--buildbot', '--buildroot', '/buildroot',
44 '--git-cache-dir', '/git-cache',
45 '-b', 'release-R57-9202.B',
46 'daisy-incremental'],
47 ('release-R57-9202.B', '/buildroot', '/git-cache')),
48
49 (['--debug', '--buildbot', '--notests',
50 '--buildroot', '/buildroot',
51 '--git-cache-dir', '/git-cache',
52 '--branch', 'release-R57-9202.B',
53 'daisy-incremental'],
54 ('release-R57-9202.B', '/buildroot', '/git-cache')),
Don Garrettc4114cc2016-11-01 20:04:06 -070055 )
56
Don Garrett597ddff2017-02-17 18:29:37 -080057 for cmd_args, expected in CASES:
58 expected_branch, expected_buildroot, expected_cache_dir = expected
59
Don Garrett0c54ed72017-03-03 11:18:57 -080060 options = cbuildbot_launch.PreParseArguments(cmd_args)
Don Garrett597ddff2017-02-17 18:29:37 -080061
62 self.assertEqual(options.branch, expected_branch)
63 self.assertEqual(options.buildroot, expected_buildroot)
64 self.assertEqual(options.git_cache_dir, expected_cache_dir)
Don Garrett86881cb2017-02-15 15:41:55 -080065
Don Garrettf324bc32017-05-23 14:00:53 -070066 def testInitialCheckout(self):
Don Garrett86881cb2017-02-15 15:41:55 -080067 """Test InitialCheckout with minimum settings."""
Don Garrettf324bc32017-05-23 14:00:53 -070068 mock_repo = mock.MagicMock()
69 mock_repo.branch = 'branch'
Don Garrett86881cb2017-02-15 15:41:55 -080070
Don Garrettf324bc32017-05-23 14:00:53 -070071 cbuildbot_launch.InitialCheckout(mock_repo)
Don Garrett86881cb2017-02-15 15:41:55 -080072
73 self.assertEqual(mock_repo.mock_calls, [
Don Garrett5516acb2018-11-15 16:02:59 -080074 mock.call.PreLoad('/preload/chromeos'),
Don Garrettf324bc32017-05-23 14:00:53 -070075 mock.call.Sync(detach=True),
Don Garrett8d314792017-05-18 13:11:42 -070076 ])
77
Don Garrettf15d65b2017-04-12 12:39:55 -070078 def testConfigureGlobalEnvironment(self):
Don Garrett60967922017-04-12 18:51:44 -070079 """Ensure that we can setup our global runtime environment correctly."""
Don Garrett86fec482017-05-17 18:13:33 -070080
81 os.environ.pop('LANG', None)
82 os.environ['LC_MONETARY'] = 'bad'
83
Don Garrettf15d65b2017-04-12 12:39:55 -070084 cbuildbot_launch.ConfigureGlobalEnvironment()
85
Don Garrett86fec482017-05-17 18:13:33 -070086 # Verify umask is updated.
Don Garrettf15d65b2017-04-12 12:39:55 -070087 self.assertEqual(os.umask(0), 0o22)
88
Don Garrett86fec482017-05-17 18:13:33 -070089 # Verify ENVs are cleaned up.
90 self.assertEqual(os.environ['LANG'], 'en_US.UTF-8')
91 self.assertNotIn('LC_MONETARY', os.environ)
92
Don Garrettf15d65b2017-04-12 12:39:55 -070093
Benjamin Gordon121a2aa2018-05-04 16:24:45 -060094class RunTests(cros_test_lib.RunCommandTestCase):
Don Garrett0c54ed72017-03-03 11:18:57 -080095 """Tests for cbuildbot_launch script."""
Don Garrett597ddff2017-02-17 18:29:37 -080096
97 ARGS_BASE = ['--buildroot', '/buildroot']
Don Garrett5cd946b2017-07-20 13:42:20 -070098 EXPECTED_ARGS_BASE = ['--buildroot', '/cbuildbot_buildroot']
Don Garrett597ddff2017-02-17 18:29:37 -080099 ARGS_GIT_CACHE = ['--git-cache-dir', '/git-cache']
100 ARGS_CONFIG = ['config']
Don Garrettbf90cdf2017-05-19 15:54:02 -0700101 CMD = ['/cbuildbot_buildroot/chromite/bin/cbuildbot']
Don Garrett597ddff2017-02-17 18:29:37 -0800102
Don Garrett6e5c6b92018-04-06 17:58:49 -0700103 def verifyCbuildbot(self, args, expected_cmd, version):
Don Garrett86881cb2017-02-15 15:41:55 -0800104 """Ensure we invoke cbuildbot correctly."""
Don Garrett597ddff2017-02-17 18:29:37 -0800105 self.PatchObject(
106 cros_build_lib, 'GetTargetChromiteApiVersion', autospec=True,
107 return_value=version)
108
Don Garrett6e5c6b92018-04-06 17:58:49 -0700109 cbuildbot_launch.Cbuildbot('/cbuildbot_buildroot', '/depot_tools', args)
Don Garrett597ddff2017-02-17 18:29:37 -0800110
111 self.assertCommandCalled(
Don Garretta50bf492017-09-28 18:33:02 -0700112 expected_cmd, extra_env={'PATH': mock.ANY},
113 cwd='/cbuildbot_buildroot', error_code_ok=True)
Don Garrett597ddff2017-02-17 18:29:37 -0800114
Don Garrett6e5c6b92018-04-06 17:58:49 -0700115 def testCbuildbotSimple(self):
Don Garrett597ddff2017-02-17 18:29:37 -0800116 """Ensure we invoke cbuildbot correctly."""
Don Garrett6e5c6b92018-04-06 17:58:49 -0700117 self.verifyCbuildbot(
Don Garrett597ddff2017-02-17 18:29:37 -0800118 self.ARGS_BASE + self.ARGS_CONFIG,
Don Garrettbf90cdf2017-05-19 15:54:02 -0700119 self.CMD + self.ARGS_CONFIG + self.EXPECTED_ARGS_BASE,
Don Garrett597ddff2017-02-17 18:29:37 -0800120 (0, 4))
121
Don Garrett6e5c6b92018-04-06 17:58:49 -0700122 def testCbuildbotNotFiltered(self):
Don Garrett597ddff2017-02-17 18:29:37 -0800123 """Ensure we invoke cbuildbot correctly."""
Don Garrett6e5c6b92018-04-06 17:58:49 -0700124 self.verifyCbuildbot(
Don Garrett597ddff2017-02-17 18:29:37 -0800125 self.ARGS_BASE + self.ARGS_CONFIG + self.ARGS_GIT_CACHE,
Don Garrettbf90cdf2017-05-19 15:54:02 -0700126 (self.CMD + self.ARGS_CONFIG + self.EXPECTED_ARGS_BASE +
127 self.ARGS_GIT_CACHE),
Don Garrett597ddff2017-02-17 18:29:37 -0800128 (0, 4))
129
Don Garrett6e5c6b92018-04-06 17:58:49 -0700130 def testCbuildbotFiltered(self):
Don Garrett597ddff2017-02-17 18:29:37 -0800131 """Ensure we invoke cbuildbot correctly."""
Don Garrett6e5c6b92018-04-06 17:58:49 -0700132 self.verifyCbuildbot(
Don Garrett597ddff2017-02-17 18:29:37 -0800133 self.ARGS_BASE + self.ARGS_CONFIG + self.ARGS_GIT_CACHE,
Don Garrettbf90cdf2017-05-19 15:54:02 -0700134 self.CMD + self.ARGS_CONFIG + self.EXPECTED_ARGS_BASE,
Don Garrett597ddff2017-02-17 18:29:37 -0800135 (0, 2))
Don Garrettc4114cc2016-11-01 20:04:06 -0700136
Don Garrett86881cb2017-02-15 15:41:55 -0800137 def testMainMin(self):
138 """Test a minimal set of command line options."""
Don Garrett597ddff2017-02-17 18:29:37 -0800139 self.PatchObject(osutils, 'SafeMakedirs', autospec=True)
140 self.PatchObject(cros_build_lib, 'GetTargetChromiteApiVersion',
Don Garrett861e9182017-05-15 15:30:23 -0700141 autospec=True, return_value=(constants.REEXEC_API_MAJOR,
142 constants.REEXEC_API_MINOR))
Don Garrettf324bc32017-05-23 14:00:53 -0700143 mock_repo = mock.MagicMock()
144 mock_repo.branch = 'master'
Don Garrettbf90cdf2017-05-19 15:54:02 -0700145 mock_repo.directory = '/root/repository'
146
Don Garrettf324bc32017-05-23 14:00:53 -0700147 mock_repo_create = self.PatchObject(repository, 'RepoRepository',
148 autospec=True, return_value=mock_repo)
Don Garrettbf90cdf2017-05-19 15:54:02 -0700149 mock_clean = self.PatchObject(cbuildbot_launch, 'CleanBuildRoot',
Don Garrett0c54ed72017-03-03 11:18:57 -0800150 autospec=True)
151 mock_checkout = self.PatchObject(cbuildbot_launch, 'InitialCheckout',
Don Garrett86881cb2017-02-15 15:41:55 -0800152 autospec=True)
Benjamin Gordonaee36b82018-02-05 14:25:26 -0700153 mock_cleanup_chroot = self.PatchObject(cbuildbot_launch, 'CleanupChroot',
154 autospec=True)
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600155 mock_set_last_build_state = self.PatchObject(
156 cbuildbot_launch, 'SetLastBuildState', autospec=True)
157
158 expected_build_state = build_summary.BuildSummary(
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600159 build_number=0, master_build_id=0, status=mock.ANY,
160 buildroot_layout=2, branch='master')
Don Garrett7ade05a2017-02-17 13:31:47 -0800161
Dhanya Ganesh95c5c152018-10-08 16:48:29 -0600162 argv = ['-r', '/root', 'config']
163 options = cbuildbot_launch.PreParseArguments(argv)
164 cbuildbot_launch._main(options, argv)
Don Garrettc4114cc2016-11-01 20:04:06 -0700165
Don Garrettf324bc32017-05-23 14:00:53 -0700166 # Did we create the repo instance correctly?
167 self.assertEqual(mock_repo_create.mock_calls,
Don Garrettbf90cdf2017-05-19 15:54:02 -0700168 [mock.call(EXPECTED_MANIFEST_URL, '/root/repository',
Don Garrett33872502018-08-03 22:30:40 +0000169 git_cache_dir=None, branch='master')])
Don Garrettf324bc32017-05-23 14:00:53 -0700170
Don Garrett7ade05a2017-02-17 13:31:47 -0800171 # Ensure we clean, as expected.
Don Garrettbf90cdf2017-05-19 15:54:02 -0700172 self.assertEqual(mock_clean.mock_calls, [
Don Garrettd1d90dd2017-06-13 17:35:52 -0700173 mock.call('/root', mock_repo,
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600174 expected_build_state)])
Don Garrett7ade05a2017-02-17 13:31:47 -0800175
Don Garrett86881cb2017-02-15 15:41:55 -0800176 # Ensure we checkout, as expected.
177 self.assertEqual(mock_checkout.mock_calls,
Don Garrettf324bc32017-05-23 14:00:53 -0700178 [mock.call(mock_repo)])
Don Garrettc4114cc2016-11-01 20:04:06 -0700179
Don Garrett86881cb2017-02-15 15:41:55 -0800180 # Ensure we invoke cbuildbot, as expected.
181 self.assertCommandCalled(
Don Garrett5cd946b2017-07-20 13:42:20 -0700182 [
183 '/root/repository/chromite/bin/cbuildbot',
184 'config',
185 '-r', '/root/repository',
Don Garrettb497f552018-07-09 16:01:13 -0700186 '--workspace', '/root/workspace',
Don Garrett5cd946b2017-07-20 13:42:20 -0700187 '--ts-mon-task-num', '1',
188 ],
Don Garretta50bf492017-09-28 18:33:02 -0700189 extra_env={'PATH': mock.ANY},
Don Garrettbf90cdf2017-05-19 15:54:02 -0700190 cwd='/root/repository',
Don Garrettacbb2392017-05-11 18:27:41 -0700191 error_code_ok=True)
Don Garrettc4114cc2016-11-01 20:04:06 -0700192
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600193 # Ensure we saved the final state, as expected.
194 self.assertEqual(expected_build_state.status,
195 constants.BUILDER_STATUS_PASSED)
196 self.assertEqual(mock_set_last_build_state.mock_calls, [
197 mock.call('/root', expected_build_state)])
198
Benjamin Gordonaee36b82018-02-05 14:25:26 -0700199 # Ensure we clean the chroot, as expected.
200 self.assertEqual(mock_cleanup_chroot.mock_calls, [
201 mock.call('/root/repository')])
202
Don Garrett86881cb2017-02-15 15:41:55 -0800203 def testMainMax(self):
Don Garrett597ddff2017-02-17 18:29:37 -0800204 """Test a larger set of command line options."""
205 self.PatchObject(osutils, 'SafeMakedirs', autospec=True)
206 self.PatchObject(cros_build_lib, 'GetTargetChromiteApiVersion',
Don Garrett861e9182017-05-15 15:30:23 -0700207 autospec=True, return_value=(constants.REEXEC_API_MAJOR,
208 constants.REEXEC_API_MINOR))
Don Garrettf324bc32017-05-23 14:00:53 -0700209 mock_repo = mock.MagicMock()
210 mock_repo.branch = 'branch'
Don Garrettbf90cdf2017-05-19 15:54:02 -0700211 mock_repo.directory = '/root/repository'
212
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600213 mock_summary = build_summary.BuildSummary(
214 build_number=313,
215 master_build_id=123123123,
216 status=constants.BUILDER_STATUS_FAILED,
217 buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
218 branch='branch')
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600219
220 mock_get_last_build_state = self.PatchObject(
221 cbuildbot_launch, 'GetLastBuildState', autospec=True,
222 return_value=mock_summary)
Don Garrettf324bc32017-05-23 14:00:53 -0700223 mock_repo_create = self.PatchObject(repository, 'RepoRepository',
224 autospec=True, return_value=mock_repo)
Don Garrettbf90cdf2017-05-19 15:54:02 -0700225 mock_clean = self.PatchObject(cbuildbot_launch, 'CleanBuildRoot',
Don Garrett0c54ed72017-03-03 11:18:57 -0800226 autospec=True)
227 mock_checkout = self.PatchObject(cbuildbot_launch, 'InitialCheckout',
Don Garrett86881cb2017-02-15 15:41:55 -0800228 autospec=True)
Benjamin Gordonaee36b82018-02-05 14:25:26 -0700229 mock_cleanup_chroot = self.PatchObject(cbuildbot_launch, 'CleanupChroot',
230 autospec=True)
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600231 mock_set_last_build_state = self.PatchObject(
232 cbuildbot_launch, 'SetLastBuildState', autospec=True)
Dhanya Ganesh95c5c152018-10-08 16:48:29 -0600233 argv = ['--buildroot', '/root',
234 '--branch', 'branch',
235 '--git-cache-dir', '/git-cache',
236 '--remote-trybot',
237 '--master-build-id', '123456789',
238 '--buildnumber', '314',
239 'config']
240 options = cbuildbot_launch.PreParseArguments(argv)
241 cbuildbot_launch._main(options, argv)
Don Garrettc4114cc2016-11-01 20:04:06 -0700242
Don Garrettf324bc32017-05-23 14:00:53 -0700243 # Did we create the repo instance correctly?
244 self.assertEqual(mock_repo_create.mock_calls,
Don Garrettbf90cdf2017-05-19 15:54:02 -0700245 [mock.call(EXPECTED_MANIFEST_URL, '/root/repository',
Don Garrett33872502018-08-03 22:30:40 +0000246 git_cache_dir='/git-cache', branch='branch')])
Don Garrettf324bc32017-05-23 14:00:53 -0700247
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600248 # Ensure we look up the previous status.
249 self.assertEqual(mock_get_last_build_state.mock_calls, [
250 mock.call('/root')])
251
Don Garrett7ade05a2017-02-17 13:31:47 -0800252 # Ensure we clean, as expected.
Don Garrettbf90cdf2017-05-19 15:54:02 -0700253 self.assertEqual(mock_clean.mock_calls, [
Don Garrettd1d90dd2017-06-13 17:35:52 -0700254 mock.call('/root',
255 mock_repo,
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600256 build_summary.BuildSummary(
257 build_number=314,
258 master_build_id=123456789,
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600259 status=mock.ANY,
260 branch='branch',
261 buildroot_layout=2
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600262 ))])
Don Garrett7ade05a2017-02-17 13:31:47 -0800263
Don Garrett86881cb2017-02-15 15:41:55 -0800264 # Ensure we checkout, as expected.
265 self.assertEqual(mock_checkout.mock_calls,
Don Garrettf324bc32017-05-23 14:00:53 -0700266 [mock.call(mock_repo)])
Don Garrett86881cb2017-02-15 15:41:55 -0800267
268 # Ensure we invoke cbuildbot, as expected.
269 self.assertCommandCalled(
Don Garrett5cd946b2017-07-20 13:42:20 -0700270 [
271 '/root/repository/chromite/bin/cbuildbot',
272 'config',
273 '--buildroot', '/root/repository',
274 '--branch', 'branch',
275 '--git-cache-dir', '/git-cache',
276 '--remote-trybot',
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600277 '--master-build-id', '123456789',
278 '--buildnumber', '314',
279 '--previous-build-state',
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600280 'eyJzdGF0dXMiOiAiZmFpbCIsICJtYXN0ZXJfYnVpbGRfaWQiOiAxMjMxMjMxMj'
281 'MsICJidWlsZF9udW1iZXIiOiAzMTMsICJidWlsZHJvb3RfbGF5b3V0IjogMiwg'
282 'ImJyYW5jaCI6ICJicmFuY2gifQ==',
Don Garrettb497f552018-07-09 16:01:13 -0700283 '--workspace', '/root/workspace',
Don Garrett5cd946b2017-07-20 13:42:20 -0700284 '--ts-mon-task-num', '1',
285 ],
Don Garretta50bf492017-09-28 18:33:02 -0700286 extra_env={'PATH': mock.ANY},
Don Garrettbf90cdf2017-05-19 15:54:02 -0700287 cwd='/root/repository',
Don Garrettacbb2392017-05-11 18:27:41 -0700288 error_code_ok=True)
Don Garrett7ade05a2017-02-17 13:31:47 -0800289
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600290 # Ensure we write the final build state, as expected.
291 final_state = build_summary.BuildSummary(
292 build_number=314,
293 master_build_id=123456789,
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600294 status=constants.BUILDER_STATUS_PASSED,
295 buildroot_layout=2,
296 branch='branch')
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600297 self.assertEqual(mock_set_last_build_state.mock_calls, [
298 mock.call('/root', final_state)])
299
Benjamin Gordonaee36b82018-02-05 14:25:26 -0700300 # Ensure we clean the chroot, as expected.
301 self.assertEqual(mock_cleanup_chroot.mock_calls, [
302 mock.call('/root/repository')])
303
Don Garrett7ade05a2017-02-17 13:31:47 -0800304
Don Garrettbf90cdf2017-05-19 15:54:02 -0700305class CleanBuildRootTest(cros_test_lib.MockTempDirTestCase):
306 """Tests for CleanBuildRoot method."""
Don Garrett7ade05a2017-02-17 13:31:47 -0800307
308 def setUp(self):
309 """Create standard buildroot contents for cleanup."""
Don Garrettbf90cdf2017-05-19 15:54:02 -0700310 self.root = os.path.join(self.tempdir)
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600311 self.previous_build_state = os.path.join(
312 self.root, '.cbuildbot_build_state.json')
Don Garrettbf90cdf2017-05-19 15:54:02 -0700313 self.buildroot = os.path.join(self.root, 'buildroot')
314 self.repo = os.path.join(self.buildroot, '.repo/repo')
Don Garrett36650112018-06-28 15:54:34 -0700315 self.chroot = os.path.join(self.buildroot, 'chroot')
Don Garrettbf90cdf2017-05-19 15:54:02 -0700316 self.general = os.path.join(self.buildroot, 'general/general')
Prathmesh Prabhuc41a0f52018-04-03 13:26:52 -0700317 self.cache = os.path.join(self.buildroot, '.cache')
318 self.distfiles = os.path.join(self.cache, 'distfiles')
Don Garrett7ade05a2017-02-17 13:31:47 -0800319
Don Garrett4166d182018-12-17 12:52:02 -0800320 self.mock_repo = mock.Mock(repository.RepoRepository)
Don Garrettbf90cdf2017-05-19 15:54:02 -0700321 self.mock_repo.directory = self.buildroot
Don Garrettf324bc32017-05-23 14:00:53 -0700322
Benjamin Gordon8642bcc2018-05-01 13:49:56 -0600323 def populateBuildroot(self, previous_build_state=None):
Don Garrett7ade05a2017-02-17 13:31:47 -0800324 """Create standard buildroot contents for cleanup."""
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600325 if previous_build_state:
326 osutils.SafeMakedirs(self.root)
327 osutils.WriteFile(self.previous_build_state, previous_build_state)
328
Don Garrett7ade05a2017-02-17 13:31:47 -0800329 # Create files.
Prathmesh Prabhuc41a0f52018-04-03 13:26:52 -0700330 for f in (self.repo, self.chroot, self.general, self.distfiles):
Don Garrette17e1d92017-04-12 15:28:19 -0700331 osutils.Touch(f, makedirs=True)
Don Garrett7ade05a2017-02-17 13:31:47 -0800332
Don Garrette17e1d92017-04-12 15:28:19 -0700333 def testNoBuildroot(self):
Don Garrettbf90cdf2017-05-19 15:54:02 -0700334 """Test CleanBuildRoot with no history."""
Don Garrettf324bc32017-05-23 14:00:53 -0700335 self.mock_repo.branch = 'master'
336
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600337 build_state = build_summary.BuildSummary(
338 status=constants.BUILDER_STATUS_INFLIGHT,
339 buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
340 branch='master')
Don Garrettbf90cdf2017-05-19 15:54:02 -0700341 cbuildbot_launch.CleanBuildRoot(
Dhanya Ganesh95c5c152018-10-08 16:48:29 -0600342 self.root, self.mock_repo, build_state)
Don Garrett7ade05a2017-02-17 13:31:47 -0800343
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600344 new_summary = cbuildbot_launch.GetLastBuildState(self.root)
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600345 self.assertEqual(new_summary.buildroot_layout, 2)
346 self.assertEqual(new_summary.branch, 'master')
347 self.assertIsNotNone(new_summary.distfiles_ts)
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600348 self.assertEqual(new_summary, build_state)
Don Garrett7ade05a2017-02-17 13:31:47 -0800349
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600350 self.assertExists(self.previous_build_state)
351
Don Garrett7ade05a2017-02-17 13:31:47 -0800352 def testBuildrootNoState(self):
Don Garrettbf90cdf2017-05-19 15:54:02 -0700353 """Test CleanBuildRoot with no state information."""
Don Garrett7ade05a2017-02-17 13:31:47 -0800354 self.populateBuildroot()
Don Garrettf324bc32017-05-23 14:00:53 -0700355 self.mock_repo.branch = 'master'
Don Garrett7ade05a2017-02-17 13:31:47 -0800356
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600357 build_state = build_summary.BuildSummary(
358 status=constants.BUILDER_STATUS_INFLIGHT,
359 buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
360 branch='master')
Don Garrettbf90cdf2017-05-19 15:54:02 -0700361 cbuildbot_launch.CleanBuildRoot(
Dhanya Ganesh95c5c152018-10-08 16:48:29 -0600362 self.root, self.mock_repo, build_state)
Don Garrett7ade05a2017-02-17 13:31:47 -0800363
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600364 new_summary = cbuildbot_launch.GetLastBuildState(self.root)
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600365 self.assertEqual(new_summary.buildroot_layout, 2)
366 self.assertEqual(new_summary.branch, 'master')
367 self.assertIsNotNone(new_summary.distfiles_ts)
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600368 self.assertEqual(new_summary, build_state)
Prathmesh Prabhuc41a0f52018-04-03 13:26:52 -0700369
Don Garrett60967922017-04-12 18:51:44 -0700370 self.assertNotExists(self.repo)
Don Garrett7ade05a2017-02-17 13:31:47 -0800371 self.assertNotExists(self.chroot)
Don Garrett60967922017-04-12 18:51:44 -0700372 self.assertNotExists(self.general)
Prathmesh Prabhuc41a0f52018-04-03 13:26:52 -0700373 self.assertNotExists(self.distfiles)
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600374 self.assertExists(self.previous_build_state)
Don Garrett7ade05a2017-02-17 13:31:47 -0800375
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600376 def testBuildrootFormatMismatch(self):
377 """Test CleanBuildRoot with buildroot layout mismatch."""
378 old_build_state = build_summary.BuildSummary(
379 status=constants.BUILDER_STATUS_PASSED,
380 buildroot_layout=1,
381 branch='master')
382 self.populateBuildroot(previous_build_state=old_build_state.to_json())
383 self.mock_repo.branch = 'master'
384
385 build_state = build_summary.BuildSummary(
386 status=constants.BUILDER_STATUS_INFLIGHT,
387 buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
388 branch='master')
389 cbuildbot_launch.CleanBuildRoot(
Dhanya Ganesh95c5c152018-10-08 16:48:29 -0600390 self.root, self.mock_repo, build_state)
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600391
392 new_summary = cbuildbot_launch.GetLastBuildState(self.root)
393 self.assertEqual(new_summary.buildroot_layout, 2)
394 self.assertEqual(new_summary.branch, 'master')
395 self.assertIsNotNone(new_summary.distfiles_ts)
396 self.assertEqual(new_summary, build_state)
397
398 self.assertNotExists(self.repo)
399 self.assertNotExists(self.chroot)
400 self.assertNotExists(self.general)
401 self.assertNotExists(self.distfiles)
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600402 self.assertExists(self.previous_build_state)
403
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600404 def testBuildrootBranchChange(self):
405 """Test CleanBuildRoot with a change in branches."""
406 old_build_state = build_summary.BuildSummary(
407 status=constants.BUILDER_STATUS_PASSED,
408 buildroot_layout=2,
409 branch='branchA')
410 self.populateBuildroot(previous_build_state=old_build_state.to_json())
411 self.mock_repo.branch = 'branchB'
Benjamin Gordon74645232018-05-04 17:40:42 -0600412 m = self.PatchObject(cros_sdk_lib, 'CleanupChrootMount')
Don Garrett7ade05a2017-02-17 13:31:47 -0800413
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600414 build_state = build_summary.BuildSummary(
415 status=constants.BUILDER_STATUS_INFLIGHT,
416 buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
417 branch='branchB')
Don Garrettbf90cdf2017-05-19 15:54:02 -0700418 cbuildbot_launch.CleanBuildRoot(
Dhanya Ganesh95c5c152018-10-08 16:48:29 -0600419 self.root, self.mock_repo, build_state)
Don Garrett7ade05a2017-02-17 13:31:47 -0800420
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600421 new_summary = cbuildbot_launch.GetLastBuildState(self.root)
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600422 self.assertEqual(new_summary.buildroot_layout, 2)
423 self.assertEqual(new_summary.branch, 'branchB')
424 self.assertIsNotNone(new_summary.distfiles_ts)
425 self.assertEqual(new_summary, build_state)
426
Don Garrett4166d182018-12-17 12:52:02 -0800427 # self.assertExists(self.repo)
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600428 self.assertExists(self.general)
429 self.assertNotExists(self.distfiles)
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600430 self.assertExists(self.previous_build_state)
Don Garrett36650112018-06-28 15:54:34 -0700431 m.assert_called_with(self.chroot, delete=True)
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600432
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600433 def testBuildrootBranchMatch(self):
434 """Test CleanBuildRoot with no change in branch."""
435 old_build_state = build_summary.BuildSummary(
436 status=constants.BUILDER_STATUS_PASSED,
437 buildroot_layout=2,
438 branch='branchA')
439 self.populateBuildroot(previous_build_state=old_build_state.to_json())
440 self.mock_repo.branch = 'branchA'
441
442 build_state = build_summary.BuildSummary(
443 status=constants.BUILDER_STATUS_INFLIGHT,
444 buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
445 branch='branchA')
446 cbuildbot_launch.CleanBuildRoot(
Dhanya Ganesh95c5c152018-10-08 16:48:29 -0600447 self.root, self.mock_repo, build_state)
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600448
449 new_summary = cbuildbot_launch.GetLastBuildState(self.root)
450 self.assertEqual(new_summary.buildroot_layout, 2)
451 self.assertEqual(new_summary.branch, 'branchA')
452 self.assertIsNotNone(new_summary.distfiles_ts)
453 self.assertEqual(new_summary, build_state)
454
455 self.assertExists(self.repo)
456 self.assertExists(self.chroot)
457 self.assertExists(self.general)
458 self.assertExists(self.distfiles)
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600459 self.assertExists(self.previous_build_state)
Prathmesh Prabhuc41a0f52018-04-03 13:26:52 -0700460
Don Garrett4166d182018-12-17 12:52:02 -0800461 def testBuildrootGitLocksPrevPass(self):
462 """Verify not CleanStaleLocks, if previous build was in passed."""
463 old_build_state = build_summary.BuildSummary(
464 status=constants.BUILDER_STATUS_PASSED,
465 buildroot_layout=2,
466 branch='branchA')
467 self.populateBuildroot(previous_build_state=old_build_state.to_json())
468 self.mock_repo.branch = 'branchA'
469
470 build_state = build_summary.BuildSummary(
471 status=constants.BUILDER_STATUS_INFLIGHT,
472 buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
473 branch='branchA')
474 cbuildbot_launch.CleanBuildRoot(
475 self.root, self.mock_repo, build_state)
476
477 self.assertEqual(
478 self.mock_repo.mock_calls, [
479 mock.call.PreLoad(),
480 mock.call.BuildRootGitCleanup(prune_all=True),
481 ])
482
483 def testBuildrootGitLocksPrevFail(self):
484 """Verify not CleanStaleLocks, if previous build was in failed."""
485 old_build_state = build_summary.BuildSummary(
486 status=constants.BUILDER_STATUS_FAILED,
487 buildroot_layout=2,
488 branch='branchA')
489 self.populateBuildroot(previous_build_state=old_build_state.to_json())
490 self.mock_repo.branch = 'branchA'
491
492 build_state = build_summary.BuildSummary(
493 status=constants.BUILDER_STATUS_INFLIGHT,
494 buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
495 branch='branchA')
496 cbuildbot_launch.CleanBuildRoot(
497 self.root, self.mock_repo, build_state)
498
499 self.assertEqual(
500 self.mock_repo.mock_calls, [
501 mock.call.PreLoad(),
502 mock.call.BuildRootGitCleanup(prune_all=True),
503 ])
504
505 def testBuildrootGitLocksPrevInFlight(self):
506 """Verify CleanStaleLocks, if previous build was in flight."""
507 old_build_state = build_summary.BuildSummary(
508 status=constants.BUILDER_STATUS_INFLIGHT,
509 buildroot_layout=2,
510 branch='branchA')
511 self.populateBuildroot(previous_build_state=old_build_state.to_json())
512 self.mock_repo.branch = 'branchA'
513
514 build_state = build_summary.BuildSummary(
515 status=constants.BUILDER_STATUS_INFLIGHT,
516 buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
517 branch='branchA')
518 cbuildbot_launch.CleanBuildRoot(
519 self.root, self.mock_repo, build_state)
520
521
522 self.assertEqual(
523 self.mock_repo.method_calls, [
524 mock.call.PreLoad(),
525 mock.call.CleanStaleLocks(),
526 mock.call.BuildRootGitCleanup(prune_all=True),
527 ])
528
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600529 def testBuildrootDistfilesRecentCache(self):
530 """Test CleanBuildRoot does not delete distfiles when cache is recent."""
531 seed_distfiles_ts = time.time() - 60
532 old_build_state = build_summary.BuildSummary(
533 status=constants.BUILDER_STATUS_PASSED,
534 buildroot_layout=2,
535 branch='branchA',
536 distfiles_ts=seed_distfiles_ts)
537 self.populateBuildroot(previous_build_state=old_build_state.to_json())
538 self.mock_repo.branch = 'branchA'
539
540 build_state = build_summary.BuildSummary(
541 status=constants.BUILDER_STATUS_INFLIGHT,
542 buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
543 branch='branchA')
544 cbuildbot_launch.CleanBuildRoot(
Dhanya Ganesh95c5c152018-10-08 16:48:29 -0600545 self.root, self.mock_repo, build_state)
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600546
547 new_summary = cbuildbot_launch.GetLastBuildState(self.root)
548 self.assertEqual(new_summary.buildroot_layout, 2)
549 self.assertEqual(new_summary.branch, 'branchA')
550 # Same cache creation timestamp is rewritten to state.
551 self.assertEqual(new_summary.distfiles_ts, seed_distfiles_ts)
552 self.assertEqual(new_summary, build_state)
553
554 self.assertExists(self.repo)
555 self.assertExists(self.chroot)
556 self.assertExists(self.general)
557 self.assertExists(self.distfiles)
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600558 self.assertExists(self.previous_build_state)
Don Garrette17e1d92017-04-12 15:28:19 -0700559
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600560 def testBuildrootDistfilesCacheExpired(self):
561 """Test CleanBuildRoot when the distfiles cache is too old."""
562 old_build_state = build_summary.BuildSummary(
563 status=constants.BUILDER_STATUS_PASSED,
564 buildroot_layout=2,
565 branch='branchA',
566 distfiles_ts=100.0)
567 self.populateBuildroot(previous_build_state=old_build_state.to_json())
568 self.mock_repo.branch = 'branchA'
569
570 build_state = build_summary.BuildSummary(
571 status=constants.BUILDER_STATUS_INFLIGHT,
572 buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
573 branch='branchA')
574 cbuildbot_launch.CleanBuildRoot(
Dhanya Ganesh95c5c152018-10-08 16:48:29 -0600575 self.root, self.mock_repo, build_state)
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600576
577 new_summary = cbuildbot_launch.GetLastBuildState(self.root)
578 self.assertEqual(new_summary.buildroot_layout, 2)
579 self.assertEqual(new_summary.branch, 'branchA')
580 self.assertIsNotNone(new_summary.distfiles_ts)
581 self.assertEqual(new_summary, build_state)
582
583 self.assertExists(self.repo)
584 self.assertExists(self.chroot)
585 self.assertExists(self.general)
586 self.assertNotExists(self.distfiles)
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600587 self.assertExists(self.previous_build_state)
588
589 def testBuildrootRepoCleanFailure(self):
590 """Test CleanBuildRoot with repo checkout failure."""
591 old_build_state = build_summary.BuildSummary(
592 status=constants.BUILDER_STATUS_PASSED,
593 buildroot_layout=1,
594 branch='branchA')
595 self.populateBuildroot(previous_build_state=old_build_state.to_json())
596 self.mock_repo.branch = 'branchA'
597 self.mock_repo.BuildRootGitCleanup.side_effect = Exception
598
599 build_state = build_summary.BuildSummary(
600 status=constants.BUILDER_STATUS_INFLIGHT,
601 buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
602 branch='branchA')
603 cbuildbot_launch.CleanBuildRoot(
Dhanya Ganesh95c5c152018-10-08 16:48:29 -0600604 self.root, self.mock_repo, build_state)
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600605
606 new_summary = cbuildbot_launch.GetLastBuildState(self.root)
607 self.assertEqual(new_summary.buildroot_layout, 2)
608 self.assertEqual(new_summary.branch, 'branchA')
609 self.assertIsNotNone(new_summary.distfiles_ts)
610 self.assertEqual(new_summary, build_state)
611
612 self.assertNotExists(self.repo)
613 self.assertNotExists(self.chroot)
614 self.assertNotExists(self.general)
615 self.assertNotExists(self.distfiles)
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600616 self.assertExists(self.previous_build_state)
Don Garrettf324bc32017-05-23 14:00:53 -0700617
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600618 def testGetCurrentBuildStateNoArgs(self):
619 """Tests GetCurrentBuildState without arguments."""
620 options = cbuildbot_launch.PreParseArguments([
621 '--buildroot', self.root, 'config'
622 ])
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600623 state = cbuildbot_launch.GetCurrentBuildState(options, 'master')
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600624
625 expected_state = build_summary.BuildSummary(
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600626 status=constants.BUILDER_STATUS_INFLIGHT,
627 buildroot_layout=2,
628 branch='master')
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600629 self.assertEqual(state, expected_state)
630
631 def testGetCurrentBuildStateHasArgs(self):
632 """Tests GetCurrentBuildState with arguments."""
633 options = cbuildbot_launch.PreParseArguments([
634 '--buildroot', self.root,
635 '--buildnumber', '20',
636 '--master-build-id', '50',
637 'config'
638 ])
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600639 state = cbuildbot_launch.GetCurrentBuildState(options, 'branchA')
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600640
641 expected_state = build_summary.BuildSummary(
642 build_number=20,
643 master_build_id=50,
Benjamin Gordon8b6d4122018-04-26 13:38:39 -0600644 status=constants.BUILDER_STATUS_INFLIGHT,
645 buildroot_layout=2,
646 branch='branchA')
647 self.assertEqual(state, expected_state)
648
649 def testGetCurrentBuildStateLayout(self):
650 """Test that GetCurrentBuildState uses the current buildroot layout."""
651 # Change to a future version.
652 self.PatchObject(cbuildbot_launch, 'BUILDROOT_BUILDROOT_LAYOUT', 22)
653
654 options = cbuildbot_launch.PreParseArguments([
655 '--buildroot', self.root, 'config'
656 ])
657 state = cbuildbot_launch.GetCurrentBuildState(options, 'branchA')
658
659 expected_state = build_summary.BuildSummary(
660 status=constants.BUILDER_STATUS_INFLIGHT,
661 buildroot_layout=22,
662 branch='branchA')
Benjamin Gordon90b2dd92018-04-12 14:04:21 -0600663 self.assertEqual(state, expected_state)
664
665 def testGetLastBuildStateNoFile(self):
666 """Tests GetLastBuildState if the file is missing."""
667 osutils.SafeMakedirs(self.root)
668 state = cbuildbot_launch.GetLastBuildState(self.root)
669 self.assertEqual(state, build_summary.BuildSummary())
670
671 def testGetLastBuildStateBadFile(self):
672 """Tests GetLastBuildState if the file contains invalid JSON."""
673 osutils.SafeMakedirs(self.root)
674 osutils.WriteFile(self.previous_build_state, '}}')
675 state = cbuildbot_launch.GetLastBuildState(self.root)
676 self.assertEqual(state, build_summary.BuildSummary())
677
678 def testGetLastBuildStateMissingBuildStatus(self):
679 """Tests GetLastBuildState if the file doesn't have a valid status."""
680 osutils.SafeMakedirs(self.root)
681 osutils.WriteFile(self.previous_build_state, '{"build_number": "3"}')
682 state = cbuildbot_launch.GetLastBuildState(self.root)
683 self.assertEqual(state, build_summary.BuildSummary())
684
685 def testGetLastBuildStateGoodFile(self):
686 """Tests GetLastBuildState on a good file."""
687 osutils.SafeMakedirs(self.root)
688 osutils.WriteFile(
689 self.previous_build_state,
690 '{"build_number": 1, "master_build_id": 3, "status": "pass"}')
691 state = cbuildbot_launch.GetLastBuildState(self.root)
692 self.assertEqual(
693 state,
694 build_summary.BuildSummary(
695 build_number=1, master_build_id=3, status='pass'))
696
697 def testSetLastBuildState(self):
698 """Verifies that SetLastBuildState writes to the expected file."""
699 osutils.SafeMakedirs(self.root)
700 old_state = build_summary.BuildSummary(
701 build_number=314,
702 master_build_id=2178,
703 status=constants.BUILDER_STATUS_PASSED)
704 cbuildbot_launch.SetLastBuildState(self.root, old_state)
705
706 saved_state = osutils.ReadFile(self.previous_build_state)
707 new_state = build_summary.BuildSummary()
708 new_state.from_json(saved_state)
709
710 self.assertEqual(old_state, new_state)