blob: c48dfacd86eeeb4f05091391fa7c6aeda929ee8c [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):
74 """Ensure a Task CANNOT be built without suite, and raise error."""
75 self.config.set(self._TASK_NAME, 'non-valid-header', 'test')
76 task_config = task_config_reader.TaskConfig(self.config)
77 self.assertRaises(task_config_reader.MalformedConfigEntryError,
78 task_config._create_task_from_config_section,
79 self._TASK_NAME)
80
81 def testGetTaskByKeyword(self):
82 """Ensure a Task can be built from a correct config."""
83 task_config = task_config_reader.TaskConfig(self.config)
84 tasks = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
85 self.assertEqual(len(tasks), 1)
86 new_task = tasks[0]
87 self.assertEqual(new_task.name, self._TASK_NAME)
88 self.assertEqual(new_task.suite, self._SUITE)
89 self.assertEqual(new_task.branch_specs, [self._BRANCH_SPEC])
90 self.assertEqual(new_task.pool, self._POOL)
91 self.assertEqual(new_task.num, self._NUM)
92 self.assertEqual(new_task.boards,
93 [t.lstrip() for t in self._BOARD.split(',')])
94 self.assertEqual(new_task.priority, self._PRIORITY)
95 self.assertEqual(new_task.timeout, self._TIMEOUT)
Xinan Linc8647112020-02-04 16:45:56 -080096 self.assertEqual(new_task.dimensions, self._DIMENSIONS)
Xixuan Wu51bb7102019-03-18 14:51:44 -070097
98 def testGetTaskByKeywordNoRunonNoRaise(self):
99 """Ensure a Task CANNOT be built without run_on, but not raise error."""
100 self.config.remove_option(self._TASK_NAME, 'run_on')
101 task_config = task_config_reader.TaskConfig(self.config)
102 try:
103 response = task_config.get_tasks_by_keyword(self._EVENT_TYPE)
104 self.assertEqual(len(response['tasks']), 0)
105 self.assertEqual(len(response['exceptions']), 1)
106 except task_config_reader.MalformedConfigEntryError:
107 self.fail('task_config should not raise error without run_on!')
108
109 def testGetTaskByKeywordNoSuiteNoRaise(self):
110 """Ensure a Task CANNOT be built without suite, but not raise error.
111
112 This is to ensure a malformed task won't affect other tasks' reading.
113 """
114 self.config.remove_option(self._TASK_NAME, 'suite')
115 task_config = task_config_reader.TaskConfig(self.config)
116 try:
117 response = task_config.get_tasks_by_keyword(self._EVENT_TYPE)
118 self.assertEqual(len(response['tasks']), 0)
119 self.assertEqual(len(response['exceptions']), 1)
120 except config_reader.MalformedConfigEntry:
121 self.fail('task_config should not raise error without suite!')
122
123 def testGetTaskByKeywordNoBranch(self):
124 """Ensure a Task can be built without branch_specs."""
125 self.config.remove_option(self._TASK_NAME, 'branch_specs')
126 task_config = task_config_reader.TaskConfig(self.config)
127 tasks = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
128 self.assertEqual(tasks[0].branch_specs, [])
129
130 def testGetTaskByKeywordNoNum(self):
131 """Ensure a Task can be built without num."""
132 self.config.remove_option(self._TASK_NAME, 'num')
133 task_config = task_config_reader.TaskConfig(self.config)
134 tasks = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
135 self.assertIsNone(tasks[0].num)
136
137 def testSetPriority(self):
138 """Ensure priority can be set by user."""
139 priority = constants.Priorities.DEFAULT
140 self.config.set(self._TASK_NAME, 'priority', str(priority))
141 task_config = task_config_reader.TaskConfig(self.config)
142 tasks = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
143 self.assertEqual(tasks[0].priority, priority)
144
Xinan Lin292f38c2020-04-16 14:09:50 -0700145 def testSuitePoolShouldNotSetPriority(self):
146 """Ensure priority is not set for pool suites."""
147 self.config.set(self._TASK_NAME, 'pool', 'suites')
148 task_config = task_config_reader.TaskConfig(self.config)
149 tasks = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
150 self.assertIsNone(tasks[0].priority)
151
Xixuan Wu51bb7102019-03-18 14:51:44 -0700152 def testSetTimeout(self):
153 """Ensure timeout can be set by user."""
154 timeout = 1000
155 self.config.set(self._TASK_NAME, 'timeout', str(timeout))
156 task_config = task_config_reader.TaskConfig(self.config)
157 tasks = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
158 self.assertEqual(tasks[0].timeout, timeout)
159
160
161class TaskInfoCheckTestCase(BaseTaskConfigReaderTestCase):
162
163 def testNonIntNum(self):
164 """Ensure a Task's num is a Integer."""
165 self.config.set(self._TASK_NAME, 'num', 'non_int')
166 task_config = task_config_reader.TaskConfig(self.config)
167 self.assertRaises(task_config_reader.MalformedConfigEntryError,
168 task_config._read_task_section,
169 self._TASK_NAME)
170
171 def testNonIntHour(self):
172 """Ensure a Task's hour is a Integer."""
173 self.config.set(self._TASK_NAME, 'hour', 'non_int')
174 task_config = task_config_reader.TaskConfig(self.config)
175 self.assertRaises(task_config_reader.MalformedConfigEntryError,
176 task_config._read_task_section,
177 self._TASK_NAME)
178
179 def testNonIntDay(self):
180 """Ensure a Task's hour is a Integer."""
181 self.config.set(self._TASK_NAME, 'day', 'non_int')
182 task_config = task_config_reader.TaskConfig(self.config)
183 self.assertRaises(task_config_reader.MalformedConfigEntryError,
184 task_config._read_task_section,
185 self._TASK_NAME)
186
187 def testNoSuite(self):
188 """Ensure a Task's suite exists."""
189 self.config.remove_option(self._TASK_NAME, 'suite')
190 task_config = task_config_reader.TaskConfig(self.config)
191 task_info = task_config._read_task_section(self._TASK_NAME)
192 self.assertRaises(task_config_reader.MalformedConfigEntryError,
193 task_config._validate_task_section,
194 task_info)
195
196 def testInvalidIntHour(self):
197 """Ensure a Task's hour is in 0~23."""
198 self.config.set(self._TASK_NAME, 'hour', '24')
199 task_config = task_config_reader.TaskConfig(self.config)
200 task_info = task_config._read_task_section(self._TASK_NAME)
201 self.assertRaises(task_config_reader.MalformedConfigEntryError,
202 task_config._validate_task_section,
203 task_info)
204
205 def testNoHourForNonNightlyEvent(self):
206 """Ensure a non-nightly Task cannot specify hour."""
207 self.config.set(self._TASK_NAME, 'hour', '10')
208 self.config.set(self._TASK_NAME, 'run_on', 'new_build')
209 task_config = task_config_reader.TaskConfig(self.config)
210 task_info = task_config._read_task_section(self._TASK_NAME)
211 self.assertRaises(task_config_reader.MalformedConfigEntryError,
212 task_config._validate_task_section,
213 task_info)
214
215 def testInvalidIntDay(self):
216 """Ensure a Task's day is in 0~6."""
217 self.config.set(self._TASK_NAME, 'day', '10')
218 self.config.set(self._TASK_NAME, 'run_on', 'weekly')
219 task_config = task_config_reader.TaskConfig(self.config)
220 task_info = task_config._read_task_section(self._TASK_NAME)
221 self.assertRaises(task_config_reader.MalformedConfigEntryError,
222 task_config._validate_task_section,
223 task_info)
224
225 def testNoDayForNonWeeklyEvent(self):
226 """Ensure a non-weekly Task cannot specify day."""
227 self.config.set(self._TASK_NAME, 'day', '1')
228 self.config.set(self._TASK_NAME, 'run_on', 'nightly')
229 task_config = task_config_reader.TaskConfig(self.config)
230 task_info = task_config._read_task_section(self._TASK_NAME)
231 self.assertRaises(task_config_reader.MalformedConfigEntryError,
232 task_config._validate_task_section,
233 task_info)
234
235 def testInValidOSType(self):
236 """Ensure a Task's os_type is valid."""
237 self.config.set(self._TASK_NAME, 'os_type', 'invalid')
238 task_config = task_config_reader.TaskConfig(self.config)
239 task_info = task_config._read_task_section(self._TASK_NAME)
240 self.assertRaises(task_config_reader.MalformedConfigEntryError,
241 task_config._check_os_type,
242 task_info)
243
244 def testNoLaunchControlForCrOS(self):
245 """Ensure a CrOS Task doesn't have launch control settings."""
246 self.config.set(self._TASK_NAME, 'os_type', 'CrOS')
247 self.config.set(self._TASK_NAME, 'branches', 'shamu-userdebug')
248 task_config = task_config_reader.TaskConfig(self.config)
249 task_info = task_config._read_task_section(self._TASK_NAME)
250 self.assertRaises(task_config_reader.MalformedConfigEntryError,
251 task_config._check_os_type,
252 task_info)
253
254 def testLaunchControlForNonCrOS(self):
255 """Ensure an android Task has launch control settings."""
256 self.config.set(self._TASK_NAME, 'os_type', 'android')
257 task_config = task_config_reader.TaskConfig(self.config)
258 task_info = task_config._read_task_section(self._TASK_NAME)
259 self.assertRaises(task_config_reader.MalformedConfigEntryError,
260 task_config._check_os_type,
261 task_info)
262
263 def testGetTestbedCount(self):
264 """Ensure testbed count can be successfully parsed."""
265 task_config = task_config_reader.TaskConfig(self.config)
266 self.assertEqual(task_config._get_testbed_dut_count('sharu-2'), 2)
267
268 def testNoTestbedForCrOS(self):
269 """Ensure CrOS task won't specify testbed parameters."""
270 self.config.set(self._TASK_NAME, 'boards', 'sharu-2')
271 task_config = task_config_reader.TaskConfig(self.config)
272 task_info = task_config._read_task_section(self._TASK_NAME)
273 self.assertRaises(task_config_reader.MalformedConfigEntryError,
274 task_config._check_testbed_parameter,
275 task_info)
276
277 def testInvalidBoardFamilies(self):
278 """Ensure to raise exception when a board family is invalid."""
279 self.config.set(self._TASK_NAME, 'board_families', 'fake_one')
280 task_config = task_config_reader.TaskConfig(self.config)
281 self.assertRaises(task_config_reader.MalformedConfigEntryError,
282 task_config._read_task_section,
283 self._TASK_NAME)
284
285 def testInvalidExcludeBoardFamilies(self):
286 """Ensure to raise exception when an exclude board family is invalid."""
287 self.config.set(self._TASK_NAME, 'exclude_board_families', 'fake_one')
288 task_config = task_config_reader.TaskConfig(self.config)
289 self.assertRaises(task_config_reader.MalformedConfigEntryError,
290 task_config._read_task_section,
291 self._TASK_NAME)