# -*- 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.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 testMainBasic(self):
    """Basic test on main branch."""
    template = 'build_config.ToT.json'
    stage = self.ConstructStage(template)
    stage.PerformStage()
    self.assertTrue(stage.branch == 'main')

  def testReleaseBasic(self):
    """Basic test on release branch."""
    template = 'build_config.release-R50-7978.B.json'
    stage = self.ConstructStage(template)
    stage.PerformStage()
    self.assertTrue(stage.branch == 'release-R50-7978.B')
