blob: a79306dfc6082bf1ff7951cd1c5bcea20273ea39 [file] [log] [blame]
Xixuan Wuabbaa4c2017-08-23 17:31:49 -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 config reader unittests."""
6
7import unittest
8
9import config_reader
10import constants
11import mock
Xixuan Wu7e30c9d2017-09-05 18:46:00 -070012import tot_manager
13
14
15class FakeTotMilestoneManager(tot_manager.TotMilestoneManager):
16
17 def __init__(self, is_sanity):
18 self.is_sanity = is_sanity
19 self.storage_client = None
20 self.tot = self._tot_milestone()
Xixuan Wuabbaa4c2017-08-23 17:31:49 -070021
22
23class BaseTaskConfigReaderTestCase(unittest.TestCase):
24
25 _EVENT_TYPE = 'nightly'
26 _PRIORITY = config_reader.EVENT_CLASSES[_EVENT_TYPE].PRIORITY
27 _TIMEOUT = config_reader.EVENT_CLASSES[_EVENT_TYPE].TIMEOUT
28 _TASK_NAME = 'fake_task'
29 _SUITE = 'fake_suite'
30 _BRANCH_SPEC = 'tot-1'
31 _POOL = 'bvt'
32 _NUM = 2
33 _BOARD = 'link'
34
35 def setUp(self):
36 self.config = config_reader.ConfigReader(None)
37 self.config.add_section(self._TASK_NAME)
38 self.config.set(self._TASK_NAME, 'suite', self._SUITE)
39 self.config.set(self._TASK_NAME, 'branch_specs', self._BRANCH_SPEC)
40 self.config.set(self._TASK_NAME, 'run_on', self._EVENT_TYPE)
41 self.config.set(self._TASK_NAME, 'pool', self._POOL)
42 self.config.set(self._TASK_NAME, 'num', '%d' % self._NUM)
43 self.config.set(self._TASK_NAME, 'boards', self._BOARD)
44
45 tot_patcher = mock.patch('tot_manager.TotMilestoneManager')
46 self._tot = tot_patcher.start()
Xixuan Wu7e30c9d2017-09-05 18:46:00 -070047 self._tot.return_value = FakeTotMilestoneManager(True)
Xixuan Wu244e0ec2018-05-23 14:49:55 -070048
49 board_family_patcher = mock.patch(
50 'build_lib.get_board_family_mapping_from_gs')
51 board_family_getter = board_family_patcher.start()
52 board_family_getter.return_value = {
53 'nyan': ['nyan', 'nyan_blaze', 'nyan_big'],
54 'ivybridge': ['link', 'link_freon']}
55
Xixuan Wuabbaa4c2017-08-23 17:31:49 -070056 self.addCleanup(tot_patcher.stop)
Xixuan Wu244e0ec2018-05-23 14:49:55 -070057 self.addCleanup(board_family_patcher.stop)
Xixuan Wuabbaa4c2017-08-23 17:31:49 -070058
59
60class TaskCreationTestCase(BaseTaskConfigReaderTestCase):
61
62 def testCreateTaskFromConfigNonexistentSection(self):
63 """Ensure a Task CANNOT be built without suite, and raise error."""
64 task_config = config_reader.TaskConfig(self.config)
65 self.assertRaises(config_reader.MalformedConfigEntryError,
66 task_config._create_task_from_config_section,
67 'non-existent section')
68
69 def testCreateTaskFromConfigNotAllowedHeader(self):
70 """Ensure a Task CANNOT be built without suite, and raise error."""
71 self.config.set(self._TASK_NAME, 'non-valid-header', 'test')
72 task_config = config_reader.TaskConfig(self.config)
73 self.assertRaises(config_reader.MalformedConfigEntryError,
74 task_config._create_task_from_config_section,
75 self._TASK_NAME)
76
77 def testGetTaskByKeyword(self):
78 """Ensure a Task can be built from a correct config."""
79 task_config = config_reader.TaskConfig(self.config)
Xixuan Wu4ac56dd2017-10-12 11:59:30 -070080 tasks = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
Xixuan Wuabbaa4c2017-08-23 17:31:49 -070081 self.assertEqual(len(tasks), 1)
82 new_task = tasks[0]
83 self.assertEqual(new_task.name, self._TASK_NAME)
84 self.assertEqual(new_task.suite, self._SUITE)
85 self.assertEqual(new_task.branch_specs, [self._BRANCH_SPEC])
86 self.assertEqual(new_task.pool, self._POOL)
87 self.assertEqual(new_task.num, self._NUM)
Xixuan Wu0c76d5b2017-08-30 16:40:17 -070088 self.assertEqual(new_task.boards,
89 [t.lstrip() for t in self._BOARD.split(',')])
Xixuan Wuabbaa4c2017-08-23 17:31:49 -070090 self.assertEqual(new_task.priority, self._PRIORITY)
91 self.assertEqual(new_task.timeout, self._TIMEOUT)
92
Xixuan Wuabbaa4c2017-08-23 17:31:49 -070093 def testGetTaskByKeywordNoRunonNoRaise(self):
94 """Ensure a Task CANNOT be built without run_on, but not raise error."""
95 self.config.remove_option(self._TASK_NAME, 'run_on')
96 task_config = config_reader.TaskConfig(self.config)
97 try:
Xixuan Wu4ac56dd2017-10-12 11:59:30 -070098 response = task_config.get_tasks_by_keyword(self._EVENT_TYPE)
99 self.assertEqual(len(response['tasks']), 0)
100 self.assertEqual(len(response['exceptions']), 1)
Xixuan Wuabbaa4c2017-08-23 17:31:49 -0700101 except config_reader.MalformedConfigEntryError:
102 self.fail('task_config should not raise error without run_on!')
103
104 def testGetTaskByKeywordNoSuiteNoRaise(self):
105 """Ensure a Task CANNOT be built without suite, but not raise error.
106
107 This is to ensure a malformed task won't affect other tasks' reading.
108 """
109 self.config.remove_option(self._TASK_NAME, 'suite')
110 task_config = config_reader.TaskConfig(self.config)
111 try:
Xixuan Wu4ac56dd2017-10-12 11:59:30 -0700112 response = task_config.get_tasks_by_keyword(self._EVENT_TYPE)
113 self.assertEqual(len(response['tasks']), 0)
114 self.assertEqual(len(response['exceptions']), 1)
Xixuan Wuabbaa4c2017-08-23 17:31:49 -0700115 except config_reader.MalformedConfigEntry:
116 self.fail('task_config should not raise error without suite!')
117
118 def testGetTaskByKeywordNoBranch(self):
119 """Ensure a Task can be built without branch_specs."""
120 self.config.remove_option(self._TASK_NAME, 'branch_specs')
121 task_config = config_reader.TaskConfig(self.config)
Xixuan Wu4ac56dd2017-10-12 11:59:30 -0700122 tasks = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
Xixuan Wuabbaa4c2017-08-23 17:31:49 -0700123 self.assertEqual(tasks[0].branch_specs, [])
124
125 def testGetTaskByKeywordNoNum(self):
126 """Ensure a Task can be built without num."""
127 self.config.remove_option(self._TASK_NAME, 'num')
128 task_config = config_reader.TaskConfig(self.config)
Xixuan Wu4ac56dd2017-10-12 11:59:30 -0700129 tasks = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
Xixuan Wuabbaa4c2017-08-23 17:31:49 -0700130 self.assertIsNone(tasks[0].num)
131
132 def testSetPriority(self):
133 """Ensure priority can be set by user."""
134 priority = constants.Priorities.DEFAULT
135 self.config.set(self._TASK_NAME, 'priority', str(priority))
136 task_config = config_reader.TaskConfig(self.config)
Xixuan Wu4ac56dd2017-10-12 11:59:30 -0700137 tasks = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
Xixuan Wuabbaa4c2017-08-23 17:31:49 -0700138 self.assertEqual(tasks[0].priority, priority)
139
140 def testSetTimeout(self):
141 """Ensure timeout can be set by user."""
142 timeout = 1000
143 self.config.set(self._TASK_NAME, 'timeout', str(timeout))
144 task_config = config_reader.TaskConfig(self.config)
Xixuan Wu4ac56dd2017-10-12 11:59:30 -0700145 tasks = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
Xixuan Wuabbaa4c2017-08-23 17:31:49 -0700146 self.assertEqual(tasks[0].timeout, timeout)
147
148
149class TaskInfoCheckTestCase(BaseTaskConfigReaderTestCase):
150
151 def testNonIntNum(self):
152 """Ensure a Task's num is a Integer."""
153 self.config.set(self._TASK_NAME, 'num', 'non_int')
154 task_config = config_reader.TaskConfig(self.config)
155 self.assertRaises(config_reader.MalformedConfigEntryError,
156 task_config._read_task_section,
157 self._TASK_NAME)
158
159 def testNonIntHour(self):
160 """Ensure a Task's hour is a Integer."""
161 self.config.set(self._TASK_NAME, 'hour', 'non_int')
162 task_config = config_reader.TaskConfig(self.config)
163 self.assertRaises(config_reader.MalformedConfigEntryError,
164 task_config._read_task_section,
165 self._TASK_NAME)
166
167 def testNonIntDay(self):
168 """Ensure a Task's hour is a Integer."""
169 self.config.set(self._TASK_NAME, 'day', 'non_int')
170 task_config = config_reader.TaskConfig(self.config)
171 self.assertRaises(config_reader.MalformedConfigEntryError,
172 task_config._read_task_section,
173 self._TASK_NAME)
174
175 def testNoSuite(self):
176 """Ensure a Task's suite exists."""
177 self.config.remove_option(self._TASK_NAME, 'suite')
178 task_config = config_reader.TaskConfig(self.config)
179 task_info = task_config._read_task_section(self._TASK_NAME)
180 self.assertRaises(config_reader.MalformedConfigEntryError,
181 task_config._validate_task_section,
182 task_info)
183
184 def testInvalidIntHour(self):
185 """Ensure a Task's hour is in 0~23."""
186 self.config.set(self._TASK_NAME, 'hour', '24')
187 task_config = config_reader.TaskConfig(self.config)
188 task_info = task_config._read_task_section(self._TASK_NAME)
189 self.assertRaises(config_reader.MalformedConfigEntryError,
190 task_config._validate_task_section,
191 task_info)
192
193 def testNoHourForNonNightlyEvent(self):
194 """Ensure a non-nightly Task cannot specify hour."""
195 self.config.set(self._TASK_NAME, 'hour', '10')
196 self.config.set(self._TASK_NAME, 'run_on', 'new_build')
197 task_config = config_reader.TaskConfig(self.config)
198 task_info = task_config._read_task_section(self._TASK_NAME)
199 self.assertRaises(config_reader.MalformedConfigEntryError,
200 task_config._validate_task_section,
201 task_info)
202
203 def testInvalidIntDay(self):
204 """Ensure a Task's day is in 0~6."""
205 self.config.set(self._TASK_NAME, 'day', '10')
206 self.config.set(self._TASK_NAME, 'run_on', 'weekly')
207 task_config = config_reader.TaskConfig(self.config)
208 task_info = task_config._read_task_section(self._TASK_NAME)
209 self.assertRaises(config_reader.MalformedConfigEntryError,
210 task_config._validate_task_section,
211 task_info)
212
213 def testNoDayForNonWeeklyEvent(self):
214 """Ensure a non-weekly Task cannot specify day."""
215 self.config.set(self._TASK_NAME, 'day', '1')
216 self.config.set(self._TASK_NAME, 'run_on', 'nightly')
217 task_config = config_reader.TaskConfig(self.config)
218 task_info = task_config._read_task_section(self._TASK_NAME)
219 self.assertRaises(config_reader.MalformedConfigEntryError,
220 task_config._validate_task_section,
221 task_info)
222
223 def testInValidOSType(self):
224 """Ensure a Task's os_type is valid."""
225 self.config.set(self._TASK_NAME, 'os_type', 'invalid')
226 task_config = config_reader.TaskConfig(self.config)
227 task_info = task_config._read_task_section(self._TASK_NAME)
228 self.assertRaises(config_reader.MalformedConfigEntryError,
229 task_config._check_os_type,
230 task_info)
231
232 def testNoLaunchControlForCrOS(self):
233 """Ensure a CrOS Task doesn't have launch control settings."""
234 self.config.set(self._TASK_NAME, 'os_type', 'CrOS')
235 self.config.set(self._TASK_NAME, 'branches', 'shamu-userdebug')
236 task_config = config_reader.TaskConfig(self.config)
237 task_info = task_config._read_task_section(self._TASK_NAME)
238 self.assertRaises(config_reader.MalformedConfigEntryError,
239 task_config._check_os_type,
240 task_info)
241
242 def testLaunchControlForNonCrOS(self):
243 """Ensure an android Task has launch control settings."""
244 self.config.set(self._TASK_NAME, 'os_type', 'android')
245 task_config = config_reader.TaskConfig(self.config)
246 task_info = task_config._read_task_section(self._TASK_NAME)
247 self.assertRaises(config_reader.MalformedConfigEntryError,
248 task_config._check_os_type,
249 task_info)
250
251 def testGetTestbedCount(self):
252 """Ensure testbed count can be successfully parsed."""
253 task_config = config_reader.TaskConfig(self.config)
254 self.assertEqual(task_config._get_testbed_dut_count('sharu-2'), 2)
255
256 def testNoTestbedForCrOS(self):
257 """Ensure CrOS task won't specify testbed parameters."""
258 self.config.set(self._TASK_NAME, 'boards', 'sharu-2')
259 task_config = config_reader.TaskConfig(self.config)
260 task_info = task_config._read_task_section(self._TASK_NAME)
261 self.assertRaises(config_reader.MalformedConfigEntryError,
262 task_config._check_testbed_parameter,
263 task_info)
264
Po-Hsien Wangdd833072018-08-16 18:09:20 -0700265 def testInvalidBoardFamilies(self):
Xixuan Wu244e0ec2018-05-23 14:49:55 -0700266 """Ensure to raise exception when a board family is invalid."""
Po-Hsien Wangdd833072018-08-16 18:09:20 -0700267 self.config.set(self._TASK_NAME, 'board_families', 'fake_one')
268 task_config = config_reader.TaskConfig(self.config)
269 self.assertRaises(config_reader.MalformedConfigEntryError,
270 task_config._read_task_section,
271 self._TASK_NAME)
272
273 def testInvalidExcludeBoardFamilies(self):
274 """Ensure to raise exception when an exclude board family is invalid."""
275 self.config.set(self._TASK_NAME, 'exclude_board_families', 'fake_one')
Xixuan Wu244e0ec2018-05-23 14:49:55 -0700276 task_config = config_reader.TaskConfig(self.config)
277 self.assertRaises(config_reader.MalformedConfigEntryError,
278 task_config._read_task_section,
279 self._TASK_NAME)
280
Xixuan Wuabbaa4c2017-08-23 17:31:49 -0700281
282class LabReaderTestCase(unittest.TestCase):
283
284 def setUp(self):
285 self.config = config_reader.ConfigReader(None)
Xixuan Wu26d06e02017-09-20 14:50:28 -0700286 self.config.add_section(config_reader.ANDROID_SETTINGS)
Xixuan Wu6fb16272017-10-19 13:16:00 -0700287 self.config.add_section(config_reader.CROS_SETTINGS)
Xixuan Wuabbaa4c2017-08-23 17:31:49 -0700288 self.config.add_section(config_reader.RELEASED_RO_BUILDS)
289
290 def testGetAndroidBoardList(self):
291 """Ensure android board list can be correctly fetched."""
Xixuan Wu26d06e02017-09-20 14:50:28 -0700292 self.config.set(config_reader.ANDROID_SETTINGS, 'board_list',
293 '\nabox_edge,\nandroid-angler-1,\nangler-6')
Xixuan Wuabbaa4c2017-08-23 17:31:49 -0700294 lab_config = config_reader.LabConfig(self.config)
295 self.assertEqual(lab_config.get_android_board_list(),
296 set(['abox_edge', 'android-angler', 'angler']))
297
298 def testGetInvalidAndroidBoardListEntry(self):
299 """Ensure ValueError is raised if no valid board list entry."""
Xixuan Wu26d06e02017-09-20 14:50:28 -0700300 self.config.set(config_reader.ANDROID_SETTINGS, 'invalid_board_list',
301 '\nabox_edge,\nandroid-angler-1,\nangler-6')
Xixuan Wuabbaa4c2017-08-23 17:31:49 -0700302 lab_config = config_reader.LabConfig(self.config)
303 self.assertRaises(ValueError, lab_config.get_android_board_list)
304
305 def testGetEmptyAndroidBoardListEntry(self):
306 """Ensure ValueError is raised if no android board list is found."""
307 lab_config = config_reader.LabConfig(self.config)
308 self.assertRaises(ValueError, lab_config.get_android_board_list)
309
Xixuan Wu6fb16272017-10-19 13:16:00 -0700310 def testGetCrOSBoardList(self):
311 """Ensure android board list can be correctly fetched."""
312 self.config.set(config_reader.CROS_SETTINGS, 'board_list',
313 '\nlink,\nandroid-angler-1,\nangler-6')
314 self.config.set(config_reader.ANDROID_SETTINGS, 'board_list',
315 '\nandroid-angler-1,\nangler-6')
316 lab_config = config_reader.LabConfig(self.config)
317 self.assertEqual(lab_config.get_cros_board_list(),
318 set(['link']))
319
Xixuan Wuabbaa4c2017-08-23 17:31:49 -0700320 def testGetFirmwareROBuildList(self):
321 """Ensure firmware ro build can be successfully found."""
322 self.config.set(config_reader.RELEASED_RO_BUILDS, 'link', 'firmware')
323 lab_config = config_reader.LabConfig(self.config)
324 self.assertEqual(lab_config.get_firmware_ro_build_list('link'),
325 'firmware')
326
327 def testGetEmptyFirmwareROBuildList(self):
328 """Ensure ValueError is raised if no firmware ro build is found."""
329 lab_config = config_reader.LabConfig(self.config)
330 self.assertRaises(ValueError,
331 lab_config.get_firmware_ro_build_list, 'link')
332
C Shapiro7f24a002017-12-05 14:25:09 -0700333 def testGetCrOSModelMap(self):
334 """Ensure cros_model_map can be correctly fetched."""
335 self.config.set(config_reader.CROS_SETTINGS, 'model_list',
336 '\ncoral_astronaut,\ncoral_robo360')
337 lab_config = config_reader.LabConfig(self.config)
338 result = lab_config.get_cros_model_map()
339 self.assertEqual(len(result), 1)
340 self.assertEqual(result['coral'], ['astronaut', 'robo360'])
341
Xixuan Wubb74a372018-08-21 17:37:08 -0700342 def testGetSkylabBoardList(self):
343 """Ensure skylab_board_list can be correctly fetched."""
344 self.config.set(config_reader.CROS_SETTINGS, 'skylab_board_list',
345 '\nnyan_blaze,\nreef')
346 lab_config = config_reader.LabConfig(self.config)
347 result = lab_config.get_skylab_board_list()
348 self.assertEqual(len(result), 2)
349 self.assertIn('nyan_blaze', result)
350 self.assertIn('reef', result)
351
C Shapiro7f24a002017-12-05 14:25:09 -0700352 def testGetEmptyCrOSModelMap(self):
353 """Ensure cros_model_map can be correctly fetched."""
354 lab_config = config_reader.LabConfig(self.config)
355 self.assertEqual(lab_config.get_cros_model_map(), {})
356
Xixuan Wuabbaa4c2017-08-23 17:31:49 -0700357
358if __name__ == '__main__':
359 unittest.main()