blob: 32869ec4111eb9f713db8cf6c93b95ba8cd3e9d5 [file] [log] [blame]
Xixuan Wu0c76d5b2017-08-30 16:40:17 -07001# Copyright 2017 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"""Module for task unittests."""
Xixuan Wu5ff0fac2019-01-07 10:06:35 -08006# pylint: disable=g-missing-super-call
Xixuan Wu0c76d5b2017-08-30 16:40:17 -07007
8import re
9import unittest
10
Xixuan Wu5451a662017-10-17 10:57:40 -070011import build_lib
Xixuan Wu0c76d5b2017-08-30 16:40:17 -070012import config_reader
13import mock
Xixuan Wu0c76d5b2017-08-30 16:40:17 -070014import task
Xixuan Wu51bb7102019-03-18 14:51:44 -070015import task_config_reader
Xixuan Wu0c76d5b2017-08-30 16:40:17 -070016import tot_manager
17
18
19class FakeTotMilestoneManager(tot_manager.TotMilestoneManager):
20 """Mock class for tot_manager.TotMilestoneManager."""
21
22 def __init__(self, is_sanity):
23 self.is_sanity = is_sanity
24 self.storage_client = None
25 self.tot = self._tot_milestone()
26
27
Xixuan Wuc6819012019-05-23 11:34:59 -070028class FakeBuildClient(object):
29 """Mock rest_client.BuildBucketBigqueryClient."""
30
31 def __init__(self, success=True):
32 self.success = success
33
34 def get_latest_passed_builds(self, build_config):
35 if not self.success:
Xixuan Wu6ec23e32019-05-23 11:56:02 -070036 raise ValueError('No valid builds')
Xixuan Wuc6819012019-05-23 11:34:59 -070037
38 return build_lib.BuildInfo(board=build_config.split('-')[0],
39 model=None,
40 milestone=TaskTestCase.MILESTONE,
41 platform=TaskTestCase.PLATFORM,
42 build_config=build_config)
43
44
Xixuan Wu8d2f2862018-08-28 16:48:04 -070045class FakeLabConfig(object):
Xixuan Wuf4a4c882019-03-15 14:48:26 -070046 """Mock class for config_reader.LabConfig."""
47
48 def get_cros_model_map(self):
49 return {'coral': ['robo', 'nasher', 'lava']}
50
51
52class FakeMigrationConfig(object):
53 """Mock class for config_reader.MigrationConfig."""
Xixuan Wu8d2f2862018-08-28 16:48:04 -070054
Xixuan Wu1e42c752019-03-21 13:41:49 -070055 def get_skylab_suites_dump(self):
56 return {}
Xixuan Wu8d2f2862018-08-28 16:48:04 -070057
58
Xixuan Wu5451a662017-10-17 10:57:40 -070059class TaskBaseTestCase(unittest.TestCase):
Xixuan Wu0c76d5b2017-08-30 16:40:17 -070060
61 BOARD = 'fake_board'
Xixuan Wu8d2f2862018-08-28 16:48:04 -070062 UNIBUILD_BOARD = 'coral'
Po-Hsien Wang6d589732018-05-15 17:19:34 -070063 EXCLUDE_BOARD = 'exclude_fake_board'
Xixuan Wu0c76d5b2017-08-30 16:40:17 -070064 NAME = 'fake_name'
65 SUITE = 'fake_suite'
66 POOL = 'fake_pool'
67 PLATFORM = '6182.0.0-rc2'
68 MILESTONE = '30'
69 NUM = 1
70 PRIORITY = 50
71 TIMEOUT = 600
72
73 def setUp(self):
74 tot_patcher = mock.patch('tot_manager.TotMilestoneManager')
75 self._mock_tot = tot_patcher.start()
76 self.addCleanup(tot_patcher.stop)
77 # Can't pass in False since storage_client is not mocked.
78 self._mock_tot.return_value = FakeTotMilestoneManager(True)
Xixuan Wu51bb7102019-03-18 14:51:44 -070079 self.task = task.Task(task_config_reader.TaskInfo(
Xixuan Wu0c76d5b2017-08-30 16:40:17 -070080 name=self.NAME,
81 suite=self.SUITE,
82 branch_specs=[],
83 pool=self.POOL,
84 num=self.NUM,
Xixuan Wu8d2f2862018-08-28 16:48:04 -070085 boards=','.join([self.BOARD, self.UNIBUILD_BOARD]),
Po-Hsien Wang6d589732018-05-15 17:19:34 -070086 exclude_boards=self.EXCLUDE_BOARD,
Xixuan Wu0c76d5b2017-08-30 16:40:17 -070087 priority=self.PRIORITY,
88 timeout=self.TIMEOUT))
89
Xixuan Wuf4a4c882019-03-15 14:48:26 -070090 self._empty_configs = config_reader.Configs(
91 lab_config=config_reader.LabConfig(None),
92 migration_config=config_reader.MigrationConfig(None))
93 self._fake_configs = config_reader.Configs(
94 lab_config=FakeLabConfig(),
95 migration_config=FakeMigrationConfig())
96
Xixuan Wu5451a662017-10-17 10:57:40 -070097
98class TaskTestCase(TaskBaseTestCase):
99
100 def setUp(self):
101 super(TaskTestCase, self).setUp()
102
Xixuan Wu0c76d5b2017-08-30 16:40:17 -0700103 mock_push = mock.patch('task.Task._push_suite')
104 self._mock_push = mock_push.start()
105 self.addCleanup(mock_push.stop)
106
107 def testSetSpecCompareInfoEqual(self):
108 """Test compare info setting for specs that equals to a milestone."""
109 self.task.branch_specs = re.split(r'\s*,\s*', '==tot-2')
110 self.task._set_spec_compare_info()
111 self.assertTrue(self.task._version_equal_constraint)
112 self.assertFalse(self.task._version_gte_constraint)
113 self.assertFalse(self.task._version_lte_constraint)
114 self.assertEqual(self.task._bare_branches, [])
115
116 def testSetSpecCompareInfoLess(self):
117 """Test compare info setting for specs that is less than a milestone."""
118 self.task.branch_specs = re.split(r'\s*,\s*', '<=tot')
119 self.task._set_spec_compare_info()
120 self.assertFalse(self.task._version_equal_constraint)
121 self.assertFalse(self.task._version_gte_constraint)
122 self.assertTrue(self.task._version_lte_constraint)
123 self.assertEqual(self.task._bare_branches, [])
124
125 def testSetSpecCompareInfoGreater(self):
126 """Test compare info setting for specs that is greater than a milestone."""
127 self.task.branch_specs = re.split(r'\s*,\s*', '>=tot-2')
128 self.task._set_spec_compare_info()
129 self.assertFalse(self.task._version_equal_constraint)
130 self.assertTrue(self.task._version_gte_constraint)
131 self.assertFalse(self.task._version_lte_constraint)
132 self.assertEqual(self.task._bare_branches, [])
133
134 def testFitsSpecEqual(self):
135 """Test milestone check for specs that equals to a milestone."""
136 self.task.branch_specs = re.split(r'\s*,\s*', '==tot-1')
137 self.task._set_spec_compare_info()
138 self.assertFalse(self.task._fits_spec('40'))
139 self.assertTrue(self.task._fits_spec('39'))
140 self.assertFalse(self.task._fits_spec('38'))
141
142 def testFitsSpecLess(self):
143 """Test milestone check for specs that is less than a milestone."""
144 self.task.branch_specs = re.split(r'\s*,\s*', '<=tot-1')
145 self.task._set_spec_compare_info()
146 self.assertFalse(self.task._fits_spec('40'))
147 self.assertTrue(self.task._fits_spec('39'))
148 self.assertTrue(self.task._fits_spec('38'))
149
150 def testFitsSpecGreater(self):
151 """Test milestone check for specs that is greater than a milestone."""
152 self.task.branch_specs = re.split(r'\s*,\s*', '>=tot-2')
153 self.task._set_spec_compare_info()
154 self.assertTrue(self.task._fits_spec('39'))
155 self.assertTrue(self.task._fits_spec('38'))
156 self.assertFalse(self.task._fits_spec('37'))
157
158 def testGetFirmwareFromLabConfig(self):
159 """Test get firmware from lab config successfully."""
160 with mock.patch('config_reader.LabConfig.get_firmware_ro_build_list',
161 return_value='build1,build2'):
162 firmware = self.task._get_firmware_build(
163 'released_ro_2', self.BOARD, config_reader.LabConfig(None), None)
164 self.assertEqual(firmware, 'build2')
165
166 def testGetFirmwareFromLabConfigOutofIndex(self):
167 """Test get firmware from lab config when firmware index is invalid."""
168 with mock.patch('config_reader.LabConfig.get_firmware_ro_build_list',
169 return_value='build1,build2'):
170 self.assertRaises(ValueError,
171 self.task._get_latest_firmware_build_from_lab_config,
172 'released_ro_3',
173 self.BOARD,
174 config_reader.LabConfig(None))
175 self.assertIsNone(self.task._get_firmware_build(
176 'released_ro_3', self.BOARD, config_reader.LabConfig(None), None))
177
178 def testGetFirmwareFromDB(self):
179 """Test get firmware from DB successfully."""
180 firmware = self.task._get_firmware_build(
Xixuan Wuc6819012019-05-23 11:34:59 -0700181 'firmware', self.BOARD, None, FakeBuildClient())
Xixuan Wu0c76d5b2017-08-30 16:40:17 -0700182 self.assertEqual(
183 firmware,
184 '%s-firmware/R%s-%s' % (self.BOARD, self.MILESTONE, self.PLATFORM))
185
Xixuan Wu0c76d5b2017-08-30 16:40:17 -0700186 def testScheduleCrosSuccessfully(self):
Xixuan Wu8d2f2862018-08-28 16:48:04 -0700187 """test schedule cros builds successfully."""
188 branch_builds = {(self.BOARD, None, 'release', '56'): '0000.00.00'}
Xixuan Wu0c76d5b2017-08-30 16:40:17 -0700189 self.task._schedule_cros_builds(branch_builds,
Xixuan Wu1e42c752019-03-21 13:41:49 -0700190 self._fake_configs,
Xixuan Wuc6819012019-05-23 11:34:59 -0700191 FakeBuildClient())
Xixuan Wu0c76d5b2017-08-30 16:40:17 -0700192 self.assertEqual(self._mock_push.call_count, 1)
193
194 def testScheduleCrosNonvalidBoard(self):
195 """Test schedule no cros builds due to non-allowed board."""
Xixuan Wu8d2f2862018-08-28 16:48:04 -0700196 branch_builds = {('%s_2' % self.BOARD, None, 'release', '56'): '0000.00.00'}
Xixuan Wu0c76d5b2017-08-30 16:40:17 -0700197 self.task._schedule_cros_builds(branch_builds,
Xixuan Wuf4a4c882019-03-15 14:48:26 -0700198 self._empty_configs,
Xixuan Wuc6819012019-05-23 11:34:59 -0700199 FakeBuildClient())
Xixuan Wu0c76d5b2017-08-30 16:40:17 -0700200 self.assertEqual(self._mock_push.call_count, 0)
201
Po-Hsien Wang6d589732018-05-15 17:19:34 -0700202 def testScheduleCrosExcludeBoard(self):
203 """Test schedule no cros builds due to board is excluded."""
Xixuan Wu8d2f2862018-08-28 16:48:04 -0700204 branch_builds = {(self.EXCLUDE_BOARD, None, 'release', '56'): '0000.00.00'}
Po-Hsien Wang6d589732018-05-15 17:19:34 -0700205 self.task._schedule_cros_builds(branch_builds,
Xixuan Wuf4a4c882019-03-15 14:48:26 -0700206 self._empty_configs,
Xixuan Wuc6819012019-05-23 11:34:59 -0700207 FakeBuildClient())
Po-Hsien Wang6d589732018-05-15 17:19:34 -0700208 self.assertEqual(self._mock_push.call_count, 0)
209
Xixuan Wu8d2f2862018-08-28 16:48:04 -0700210 def testScheduleCrosSuccessfullyWithSpecifiedModel(self):
211 """Test schedule unibuild with specific model."""
212 self.task.board = self.UNIBUILD_BOARD
213 branch_builds = {(self.UNIBUILD_BOARD, 'robo', 'release', '56'):
214 '0000.00.00',
215 (self.UNIBUILD_BOARD, 'lava', 'release', '56'):
216 '0000.00.00'}
217 self.task._schedule_cros_builds(branch_builds,
Xixuan Wuf4a4c882019-03-15 14:48:26 -0700218 self._fake_configs,
Xixuan Wuc6819012019-05-23 11:34:59 -0700219 FakeBuildClient())
Xixuan Wu8d2f2862018-08-28 16:48:04 -0700220 self.assertEqual(self._mock_push.call_count, 2)
221
Xixuan Wu0c76d5b2017-08-30 16:40:17 -0700222 def testScheduleCrosNonValidSpec(self):
223 """Test schedule no cros builds due to non-allowed branch milestone."""
Xixuan Wu8d2f2862018-08-28 16:48:04 -0700224 branch_builds = {(self.BOARD, None, 'release', '56'): '0000.00.00'}
Xixuan Wu0c76d5b2017-08-30 16:40:17 -0700225 # Only run tasks whose milestone = tot (R40)
226 self.task.branch_specs = re.split(r'\s*,\s*', '==tot')
227 self.task._set_spec_compare_info()
228 self.task._schedule_cros_builds(branch_builds,
Xixuan Wuf4a4c882019-03-15 14:48:26 -0700229 self._empty_configs,
Xixuan Wuc6819012019-05-23 11:34:59 -0700230 FakeBuildClient())
Xixuan Wu0c76d5b2017-08-30 16:40:17 -0700231 self.assertEqual(self._mock_push.call_count, 0)
232
233 def testScheduleCrosSuccessfullyWithValidFirmware(self):
234 """Test schedule cros builds successfully with valid firmware."""
Xixuan Wu8d2f2862018-08-28 16:48:04 -0700235 branch_builds = {(self.BOARD, None, 'release', '56'): '0000.00.00'}
Xixuan Wu0c76d5b2017-08-30 16:40:17 -0700236 self.task.firmware_ro_build_spec = 'firmware'
237 self.task._schedule_cros_builds(branch_builds,
Xixuan Wu1e42c752019-03-21 13:41:49 -0700238 self._fake_configs,
Xixuan Wuc6819012019-05-23 11:34:59 -0700239 FakeBuildClient())
Xixuan Wu0c76d5b2017-08-30 16:40:17 -0700240 self.assertEqual(self._mock_push.call_count, 1)
241
242 def testScheduleCrosWithNonValidFirmware(self):
243 """Test schedule no cros builds due to non-existent firmware."""
Xixuan Wu8d2f2862018-08-28 16:48:04 -0700244 branch_builds = {(self.BOARD, None, 'release', '56'): '0000.00.00'}
Xixuan Wu0c76d5b2017-08-30 16:40:17 -0700245 self.task.firmware_ro_build_spec = 'firmware'
246 self.task._schedule_cros_builds(branch_builds,
Xixuan Wuf4a4c882019-03-15 14:48:26 -0700247 self._empty_configs,
Xixuan Wuc6819012019-05-23 11:34:59 -0700248 FakeBuildClient(success=False))
Xixuan Wu0c76d5b2017-08-30 16:40:17 -0700249 self.assertEqual(self._mock_push.call_count, 0)
250
251 def testScheduleLaunchControlWithFullBranches(self):
252 """Test schedule all launch control builds successfully."""
253 lc_builds = {self.BOARD: ['git_nyc-mr2-release/shamu-userdebug/3844975',
254 'git_nyc-mr1-release/shamu-userdebug/3783920']}
255 lc_branches = 'git_nyc-mr1-release,git_nyc-mr2-release'
256 self.task.launch_control_branches = [
257 t.lstrip() for t in lc_branches.split(',')]
258 self.task._schedule_launch_control_builds(lc_builds)
259 self.assertEqual(self._mock_push.call_count, 2)
260
261 def testScheduleLaunchControlWithPartlyBranches(self):
262 """Test schedule part of launch control builds due to branch check."""
263 lc_builds = {self.BOARD: ['git_nyc-mr2-release/shamu-userdebug/3844975',
264 'git_nyc-mr1-release/shamu-userdebug/3783920']}
265 lc_branches = 'git_nyc-mr1-release'
266 self.task.launch_control_branches = [
267 t.lstrip() for t in lc_branches.split(',')]
268 self.task._schedule_launch_control_builds(lc_builds)
269 self.assertEqual(self._mock_push.call_count, 1)
270
271 def testScheduleLaunchControlWithNoBranches(self):
272 """Test schedule none of launch control builds due to branch check."""
273 lc_builds = {self.BOARD: ['git_nyc-mr2-release/shamu-userdebug/3844975',
274 'git_nyc-mr1-release/shamu-userdebug/3783920']}
275 self.task.launch_control_branches = []
276 self.task._schedule_launch_control_builds(lc_builds)
277 self.assertEqual(self._mock_push.call_count, 0)
278
279 def testScheduleLaunchControlNonvalidBoard(self):
280 """Test schedule none of launch control builds due to board check."""
281 lc_builds = {'%s_2' % self.BOARD:
282 ['git_nyc-mr2-release/shamu-userdebug/3844975',
283 'git_nyc-mr1-release/shamu-userdebug/3783920']}
284 lc_branches = 'git_nyc-mr1-release,git_nyc-mr2-release'
285 self.task.launch_control_branches = [
286 t.lstrip() for t in lc_branches.split(',')]
287 self.task._schedule_launch_control_builds(lc_builds)
288 self.assertEqual(self._mock_push.call_count, 0)
Xixuan Wu5451a662017-10-17 10:57:40 -0700289
Po-Hsien Wang6d589732018-05-15 17:19:34 -0700290 def testScheduleLaunchControlExcludeBoard(self):
291 """Test schedule none of launch control builds due to board check."""
292 lc_builds = {self.EXCLUDE_BOARD:
293 ['git_nyc-mr2-release/shamu-userdebug/3844975',
294 'git_nyc-mr1-release/shamu-userdebug/3783920']}
295 lc_branches = 'git_nyc-mr1-release,git_nyc-mr2-release'
296 self.task.launch_control_branches = [
297 t.lstrip() for t in lc_branches.split(',')]
298 self.task._schedule_launch_control_builds(lc_builds)
299 self.assertEqual(self._mock_push.call_count, 0)
300
Xixuan Wu5451a662017-10-17 10:57:40 -0700301
302class TaskPushTestCase(TaskBaseTestCase):
303
304 def setUp(self):
305 super(TaskPushTestCase, self).setUp()
306 mock_push = mock.patch('task_executor.push')
307 self._mock_push = mock_push.start()
308 self.addCleanup(mock_push.stop)
309
310 def testScheduleCrOSIsPushSuccessfully(self):
311 """Test IS_PUSHED is changed if some CrOS suites are scheduled."""
Xixuan Wu8d2f2862018-08-28 16:48:04 -0700312 branch_builds = {(self.BOARD, None, 'release', '56'): '0000.00.00'}
Xixuan Wu5451a662017-10-17 10:57:40 -0700313 self.task.os_type = build_lib.OS_TYPE_CROS
314 self.assertTrue(self.task.schedule(
Xixuan Wu1e42c752019-03-21 13:41:49 -0700315 [], (branch_builds, []), self._fake_configs,
Xixuan Wuc6819012019-05-23 11:34:59 -0700316 FakeBuildClient()))
Xixuan Wu5451a662017-10-17 10:57:40 -0700317
318 def testScheduleLaunchControlIsPushSuccessfully(self):
319 """Test IS_PUSHED is changed if some launch control suites are scheduled."""
320 lc_builds = {self.BOARD: ['git_nyc-mr2-release/shamu-userdebug/3844975',
321 'git_nyc-mr1-release/shamu-userdebug/3783920']}
322 lc_branches = 'git_nyc-mr1-release,git_nyc-mr2-release'
323 self.task.launch_control_branches = [
324 t.lstrip() for t in lc_branches.split(',')]
325 self.task.os_type = build_lib.OS_TYPES_LAUNCH_CONTROL
326 self.assertTrue(self.task.schedule(
Xixuan Wuc6819012019-05-23 11:34:59 -0700327 lc_builds, ([], []), self._empty_configs, FakeBuildClient()))
Xixuan Wu5451a662017-10-17 10:57:40 -0700328
329 def testScheduleCrosIsPushInvalidBoard(self):
330 """Test schedule no cros builds due to non-allowed board."""
Craig Bergstrom58263d32018-04-26 14:11:35 -0600331 branch_builds = (
Xixuan Wu8d2f2862018-08-28 16:48:04 -0700332 {('%s_2' % self.BOARD, None, 'release', '56'): '0000.00.00'}, {},
Craig Bergstrom58263d32018-04-26 14:11:35 -0600333 )
Xixuan Wu5451a662017-10-17 10:57:40 -0700334 self.task.os_type = build_lib.OS_TYPE_CROS
335 self.assertFalse(self.task.schedule(
Xixuan Wuc6819012019-05-23 11:34:59 -0700336 [], branch_builds, self._empty_configs, FakeBuildClient()))
Xixuan Wu5451a662017-10-17 10:57:40 -0700337
338 def testScheduleLaunchControlIsPushInvalidBoard(self):
339 """Test schedule none of launch control builds due to board check."""
340 lc_builds = {'%s_2' % self.BOARD:
341 ['git_nyc-mr2-release/shamu-userdebug/3844975',
342 'git_nyc-mr1-release/shamu-userdebug/3783920']}
343 lc_branches = 'git_nyc-mr1-release,git_nyc-mr2-release'
344 self.task.launch_control_branches = [
345 t.lstrip() for t in lc_branches.split(',')]
346 self.task.os_type = build_lib.OS_TYPES_LAUNCH_CONTROL
347 self.task._schedule_launch_control_builds(lc_builds)
348 self.assertFalse(self.task.schedule(
Xixuan Wuc6819012019-05-23 11:34:59 -0700349 lc_builds, ([], []), self._empty_configs, FakeBuildClient()))