# -*- coding: utf-8 -*-
# Copyright (c) 2012 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 portage_util.py."""

from __future__ import print_function

import os
import sys

from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import cros_test_lib
from chromite.lib import failures_lib
from chromite.lib import git
from chromite.lib import osutils
from chromite.lib import portage_util


assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'


MANIFEST = git.ManifestCheckout.Cached(constants.SOURCE_ROOT)


# pylint: disable=protected-access


class _Package(object):
  """Package helper class."""

  def __init__(self, package):
    self.package = package


class EBuildTest(cros_test_lib.MockTempDirTestCase):
  """Ebuild related tests."""
  _MULTILINE_WITH_TEST = """
hello
src_test() {
}"""

  _MULTILINE_NO_TEST = """
hello
src_compile() {
}"""

  _MULTILINE_COMMENTED = """
#src_test() {
# notactive
# }"""

  _MULTILINE_PLATFORM = """
platform_pkg_test() {
}"""

  _AUTOTEST_NORMAL = (
      '\n\t+tests_fake_Test1\n\t+tests_fake_Test2\n',
      ('fake_Test1', 'fake_Test2',))

  _AUTOTEST_EXTRA_PLUS = (
      '\n\t++++tests_fake_Test1\n', ('fake_Test1',))

  _AUTOTEST_EXTRA_TAB = (
      '\t\t\n\t\n\t+tests_fake_Test1\tfoo\n', ('fake_Test1',))

  _SINGLE_LINE_TEST = 'src_test() { echo "foo" }'

  _INHERIT_CROS_GO = 'inherit cros-workon cros-go'

  _INHERIT_TAST_BUNDLE = 'inherit tast-bundle'

  _INHERIT_CROS_DEBUG = 'inherit cros-debug'

  _EBUILD_BASE = """
CROS_WORKON_COMMIT=commit1
CROS_WORKON_TREE=("tree1" "tree2")
inherit cros-workon
"""

  _EBUILD_DIFFERENT_COMMIT = """
CROS_WORKON_COMMIT=commit9
CROS_WORKON_TREE=("tree1" "tree2")
inherit cros-workon
"""

  _EBUILD_DIFFERENT_TREE = """
CROS_WORKON_COMMIT=commit1
CROS_WORKON_TREE=("tree9" "tree2")
inherit cros-workon
"""

  _EBUILD_DIFFERENT_CONTENT = """
CROS_WORKON_COMMIT=commit1
CROS_WORKON_TREE=("tree1" "tree2")
inherit cros-workon superpower
"""

  def _MakeFakeEbuild(self, fake_ebuild_path, fake_ebuild_content=''):
    osutils.WriteFile(fake_ebuild_path, fake_ebuild_content, makedirs=True)
    fake_ebuild = portage_util.EBuild(fake_ebuild_path, False)
    return fake_ebuild

  def testParseEBuildPath(self):
    """Test with ebuild with revision number."""
    basedir = os.path.join(self.tempdir, 'cat', 'test_package')
    fake_ebuild_path = os.path.join(basedir, 'test_package-0.0.1-r1.ebuild')
    fake_ebuild = self._MakeFakeEbuild(fake_ebuild_path)

    self.assertEqual(fake_ebuild.category, 'cat')
    self.assertEqual(fake_ebuild.pkgname, 'test_package')
    self.assertEqual(fake_ebuild.version_no_rev, '0.0.1')
    self.assertEqual(fake_ebuild.current_revision, 1)
    self.assertEqual(fake_ebuild.version, '0.0.1-r1')
    self.assertEqual(fake_ebuild.package, 'cat/test_package')
    self.assertEqual(fake_ebuild._ebuild_path_no_version,
                     os.path.join(basedir, 'test_package'))
    self.assertEqual(fake_ebuild.ebuild_path_no_revision,
                     os.path.join(basedir, 'test_package-0.0.1'))
    self.assertEqual(fake_ebuild._unstable_ebuild_path,
                     os.path.join(basedir, 'test_package-9999.ebuild'))
    self.assertEqual(fake_ebuild.ebuild_path, fake_ebuild_path)

  def testParseEBuildPathNoRevisionNumber(self):
    """Test with ebuild without revision number."""
    basedir = os.path.join(self.tempdir, 'cat', 'test_package')
    fake_ebuild_path = os.path.join(basedir, 'test_package-9999.ebuild')
    fake_ebuild = self._MakeFakeEbuild(fake_ebuild_path)

    self.assertEqual(fake_ebuild.category, 'cat')
    self.assertEqual(fake_ebuild.pkgname, 'test_package')
    self.assertEqual(fake_ebuild.version_no_rev, '9999')
    self.assertEqual(fake_ebuild.current_revision, 0)
    self.assertEqual(fake_ebuild.version, '9999')
    self.assertEqual(fake_ebuild.package, 'cat/test_package')
    self.assertEqual(fake_ebuild._ebuild_path_no_version,
                     os.path.join(basedir, 'test_package'))
    self.assertEqual(fake_ebuild.ebuild_path_no_revision,
                     os.path.join(basedir, 'test_package-9999'))
    self.assertEqual(fake_ebuild._unstable_ebuild_path,
                     os.path.join(basedir, 'test_package-9999.ebuild'))
    self.assertEqual(fake_ebuild.ebuild_path, fake_ebuild_path)

  def testGetCommitId(self):
    fake_hash = '24ab3c9f6d6b5c744382dba2ca8fb444b9808e9f'
    basedir = os.path.join(self.tempdir, 'cat', 'test_package')
    fake_ebuild_path = os.path.join(basedir, 'test_package-9999.ebuild')
    fake_ebuild = self._MakeFakeEbuild(fake_ebuild_path)

    # git rev-parse HEAD
    self.PatchObject(
        git, 'RunGit',
        return_value=cros_build_lib.CommandResult(stdout=fake_hash + '\n'))
    test_hash = fake_ebuild.GetCommitId(self.tempdir)
    self.assertEqual(test_hash, fake_hash)

  def testEBuildStable(self):
    """Test ebuild w/keyword variations"""
    basedir = os.path.join(self.tempdir, 'cat', 'test_package')
    fake_ebuild_path = os.path.join(basedir, 'test_package-9999.ebuild')

    datasets = (
        ('~amd64', False),
        ('amd64', True),
        ('~amd64 ~arm ~x86', False),
        ('~amd64 arm ~x86', True),
        ('-* ~arm', False),
        ('-* x86', True),
    )
    for keywords, stable in datasets:
      fake_ebuild = self._MakeFakeEbuild(
          fake_ebuild_path, fake_ebuild_content=['KEYWORDS="%s"\n' % keywords])
      self.assertEqual(fake_ebuild.is_stable, stable)

  def testEBuildBlacklisted(self):
    """Test blacklisted ebuild"""
    basedir = os.path.join(self.tempdir, 'cat', 'test_package')
    fake_ebuild_path = os.path.join(basedir, 'test_package-9999.ebuild')

    fake_ebuild = self._MakeFakeEbuild(fake_ebuild_path)
    self.assertEqual(fake_ebuild.is_blacklisted, False)

    fake_ebuild = self._MakeFakeEbuild(
        fake_ebuild_path, fake_ebuild_content=['CROS_WORKON_BLACKLIST="1"\n'])
    self.assertEqual(fake_ebuild.is_blacklisted, True)

  def testHasTest(self):
    """Tests that we detect test stanzas correctly."""
    def run_case(content, expected):
      with osutils.TempDir() as temp:
        ebuild = os.path.join(temp, 'overlay', 'app-misc',
                              'foo-0.0.1-r1.ebuild')
        osutils.WriteFile(ebuild, content, makedirs=True)
        self.assertEqual(expected, portage_util.EBuild(ebuild, False).has_test)

    run_case(self._MULTILINE_WITH_TEST, True)
    run_case(self._MULTILINE_NO_TEST, False)
    run_case(self._MULTILINE_COMMENTED, False)
    run_case(self._MULTILINE_PLATFORM, True)
    run_case(self._SINGLE_LINE_TEST, True)
    run_case(self._INHERIT_CROS_GO, True)
    run_case(self._INHERIT_TAST_BUNDLE, True)
    run_case(self._INHERIT_CROS_DEBUG, False)

  def testCheckHasTestWithoutEbuild(self):
    """Test CheckHasTest on a package without ebuild config file"""
    package_name = 'chromeos-base/temp_mypackage'
    package_path = os.path.join(self.tempdir, package_name)
    os.makedirs(package_path)
    with self.assertRaises(failures_lib.PackageBuildFailure):
      portage_util._CheckHasTest(self.tempdir, package_name)

  def testEBuildGetAutotestTests(self):
    """Test extraction of test names from IUSE_TESTS variable.

    Used for autotest ebuilds.
    """

    def run_case(tests_str, results):
      settings = {'IUSE_TESTS' : tests_str}
      self.assertEqual(
          portage_util.EBuild._GetAutotestTestsFromSettings(settings), results)

    run_case(self._AUTOTEST_NORMAL[0], list(self._AUTOTEST_NORMAL[1]))
    run_case(self._AUTOTEST_EXTRA_PLUS[0], list(self._AUTOTEST_EXTRA_PLUS[1]))
    run_case(self._AUTOTEST_EXTRA_TAB[0], list(self._AUTOTEST_EXTRA_TAB[1]))

  def testAlmostSameEBuilds(self):
    """Test _AlmostSameEBuilds()."""
    def AlmostSameEBuilds(ebuild1_contents, ebuild2_contents):
      ebuild1_path = os.path.join(self.tempdir, 'a.ebuild')
      ebuild2_path = os.path.join(self.tempdir, 'b.ebuild')
      osutils.WriteFile(ebuild1_path, ebuild1_contents)
      osutils.WriteFile(ebuild2_path, ebuild2_contents)
      return portage_util.EBuild._AlmostSameEBuilds(ebuild1_path, ebuild2_path)

    self.assertTrue(
        AlmostSameEBuilds(self._EBUILD_BASE, self._EBUILD_BASE))
    self.assertTrue(
        AlmostSameEBuilds(self._EBUILD_BASE, self._EBUILD_DIFFERENT_COMMIT))
    self.assertFalse(
        AlmostSameEBuilds(self._EBUILD_BASE, self._EBUILD_DIFFERENT_TREE))
    self.assertFalse(
        AlmostSameEBuilds(self._EBUILD_BASE, self._EBUILD_DIFFERENT_CONTENT))

  def testClassifySimple(self):
    """Test Classify on a simple ebuild."""
    ebuild_path = os.path.join(self.tempdir, 'foo-1.ebuild')
    osutils.WriteFile(ebuild_path, '')
    attrs = portage_util.EBuild.Classify(ebuild_path)
    self.assertFalse(attrs.is_workon)
    self.assertFalse(attrs.is_stable)
    self.assertFalse(attrs.is_blacklisted)
    self.assertFalse(attrs.has_test)

  def testClassifyUnstable(self):
    """Test Classify handling of non-stable KEYWORDS."""
    ebuild_path = os.path.join(self.tempdir, 'foo-1.ebuild')
    TESTS = (
        'KEYWORDS=',
        'KEYWORDS= # Yep.',
        'KEYWORDS="-*"',
        'KEYWORDS="-* ~arm"',
        'KEYWORDS="~*"',
    )
    for keywords in TESTS:
      osutils.WriteFile(ebuild_path, keywords)
      attrs = portage_util.EBuild.Classify(ebuild_path)
      self.assertFalse(attrs.is_stable, msg='Failing: %s' % (keywords,))

  def testClassifyStable(self):
    """Test Classify handling of stable KEYWORDS."""
    ebuild_path = os.path.join(self.tempdir, 'foo-1.ebuild')
    TESTS = (
        'KEYWORDS="*"',
        'KEYWORDS="*" # Yep.',
        'KEYWORDS="-* arm"',
    )
    for keywords in TESTS:
      osutils.WriteFile(ebuild_path, keywords)
      attrs = portage_util.EBuild.Classify(ebuild_path)
      self.assertTrue(attrs.is_stable, msg='Failing: %s' % (keywords,))

  def testClassifyEncodingASCII(self):
    """Test Classify with ASCII file encodings."""
    ebuild_path = os.path.join(self.tempdir, 'foo-1.ebuild')
    # Generate a valid shell script with all possible ASCII values.
    osutils.WriteFile(
        ebuild_path,
        'cat <<\\EOF\n%s\nEOF\n' % (''.join(chr(x) for x in range(0, 128)),))
    # Just check that we don't throw an exception.
    portage_util.EBuild.Classify(ebuild_path)

  def testClassifyEncodingUTF8(self):
    """Test Classify with UTF-8 file encodings."""
    ebuild_path = os.path.join(self.tempdir, 'foo-1.ebuild')
    osutils.WriteFile(ebuild_path, u'# FöÖßbäłł')
    # Just check that we don't throw an exception.
    portage_util.EBuild.Classify(ebuild_path)

  def testClassifyEncodingLatin1(self):
    """Test Classify with ISO 8859-1 file encodings."""
    ebuild_path = os.path.join(self.tempdir, 'foo-1.ebuild')
    osutils.WriteFile(ebuild_path, b'# This is \xa0 bad UTF-8', mode='wb')
    with self.assertRaises(UnicodeDecodeError):
      portage_util.EBuild.Classify(ebuild_path)


class ProjectAndPathTest(cros_test_lib.MockTempDirTestCase):
  """Project and Path related tests."""

  def _MockParseWorkonVariables(self, fake_projects, fake_srcpaths,
                                fake_localnames, fake_ebuild_contents):
    """Mock the necessary calls, call GetSourceInfo()."""

    def _isdir(path):
      """Mock function for os.path.isdir"""
      if any(fake_srcpaths):
        if path == os.path.join(self.tempdir, 'src'):
          return True

      for srcpath in fake_srcpaths:
        if srcpath:
          if path == os.path.join(self.tempdir, 'src', srcpath):
            return True
        else:
          for localname in fake_localnames:
            if path == os.path.join(self.tempdir, localname):
              return False
            elif path == os.path.join(self.tempdir, 'platform', localname):
              return True

      raise Exception('unhandled path: %s' % path)

    def _FindCheckoutFromPath(path):
      """Mock function for manifest.FindCheckoutFromPath"""
      for project, localname in zip(fake_projects, fake_localnames):
        if path == os.path.join(self.tempdir, 'platform', localname):
          return {'name': project, 'local_path': localname}
      return {}

    self.PatchObject(os.path, 'isdir', side_effect=_isdir)
    self.PatchObject(MANIFEST, 'FindCheckoutFromPath',
                     side_effect=_FindCheckoutFromPath)

    if not fake_srcpaths:
      fake_srcpaths = [''] * len(fake_projects)
    if not fake_projects:
      fake_projects = [''] * len(fake_srcpaths)

    # We need 'chromeos-base' here because it controls default _SUBDIR values.
    ebuild_path = os.path.join(self.tempdir, 'packages', 'chromeos-base',
                               'package', 'package-9999.ebuild')
    osutils.WriteFile(ebuild_path, fake_ebuild_contents, makedirs=True)

    ebuild = portage_util.EBuild(ebuild_path, False)
    return ebuild.GetSourceInfo(self.tempdir, MANIFEST)

  def testParseLegacyWorkonVariables(self):
    """Tests if ebuilds in a single item format are correctly parsed."""
    fake_project = 'my_project1'
    fake_localname = 'foo'
    fake_ebuild_contents = """
CROS_WORKON_PROJECT=%s
CROS_WORKON_LOCALNAME=%s
    """ % (fake_project, fake_localname)
    info = self._MockParseWorkonVariables(
        [fake_project], [], [fake_localname], fake_ebuild_contents)
    self.assertEqual(info.projects, [fake_project])
    self.assertEqual(info.srcdirs, [os.path.join(
        self.tempdir, 'platform', fake_localname)])
    self.assertEqual(info.subtrees, [os.path.join(
        self.tempdir, 'platform', fake_localname)])

  def testParseAlwaysLive(self):
    """Tests if an ebuild which is always live is correctly handled."""
    fake_project = 'my_project1'
    fake_localname = 'foo'
    fake_ebuild_contents = """
CROS_WORKON_PROJECT=%s
CROS_WORKON_LOCALNAME=%s
CROS_WORKON_ALWAYS_LIVE=1
    """ % (fake_project, fake_localname)
    info = self._MockParseWorkonVariables(
        [fake_project], [], [fake_localname], fake_ebuild_contents)
    self.assertEqual(info.projects, [])
    self.assertEqual(info.srcdirs, [])
    self.assertEqual(info.srcdirs, [])
    self.assertEqual(info.subtrees, [])

  def testParseArrayWorkonVariables(self):
    """Tests if ebuilds in an array format are correctly parsed."""
    fake_projects = ['my_project1', 'my_project2', 'my_project3']
    fake_localnames = ['foo', 'bar', 'bas']
    # The test content is formatted using the same function that
    # formats ebuild output, ensuring that we can parse our own
    # products.
    fake_ebuild_contents = """
CROS_WORKON_PROJECT=%s
CROS_WORKON_LOCALNAME=%s
    """ % (portage_util.EBuild.FormatBashArray(fake_projects),
           portage_util.EBuild.FormatBashArray(fake_localnames))
    info = self._MockParseWorkonVariables(
        fake_projects, [], fake_localnames, fake_ebuild_contents)
    self.assertEqual(info.projects, fake_projects)
    fake_paths = [
        os.path.realpath(os.path.join(self.tempdir, 'platform', x))
        for x in fake_localnames
    ]
    self.assertEqual(info.srcdirs, fake_paths)
    self.assertEqual(info.subtrees, fake_paths)

  def testParseArrayWorkonVariablesWithSrcpaths(self):
    """Tests if ebuilds with CROS_WORKON_SRCPATH are handled correctly."""
    fake_projects = ['my_project1', '', '']
    fake_srcpaths = ['', 'path/to/src', 'path/to/other/src']
    fake_localnames = ['foo', 'bar', 'bas']
    # The test content is formatted using the same function that
    # formats ebuild output, ensuring that we can parse our own
    # products.
    fake_ebuild_contents = """
CROS_WORKON_PROJECT=%s
CROS_WORKON_SRCPATH=%s
CROS_WORKON_LOCALNAME=%s
    """ % (portage_util.EBuild.FormatBashArray(fake_projects),
           portage_util.EBuild.FormatBashArray(fake_srcpaths),
           portage_util.EBuild.FormatBashArray(fake_localnames))
    info = self._MockParseWorkonVariables(
        fake_projects, fake_srcpaths, fake_localnames, fake_ebuild_contents)
    self.assertEqual(info.projects, fake_projects)
    fake_paths = []
    for srcpath, localname in zip(fake_srcpaths, fake_localnames):
      if srcpath:
        path = os.path.realpath(os.path.join(self.tempdir, 'src', srcpath))
      else:
        path = os.path.realpath(os.path.join(
            self.tempdir, 'platform', localname))
      fake_paths.append(path)

    self.assertEqual(info.srcdirs, fake_paths)
    self.assertEqual(info.subtrees, fake_paths)

  def testParseArrayWorkonVariablesWithSubtrees(self):
    """Tests if ebuilds with CROS_WORKON_SUBTREE are handled correctly."""
    fake_project = 'my_project1'
    fake_localname = 'foo/bar'
    fake_subtrees = 'test baz/quz'
    # The test content is formatted using the same function that
    # formats ebuild output, ensuring that we can parse our own
    # products.
    fake_ebuild_contents = """
CROS_WORKON_PROJECT=%s
CROS_WORKON_LOCALNAME=%s
CROS_WORKON_SUBTREE="%s"
    """ % (fake_project, fake_localname, fake_subtrees)
    info = self._MockParseWorkonVariables(
        [fake_project], [], [fake_localname], fake_ebuild_contents)
    self.assertEqual(info.projects, [fake_project])
    self.assertEqual(info.srcdirs, [os.path.join(
        self.tempdir, 'platform', fake_localname)])
    self.assertEqual(info.subtrees, [
        os.path.join(self.tempdir, 'platform', 'foo/bar/test'),
        os.path.join(self.tempdir, 'platform', 'foo/bar/baz/quz')])


class StubEBuild(portage_util.EBuild):
  """Test helper to StubEBuild."""

  def __init__(self, path, subdir_support):
    super(StubEBuild, self).__init__(path, subdir_support)
    self.is_workon = True
    self.is_stable = True

  def _ReadEBuild(self, path):
    pass

  def GetCommitId(self, srcdir):
    id_map = {
        'p1_path1': 'my_id1',
        'p1_path2': 'my_id2'
    }
    if srcdir in id_map:
      return id_map[srcdir]
    else:
      return 'you_lose'


class EBuildRevWorkonTest(cros_test_lib.MockTempDirTestCase):
  """Tests for EBuildRevWorkon."""

  # Lines that we will feed as fake ebuild contents to
  # EBuild.MarAsStable().  This is the minimum content needed
  # to test the various branches in the function's main processing
  # loop.
  _mock_ebuild = ['EAPI=2\n',
                  'CROS_WORKON_COMMIT=old_id\n',
                  'CROS_WORKON_PROJECT=test_package\n',
                  'KEYWORDS="~x86 ~arm ~amd64"\n',
                  'src_unpack(){}\n']
  _mock_ebuild_multi = ['EAPI=2\n',
                        'CROS_WORKON_COMMIT=("old_id1","old_id2")\n',
                        'KEYWORDS="~x86 ~arm ~amd64"\n',
                        'src_unpack(){}\n']
  _mock_ebuild_subdir = ['EAPI=5\n',
                         'CROS_WORKON_COMMIT=old_id\n',
                         'CROS_WORKON_PROJECT=test_package\n',
                         'CROS_WORKON_SUBDIRS_TO_REV=( foo )\n'
                         'KEYWORDS="~x86 ~arm ~amd64"\n',
                         'src_unpack(){}\n']
  _revved_ebuild = ('EAPI=2\n'
                    'CROS_WORKON_COMMIT="my_id1"\n'
                    'CROS_WORKON_TREE=("treehash1a" "treehash1b")\n'
                    'CROS_WORKON_PROJECT=test_package\n'
                    'KEYWORDS="x86 arm amd64"\n'
                    'src_unpack(){}\n')
  _revved_ebuild_multi = (
      'EAPI=2\n'
      'CROS_WORKON_COMMIT=("my_id1" "my_id2")\n'
      'CROS_WORKON_TREE=("treehash1a" "treehash1b" "treehash2")\n'
      'KEYWORDS="x86 arm amd64"\n'
      'src_unpack(){}\n')
  _revved_ebuild_subdir = ('EAPI=5\n'
                           'CROS_WORKON_COMMIT="my_id1"\n'
                           'CROS_WORKON_TREE=("treehash1a" "treehash1b")\n'
                           'CROS_WORKON_PROJECT=test_package\n'
                           'CROS_WORKON_SUBDIRS_TO_REV=( foo )\n'
                           'KEYWORDS="x86 arm amd64"\n'
                           'src_unpack(){}\n')

  unstable_ebuild_changed = False

  def setUp(self):
    self.overlay = os.path.join(self.tempdir, 'overlay')
    package_name = os.path.join(self.overlay,
                                'category/test_package/test_package-0.0.1')
    ebuild_path = package_name + '-r1.ebuild'
    self.m_ebuild = StubEBuild(ebuild_path, False)
    self.revved_ebuild_path = package_name + '-r2.ebuild'
    self.git_files_changed = []

  def createRevWorkOnMocks(self, ebuild_content, rev, multi=False):
    """Creates a mock environment to run RevWorkOnEBuild.

    Args:
      ebuild_content: The content of the ebuild that will be revved.
      rev: Tell _RunGit whether this is attempt an attempt to rev an ebuild.
      multi: Whether there are multiple projects to uprev.
    """
    def _GetTreeId(path):
      """Mock function for portage_util.EBuild.GetTreeId"""
      return {
          'p1_path1/a': 'treehash1a',
          'p1_path1/b': 'treehash1b',
          'p1_path2': 'treehash2',
      }.get(path)

    def _RunGit(cwd, cmd):
      """Mock function for portage_util.EBuild._RunGit"""
      if cmd[0] == 'log':
        # special case for git log in the overlay:
        # report if -9999.ebuild supposedly changed
        if cwd == self.overlay and self.unstable_ebuild_changed:
          return 'someebuild-9999.ebuild'

        file_list = cmd[cmd.index('--') + 1:]
        # Just get the last path component so we can specify the file_list
        # without concerning outselves with tempdir
        file_list = [os.path.split(f)[1] for f in file_list]
        # Return a dummy file if we have changes in any of the listed files.
        if set(self.git_files_changed).intersection(file_list):
          return 'somefile'
        return ''
      self.assertEqual(cwd, self.overlay)
      self.assertTrue(rev, msg='git should not be run when not revving')
      if cmd[0] == 'add':
        self.assertEqual(cmd, ['add', self.revved_ebuild_path])
      else:
        self.assertTrue(self.m_ebuild.is_stable)
        self.assertEqual(cmd, ['rm', '-f', self.m_ebuild.ebuild_path])

    source_mock = self.PatchObject(portage_util.EBuild, 'GetSourceInfo')
    if multi:
      source_mock.return_value = portage_util.SourceInfo(
          projects=['fake_project1', 'fake_project2'],
          srcdirs=['p1_path1', 'p1_path2'],
          subdirs=['files', None],
          subtrees=['p1_path1/a', 'p1_path1/b', 'p1_path2'])
    else:
      source_mock.return_value = portage_util.SourceInfo(
          projects=['fake_project1'],
          srcdirs=['p1_path1'],
          subdirs=['files', None],
          subtrees=['p1_path1/a', 'p1_path1/b'])

    self.PatchObject(portage_util.EBuild, 'GetTreeId', side_effect=_GetTreeId)
    self.PatchObject(portage_util.EBuild, '_RunGit', side_effect=_RunGit)

    osutils.WriteFile(self.m_ebuild._unstable_ebuild_path, ebuild_content,
                      makedirs=True)
    osutils.WriteFile(self.m_ebuild.ebuild_path, ebuild_content, makedirs=True)

  def testRevWorkOnEBuild(self):
    """Test Uprev of a single project ebuild."""
    self.createRevWorkOnMocks(self._mock_ebuild, rev=True)
    result = self.m_ebuild.RevWorkOnEBuild(self.tempdir, MANIFEST)
    self.assertEqual(result[0], 'category/test_package-0.0.1-r2')
    self.assertExists(self.revved_ebuild_path)
    self.assertEqual(self._revved_ebuild,
                     osutils.ReadFile(self.revved_ebuild_path))

  def testRevUnchangedEBuildSubdirsNoChange(self):
    """Test Uprev of a single-project ebuild with CROS_WORKON_SUBDIRS_TO_REV.

    No files changed in git, so this should not uprev.
    """
    self.createRevWorkOnMocks(self._mock_ebuild_subdir, rev=False)
    self.m_ebuild.cros_workon_vars = portage_util.EBuild.GetCrosWorkonVars(
        self.m_ebuild.ebuild_path, 'test-package')
    result = self.m_ebuild.RevWorkOnEBuild(self.tempdir, MANIFEST)
    self.assertIsNone(result)
    self.assertNotExists(self.revved_ebuild_path)

  def testRevUnchangedEBuildSubdirsChange(self):
    """Test Uprev of a single-project ebuild with CROS_WORKON_SUBDIRS_TO_REV.

    The 'foo' directory is changed in git, and this directory is mentioned in
    CROS_WORKON_SUBDIRS_TO_REV, so this should uprev.
    """
    self.git_files_changed = ['foo']
    self.createRevWorkOnMocks(self._mock_ebuild_subdir, rev=True)
    self.m_ebuild.cros_workon_vars = portage_util.EBuild.GetCrosWorkonVars(
        self.m_ebuild.ebuild_path, 'test-package')
    result = self.m_ebuild.RevWorkOnEBuild(self.tempdir, MANIFEST)
    self.assertEqual(result[0], 'category/test_package-0.0.1-r2')
    self.assertExists(self.revved_ebuild_path)
    self.assertEqual(self._revved_ebuild_subdir,
                     osutils.ReadFile(self.revved_ebuild_path))

  def testRevChangedEBuildFilesChanged(self):
    """Test Uprev of a single-project ebuild whose files/ content has changed.

    The 'files' directory is changed in git and some other directory is
    mentioned in CROS_WORKON_SUBDIRS_TO_REV. files/ should always force uprev.
    """
    self.git_files_changed = ['files']
    self.createRevWorkOnMocks(self._mock_ebuild_subdir, rev=True)
    self.m_ebuild.cros_workon_vars = portage_util.EBuild.GetCrosWorkonVars(
        self.m_ebuild.ebuild_path, 'test-package')
    result = self.m_ebuild.RevWorkOnEBuild(self.tempdir, MANIFEST)
    self.assertEqual(result[0], 'category/test_package-0.0.1-r2')
    self.assertExists(self.revved_ebuild_path)
    self.assertEqual(self._revved_ebuild_subdir,
                     osutils.ReadFile(self.revved_ebuild_path))

  def testRevUnchangedEBuildFilesChanged(self):
    """Test Uprev of a single-project ebuild whose files/ content has changed.

    The 'files' directory is changed in git and some other directory is
    mentioned in CROS_WORKON_SUBDIRS_TO_REV. files/ should always force uprev.
    """
    self.git_files_changed = ['files']
    self.createRevWorkOnMocks(self._mock_ebuild_subdir, rev=False)
    self.m_ebuild.cros_workon_vars = portage_util.EBuild.GetCrosWorkonVars(
        self.m_ebuild.ebuild_path, 'test-package')
    result = self.m_ebuild.RevWorkOnEBuild(self.tempdir, MANIFEST)
    self.assertEqual(result[0], 'category/test_package-0.0.1-r2')
    self.assertExists(self.revved_ebuild_path)
    self.assertEqual(self._revved_ebuild_subdir,
                     osutils.ReadFile(self.revved_ebuild_path))

  def testRevUnchangedEBuildOtherSubdirChange(self):
    """Uprev an other subdir with no CROS_WORKON_SUBDIRS_TO_REV.

    The 'other' directory is changed in git, but there is no
    CROS_WORKON_SUBDIRS_TO_REV in the build, so any change causes an uprev.
    """
    self.git_files_changed = ['other']
    self.createRevWorkOnMocks(self._mock_ebuild, rev=True)
    self.m_ebuild.cros_workon_vars = portage_util.EBuild.GetCrosWorkonVars(
        self.m_ebuild.ebuild_path, 'test-package')
    result = self.m_ebuild.RevWorkOnEBuild(self.tempdir, MANIFEST)
    self.assertEqual(result[0], 'category/test_package-0.0.1-r2')
    self.assertExists(self.revved_ebuild_path)
    self.assertEqual(self._revved_ebuild,
                     osutils.ReadFile(self.revved_ebuild_path))

  def testNoRevUnchangedEBuildOtherSubdirChange(self):
    """Uprev an other subdir with no CROS_WORKON_SUBDIRS_TO_REV.

    The 'other' directory is changed in git, but CROS_WORKON_SUBDIRS_TO_REV
    is empty, so this should not uprev.
    """
    self.git_files_changed = ['other']
    self.createRevWorkOnMocks(self._mock_ebuild_subdir, rev=False)
    self.m_ebuild.cros_workon_vars = portage_util.EBuild.GetCrosWorkonVars(
        self.m_ebuild.ebuild_path, 'test-package')
    result = self.m_ebuild.RevWorkOnEBuild(self.tempdir, MANIFEST)
    self.assertIsNone(result)
    self.assertNotExists(self.revved_ebuild_path)

  def testRevChangedEBuildNoSubdirChange(self):
    """Uprev a changed ebuild with CROS_WORKON_SUBDIRS_TO_REV.

    Any change to the 9999 ebuild should cause an uprev, even if
    CROS_WORKON_SUBDIRS_TO_REV is set and no files in that list are changed in
    git.
    """
    self.unstable_ebuild_changed = True
    self.createRevWorkOnMocks(self._mock_ebuild_subdir, rev=True)
    self.m_ebuild.cros_workon_vars = portage_util.EBuild.GetCrosWorkonVars(
        self.m_ebuild.ebuild_path, 'test-package')
    result = self.m_ebuild.RevWorkOnEBuild(self.tempdir, MANIFEST)
    self.assertEqual(result[0], 'category/test_package-0.0.1-r2')
    self.assertExists(self.revved_ebuild_path)
    self.assertEqual(self._revved_ebuild_subdir,
                     osutils.ReadFile(self.revved_ebuild_path))

  def testRevWorkOnMultiEBuild(self):
    """Test Uprev of a multi-project (array) ebuild."""
    self.createRevWorkOnMocks(self._mock_ebuild_multi, rev=True, multi=True)
    result = self.m_ebuild.RevWorkOnEBuild(self.tempdir, MANIFEST)
    self.assertEqual(result[0], 'category/test_package-0.0.1-r2')
    self.assertExists(self.revved_ebuild_path)
    self.assertEqual(self._revved_ebuild_multi,
                     osutils.ReadFile(self.revved_ebuild_path))

  def testRevUnchangedEBuild(self):
    self.createRevWorkOnMocks(self._mock_ebuild, rev=False)

    self.PatchObject(
        portage_util.EBuild, '_AlmostSameEBuilds', return_value=True)
    result = self.m_ebuild.RevWorkOnEBuild(self.tempdir, MANIFEST)
    self.assertIsNone(result)
    self.assertNotExists(self.revved_ebuild_path)

  def testRevMissingEBuild(self):
    self.revved_ebuild_path = self.m_ebuild.ebuild_path
    self.m_ebuild.ebuild_path = self.m_ebuild._unstable_ebuild_path
    self.m_ebuild.current_revision = 0
    self.m_ebuild.is_stable = False

    self.createRevWorkOnMocks(self._mock_ebuild[0:1] + self._mock_ebuild[2:],
                              rev=True)
    result = self.m_ebuild.RevWorkOnEBuild(self.tempdir, MANIFEST)

    self.assertEqual(result[0], 'category/test_package-0.0.1-r1')
    self.assertExists(self.revved_ebuild_path)
    self.assertEqual(self._revved_ebuild,
                     osutils.ReadFile(self.revved_ebuild_path))

  def testCommitChange(self):
    m = self.PatchObject(portage_util.EBuild, '_RunGit', return_value='')
    mock_message = 'Commitme'
    self.m_ebuild.CommitChange(mock_message, '.')
    m.assert_called_once_with('.', ['commit', '-a', '-m', 'Commitme'])

  def testGitRepoHasChanges(self):
    """Tests that GitRepoHasChanges works correctly."""
    git.RunGit(self.tempdir,
               ['clone', '--depth=1', constants.CHROMITE_DIR, self.tempdir])
    # No changes yet as we just cloned the repo.
    self.assertFalse(portage_util.EBuild.GitRepoHasChanges(self.tempdir))
    # Update metadata but no real changes.
    osutils.Touch(os.path.join(self.tempdir, 'LICENSE'))
    self.assertFalse(portage_util.EBuild.GitRepoHasChanges(self.tempdir))
    # A real change.
    osutils.WriteFile(os.path.join(self.tempdir, 'LICENSE'), 'hi')
    self.assertTrue(portage_util.EBuild.GitRepoHasChanges(self.tempdir))

  def testNoVersionScript(self):
    """Verify default behavior with no chromeos-version.sh script."""
    self.assertEqual('1234', self.m_ebuild.GetVersion(None, None, '1234'))

  def testValidVersionScript(self):
    """Verify normal behavior with a chromeos-version.sh script."""
    exists = self.PatchObject(os.path, 'exists', return_value=True)
    self.PatchObject(portage_util.EBuild, 'GetSourceInfo',
                     return_value=portage_util.SourceInfo(
                         projects=None, srcdirs=[], subdirs=[], subtrees=[]))
    self.PatchObject(cros_build_lib, 'run',
                     return_value=cros_build_lib.CommandResult(
                         returncode=0, output='1122', error='STDERR'))
    self.assertEqual('1122', self.m_ebuild.GetVersion(None, None, '1234'))
    # Sanity check.
    self.assertEqual(exists.call_count, 1)

  def testVersionScriptNoOutput(self):
    """Reject scripts that output nothing."""
    exists = self.PatchObject(os.path, 'exists', return_value=True)
    self.PatchObject(portage_util.EBuild, 'GetSourceInfo',
                     return_value=portage_util.SourceInfo(
                         projects=None, srcdirs=[], subdirs=[], subtrees=[]))
    run = self.PatchObject(cros_build_lib, 'run')

    # Reject no output.
    run.return_value = cros_build_lib.CommandResult(
        returncode=0, output='', error='STDERR')
    self.assertRaises(portage_util.Error,
                      self.m_ebuild.GetVersion, None, None, '1234')
    # Sanity check.
    self.assertEqual(exists.call_count, 1)
    exists.reset_mock()

    # Reject simple output.
    run.return_value = cros_build_lib.CommandResult(
        returncode=0, output='\n', error='STDERR')
    self.assertRaises(portage_util.Error,
                      self.m_ebuild.GetVersion, None, None, '1234')
    # Sanity check.
    self.assertEqual(exists.call_count, 1)
    exists.reset_mock()

    # Reject error.
    run.return_value = cros_build_lib.CommandResult(
        returncode=1, output='FAIL\n', error='STDERR')
    self.assertRaises(portage_util.Error,
                      self.m_ebuild.GetVersion, None, None, '1234')
    # Sanity check.
    self.assertEqual(exists.call_count, 1)

  def testVersionScriptTooHighVersion(self):
    """Reject scripts that output high version numbers."""
    exists = self.PatchObject(os.path, 'exists', return_value=True)
    self.PatchObject(portage_util.EBuild, 'GetSourceInfo',
                     return_value=portage_util.SourceInfo(
                         projects=None, srcdirs=[], subdirs=[], subtrees=[]))
    self.PatchObject(cros_build_lib, 'run',
                     return_value=cros_build_lib.CommandResult(
                         returncode=0, output='999999', error='STDERR'))
    self.assertRaises(ValueError, self.m_ebuild.GetVersion, None, None, '1234')
    # Sanity check.
    self.assertEqual(exists.call_count, 1)

  def testVersionScriptInvalidVersion(self):
    """Reject scripts that output bad version numbers."""
    exists = self.PatchObject(os.path, 'exists', return_value=True)
    self.PatchObject(portage_util.EBuild, 'GetSourceInfo',
                     return_value=portage_util.SourceInfo(
                         projects=None, srcdirs=[], subdirs=[], subtrees=[]))
    self.PatchObject(cros_build_lib, 'run',
                     return_value=cros_build_lib.CommandResult(
                         returncode=0, output='abcd', error='STDERR'))
    self.assertRaises(ValueError, self.m_ebuild.GetVersion, None, None, '1234')
    # Sanity check.
    self.assertEqual(exists.call_count, 1)

  def testVersionScriptInvalidVersionPostfix(self):
    """Reject scripts that output bad version numbers."""
    exists = self.PatchObject(os.path, 'exists', return_value=True)
    self.PatchObject(
        portage_util.EBuild,
        'GetSourceInfo',
        return_value=portage_util.SourceInfo(
            projects=None, srcdirs=[], subdirs=[], subtrees=[]))
    self.PatchObject(
        cros_build_lib,
        'run',
        return_value=cros_build_lib.CommandResult(
            returncode=0, output='4.4.21_baseline', error='STDERR'))
    with self.assertRaises(portage_util.EbuildVersionError):
      self.m_ebuild.GetVersion(None, None, '1234')
    # Sanity check.
    self.assertEqual(exists.call_count, 1)

  def testUpdateEBuildRecovery(self):
    """Make sure UpdateEBuild can be called more than once even w/failures."""
    ebuild = os.path.join(self.tempdir, 'test.ebuild')
    content = '# Some data\nVAR=val\n'
    osutils.WriteFile(ebuild, content)

    # First run: pass in an invalid redirect file to trigger an exception.
    try:
      portage_util.EBuild.UpdateEBuild(ebuild, [])
      self.fail('this should have thrown an exception')
    except Exception:
      pass
    self.assertEqual(content, osutils.ReadFile(ebuild))

    # Second run: it should pass normally.
    portage_util.EBuild.UpdateEBuild(ebuild, {'VAR': 'b'})


class ListOverlaysTest(cros_test_lib.TempDirTestCase):
  """Tests related to listing overlays."""

  def testMissingOverlays(self):
    """Tests that exceptions are raised when an overlay is missing."""
    self.assertRaises(portage_util.MissingOverlayError,
                      portage_util._ListOverlays,
                      board='foo', buildroot=self.tempdir)


class FindOverlaysTest(cros_test_lib.MockTempDirTestCase):
  """Tests related to finding overlays."""

  FAKE, PUB_PRIV, PUB_PRIV_VARIANT, PUB_ONLY, PUB2_ONLY, PRIV_ONLY = (
      'fake!board', 'pub-priv-board', 'pub-priv-board_variant',
      'pub-only-board', 'pub2-only-board', 'priv-only-board',
  )
  PRIVATE = constants.PRIVATE_OVERLAYS
  PUBLIC = constants.PUBLIC_OVERLAYS
  BOTH = constants.BOTH_OVERLAYS

  def setUp(self):
    # Create an overlay tree to run tests against and isolate ourselves from
    # changes in the main tree.
    D = cros_test_lib.Directory
    overlay_files = (D('metadata', ('layout.conf',)),)
    board_overlay_files = overlay_files + (
        'make.conf',
        'toolchain.conf',
    )
    file_layout = (
        D('src', (
            D('overlays', (
                D('overlay-%s' % self.PUB_ONLY, board_overlay_files),
                D('overlay-%s' % self.PUB2_ONLY, board_overlay_files),
                D('overlay-%s' % self.PUB_PRIV, board_overlay_files),
                D('overlay-%s' % self.PUB_PRIV_VARIANT, board_overlay_files),
            )),
            D('private-overlays', (
                D('overlay-%s' % self.PUB_PRIV, board_overlay_files),
                D('overlay-%s' % self.PUB_PRIV_VARIANT, board_overlay_files),
                D('overlay-%s' % self.PRIV_ONLY, board_overlay_files),
            )),
            D('third_party', (
                D('chromiumos-overlay', overlay_files),
                D('portage-stable', overlay_files),
            )),
        )),
    )
    cros_test_lib.CreateOnDiskHierarchy(self.tempdir, file_layout)

    # Seed the board overlays.
    conf_data = 'repo-name = %(repo-name)s\nmasters = %(masters)s'
    conf_path = os.path.join(self.tempdir, 'src', '%(private)soverlays',
                             'overlay-%(board)s', 'metadata', 'layout.conf')

    for board in (self.PUB_PRIV, self.PUB_PRIV_VARIANT, self.PUB_ONLY,
                  self.PUB2_ONLY):
      settings = {
          'board': board,
          'masters': 'portage-stable ',
          'private': '',
          'repo-name': board,
      }
      if '_' in board:
        settings['masters'] += board.split('_')[0]
      osutils.WriteFile(conf_path % settings,
                        conf_data % settings)

    for board in (self.PUB_PRIV, self.PUB_PRIV_VARIANT, self.PRIV_ONLY):
      settings = {
          'board': board,
          'masters': 'portage-stable ',
          'private': 'private-',
          'repo-name': '%s-private' % board,
      }
      if '_' in board:
        settings['masters'] += board.split('_')[0]
      osutils.WriteFile(conf_path % settings,
                        conf_data % settings)

    # Seed the common overlays.
    conf_path = os.path.join(self.tempdir, 'src', 'third_party', '%(overlay)s',
                             'metadata', 'layout.conf')
    osutils.WriteFile(conf_path % {'overlay': 'chromiumos-overlay'},
                      conf_data % {'repo-name': 'chromiumos', 'masters': ''})
    osutils.WriteFile(conf_path % {'overlay': 'portage-stable'},
                      conf_data % {'repo-name': 'portage-stable',
                                   'masters': ''})

    # Now build up the list of overlays that we'll use in tests below.
    self.overlays = {}
    for b in (None, self.FAKE, self.PUB_PRIV, self.PUB_PRIV_VARIANT,
              self.PUB_ONLY, self.PUB2_ONLY, self.PRIV_ONLY):
      self.overlays[b] = d = {}
      for o in (self.PRIVATE, self.PUBLIC, self.BOTH, None):
        try:
          d[o] = portage_util.FindOverlays(o, b, self.tempdir)
        except portage_util.MissingOverlayError:
          d[o] = []
    self._no_overlays = not bool(any(d.values()))

  def testDuplicates(self):
    """Verify that no duplicate overlays are returned."""
    for d in self.overlays.values():
      for overlays in d.values():
        self.assertEqual(len(overlays), len(set(overlays)))

  def testOverlaysExist(self):
    """Verify that all overlays returned actually exist on disk."""
    for d in self.overlays.values():
      for overlays in d.values():
        self.assertTrue(all(os.path.isdir(x) for x in overlays))

  def testPrivatePublicOverlayTypes(self):
    """Verify public/private filtering.

    If we ask for results from 'both overlays', we should
    find all public and all private overlays.
    """
    for b, d in self.overlays.items():
      if b == self.FAKE:
        continue
      self.assertGreaterEqual(set(d[self.BOTH]), set(d[self.PUBLIC]))
      self.assertGreater(set(d[self.BOTH]), set(d[self.PRIVATE]))
      self.assertTrue(set(d[self.PUBLIC]).isdisjoint(d[self.PRIVATE]))

  def testNoOverlayType(self):
    """If we specify overlay_type=None, no results should be returned."""
    self.assertTrue(all(d[None] == [] for d in self.overlays.values()))

  def testNonExistentBoard(self):
    """Test what happens when a non-existent board is supplied.

    If we specify a non-existent board to FindOverlays, only generic
    overlays should be returned.
    """
    for o in (self.PUBLIC, self.BOTH):
      self.assertLess(set(self.overlays[self.FAKE][o]),
                      set(self.overlays[self.PUB_PRIV][o]))

  def testAllBoards(self):
    """If we specify board=None, all overlays should be returned."""
    for o in (self.PUBLIC, self.BOTH):
      for b in (self.FAKE, self.PUB_PRIV):
        self.assertLess(set(self.overlays[b][o]), set(self.overlays[None][o]))

  def testReadOverlayFileOrder(self):
    """Verify that the boards are examined in the right order."""
    m = self.PatchObject(os.path, 'isfile', return_value=False)
    portage_util.ReadOverlayFile('test', self.PUBLIC, self.PUB_PRIV,
                                 self.tempdir)
    read_overlays = [x[0][0][:-5] for x in m.call_args_list]
    overlays = [x for x in reversed(self.overlays[self.PUB_PRIV][self.PUBLIC])]
    self.assertEqual(read_overlays, overlays)

  def testFindOverlayFile(self):
    """Verify that the first file found is returned."""
    file_to_find = 'something_special'
    full_path = os.path.join(self.tempdir,
                             'src', 'private-overlays',
                             'overlay-%s' % self.PUB_PRIV,
                             file_to_find)
    osutils.Touch(full_path)
    self.assertEqual(full_path,
                     portage_util.FindOverlayFile(file_to_find, self.BOTH,
                                                  self.PUB_PRIV_VARIANT,
                                                  self.tempdir))

  def testFoundPrivateOverlays(self):
    """Verify that private boards had their overlays located."""
    for b in (self.PUB_PRIV, self.PUB_PRIV_VARIANT, self.PRIV_ONLY):
      self.assertNotEqual(self.overlays[b][self.PRIVATE], [])
    self.assertNotEqual(self.overlays[self.PUB_PRIV][self.BOTH],
                        self.overlays[self.PUB_PRIV][self.PRIVATE])
    self.assertNotEqual(self.overlays[self.PUB_PRIV_VARIANT][self.BOTH],
                        self.overlays[self.PUB_PRIV_VARIANT][self.PRIVATE])

  def testFoundPublicOverlays(self):
    """Verify that public boards had their overlays located."""
    for b in (self.PUB_PRIV, self.PUB_PRIV_VARIANT, self.PUB_ONLY,
              self.PUB2_ONLY):
      self.assertNotEqual(self.overlays[b][self.PUBLIC], [])
    self.assertNotEqual(self.overlays[self.PUB_PRIV][self.BOTH],
                        self.overlays[self.PUB_PRIV][self.PUBLIC])
    self.assertNotEqual(self.overlays[self.PUB_PRIV_VARIANT][self.BOTH],
                        self.overlays[self.PUB_PRIV_VARIANT][self.PUBLIC])

  def testFoundParentOverlays(self):
    """Verify that the overlays for a parent board are found."""
    for d in self.PUBLIC, self.PRIVATE:
      self.assertLess(set(self.overlays[self.PUB_PRIV][d]),
                      set(self.overlays[self.PUB_PRIV_VARIANT][d]))


class UtilFuncsTest(cros_test_lib.TempDirTestCase):
  """Basic tests for utility functions"""

  def _CreateProfilesRepoName(self, name):
    """Write |name| to profiles/repo_name"""
    profiles = os.path.join(self.tempdir, 'profiles')
    osutils.SafeMakedirs(profiles)
    repo_name = os.path.join(profiles, 'repo_name')
    osutils.WriteFile(repo_name, name)

  def testGetOverlayNameNone(self):
    """If the overlay has no name, it should be fine"""
    self.assertEqual(portage_util.GetOverlayName(self.tempdir), None)

  def testGetOverlayNameProfilesRepoName(self):
    """Verify profiles/repo_name can be read"""
    self._CreateProfilesRepoName('hi!')
    self.assertEqual(portage_util.GetOverlayName(self.tempdir), 'hi!')

  def testGetOverlayNameProfilesLayoutConf(self):
    """Verify metadata/layout.conf is read before profiles/repo_name"""
    self._CreateProfilesRepoName('hi!')
    metadata = os.path.join(self.tempdir, 'metadata')
    osutils.SafeMakedirs(metadata)
    layout_conf = os.path.join(metadata, 'layout.conf')
    osutils.WriteFile(layout_conf, 'repo-name = bye')
    self.assertEqual(portage_util.GetOverlayName(self.tempdir), 'bye')

  def testGetOverlayNameProfilesLayoutConfNoRepoName(self):
    """Verify metadata/layout.conf w/out repo-name is ignored"""
    self._CreateProfilesRepoName('hi!')
    metadata = os.path.join(self.tempdir, 'metadata')
    osutils.SafeMakedirs(metadata)
    layout_conf = os.path.join(metadata, 'layout.conf')
    osutils.WriteFile(layout_conf, 'here = we go')
    self.assertEqual(portage_util.GetOverlayName(self.tempdir), 'hi!')

  def testGetRepositoryFromEbuildInfo(self):
    """Verify GetRepositoryFromEbuildInfo handles data from ebuild info."""

    def _runTestGetRepositoryFromEbuildInfo(fake_projects, fake_srcdirs):
      """Generate the output from ebuild info"""

      # ebuild info always put () around the result, even for single element
      # array.
      fake_ebuild_contents = """
CROS_WORKON_PROJECT=("%s")
CROS_WORKON_SRCDIR=("%s")
      """ % ('" "'.join(fake_projects),
             '" "'.join(fake_srcdirs))
      result = portage_util.GetRepositoryFromEbuildInfo(fake_ebuild_contents)
      result_srcdirs, result_projects = zip(*result)
      self.assertEqual(fake_projects, list(result_projects))
      self.assertEqual(fake_srcdirs, list(result_srcdirs))

    _runTestGetRepositoryFromEbuildInfo(['a', 'b'], ['src_a', 'src_b'])
    _runTestGetRepositoryFromEbuildInfo(['a'], ['src_a'])


class GetOverlayEBuildsTest(cros_test_lib.MockTempDirTestCase):
  """Tests for GetOverlayEBuilds."""

  def setUp(self):
    self.overlay = self.tempdir
    self.uprev_candidate_mock = self.PatchObject(
        portage_util, '_FindUprevCandidates',
        side_effect=GetOverlayEBuildsTest._FindUprevCandidateMock)

  def _CreatePackage(self, name, blacklisted=False):
    """Helper that creates an ebuild."""
    package_path = os.path.join(self.overlay, name,
                                'test_package-0.0.1.ebuild')
    content = 'CROS_WORKON_BLACKLIST=1' if blacklisted else ''
    osutils.WriteFile(package_path, content, makedirs=True)

  @staticmethod
  def _FindUprevCandidateMock(files, allow_blacklisted, _subdir_support):
    """Mock for the FindUprevCandidateMock function.

    Simplified implementation of FindUprevCandidate: consider an ebuild worthy
    of uprev if |allow_blacklisted| is set or the ebuild is not blacklisted.
    """
    for f in files:
      if (f.endswith('.ebuild') and
          (not 'CROS_WORKON_BLACKLIST=1' in osutils.ReadFile(f) or
           allow_blacklisted)):
        pkgdir = os.path.dirname(f)
        return _Package(os.path.join(os.path.basename(os.path.dirname(pkgdir)),
                                     os.path.basename(pkgdir)))
    return None

  def _assertFoundPackages(self, ebuilds, packages):
    """Succeeds iff the packages discovered were packages."""
    self.assertEqual([e.package for e in ebuilds],
                     packages)

  def testWantedPackage(self):
    """Test that we can find a specific package."""
    package_name = 'chromeos-base/mypackage'
    self._CreatePackage(package_name)
    ebuilds = portage_util.GetOverlayEBuilds(
        self.overlay, False, [package_name])
    self._assertFoundPackages(ebuilds, [package_name])

  def testUnwantedPackage(self):
    """Test that we find only the packages we want."""
    ebuilds = portage_util.GetOverlayEBuilds(self.overlay, False, [])
    self._assertFoundPackages(ebuilds, [])

  def testAnyPackage(self):
    """Test that we return all packages available if use_all is set."""
    package_name = 'chromeos-base/package_name'
    self._CreatePackage(package_name)
    ebuilds = portage_util.GetOverlayEBuilds(self.overlay, True, [])
    self._assertFoundPackages(ebuilds, [package_name])

  def testUnknownPackage(self):
    """Test that _FindUprevCandidates is only called if the CP matches."""
    self._CreatePackage('chromeos-base/package_name')
    ebuilds = portage_util.GetOverlayEBuilds(
        self.overlay, False, ['chromeos-base/other_package'])
    self.assertFalse(self.uprev_candidate_mock.called)
    self._assertFoundPackages(ebuilds, [])

  def testBlacklistedPackagesIgnoredByDefault(self):
    """Test that blacklisted packages are ignored by default."""
    package_name = 'chromeos-base/blacklisted_package'
    self._CreatePackage(package_name, blacklisted=True)
    ebuilds = portage_util.GetOverlayEBuilds(
        self.overlay, False, [package_name])
    self._assertFoundPackages(ebuilds, [])

  def testBlacklistedPackagesAllowed(self):
    """Test that we can find blacklisted packages with |allow_blacklisted|."""
    package_name = 'chromeos-base/blacklisted_package'
    self._CreatePackage(package_name, blacklisted=True)
    ebuilds = portage_util.GetOverlayEBuilds(
        self.overlay, False, [package_name], allow_blacklisted=True)
    self._assertFoundPackages(ebuilds, [package_name])


class ProjectMappingTest(cros_test_lib.TestCase):
  """Tests related to Proejct Mapping."""

  def testSplitEbuildPath(self):
    """Test if we can split an ebuild path into its components."""
    ebuild_path = 'chromeos-base/platform2/platform2-9999.ebuild'
    components = ['chromeos-base', 'platform2', 'platform2-9999']
    for path in (ebuild_path, './' + ebuild_path, 'foo.bar/' + ebuild_path):
      self.assertEqual(components, portage_util.SplitEbuildPath(path))

  def testSplitPV(self):
    """Test splitting PVs into package and version components."""
    pv = 'bar-1.2.3_rc1-r5'
    package, version_no_rev, rev = tuple(pv.split('-'))
    split_pv = portage_util.SplitPV(pv)
    self.assertEqual(split_pv.pv, pv)
    self.assertEqual(split_pv.package, package)
    self.assertEqual(split_pv.version_no_rev, version_no_rev)
    self.assertEqual(split_pv.rev, rev)
    self.assertEqual(split_pv.version, '%s-%s' % (version_no_rev, rev))

  def testSplitCPV(self):
    """Test splitting CPV into components."""
    # Test 1: Valid input.
    cpv = 'foo/bar-4.5.6_alpha-r6'
    cp, ver, rev = cpv.split('-')
    cat, pv = cpv.split('/', 1)

    split_pv = portage_util.SplitPV(pv)
    split_cpv = portage_util.SplitCPV(cpv)

    self.assertEqual(split_cpv.category, cat)
    self.assertEqual(cp, split_cpv.cp)
    self.assertEqual('%s-%s' % (cp, ver), split_cpv.cpv)
    self.assertEqual('%s-%s-%s' % (cp, ver, rev), split_cpv.cpf)
    for k, v in split_pv._asdict().items():
      self.assertEqual(getattr(split_cpv, k), v)

    # Test 2: No category, valid pvr.
    cpv = 'bar-pkg-1.2.3_rc4-r5'
    split_cpv_ns = portage_util.SplitCPV(cpv, strict=False)

    # Make sure strict parses correctly.
    self.assertIsNone(portage_util.SplitCPV(cpv, strict=True))
    self.assertIsNotNone(portage_util.SplitPV(cpv, strict=True))
    # All category references should be None when not strict.
    self.assertIsNotNone(split_cpv_ns)
    self.assertIsNone(split_cpv_ns.category)
    self.assertIsNone(split_cpv_ns.cp)
    self.assertIsNone(split_cpv_ns.cpv)
    self.assertIsNone(split_cpv_ns.cpf)

    # Test 3: No version or revision, valid cp.
    cpv = 'cat-foo/bar-pkg'
    split_cpv_ns = portage_util.SplitCPV(cpv, strict=False)

    # Make sure strict parses correctly.
    self.assertIsNone(portage_util.SplitCPV(cpv, strict=True))
    self.assertIsNone(portage_util.SplitPV(cpv, strict=True))
    # Category should get parsed out, and the rest assigned to package.
    self.assertIsNotNone(split_cpv_ns)
    self.assertEqual('cat-foo', split_cpv_ns.category)
    self.assertEqual('bar-pkg', split_cpv_ns.package)
    # The cp should just have category/package. In this case it's valid.
    self.assertEqual('cat-foo/bar-pkg', split_cpv_ns.cp)
    self.assertIsNone(split_cpv_ns.cpv)
    self.assertIsNone(split_cpv_ns.cpf)

    # Test 4: No version - skipped to valid revision.
    cpv = 'cat-foo/bar-pkg-r5'
    split_cpv_ns = portage_util.SplitCPV(cpv, strict=False)

    # Make sure strict parses correctly.
    self.assertIsNone(portage_util.SplitCPV(cpv, strict=True))
    self.assertIsNone(portage_util.SplitPV(cpv, strict=True))
    # Category should get parsed out, and the rest assigned to package.
    self.assertIsNotNone(split_cpv_ns)
    self.assertEqual('cat-foo', split_cpv_ns.category)
    self.assertEqual('bar-pkg-r5', split_cpv_ns.package)
    # The cp should just have category/package. Invalid in this case, but
    # meeting expectations.
    self.assertEqual('cat-foo/bar-pkg-r5', split_cpv_ns.cp)
    self.assertIsNone(split_cpv_ns.cpv)
    self.assertIsNone(split_cpv_ns.cpf)

    cpv = 'invalid/format/package'
    with self.assertRaises(ValueError):
      portage_util.SplitCPV(cpv)

  def testFindWorkonProjects(self):
    """Test if we can find the list of workon projects."""
    frecon = 'sys-apps/frecon'
    frecon_project = 'chromiumos/platform/frecon'
    this = 'chromeos-base/chromite'
    this_project = 'chromiumos/chromite'
    matches = [
        ([frecon], set([frecon_project])),
        ([this], set([this_project])),
        ([frecon, this], set([frecon_project, this_project]))
    ]
    if portage_util.FindOverlays(constants.BOTH_OVERLAYS):
      for packages, projects in matches:
        self.assertEqual(projects,
                         portage_util.FindWorkonProjects(packages))


class PortageDBTest(cros_test_lib.TempDirTestCase):
  """Portage package Database related tests."""

  fake_pkgdb = {'category1': ['package-1', 'package-2'],
                'category2': ['package-3', 'package-4'],
                'category3': ['invalid', 'semi-invalid'],
                'with': ['files-1'],
                'dash-category': ['package-5'],
                '-invalid': ['package-6'],
                'invalid': []}
  fake_packages = []
  build_root = None
  fake_chroot = None

  fake_files = [
      ('dir', '/lib64'),
      ('obj', '/lib64/libext2fs.so.2.4', 'a6723f44cf82f1979e9731043f820d8c',
       '1390848093'),
      ('dir', '/dir with spaces'),
      ('obj', '/dir with spaces/file with spaces',
       'cd4865bbf122da11fca97a04dfcac258', '1390848093'),
      ('sym', '/lib64/libe2p.so.2', '->', 'libe2p.so.2.3', '1390850489'),
      ('foo'),
  ]

  def setUp(self):
    self.build_root = self.tempdir
    self.fake_packages = []
    # Prepare a fake chroot.
    self.fake_chroot = os.path.join(self.build_root, 'chroot/build/amd64-host')
    fake_pkgdb_path = os.path.join(self.fake_chroot, portage_util.VDB_PATH)
    os.makedirs(fake_pkgdb_path)
    for cat, pkgs in self.fake_pkgdb.items():
      catpath = os.path.join(fake_pkgdb_path, cat)
      if cat == 'invalid':
        # Invalid category is a file. Should not be delved into.
        osutils.Touch(catpath)
        continue
      os.makedirs(catpath)
      for pkg in pkgs:
        pkgpath = os.path.join(catpath, pkg)
        if pkg == 'invalid':
          # Invalid package is a file instead of a directory/
          osutils.Touch(pkgpath)
          continue
        os.makedirs(pkgpath)
        if pkg.endswith('-invalid'):
          # Invalid package does not meet existence of "%s/%s.ebuild" file.
          osutils.Touch(os.path.join(pkgpath, 'whatever'))
          continue
        # Create the package.
        osutils.Touch(os.path.join(pkgpath, pkg + '.ebuild'))
        if cat.startswith('-'):
          # Invalid category.
          continue
        # Correct pkg.
        pv = portage_util.SplitPV(pkg)
        key = '%s/%s' % (cat, pv.package)
        self.fake_packages.append((key, pv.version))
    # Add contents to with/files-1.
    osutils.WriteFile(
        os.path.join(fake_pkgdb_path, 'with', 'files-1', 'CONTENTS'),
        ''.join(' '.join(entry) + '\n' for entry in self.fake_files))

  def testListInstalledPackages(self):
    """Test if listing packages installed into a root works."""
    packages = portage_util.ListInstalledPackages(self.fake_chroot)
    # Sort the lists, because the filesystem might reorder the entries for us.
    packages.sort()
    self.fake_packages.sort()
    self.assertEqual(self.fake_packages, packages)

  def testGeneratePackageSizes(self):
    """Test if calculating installed package sizes works."""
    fake_data = 'FAKE DATA'
    expected_size = 0
    for fake_file in self.fake_files:
      if fake_file[0] == 'obj':
        fake_filename = os.path.join(self.fake_chroot,
                                     os.path.relpath(fake_file[1], '/'))
        osutils.WriteFile(fake_filename, fake_data, makedirs=True)
        expected_size += len(fake_data)

    portage_db = portage_util.PortageDB(self.fake_chroot)
    installed_packages = portage_db.InstalledPackages()
    package_size_pairs = portage_util.GeneratePackageSizes(portage_db,
                                                           'fake_chroot',
                                                           installed_packages)
    total_size = sum(x for _, x in package_size_pairs)
    self.assertEqual(total_size, expected_size)

  def testIsPackageInstalled(self):
    """Test if checking the existence of an installed package works."""
    self.assertTrue(portage_util.IsPackageInstalled(
        'category1/package',
        sysroot=self.fake_chroot))
    self.assertFalse(portage_util.IsPackageInstalled(
        'category1/foo',
        sysroot=self.fake_chroot))

  def testListContents(self):
    """Test if the list of installed files is properly parsed."""
    pdb = portage_util.PortageDB(self.fake_chroot)
    pkg = pdb.GetInstalledPackage('with', 'files-1')
    self.assertTrue(pkg)
    lst = pkg.ListContents()

    # Check ListContents filters out the garbage we added to the list of files.
    fake_files = [f for f in self.fake_files if f[0] in ('sym', 'obj', 'dir')]
    self.assertEqual(len(fake_files), len(lst))

    # Check the paths are all relative.
    self.assertTrue(all(not f[1].startswith('/') for f in lst))

    # Check all the files are present. We only consider file type and path, and
    # convert the path to a relative path.
    fake_files = [(f[0], f[1].lstrip('/')) for f in fake_files]
    self.assertEqual(fake_files, lst)


class InstalledPackageTest(cros_test_lib.TempDirTestCase):
  """InstalledPackage class tests outside a PortageDB."""

  def setUp(self):
    content = (
        ('package-1.ebuild', 'EAPI=1'),
        ('CATEGORY', 'category-1\n'),
        ('HOMEPAGE', 'http://example.com\n'),
        ('LICENSE', 'GPL-2\n'),
        ('PF', 'package-1\n'),
        ('repository', 'portage-stable\n'),
        ('SIZE', '123\n'),
    )
    for path, data in content:
      osutils.WriteFile(os.path.join(self.tempdir, path), data)

  def testOutOfDBPackage(self):
    """Tests an InstalledPackage instance can be created without a PortageDB."""
    pkg = portage_util.InstalledPackage(None, self.tempdir)
    self.assertEqual('category-1', pkg.category)
    self.assertEqual('http://example.com', pkg.homepage)
    self.assertEqual('GPL-2', pkg.license)
    self.assertEqual('package-1', pkg.pf)
    self.assertEqual('portage-stable', pkg.repository)
    self.assertEqual('123', pkg.size)

  def testIncompletePackage(self):
    """Tests an incomplete or otherwise invalid package raises an exception."""
    # No package name is provided.
    os.unlink(os.path.join(self.tempdir, 'PF'))
    self.assertRaises(portage_util.PortageDBError,
                      portage_util.InstalledPackage, None, self.tempdir)

    # Check that doesn't fail when the package name is provided.
    pkg = portage_util.InstalledPackage(None, self.tempdir, pf='package-1')
    self.assertEqual('package-1', pkg.pf)


class HasPrebuiltTest(cros_test_lib.RunCommandTestCase):
  """HasPrebuilt tests."""

  def setUp(self):
    self.atom = 'chromeos-base/chromeos-chrome'
    self.r1_cpf = 'chromeos-base/chromeos-chrome-78.0.3900.0_rc-r1'
    self.r2_cpf = 'chromeos-base/chromeos-chrome-78.0.3900.0_rc-r2'
    self.r1_cpv = portage_util.SplitCPV(self.r1_cpf)
    self.r2_cpv = portage_util.SplitCPV(self.r2_cpf)

    def _check_pkg(cmd, *_args, **_kwargs):
      rc = 0 if '=%s' % self.r1_cpf in cmd else 1
      return cros_build_lib.CommandResult(cmd=cmd, returncode=rc)
    self.rc.SetDefaultCmdResult(side_effect=_check_pkg)

  def testHasPrebuilt(self):
    """Test a package with a matching prebuilt."""
    self.PatchObject(portage_util, 'PortageqBestVisible',
                     return_value=self.r1_cpv)
    self.rc.SetDefaultCmdResult(returncode=0)

    self.assertTrue(portage_util.HasPrebuilt(self.atom))
    self.rc.assertCommandContains(('=%s' % self.r1_cpf,))

  def testNoPrebuilt(self):
    """Test a package without a matching prebuilt."""
    self.PatchObject(portage_util, 'PortageqBestVisible',
                     return_value=self.r2_cpv)
    self.rc.SetDefaultCmdResult(returncode=1)

    self.assertFalse(portage_util.HasPrebuilt(self.atom))
    self.rc.assertCommandContains(('=%s' % self.r2_cpf,))


class PortageqBestVisibleTest(cros_test_lib.MockTestCase):
  """PortageqBestVisible tests."""

  def testValidPackage(self):
    """Test valid outputs."""
    result = cros_build_lib.CommandResult(output='cat/pkg-1.0', returncode=0)
    self.PatchObject(portage_util, '_Portageq', return_value=result)

    self.assertIsInstance(portage_util.PortageqBestVisible('cat/pkg'),
                          portage_util.CPV)


class PortageqEnvvarTest(cros_test_lib.MockTestCase):
  """PortageqEnvvar[s] tests."""

  def testValidEnvvar(self):
    """Test valid variables."""
    result = cros_build_lib.CommandResult(output='TEST=value\n', returncode=0)
    self.PatchObject(portage_util, '_Portageq', return_value=result)

    envvar1 = portage_util.PortageqEnvvar('TEST')
    envvars1 = portage_util.PortageqEnvvars(['TEST'])

    self.assertEqual('value', envvar1)
    self.assertEqual(envvar1, envvars1['TEST'])

  def testUndefinedEnvvars(self):
    """Test undefined variable handling."""
    # The variable exists in the command output even when not actually defined.
    result = cros_build_lib.CommandResult(output='DOES_NOT_EXIST=\n',
                                          returncode=1)
    success_error = cros_build_lib.RunCommandError('', result)
    self.PatchObject(portage_util, '_Portageq', side_effect=success_error)

    # Test ignoring error when just from undefined variable.
    envv = portage_util.PortageqEnvvar('DOES_NOT_EXIST', allow_undefined=True)
    envvs = portage_util.PortageqEnvvars(['DOES_NOT_EXIST'],
                                         allow_undefined=True)
    self.assertEqual('', envv)
    self.assertEqual(envv, envvs['DOES_NOT_EXIST'])

    # Test raising the error when just from undefined variable.
    with self.assertRaises(portage_util.PortageqError):
      portage_util.PortageqEnvvar('DOES_NOT_EXIST')
    with self.assertRaises(portage_util.PortageqError):
      portage_util.PortageqEnvvars(['DOES_NOT_EXIST'])

    run_error = cros_build_lib.CommandResult(output='\n', returncode=2)
    failure_error = cros_build_lib.RunCommandError('', run_error)
    self.PatchObject(portage_util, '_Portageq', side_effect=failure_error)

    # Test re-raising the error when the command did not run successfully.
    with self.assertRaises(cros_build_lib.RunCommandError):
      portage_util.PortageqEnvvar('DOES_NOT_EXIST')
    with self.assertRaises(cros_build_lib.RunCommandError):
      portage_util.PortageqEnvvars(['DOES_NOT_EXIST'])

  def testInvalidEnvvars(self):
    """Test invalid variables handling."""
    # Envvar tests.
    with self.assertRaises(TypeError):
      portage_util.PortageqEnvvar([])
    with self.assertRaises(ValueError):
      portage_util.PortageqEnvvar('')

    # Envvars tests.
    self.assertEqual({}, portage_util.PortageqEnvvars([]))
    with self.assertRaises(TypeError):
      portage_util.PortageqEnvvars('')

    # Raised when extending the command list. This is currently expected, and
    # ints should not be accepted, but more formal handling can be added.
    with self.assertRaises(TypeError):
      portage_util.PortageqEnvvars(1)


class PortageqHasVersionTest(cros_test_lib.MockTestCase):
  """PortageqHasVersion tests."""

  def testPortageqHasVersion(self):
    """Test HasVersion."""
    result_true = cros_build_lib.CommandResult(returncode=0)
    result_false = cros_build_lib.CommandResult(returncode=1)
    result_error = cros_build_lib.CommandResult(returncode=2)

    # Test has version.
    self.PatchObject(portage_util, '_Portageq', return_value=result_true)
    self.assertTrue(portage_util.PortageqHasVersion('cat/pkg'))

    # Test not has version.
    self.PatchObject(portage_util, '_Portageq', return_value=result_false)
    self.assertFalse(portage_util.PortageqHasVersion('cat/pkg'))

    # Test run error.
    self.PatchObject(portage_util, '_Portageq', return_value=result_error)
    self.assertFalse(portage_util.PortageqHasVersion('cat/pkg'))


class PortageqMatchTest(cros_test_lib.MockTestCase):
  """PortageqMatch tests."""

  def testMultiError(self):
    """Test unspecific query results in error.

    The method currently isn't setup to support multiple values in the output.
    It is instead interpreted as a cpv format error by SplitCPV. This isn't
    a hard requirement, just the current expected behavior.
    """
    output_str = 'cat-1/pkg-one-1.0\ncat-2/pkg-two-2.1.3-r45\n'
    result = cros_build_lib.CommandResult(returncode=0,
                                          output=output_str)
    self.PatchObject(portage_util, '_Portageq', return_value=result)

    with self.assertRaises(ValueError):
      portage_util.PortageqMatch('*/*')

  def testValidPackage(self):
    """Test valid package produces a CPV."""
    result = cros_build_lib.CommandResult(returncode=0, output='cat/pkg-1.0-r1')
    self.PatchObject(portage_util, '_Portageq', return_value=result)

    self.assertIsInstance(portage_util.PortageqMatch('cat/pkg'),
                          portage_util.CPV)


class FindEbuildTest(cros_test_lib.RunCommandTestCase):
  """Tests for FindEbuildsForPackages and FindEbuildsForPackages."""

  def testFindEbuildsForPackagesReturnResultsSimple(self):
    equery_output = ('/chromeos-overlay/misc/foo/foo.ebuild\n'
                     '/chromeos-overlay/misc/bar/bar.ebuild\n')
    self.rc.AddCmdResult(
        ['/build/nami/build/bin/equery', 'which', 'misc/foo', 'misc/bar'],
        output=equery_output)
    self.assertEqual(
        portage_util.FindEbuildsForPackages(['misc/foo', 'misc/bar'],
                                            sysroot='/build/nami'),
        {'misc/bar': '/chromeos-overlay/misc/bar/bar.ebuild',
         'misc/foo': '/chromeos-overlay/misc/foo/foo.ebuild'})

  def testFindEbuildsForPackagesWithoutCategoryReturnResults(self):
    equery_output = ('/chromeos-overlay/misc/foo/foo.ebuild\n'
                     '/chromeos-overlay/misc/bar/bar.ebuild\n')
    self.rc.AddCmdResult(
        ['/build/nami/build/bin/equery', 'which', 'misc/foo', 'bar'],
        output=equery_output)
    self.assertEqual(
        portage_util.FindEbuildsForPackages(['misc/foo', 'bar'],
                                            sysroot='/build/nami'),
        {'bar': '/chromeos-overlay/misc/bar/bar.ebuild',
         'misc/foo': '/chromeos-overlay/misc/foo/foo.ebuild'})

  def testFindEbuildsForPackagesReturnResultsComplexPackages(self):
    ebuild_path = (
        '/portage-stable/sys-libs/timezone-data/timezone-data-2018i.ebuild')
    equery_output = '\n'.join([ebuild_path] * 4)
    packages = [
        # CATEGORY/PN
        'sys-libs/timezone-data',
        # CATEGORY/P
        'sys-libs/timezone-data-2018i',
        # CATEGORY/PN:SLOT
        'sys-libs/timezone-data:0',
        # CATEGORY/P:SLOT
        'sys-libs/timezone-data-2018i:0',
    ]
    self.rc.AddCmdResult(
        ['/build/nami/build/bin/equery', 'which'] + packages,
        output=equery_output)
    self.assertEqual(
        portage_util.FindEbuildsForPackages(packages,
                                            sysroot='/build/nami'),
        {'sys-libs/timezone-data': ebuild_path,
         'sys-libs/timezone-data-2018i:0': ebuild_path,
         'sys-libs/timezone-data:0': ebuild_path,
         'sys-libs/timezone-data-2018i': ebuild_path,
        })

  def testFindEbuildsForPackagesReturnNone(self):
    # Result for package 'bar' is missing.
    equery_output = ('/chromeos-overlay/bar/bar.ebuild\n')
    self.rc.AddCmdResult(
        ['/build/nami/build/bin/equery', 'which', 'foo', 'bar'],
        output=equery_output, returncode=1)
    self.assertEqual(portage_util.FindEbuildsForPackages(
        ['foo', 'bar'], sysroot='/build/nami'), {})

  def testFindEbuildsForPackagesInvalidEbuildsOrder(self):
    equery_output = ('/chromeos-overlay/bar/bar.ebuild\n'
                     '/chromeos-overlay/foo/foo.ebuild\n')
    self.rc.AddCmdResult(
        ['/build/nami/build/bin/equery', 'which', 'foo', 'bar'],
        output=equery_output)
    with self.assertRaises(AssertionError):
      portage_util.FindEbuildsForPackages(
          ['foo', 'bar'], sysroot='/build/nami')

  def testFindEbuildForPackageReturnResults(self):
    equery_output = '/chromeos-overlay/misc/foo/foo-9999.ebuild\n'
    self.rc.AddCmdResult(
        ['/build/nami/build/bin/equery', 'which', 'misc/foo'],
        output=equery_output)
    self.assertEqual(
        portage_util.FindEbuildForPackage('misc/foo', sysroot='/build/nami'),
        '/chromeos-overlay/misc/foo/foo-9999.ebuild')

  def testFindEbuildForPackageReturnNone(self):
    equery_output = "Cannot find ebuild for package 'foo'\n"
    self.rc.AddCmdResult(
        ['/build/nami/build/bin/equery', 'which', 'foo'],
        output=equery_output, returncode=1)
    self.assertEqual(portage_util.FindEbuildForPackage(
        'foo', sysroot='/build/nami'), None)

_EQUERY_OUTPUT_CORPUS = """

virtual/editor-0:
 [  0]  virtual/editor-0   
 [  1]  app-editors/nano-4.2   
 [  1]  app-editors/emacs-26.1-r3   
 [  1]  app-editors/qemacs-0.4.1_pre20170225   
 [  1]  app-editors/vim-8.1.1486   
 [  1]  app-misc/mc-4.8.10   
 [  1]  sys-apps/busybox-1.29.3   
 [  1]  sys-apps/ed-1.14.2   
"""


class DepTreeTest(cros_test_lib.TestCase):
  """Tests for GetDepTreeForPackage & parsing"""

  def testParseDepTreeOutput(self):
    expected = [
        'virtual/editor-0',
        'app-editors/nano-4.2',
        'app-editors/emacs-26.1-r3',
        'app-editors/qemacs-0.4.1_pre20170225',
        'app-editors/vim-8.1.1486',
        'app-misc/mc-4.8.10',
        'sys-apps/busybox-1.29.3',
        'sys-apps/ed-1.14.2',
    ]
    self.assertEqual(expected,
                     portage_util._ParseDepTreeOutput(_EQUERY_OUTPUT_CORPUS))
