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

"""Sysroot service unittest."""

from __future__ import print_function

import os

import mock

from chromite.lib import binpkg
from chromite.lib import build_target_lib
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import cros_test_lib
from chromite.lib import osutils
from chromite.lib import portage_util
from chromite.lib import sysroot_lib
from chromite.lib.parser import package_info
from chromite.service import sysroot


class SetupBoardRunConfigTest(cros_test_lib.TestCase):
  """Tests for the SetupBoardRunConfig class."""

  def testGetUpdateChrootArgs(self):
    """Test the update chroot args conversion method."""
    # False/0/None tests.
    instance = sysroot.SetupBoardRunConfig(usepkg=False, jobs=None,
                                           update_toolchain=False)
    args = instance.GetUpdateChrootArgs()
    self.assertIn('--nousepkg', args)
    self.assertIn('--skip_toolchain_update', args)
    self.assertNotIn('--usepkg', args)
    self.assertNotIn('--jobs', args)

    instance.jobs = 0
    args = instance.GetUpdateChrootArgs()
    self.assertNotIn('--jobs', args)

    # True/set values tests.
    instance = sysroot.SetupBoardRunConfig(usepkg=True, jobs=1,
                                           update_toolchain=True)
    args = instance.GetUpdateChrootArgs()
    self.assertIn('--usepkg', args)
    self.assertIn('--jobs', args)
    self.assertNotIn('--nousepkg', args)
    self.assertNotIn('--skip_toolchain_update', args)


class SetupBoardTest(cros_test_lib.MockTestCase):
  """Tests for SetupBoard."""

  def setUp(self):
    self.PatchObject(cros_build_lib, 'IsInsideChroot', return_value=True)

  def testFullRun(self):
    """Test a regular full run.

    This method is basically just a sanity check that it's trying to create the
    sysroot and install the toolchain by default.
    """
    target_sysroot = sysroot_lib.Sysroot('/build/board')
    create_mock = self.PatchObject(sysroot, 'Create',
                                   return_value=target_sysroot)
    install_toolchain_mock = self.PatchObject(sysroot, 'InstallToolchain')

    sysroot.SetupBoard(build_target_lib.BuildTarget('board'))

    create_mock.assert_called_once()
    install_toolchain_mock.assert_called_once()

  def testRegenConfigs(self):
    """Test the regen configs install prevention."""
    target_sysroot = sysroot_lib.Sysroot('/build/board')
    create_mock = self.PatchObject(sysroot, 'Create',
                                   return_value=target_sysroot)
    install_toolchain_mock = self.PatchObject(sysroot, 'InstallToolchain')

    target = build_target_lib.BuildTarget('board')
    configs = sysroot.SetupBoardRunConfig(regen_configs=True)

    sysroot.SetupBoard(target, run_configs=configs)

    # Should still try to create the sysroot, but should not try to install
    # the toolchain.
    create_mock.assert_called_once()
    install_toolchain_mock.assert_not_called()


class CreateTest(cros_test_lib.RunCommandTempDirTestCase):
  """Create function tests."""

  def setUp(self):
    # Avoid sudo password prompt for config writing.
    self.PatchObject(os, 'getuid', return_value=0)
    self.PatchObject(os, 'geteuid', return_value=0)

    # It has to be run inside the chroot.
    self.PatchObject(cros_build_lib, 'IsInsideChroot', return_value=True)

    # A board we have a sysroot for already.
    self.board = 'board'
    self.sysroot_path = os.path.join(self.tempdir, 'build', self.board)
    self.build_target = build_target_lib.BuildTarget(
        self.board, build_root=self.sysroot_path)
    # A board we don't have a sysroot for yet.
    self.unbuilt_board = 'board2'
    self.unbuilt_path = os.path.join(self.tempdir, 'build', self.unbuilt_board)
    self.unbuilt_target = build_target_lib.BuildTarget(
        self.unbuilt_board, build_root=self.unbuilt_path)

    # Create the sysroot.
    osutils.SafeMakedirs(self.sysroot_path)

  def testUpdateChroot(self):
    """Test the update_chroot related handling."""
    # Prevent it from doing anything else for this test.
    self.PatchObject(sysroot, '_CreateSysrootSkeleton')
    self.PatchObject(sysroot, '_InstallConfigs')
    self.PatchObject(sysroot, '_InstallPortageConfigs')

    # Make sure we have a board we haven't setup to avoid triggering the
    # existing sysroot logic. That is entirely unrelated to the chroot update.
    target = self.unbuilt_target

    # Test no update case.
    config = sysroot.SetupBoardRunConfig(upgrade_chroot=False)
    get_args_patch = self.PatchObject(config, 'GetUpdateChrootArgs')

    sysroot.Create(target, config, None)

    # The update chroot args not being fetched is a
    # strong enough signal that the update wasn't run.
    get_args_patch.assert_not_called()

    # Test update case.
    script_loc = os.path.join(constants.CROSUTILS_DIR, 'update_chroot')
    config = sysroot.SetupBoardRunConfig(upgrade_chroot=True)

    sysroot.Create(target, config, None)

    self.assertCommandContains([script_loc])

  def testForce(self):
    """Test the force flag."""
    # Prevent it from doing anything else for this test.
    self.PatchObject(sysroot, '_CreateSysrootSkeleton')
    self.PatchObject(sysroot, '_InstallConfigs')
    self.PatchObject(sysroot, '_InstallPortageConfigs')

    delete_patch = self.PatchObject(sysroot_lib.Sysroot, 'Delete')

    config = sysroot.SetupBoardRunConfig(force=False)
    sysroot.Create(self.build_target, config, None)
    delete_patch.assert_not_called()

    config = sysroot.SetupBoardRunConfig(force=True)
    sysroot.Create(self.build_target, config, None)
    delete_patch.assert_called_once()


class CreateSimpleChromeSysrootTest(cros_test_lib.MockTempDirTestCase):
  """Tests for CreateSimpleChromeSysroot."""

  def setUp(self):
    self.run_mock = self.PatchObject(cros_build_lib, 'run', return_value=True)
    self.source_root = os.path.join(self.tempdir, 'source_root')
    osutils.SafeMakedirs(self.source_root)
    self.PatchObject(constants, 'SOURCE_ROOT', new=self.source_root)

  def testCreateSimpleChromeSysroot(self):
    # A board for which we will create a simple chrome sysroot.
    target = 'board'
    use_flags = ['cros-debug', 'chrome_internal']

    # Call service, verify arguments passed to run.
    sysroot.CreateSimpleChromeSysroot(target, use_flags)
    self.run_mock.assert_called_with(
        ['cros_generate_sysroot', '--out-dir', mock.ANY, '--board', target,
         '--deps-only', '--package', 'chromeos-base/chromeos-chrome'],
        extra_env={'USE': 'cros-debug chrome_internal'},
        enter_chroot=True,
        cwd=self.source_root
    )


class GenerateArchiveTest(cros_test_lib.MockTempDirTestCase):
  """Tests for GenerateArchive."""

  def setUp(self):
    self.run_mock = self.PatchObject(cros_build_lib, 'run', return_value=True)
    self.chroot_path = os.path.join(self.tempdir, 'chroot_dir')

  def testCreateSimpleChromeSysroot(self):
    # A board for which we will create a simple chrome sysroot.
    target = 'board'
    pkg_list = ['virtual/target-fuzzers']

    # Call service, verify arguments passed to run.
    sysroot.GenerateArchive(self.chroot_path, target, pkg_list)
    self.run_mock.assert_called_with(
        ['cros_generate_sysroot', '--out-file', constants.TARGET_SYSROOT_TAR,
         '--out-dir', mock.ANY, '--board', target,
         '--package', 'virtual/target-fuzzers'],
        cwd=constants.SOURCE_ROOT
    )


class InstallToolchainTest(cros_test_lib.MockTempDirTestCase):
  """Tests for InstallToolchain."""

  def setUp(self):
    self.PatchObject(cros_build_lib, 'IsInsideChroot', return_value=True)
    # A board we have a sysroot for already.
    self.board = 'board'
    self.sysroot_path = os.path.join(self.tempdir, 'build', self.board)
    self.build_target = build_target_lib.BuildTarget(
        self.board, build_root=self.sysroot_path)
    self.sysroot = sysroot_lib.Sysroot(self.sysroot_path)

    # A board we don't have a sysroot for yet.
    self.unbuilt_board = 'board2'
    self.unbuilt_path = os.path.join(self.tempdir, 'build', self.unbuilt_board)
    self.unbuilt_target = build_target_lib.BuildTarget(
        self.unbuilt_board, build_root=self.unbuilt_path)
    self.unbuilt_sysroot = sysroot_lib.Sysroot(self.unbuilt_path)

    osutils.SafeMakedirs(self.sysroot_path)

  def testNoSysroot(self):
    """Test handling of no sysroot."""
    with self.assertRaises(ValueError):
      sysroot.InstallToolchain(self.unbuilt_target, self.unbuilt_sysroot,
                               sysroot.SetupBoardRunConfig())

  def testLocalBuild(self):
    """Test the local build logic."""
    update_patch = self.PatchObject(self.sysroot, 'UpdateToolchain')

    # Test False.
    config = sysroot.SetupBoardRunConfig(usepkg=False, local_build=False)
    sysroot.InstallToolchain(self.build_target, self.sysroot, config)
    update_patch.assert_called_with(self.board, local_init=False)

    # Test usepkg True.
    update_patch.reset_mock()
    config = sysroot.SetupBoardRunConfig(usepkg=True, local_build=False)
    sysroot.InstallToolchain(self.build_target, self.sysroot, config)
    update_patch.assert_called_with(self.board, local_init=True)

    # Test local_build True.
    update_patch.reset_mock()
    config = sysroot.SetupBoardRunConfig(usepkg=False, local_build=True)
    sysroot.InstallToolchain(self.build_target, self.sysroot, config)
    update_patch.assert_called_with(self.board, local_init=True)


class BuildPackagesRunConfigTest(cros_test_lib.TestCase):
  """Tests for the BuildPackagesRunConfig."""

  def AssertHasRequiredArgs(self, args):
    """Tests the default/required args for the builders."""
    self.assertIn('--accept_licenses', args)
    self.assertIn('@CHROMEOS', args)
    self.assertIn('--skip_chroot_upgrade', args)

  def testGetBuildPackagesDefaultArgs(self):
    """Test the build_packages args building for empty/false/0 values."""
    # Test False/None/0 values.
    instance = sysroot.BuildPackagesRunConfig(usepkg=False,
                                              install_debug_symbols=False,
                                              packages=None)

    args = instance.GetBuildPackagesArgs()
    self.AssertHasRequiredArgs(args)
    # Debug symbols not included.
    self.assertNotIn('--withdebugsymbols', args)
    # Source used.
    self.assertIn('--nousepkg', args)
    # Flag removed due to broken logic.  See crbug/1048419.
    self.assertNotIn('--reuse_pkgs_from_local_boards', args)

  def testGetBuildPackagesArgs(self):
    """Test the build_packages args building for non-empty values."""
    packages = ['cat/pkg', 'cat2/pkg2']
    instance = sysroot.BuildPackagesRunConfig(usepkg=True,
                                              install_debug_symbols=True,
                                              packages=packages)

    args = instance.GetBuildPackagesArgs()
    self.AssertHasRequiredArgs(args)
    # Local build not used.
    self.assertNotIn('--nousepkg', args)
    self.assertNotIn('--reuse_pkgs_from_local_boards', args)
    # Debug symbols included.
    self.assertIn('--withdebugsymbols', args)
    # Packages included.
    for package in packages:
      self.assertIn(package, args)

  def testGetBuildPackagesEnv(self):
    """Test the build_packages env."""
    instance = sysroot.BuildPackagesRunConfig()

    # PORTAGE_BINHOST is not set when there are no package_indexes
    self.assertNotIn('PORTAGE_BINHOST', instance.GetEnv())

    # PORTAGE_BINHOST is correctly set when there are package_indexes.
    pkg_indexes = [
        binpkg.PackageIndexInfo(
            build_target=build_target_lib.BuildTarget('board'),
            snapshot_sha='A', location='AAAA'),
        binpkg.PackageIndexInfo(
            build_target=build_target_lib.BuildTarget('board'),
            snapshot_sha='B', location='BBBB')]

    instance = sysroot.BuildPackagesRunConfig(package_indexes=pkg_indexes)

    env = instance.GetEnv()
    self.assertEqual(env.get('PORTAGE_BINHOST'),
                     ' '.join([x.location for x in reversed(pkg_indexes)]))


class BuildPackagesTest(cros_test_lib.RunCommandTestCase):
  """Test BuildPackages function."""

  def setUp(self):
    # Currently just used to keep the parallel emerge status file from being
    # created in the chroot. This probably isn't strictly necessary, but since
    # we can otherwise run this test without a chroot existing at all and
    # without touching the chroot folder, it's better to keep it out of there
    # all together.
    self.PatchObject(cros_build_lib, 'IsInsideChroot', return_value=True)

    self.board = 'board'
    self.target = build_target_lib.BuildTarget(self.board)
    self.sysroot_path = '/sysroot/path'
    self.sysroot = sysroot_lib.Sysroot(self.sysroot_path)

    self.build_packages = os.path.join(constants.CROSUTILS_DIR,
                                       'build_packages')
    self.base_command = [self.build_packages, '--board', self.board,
                         '--board_root', self.sysroot_path]

  def testSuccess(self):
    """Test successful run."""
    config = sysroot.BuildPackagesRunConfig()
    sysroot.BuildPackages(self.target, self.sysroot, config)

    # The rest of the command's args we test in BuildPackagesRunConfigTest,
    # so just make sure we're calling the right command and pass the args not
    # handled by the run config.
    self.assertCommandContains(self.base_command)

  def testPackageFailure(self):
    """Test package failure handling."""
    failed = ['cat/pkg', 'foo/bar']
    cpvs = [package_info.SplitCPV(p, strict=False) for p in failed]
    self.PatchObject(portage_util, 'ParseDieHookStatusFile',
                     return_value=cpvs)

    config = sysroot.BuildPackagesRunConfig()
    command = self.base_command + config.GetBuildPackagesArgs()

    result = cros_build_lib.CommandResult(cmd=command, returncode=1)
    error = cros_build_lib.RunCommandError('Error', result)

    self.rc.AddCmdResult(command, side_effect=error)

    try:
      sysroot.BuildPackages(self.target, self.sysroot, config)
    except sysroot_lib.PackageInstallError as e:
      self.assertEqual(cpvs, e.failed_packages)
      self.assertEqual(result, e.result)
    except Exception as e:
      self.fail('Unexpected exception type: %s' % type(e))
    else:
      self.fail('Expected an exception to be thrown.')
