# -*- coding: utf-8 -*-
# Copyright 2015 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.
"""Unittests for simpler builders."""

from __future__ import print_function

import copy
import os

import mock

from chromite.cbuildbot import cbuildbot_run
from chromite.cbuildbot.builders import generic_builders
from chromite.cbuildbot.builders import simple_builders
from chromite.cbuildbot.stages import completion_stages
from chromite.cbuildbot.stages import generic_stages
from chromite.cbuildbot.stages import handle_changes_stages
from chromite.cbuildbot.stages import tast_test_stages
from chromite.cbuildbot.stages import vm_test_stages
from chromite.lib import config_lib
from chromite.lib import constants
from chromite.lib import cros_test_lib
from chromite.lib import failures_lib
from chromite.lib import osutils
from chromite.lib import parallel
from chromite.lib.buildstore import FakeBuildStore
from chromite.scripts import cbuildbot

# pylint: disable=protected-access


class SimpleBuilderTest(cros_test_lib.MockTempDirTestCase):
  """Tests for the main code paths in simple_builders.SimpleBuilder"""

  def setUp(self):
    # List of all stages that would have been called as part of this run.
    self.called_stages = []

    # Map from stage class to exception to be raised when stage is run.
    self.stage_exceptions = {}

    # VM test stages that are run by SimpleBuilder._RunVMTests.
    self.all_vm_test_stages = [vm_test_stages.VMTestStage,
                               tast_test_stages.TastVMTestStage]

    self.buildstore = FakeBuildStore()
    # Simple new function that redirects RunStage to record all stages to be
    # run rather than mock them completely. These can be used in a test to
    # assert something has been called.
    def run_stage(_class_instance, stage_name, *args, **_kwargs):
      # It's more useful to record the actual stage that's wrapped within
      # RepeatStage or RetryStage.
      if stage_name in [generic_stages.RepeatStage, generic_stages.RetryStage]:
        stage_name = args[1]

      self.called_stages.append(stage_name)
      if stage_name in self.stage_exceptions:
        raise self.stage_exceptions[stage_name]

    # Parallel version.
    def run_parallel_stages(_class_instance, *_args):
      # Since parallel stages are forked processes, we can't actually
      # update anything here unless we want to do interprocesses comms.
      pass

    self.buildroot = os.path.join(self.tempdir, 'buildroot')
    chroot_path = os.path.join(self.buildroot, constants.DEFAULT_CHROOT_DIR)
    osutils.SafeMakedirs(os.path.join(chroot_path, 'tmp'))

    self.PatchObject(generic_builders.Builder, '_RunStage',
                     new=run_stage)
    self.PatchObject(simple_builders.SimpleBuilder, '_RunParallelStages',
                     new=run_parallel_stages)
    self.PatchObject(cbuildbot_run._BuilderRunBase, 'GetVersion',
                     return_value='R32-1234.0.0')

    self._manager = parallel.Manager()
    # Pylint-1.9 has a false positive on this for some reason.
    self._manager.__enter__()  # pylint: disable=no-value-for-parameter

  def tearDown(self):
    # Mimic exiting a 'with' statement.
    self._manager.__exit__(None, None, None)

  def _initConfig(
      self, bot_id, master=False, extra_argv=None, override_hw_test_config=None,
      models=None):
    """Return normal options/build_config for |bot_id|"""
    site_config = config_lib.GetConfig()
    build_config = copy.deepcopy(site_config[bot_id])
    build_config['master'] = master
    build_config['important'] = False
    if models:
      build_config['models'] = models

    # Use the cbuildbot parser to create properties and populate default values.
    parser = cbuildbot._CreateParser()
    argv = (['-r', self.buildroot, '--buildbot', '--debug', '--nochromesdk'] +
            (extra_argv if extra_argv else []) + [bot_id])
    options = cbuildbot.ParseCommandLine(parser, argv)

    # Yikes.
    options.managed_chrome = build_config['sync_chrome']

    # Iterate through override and update HWTestConfig attributes.
    if override_hw_test_config:
      for key, val in override_hw_test_config.items():
        for hw_test in build_config.hw_tests:
          setattr(hw_test, key, val)

    return cbuildbot_run.BuilderRun(
        options, site_config, build_config, self._manager)

  def _RunVMTests(self):
    """Helper method that runs VM tests and returns exceptions.

    Returns:
      List of exception classes in CompoundFailure.
    """
    board = 'betty-release'
    builder_run = self._initConfig(board)
    exception_types = []

    try:
      simple_builders.SimpleBuilder(builder_run, self.buildstore)._RunVMTests(
          builder_run, board)
    except failures_lib.CompoundFailure as f:
      exception_types = [e.type for e in f.exc_infos]
    return exception_types

  def testRunStagesPreCQ(self):
    """Verify RunStages for PRE_CQ_LAUNCHER_TYPE builders"""
    builder_run = self._initConfig('pre-cq-launcher')
    simple_builders.SimpleBuilder(builder_run, self.buildstore).RunStages()

  def testRunStagesChrootBuilder(self):
    """Verify RunStages for CHROOT_BUILDER_TYPE builders"""
    builder_run = self._initConfig('chromiumos-sdk')
    simple_builders.SimpleBuilder(builder_run, self.buildstore).RunStages()

  def testRunStagesDefaultBuild(self):
    """Verify RunStages for standard board builders"""
    builder_run = self._initConfig('amd64-generic-full')
    builder_run.attrs.chrome_version = 'TheChromeVersion'
    simple_builders.SimpleBuilder(builder_run, self.buildstore).RunStages()

  def testRunStagesDefaultBuildCompileCheck(self):
    """Verify RunStages for standard board builders (compile only)"""
    extra_argv = ['--compilecheck']
    builder_run = self._initConfig('amd64-generic-full', extra_argv=extra_argv)
    builder_run.attrs.chrome_version = 'TheChromeVersion'
    simple_builders.SimpleBuilder(builder_run, self.buildstore).RunStages()

  def testRunStagesDefaultBuildHwTests(self):
    """Verify RunStages for boards w/hwtests"""
    extra_argv = ['--hwtest']
    builder_run = self._initConfig('eve-release', extra_argv=extra_argv)
    builder_run.attrs.chrome_version = 'TheChromeVersion'
    simple_builders.SimpleBuilder(builder_run, self.buildstore).RunStages()

  def testThatWeScheduleHWTestsRegardlessOfBlocking(self):
    """Verify RunStages for boards w/hwtests (blocking).

    Make sure the same stages get scheduled regardless of whether their hwtest
    suites are marked blocking or not.
    """
    extra_argv = ['--hwtest']
    builder_run_without_blocking = self._initConfig(
        'eve-release', extra_argv=extra_argv,
        override_hw_test_config=dict(blocking=False))
    builder_run_with_blocking = self._initConfig(
        'eve-release', extra_argv=extra_argv,
        override_hw_test_config=dict(blocking=True))
    builder_run_without_blocking.attrs.chrome_version = 'TheChromeVersion'
    builder_run_with_blocking.attrs.chrome_version = 'TheChromeVersion'

    simple_builders.SimpleBuilder(builder_run_without_blocking,
                                  self.buildstore).RunStages()
    without_blocking_stages = list(self.called_stages)

    self.called_stages = []
    simple_builders.SimpleBuilder(builder_run_with_blocking,
                                  self.buildstore).RunStages()
    self.assertEqual(without_blocking_stages, self.called_stages)

  def testUnifiedBuildsRunHwTestsForAllModels(self):
    """Verify hwtests run for model fanout with unified builds"""
    extra_argv = ['--hwtest']
    unified_build = self._initConfig(
        'eve-release',
        extra_argv=extra_argv,
        models=[config_lib.ModelTestConfig('model1', 'model1'),
                config_lib.ModelTestConfig(
                    'model2', 'model2', ['sanity', 'bvt-inline'])])
    unified_build.attrs.chrome_version = 'TheChromeVersion'
    simple_builders.SimpleBuilder(unified_build, self.buildstore).RunStages()

  def testAllVMTestStagesSucceed(self):
    """Verify all VM test stages are run."""
    self.assertEqual([], self._RunVMTests())
    self.assertEqual(self.all_vm_test_stages, self.called_stages)

  def testAllVMTestStagesFail(self):
    """Verify failures are reported when all VM test stages fail."""
    self.stage_exceptions = {
        vm_test_stages.VMTestStage: failures_lib.InfrastructureFailure(),
        tast_test_stages.TastVMTestStage: failures_lib.TestFailure(),
    }
    self.assertEqual(
        [failures_lib.InfrastructureFailure, failures_lib.TestFailure],
        self._RunVMTests())
    self.assertEqual(self.all_vm_test_stages, self.called_stages)

  def testVMTestStageFails(self):
    """Verify TastVMTestStage is still run when VMTestStage fails."""
    self.stage_exceptions = {
        vm_test_stages.VMTestStage: failures_lib.TestFailure(),
    }
    self.assertEqual([failures_lib.TestFailure], self._RunVMTests())
    self.assertEqual(self.all_vm_test_stages, self.called_stages)

  def testTastVMTestStageFails(self):
    """Verify VMTestStage is still run when TastVMTestStage fails."""
    self.stage_exceptions = {
        tast_test_stages.TastVMTestStage: failures_lib.TestFailure(),
    }
    self.assertEqual([failures_lib.TestFailure], self._RunVMTests())
    self.assertEqual(self.all_vm_test_stages, self.called_stages)


class DistributedBuilderTests(SimpleBuilderTest):
  """Tests for DistributedBuilder."""

  def testRunStagesCommitQueueMaster(self):
    """Verify RunStages for master-paladin builder."""
    builder_run = self._initConfig('master-paladin', master=True)
    builder = simple_builders.DistributedBuilder(builder_run, self.buildstore)
    builder.sync_stage = mock.Mock()
    builder.completion_stage_class = mock.Mock()
    builder.RunStages()
    self.assertTrue(handle_changes_stages.CommitQueueHandleChangesStage
                    in self.called_stages)

  def testRunStagesCommitQueueMasterWithImportantBuilderFailedException(self):
    """Verify RunStages for CQ-master with ImportantBuilderFailedException."""
    builder_run = self._initConfig('master-paladin', master=True)
    builder = simple_builders.DistributedBuilder(builder_run, self.buildstore)
    builder.sync_stage = mock.Mock()
    builder.completion_stage_class = (
        completion_stages.CommitQueueCompletionStage)
    self.PatchObject(
        completion_stages.CommitQueueCompletionStage, '__init__',
        return_value=None)
    self.PatchObject(
        completion_stages.CommitQueueCompletionStage, 'Run',
        side_effect=completion_stages.ImportantBuilderFailedException)
    self.assertRaises(completion_stages.ImportantBuilderFailedException,
                      builder.RunStages)
    self.assertTrue(handle_changes_stages.CommitQueueHandleChangesStage
                    in self.called_stages)

  def testRunStagesCommitQueueMasterWithStepFailure(self):
    """Verify RunStages for CQ-master with StepFailure."""
    builder_run = self._initConfig('master-paladin', master=True)
    builder = simple_builders.DistributedBuilder(builder_run, self.buildstore)
    builder.sync_stage = mock.Mock()
    builder.completion_stage_class = (
        completion_stages.CommitQueueCompletionStage)
    self.PatchObject(
        completion_stages.CommitQueueCompletionStage, '__init__',
        return_value=None)
    self.PatchObject(
        completion_stages.CommitQueueCompletionStage, 'Run',
        side_effect=failures_lib.StepFailure)
    self.assertRaises(failures_lib.StepFailure, builder.RunStages)
    self.assertFalse(handle_changes_stages.CommitQueueHandleChangesStage
                     in self.called_stages)

  def testRunStagesReleaseMaster(self):
    """Verify RunStages for master-release builder."""
    builder_run = self._initConfig('master-release', master=True)
    builder = simple_builders.DistributedBuilder(builder_run, self.buildstore)
    builder.sync_stage = mock.Mock()
    builder.completion_stage_class = mock.Mock()
    builder.RunStages()
    self.assertFalse(handle_changes_stages.CommitQueueHandleChangesStage
                     in self.called_stages)
