• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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