blob: a89b78f863747bcc044b478651acbc1ec2d7ab57 [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."""
6
7import re
8import unittest
9
10import cloud_sql_client
11import config_reader
12import mock
13import MySQLdb
14import task
15import tot_manager
16
17
18class FakeTotMilestoneManager(tot_manager.TotMilestoneManager):
19 """Mock class for tot_manager.TotMilestoneManager."""
20
21 def __init__(self, is_sanity):
22 self.is_sanity = is_sanity
23 self.storage_client = None
24 self.tot = self._tot_milestone()
25
26
27class FakeCIDBClient(object):
28 """Mock class for cloud_sql_client.CIDBClient."""
29
30 def __init__(self, success=True):
31 self.success = success
32
33 def get_latest_passed_builds(self, build_config):
34 if not self.success:
35 raise MySQLdb.OperationalError('Failed to connect to db')
36
37 return cloud_sql_client.BuildInfo(board=build_config.split('-')[0],
38 milestone=TaskTestCase.MILESTONE,
39 platform=TaskTestCase.PLATFORM,
40 build_config=build_config)
41
42
43class TaskTestCase(unittest.TestCase):
44
45 BOARD = 'fake_board'
46 NAME = 'fake_name'
47 SUITE = 'fake_suite'
48 POOL = 'fake_pool'
49 PLATFORM = '6182.0.0-rc2'
50 MILESTONE = '30'
51 NUM = 1
52 PRIORITY = 50
53 TIMEOUT = 600
54
55 def setUp(self):
56 tot_patcher = mock.patch('tot_manager.TotMilestoneManager')
57 self._mock_tot = tot_patcher.start()
58 self.addCleanup(tot_patcher.stop)
59 # Can't pass in False since storage_client is not mocked.
60 self._mock_tot.return_value = FakeTotMilestoneManager(True)
61 self.task = task.Task(config_reader.TaskInfo(
62 name=self.NAME,
63 suite=self.SUITE,
64 branch_specs=[],
65 pool=self.POOL,
66 num=self.NUM,
67 boards=self.BOARD,
68 priority=self.PRIORITY,
69 timeout=self.TIMEOUT))
70
71 mock_push = mock.patch('task.Task._push_suite')
72 self._mock_push = mock_push.start()
73 self.addCleanup(mock_push.stop)
74
75 def testSetSpecCompareInfoEqual(self):
76 """Test compare info setting for specs that equals to a milestone."""
77 self.task.branch_specs = re.split(r'\s*,\s*', '==tot-2')
78 self.task._set_spec_compare_info()
79 self.assertTrue(self.task._version_equal_constraint)
80 self.assertFalse(self.task._version_gte_constraint)
81 self.assertFalse(self.task._version_lte_constraint)
82 self.assertEqual(self.task._bare_branches, [])
83
84 def testSetSpecCompareInfoLess(self):
85 """Test compare info setting for specs that is less than a milestone."""
86 self.task.branch_specs = re.split(r'\s*,\s*', '<=tot')
87 self.task._set_spec_compare_info()
88 self.assertFalse(self.task._version_equal_constraint)
89 self.assertFalse(self.task._version_gte_constraint)
90 self.assertTrue(self.task._version_lte_constraint)
91 self.assertEqual(self.task._bare_branches, [])
92
93 def testSetSpecCompareInfoGreater(self):
94 """Test compare info setting for specs that is greater than a milestone."""
95 self.task.branch_specs = re.split(r'\s*,\s*', '>=tot-2')
96 self.task._set_spec_compare_info()
97 self.assertFalse(self.task._version_equal_constraint)
98 self.assertTrue(self.task._version_gte_constraint)
99 self.assertFalse(self.task._version_lte_constraint)
100 self.assertEqual(self.task._bare_branches, [])
101
102 def testFitsSpecEqual(self):
103 """Test milestone check for specs that equals to a milestone."""
104 self.task.branch_specs = re.split(r'\s*,\s*', '==tot-1')
105 self.task._set_spec_compare_info()
106 self.assertFalse(self.task._fits_spec('40'))
107 self.assertTrue(self.task._fits_spec('39'))
108 self.assertFalse(self.task._fits_spec('38'))
109
110 def testFitsSpecLess(self):
111 """Test milestone check for specs that is less than a milestone."""
112 self.task.branch_specs = re.split(r'\s*,\s*', '<=tot-1')
113 self.task._set_spec_compare_info()
114 self.assertFalse(self.task._fits_spec('40'))
115 self.assertTrue(self.task._fits_spec('39'))
116 self.assertTrue(self.task._fits_spec('38'))
117
118 def testFitsSpecGreater(self):
119 """Test milestone check for specs that is greater than a milestone."""
120 self.task.branch_specs = re.split(r'\s*,\s*', '>=tot-2')
121 self.task._set_spec_compare_info()
122 self.assertTrue(self.task._fits_spec('39'))
123 self.assertTrue(self.task._fits_spec('38'))
124 self.assertFalse(self.task._fits_spec('37'))
125
126 def testGetFirmwareFromLabConfig(self):
127 """Test get firmware from lab config successfully."""
128 with mock.patch('config_reader.LabConfig.get_firmware_ro_build_list',
129 return_value='build1,build2'):
130 firmware = self.task._get_firmware_build(
131 'released_ro_2', self.BOARD, config_reader.LabConfig(None), None)
132 self.assertEqual(firmware, 'build2')
133
134 def testGetFirmwareFromLabConfigOutofIndex(self):
135 """Test get firmware from lab config when firmware index is invalid."""
136 with mock.patch('config_reader.LabConfig.get_firmware_ro_build_list',
137 return_value='build1,build2'):
138 self.assertRaises(ValueError,
139 self.task._get_latest_firmware_build_from_lab_config,
140 'released_ro_3',
141 self.BOARD,
142 config_reader.LabConfig(None))
143 self.assertIsNone(self.task._get_firmware_build(
144 'released_ro_3', self.BOARD, config_reader.LabConfig(None), None))
145
146 def testGetFirmwareFromDB(self):
147 """Test get firmware from DB successfully."""
148 firmware = self.task._get_firmware_build(
149 'firmware', self.BOARD, None, FakeCIDBClient())
150 self.assertEqual(
151 firmware,
152 '%s-firmware/R%s-%s' % (self.BOARD, self.MILESTONE, self.PLATFORM))
153
154 def testGetFirmwareFromDBConnectionError(self):
155 """Test get firmware from DB when DB connection is failed."""
156 self.assertIsNone(self.task._get_firmware_build(
157 'firmware', self.BOARD, None, FakeCIDBClient(success=False)))
158
159 def testScheduleCrosSuccessfully(self):
160 """Test schedule cros builds successfully."""
161 branch_builds = {(self.BOARD, 'release', '56'): '0000.00.00'}
162 self.task._schedule_cros_builds(branch_builds,
163 config_reader.LabConfig(None),
164 FakeCIDBClient())
165 self.assertEqual(self._mock_push.call_count, 1)
166
167 def testScheduleCrosNonvalidBoard(self):
168 """Test schedule no cros builds due to non-allowed board."""
169 branch_builds = {('%s_2' % self.BOARD, 'release', '56'): '0000.00.00'}
170 self.task._schedule_cros_builds(branch_builds,
171 config_reader.LabConfig(None),
172 FakeCIDBClient())
173 self.assertEqual(self._mock_push.call_count, 0)
174
175 def testScheduleCrosNonValidSpec(self):
176 """Test schedule no cros builds due to non-allowed branch milestone."""
177 branch_builds = {(self.BOARD, 'release', '56'): '0000.00.00'}
178 # Only run tasks whose milestone = tot (R40)
179 self.task.branch_specs = re.split(r'\s*,\s*', '==tot')
180 self.task._set_spec_compare_info()
181 self.task._schedule_cros_builds(branch_builds,
182 config_reader.LabConfig(None),
183 FakeCIDBClient())
184 self.assertEqual(self._mock_push.call_count, 0)
185
186 def testScheduleCrosSuccessfullyWithValidFirmware(self):
187 """Test schedule cros builds successfully with valid firmware."""
188 branch_builds = {(self.BOARD, 'release', '56'): '0000.00.00'}
189 self.task.firmware_ro_build_spec = 'firmware'
190 self.task._schedule_cros_builds(branch_builds,
191 config_reader.LabConfig(None),
192 FakeCIDBClient())
193 self.assertEqual(self._mock_push.call_count, 1)
194
195 def testScheduleCrosWithNonValidFirmware(self):
196 """Test schedule no cros builds due to non-existent firmware."""
197 branch_builds = {(self.BOARD, 'release', '56'): '0000.00.00'}
198 self.task.firmware_ro_build_spec = 'firmware'
199 self.task._schedule_cros_builds(branch_builds,
200 config_reader.LabConfig(None),
201 FakeCIDBClient(success=False))
202 self.assertEqual(self._mock_push.call_count, 0)
203
204 def testScheduleLaunchControlWithFullBranches(self):
205 """Test schedule all launch control builds successfully."""
206 lc_builds = {self.BOARD: ['git_nyc-mr2-release/shamu-userdebug/3844975',
207 'git_nyc-mr1-release/shamu-userdebug/3783920']}
208 lc_branches = 'git_nyc-mr1-release,git_nyc-mr2-release'
209 self.task.launch_control_branches = [
210 t.lstrip() for t in lc_branches.split(',')]
211 self.task._schedule_launch_control_builds(lc_builds)
212 self.assertEqual(self._mock_push.call_count, 2)
213
214 def testScheduleLaunchControlWithPartlyBranches(self):
215 """Test schedule part of launch control builds due to branch check."""
216 lc_builds = {self.BOARD: ['git_nyc-mr2-release/shamu-userdebug/3844975',
217 'git_nyc-mr1-release/shamu-userdebug/3783920']}
218 lc_branches = 'git_nyc-mr1-release'
219 self.task.launch_control_branches = [
220 t.lstrip() for t in lc_branches.split(',')]
221 self.task._schedule_launch_control_builds(lc_builds)
222 self.assertEqual(self._mock_push.call_count, 1)
223
224 def testScheduleLaunchControlWithNoBranches(self):
225 """Test schedule none of launch control builds due to branch check."""
226 lc_builds = {self.BOARD: ['git_nyc-mr2-release/shamu-userdebug/3844975',
227 'git_nyc-mr1-release/shamu-userdebug/3783920']}
228 self.task.launch_control_branches = []
229 self.task._schedule_launch_control_builds(lc_builds)
230 self.assertEqual(self._mock_push.call_count, 0)
231
232 def testScheduleLaunchControlNonvalidBoard(self):
233 """Test schedule none of launch control builds due to board check."""
234 lc_builds = {'%s_2' % self.BOARD:
235 ['git_nyc-mr2-release/shamu-userdebug/3844975',
236 'git_nyc-mr1-release/shamu-userdebug/3783920']}
237 lc_branches = 'git_nyc-mr1-release,git_nyc-mr2-release'
238 self.task.launch_control_branches = [
239 t.lstrip() for t in lc_branches.split(',')]
240 self.task._schedule_launch_control_builds(lc_builds)
241 self.assertEqual(self._mock_push.call_count, 0)