1#!/usr/bin/python 2# 3# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7"""Unit tests for site_utils/board_enumerator.py.""" 8 9import mox, unittest 10 11# driver must be imported first due to circular imports in base_event and task 12import driver # pylint: disable-msg=W0611 13import base_event, board_enumerator, build_event, deduping_scheduler 14import forgiving_config_parser, manifest_versions, task, timed_event 15 16import common 17from autotest_lib.server import frontend 18from constants import Labels 19 20 21class DriverTest(mox.MoxTestBase): 22 """Unit tests for Driver.""" 23 24 _BOARDS = ['board1', 'board2'] 25 26 27 def setUp(self): 28 super(DriverTest, self).setUp() 29 self.afe = self.mox.CreateMock(frontend.AFE) 30 self.be = board_enumerator.BoardEnumerator(self.afe) 31 self.ds = deduping_scheduler.DedupingScheduler(self.afe) 32 self.mv = self.mox.CreateMock(manifest_versions.ManifestVersions) 33 34 self.config = forgiving_config_parser.ForgivingConfigParser() 35 36 self.nightly_bvt = task.Task(timed_event.Nightly.KEYWORD, '', '') 37 self.weekly_bvt = task.Task(timed_event.Weekly.KEYWORD, '', '') 38 self.new_build_bvt = task.Task(build_event.NewBuild.KEYWORD, '', '') 39 40 self.driver = driver.Driver(self.ds, self.be) 41 driver.Driver._cros_boards.clear() 42 43 44 def _CreateMockEvent(self, klass): 45 event = self.mox.CreateMock(klass) 46 event.keyword = klass.KEYWORD 47 event.tasks = [] 48 return event 49 50 51 def _ExpectSetup(self): 52 mock_nightly = self._CreateMockEvent(timed_event.Nightly) 53 mock_weekly = self._CreateMockEvent(timed_event.Weekly) 54 mock_new_build = self._CreateMockEvent(build_event.NewBuild) 55 56 self.mox.StubOutWithMock(timed_event.Nightly, 'CreateFromConfig') 57 self.mox.StubOutWithMock(timed_event.Weekly, 'CreateFromConfig') 58 self.mox.StubOutWithMock(build_event.NewBuild, 'CreateFromConfig') 59 timed_event.Nightly.CreateFromConfig( 60 mox.IgnoreArg(), self.mv).AndReturn(mock_nightly) 61 timed_event.Weekly.CreateFromConfig( 62 mox.IgnoreArg(), self.mv).AndReturn(mock_weekly) 63 build_event.NewBuild.CreateFromConfig( 64 mox.IgnoreArg(), self.mv).AndReturn(mock_new_build) 65 return [mock_nightly, mock_weekly, mock_new_build] 66 67 68 def _ExpectBoardListConfig(self): 69 board_lists = 'sub_board1,sub_board2' 70 self.config.add_section(driver.BOARD_WHITELIST_SECTION) 71 self.config.set(driver.BOARD_WHITELIST_SECTION, 72 self._BOARDS[0], board_lists) 73 74 75 def _ExpectTaskConfig(self): 76 self.config.add_section(timed_event.Nightly.KEYWORD) 77 self.config.add_section(timed_event.Weekly.KEYWORD) 78 self.mox.StubOutWithMock(task.Task, 'CreateFromConfigSection') 79 task.Task.CreateFromConfigSection( 80 self.config, timed_event.Nightly.KEYWORD, 81 board_lists=mox.IgnoreArg()).InAnyOrder().AndReturn( 82 (timed_event.Nightly.KEYWORD, self.nightly_bvt)) 83 task.Task.CreateFromConfigSection( 84 self.config, timed_event.Weekly.KEYWORD, 85 board_lists=mox.IgnoreArg()).InAnyOrder().AndReturn( 86 (timed_event.Weekly.KEYWORD, self.weekly_bvt)) 87 88 89 def _ExpectEnumeration(self): 90 """Expect one call to BoardEnumerator.Enumerate().""" 91 prefix = Labels.BOARD_PREFIX 92 mocks = [] 93 for board in self._BOARDS: 94 mocks.append(self.mox.CreateMock(frontend.Label)) 95 mocks[-1].name = prefix + board 96 self.afe.get_labels(name__startswith=prefix).AndReturn(mocks) 97 98 99 def _ExpectHandle(self, event, group, launch_control_build_called=False): 100 """Make event report that it's handle-able, and expect it to be handle. 101 102 @param event: the mock event that expectations will be set on. 103 @param group: group to put new expectations in. 104 @param launch_control_build_called: True if event has called method 105 GetLaunchControlBuildsForBoard already, and should not expect 106 to call it again due to the cache of driver.Driver._cros_builds. 107 Default is set to False. 108 """ 109 bbs = {'branch': 'build-string'} 110 event.ShouldHandle().InAnyOrder(group).AndReturn(True) 111 for board in self._BOARDS: 112 if not launch_control_build_called: 113 event.GetLaunchControlBuildsForBoard( 114 board).InAnyOrder(group).AndReturn(None) 115 event.GetBranchBuildsForBoard( 116 board).InAnyOrder(group).AndReturn(bbs) 117 event.Handle(mox.IgnoreArg(), bbs, board).InAnyOrder(group) 118 # Should happen once per loop, not once per Handle() 119 # http://crosbug.com/30642 120 event.UpdateCriteria().InAnyOrder(group) 121 122 123 def _ExpectNoHandle(self, event, group): 124 """Make event report that it's handle-able, but do not expect to 125 handle it. 126 127 @param event: the mock event that expectations will be set on. 128 @param group: group to put new expectations in. 129 """ 130 bbs = {'branch': 'build-string'} 131 event.ShouldHandle().InAnyOrder(group).AndReturn(True) 132 133 134 def testTasksFromConfig(self): 135 """Test that we can build a list of Tasks from a config.""" 136 self._ExpectTaskConfig() 137 self._ExpectBoardListConfig() 138 self.mox.ReplayAll() 139 tasks = self.driver.TasksFromConfig(self.config) 140 self.assertTrue(self.nightly_bvt in tasks[timed_event.Nightly.KEYWORD]) 141 self.assertTrue(self.weekly_bvt in tasks[timed_event.Weekly.KEYWORD]) 142 143 144 def testTasksFromConfigRecall(self): 145 """Test that we can build a list of Tasks from a config twice.""" 146 events = self._ExpectSetup() 147 self._ExpectTaskConfig() 148 self._ExpectBoardListConfig() 149 self.mox.ReplayAll() 150 151 self.driver.SetUpEventsAndTasks(self.config, self.mv) 152 for keyword, event in self.driver._events.iteritems(): 153 if keyword == timed_event.Nightly.KEYWORD: 154 self.assertTrue(self.nightly_bvt in event.tasks) 155 if keyword == timed_event.Weekly.KEYWORD: 156 self.assertTrue(self.weekly_bvt in event.tasks) 157 158 self.mox.UnsetStubs() 159 self.mox.VerifyAll() 160 161 self.mox.ResetAll() 162 self.config.remove_section(timed_event.Weekly.KEYWORD) 163 164 self._ExpectSetup() 165 self.mox.StubOutWithMock(task.Task, 'CreateFromConfigSection') 166 task.Task.CreateFromConfigSection( 167 self.config, timed_event.Nightly.KEYWORD, 168 board_lists=mox.IgnoreArg()).InAnyOrder().AndReturn( 169 (timed_event.Nightly.KEYWORD, self.nightly_bvt)) 170 self.mox.ReplayAll() 171 self.driver.SetUpEventsAndTasks(self.config, self.mv) 172 for keyword, event in self.driver._events.iteritems(): 173 if keyword == timed_event.Nightly.KEYWORD: 174 self.assertTrue(self.nightly_bvt in event.tasks) 175 elif keyword == timed_event.Weekly.KEYWORD: 176 self.assertFalse(self.weekly_bvt in event.tasks) 177 178 179 def testHandleAllEventsOnce(self): 180 """Test that all events being ready is handled correctly.""" 181 events = self._ExpectSetup() 182 self._ExpectBoardListConfig() 183 self._ExpectEnumeration() 184 launch_control_build_called = False 185 for event in events: 186 self._ExpectHandle(event, 'events', launch_control_build_called) 187 launch_control_build_called = True 188 self.mox.ReplayAll() 189 190 driver.POOL_SIZE = 1 191 self.driver.SetUpEventsAndTasks(self.config, self.mv) 192 self.driver.HandleEventsOnce(self.mv) 193 194 195 def testHandleNightlyEventOnce(self): 196 """Test that one ready event is handled correctly.""" 197 events = self._ExpectSetup() 198 self._ExpectBoardListConfig() 199 self._ExpectEnumeration() 200 for event in events: 201 if event.keyword == timed_event.Nightly.KEYWORD: 202 self._ExpectHandle(event, 'events') 203 else: 204 event.ShouldHandle().InAnyOrder('events').AndReturn(False) 205 self.mox.ReplayAll() 206 207 driver.POOL_SIZE = 1 208 self.driver.SetUpEventsAndTasks(self.config, self.mv) 209 self.driver.HandleEventsOnce(self.mv) 210 211 212 def testForceOnceForBuild(self): 213 """Test that one event being forced is handled correctly.""" 214 events = self._ExpectSetup() 215 self._ExpectBoardListConfig() 216 217 board = 'board' 218 type = 'release' 219 milestone = '00' 220 manifest = '200.0.02' 221 build = base_event.BuildName(board, type, milestone, manifest) 222 223 events[0].Handle(mox.IgnoreArg(), {milestone: [build]}, board, 224 force=True, launch_control_builds=None) 225 self.mox.ReplayAll() 226 227 self.driver.SetUpEventsAndTasks(self.config, self.mv) 228 self.driver.ForceEventsOnceForBuild([events[0].keyword], build) 229 230 231if __name__ == '__main__': 232 unittest.main() 233