Home | History | Annotate | Download | only in suite_scheduler
      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/deduping_scheduler.py."""
      8 
      9 import mox
     10 import unittest
     11 
     12 # driver must be imported first due to circular imports in base_event and task
     13 import driver  # pylint: disable-msg=W0611
     14 import deduping_scheduler
     15 
     16 import common
     17 from autotest_lib.client.common_lib import error
     18 from autotest_lib.client.common_lib import priorities
     19 from autotest_lib.server import frontend, site_utils
     20 from autotest_lib.server.cros.dynamic_suite import reporting
     21 
     22 
     23 class DedupingSchedulerTest(mox.MoxTestBase):
     24     """Unit tests for DedupingScheduler
     25 
     26     @var _BUILD: fake build
     27     @var _BOARD: fake board to reimage
     28     @var _SUITE: fake suite name
     29     @var _POOL: fake machine pool name
     30     """
     31 
     32     _BUILD = 'build'
     33     _BUILDS = {'cros-version': 'build'}
     34     _BOARD = 'board'
     35     _SUITE = 'suite'
     36     _POOL = 'pool'
     37     _NUM = 2
     38     _PRIORITY = priorities.Priority.POSTBUILD
     39     _TIMEOUT = 24
     40     _TIMEOUT_MINS = 1440
     41 
     42 
     43     def setUp(self):
     44         super(DedupingSchedulerTest, self).setUp()
     45         self.afe = self.mox.CreateMock(frontend.AFE)
     46         self.scheduler = deduping_scheduler.DedupingScheduler(afe=self.afe)
     47         self.mox.StubOutWithMock(site_utils, 'check_lab_status')
     48 
     49 
     50     def _SetupLabStatus(self, build, message=None):
     51         """Set up to mock one call to `site_utils.check_lab_status()`.
     52 
     53         @param build    The build to expect to be passed to
     54                         `check_lab_status()`.
     55         @param message  `None` if the mocked call should return that
     56                         the lab status is up.  Otherwise, a string for
     57                         the exception message.
     58 
     59         """
     60         if message is None:
     61             site_utils.check_lab_status(build)
     62         else:
     63             site_utils.check_lab_status(build).AndRaise(
     64                 site_utils.TestLabException(message))
     65 
     66 
     67     def testScheduleSuite(self):
     68         """Test a successful de-dup and suite schedule."""
     69         # Lab is UP!
     70         self._SetupLabStatus(self._BUILD)
     71         # A similar suite has not already been scheduled.
     72         self.afe.get_jobs(name__istartswith=self._BUILD,
     73                           name__iendswith='control.'+self._SUITE,
     74                           created_on__gte=mox.IgnoreArg(),
     75                           min_rpc_timeout=mox.IgnoreArg()).AndReturn([])
     76         # Expect an attempt to schedule; allow it to succeed.
     77         self.afe.run('create_suite_job',
     78                      name=self._SUITE,
     79                      board=self._BOARD,
     80                      builds=self._BUILDS,
     81                      check_hosts=False,
     82                      pool=self._POOL,
     83                      num=self._NUM,
     84                      priority=self._PRIORITY,
     85                      test_source_build=None,
     86                      timeout=self._TIMEOUT,
     87                      max_runtime_mins=self._TIMEOUT_MINS,
     88                      timeout_mins=self._TIMEOUT_MINS,
     89                      file_bugs=False,
     90                      wait_for_results=False,
     91                      job_retry=False,
     92                      delay_minutes=0,
     93                      run_prod_code=False,
     94                      min_rpc_timeout=mox.IgnoreArg()).AndReturn(7)
     95         self.mox.ReplayAll()
     96         self.assertTrue(self.scheduler.ScheduleSuite(self._SUITE,
     97                                                      self._BOARD,
     98                                                      self._BUILD,
     99                                                      self._POOL,
    100                                                      self._NUM,
    101                                                      self._PRIORITY,
    102                                                      self._TIMEOUT))
    103 
    104 
    105     def testShouldNotScheduleSuite(self):
    106         """Test a successful de-dup and avoiding scheduling the suite."""
    107         # Lab is UP!
    108         self._SetupLabStatus(self._BUILD)
    109         # A similar suite has already been scheduled.
    110         self.afe.get_jobs(
    111             name__istartswith=self._BUILD,
    112             name__iendswith='control.'+self._SUITE,
    113             created_on__gte=mox.IgnoreArg(),
    114             min_rpc_timeout=mox.IgnoreArg()).AndReturn(['42'])
    115         self.mox.ReplayAll()
    116         self.assertFalse(self.scheduler.ScheduleSuite(self._SUITE,
    117                                                       self._BOARD,
    118                                                       self._BUILD,
    119                                                       self._POOL,
    120                                                       None,
    121                                                       self._PRIORITY,
    122                                                       self._TIMEOUT))
    123 
    124 
    125     def testShouldNotScheduleSuiteLabClosed(self):
    126         """Test that we don't schedule when the lab is closed."""
    127         # Lab is down.  :-(
    128         self._SetupLabStatus(self._BUILD, 'Lab closed due to sheep.')
    129         self.mox.ReplayAll()
    130         self.assertFalse(self.scheduler.ScheduleSuite(self._SUITE,
    131                                                       self._BOARD,
    132                                                       self._BUILD,
    133                                                       self._POOL,
    134                                                       None,
    135                                                       self._PRIORITY,
    136                                                       self._TIMEOUT))
    137 
    138 
    139     def testForceScheduleSuite(self):
    140         """Test a successful de-dup, but force scheduling the suite."""
    141         # Expect an attempt to schedule; allow it to succeed.
    142         self.afe.run('create_suite_job',
    143                      name=self._SUITE,
    144                      board=self._BOARD,
    145                      builds=self._BUILDS,
    146                      check_hosts=False,
    147                      num=None,
    148                      pool=self._POOL,
    149                      priority=self._PRIORITY,
    150                      test_source_build=None,
    151                      timeout=self._TIMEOUT,
    152                      max_runtime_mins=self._TIMEOUT_MINS,
    153                      timeout_mins=self._TIMEOUT_MINS,
    154                      file_bugs=False,
    155                      wait_for_results=False,
    156                      job_retry=False,
    157                      delay_minutes=0,
    158                      run_prod_code=False,
    159                      min_rpc_timeout=mox.IgnoreArg()).AndReturn(7)
    160         self.mox.ReplayAll()
    161         self.assertTrue(self.scheduler.ScheduleSuite(self._SUITE,
    162                                                      self._BOARD,
    163                                                      self._BUILD,
    164                                                      self._POOL,
    165                                                      None,
    166                                                      self._PRIORITY,
    167                                                      self._TIMEOUT,
    168                                                      force=True))
    169 
    170 
    171     def testShouldScheduleSuiteExplodes(self):
    172         """Test a failure to de-dup."""
    173         # Lab is UP!
    174         self._SetupLabStatus(self._BUILD)
    175         # Barf while checking for similar suites.
    176         self.afe.get_jobs(
    177             name__istartswith=self._BUILD,
    178             name__iendswith='control.'+self._SUITE,
    179             created_on__gte=mox.IgnoreArg(),
    180             min_rpc_timeout=mox.IgnoreArg()).AndRaise(Exception())
    181         self.mox.ReplayAll()
    182         self.assertRaises(deduping_scheduler.DedupException,
    183                           self.scheduler.ScheduleSuite,
    184                           self._SUITE,
    185                           self._BOARD,
    186                           self._BUILD,
    187                           self._POOL,
    188                           self._NUM,
    189                           self._PRIORITY,
    190                           self._TIMEOUT)
    191 
    192 
    193     def testScheduleFail(self):
    194         """Test a successful de-dup and failure to schedule the suite."""
    195         # Lab is UP!
    196         self._SetupLabStatus(self._BUILD)
    197         # A similar suite has not already been scheduled.
    198         self.afe.get_jobs(name__istartswith=self._BUILD,
    199                           name__iendswith='control.'+self._SUITE,
    200                           created_on__gte=mox.IgnoreArg(),
    201                           min_rpc_timeout=mox.IgnoreArg()).AndReturn([])
    202         # Expect an attempt to create a job for the suite; fail it.
    203         self.afe.run('create_suite_job',
    204                      name=self._SUITE,
    205                      board=self._BOARD,
    206                      builds=self._BUILDS,
    207                      check_hosts=False,
    208                      num=None,
    209                      pool=None,
    210                      priority=self._PRIORITY,
    211                      test_source_build=None,
    212                      timeout=self._TIMEOUT,
    213                      max_runtime_mins=self._TIMEOUT_MINS,
    214                      timeout_mins=self._TIMEOUT_MINS,
    215                      file_bugs=False,
    216                      wait_for_results=False,
    217                      run_prod_code=False,
    218                      min_rpc_timeout=mox.IgnoreArg()).AndReturn(None)
    219         self.mox.ReplayAll()
    220         self.assertRaises(deduping_scheduler.ScheduleException,
    221                           self.scheduler.ScheduleSuite,
    222                           self._SUITE,
    223                           self._BOARD,
    224                           self._BUILD,
    225                           None,
    226                           None,
    227                           self._PRIORITY,
    228                           self._TIMEOUT)
    229 
    230 
    231     def testScheduleExplodes(self):
    232         """Test a successful de-dup and barf while scheduling the suite."""
    233         # Lab is UP!
    234         self._SetupLabStatus(self._BUILD)
    235         # A similar suite has not already been scheduled.
    236         self.afe.get_jobs(name__istartswith=self._BUILD,
    237                           name__iendswith='control.'+self._SUITE,
    238                           created_on__gte=mox.IgnoreArg(),
    239                           min_rpc_timeout=mox.IgnoreArg()).AndReturn([])
    240         # Expect an attempt to create a job for the suite; barf on it.
    241         self.afe.run('create_suite_job',
    242                      name=self._SUITE,
    243                      board=self._BOARD,
    244                      builds=self._BUILDS,
    245                      check_hosts=False,
    246                      num=None,
    247                      pool=None,
    248                      priority=self._PRIORITY,
    249                      test_source_build=None,
    250                      timeout=self._TIMEOUT,
    251                      max_runtime_mins=self._TIMEOUT_MINS,
    252                      timeout_mins=self._TIMEOUT_MINS,
    253                      file_bugs=False,
    254                      wait_for_results=False,
    255                      run_prod_code=False,
    256                      min_rpc_timeout=mox.IgnoreArg()).AndRaise(Exception())
    257         self.mox.ReplayAll()
    258         self.assertRaises(deduping_scheduler.ScheduleException,
    259                           self.scheduler.ScheduleSuite,
    260                           self._SUITE,
    261                           self._BOARD,
    262                           self._BUILD,
    263                           None,
    264                           None,
    265                           self._PRIORITY,
    266                           self._TIMEOUT)
    267 
    268 
    269     def _SetupScheduleSuiteMocks(self, mock_bug_id):
    270         """Setup mocks needed for SuiteSchedulerBug testing.
    271 
    272         @param mock_bug_id: An integer representing a bug id that should be
    273                             returned by Reporter._create_bug_report
    274                             None if _create_bug_report is supposed to
    275                             fail.
    276         """
    277         self.mox.StubOutWithMock(reporting.Reporter, '__init__')
    278         self.mox.StubOutWithMock(reporting.Reporter, '_create_bug_report')
    279         self.mox.StubOutWithMock(reporting.Reporter, '_check_tracker')
    280         self.mox.StubOutWithMock(reporting.Reporter, '_find_issue_by_marker')
    281         self.mox.StubOutWithMock(site_utils, 'get_sheriffs')
    282         self.scheduler._file_bug = True
    283         # Lab is UP!
    284         self._SetupLabStatus(self._BUILD)
    285         # A similar suite has not already been scheduled.
    286         self.afe.get_jobs(name__istartswith=self._BUILD,
    287                           name__iendswith='control.'+self._SUITE,
    288                           created_on__gte=mox.IgnoreArg(),
    289                           min_rpc_timeout=mox.IgnoreArg()).AndReturn([])
    290         message = 'Control file not found.'
    291         exception = error.ControlFileNotFound(message)
    292         site_utils.get_sheriffs(lab_only=True).AndReturn(['deputy1', 'deputy2'])
    293         self.afe.run('create_suite_job',
    294                      name=self._SUITE,
    295                      board=self._BOARD,
    296                      builds=self._BUILDS,
    297                      check_hosts=False,
    298                      pool=self._POOL,
    299                      num=self._NUM,
    300                      priority=self._PRIORITY,
    301                      test_source_build=None,
    302                      timeout=self._TIMEOUT,
    303                      max_runtime_mins=self._TIMEOUT_MINS,
    304                      timeout_mins=self._TIMEOUT_MINS,
    305                      file_bugs=False,
    306                      wait_for_results=False,
    307                      job_retry=False,
    308                      delay_minutes=0,
    309                      run_prod_code=False,
    310                      min_rpc_timeout=mox.IgnoreArg()).AndRaise(exception)
    311         reporting.Reporter.__init__()
    312         reporting.Reporter._check_tracker().AndReturn(True)
    313         (reporting.Reporter._find_issue_by_marker(mox.IgnoreArg())
    314          .AndReturn(None))
    315         reporting.Reporter._create_bug_report(
    316                 mox.IgnoreArg(), {}, []).AndReturn(mock_bug_id)
    317 
    318 
    319     def testScheduleReportsBugSuccess(self):
    320         """Test that the scheduler file a bug."""
    321         self._SetupScheduleSuiteMocks(1158)
    322         self.mox.ReplayAll()
    323         self.assertFalse(self.scheduler.ScheduleSuite(
    324                     self._SUITE, self._BOARD, self._BUILD, self._POOL,
    325                     self._NUM, self._PRIORITY, self._TIMEOUT))
    326         self.mox.VerifyAll()
    327 
    328 
    329     def testScheduleReportsBugFalse(self):
    330         """Test that the scheduler failed to file a bug."""
    331         self._SetupScheduleSuiteMocks(None)
    332         self.mox.ReplayAll()
    333         self.assertRaises(
    334                 deduping_scheduler.ScheduleException,
    335                 self.scheduler.ScheduleSuite,
    336                 self._SUITE, self._BOARD, self._BUILD, self._POOL,
    337                 self._NUM, self._PRIORITY, self._TIMEOUT)
    338         self.mox.VerifyAll()
    339 
    340 
    341 if __name__ == '__main__':
    342     unittest.main()
    343