# -*- coding: utf-8 -*-
# Copyright 2016 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 config stages"""

from __future__ import print_function

import os

import mock
from six.moves import builtins

from chromite.cbuildbot import repository
from chromite.cbuildbot.stages import config_stages
from chromite.cbuildbot.stages import generic_stages_unittest
from chromite.cbuildbot.stages import test_stages
from chromite.lib import cros_build_lib
from chromite.lib import git
from chromite.lib import gs
from chromite.lib import osutils
from chromite.lib.buildstore import FakeBuildStore

# pylint: disable=protected-access


class CheckTemplateStageTest(generic_stages_unittest.AbstractStageTestCase):
  """Tests for CheckTemplateStage."""

  TOT_PATH = (config_stages.GS_GE_TEMPLATE_BUCKET + 'build_config.ToT.json')
  R52_PATH = (
      config_stages.GS_GE_TEMPLATE_BUCKET +
      'build_config.release-R52-7978.B.json')
  R53_PATH = (
      config_stages.GS_GE_TEMPLATE_BUCKET +
      'build_config.release-R53-7978.B.json')
  R54_PATH = (
      config_stages.GS_GE_TEMPLATE_BUCKET +
      'build_config.release-R54-7978.B.json')

  def setUp(self):
    self._Prepare()
    self.PatchObject(repository, 'CloneWorkingRepo')
    self.PatchObject(gs, 'GSContext')
    self.update_mock = self.PatchObject(config_stages.UpdateConfigStage, 'Run')
    self.buildstore = FakeBuildStore()

  def ConstructStage(self):
    return config_stages.CheckTemplateStage(self._run, self.buildstore)

  def testListTemplates(self):
    """Test _ListTemplates."""
    self.PatchObject(
        config_stages.CheckTemplateStage,
        'SortAndGetReleasePaths',
        return_value=['R_template.json'])
    stage = self.ConstructStage()
    stage.ctx = mock.Mock()
    stage.ctx.LS.return_value = ['template.json']

    gs_paths = stage._ListTemplates()
    self.assertCountEqual(gs_paths, ['R_template.json', 'template.json'])

  def test_ListTemplatesWithNoSuchKeyError(self):
    """Test _ListTemplates with NoSuchKeyError."""
    stage = self.ConstructStage()
    stage.ctx = mock.Mock()
    stage.ctx.LS.side_effect = gs.GSNoSuchKey()

    gs_paths = stage._ListTemplates()
    self.assertEqual(gs_paths, [])

  def testBasicPerformStage(self):
    """Test basic PerformStage."""
    self.PatchObject(
        config_stages.CheckTemplateStage,
        '_ListTemplates',
        return_value=[self.TOT_PATH, self.R54_PATH])
    stage = self.ConstructStage()

    stage.PerformStage()
    self.assertEqual(self.update_mock.call_count, 2)

  def testSortAndGetReleasePaths(self):
    """Test SortAndGetReleasePaths."""
    stage = self.ConstructStage()

    paths = stage.SortAndGetReleasePaths(
        [self.R54_PATH, self.R53_PATH, self.R52_PATH])
    self.assertTrue(len(paths) == 1)
    self.assertEqual(paths[0], self.R54_PATH)


class UpdateConfigStageTest(generic_stages_unittest.AbstractStageTestCase):
  """Tests for UpdateConfigStage."""

  def setUp(self):
    self._Prepare()
    self.PatchObject(config_stages.UpdateConfigStage, '_DownloadTemplate')
    self.PatchObject(config_stages.UpdateConfigStage, '_CheckoutBranch')
    self.PatchObject(config_stages.UpdateConfigStage, '_RunUnitTest')
    self.PatchObject(git, 'PushBranch')
    self.PatchObject(git, 'RunGit')
    self.PatchObject(repository, 'CloneWorkingRepo')
    self.PatchObject(cros_build_lib, 'run')

    self.project = 'chromite'
    self.chromite_dir = os.path.join(self.tempdir, self.project)
    self.buildstore = FakeBuildStore()

  # pylint: disable=arguments-differ
  def ConstructStage(self, template, new_config=True):
    template_path = config_stages.GS_GE_TEMPLATE_BUCKET + template
    branch = config_stages.GetBranchName(template)
    stage = config_stages.UpdateConfigStage(self._run, self.buildstore,
                                            template_path, branch,
                                            self.chromite_dir, True)

    if new_config:
      fake_config_path = os.path.join(self.chromite_dir, 'config',
                                      config_stages.GE_BUILD_CONFIG_FILE)
    else:
      fake_config_path = os.path.join(self.chromite_dir, 'cbuildbot',
                                      config_stages.GE_BUILD_CONFIG_FILE)

    osutils.Touch(fake_config_path, makedirs=True)

    stage._SetupConfigPaths()
    return stage

  def testSetupConfigPathsOld(self):
    """Test _CreateConfigPatch."""
    template = 'build_config.ToT.json'
    stage = self.ConstructStage(template, new_config=False)

    expected = [
        os.path.join(self.chromite_dir, 'cbuildbot/ge_build_config.json'),
        os.path.join(self.chromite_dir, 'cbuildbot/config_dump.json'),
        os.path.join(self.chromite_dir, 'cbuildbot/waterfall_layout_dump.txt'),
    ]

    self.assertEqual(stage.config_paths, expected)
    self.assertEqual(stage.ge_config_local_path, expected[0])

  def testSetupConfigPathsNew(self):
    """Test _CreateConfigPatch."""
    template = 'build_config.ToT.json'
    stage = self.ConstructStage(template, new_config=True)

    expected = [
        os.path.join(self.chromite_dir, 'config/ge_build_config.json'),
        os.path.join(self.chromite_dir, 'config/config_dump.json'),
        os.path.join(self.chromite_dir, 'config/waterfall_layout_dump.txt'),
    ]

    self.assertEqual(stage.config_paths, expected)
    self.assertEqual(stage.ge_config_local_path, expected[0])

  def testCreateConfigPatch(self):
    """Test _CreateConfigPatch."""
    template = 'build_config.ToT.json'
    stage = self.ConstructStage(template)

    with mock.patch.object(builtins, 'open'):
      config_change_patch = stage._CreateConfigPatch()
      self.assertEqual(
          os.path.basename(config_change_patch), 'config_change.patch')

  def testCreateConfigPatchOldPath(self):
    """Test _CreateConfigPatch."""
    template = 'build_config.ToT.json'
    stage = self.ConstructStage(template, new_config=False)

    with mock.patch.object(builtins, 'open'):
      config_change_patch = stage._CreateConfigPatch()
      self.assertEqual(
          os.path.basename(config_change_patch), 'config_change.patch')

  def testRunBinhostTest(self):
    """Test RunBinhostTest."""
    self.PatchObject(
        config_stages.UpdateConfigStage,
        '_CreateConfigPatch',
        return_value='patch')
    mock_binhost_run = self.PatchObject(test_stages.BinhostTestStage, 'Run')
    mock_run_git = self.PatchObject(git, 'RunGit')
    template = 'build_config.ToT.json'
    stage = self.ConstructStage(template)

    stage._RunBinhostTest()
    self.assertEqual(mock_run_git.call_count, 2)
    mock_binhost_run.assert_called_once_with()

  def testMasterBasic(self):
    """Basic test on master branch."""
    mock_binhost_test = self.PatchObject(config_stages.UpdateConfigStage,
                                         '_RunBinhostTest')
    template = 'build_config.ToT.json'
    stage = self.ConstructStage(template)
    stage.PerformStage()
    self.assertTrue(stage.branch == 'master')
    mock_binhost_test.assert_called_once_with()

  def testReleaseBasic(self):
    """Basic test on release branch."""
    template = 'build_config.release-R50-7978.B.json'
    mock_binhost_test = self.PatchObject(config_stages.UpdateConfigStage,
                                         '_RunBinhostTest')
    stage = self.ConstructStage(template)
    stage.PerformStage()
    self.assertTrue(stage.branch == 'release-R50-7978.B')
    mock_binhost_test.assert_not_called()
