blob: 4b83d2e5dfd92f2d6a4b7eb2d195676fc761be16 [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'
36
37 def setUp(self):
38 self.config = config_reader.ConfigReader(None)
39 self.config.add_section(self._TASK_NAME)
40 self.config.set(self._TASK_NAME, 'suite', self._SUITE)
41 self.config.set(self._TASK_NAME, 'branch_specs', self._BRANCH_SPEC)
42 self.config.set(self._TASK_NAME, 'run_on', self._EVENT_TYPE)
43 self.config.set(self._TASK_NAME, 'pool', self._POOL)
44 self.config.set(self._TASK_NAME, 'num', '%d' % self._NUM)
45 self.config.set(self._TASK_NAME, 'boards', self._BOARD)
46
47 tot_patcher = mock.patch('tot_manager.TotMilestoneManager')
48 self._tot = tot_patcher.start()
49 self._tot.return_value = FakeTotMilestoneManager(True)
50
51 board_family_patcher = mock.patch(
52 'build_lib.get_board_family_mapping_from_gs')
53 board_family_getter = board_family_patcher.start()
54 board_family_getter.return_value = {
55 'nyan': ['nyan', 'nyan_blaze', 'nyan_big'],
56 'ivybridge': ['link', 'link_freon']}
57
58 self.addCleanup(tot_patcher.stop)
59 self.addCleanup(board_family_patcher.stop)
60
61
62class TaskCreationTestCase(BaseTaskConfigReaderTestCase):
63
64 def testCreateTaskFromConfigNonexistentSection(self):
65 """Ensure a Task CANNOT be built without suite, and raise error."""
66 task_config = task_config_reader.TaskConfig(self.config)
67 self.assertRaises(task_config_reader.MalformedConfigEntryError,
68 task_config._create_task_from_config_section,
69 'non-existent section')
70
71 def testCreateTaskFromConfigNotAllowedHeader(self):
72 """Ensure a Task CANNOT be built without suite, and raise error."""
73 self.config.set(self._TASK_NAME, 'non-valid-header', 'test')
74 task_config = task_config_reader.TaskConfig(self.config)
75 self.assertRaises(task_config_reader.MalformedConfigEntryError,
76 task_config._create_task_from_config_section,
77 self._TASK_NAME)
78
79 def testGetTaskByKeyword(self):
80 """Ensure a Task can be built from a correct config."""
81 task_config = task_config_reader.TaskConfig(self.config)
82 tasks = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
83 self.assertEqual(len(tasks), 1)
84 new_task = tasks[0]
85 self.assertEqual(new_task.name, self._TASK_NAME)
86 self.assertEqual(new_task.suite, self._SUITE)
87 self.assertEqual(new_task.branch_specs, [self._BRANCH_SPEC])
88 self.assertEqual(new_task.pool, self._POOL)
89 self.assertEqual(new_task.num, self._NUM)
90 self.assertEqual(new_task.boards,
91 [t.lstrip() for t in self._BOARD.split(',')])
92 self.assertEqual(new_task.priority, self._PRIORITY)
93 self.assertEqual(new_task.timeout, self._TIMEOUT)
94
95 def testGetTaskByKeywordNoRunonNoRaise(self):
96 """Ensure a Task CANNOT be built without run_on, but not raise error."""
97 self.config.remove_option(self._TASK_NAME, 'run_on')
98 task_config = task_config_reader.TaskConfig(self.config)
99 try:
100 response = task_config.get_tasks_by_keyword(self._EVENT_TYPE)
101 self.assertEqual(len(response['tasks']), 0)
102 self.assertEqual(len(response['exceptions']), 1)
103 except task_config_reader.MalformedConfigEntryError:
104 self.fail('task_config should not raise error without run_on!')
105
106 def testGetTaskByKeywordNoSuiteNoRaise(self):
107 """Ensure a Task CANNOT be built without suite, but not raise error.
108
109 This is to ensure a malformed task won't affect other tasks' reading.
110 """
111 self.config.remove_option(self._TASK_NAME, 'suite')
112 task_config = task_config_reader.TaskConfig(self.config)
113 try:
114 response = task_config.get_tasks_by_keyword(self._EVENT_TYPE)
115 self.assertEqual(len(response['tasks']), 0)
116 self.assertEqual(len(response['exceptions']), 1)
117 except config_reader.MalformedConfigEntry:
118 self.fail('task_config should not raise error without suite!')
119
120 def testGetTaskByKeywordNoBranch(self):
121 """Ensure a Task can be built without branch_specs."""
122 self.config.remove_option(self._TASK_NAME, 'branch_specs')
123 task_config = task_config_reader.TaskConfig(self.config)
124 tasks = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
125 self.assertEqual(tasks[0].branch_specs, [])
126
127 def testGetTaskByKeywordNoNum(self):
128 """Ensure a Task can be built without num."""
129 self.config.remove_option(self._TASK_NAME, 'num')
130 task_config = task_config_reader.TaskConfig(self.config)
131 tasks = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
132 self.assertIsNone(tasks[0].num)
133
134 def testSetPriority(self):
135 """Ensure priority can be set by user."""
136 priority = constants.Priorities.DEFAULT
137 self.config.set(self._TASK_NAME, 'priority', str(priority))
138 task_config = task_config_reader.TaskConfig(self.config)
139 tasks = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
140 self.assertEqual(tasks[0].priority, priority)
141
142 def testSetTimeout(self):
143 """Ensure timeout can be set by user."""
144 timeout = 1000
145 self.config.set(self._TASK_NAME, 'timeout', str(timeout))
146 task_config = task_config_reader.TaskConfig(self.config)
147 tasks = task_config.get_tasks_by_keyword(self._EVENT_TYPE)['tasks']
148 self.assertEqual(tasks[0].timeout, timeout)
149
150
151class TaskInfoCheckTestCase(BaseTaskConfigReaderTestCase):
152
153 def testNonIntNum(self):
154 """Ensure a Task's num is a Integer."""
155 self.config.set(self._TASK_NAME, 'num', 'non_int')
156 task_config = task_config_reader.TaskConfig(self.config)
157 self.assertRaises(task_config_reader.MalformedConfigEntryError,
158 task_config._read_task_section,
159 self._TASK_NAME)
160
161 def testNonIntHour(self):
162 """Ensure a Task's hour is a Integer."""
163 self.config.set(self._TASK_NAME, 'hour', 'non_int')
164 task_config = task_config_reader.TaskConfig(self.config)
165 self.assertRaises(task_config_reader.MalformedConfigEntryError,
166 task_config._read_task_section,
167 self._TASK_NAME)
168
169 def testNonIntDay(self):
170 """Ensure a Task's hour is a Integer."""
171 self.config.set(self._TASK_NAME, 'day', 'non_int')
172 task_config = task_config_reader.TaskConfig(self.config)
173 self.assertRaises(task_config_reader.MalformedConfigEntryError,
174 task_config._read_task_section,
175 self._TASK_NAME)
176
177 def testNoSuite(self):
178 """Ensure a Task's suite exists."""
179 self.config.remove_option(self._TASK_NAME, 'suite')
180 task_config = task_config_reader.TaskConfig(self.config)
181 task_info = task_config._read_task_section(self._TASK_NAME)
182 self.assertRaises(task_config_reader.MalformedConfigEntryError,
183 task_config._validate_task_section,
184 task_info)
185
186 def testInvalidIntHour(self):
187 """Ensure a Task's hour is in 0~23."""
188 self.config.set(self._TASK_NAME, 'hour', '24')
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 testNoHourForNonNightlyEvent(self):
196 """Ensure a non-nightly Task cannot specify hour."""
197 self.config.set(self._TASK_NAME, 'hour', '10')
198 self.config.set(self._TASK_NAME, 'run_on', 'new_build')
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 testInvalidIntDay(self):
206 """Ensure a Task's day is in 0~6."""
207 self.config.set(self._TASK_NAME, 'day', '10')
208 self.config.set(self._TASK_NAME, 'run_on', 'weekly')
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 testNoDayForNonWeeklyEvent(self):
216 """Ensure a non-weekly Task cannot specify day."""
217 self.config.set(self._TASK_NAME, 'day', '1')
218 self.config.set(self._TASK_NAME, 'run_on', 'nightly')
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 testInValidOSType(self):
226 """Ensure a Task's os_type is valid."""
227 self.config.set(self._TASK_NAME, 'os_type', 'invalid')
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._check_os_type,
232 task_info)
233
234 def testNoLaunchControlForCrOS(self):
235 """Ensure a CrOS Task doesn't have launch control settings."""
236 self.config.set(self._TASK_NAME, 'os_type', 'CrOS')
237 self.config.set(self._TASK_NAME, 'branches', 'shamu-userdebug')
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 testLaunchControlForNonCrOS(self):
245 """Ensure an android Task has launch control settings."""
246 self.config.set(self._TASK_NAME, 'os_type', 'android')
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 testGetTestbedCount(self):
254 """Ensure testbed count can be successfully parsed."""
255 task_config = task_config_reader.TaskConfig(self.config)
256 self.assertEqual(task_config._get_testbed_dut_count('sharu-2'), 2)
257
258 def testNoTestbedForCrOS(self):
259 """Ensure CrOS task won't specify testbed parameters."""
260 self.config.set(self._TASK_NAME, 'boards', 'sharu-2')
261 task_config = task_config_reader.TaskConfig(self.config)
262 task_info = task_config._read_task_section(self._TASK_NAME)
263 self.assertRaises(task_config_reader.MalformedConfigEntryError,
264 task_config._check_testbed_parameter,
265 task_info)
266
267 def testInvalidBoardFamilies(self):
268 """Ensure to raise exception when a board family is invalid."""
269 self.config.set(self._TASK_NAME, 'board_families', 'fake_one')
270 task_config = task_config_reader.TaskConfig(self.config)
271 self.assertRaises(task_config_reader.MalformedConfigEntryError,
272 task_config._read_task_section,
273 self._TASK_NAME)
274
275 def testInvalidExcludeBoardFamilies(self):
276 """Ensure to raise exception when an exclude board family is invalid."""
277 self.config.set(self._TASK_NAME, 'exclude_board_families', 'fake_one')
278 task_config = task_config_reader.TaskConfig(self.config)
279 self.assertRaises(task_config_reader.MalformedConfigEntryError,
280 task_config._read_task_section,
281 self._TASK_NAME)