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

"""packages controller unit tests."""

from unittest import mock

from chromite.api.api_config import ApiConfigMixin
from chromite.api.controller import controller_util
from chromite.api.controller import packages as packages_controller
from chromite.api.gen.chromite.api import binhost_pb2
from chromite.api.gen.chromite.api import packages_pb2
from chromite.api.gen.chromiumos import common_pb2
from chromite.lib import build_target_lib
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import cros_test_lib
from chromite.lib import portage_util
from chromite.lib import uprev_lib
from chromite.lib.parser import package_info
from chromite.service import packages as packages_service


class UprevTest(cros_test_lib.MockTestCase, ApiConfigMixin):
    """Uprev tests."""

    _PUBLIC = binhost_pb2.OVERLAYTYPE_PUBLIC
    _PRIVATE = binhost_pb2.OVERLAYTYPE_PRIVATE
    _BOTH = binhost_pb2.OVERLAYTYPE_BOTH
    _NONE = binhost_pb2.OVERLAYTYPE_NONE

    def setUp(self):
        self.uprev_patch = self.PatchObject(
            packages_service, "uprev_build_targets"
        )
        self.response = packages_pb2.UprevPackagesResponse()

    def _GetRequest(self, targets=None, overlay_type=None, output_dir=None):
        return packages_pb2.UprevPackagesRequest(
            build_targets=[{"name": name} for name in targets or []],
            overlay_type=overlay_type,
            output_dir=output_dir,
        )

    def testValidateOnly(self):
        """Verify a validate-only call does not execute any logic."""
        patch = self.PatchObject(packages_service, "uprev_build_targets")

        targets = ["foo", "bar"]
        request = self._GetRequest(targets=targets, overlay_type=self._BOTH)
        packages_controller.Uprev(
            request, self.response, self.validate_only_config
        )
        patch.assert_not_called()

    def testMockCall(self):
        """Test a mock call does not execute logic, returns mocked value."""
        patch = self.PatchObject(packages_service, "uprev_build_targets")
        targets = ["foo", "bar"]
        request = self._GetRequest(targets=targets, overlay_type=self._BOTH)
        packages_controller.Uprev(request, self.response, self.mock_call_config)
        patch.assert_not_called()
        self.assertTrue(self.response.modified_ebuilds)

    def testNoOverlayTypeFails(self):
        """No overlay type provided should fail."""
        request = self._GetRequest(targets=["foo"])

        with self.assertRaises(cros_build_lib.DieSystemExit):
            packages_controller.Uprev(request, self.response, self.api_config)

    def testOverlayTypeNoneFails(self):
        """Overlay type none means nothing here and should fail."""
        request = self._GetRequest(targets=["foo"], overlay_type=self._NONE)

        with self.assertRaises(cros_build_lib.DieSystemExit):
            packages_controller.Uprev(request, self.response, self.api_config)

    def testSuccess(self):
        """Test overall successful argument handling."""
        targets = ["foo", "bar"]
        output_dir = "/tmp/uprev_output_dir"
        changed = ["/ebuild-1.0-r1.ebuild", "/ebuild-1.0-r2.ebuild"]
        revved_packages = ["cat1/pkg1-1.11", "cat2/pkg2-1.12"]
        expected_type = constants.BOTH_OVERLAYS
        request = self._GetRequest(
            targets=targets, overlay_type=self._BOTH, output_dir=output_dir
        )
        uprev_patch = self.PatchObject(
            packages_service,
            "uprev_build_targets",
            return_value=(changed, revved_packages),
        )

        packages_controller.Uprev(request, self.response, self.api_config)

        # Make sure the type is right, verify build targets after.
        uprev_patch.assert_called_once_with(
            mock.ANY, expected_type, mock.ANY, output_dir
        )
        # First argument (build targets) of the first (only) call.
        call_targets = uprev_patch.call_args[0][0]
        self.assertCountEqual(targets, [t.name for t in call_targets])

        for ebuild in self.response.modified_ebuilds:
            self.assertIn(ebuild.path, changed)
            changed.remove(ebuild.path)
        self.assertFalse(changed)

        for pkg in self.response.packages:
            self.assertTrue(pkg.category.startswith("cat"))
            self.assertTrue(pkg.package_name.startswith("pkg"))
            self.assertTrue(pkg.version.startswith("1.1"))


class UprevVersionedPackageTest(cros_test_lib.MockTestCase, ApiConfigMixin):
    """UprevVersionedPackage tests."""

    def setUp(self):
        self.response = packages_pb2.UprevVersionedPackageResponse()

    def _addVersion(self, request, version):
        """Helper method to add a full version message to the request."""
        ref = request.versions.add()
        ref.repository = "/some/path"
        ref.ref = "refs/tags/%s" % version
        ref.revision = "abc123"

    def testValidateOnly(self):
        """Sanity check validate only calls are working properly."""
        service = self.PatchObject(packages_service, "uprev_versioned_package")

        request = packages_pb2.UprevVersionedPackageRequest()
        self._addVersion(request, "1.2.3.4")
        request.package_info.category = "chromeos-base"
        request.package_info.package_name = "chromeos-chrome"

        packages_controller.UprevVersionedPackage(
            request, self.response, self.validate_only_config
        )

        service.assert_not_called()

    def testMockCall(self):
        """Test a mock call does not execute logic, returns mocked value."""
        patch = self.PatchObject(packages_service, "uprev_versioned_package")
        request = packages_pb2.UprevVersionedPackageRequest()
        packages_controller.UprevVersionedPackage(
            request, self.response, self.mock_call_config
        )
        patch.assert_not_called()
        self.assertTrue(self.response.responses)
        self.assertTrue(self.response.responses[0].modified_ebuilds)

    def testNoVersions(self):
        """Test no versions provided."""
        request = packages_pb2.UprevVersionedPackageRequest()
        request.package_info.category = "chromeos-base"
        request.package_info.package_name = "chromeos-chrome"

        with self.assertRaises(cros_build_lib.DieSystemExit):
            packages_controller.UprevVersionedPackage(
                request, self.response, self.api_config
            )

    def testNoPackageName(self):
        """Test no package name provided."""
        request = packages_pb2.UprevVersionedPackageRequest()
        self._addVersion(request, "1.2.3.4")
        request.package_info.category = "chromeos-base"

        with self.assertRaises(cros_build_lib.DieSystemExit):
            packages_controller.UprevVersionedPackage(
                request, self.response, self.api_config
            )

    def testNoCategory(self):
        """Test no package category provided."""
        request = packages_pb2.UprevVersionedPackageRequest()
        self._addVersion(request, "1.2.3.4")
        request.package_info.package_name = "chromeos-chrome"

        with self.assertRaises(cros_build_lib.DieSystemExit):
            packages_controller.UprevVersionedPackage(
                request, self.response, self.api_config
            )

    def testOutputHandling(self):
        """Test the modified files are getting correctly added to the output."""
        version = "1.2.3.4"
        result = uprev_lib.UprevVersionedPackageResult().add_result(
            version, ["/file/one", "/file/two"]
        )

        self.PatchObject(
            packages_service, "uprev_versioned_package", return_value=result
        )

        request = packages_pb2.UprevVersionedPackageRequest()
        self._addVersion(request, version)
        request.package_info.category = "chromeos-base"
        request.package_info.package_name = "chromeos-chrome"

        packages_controller.UprevVersionedPackage(
            request, self.response, self.api_config
        )

        for idx, uprev_response in enumerate(self.response.responses):
            self.assertEqual(
                result.modified[idx].new_version, uprev_response.version
            )
            self.assertCountEqual(
                result.modified[idx].files,
                [ebuild.path for ebuild in uprev_response.modified_ebuilds],
            )


class GetBestVisibleTest(cros_test_lib.MockTestCase, ApiConfigMixin):
    """GetBestVisible tests."""

    def setUp(self):
        self.response = packages_pb2.GetBestVisibleResponse()

    def _GetRequest(self, atom=None):
        return packages_pb2.GetBestVisibleRequest(
            atom=atom,
        )

    def testValidateOnly(self):
        """Verify a validate-only call does not execute any logic."""
        patch = self.PatchObject(packages_service, "get_best_visible")

        request = self._GetRequest(atom="chromeos-chrome")
        packages_controller.GetBestVisible(
            request, self.response, self.validate_only_config
        )
        patch.assert_not_called()

    def testMockCall(self):
        """Test a mock call does not execute logic, returns mocked value."""
        patch = self.PatchObject(packages_service, "get_best_visible")
        request = self._GetRequest(atom="chromeos-chrome")
        packages_controller.GetBestVisible(
            request, self.response, self.mock_call_config
        )
        patch.assert_not_called()
        self.assertTrue(self.response.package_info)
        self.assertTrue(self.response.package_info.category)
        self.assertTrue(self.response.package_info.package_name)
        self.assertTrue(self.response.package_info.version)

    def testNoAtomFails(self):
        """No atom provided should fail."""
        request = self._GetRequest()
        with self.assertRaises(cros_build_lib.DieSystemExit):
            packages_controller.GetBestVisible(
                request, self.response, self.api_config
            )

    def testSuccess(self):
        """Test overall success, argument handling, result forwarding."""
        pkg = package_info.PackageInfo("category", "package", "1.2.3.4", 5)
        self.PatchObject(packages_service, "get_best_visible", return_value=pkg)

        request = self._GetRequest(atom="category/package")

        packages_controller.GetBestVisible(
            request, self.response, self.api_config
        )

        package_info_msg = self.response.package_info
        self.assertEqual(package_info_msg.category, pkg.category)
        self.assertEqual(package_info_msg.package_name, pkg.package)
        self.assertEqual(package_info_msg.version, pkg.vr)


class GetChromeVersion(cros_test_lib.MockTestCase, ApiConfigMixin):
    """GetChromeVersion tests."""

    def setUp(self):
        self.response = packages_pb2.GetChromeVersionResponse()

    def _GetRequest(self, board=None):
        """Helper to build out a request."""
        request = packages_pb2.GetChromeVersionRequest()

        if board:
            request.build_target.name = board

        return request

    def testValidateOnly(self):
        """Verify a validate-only call does not execute any logic."""
        chrome_version = self.PatchObject(
            packages_service, "determine_package_version"
        )
        request = self._GetRequest(board="betty")
        packages_controller.GetChromeVersion(
            request, self.response, self.validate_only_config
        )
        chrome_version.assert_not_called()

    def testMockCall(self):
        """Test a mock call does not execute logic, returns mocked value."""
        chrome_version = self.PatchObject(
            packages_service, "determine_package_version"
        )
        request = self._GetRequest(board="betty")
        packages_controller.GetChromeVersion(
            request, self.response, self.mock_call_config
        )
        chrome_version.assert_not_called()
        self.assertTrue(self.response.version)

    def testGetChromeVersion(self):
        """Verify basic return values."""
        chrome_version = "76.0.1.2"
        chrome_version_mock = self.PatchObject(
            packages_service,
            "determine_package_version",
            return_value=chrome_version,
        )
        request = self._GetRequest(board="betty")
        packages_controller.GetChromeVersion(
            request, self.response, self.api_config
        )
        self.assertEqual(self.response.version, chrome_version)
        # Verify call to determine_package_version passes a build_target object.
        build_target = build_target_lib.BuildTarget("betty")
        chrome_version_mock.assert_called_with(
            constants.CHROME_CP, build_target
        )

    def testGetChromeVersionHandleNone(self):
        """Verify basic return values."""
        self.PatchObject(
            packages_service, "determine_package_version", return_value=None
        )
        request = self._GetRequest(board="betty")
        packages_controller.GetChromeVersion(
            request, self.response, self.api_config
        )
        self.assertFalse(self.response.version)


class GetTargetVersionsTest(cros_test_lib.MockTestCase, ApiConfigMixin):
    """GetTargetVersions tests."""

    def setUp(self):
        self.response = packages_pb2.GetTargetVersionsResponse()

    def _GetRequest(self, board=None):
        """Helper to build out a request."""
        request = packages_pb2.GetTargetVersionsRequest()

        if board:
            request.build_target.name = board

        return request

    def testValidateOnly(self):
        """Quick check that a validate only call does not execute any logic."""
        patch_version = self.PatchObject(
            packages_service, "get_target_versions"
        )

        request = self._GetRequest(board="betty")
        packages_controller.GetTargetVersions(
            request, self.response, self.validate_only_config
        )
        patch_version.assert_not_called()

    def testMockCall(self):
        """Test a mock call does not execute logic, returns mocked value."""
        patch_version = self.PatchObject(
            packages_service, "get_target_versions"
        )

        request = self._GetRequest(board="betty")
        packages_controller.GetTargetVersions(
            request, self.response, self.mock_call_config
        )

        patch_version.assert_not_called()

        self.assertTrue(self.response.android_version)
        self.assertTrue(self.response.android_branch_version)
        self.assertTrue(self.response.android_target_version)
        self.assertTrue(self.response.chrome_version)
        self.assertTrue(self.response.platform_version)
        self.assertTrue(self.response.milestone_version)
        self.assertTrue(self.response.full_version)

    def testNoBuildTargetFails(self):
        """No build target argument should fail."""
        request = self._GetRequest()

        with self.assertRaises(cros_build_lib.DieSystemExit):
            packages_controller.GetTargetVersions(
                request, self.response, self.api_config
            )

    def testGetTargetVersions(self):
        """Verify basic return values."""
        # Mock that chrome is built and set the chrome_version.
        self.PatchObject(packages_service, "builds", return_value=True)
        chrome_version = "76.0.1.2"
        lacros_version = "100.0.0.1"
        package_version_mock = self.PatchObject(
            packages_service,
            "determine_package_version",
            side_effect=[chrome_version, lacros_version],
        )
        android_package = "chromeos-base/android-container-pi-10.3"
        self.PatchObject(
            packages_service,
            "determine_android_package",
            return_value=android_package,
        )
        android_branch = "android_test_branch"
        android_branch_mock = self.PatchObject(
            packages_service,
            "determine_android_branch",
            return_value=android_branch,
        )
        platform_version = "12345.1.2"
        self.PatchObject(
            packages_service,
            "determine_platform_version",
            return_value=platform_version,
        )
        milestone_version = "79"
        self.PatchObject(
            packages_service,
            "determine_milestone_version",
            return_value=milestone_version,
        )
        full_version = "R79-12345.1.2"
        self.PatchObject(
            packages_service,
            "determine_full_version",
            return_value=full_version,
        )
        request = self._GetRequest(board="betty")
        packages_controller.GetTargetVersions(
            request, self.response, self.api_config
        )
        self.assertEqual(self.response.android_version, "10.3")
        self.assertEqual(self.response.android_branch_version, android_branch)
        self.assertEqual(self.response.android_target_version, "cheets")
        self.assertEqual(self.response.chrome_version, chrome_version)
        self.assertEqual(self.response.platform_version, platform_version)
        self.assertEqual(self.response.milestone_version, milestone_version)
        self.assertEqual(self.response.full_version, full_version)
        self.assertEqual(self.response.lacros_version, lacros_version)
        # Verify call to determine_chrome_version passes a build_target object.
        build_target = build_target_lib.BuildTarget("betty")
        package_version_mock.assert_has_calls(
            calls=[
                mock.call(constants.CHROME_CP, build_target),
                mock.call(constants.LACROS_CP, build_target),
            ]
        )
        # Verify call to determine_android_branch passes a board name.
        android_branch_mock.assert_called_with("betty")

    def testGetTargetVersionsWithPackagesSet(self):
        """Verify packages pass through and basic return values."""
        # TODO(crbug.com/1124393): Migrate this test to use portage_testables
        # rather than mocking the boundary to portage calls such as
        # packages_service.builds).
        builds_mock = self.PatchObject(
            packages_service, "builds", return_value=True
        )
        # Mock that chrome is built and set the chrome_version.
        chrome_version = "76.0.1.2"
        lacros_version = "100.0.0.1"
        self.PatchObject(
            packages_service,
            "determine_package_version",
            side_effect=[chrome_version, lacros_version],
        )
        android_package = "chromeos-base/android-container-pi-10.3"
        self.PatchObject(
            packages_service,
            "determine_android_package",
            return_value=android_package,
        )
        android_branch = "android_test_branch"
        self.PatchObject(
            packages_service,
            "determine_android_branch",
            return_value=android_branch,
        )
        platform_version = "12345.1.2"
        self.PatchObject(
            packages_service,
            "determine_platform_version",
            return_value=platform_version,
        )
        milestone_version = "79"
        self.PatchObject(
            packages_service,
            "determine_milestone_version",
            return_value=milestone_version,
        )
        full_version = "R79-12345.1.2"
        self.PatchObject(
            packages_service,
            "determine_full_version",
            return_value=full_version,
        )
        request = self._GetRequest(board="betty")
        # Add optional packages to the request.
        package_list = []
        package = request.packages.add()
        package.package_name = "test"
        package.category = "chromeos-base"
        package.version = "0.0.1-r1"
        package_list.append(controller_util.deserialize_package_info(package))
        package = request.packages.add()
        package.package_name = "target-fuzzers"
        package.category = "virtual"
        package_list.append(controller_util.deserialize_package_info(package))

        packages_controller.GetTargetVersions(
            request, self.response, self.api_config
        )
        self.assertEqual(self.response.android_version, "10.3")
        self.assertEqual(self.response.android_branch_version, android_branch)
        self.assertEqual(self.response.android_target_version, "cheets")
        self.assertEqual(self.response.chrome_version, chrome_version)
        self.assertEqual(self.response.platform_version, platform_version)
        self.assertEqual(self.response.milestone_version, milestone_version)
        self.assertEqual(self.response.lacros_version, lacros_version)
        # Verify call to packages.builds passes the package list.
        builds_mock.assert_has_calls(
            calls=[
                mock.call(constants.CHROME_CP, mock.ANY, packages=package_list),
                mock.call(constants.LACROS_CP, mock.ANY, packages=package_list),
            ]
        )

    def testGetTargetVersionNoAndroidNoChrome(self):
        """Verify return values on a board that does not have android."""
        platform_version = "12345.1.2"
        self.PatchObject(
            packages_service,
            "determine_platform_version",
            return_value=platform_version,
        )
        self.PatchObject(packages_service, "builds", return_value=False)
        self.PatchObject(
            packages_service, "determine_android_package", return_value=None
        )
        request = self._GetRequest(board="betty")
        packages_controller.GetTargetVersions(
            request, self.response, self.api_config
        )
        self.assertFalse(self.response.chrome_version)
        self.assertFalse(self.response.android_version)
        self.assertFalse(self.response.android_branch_version)
        self.assertFalse(self.response.android_target_version)
        self.assertEqual(self.response.platform_version, platform_version)


class GetBuilderMetadataTest(cros_test_lib.MockTestCase, ApiConfigMixin):
    """GetBuilderMetadata tests."""

    def setUp(self):
        self.response = packages_pb2.GetBuilderMetadataResponse()

    def _GetRequest(self, board=None):
        """Helper to build out a request."""
        request = packages_pb2.GetBuilderMetadataRequest()

        if board:
            request.build_target.name = board

        return request

    def testValidateOnly(self):
        """Verify a validate-only call does not execute any logic."""
        request = self._GetRequest(board="betty")
        patch_version = self.PatchObject(
            packages_service, "determine_android_version"
        )
        patch_branch_version = self.PatchObject(
            packages_service, "determine_android_branch"
        )
        patch_fw_versions = self.PatchObject(
            packages_service, "determine_firmware_versions"
        )
        patch_fingerprints = self.PatchObject(
            packages_service, "find_fingerprints"
        )
        patch_get_models = self.PatchObject(packages_service, "get_models")
        packages_controller.GetBuilderMetadata(
            request, self.response, self.validate_only_config
        )
        patch_version.assert_not_called()
        patch_branch_version.assert_not_called()
        patch_fw_versions.assert_not_called()
        patch_fingerprints.assert_not_called()
        patch_get_models.assert_not_called()

    def testMockCall(self):
        """Test a mock call does not execute logic, returns mocked value."""
        request = self._GetRequest(board="betty")
        patch_version = self.PatchObject(
            packages_service, "determine_android_version"
        )
        patch_branch_version = self.PatchObject(
            packages_service, "determine_android_branch"
        )
        patch_fw_versions = self.PatchObject(
            packages_service, "determine_firmware_versions"
        )
        patch_fingerprints = self.PatchObject(
            packages_service, "find_fingerprints"
        )
        patch_get_models = self.PatchObject(packages_service, "get_models")
        packages_controller.GetBuilderMetadata(
            request, self.response, self.mock_call_config
        )
        patch_version.assert_not_called()
        patch_branch_version.assert_not_called()
        patch_fw_versions.assert_not_called()
        patch_fingerprints.assert_not_called()
        patch_get_models.assert_not_called()

        self.assertEqual(len(self.response.build_target_metadata), 1)
        self.assertEqual(
            self.response.build_target_metadata[0].build_target,
            request.build_target.name,
        )
        self.assertEqual(len(self.response.model_metadata), 1)
        self.assertTrue(self.response.model_metadata[0].model_name)
        self.assertTrue(self.response.model_metadata[0].ec_firmware_version)

    def testNoBuildTargetFails(self):
        """No build target argument should fail."""
        request = self._GetRequest()

        with self.assertRaises(cros_build_lib.DieSystemExit):
            packages_controller.GetBuilderMetadata(
                request, self.response, self.api_config
            )

    def _patch_all(
        self,
        android_version,
        android_branch,
        android_target,
        fw_versions,
        fingerprints,
    ):
        """Patch everything that hasn't been broken out yet."""
        android_version_mock = self.PatchObject(
            packages_service,
            "determine_android_version",
            return_value=android_version,
        )
        android_branch_mock = self.PatchObject(
            packages_service,
            "determine_android_branch",
            return_value=android_branch,
        )
        android_target_mock = self.PatchObject(
            packages_service,
            "determine_android_target",
            return_value=android_target,
        )
        self.PatchObject(
            portage_util,
            "GetBoardUseFlags",
            return_value=["arc", "arcvm", "big_little", "cheets"],
        )

        kernel_candidates = [
            "sys-kernel/chromeos-kernel-4_4-4.4.223-r2209",
            "sys-kernel/chromeos-kernel-experimental-4.18_rc2-r23",
            "sys-kernel/sys-kernel/socfpga-kernel-4.20-r34",
        ]
        self.PatchObject(
            portage_util,
            "GetFlattenedDepsForPackage",
            return_value=kernel_candidates,
        )
        installed_packages = [
            "sys-kernel/linux-headers-4.14-r24",
            "sys-devel/flex-2.6.4-r1",
            "sys-kernel/chromeos-kernel-4_4-4.4.223-r2209",
        ]
        self.PatchObject(
            portage_util,
            "GetPackageDependencies",
            return_value=installed_packages,
        )

        self.PatchObject(
            packages_service, "get_firmware_versions", return_value=fw_versions
        )
        self.PatchObject(
            packages_service, "find_fingerprints", return_value=fingerprints
        )

        return android_version_mock, android_branch_mock, android_target_mock

    def _patch_get_all_firmware(self, all_fw_versions):
        """Patch get_all_firmware_versions and related functions."""
        # Patch packages.get_models, packages.get_all_firmware_versions,
        # and packages.get_key_id for calls needed by model_metadata.
        model_list = list(all_fw_versions.keys())
        self.PatchObject(
            packages_service,
            "get_all_firmware_versions",
            return_value=all_fw_versions,
        )
        self.PatchObject(
            packages_service, "get_models", return_value=model_list
        )
        self.PatchObject(packages_service, "get_key_id", return_value="key")

    def testNoFirmware(self):
        """Test no firmware versions handled well."""
        android_version = "android_test_version"
        android_branch = "android_test_branch"
        android_target = "android_test_target"
        fw_versions = packages_service.FirmwareVersions(
            None, None, None, None, None
        )
        fingerprints = ["fingerprint1", "fingerprint2"]
        self._patch_all(
            android_version,
            android_branch,
            android_target,
            fw_versions,
            fingerprints,
        )

        all_fw_versions = {
            "pyro": packages_service.FirmwareVersions(
                "pyro", None, None, None, None
            ),
            "reef": packages_service.FirmwareVersions(
                "reef", None, None, None, None
            ),
        }
        self._patch_get_all_firmware(all_fw_versions)

        request = self._GetRequest(board="betty")
        packages_controller.GetBuilderMetadata(
            request, self.response, self.api_config
        )

        self.assertFalse(
            self.response.build_target_metadata[0].main_firmware_version
        )
        self.assertFalse(
            self.response.build_target_metadata[0].ec_firmware_version
        )

        self.assertEqual(self.response.model_metadata[0].model_name, "pyro")
        self.assertFalse(self.response.model_metadata[0].ec_firmware_version)
        self.assertEqual(self.response.model_metadata[0].firmware_key_id, "key")
        self.assertFalse(
            self.response.model_metadata[0].main_readonly_firmware_version
        )
        self.assertFalse(
            self.response.model_metadata[0].main_readwrite_firmware_version
        )
        self.assertEqual(self.response.model_metadata[1].model_name, "reef")
        self.assertFalse(self.response.model_metadata[1].ec_firmware_version)
        self.assertEqual(self.response.model_metadata[1].firmware_key_id, "key")
        self.assertFalse(
            self.response.model_metadata[1].main_readonly_firmware_version
        )
        self.assertFalse(
            self.response.model_metadata[1].main_readwrite_firmware_version
        )

    def testGetBuilderMetadata(self):
        """Verify basic return values."""
        android_version = "android_test_version"
        android_branch = "android_test_branch"
        android_target = "android_test_target"
        fw_versions = packages_service.FirmwareVersions(
            None,
            "Google_Caroline.7820.263.0",
            "Google_Caroline.7820.286.0",
            "caroline_v1.9.357-ac5c7b4",
            "caroline_v1.9.370-e8b9bd2",
        )
        fingerprints = ["fingerprint1", "fingerprint2"]

        (
            android_version_mock,
            android_branch_mock,
            android_target_mock,
        ) = self._patch_all(
            android_version,
            android_branch,
            android_target,
            fw_versions,
            fingerprints,
        )

        all_fw_versions = {
            "pyro": packages_service.FirmwareVersions(
                "pyro",
                "Google_Pyro.9042.87.1",
                "Google_Pyro.9042.110.0",
                "pyro_v1.1.5900-ab1ee51",
                "pyro_v1.1.5909-bd1f0c9",
            ),
            "reef": packages_service.FirmwareVersions(
                "reef",
                "Google_Reef.9042.87.1",
                "Google_Reef.9042.110.0",
                "reef_v1.1.5900-ab1ee51",
                "reef_v1.1.5909-bd1f0c9",
            ),
        }
        self._patch_get_all_firmware(all_fw_versions)

        request = self._GetRequest(board="betty")
        packages_controller.GetBuilderMetadata(
            request, self.response, self.api_config
        )
        self.assertEqual(
            self.response.build_target_metadata[0].build_target, "betty"
        )
        self.assertEqual(
            self.response.build_target_metadata[0].android_container_version,
            android_version,
        )
        self.assertEqual(
            self.response.build_target_metadata[0].android_container_branch,
            android_branch,
        )
        self.assertEqual(
            self.response.build_target_metadata[0].android_container_target,
            android_target,
        )
        self.assertEqual(
            self.response.build_target_metadata[0].arc_use_set, True
        )
        # Verify call to determine_android_version passes board name.
        android_version_mock.assert_called_with("betty")
        # Verify call to determine_android_branch passes board name.
        android_branch_mock.assert_called_with("betty")
        # Verify call to determine_android_target passes board name.
        android_target_mock.assert_called_with("betty")
        self.assertEqual(
            self.response.build_target_metadata[0].main_firmware_version,
            "Google_Caroline.7820.286.0",
        )
        self.assertEqual(
            self.response.build_target_metadata[0].ec_firmware_version,
            "caroline_v1.9.370-e8b9bd2",
        )
        self.assertEqual(
            self.response.build_target_metadata[0].kernel_version,
            "4.4.223-r2209",
        )
        self.assertEqual(
            len(self.response.build_target_metadata[0].fingerprints), 2
        )
        self.assertEqual(
            self.response.build_target_metadata[0].fingerprints, fingerprints
        )
        self.assertEqual(len(self.response.model_metadata), 2)
        self.assertEqual(self.response.model_metadata[0].model_name, "pyro")
        self.assertEqual(
            self.response.model_metadata[0].ec_firmware_version,
            "pyro_v1.1.5909-bd1f0c9",
        )
        self.assertEqual(self.response.model_metadata[0].firmware_key_id, "key")
        self.assertEqual(
            self.response.model_metadata[0].main_readonly_firmware_version,
            "Google_Pyro.9042.87.1",
        )
        self.assertEqual(
            self.response.model_metadata[0].main_readwrite_firmware_version,
            "Google_Pyro.9042.110.0",
        )
        self.assertEqual(self.response.model_metadata[1].model_name, "reef")
        self.assertEqual(
            self.response.model_metadata[1].ec_firmware_version,
            "reef_v1.1.5909-bd1f0c9",
        )
        self.assertEqual(self.response.model_metadata[1].firmware_key_id, "key")
        self.assertEqual(
            self.response.model_metadata[1].main_readonly_firmware_version,
            "Google_Reef.9042.87.1",
        )
        self.assertEqual(
            self.response.model_metadata[1].main_readwrite_firmware_version,
            "Google_Reef.9042.110.0",
        )

        # Test corner case where find_fingerprints returns None.
        # Re-patch find_fingerprints to now return None and re-execute
        # GetBuilderMetadata to verify behavior.
        response = packages_pb2.GetBuilderMetadataResponse()
        self.PatchObject(packages_service, "find_fingerprints", return_value=[])
        request = self._GetRequest(board="betty")
        packages_controller.GetBuilderMetadata(
            request, response, self.api_config
        )
        # Verify a non-fingerprint build_target_metdata field was still set.
        self.assertEqual(
            response.build_target_metadata[0].kernel_version, "4.4.223-r2209"
        )
        # And then verify that fingerprints was empty.
        self.assertEqual(response.build_target_metadata[0].fingerprints, [])


class HasChromePrebuiltTest(cros_test_lib.MockTestCase, ApiConfigMixin):
    """HasChromePrebuilt tests."""

    def setUp(self):
        self.response = packages_pb2.HasChromePrebuiltResponse()

    def _GetRequest(self, board=None):
        """Helper to build out a request."""
        request = packages_pb2.HasChromePrebuiltRequest()

        if board:
            request.build_target.name = board

        return request

    def testValidateOnly(self):
        """Verify a validate-only call does not execute any logic."""
        patch = self.PatchObject(packages_service, "has_prebuilt")

        request = self._GetRequest(board="betty")
        packages_controller.HasChromePrebuilt(
            request, self.response, self.validate_only_config
        )
        patch.assert_not_called()

    def testMockCall(self):
        """Test a mock call does not execute logic, returns mocked value."""
        patch = self.PatchObject(packages_service, "has_prebuilt")

        request = self._GetRequest(board="betty")
        packages_controller.HasChromePrebuilt(
            request, self.response, self.mock_call_config
        )
        patch.assert_not_called()
        self.assertTrue(self.response.has_prebuilt)

    def testNoBuildTargetFails(self):
        """No build target argument should fail."""
        request = self._GetRequest()

        with self.assertRaises(cros_build_lib.DieSystemExit):
            packages_controller.HasChromePrebuilt(
                request, self.response, self.api_config
            )


class BuildsChromeTest(cros_test_lib.MockTestCase, ApiConfigMixin):
    """BuildsChrome tests."""

    def setUp(self):
        self.response = packages_pb2.BuildsChromeResponse()

    def _GetRequest(self, board=None, packages=None):
        """Helper to build out a request."""
        request = packages_pb2.BuildsChromeRequest()

        if board:
            request.build_target.name = board

        if packages:
            request.packages.extend(packages)

        return request

    def testValidateOnly(self):
        """Verify a validate-only call does not execute any logic."""
        patch = self.PatchObject(packages_service, "builds")

        request = self._GetRequest(board="betty")
        packages_controller.BuildsChrome(
            request, self.response, self.validate_only_config
        )
        patch.assert_not_called()

    def testNoBuildTargetFails(self):
        """No build target argument should fail."""
        request = self._GetRequest()

        with self.assertRaises(cros_build_lib.DieSystemExit):
            packages_controller.BuildsChrome(
                request, self.response, self.api_config
            )

    def testBuilds(self):
        """Test successful call handling."""
        patch = self.PatchObject(packages_service, "builds", return_value=True)

        request = self._GetRequest(board="foo")
        packages_controller.BuildsChrome(
            request, self.response, self.api_config
        )
        self.assertTrue(self.response.builds_chrome)
        patch.assert_called_once_with(
            constants.CHROME_CP, build_target_lib.BuildTarget("foo"), []
        )

    def testBuildsChromeWithPackages(self):
        """Test successful call with packages handling."""
        patch = self.PatchObject(packages_service, "builds", return_value=True)

        package = common_pb2.PackageInfo(
            category="category",
            package_name="name",
            version="1.01",
        )
        request = self._GetRequest(board="foo", packages=[package])
        packages_controller.BuildsChrome(
            request, self.response, self.api_config
        )
        self.assertTrue(self.response.builds_chrome)
        patch.assert_called_once_with(
            constants.CHROME_CP,
            build_target_lib.BuildTarget("foo"),
            [controller_util.deserialize_package_info(package)],
        )


class NeedsChromeSourceTest(cros_test_lib.MockTempDirTestCase, ApiConfigMixin):
    """NeedsChromeSource tests."""

    def setUp(self):
        self.response = packages_pb2.NeedsChromeSourceResponse()

        self.board = "board"
        self.sysroot = self.tempdir

    def _GetRequest(self, compile_source=False):
        """Helper to build a request."""
        request = packages_pb2.NeedsChromeSourceRequest()

        request.install_request.sysroot.path = str(self.sysroot)
        request.install_request.sysroot.build_target.name = self.board
        request.install_request.flags.compile_source = compile_source

        return request

    def testAll(self):
        """Reason translation test."""
        result = packages_service.NeedsChromeSourceResult(
            needs_chrome_source=True,
            builds_chrome=True,
            packages=[package_info.parse("cat/pkg")],
            missing_chrome_prebuilt=True,
            missing_follower_prebuilt=True,
            local_uprev=True,
        )
        self.PatchObject(
            packages_service, "needs_chrome_source", return_value=result
        )

        packages_controller.NeedsChromeSource(
            self._GetRequest(compile_source=True),
            self.response,
            self.api_config,
        )

        self.assertIn(
            packages_pb2.NeedsChromeSourceResponse.COMPILE_SOURCE,
            self.response.reasons,
        )
        self.assertIn(
            packages_pb2.NeedsChromeSourceResponse.LOCAL_UPREV,
            self.response.reasons,
        )
        self.assertIn(
            packages_pb2.NeedsChromeSourceResponse.NO_PREBUILT,
            self.response.reasons,
        )
        self.assertIn(
            packages_pb2.NeedsChromeSourceResponse.FOLLOWER_LACKS_PREBUILT,
            self.response.reasons,
        )
        self.assertIn(
            packages_pb2.NeedsChromeSourceResponse.COMPILE_SOURCE,
            self.response.reasons,
        )
        self.assertIn(
            packages_pb2.NeedsChromeSourceResponse.COMPILE_SOURCE,
            self.response.reasons,
        )

        self.assertEqual(1, len(self.response.packages))
        self.assertEqual(
            ("cat", "pkg"),
            (
                self.response.packages[0].category,
                self.response.packages[0].package_name,
            ),
        )


class GetAndroidMetadataTest(cros_test_lib.MockTestCase, ApiConfigMixin):
    """GetAndroidMetadata tests."""

    def setUp(self):
        self.response = packages_pb2.GetAndroidMetadataResponse()

    def _GetRequest(self, board=None):
        """Helper to build out a request."""
        request = packages_pb2.GetAndroidMetadataRequest()

        if board:
            request.build_target.name = board

        return request

    def testValidateOnly(self):
        """Check that a validate only call does not execute any logic."""
        package_mock = self.PatchObject(
            packages_service, "determine_android_package"
        )
        branch_mock = self.PatchObject(
            packages_service, "determine_android_branch"
        )
        version_mock = self.PatchObject(
            packages_service, "determine_android_version"
        )

        request = self._GetRequest(board="betty")
        packages_controller.GetAndroidMetadata(
            request, self.response, self.validate_only_config
        )

        package_mock.assert_not_called()
        branch_mock.assert_not_called()
        version_mock.assert_not_called()

    def testMockCall(self):
        """Test a mock call does not execute logic, returns mocked value."""
        package_mock = self.PatchObject(
            packages_service, "determine_android_package"
        )
        branch_mock = self.PatchObject(
            packages_service, "determine_android_branch"
        )
        version_mock = self.PatchObject(
            packages_service, "determine_android_version"
        )

        request = self._GetRequest(board="betty")
        packages_controller.GetAndroidMetadata(
            request, self.response, self.mock_call_config
        )

        package_mock.assert_not_called()
        branch_mock.assert_not_called()
        version_mock.assert_not_called()

        self.assertTrue(self.response.android_package)
        self.assertTrue(self.response.android_branch)
        self.assertTrue(self.response.android_version)

    def testNoBuildTargetFails(self):
        """No build target argument should fail."""
        request = self._GetRequest()
        with self.assertRaises(cros_build_lib.DieSystemExit):
            packages_controller.GetAndroidMetadata(
                request, self.response, self.api_config
            )

    def testSuccess(self):
        """Test a successful call."""
        board = "betty"
        package = "android-package"
        branch = "android-branch"
        version = "7123456"
        full_package = f"chromeos-base/{package}-{version}-r1"

        package_mock = self.PatchObject(
            packages_service,
            "determine_android_package",
            return_value=full_package,
        )
        branch_mock = self.PatchObject(
            packages_service, "determine_android_branch", return_value=branch
        )
        version_mock = self.PatchObject(
            packages_service, "determine_android_version", return_value=version
        )

        request = self._GetRequest(board=board)
        packages_controller.GetAndroidMetadata(
            request, self.response, self.api_config
        )

        package_mock.assert_called_once_with(board)
        branch_mock.assert_called_once_with(board, package=full_package)
        version_mock.assert_called_once_with(board, package=full_package)

        self.assertEqual(self.response.android_package, package)
        self.assertEqual(self.response.android_branch, branch)
        self.assertEqual(self.response.android_version, version)

    def testNoAndroid(self):
        """Test returns an empty response if given board has no Android."""
        board = "betty"

        package_mock = self.PatchObject(
            packages_service, "determine_android_package", return_value=None
        )
        branch_mock = self.PatchObject(
            packages_service, "determine_android_branch"
        )
        version_mock = self.PatchObject(
            packages_service, "determine_android_version"
        )

        request = self._GetRequest(board=board)
        packages_controller.GetAndroidMetadata(
            request, self.response, self.api_config
        )

        package_mock.assert_called_once_with(board)
        branch_mock.assert_not_called()
        version_mock.assert_not_called()

        self.assertFalse(self.response.android_package)
        self.assertFalse(self.response.android_branch)
        self.assertFalse(self.response.android_version)
