# -*- coding: utf-8 -*-
# Copyright 2017 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.

"""Test simple_chrome_builder  module."""

from __future__ import print_function

import os

import mock

from chromite.cros_bisect import simple_chrome_builder
from chromite.cbuildbot import commands
from chromite.lib import commandline
from chromite.lib import cros_logging as logging
from chromite.lib import cros_test_lib
from chromite.lib import gclient
from chromite.lib import git
from chromite.lib import osutils


class TestSimpleChromeBuilder(cros_test_lib.MockTempDirTestCase):
  """Tests AutotestEvaluator class."""
  BOARD = 'samus'
  DUT_IP = '192.168.1.1'
  DUT = commandline.DeviceParser(commandline.DEVICE_SCHEME_SSH)(DUT_IP)

  def setUp(self):
    self.default_chromium_dir = os.path.join(self.tempdir, 'chromium')
    self.default_repo_dir = os.path.join(self.tempdir, 'chromium', 'src')
    self.default_archive_base = os.path.join(self.tempdir, 'build')
    self.gclient_path = os.path.join(self.tempdir, 'gclient')
    self.log_output_args = {'log_output': True}

    # The SimpleChromeBuilder class sets a 'verbose' setting based on the
    # ambient logging level, so we must set the logger to the default setting
    # of INFO for this test and then restore the logger to whatever it was
    # originally set to when we clean the test up.
    logger = logging.getLogger()
    self._prev_logging_level = logger.getEffectiveLevel()
    logger.setLevel(logging.INFO)

  def tearDown(self):
    logger = logging.getLogger()
    logger.setLevel(self._prev_logging_level)

  def GetBuilder(self, base_dir=None, board=None, reuse_repo=True,
                 chromium_dir=None, build_dir=None, archive_build=True,
                 reuse_build=True):
    """Obtains a SimpleChromeBuilder instance.

    Args:
      base_dir: Base directory. Default self.tempdir.
      board: Board name. Default self.BOARD.
      reuse_repo: True to reuse repo.
      chromium_dir: Optional. If specified, use the chromium repo the path
          points to.
      build_dir: Optional. Store build result to it if specified.
      archive_build: True to archive build.
      reuse_build: True to reuse previous build.

    Returns:
      A SimpleChromeBuilder instance.
    """
    if base_dir is None:
      base_dir = self.tempdir
    if board is None:
      board = self.BOARD
    options = cros_test_lib.EasyAttr(
        base_dir=base_dir, board=board, reuse_repo=reuse_repo,
        chromium_dir=chromium_dir, build_dir=build_dir,
        archive_build=archive_build, reuse_build=reuse_build)
    builder = simple_chrome_builder.SimpleChromeBuilder(options)

    # Override gclient path.
    builder.gclient = self.gclient_path

    return builder

  def testInit(self):
    builder = self.GetBuilder()
    base_dir = self.tempdir
    self.assertEqual(base_dir, builder.base_dir)
    self.assertEqual(self.default_chromium_dir, builder.chromium_dir)
    self.assertEqual(self.default_repo_dir, builder.repo_dir)
    self.assertTrue(builder.reuse_repo)
    self.assertTrue(builder.reuse_build)
    self.assertTrue(builder.archive_build)
    self.assertEqual(self.default_archive_base, builder.archive_base)
    self.assertTrue(os.path.isdir(builder.archive_base))
    self.assertDictEqual(self.log_output_args, builder.log_output_args)

  def testInitMissingRequiredArgs(self):
    options = cros_test_lib.EasyAttr()
    with self.assertRaises(Exception) as cm:
      simple_chrome_builder.SimpleChromeBuilder(options)
    exception_message = str(cm.exception)
    self.assertIn('Missing command line', exception_message)
    self.assertIn('SimpleChromeBuilder', exception_message)
    for arg in simple_chrome_builder.SimpleChromeBuilder.REQUIRED_ARGS:
      self.assertIn(arg, exception_message)

  def testInitCustomizedDir(self):
    base_dir = self.tempdir
    chromium_dir = os.path.join(base_dir, 'another_chromium')
    build_dir = os.path.join(base_dir, 'another_build')
    builder = self.GetBuilder(chromium_dir=chromium_dir, build_dir=build_dir)

    self.assertEqual(base_dir, builder.base_dir)
    self.assertEqual(chromium_dir, builder.chromium_dir)
    self.assertEqual(os.path.join(chromium_dir, 'src'), builder.repo_dir)
    self.assertTrue(builder.reuse_repo)
    self.assertTrue(builder.reuse_build)
    self.assertTrue(builder.archive_build)
    self.assertEqual(build_dir, builder.archive_base)
    self.assertTrue(os.path.isdir(builder.archive_base))
    self.assertDictEqual(self.log_output_args, builder.log_output_args)

  def testInitFlipFlags(self):
    builder = self.GetBuilder(reuse_repo=False, archive_build=False,
                              reuse_build=False)
    base_dir = self.tempdir
    self.assertEqual(base_dir, builder.base_dir)
    self.assertEqual(self.default_chromium_dir, builder.chromium_dir)
    self.assertEqual(self.default_repo_dir, builder.repo_dir)
    self.assertFalse(builder.reuse_repo)
    self.assertFalse(builder.reuse_build)
    self.assertFalse(builder.archive_build)
    self.assertEqual(self.default_archive_base, builder.archive_base)
    self.assertFalse(os.path.isdir(builder.archive_base))
    self.assertDictEqual(self.log_output_args, builder.log_output_args)

  def testSetUp(self):
    command_mock = self.StartPatcher(cros_test_lib.RunCommandMock())
    command_mock.AddCmdResult(['fetch', '--nohooks', 'chromium'])
    write_config_mock = self.PatchObject(gclient, 'WriteConfigFile')
    git_mock = self.PatchObject(git, 'RunGit')
    gsync_mock = self.PatchObject(gclient, 'Sync')

    builder = self.GetBuilder()
    builder.SetUp()

    write_config_mock.assert_called_with(
        self.gclient_path, self.default_chromium_dir, True, None, managed=False)
    git_mock.assert_called_with(self.default_repo_dir,
                                ['pull', 'origin', 'master'])
    gsync_mock.assert_called_with(
        self.gclient_path, self.default_chromium_dir, reset=True, nohooks=True,
        verbose=False, run_args=self.log_output_args)

  def testSetUpSkip(self):
    write_config_mock = self.PatchObject(gclient, 'WriteConfigFile')
    git_mock = self.PatchObject(git, 'RunGit')
    gsync_mock = self.PatchObject(gclient, 'Sync')

    # Make it looks like a git repo.
    osutils.SafeMakedirs(os.path.join(self.default_repo_dir, '.git'))

    builder = self.GetBuilder()
    builder.SetUp()

    write_config_mock.assert_not_called()
    git_mock.assert_not_called()
    gsync_mock.assert_not_called()

  def testSetUpExistingRepoException(self):
    write_config_mock = self.PatchObject(gclient, 'WriteConfigFile')
    git_mock = self.PatchObject(git, 'RunGit')
    gsync_mock = self.PatchObject(gclient, 'Sync')

    # Make it looks like a git repo.
    osutils.SafeMakedirs(os.path.join(self.default_repo_dir, '.git'))

    builder = self.GetBuilder(reuse_repo=False)
    self.assertRaisesRegex(Exception, 'Chromium repo exists.*',
                           builder.SetUp)

    write_config_mock.assert_not_called()
    git_mock.assert_not_called()
    gsync_mock.assert_not_called()

  def testSyncToHead(self):
    git_mock = self.PatchObject(git, 'CleanAndCheckoutUpstream')
    builder = self.GetBuilder()
    builder.SyncToHead()
    git_mock.assert_called_with(self.default_repo_dir)

  def testGclientSync(self):
    gsync_mock = self.PatchObject(gclient, 'Sync')

    builder = self.GetBuilder()
    builder.GclientSync()
    gsync_mock.assert_called_with(
        self.gclient_path, self.default_chromium_dir, reset=False,
        nohooks=False, verbose=False, run_args=self.log_output_args)

    builder.GclientSync(reset=True, nohooks=True)
    gsync_mock.assert_called_with(
        self.gclient_path, self.default_chromium_dir, reset=True,
        nohooks=True, verbose=False, run_args=self.log_output_args)

  def testBuildReuse(self):
    commit_label = 'test'

    # Let the build already be in archive.
    archive_path = os.path.join(
        self.default_archive_base, 'out_%s_%s' % (self.BOARD, commit_label),
        'Release')
    osutils.SafeMakedirs(archive_path)

    builder = self.GetBuilder()
    build_to_deploy = builder.Build(commit_label)
    self.assertEqual(archive_path, build_to_deploy)

  def _ChromeSdkRunSideEffect(self, *args, **unused_kwargs):
    if args and len(args[0]) == 3:
      bash_command = args[0][2]
      if 'gn gen' in bash_command:
        build_dir = bash_command.split()[2]
        osutils.SafeMakedirs(os.path.join(self.default_repo_dir, build_dir))
      return mock.DEFAULT

  def testBuild(self):
    gsync_mock = self.PatchObject(simple_chrome_builder.SimpleChromeBuilder,
                                  'GclientSync')
    success_result = cros_test_lib.EasyAttr(returncode=0)
    chrome_sdk_run_mock = self.PatchObject(
        commands.ChromeSDK, 'Run', side_effect=self._ChromeSdkRunSideEffect,
        return_value=success_result)
    chrome_sdk_ninja_mock = self.PatchObject(
        commands.ChromeSDK, 'Ninja', return_value=success_result)

    commit_label = 'test'
    archive_path = os.path.join(
        self.default_archive_base, 'out_%s_%s' % (self.BOARD, commit_label),
        'Release')

    self.assertFalse(os.path.isdir(archive_path))
    builder = self.GetBuilder()
    build_to_deploy = builder.Build(commit_label)
    self.assertEqual(archive_path, build_to_deploy)
    # Check that build_to_deploy exists after builder.Build()
    self.assertTrue(os.path.isdir(archive_path))
    gsync_mock.assert_called()
    chrome_sdk_run_mock.assert_called_with(
        ['bash', '-c', 'gn gen out_%s/Release --args="$GN_ARGS"' % self.BOARD],
        run_args=self.log_output_args)
    chrome_sdk_ninja_mock.assert_called_with(run_args=self.log_output_args)

  def testBuildNoArchive(self):
    gsync_mock = self.PatchObject(simple_chrome_builder.SimpleChromeBuilder,
                                  'GclientSync')
    success_result = cros_test_lib.EasyAttr(returncode=0)
    chrome_sdk_run_mock = self.PatchObject(
        commands.ChromeSDK, 'Run', side_effect=self._ChromeSdkRunSideEffect,
        return_value=success_result)
    chrome_sdk_ninja_mock = self.PatchObject(
        commands.ChromeSDK, 'Ninja', return_value=success_result)

    commit_label = 'test'
    archive_path = os.path.join(
        self.default_archive_base, 'out_%s_%s' % (self.BOARD, commit_label),
        'Release')

    self.assertFalse(os.path.isdir(archive_path))
    builder = self.GetBuilder(archive_build=False)
    build_to_deploy = builder.Build(commit_label)
    # No archive. Check that archive_path is not created.
    self.assertNotEqual(archive_path, build_to_deploy)
    self.assertFalse(os.path.isdir(archive_path))

    self.assertEqual(os.path.join('out_%s' % self.BOARD, 'Release'),
                     build_to_deploy)
    self.assertTrue(os.path.isdir(
        os.path.join(self.default_repo_dir, build_to_deploy)))
    gsync_mock.assert_called()
    chrome_sdk_run_mock.assert_called_with(
        ['bash', '-c', 'gn gen out_%s/Release --args="$GN_ARGS"' % self.BOARD],
        run_args=self.log_output_args)
    chrome_sdk_ninja_mock.assert_called_with(run_args=self.log_output_args)

  def testDeploy(self):
    chrome_sdk_run_mock = self.PatchObject(commands.ChromeSDK, 'Run')
    build_to_deploy = os.path.join('out_%s' % self.BOARD, 'Release')
    commit_label = 'test'

    builder = self.GetBuilder()
    builder.Deploy(self.DUT, build_to_deploy, commit_label)
    chrome_sdk_run_mock.assert_called_with(
        ['deploy_chrome', '--build-dir', build_to_deploy, '--force',
         '--device', self.DUT_IP],
        run_args=self.log_output_args)

  def testDeployWithPort(self):
    port = '9999'
    dut = commandline.DeviceParser(commandline.DEVICE_SCHEME_SSH)(
        self.DUT_IP + ':' + port)
    chrome_sdk_run_mock = self.PatchObject(commands.ChromeSDK, 'Run')
    build_to_deploy = os.path.join('out_%s' % self.BOARD, 'Release')
    commit_label = 'test'

    builder = self.GetBuilder()
    builder.Deploy(dut, build_to_deploy, commit_label)
    chrome_sdk_run_mock.assert_called_with(
        ['deploy_chrome', '--build-dir', build_to_deploy, '--force',
         '--device', self.DUT_IP + ':' + port],
        run_args=self.log_output_args)
