# Copyright 2012 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""This module tests the cros image command."""

import copy
import os
import shutil
import threading
from unittest import mock

from chromite.third_party.gn_helpers import gn_helpers

from chromite.cli import command_unittest
from chromite.cli.cros import cros_chrome_sdk
from chromite.lib import cache
from chromite.lib import chromite_config
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import cros_test_lib
from chromite.lib import gs
from chromite.lib import gs_unittest
from chromite.lib import osutils
from chromite.lib import parallel_unittest
from chromite.lib import partial_mock


# pylint: disable=protected-access


class MockChromeSDKCommand(command_unittest.MockCommand):
    """Mock out the build command."""

    TARGET = "chromite.cli.cros.cros_chrome_sdk.ChromeSDKCommand"
    TARGET_CLASS = cros_chrome_sdk.ChromeSDKCommand
    COMMAND = "chrome-sdk"
    ATTRS = ("_SetupEnvironment",) + command_unittest.MockCommand.ATTRS

    def __init__(self, *args, **kwargs):
        command_unittest.MockCommand.__init__(self, *args, **kwargs)
        self.env = None

    def _SetupEnvironment(self, *args, **kwargs):
        env = self.backup["_SetupEnvironment"](*args, **kwargs)
        self.env = copy.deepcopy(env)
        return env


class ParserTest(cros_test_lib.MockTempDirTestCase):
    """Test the parser."""

    def testNormal(self):
        """Tests that our example parser works normally."""
        with MockChromeSDKCommand(
            ["--board", SDKFetcherMock.BOARD],
            base_args=["--cache-dir", str(self.tempdir)],
        ) as bootstrap:
            self.assertEqual(bootstrap.inst.options.board, SDKFetcherMock.BOARD)
            self.assertEqual(
                bootstrap.inst.options.cache_dir, str(self.tempdir)
            )

    def testVersion(self):
        """Tests that a platform version is allowed."""
        VERSION = "1234.0.0"
        with MockChromeSDKCommand(
            ["--board", SDKFetcherMock.BOARD, "--version", VERSION]
        ) as parser:
            self.assertEqual(parser.inst.options.version, VERSION)

    def testFullVersion(self):
        """Tests that a full version is allowed."""
        FULL_VERSION = "R56-1234.0.0"
        with MockChromeSDKCommand(
            ["--board", SDKFetcherMock.BOARD, "--version", FULL_VERSION]
        ) as parser:
            self.assertEqual(parser.inst.options.version, FULL_VERSION)


def _GSCopyMock(_self, path, dest, **_kwargs):
    """Used to simulate a GS Copy operation."""
    with osutils.TempDir() as tempdir:
        local_path = os.path.join(tempdir, os.path.basename(path))
        osutils.Touch(local_path)
        shutil.move(local_path, dest)


def _DependencyMockCtx(f):
    """Attribute that ensures dependency PartialMocks are started.

    Since PartialMock does not support nested mocking, we need to first call
    stop() on the outer level PartialMock (which is passed in to us).  We then
    re-start() the outer level upon exiting the context.
    """

    def new_f(self, *args, **kwargs):
        if not self.entered:
            try:
                self.entered = True
                # Temporarily disable outer GSContext mock before starting our
                # mock.
                # TODO(rcui): Generalize this attribute and include in
                #   partial_mock.py.
                for emock in self.external_mocks:
                    emock.stop()

                with self.gs_mock:
                    return f(self, *args, **kwargs)
            finally:
                self.entered = False
                for emock in self.external_mocks:
                    emock.start()
        else:
            return f(self, *args, **kwargs)

    return new_f


class SDKFetcherMock(partial_mock.PartialMock):
    """Provides mocking functionality for SDKFetcher."""

    TARGET = "chromite.cli.cros.cros_chrome_sdk.SDKFetcher"
    ATTRS = (
        "__init__",
        "GetFullVersion",
        "_GetMetadata",
        "_UpdateTarball",
        "_GetManifest",
        "UpdateDefaultVersion",
        "_GetTarballCacheKey",
        "_GetBuildReport",
    )

    FAKE_METADATA = """
{
  "boards": ["eve"],
  "cros-version": "25.3543.2",
  "metadata-version": "1",
  "bot-hostname": "build82-m2.golo.chromium.org",
  "bot-config": "eve-release",
  "toolchain-tuple": ["i686-pc-linux-gnu"],
  "toolchain-url": "2013/01/%(target)s-2013.01.23.003823.tar.xz",
  "sdk-version": "2013.01.23.003823"
}"""
    FAKE_BUILD_REPORT = """
{
  "sdkVersion": "2013.01.23.003823",
  "toolchainUrl": "2013/01/%(target)s-2013.01.23.003823.tar.xz",
  "toolchains": ["i686-pc-linux-gnu"]
}
"""

    BOARD = "eve"
    # These are boards that Lacros is currently supporting.
    # Specifically, *-crostoolchain.gni files need to be generated for them.
    BOARDS = ["amd64-generic", "arm-generic", "arm64-generic"]
    VERSION = "4567.8.9"

    def __init__(self, external_mocks=None):
        """Initializes the mock.

        Args:
            external_mocks: A list of already started PartialMock/patcher
                instances. stop() will be called on each element every time
                execution enters one of our the mocked out methods, and start()
                called on it once execution leaves the mocked out method.
        """
        partial_mock.PartialMock.__init__(self)
        self.external_mocks = external_mocks or []
        self.entered = False
        self.gs_mock = gs_unittest.GSContextMock()
        self.gs_mock.SetDefaultCmdResult()
        self.env = None
        self.tarball_cache_key_map = {}
        self.tarball_fetch_lock = threading.Lock()

    @_DependencyMockCtx
    def _target__init__(self, inst, *args, **kwargs):
        self.backup["__init__"](inst, *args, **kwargs)
        if not inst.cache_base.startswith("/tmp"):
            raise AssertionError(
                "For testing, SDKFetcher cache_dir needs to be a "
                "dir under /tmp"
            )

    @_DependencyMockCtx
    def UpdateDefaultVersion(self, inst, *_args, **_kwargs):
        inst._SetDefaultVersion(self.VERSION)
        return self.VERSION, True

    @_DependencyMockCtx
    def _UpdateTarball(self, inst, *args, **kwargs):
        # The mocks here can fall off in the middle of the test unreliably,
        # likely due to a race condition when running _UpdateTarball across
        # multiple threads. So lock around the mocks to avoid.
        with self.tarball_fetch_lock:
            with mock.patch.object(
                gs.GSContext, "Copy", autospec=True, side_effect=_GSCopyMock
            ):
                with mock.patch.object(cache, "Untar"):
                    return self.backup["_UpdateTarball"](inst, *args, **kwargs)

    @_DependencyMockCtx
    def GetFullVersion(self, _inst, version):
        return "R26-%s" % version

    @_DependencyMockCtx
    def _GetMetadata(self, inst, *args, **kwargs):
        self.gs_mock.SetDefaultCmdResult()
        self.gs_mock.AddCmdResult(
            partial_mock.ListRegex("cat .*/%s" % constants.METADATA_JSON),
            stdout=self.FAKE_METADATA,
        )
        return self.backup["_GetMetadata"](inst, *args, **kwargs)

    @_DependencyMockCtx
    def _GetBuildReport(self, inst, *args, **kwargs):
        self.gs_mock.SetDefaultCmdResult()
        self.gs_mock.AddCmdResult(
            partial_mock.ListRegex("cat .*/%s" % constants.BUILD_REPORT_JSON),
            stdout=self.FAKE_BUILD_REPORT,
        )
        return self.backup["_GetBuildReport"](inst, *args, **kwargs)

    @_DependencyMockCtx
    def _GetManifest(self, _inst, _version):
        return {
            "packages": {
                "app-emulation/qemu": [["3.0.0", {}]],
                "chromeos-base/tast-cmd": [["1.2.3", {}]],
                "chromeos-base/tast-remote-tests-cros": [["7.8.9", {}]],
                "sys-firmware/seabios": [["1.11.0", {}]],
            }
        }

    @_DependencyMockCtx
    def _GetTarballCacheKey(self, _inst, component, _url):
        return (
            os.path.join(
                component,
                self.tarball_cache_key_map.get(component, "some-fake-hash"),
            ),
        )


class RunThroughTest(
    cros_test_lib.MockTempDirTestCase, cros_test_lib.LoggingTestCase
):
    """Run the script with most things mocked out."""

    VERSION_KEY = (
        SDKFetcherMock.BOARD,
        SDKFetcherMock.VERSION,
        constants.CHROME_SYSROOT_TAR,
    )

    FAKE_ENV = {
        "GN_ARGS": 'target_sysroot="/path/to/sysroot" is_clang=false',
        "AR": "x86_64-cros-linux-gnu-ar",
        "AS": "x86_64-cros-linux-gnu-as",
        "CXX": "x86_64-cros-linux-gnu-clang++",
        "CC": "x86_64-cros-linux-gnu-clang",
        "LD": "x86_64-cros-linux-gnu-clang++",
        "NM": "x86_64-cros-linux-gnu-nm",
        "RANLIB": "x86_64-cros-linux-gnu-ranlib",
        "READELF": "x86_64-cros-linux-gnu-readelf",
        "CFLAGS": "-O2",
        "CXXFLAGS": "-O2",
    }

    def SetupCommandMock(
        self, many_boards=False, extra_args=None, default_cache_dir=False
    ):
        cmd_args = ["--chrome-src", self.chrome_src_dir, "true"]
        if many_boards:
            cmd_args += [
                "--boards",
                ":".join(SDKFetcherMock.BOARDS),
                "--no-shell",
            ]
        else:
            cmd_args += ["--board", SDKFetcherMock.BOARD]
        if extra_args:
            cmd_args.extend(extra_args)
        # --no-shell drops gni files in //build/args/chromeos/. reclient configs
        # are also dropped here regardless of --no-shell or not.
        osutils.SafeMakedirs(
            os.path.join(self.chrome_root, "src", "build", "args", "chromeos")
        )

        base_args = (
            None if default_cache_dir else ["--cache-dir", str(self.tempdir)]
        )
        self.cmd_mock = MockChromeSDKCommand(cmd_args, base_args=base_args)
        self.StartPatcher(self.cmd_mock)
        self.cmd_mock.UnMockAttr("Run")

    def SourceEnvironmentMock(self, path, *_args, **_kwargs):
        if str(path).endswith("environment"):
            return copy.deepcopy(self.FAKE_ENV)
        return {}

    def setUp(self):
        self.rc_mock = cros_test_lib.RunCommandMock()
        self.rc_mock.SetDefaultCmdResult()
        self.StartPatcher(self.rc_mock)
        self.StartPatcher(parallel_unittest.ParallelMock())

        self.sdk_mock = self.StartPatcher(
            SDKFetcherMock(external_mocks=[self.rc_mock])
        )

        # This needs to occur before initializing MockChromeSDKCommand.
        self.bashrc = self.tempdir / "bashrc"
        self.PatchObject(chromite_config, "CHROME_SDK_BASHRC", new=self.bashrc)

        self.PatchObject(
            osutils,
            "SourceEnvironment",
            autospec=True,
            side_effect=self.SourceEnvironmentMock,
        )
        self.rc_mock.AddCmdResult(
            cros_chrome_sdk.ChromeSDKCommand.GOMACC_PORT_CMD, stdout="8088"
        )

        # Initialized by SetupCommandMock.
        self.cmd_mock = None

        # Set up a fake Chrome src/ directory
        self.chrome_root = os.path.join(self.tempdir, "chrome_root")
        self.chrome_src_dir = os.path.join(self.chrome_root, "src")
        osutils.SafeMakedirs(self.chrome_src_dir)
        osutils.Touch(os.path.join(self.chrome_root, ".gclient"))
        osutils.SafeMakedirs(os.path.join(self.chrome_src_dir, "chrome"))
        osutils.WriteFile(
            os.path.join(self.chrome_src_dir, "chrome", "VERSION"), "MAJOR=123"
        )

    @property
    def cache(self):
        return self.cmd_mock.inst.sdk.tarball_cache

    def testIt(self):
        """Test a runthrough of the script."""
        self.PatchObject(
            cros_chrome_sdk.ChromeSDKCommand, "_GomaDir", side_effect=["XXXX"]
        )
        self.SetupCommandMock()
        with cros_test_lib.LoggingCapturer() as logs:
            self.cmd_mock.inst.Run()
            self.AssertLogsContain(logs, "Goma:", inverted=True)

    def testManyBoards(self):
        """Test a runthrough when multiple boards are specified via --boards."""
        self.SetupCommandMock(many_boards=True)
        self.cmd_mock.inst.ProcessOptions(
            self.cmd_mock.parser, self.cmd_mock.inst.options
        )
        self.cmd_mock.inst.Run()
        for board in SDKFetcherMock.BOARDS:
            board_arg_file = os.path.join(
                self.chrome_src_dir, "build/args/chromeos/%s.gni" % board
            )
            self.assertExists(board_arg_file)
            board_crostoolchain_arg_file = os.path.join(
                self.chrome_src_dir,
                "build/args/chromeos/%s-crostoolchain.gni" % board,
            )
            self.assertNotExists(board_crostoolchain_arg_file)

    def testManyBoardsLacros(self):
        """Test a runthrough when multiple boards are specified via --boards."""
        self.SetupCommandMock(
            many_boards=True, extra_args=["--is-lacros", "--version=1234.0.0"]
        )
        lkgm_file = os.path.join(
            self.chrome_src_dir, constants.PATH_TO_CHROME_LKGM
        )
        osutils.Touch(lkgm_file, makedirs=True)
        osutils.WriteFile(lkgm_file, "5678.0.0")

        self.cmd_mock.inst.ProcessOptions(
            self.cmd_mock.parser, self.cmd_mock.inst.options
        )
        self.cmd_mock.inst.Run()
        for board in SDKFetcherMock.BOARDS:
            board_arg_file = os.path.join(
                self.chrome_src_dir, "build/args/chromeos/%s.gni" % board
            )
            self.assertNotExists(board_arg_file)
            board_crostoolchain_arg_file = os.path.join(
                self.chrome_src_dir,
                "build/args/chromeos/%s-crostoolchain.gni" % board,
            )
            self.assertExists(board_crostoolchain_arg_file)
            with open(board_crostoolchain_arg_file, encoding="utf-8") as f:
                self.assertIn('cros_sdk_version = "5678.0.0"', f.read())

    def testManyBoardsBrokenArgs(self):
        """Tests that malformed args.gn files will be fixed in --boards."""
        self.SetupCommandMock(many_boards=True)
        for board in SDKFetcherMock.BOARDS:
            gn_args_file = os.path.join(
                self.chrome_src_dir, "out_%s" % board, "Release", "args.gn"
            )
            osutils.WriteFile(gn_args_file, "foo\nbar", makedirs=True)

        self.cmd_mock.inst.ProcessOptions(
            self.cmd_mock.parser, self.cmd_mock.inst.options
        )
        self.cmd_mock.inst.Run()

        for board in SDKFetcherMock.BOARDS:
            gn_args_file = os.path.join(
                self.chrome_src_dir, "out_%s" % board, "Release", "args.gn"
            )
            self.assertTrue(osutils.ReadFile(gn_args_file).startswith("import"))

    def testErrorCodePassthrough(self):
        """Test that error codes are passed through."""
        self.SetupCommandMock()
        with cros_test_lib.LoggingCapturer():
            self.rc_mock.AddCmdResult(
                partial_mock.ListRegex("-- true"), returncode=5
            )
            returncode = self.cmd_mock.inst.Run()
            self.assertEqual(returncode, 5)

    def testEmptyMetadata(self):
        """Tests the use of build_report.json when metadata.json is empty."""
        sdk_dir = os.path.join(self.tempdir, "sdk_dir")
        osutils.SafeMakedirs(sdk_dir)
        osutils.WriteFile(os.path.join(sdk_dir, constants.METADATA_JSON), "{}")
        osutils.WriteFile(
            os.path.join(sdk_dir, constants.BUILD_REPORT_JSON),
            SDKFetcherMock.FAKE_BUILD_REPORT,
        )
        self.SetupCommandMock(extra_args=["--sdk-path", sdk_dir])
        with cros_test_lib.LoggingCapturer():
            self.cmd_mock.inst.Run()

    def testLocalSDKPath(self):
        """Fetch components from a local --sdk-path."""
        sdk_dir = os.path.join(self.tempdir, "sdk_dir")
        osutils.SafeMakedirs(sdk_dir)
        osutils.WriteFile(
            os.path.join(sdk_dir, constants.METADATA_JSON),
            SDKFetcherMock.FAKE_METADATA,
        )
        osutils.WriteFile(
            os.path.join(sdk_dir, constants.BUILD_REPORT_JSON),
            SDKFetcherMock.FAKE_BUILD_REPORT,
        )
        self.SetupCommandMock(extra_args=["--sdk-path", sdk_dir])
        with cros_test_lib.LoggingCapturer():
            self.cmd_mock.inst.Run()

    def testGomaError(self):
        """We print an error message when GomaError is raised."""
        self.SetupCommandMock()
        with cros_test_lib.LoggingCapturer() as logs:
            self.PatchObject(
                cros_chrome_sdk.ChromeSDKCommand,
                "_SetupGoma",
                side_effect=cros_chrome_sdk.GomaError(),
            )
            self.cmd_mock.inst.Run()
            self.AssertLogsContain(logs, "Goma:")

    def testSpecificComponent(self):
        """Verify SDKFetcher.Prepare() handles |components| param properly."""
        sdk = cros_chrome_sdk.SDKFetcher(
            os.path.join(self.tempdir), SDKFetcherMock.BOARD
        )
        components = [constants.BASE_IMAGE_TAR, constants.CHROME_SYSROOT_TAR]
        with sdk.Prepare(components=components) as ctx:
            for c in components:
                self.assertExists(ctx.key_map[c].path)
            for c in [constants.IMAGE_SCRIPTS_TAR, constants.CHROME_ENV_TAR]:
                self.assertFalse(c in ctx.key_map)

    @staticmethod
    def FindInPath(paths, endswith):
        for path in paths.split(":"):
            if path.endswith(endswith):
                return True
        return False

    def testGomaInPath(self):
        """Verify that we do indeed add Goma to the PATH."""
        self.PatchObject(
            cros_chrome_sdk.ChromeSDKCommand, "_GomaDir", side_effect=["XXXX"]
        )
        self.SetupCommandMock()
        self.cmd_mock.inst.Run()

        self.assertIn("use_goma = true", self.cmd_mock.env["GN_ARGS"])

    def testNoGoma(self):
        """Verify that we do not add Goma to the PATH."""
        self.SetupCommandMock(extra_args=["--nogoma"])
        self.cmd_mock.inst.Run()

        self.assertIn("use_goma = false", self.cmd_mock.env["GN_ARGS"])

    def testUseRBE(self):
        """Verify that we do not add Goma to the PATH."""
        self.SetupCommandMock(extra_args=["--use-remoteexec"])
        self.cmd_mock.inst.Run()

        self.assertIn("use_goma = false", self.cmd_mock.env["GN_ARGS"])
        self.assertIn("use_remoteexec = true", self.cmd_mock.env["GN_ARGS"])
        wrapper_path = os.path.join(
            self.chrome_root,
            "src",
            "build",
            "args",
            "chromeos",
            "rewrapper_%s" % SDKFetcherMock.BOARD,
        )
        self.assertIn(
            'rbe_cros_cc_wrapper = "%s"' % wrapper_path,
            self.cmd_mock.env["GN_ARGS"],
        )

    def testUseRBELacros(self):
        """Verify that we do not add Goma to the PATH."""
        self.SetupCommandMock(
            extra_args=["--use-remoteexec", "--is-lacros", "--version=1234.0.0"]
        )
        lkgm_file = os.path.join(
            self.chrome_src_dir, constants.PATH_TO_CHROME_LKGM
        )
        osutils.Touch(lkgm_file, makedirs=True)
        osutils.WriteFile(lkgm_file, "5678.0.0")

        self.cmd_mock.inst.Run()

        self.assertIn("use_goma = false", self.cmd_mock.env["GN_ARGS"])
        self.assertIn("use_remoteexec = true", self.cmd_mock.env["GN_ARGS"])
        wrapper_path = os.path.join(
            self.chrome_root,
            "src",
            "build",
            "args",
            "chromeos",
            "rewrapper_%s" % SDKFetcherMock.BOARD,
        )
        self.assertIn(
            'rbe_cros_cc_wrapper = "%s"' % wrapper_path,
            self.cmd_mock.env["GN_ARGS"],
        )

    def testGnArgsStalenessCheckNoMatch(self):
        """Verifies the GN args are checked for staleness with a mismatch."""
        with cros_test_lib.LoggingCapturer() as logs:
            out_dir = "out_%s" % SDKFetcherMock.BOARD
            build_label = "Release"
            gn_args_file_dir = os.path.join(
                self.chrome_src_dir, out_dir, build_label
            )
            gn_args_file_path = os.path.join(gn_args_file_dir, "args.gn")
            osutils.SafeMakedirs(gn_args_file_dir)
            osutils.WriteFile(gn_args_file_path, 'foo = "no match"')

            self.SetupCommandMock()
            self.cmd_mock.inst.Run()

            self.AssertLogsContain(logs, "Stale args.gn file")

    def testGnArgsStalenessCheckMatch(self):
        """Verifies the GN args are checked for staleness with a match."""
        with cros_test_lib.LoggingCapturer() as logs:
            self.SetupCommandMock()
            self.cmd_mock.inst.Run()

            out_dir = "out_%s" % SDKFetcherMock.BOARD
            build_label = "Release"
            gn_args_file_dir = os.path.join(
                self.chrome_src_dir, out_dir, build_label
            )
            gn_args_file_path = os.path.join(gn_args_file_dir, "args.gn")

            osutils.SafeMakedirs(gn_args_file_dir)
            osutils.WriteFile(gn_args_file_path, self.cmd_mock.env["GN_ARGS"])

            self.cmd_mock.inst.Run()

            self.AssertLogsContain(logs, "Stale args.gn file", inverted=True)

    def testGnArgsStalenessExtraArgs(self):
        """Verifies the GN extra args regenerate gn."""
        with cros_test_lib.LoggingCapturer() as logs:
            self.SetupCommandMock(
                extra_args=["--gn-extra-args=dcheck_always_on=true"]
            )
            self.cmd_mock.inst.Run()

            out_dir = "out_%s" % SDKFetcherMock.BOARD
            build_label = "Release"
            gn_args_file_dir = os.path.join(
                self.chrome_src_dir, out_dir, build_label
            )
            gn_args_file_path = os.path.join(gn_args_file_dir, "args.gn")

            osutils.SafeMakedirs(gn_args_file_dir)
            gn_args_dict = gn_helpers.FromGNArgs(self.cmd_mock.env["GN_ARGS"])
            osutils.WriteFile(
                gn_args_file_path, gn_helpers.ToGNString(gn_args_dict)
            )

            self.cmd_mock.inst.Run()

            self.AssertLogsContain(logs, "Stale args.gn file", inverted=True)

    def testChromiumOutDirSet(self):
        """Verify that CHROMIUM_OUT_DIR is set."""
        self.SetupCommandMock()
        self.cmd_mock.inst.Run()

        out_dir = os.path.join(
            self.chrome_src_dir, "out_%s" % SDKFetcherMock.BOARD
        )

        self.assertEqual(out_dir, self.cmd_mock.env["CHROMIUM_OUT_DIR"])

    @mock.patch("chromite.lib.gclient.LoadGclientFile")
    def testInternalGclientSpec(self, mock_gclient_load):
        """Verify the SDK exits with an error if the gclient spec is wrong."""
        self.SetupCommandMock(extra_args=["--internal"])

        # Simple Chrome should exit with an error if "--internal" is passed and
        # "checkout_src_internal" isn't present in the .gclient file.
        mock_gclient_load.return_value = [
            {
                "url": "https://chromium.googlesource.com/chromium/src.git",
                "custom_deps": {},
                "custom_vars": {},
            }
        ]
        with self.assertRaises(cros_build_lib.DieSystemExit):
            self.cmd_mock.inst.Run()

        # With "checkout_src_internal" set, Simple Chrome should run without
        # error.
        mock_gclient_load.return_value = [
            {
                "url": "https://chromium.googlesource.com/chromium/src.git",
                "custom_deps": {},
                "custom_vars": {"checkout_src_internal": True},
            }
        ]
        self.cmd_mock.inst.Run()

    def testClearSDKCache(self):
        """Verifies cache directories are removed with --clear-sdk-cache."""
        # Ensure we have checkout type GCLIENT.
        self.PatchObject(os, "getcwd", return_value=self.chrome_root)

        # Use the default cache location.
        self.SetupCommandMock(
            extra_args=["--clear-sdk-cache"], default_cache_dir=True
        )
        chrome_cache = os.path.join(self.chrome_src_dir, "build/cros_cache")
        self.assertNotExists(chrome_cache)

        self.cmd_mock.inst.Run()
        self.assertExists(chrome_cache)

    def testSeabiosDownload(self):
        """Verify _CreateSeabiosFWSymlinks.

        Create qemu/seabios directory structure with expected symlinks,
        break the symlinks, and verify that they get fixed.
        """
        qemu_share = os.path.join(
            self.tempdir,
            "chrome-sdk/tarballs/app-emulation/qemu/some-fake-hash/usr/share",
        )
        seabios_share = os.path.join(
            self.tempdir,
            "chrome-sdk/tarballs/sys-firmware/seabios/some-fake-hash/usr/share",
        )

        # Create qemu subdirectories.
        for share_dir in ["qemu", "seabios", "seavgabios"]:
            os.makedirs(os.path.join(qemu_share, share_dir))

        def _CreateLink(share, bios_dir, bios):
            src_file = os.path.join(share, bios_dir, bios)
            dest_file = os.path.join(share, "qemu", bios)
            osutils.Touch(src_file, makedirs=True)
            rel_path = os.path.relpath(src_file, os.path.dirname(dest_file))
            os.symlink(rel_path, dest_file)

        def _VerifyLinks(broken):
            """Verfies that the links are |broken|."""
            qemu_share_dir = os.path.join(qemu_share, "qemu")
            for link in os.listdir(qemu_share_dir):
                full_link = os.path.join(qemu_share_dir, link)
                self.assertTrue(os.path.islink(full_link))
                self.assertNotEqual(os.path.exists(full_link), broken)

        # Create qemu links.
        for bios in ["bios.bin", "bios256k.bin"]:
            _CreateLink(qemu_share, "seabios", bios)
        for bios in [
            "vgabios-vmware.bin",
            "vgabios-virtio.bin",
            "vgabios-stdvga.bin",
            "vgabios-qxl.bin",
            "vgabios-cirrus.bin",
            "vgabios.bin",
        ]:
            _CreateLink(qemu_share, "seavgabios", bios)

        # Move the seabios/seavgabios directories into the seabios package,
        # which breaks the links.
        for bios_dir in ["seabios", "seavgabios"]:
            shutil.move(
                os.path.join(qemu_share, bios_dir),
                os.path.join(seabios_share, bios_dir),
            )
        _VerifyLinks(broken=True)

        # Run the command and verify the links get fixed.
        self.SetupCommandMock(extra_args=["--download-vm"])
        self.cmd_mock.inst.Run()
        _VerifyLinks(broken=False)

    def testSymlinkCache(self):
        """Verify the symlink cache contains valid tarball cache links."""
        self.SetupCommandMock()
        self.cmd_mock.inst.Run()

        board, version, _ = self.VERSION_KEY
        toolchain_dir = os.path.join(
            self.tempdir, "chrome-sdk/tarballs/target_toolchain/some-fake-hash"
        )
        sysroot_dir = os.path.join(
            self.tempdir,
            "chrome-sdk/tarballs/sysroot_chromeos-base_chromeos-chrome.tar.xz/"
            "some-fake-hash",
        )
        self.assertExists(toolchain_dir)
        self.assertExists(sysroot_dir)
        toolchain_link = os.path.join(
            self.tempdir,
            "chrome-sdk/symlinks/%s+%s+target_toolchain" % (board, version),
        )
        sysroot_link = os.path.join(
            self.tempdir,
            "chrome-sdk/symlinks/%s+%s+sysroot_chromeos-base_chromeos-"
            "chrome.tar.xz" % (board, version),
        )
        self.assertTrue(os.path.islink(toolchain_link))
        self.assertTrue(os.path.islink(sysroot_link))
        self.assertEqual(os.path.realpath(toolchain_link), toolchain_dir)
        self.assertEqual(os.path.realpath(sysroot_link), sysroot_dir)

    def testSymlinkCacheToolchainOverride(self):
        """Ensures that the SDK picks up an overridden component."""
        sdk = cros_chrome_sdk.SDKFetcher(
            os.path.join(self.tempdir), SDKFetcherMock.BOARD
        )
        board, version, _ = self.VERSION_KEY
        toolchain_link = os.path.join(
            self.tempdir,
            "chrome-sdk/symlinks/%s+%s+target_toolchain" % (board, version),
        )
        components = [sdk.TARGET_TOOLCHAIN_KEY]

        toolchain_url_1 = "some-fake-gs-path-1"
        toolchain_dir_1 = os.path.join(
            self.tempdir,
            "chrome-sdk/tarballs/target_toolchain/",
            toolchain_url_1,
        )
        toolchain_url_2 = "some-fake-gs-path-2"
        toolchain_dir_2 = os.path.join(
            self.tempdir,
            "chrome-sdk/tarballs/target_toolchain/",
            toolchain_url_2,
        )
        nacl_toolchain_dir = os.path.join(
            self.tempdir, "chrome-sdk/tarballs/arm32_toolchain_for_nacl_helper/"
        )

        # Prepare the cache using 'toolchain_url_1'.
        self.sdk_mock.tarball_cache_key_map = {
            sdk.TARGET_TOOLCHAIN_KEY: toolchain_url_1
        }
        with sdk.Prepare(components, toolchain_url=toolchain_url_1):
            self.assertEqual(toolchain_dir_1, os.path.realpath(toolchain_link))
            self.assertExists(toolchain_dir_1)
            self.assertNotExists(toolchain_dir_2)

        # Prepare the cache with 'toolchain_url_2' and make sure the active
        # symlink points to it and that 'toolchain_url_1' is still present.
        self.sdk_mock.tarball_cache_key_map = {
            sdk.TARGET_TOOLCHAIN_KEY: toolchain_url_2
        }
        with sdk.Prepare(components, toolchain_url=toolchain_url_2):
            self.assertEqual(toolchain_dir_2, os.path.realpath(toolchain_link))
            self.assertExists(toolchain_dir_2)
            self.assertExists(toolchain_dir_1)

        # Test that arm32 toolchain is fetched for NaCl for arm64.
        with sdk.Prepare(
            components, toolchain_url=toolchain_url_2, target_tc=sdk.ARM64_TUPLE
        ):
            self.assertExists(nacl_toolchain_dir)


class GomaTest(
    cros_test_lib.MockTempDirTestCase, cros_test_lib.LoggingTestCase
):
    """Test Goma setup functionality."""

    def setUp(self):
        self.rc_mock = cros_test_lib.RunCommandMock()
        self.rc_mock.SetDefaultCmdResult()
        self.StartPatcher(self.rc_mock)

        self.cmd_mock = MockChromeSDKCommand(
            ["--board", SDKFetcherMock.BOARD, "true"],
            base_args=["--cache-dir", str(self.tempdir)],
        )
        self.StartPatcher(self.cmd_mock)

    def VerifyGomaError(self):
        self.assertRaises(
            cros_chrome_sdk.GomaError, self.cmd_mock.inst._SetupGoma
        )

    def testNoGomaPort(self):
        """We print an error when gomacc is not returning a port."""
        self.rc_mock.AddCmdResult(
            cros_chrome_sdk.ChromeSDKCommand.GOMACC_PORT_CMD
        )
        self.VerifyGomaError()

    def testGomaccError(self):
        """We print an error when gomacc exits with nonzero returncode."""
        self.rc_mock.AddCmdResult(
            cros_chrome_sdk.ChromeSDKCommand.GOMACC_PORT_CMD, returncode=1
        )
        self.VerifyGomaError()

    def testSetupError(self):
        """We print an error when we can't fetch Goma."""
        self.rc_mock.AddCmdResult(
            cros_chrome_sdk.ChromeSDKCommand.GOMACC_PORT_CMD, returncode=1
        )
        self.VerifyGomaError()

    def testGomaStart(self):
        """Test that we start Goma if it's not already started."""
        # Duplicate return values.
        self.PatchObject(
            cros_chrome_sdk.ChromeSDKCommand, "_GomaDir", side_effect=["XXXX"]
        )
        self.PatchObject(
            cros_chrome_sdk.ChromeSDKCommand,
            "_GomaPort",
            side_effect=["XXXX", "XXXX"],
        )
        goma_dir, goma_port = self.cmd_mock.inst._SetupGoma()
        self.assertEqual(goma_port, "XXXX")
        self.assertTrue(bool(goma_dir))


class VersionTest(
    gs_unittest.AbstractGSContextTest, cros_test_lib.LoggingTestCase
):
    """Tests the determination of which SDK version to use."""

    VERSION = "3543.0.0"
    FULL_VERSION = "R55-%s" % VERSION
    RECENT_VERSION_FOUND = "3541.0.0"
    FULL_VERSION_RECENT = "R55-%s" % RECENT_VERSION_FOUND
    NON_CANARY_VERSION = "3543.2.1"
    FULL_VERSION_NON_CANARY = "R55-%s" % NON_CANARY_VERSION
    BOARD = "eve"

    VERSION_BASE = "gs://chromeos-image-archive/%s-release/LATEST-%s" % (
        BOARD,
        VERSION,
    )

    CAT_ERROR = "CommandException: No URLs matched %s" % VERSION_BASE
    LS_ERROR = "CommandException: One or more URLs matched no objects."

    def setUp(self):
        self.sdk_mock = self.StartPatcher(
            SDKFetcherMock(external_mocks=[self.gs_mock])
        )

        os.environ.pop(cros_chrome_sdk.SDKFetcher.SDK_VERSION_ENV, None)
        self.sdk = cros_chrome_sdk.SDKFetcher(
            os.path.join(self.tempdir, "cache"), self.BOARD
        )

    def testUpdateDefaultChromeVersion(self):
        """We pick up the right LKGM version from the Chrome tree."""
        dir_struct = ["gclient_root/.gclient"]
        cros_test_lib.CreateOnDiskHierarchy(self.tempdir, dir_struct)
        gclient_root = os.path.join(self.tempdir, "gclient_root")
        self.PatchObject(os, "getcwd", return_value=gclient_root)

        lkgm_file = os.path.join(
            gclient_root, "src", constants.PATH_TO_CHROME_LKGM
        )
        osutils.Touch(lkgm_file, makedirs=True)
        osutils.WriteFile(lkgm_file, self.VERSION)

        self.sdk_mock.UnMockAttr("UpdateDefaultVersion")
        self.sdk.UpdateDefaultVersion()
        self.assertEqual(self.sdk.GetDefaultVersion(), self.VERSION)

    def testFullVersionFromFullVersion(self):
        """Test that a fully specified version is allowed."""
        self.sdk_mock.UnMockAttr("GetFullVersion")
        self.gs_mock.AddCmdResult(
            partial_mock.ListRegex("cat .*/LATEST-%s" % self.VERSION),
            stdout=self.FULL_VERSION,
        )
        self.assertEqual(
            self.FULL_VERSION, self.sdk.GetFullVersion(self.FULL_VERSION)
        )

    def testFullVersionCaching(self):
        """Test full version calculation and caching."""

        def RaiseException(*_args, **_kwargs):
            raise Exception("boom")

        self.sdk_mock.UnMockAttr("GetFullVersion")
        self.gs_mock.AddCmdResult(
            partial_mock.ListRegex("cat .*/LATEST-%s" % self.VERSION),
            stdout=self.FULL_VERSION,
        )
        self.assertEqual(
            self.FULL_VERSION, self.sdk.GetFullVersion(self.VERSION)
        )
        # Test that we access the cache on the next call, rather than checking
        # GS.
        self.gs_mock.AddCmdResult(
            partial_mock.ListRegex("cat .*/LATEST-%s" % self.VERSION),
            side_effect=RaiseException,
        )
        self.assertEqual(
            self.FULL_VERSION, self.sdk.GetFullVersion(self.VERSION)
        )
        # Test that we access GS again if the board is changed.
        self.sdk.board += "2"
        self.gs_mock.AddCmdResult(
            partial_mock.ListRegex("cat .*/LATEST-%s" % self.VERSION),
            stdout=self.FULL_VERSION + "2",
        )
        self.assertEqual(
            self.FULL_VERSION + "2", self.sdk.GetFullVersion(self.VERSION)
        )

    def testNoLatestVersion(self):
        """We raise an exception when there is no recent latest version."""
        self.sdk_mock.UnMockAttr("GetFullVersion")
        self.gs_mock.AddCmdResult(
            partial_mock.ListRegex("cat .*/LATEST-*"),
            stdout="",
            stderr=self.CAT_ERROR,
            returncode=1,
        )
        self.gs_mock.AddCmdResult(
            partial_mock.ListRegex("ls .*%s" % self.VERSION),
            stdout="",
            stderr=self.LS_ERROR,
            returncode=1,
        )
        self.assertRaises(
            cros_chrome_sdk.MissingSDK, self.sdk.GetFullVersion, self.VERSION
        )

    def testDefaultEnvBadBoard(self):
        """Verify skips version in the environment if board doesn't match."""
        os.environ[cros_chrome_sdk.SDKFetcher.SDK_VERSION_ENV] = self.VERSION
        self.assertNotEqual(self.VERSION, self.sdk_mock.VERSION)
        self.assertEqual(self.sdk.GetDefaultVersion(), None)

    def testDefaultEnvGoodBoard(self):
        """We use the version in the environment if board matches."""
        sdk_version_env = cros_chrome_sdk.SDKFetcher.SDK_VERSION_ENV
        os.environ[sdk_version_env] = self.VERSION
        os.environ[cros_chrome_sdk.SDKFetcher.SDK_BOARD_ENV] = self.BOARD
        self.assertEqual(self.sdk.GetDefaultVersion(), self.VERSION)


class PathVerifyTest(
    cros_test_lib.MockTempDirTestCase, cros_test_lib.LoggingTestCase
):
    """Tests user_rc PATH validation and warnings."""

    def testPathVerifyWarnings(self):
        """Test the user rc PATH verification codepath."""

        def SourceEnvironmentMock(*_args, **_kwargs):
            return {
                "PATH": ":".join([os.path.dirname(p) for p in abs_paths]),
            }

        self.PatchObject(
            osutils, "SourceEnvironment", side_effect=SourceEnvironmentMock
        )
        file_list = (
            "goma/goma_ctl.py",
            "clang/clang",
            "chromite/parallel_emerge",
        )
        abs_paths = [
            os.path.join(self.tempdir, relpath) for relpath in file_list
        ]
        for p in abs_paths:
            osutils.Touch(p, makedirs=True, mode=0o755)

        with cros_test_lib.LoggingCapturer() as logs:
            cros_chrome_sdk.ChromeSDKCommand._VerifyGoma(None)
            cros_chrome_sdk.ChromeSDKCommand._VerifyChromiteBin(None)

        for msg in ["managed Goma", "default Chromite"]:
            self.AssertLogsMatch(logs, msg)


class ClearOldItemsTest(
    cros_test_lib.MockTempDirTestCase, cros_test_lib.LoggingTestCase
):
    """Tests SDKFetcher.ClearOldItems() behavior."""

    def setUp(self):
        """Sets up a temporary symlink & tarball cache."""
        self.gs_mock = self.StartPatcher(gs_unittest.GSContextMock())
        self.gs_mock.SetDefaultCmdResult()

        self.sdk_fetcher = cros_chrome_sdk.SDKFetcher(
            self.tempdir, "", use_external_config=True
        )

    def testBrokenSymlinkCleared(self):
        """Adds a broken symlink and ensures it gets removed."""
        osutils.Touch(os.path.join(self.tempdir, "some-file"))
        valid_link_ref = self.sdk_fetcher.symlink_cache.Lookup(
            "some-valid-link"
        )
        with valid_link_ref:
            self.sdk_fetcher._UpdateCacheSymlink(
                valid_link_ref, os.path.join(self.tempdir, "some-file")
            )

        broken_link_ref = self.sdk_fetcher.symlink_cache.Lookup(
            "some-broken-link"
        )
        with broken_link_ref:
            self.sdk_fetcher._UpdateCacheSymlink(
                broken_link_ref, "/some/invalid/file"
            )

        # Broken symlink should exist before the ClearOldItems() call, and be
        # removed after.
        self.assertTrue(valid_link_ref.Exists())
        self.assertTrue(broken_link_ref.Exists())
        cros_chrome_sdk.SDKFetcher.ClearOldItems(self.tempdir)
        self.assertTrue(valid_link_ref.Exists())
        self.assertFalse(broken_link_ref.Exists())
