blob: 5637e3b7750aa0c7cbc1d972804ea787638fcbbc [file] [log] [blame]
Xixuan Wu51bb7102019-03-18 14:51:44 -07001# Copyright 2018 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 config reader unittests."""
6# pylint: disable=g-missing-super-call
7
8import unittest
9
10import config_reader
11import constants
12import mock
13import task_config_reader
14import tot_manager
15
16
17class FakeTotMilestoneManager(tot_manager.TotMilestoneManager):
18
19 def __init__(self, is_sanity):
20 self.is_sanity = is_sanity
21 self.storage_client = None
22 self.tot = self._tot_milestone()
23
24
25class BaseTaskConfigReaderTestCase(unittest.TestCase):
26
27 _EVENT_TYPE = 'nightly'
28 _PRIORITY = task_config_reader.EVENT_CLASSES[_EVENT_TYPE].PRIORITY
29 _TIMEOUT = task_config_reader.EVENT_CLASSES[_EVENT_TYPE].TIMEOUT
30 _TASK_NAME = 'fake_task'
31 _SUITE = 'fake_suite'
32 _BRANCH_SPEC = 'tot-1'
33 _POOL = 'bvt'
34 _NUM = 2
35 _BOARD = 'link'
Xinan Linc8647112020-02-04 16:45:56 -080036 _DIMENSIONS = 'label-wifi:foo'
Xixuan Wu51bb7102019-03-18 14:51:44 -070037
38 def setUp(self):
39 self.config = config_reader.ConfigReader(None)
40 self.config.add_section(self._TASK_NAME)
41 self.config.set(self._TASK_NAME, 'suite', self._SUITE)
42 self.config.set(self._TASK_NAME, 'branch_specs', self._BRANCH_SPEC)
43 self.config.set(self._TASK_NAME, 'run_on', self._EVENT_TYPE)
44 self.config.set(self._TASK_NAME, 'pool', self._POOL)
45 self.config.set(self._TASK_NAME, 'num', '%d' % self._NUM)
46 self.config.set(self._TASK_NAME, 'boards', self._BOARD)
Xinan Linc8647112020-02-04 16:45:56 -080047 self.config.set(self._TASK_NAME, 'dimensions', self._DIMENSIONS)
Xixuan Wu51bb7102019-03-18 14:51:44 -070048
49 tot_patcher = mock.patch('tot_manager.TotMilestoneManager')
50 self._tot = tot_patcher.start()
51 self._tot.return_value = FakeTotMilestoneManager(True)
52
53 board_family_patcher = mock.patch(
54 'build_lib.get_board_family_mapping_from_gs')
55 board_family_getter = board_family_patcher.start()
56 board_family_getter.return_value = {
57 'nyan': ['nyan', 'nyan_blaze', 'nyan_big'],
58 'ivybridge': ['link', 'link_freon']}
59
60 self.addCleanup(tot_patcher.stop)
61 self.addCleanup(board_family_patcher.stop)
62
63
64class TaskCreationTestCase(BaseTaskConfigReaderTestCase):
65
66 def testCreateTaskFromConfigNonexistentSection(self):
67 """Ensure a Task CANNOT be built without suite, and raise error."""
68 task_config = task_config_reader.TaskConfig(self.config)
69 self.assertRaises(task_config_reader.MalformedConfigEntryError,
70 task_config._create_task_from_config_section,
71 'non-existent section')
72
73 def testCreateTaskFromConfigNotAllowedHeader(self):
Brigit Rossbachf6e5a522021-01-12 13:38:01 -070074 """Ensure a Task can be built with unknown config headers."""
Xixuan Wu51bb7102019-03-18 14:51:44 -070075 self.config.set(self._TASK_NAME, 'non-valid-header', 'test')
76 task_config = task_config_reader.TaskConfig(self.config)
Brigit Rossbachf6e5a522021-01-12 13:38:01 -070077 response = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
78 self.assertEqual(len(response), 1)
Xixuan Wu51bb7102019-03-18 14:51:44 -070079
80 def testGetTaskByKeyword(self):
81 """Ensure a Task can be built from a correct config."""
82 task_config = task_config_reader.TaskConfig(self.config)
83 tasks = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
84 self.assertEqual(len(tasks), 1)
85 new_task = tasks[0]
86 self.assertEqual(new_task.name, self._TASK_NAME)
87 self.assertEqual(new_task.suite, self._SUITE)
88 self.assertEqual(new_task.branch_specs, [self._BRANCH_SPEC])
89 self.assertEqual(new_task.pool, self._POOL)
90 self.assertEqual(new_task.num, self._NUM)
91 self.assertEqual(new_task.boards,
92 [t.lstrip() for t in self._BOARD.split(',')])
93 self.assertEqual(new_task.priority, self._PRIORITY)
94 self.assertEqual(new_task.timeout, self._TIMEOUT)
Xinan Linc8647112020-02-04 16:45:56 -080095 self.assertEqual(new_task.dimensions, self._DIMENSIONS)
Xixuan Wu51bb7102019-03-18 14:51:44 -070096
97 def testGetTaskByKeywordNoRunonNoRaise(self):
98 """Ensure a Task CANNOT be built without run_on, but not raise error."""
99 self.config.remove_option(self._TASK_NAME, 'run_on')
100 task_config = task_config_reader.TaskConfig(self.config)
101 try:
102 response = task_config.get_tasks_by_keyword(self._EVENT_TYPE)
103 self.assertEqual(len(response['tasks']), 0)
104 self.assertEqual(len(response['exceptions']), 1)
105 except task_config_reader.MalformedConfigEntryError:
106 self.fail('task_config should not raise error without run_on!')
107
108 def testGetTaskByKeywordNoSuiteNoRaise(self):
109 """Ensure a Task CANNOT be built without suite, but not raise error.
110
111 This is to ensure a malformed task won't affect other tasks' reading.
112 """
113 self.config.remove_option(self._TASK_NAME, 'suite')
114 task_config = task_config_reader.TaskConfig(self.config)
115 try:
116 response = task_config.get_tasks_by_keyword(self._EVENT_TYPE)
117 self.assertEqual(len(response['tasks']), 0)
118 self.assertEqual(len(response['exceptions']), 1)
119 except config_reader.MalformedConfigEntry:
120 self.fail('task_config should not raise error without suite!')
121
122 def testGetTaskByKeywordNoBranch(self):
123 """Ensure a Task can be built without branch_specs."""
124 self.config.remove_option(self._TASK_NAME, 'branch_specs')
125 task_config = task_config_reader.TaskConfig(self.config)
126 tasks = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
127 self.assertEqual(tasks[0].branch_specs, [])
128
129 def testGetTaskByKeywordNoNum(self):
130 """Ensure a Task can be built without num."""
131 self.config.remove_option(self._TASK_NAME, 'num')
132 task_config = task_config_reader.TaskConfig(self.config)
133 tasks = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
134 self.assertIsNone(tasks[0].num)
135
136 def testSetPriority(self):
137 """Ensure priority can be set by user."""
138 priority = constants.Priorities.DEFAULT
139 self.config.set(self._TASK_NAME, 'priority', str(priority))
140 task_config = task_config_reader.TaskConfig(self.config)
141 tasks = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
142 self.assertEqual(tasks[0].priority, priority)
143
Xinan Lin292f38c2020-04-16 14:09:50 -0700144 def testSuitePoolShouldNotSetPriority(self):
145 """Ensure priority is not set for pool suites."""
146 self.config.set(self._TASK_NAME, 'pool', 'suites')
147 task_config = task_config_reader.TaskConfig(self.config)
148 tasks = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
149 self.assertIsNone(tasks[0].priority)
150
Xixuan Wu51bb7102019-03-18 14:51:44 -0700151 def testSetTimeout(self):
152 """Ensure timeout can be set by user."""
153 timeout = 1000
154 self.config.set(self._TASK_NAME, 'timeout', str(timeout))
155 task_config = task_config_reader.TaskConfig(self.config)
156 tasks = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
157 self.assertEqual(tasks[0].timeout, timeout)
158
159
160class TaskInfoCheckTestCase(BaseTaskConfigReaderTestCase):
161
162 def testNonIntNum(self):
163 """Ensure a Task's num is a Integer."""
164 self.config.set(self._TASK_NAME, 'num', 'non_int')
165 task_config = task_config_reader.TaskConfig(self.config)
166 self.assertRaises(task_config_reader.MalformedConfigEntryError,
167 task_config._read_task_section,
168 self._TASK_NAME)
169
170 def testNonIntHour(self):
171 """Ensure a Task's hour is a Integer."""
172 self.config.set(self._TASK_NAME, 'hour', 'non_int')
173 task_config = task_config_reader.TaskConfig(self.config)
174 self.assertRaises(task_config_reader.MalformedConfigEntryError,
175 task_config._read_task_section,
176 self._TASK_NAME)
177
178 def testNonIntDay(self):
179 """Ensure a Task's hour is a Integer."""
180 self.config.set(self._TASK_NAME, 'day', 'non_int')
181 task_config = task_config_reader.TaskConfig(self.config)
182 self.assertRaises(task_config_reader.MalformedConfigEntryError,
183 task_config._read_task_section,
184 self._TASK_NAME)
185
186 def testNoSuite(self):
187 """Ensure a Task's suite exists."""
188 self.config.remove_option(self._TASK_NAME, 'suite')
189 task_config = task_config_reader.TaskConfig(self.config)
190 task_info = task_config._read_task_section(self._TASK_NAME)
191 self.assertRaises(task_config_reader.MalformedConfigEntryError,
192 task_config._validate_task_section,
193 task_info)
194
195 def testInvalidIntHour(self):
196 """Ensure a Task's hour is in 0~23."""
197 self.config.set(self._TASK_NAME, 'hour', '24')
198 task_config = task_config_reader.TaskConfig(self.config)
199 task_info = task_config._read_task_section(self._TASK_NAME)
200 self.assertRaises(task_config_reader.MalformedConfigEntryError,
201 task_config._validate_task_section,
202 task_info)
203
204 def testNoHourForNonNightlyEvent(self):
205 """Ensure a non-nightly Task cannot specify hour."""
206 self.config.set(self._TASK_NAME, 'hour', '10')
207 self.config.set(self._TASK_NAME, 'run_on', 'new_build')
208 task_config = task_config_reader.TaskConfig(self.config)
209 task_info = task_config._read_task_section(self._TASK_NAME)
210 self.assertRaises(task_config_reader.MalformedConfigEntryError,
211 task_config._validate_task_section,
212 task_info)
213
214 def testInvalidIntDay(self):
215 """Ensure a Task's day is in 0~6."""
216 self.config.set(self._TASK_NAME, 'day', '10')
217 self.config.set(self._TASK_NAME, 'run_on', 'weekly')
218 task_config = task_config_reader.TaskConfig(self.config)
219 task_info = task_config._read_task_section(self._TASK_NAME)
220 self.assertRaises(task_config_reader.MalformedConfigEntryError,
221 task_config._validate_task_section,
222 task_info)
223
224 def testNoDayForNonWeeklyEvent(self):
225 """Ensure a non-weekly Task cannot specify day."""
226 self.config.set(self._TASK_NAME, 'day', '1')
227 self.config.set(self._TASK_NAME, 'run_on', 'nightly')
228 task_config = task_config_reader.TaskConfig(self.config)
229 task_info = task_config._read_task_section(self._TASK_NAME)
230 self.assertRaises(task_config_reader.MalformedConfigEntryError,
231 task_config._validate_task_section,
232 task_info)
233
234 def testInValidOSType(self):
235 """Ensure a Task's os_type is valid."""
236 self.config.set(self._TASK_NAME, 'os_type', 'invalid')
237 task_config = task_config_reader.TaskConfig(self.config)
238 task_info = task_config._read_task_section(self._TASK_NAME)
239 self.assertRaises(task_config_reader.MalformedConfigEntryError,
240 task_config._check_os_type,
241 task_info)
242
243 def testNoLaunchControlForCrOS(self):
244 """Ensure a CrOS Task doesn't have launch control settings."""
245 self.config.set(self._TASK_NAME, 'os_type', 'CrOS')
246 self.config.set(self._TASK_NAME, 'branches', 'shamu-userdebug')
247 task_config = task_config_reader.TaskConfig(self.config)
248 task_info = task_config._read_task_section(self._TASK_NAME)
249 self.assertRaises(task_config_reader.MalformedConfigEntryError,
250 task_config._check_os_type,
251 task_info)
252
253 def testLaunchControlForNonCrOS(self):
254 """Ensure an android Task has launch control settings."""
255 self.config.set(self._TASK_NAME, 'os_type', 'android')
256 task_config = task_config_reader.TaskConfig(self.config)
257 task_info = task_config._read_task_section(self._TASK_NAME)
258 self.assertRaises(task_config_reader.MalformedConfigEntryError,
259 task_config._check_os_type,
260 task_info)
261
262 def testGetTestbedCount(self):
263 """Ensure testbed count can be successfully parsed."""
264 task_config = task_config_reader.TaskConfig(self.config)
265 self.assertEqual(task_config._get_testbed_dut_count('sharu-2'), 2)
266
267 def testNoTestbedForCrOS(self):
268 """Ensure CrOS task won't specify testbed parameters."""
269 self.config.set(self._TASK_NAME, 'boards', 'sharu-2')
270 task_config = task_config_reader.TaskConfig(self.config)
271 task_info = task_config._read_task_section(self._TASK_NAME)
272 self.assertRaises(task_config_reader.MalformedConfigEntryError,
273 task_config._check_testbed_parameter,
274 task_info)
275
276 def testInvalidBoardFamilies(self):
277 """Ensure to raise exception when a board family is invalid."""
278 self.config.set(self._TASK_NAME, 'board_families', 'fake_one')
279 task_config = task_config_reader.TaskConfig(self.config)
280 self.assertRaises(task_config_reader.MalformedConfigEntryError,
281 task_config._read_task_section,
282 self._TASK_NAME)
283
284 def testInvalidExcludeBoardFamilies(self):
285 """Ensure to raise exception when an exclude board family is invalid."""
286 self.config.set(self._TASK_NAME, 'exclude_board_families', 'fake_one')
287 task_config = task_config_reader.TaskConfig(self.config)
288 self.assertRaises(task_config_reader.MalformedConfigEntryError,
289 task_config._read_task_section,
290 self._TASK_NAME)