#!/usr/bin/python
#
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Unit tests for site_utils/deduping_scheduler.py."""

import mox
import unittest

# driver must be imported first due to circular imports in base_event and task
import driver  # pylint: disable-msg=W0611
import deduping_scheduler

import common
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import priorities
from autotest_lib.server import frontend, site_utils
from autotest_lib.server.cros.dynamic_suite import reporting


class DedupingSchedulerTest(mox.MoxTestBase):
    """Unit tests for DedupingScheduler

    @var _BUILD: fake build
    @var _BOARD: fake board to reimage
    @var _SUITE: fake suite name
    @var _POOL: fake machine pool name
    """

    _BUILD = 'build'
    _BUILDS = {'cros-version': 'build'}
    _BOARD = 'board'
    _SUITE = 'suite'
    _POOL = 'pool'
    _NUM = 2
    _PRIORITY = priorities.Priority.POSTBUILD
    _TIMEOUT = 24


    def setUp(self):
        super(DedupingSchedulerTest, self).setUp()
        self.afe = self.mox.CreateMock(frontend.AFE)
        self.scheduler = deduping_scheduler.DedupingScheduler(afe=self.afe)
        self.mox.StubOutWithMock(site_utils, 'check_lab_status')


    def _SetupLabStatus(self, build, message=None):
        """Set up to mock one call to `site_utils.check_lab_status()`.

        @param build    The build to expect to be passed to
                        `check_lab_status()`.
        @param message  `None` if the mocked call should return that
                        the lab status is up.  Otherwise, a string for
                        the exception message.

        """
        if message is None:
            site_utils.check_lab_status(build)
        else:
            site_utils.check_lab_status(build).AndRaise(
                site_utils.TestLabException(message))


    def testScheduleSuite(self):
        """Test a successful de-dup and suite schedule."""
        # Lab is UP!
        self._SetupLabStatus(self._BUILD)
        # A similar suite has not already been scheduled.
        self.afe.get_jobs(name__startswith=self._BUILD,
                          name__endswith='control.'+self._SUITE,
                          created_on__gte=mox.IgnoreArg()).AndReturn([])
        # Expect an attempt to schedule; allow it to succeed.
        self.afe.run('create_suite_job',
                     name=self._SUITE,
                     board=self._BOARD,
                     builds=self._BUILDS,
                     check_hosts=False,
                     pool=self._POOL,
                     num=self._NUM,
                     priority=self._PRIORITY,
                     test_source_build=None,
                     timeout=self._TIMEOUT,
                     file_bugs=False,
                     wait_for_results=False,
                     job_retry=False,
                     delay_minutes=0,
                     run_prod_code=False).AndReturn(7)
        self.mox.ReplayAll()
        self.assertTrue(self.scheduler.ScheduleSuite(self._SUITE,
                                                     self._BOARD,
                                                     self._BUILD,
                                                     self._POOL,
                                                     self._NUM,
                                                     self._PRIORITY,
                                                     self._TIMEOUT))


    def testShouldNotScheduleSuite(self):
        """Test a successful de-dup and avoiding scheduling the suite."""
        # Lab is UP!
        self._SetupLabStatus(self._BUILD)
        # A similar suite has already been scheduled.
        self.afe.get_jobs(
            name__startswith=self._BUILD,
            name__endswith='control.'+self._SUITE,
            created_on__gte=mox.IgnoreArg()).AndReturn(['42'])
        self.mox.ReplayAll()
        self.assertFalse(self.scheduler.ScheduleSuite(self._SUITE,
                                                      self._BOARD,
                                                      self._BUILD,
                                                      self._POOL,
                                                      None,
                                                      self._PRIORITY,
                                                      self._TIMEOUT))


    def testShouldNotScheduleSuiteLabClosed(self):
        """Test that we don't schedule when the lab is closed."""
        # Lab is down.  :-(
        self._SetupLabStatus(self._BUILD, 'Lab closed due to sheep.')
        self.mox.ReplayAll()
        self.assertFalse(self.scheduler.ScheduleSuite(self._SUITE,
                                                      self._BOARD,
                                                      self._BUILD,
                                                      self._POOL,
                                                      None,
                                                      self._PRIORITY,
                                                      self._TIMEOUT))


    def testForceScheduleSuite(self):
        """Test a successful de-dup, but force scheduling the suite."""
        # Expect an attempt to schedule; allow it to succeed.
        self.afe.run('create_suite_job',
                     name=self._SUITE,
                     board=self._BOARD,
                     builds=self._BUILDS,
                     check_hosts=False,
                     num=None,
                     pool=self._POOL,
                     priority=self._PRIORITY,
                     test_source_build=None,
                     timeout=self._TIMEOUT,
                     file_bugs=False,
                     wait_for_results=False,
                     job_retry=False,
                     delay_minutes=0,
                     run_prod_code=False).AndReturn(7)
        self.mox.ReplayAll()
        self.assertTrue(self.scheduler.ScheduleSuite(self._SUITE,
                                                     self._BOARD,
                                                     self._BUILD,
                                                     self._POOL,
                                                     None,
                                                     self._PRIORITY,
                                                     self._TIMEOUT,
                                                     force=True))


    def testShouldScheduleSuiteExplodes(self):
        """Test a failure to de-dup."""
        # Lab is UP!
        self._SetupLabStatus(self._BUILD)
        # Barf while checking for similar suites.
        self.afe.get_jobs(
            name__startswith=self._BUILD,
            name__endswith='control.'+self._SUITE,
            created_on__gte=mox.IgnoreArg()).AndRaise(Exception())
        self.mox.ReplayAll()
        self.assertRaises(deduping_scheduler.DedupException,
                          self.scheduler.ScheduleSuite,
                          self._SUITE,
                          self._BOARD,
                          self._BUILD,
                          self._POOL,
                          self._NUM,
                          self._PRIORITY,
                          self._TIMEOUT)


    def testScheduleFail(self):
        """Test a successful de-dup and failure to schedule the suite."""
        # Lab is UP!
        self._SetupLabStatus(self._BUILD)
        # A similar suite has not already been scheduled.
        self.afe.get_jobs(name__startswith=self._BUILD,
                          name__endswith='control.'+self._SUITE,
                          created_on__gte=mox.IgnoreArg()).AndReturn([])
        # Expect an attempt to create a job for the suite; fail it.
        self.afe.run('create_suite_job',
                     name=self._SUITE,
                     board=self._BOARD,
                     builds=self._BUILDS,
                     check_hosts=False,
                     num=None,
                     pool=None,
                     priority=self._PRIORITY,
                     test_source_build=None,
                     timeout=self._TIMEOUT,
                     file_bugs=False,
                     wait_for_results=False,
                     run_prod_code=False).AndReturn(None)
        self.mox.ReplayAll()
        self.assertRaises(deduping_scheduler.ScheduleException,
                          self.scheduler.ScheduleSuite,
                          self._SUITE,
                          self._BOARD,
                          self._BUILD,
                          None,
                          None,
                          self._PRIORITY,
                          self._TIMEOUT)


    def testScheduleExplodes(self):
        """Test a successful de-dup and barf while scheduling the suite."""
        # Lab is UP!
        self._SetupLabStatus(self._BUILD)
        # A similar suite has not already been scheduled.
        self.afe.get_jobs(name__startswith=self._BUILD,
                          name__endswith='control.'+self._SUITE,
                          created_on__gte=mox.IgnoreArg()).AndReturn([])
        # Expect an attempt to create a job for the suite; barf on it.
        self.afe.run('create_suite_job',
                     name=self._SUITE,
                     board=self._BOARD,
                     builds=self._BUILDS,
                     check_hosts=False,
                     num=None,
                     pool=None,
                     priority=self._PRIORITY,
                     test_source_build=None,
                     timeout=self._TIMEOUT,
                     file_bugs=False,
                     wait_for_results=False,
                     run_prod_code=False).AndRaise(Exception())
        self.mox.ReplayAll()
        self.assertRaises(deduping_scheduler.ScheduleException,
                          self.scheduler.ScheduleSuite,
                          self._SUITE,
                          self._BOARD,
                          self._BUILD,
                          None,
                          None,
                          self._PRIORITY,
                          self._TIMEOUT)


    def _SetupScheduleSuiteMocks(self, mock_bug_id):
        """Setup mocks needed for SuiteSchedulerBug testing.

        @param mock_bug_id: An integer representing a bug id that should be
                            returned by Reporter._create_bug_report
                            None if _create_bug_report is supposed to
                            fail.
        """
        self.mox.StubOutWithMock(reporting.Reporter, '__init__')
        self.mox.StubOutWithMock(reporting.Reporter, '_create_bug_report')
        self.mox.StubOutWithMock(reporting.Reporter, '_check_tracker')
        self.mox.StubOutWithMock(reporting.Reporter, 'find_issue_by_marker')
        self.mox.StubOutWithMock(site_utils, 'get_sheriffs')
        self.scheduler._file_bug = True
        # Lab is UP!
        self._SetupLabStatus(self._BUILD)
        # A similar suite has not already been scheduled.
        self.afe.get_jobs(name__startswith=self._BUILD,
                          name__endswith='control.'+self._SUITE,
                          created_on__gte=mox.IgnoreArg()).AndReturn([])
        message = 'Control file not found.'
        exception = error.ControlFileNotFound(message)
        site_utils.get_sheriffs(lab_only=True).AndReturn(['deputy1', 'deputy2'])
        self.afe.run('create_suite_job',
                     name=self._SUITE,
                     board=self._BOARD,
                     builds=self._BUILDS,
                     check_hosts=False,
                     pool=self._POOL,
                     num=self._NUM,
                     priority=self._PRIORITY,
                     test_source_build=None,
                     timeout=self._TIMEOUT,
                     file_bugs=False,
                     wait_for_results=False,
                     job_retry=False,
                     delay_minutes=0,
                     run_prod_code=False).AndRaise(exception)
        reporting.Reporter.__init__()
        reporting.Reporter._check_tracker().AndReturn(True)
        reporting.Reporter.find_issue_by_marker(mox.IgnoreArg()).AndReturn(None)
        reporting.Reporter._create_bug_report(
                mox.IgnoreArg(), {}, []).AndReturn(mock_bug_id)


    def testScheduleReportsBugSuccess(self):
        """Test that the scheduler file a bug."""
        self._SetupScheduleSuiteMocks(1158)
        self.mox.ReplayAll()
        self.assertFalse(self.scheduler.ScheduleSuite(
                    self._SUITE, self._BOARD, self._BUILD, self._POOL,
                    self._NUM, self._PRIORITY, self._TIMEOUT))
        self.mox.VerifyAll()


    def testScheduleReportsBugFalse(self):
        """Test that the scheduler failed to file a bug."""
        self._SetupScheduleSuiteMocks(None)
        self.mox.ReplayAll()
        self.assertRaises(
                deduping_scheduler.ScheduleException,
                self.scheduler.ScheduleSuite,
                self._SUITE, self._BOARD, self._BUILD, self._POOL,
                self._NUM, self._PRIORITY, self._TIMEOUT)
        self.mox.VerifyAll()


if __name__ == '__main__':
    unittest.main()
