# 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.

"""The test controller tests."""

import datetime
import os
from typing import Union

from chromite.third_party.google.protobuf import json_format

from chromite.api import api_config
from chromite.api import controller
from chromite.api.controller import controller_util
from chromite.api.controller import test as test_controller
from chromite.api.gen.chromite.api import test_pb2
from chromite.api.gen.chromiumos import common_pb2
from chromite.api.gen.chromiumos.build.api import container_metadata_pb2
from chromite.lib import build_target_lib
from chromite.lib import chroot_lib
from chromite.lib import cros_build_lib
from chromite.lib import cros_test_lib
from chromite.lib import osutils
from chromite.lib import sysroot_lib
from chromite.lib.parser import package_info
from chromite.service import test as test_service


class DebugInfoTestTest(
    cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
):
    """Tests for the DebugInfoTest function."""

    def setUp(self):
        self.board = "board"
        self.chroot_path = os.path.join(self.tempdir, "chroot")
        self.sysroot_path = "/build/board"
        self.full_sysroot_path = os.path.join(
            self.chroot_path, self.sysroot_path.lstrip(os.sep)
        )
        osutils.SafeMakedirs(self.full_sysroot_path)

    def _GetInput(self, sysroot_path=None, build_target=None):
        """Helper to build an input message instance."""
        proto = test_pb2.DebugInfoTestRequest()
        if sysroot_path:
            proto.sysroot.path = sysroot_path
        if build_target:
            proto.sysroot.build_target.name = build_target
        return proto

    def _GetOutput(self):
        """Helper to get an empty output message instance."""
        return test_pb2.DebugInfoTestResponse()

    def testValidateOnly(self):
        """Verify a validate-only call does not execute any logic."""
        patch = self.PatchObject(test_service, "DebugInfoTest")
        input_msg = self._GetInput(sysroot_path=self.full_sysroot_path)
        test_controller.DebugInfoTest(
            input_msg, self._GetOutput(), self.validate_only_config
        )
        patch.assert_not_called()

    def testMockError(self):
        """Test mock error call does not execute any logic, returns error."""
        patch = self.PatchObject(test_service, "DebugInfoTest")

        input_msg = self._GetInput(sysroot_path=self.full_sysroot_path)
        rc = test_controller.DebugInfoTest(
            input_msg, self._GetOutput(), self.mock_error_config
        )
        patch.assert_not_called()
        self.assertEqual(controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY, rc)

    def testMockCall(self):
        """Test mock call does not execute any logic, returns success."""
        patch = self.PatchObject(test_service, "DebugInfoTest")

        input_msg = self._GetInput(sysroot_path=self.full_sysroot_path)
        rc = test_controller.DebugInfoTest(
            input_msg, self._GetOutput(), self.mock_call_config
        )
        patch.assert_not_called()
        self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)

    def testNoBuildTargetNoSysrootFails(self):
        """Test missing build target name and sysroot path fails."""
        input_msg = self._GetInput()
        output_msg = self._GetOutput()
        with self.assertRaises(cros_build_lib.DieSystemExit):
            test_controller.DebugInfoTest(
                input_msg, output_msg, self.api_config
            )

    def testDebugInfoTest(self):
        """Call DebugInfoTest with valid sysroot_path."""
        request = self._GetInput(sysroot_path=self.full_sysroot_path)

        test_controller.DebugInfoTest(
            request, self._GetOutput(), self.api_config
        )


class BuildTargetUnitTestTest(
    cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
):
    """Tests for the UnitTest function."""

    def setUp(self):
        # Set up portage log directory.
        self.sysroot = os.path.join(self.tempdir, "build", "board")
        osutils.SafeMakedirs(self.sysroot)
        self.target_sysroot = sysroot_lib.Sysroot(self.sysroot)
        self.portage_dir = os.path.join(self.tempdir, "portage_logdir")
        self.PatchObject(
            sysroot_lib.Sysroot, "portage_logdir", new=self.portage_dir
        )
        osutils.SafeMakedirs(self.portage_dir)

    def _GetInput(
        self,
        board=None,
        chroot_path=None,
        cache_dir=None,
        empty_sysroot=None,
        packages=None,
        blocklist=None,
    ):
        """Helper to build an input message instance."""
        formatted_packages = []
        for pkg in packages or []:
            formatted_packages.append(
                {"category": pkg.category, "package_name": pkg.package}
            )
        formatted_blocklist = []
        for pkg in blocklist or []:
            formatted_blocklist.append(
                {"category": pkg.category, "package_name": pkg.package}
            )

        return test_pb2.BuildTargetUnitTestRequest(
            build_target={"name": board},
            chroot={"path": chroot_path, "cache_dir": cache_dir},
            flags={"empty_sysroot": empty_sysroot},
            packages=formatted_packages,
            package_blocklist=formatted_blocklist,
        )

    def _GetOutput(self):
        """Helper to get an empty output message instance."""
        return test_pb2.BuildTargetUnitTestResponse()

    def _CreatePortageLogFile(
        self,
        log_path: Union[str, os.PathLike],
        pkg_info: package_info.PackageInfo,
        timestamp: datetime.datetime,
    ) -> str:
        """Creates a log file to test for individual packages built by Portage.

        Args:
            log_path: The PORTAGE_LOGDIR path.
            pkg_info: name components for log file.
            timestamp: Timestamp used to name the file.
        """
        path = os.path.join(
            log_path,
            f"{pkg_info.category}:{pkg_info.pvr}:"
            f'{timestamp.strftime("%Y%m%d-%H%M%S")}.log',
        )
        osutils.WriteFile(
            path,
            f"Test log file for package {pkg_info.category}/"
            f"{pkg_info.package} written to {path}",
        )
        return path

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

        input_msg = self._GetInput(board="board")
        test_controller.BuildTargetUnitTest(
            input_msg, self._GetOutput(), 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(test_service, "BuildTargetUnitTest")

        input_msg = self._GetInput(board="board")
        response = self._GetOutput()
        test_controller.BuildTargetUnitTest(
            input_msg, response, self.mock_call_config
        )
        patch.assert_not_called()

    def testMockError(self):
        """Test that a mock error does not execute logic, returns error."""
        patch = self.PatchObject(test_service, "BuildTargetUnitTest")

        input_msg = self._GetInput(board="board")
        response = self._GetOutput()
        rc = test_controller.BuildTargetUnitTest(
            input_msg, response, self.mock_error_config
        )
        patch.assert_not_called()
        self.assertEqual(
            controller.RETURN_CODE_UNSUCCESSFUL_RESPONSE_AVAILABLE, rc
        )
        self.assertTrue(response.failed_package_data)
        self.assertEqual(response.failed_package_data[0].name.category, "foo")
        self.assertEqual(
            response.failed_package_data[0].name.package_name, "bar"
        )
        self.assertEqual(response.failed_package_data[1].name.category, "cat")
        self.assertEqual(
            response.failed_package_data[1].name.package_name, "pkg"
        )

    def testInvalidPackageFails(self):
        """Test missing result path fails."""
        # Missing result_path.
        pkg = package_info.PackageInfo(package="bar")
        input_msg = self._GetInput(board="board", packages=[pkg])
        output_msg = self._GetOutput()
        with self.assertRaises(cros_build_lib.DieSystemExit):
            test_controller.BuildTargetUnitTest(
                input_msg, output_msg, self.api_config
            )

    def testPackageBuildFailure(self):
        """Test handling of raised BuildPackageFailure."""
        tempdir = osutils.TempDir(base_dir=self.tempdir)
        self.PatchObject(osutils, "TempDir", return_value=tempdir)

        pkgs = ["cat/pkg-1.0-r1", "foo/bar-2.0-r1"]
        cpvrs = [package_info.parse(pkg) for pkg in pkgs]
        expected = [("cat", "pkg"), ("foo", "bar")]
        new_logs = {}
        for i, pkg in enumerate(pkgs):
            self._CreatePortageLogFile(
                self.portage_dir,
                cpvrs[i],
                datetime.datetime(2021, 6, 9, 13, 37, 0),
            )
            new_logs[pkg] = self._CreatePortageLogFile(
                self.portage_dir,
                cpvrs[i],
                datetime.datetime(2021, 6, 9, 16, 20, 0),
            )

        result = test_service.BuildTargetUnitTestResult(1, None)
        result.failed_pkgs = [package_info.parse(p) for p in pkgs]
        self.PatchObject(
            test_service, "BuildTargetUnitTest", return_value=result
        )

        input_msg = self._GetInput(board="board")
        output_msg = self._GetOutput()

        rc = test_controller.BuildTargetUnitTest(
            input_msg, output_msg, self.api_config
        )

        self.assertEqual(
            controller.RETURN_CODE_UNSUCCESSFUL_RESPONSE_AVAILABLE, rc
        )
        self.assertTrue(output_msg.failed_package_data)

        failed_with_logs = []
        for data in output_msg.failed_package_data:
            failed_with_logs.append(
                (data.name.category, data.name.package_name)
            )
            package = controller_util.deserialize_package_info(data.name)
            self.assertEqual(data.log_path.path, new_logs[package.cpvr])
        self.assertCountEqual(expected, failed_with_logs)

    def testOtherBuildScriptFailure(self):
        """Test build script failure due to non-package emerge error."""
        tempdir = osutils.TempDir(base_dir=self.tempdir)
        self.PatchObject(osutils, "TempDir", return_value=tempdir)

        result = test_service.BuildTargetUnitTestResult(1, None)
        self.PatchObject(
            test_service, "BuildTargetUnitTest", return_value=result
        )

        pkgs = ["foo/bar", "cat/pkg"]
        blocklist = [package_info.parse(p) for p in pkgs]
        input_msg = self._GetInput(
            board="board", empty_sysroot=True, blocklist=blocklist
        )
        output_msg = self._GetOutput()

        rc = test_controller.BuildTargetUnitTest(
            input_msg, output_msg, self.api_config
        )

        self.assertEqual(controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY, rc)
        self.assertFalse(output_msg.failed_package_data)

    def testBuildTargetUnitTest(self):
        """Test BuildTargetUnitTest successful call."""
        pkgs = ["foo/bar", "cat/pkg"]
        packages = [package_info.SplitCPV(p, strict=False) for p in pkgs]
        input_msg = self._GetInput(board="board", packages=packages)

        result = test_service.BuildTargetUnitTestResult(0, None)
        self.PatchObject(
            test_service, "BuildTargetUnitTest", return_value=result
        )

        response = self._GetOutput()
        test_controller.BuildTargetUnitTest(
            input_msg, response, self.api_config
        )
        self.assertFalse(response.failed_package_data)


class DockerConstraintsTest(cros_test_lib.MockTestCase):
    """Tests for Docker argument constraints."""

    def assertValid(self, output):
        return output is None

    def assertInvalid(self, output):
        return not self.assertValid(output)

    def testValidDockerTag(self):
        """Check logic for validating docker tag format."""
        # pylint: disable=protected-access

        invalid_tags = [
            ".invalid-tag",
            "-invalid-tag",
            "invalid-tag;",
            "invalid" * 100,
        ]

        for tag in invalid_tags:
            self.assertInvalid(test_controller._ValidDockerTag(tag))

        valid_tags = [
            "valid-tag",
            "valid-tag-",
            "valid.tag.",
        ]

        for tag in valid_tags:
            self.assertValid(test_controller._ValidDockerTag(tag))

    def testValidDockerLabelKey(self):
        """Check logic for validating docker label key format."""
        # pylint: disable=protected-access

        invalid_keys = [
            "Invalid-keY",
            "Invalid-key",
            "invalid-keY",
            "iNVALID-KEy",
            "invalid_key",
            "invalid-key;",
        ]

        for key in invalid_keys:
            self.assertInvalid(test_controller._ValidDockerLabelKey(key))

        valid_keys = [
            "chromeos.valid-key",
            "chromeos.valid-key-2",
        ]

        for key in valid_keys:
            self.assertValid(test_controller._ValidDockerLabelKey(key))


class BuildTestServiceContainers(
    cros_test_lib.RunCommandTempDirTestCase, api_config.ApiConfigMixin
):
    """Tests for the BuildTestServiceContainers function."""

    def setUp(self):
        self.request = test_pb2.BuildTestServiceContainersRequest(
            chroot={"path": "/path/to/chroot", "out_path": "/path/to/out"},
            build_target={"name": "build_target"},
            version="R93-14033.0.0",
        )

    def testSuccess(self):
        """Check passing case with mocked cros_build_lib.run."""

        def ContainerMetadata():
            """Return mocked ContainerImageInfo proto"""
            metadata = container_metadata_pb2.ContainerImageInfo()
            metadata.repository.hostname = "gcr.io"
            metadata.repository.project = "chromeos-bot"
            metadata.name = "random-container-name"
            # pylint: disable=line-too-long
            metadata.digest = "09b730f8b6a862f9c2705cb3acf3554563325f5fca5c784bf5c98beb2e56f6db"
            # pylint: enable=line-too-long
            metadata.tags[:] = [
                "staging-cq-amd64-generic.R96-1.2.3",
                "8834106026340379089",
            ]
            return metadata

        def WriteContainerMetadata(path):
            """Write json formatted metadata to the given file."""
            osutils.WriteFile(
                path,
                json_format.MessageToJson(ContainerMetadata()),
            )

        # Write out mocked container metadata to a temporary file.
        output_path = os.path.join(self.tempdir, "metadata.jsonpb")
        self.rc.SetDefaultCmdResult(
            returncode=0,
            side_effect=lambda *_, **__: WriteContainerMetadata(output_path),
        )

        # Patch TempDir so that we always use this test's directory.
        self.PatchObject(
            osutils.TempDir, "__enter__", return_value=self.tempdir
        )

        response = test_pb2.BuildTestServiceContainersResponse()
        test_controller.BuildTestServiceContainers(
            self.request, response, self.api_config
        )

        self.assertTrue(self.rc.called)
        for result in response.results:
            self.assertEqual(result.WhichOneof("result"), "success")
            self.assertEqual(result.success.image_info, ContainerMetadata())

    def testFailure(self):
        """Check failure case with mocked cros_build_lib.run."""
        response = test_pb2.BuildTestServiceContainersResponse()
        test_controller.BuildTestServiceContainers(
            self.request, response, self.api_config
        )
        self.assertTrue(self.rc.called)
        for result in response.results:
            self.assertEqual(result.WhichOneof("result"), "failure")
            self.assertEqual(result.name, "Service Builder")


class ChromiteUnitTestTest(
    cros_test_lib.RunCommandTestCase, api_config.ApiConfigMixin
):
    """Tests for the ChromiteInfoTest function."""

    def setUp(self):
        self.board = "board"
        self.chroot_path = "/path/to/chroot"

    def _GetInput(self, chroot_path=None):
        """Helper to build an input message instance."""
        proto = test_pb2.ChromiteUnitTestRequest(
            chroot={"path": chroot_path},
        )
        return proto

    def _GetOutput(self):
        """Helper to get an empty output message instance."""
        return test_pb2.ChromiteUnitTestResponse()

    def testValidateOnly(self):
        """Verify a validate-only call does not execute any logic."""
        input_msg = self._GetInput(chroot_path=self.chroot_path)
        test_controller.ChromiteUnitTest(
            input_msg, self._GetOutput(), self.validate_only_config
        )
        self.assertFalse(self.rc.called)

    def testMockError(self):
        """Test mock error call does not execute any logic, returns error."""
        input_msg = self._GetInput(chroot_path=self.chroot_path)
        rc = test_controller.ChromiteUnitTest(
            input_msg, self._GetOutput(), self.mock_error_config
        )
        self.assertFalse(self.rc.called)
        self.assertEqual(controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY, rc)

    def testMockCall(self):
        """Test mock call does not execute any logic, returns success."""
        input_msg = self._GetInput(chroot_path=self.chroot_path)
        rc = test_controller.ChromiteUnitTest(
            input_msg, self._GetOutput(), self.mock_call_config
        )
        self.assertFalse(self.rc.called)
        self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)

    def testChromiteUnitTest(self):
        """Call ChromiteUnitTest with mocked cros_build_lib.run."""
        request = self._GetInput(chroot_path=self.chroot_path)
        test_controller.ChromiteUnitTest(
            request, self._GetOutput(), self.api_config
        )
        self.assertEqual(self.rc.call_count, 1)


class CrosSigningTestTest(
    cros_test_lib.RunCommandTestCase, api_config.ApiConfigMixin
):
    """CrosSigningTest tests."""

    def setUp(self):
        self.chroot_path = "/path/to/chroot"

    def _GetInput(self, chroot_path=None):
        """Helper to build an input message instance."""
        proto = test_pb2.CrosSigningTestRequest(
            chroot={"path": chroot_path},
        )
        return proto

    def _GetOutput(self):
        """Helper to get an empty output message instance."""
        return test_pb2.CrosSigningTestResponse()

    def testValidateOnly(self):
        """Verify a validate-only call does not execute any logic."""
        test_controller.CrosSigningTest(None, None, self.validate_only_config)
        self.assertFalse(self.rc.called)

    def testMockCall(self):
        """Test mock call does not execute any logic, returns success."""
        rc = test_controller.CrosSigningTest(None, None, self.mock_call_config)
        self.assertFalse(self.rc.called)
        self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)

    def testCrosSigningTest(self):
        """Call CrosSigningTest with mocked cros_build_lib.run."""
        request = self._GetInput(chroot_path=self.chroot_path)
        test_controller.CrosSigningTest(
            request, self._GetOutput(), self.api_config
        )
        self.assertEqual(self.rc.call_count, 1)


class SimpleChromeWorkflowTestTest(
    cros_test_lib.MockTestCase, api_config.ApiConfigMixin
):
    """Test the SimpleChromeWorkflowTest endpoint."""

    @staticmethod
    def _Output():
        return test_pb2.SimpleChromeWorkflowTestResponse()

    def _Input(
        self,
        sysroot_path=None,
        build_target=None,
        chrome_root=None,
        goma_config=None,
    ):
        proto = test_pb2.SimpleChromeWorkflowTestRequest()
        if sysroot_path:
            proto.sysroot.path = sysroot_path
        if build_target:
            proto.sysroot.build_target.name = build_target
        if chrome_root:
            proto.chrome_root = chrome_root
        if goma_config:
            proto.goma_config = goma_config
        return proto

    def setUp(self):
        self.chrome_path = "path/to/chrome"
        self.sysroot_dir = "build/board"
        self.build_target = "amd64"
        self.mock_simple_chrome_workflow_test = self.PatchObject(
            test_service, "SimpleChromeWorkflowTest"
        )

    def testMissingBuildTarget(self):
        """Test SimpleChromeWorkflowTest dies when build_target not set."""
        input_proto = self._Input(
            build_target=None,
            sysroot_path="/sysroot/dir",
            chrome_root="/chrome/path",
        )
        with self.assertRaises(cros_build_lib.DieSystemExit):
            test_controller.SimpleChromeWorkflowTest(
                input_proto, None, self.api_config
            )

    def testMissingSysrootPath(self):
        """Test SimpleChromeWorkflowTest dies when build_target not set."""
        input_proto = self._Input(
            build_target="board", sysroot_path=None, chrome_root="/chrome/path"
        )
        with self.assertRaises(cros_build_lib.DieSystemExit):
            test_controller.SimpleChromeWorkflowTest(
                input_proto, None, self.api_config
            )

    def testMissingChromeRoot(self):
        """Test SimpleChromeWorkflowTest dies when build_target not set."""
        input_proto = self._Input(
            build_target="board", sysroot_path="/sysroot/dir", chrome_root=None
        )
        with self.assertRaises(cros_build_lib.DieSystemExit):
            test_controller.SimpleChromeWorkflowTest(
                input_proto, None, self.api_config
            )

    def testSimpleChromeWorkflowTest(self):
        """Call SimpleChromeWorkflowTest with valid args and temp dir."""
        request = self._Input(
            sysroot_path="sysroot_path",
            build_target="board",
            chrome_root="/path/to/chrome",
        )
        response = self._Output()

        test_controller.SimpleChromeWorkflowTest(
            request, response, self.api_config
        )
        self.mock_simple_chrome_workflow_test.assert_called()

    def testValidateOnly(self):
        request = self._Input(
            sysroot_path="sysroot_path",
            build_target="board",
            chrome_root="/path/to/chrome",
        )
        test_controller.SimpleChromeWorkflowTest(
            request, self._Output(), self.validate_only_config
        )
        self.mock_simple_chrome_workflow_test.assert_not_called()

    def testMockCall(self):
        """Test mock call does not execute any logic, returns success."""
        patch = self.mock_simple_chrome_workflow_test = self.PatchObject(
            test_service, "SimpleChromeWorkflowTest"
        )

        request = self._Input(
            sysroot_path="sysroot_path",
            build_target="board",
            chrome_root="/path/to/chrome",
        )
        rc = test_controller.SimpleChromeWorkflowTest(
            request, self._Output(), self.mock_call_config
        )
        patch.assert_not_called()
        self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)


class VmTestTest(cros_test_lib.RunCommandTestCase, api_config.ApiConfigMixin):
    """Test the VmTest endpoint."""

    def _GetInput(self, **kwargs):
        values = dict(
            build_target=common_pb2.BuildTarget(name="target"),
            vm_path=common_pb2.Path(
                path="/path/to/image.bin", location=common_pb2.Path.INSIDE
            ),
            test_harness=test_pb2.VmTestRequest.TAST,
            vm_tests=[test_pb2.VmTestRequest.VmTest(pattern="suite")],
            ssh_options=test_pb2.VmTestRequest.SshOptions(
                port=1234,
                private_key_path={
                    "path": "/path/to/id_rsa",
                    "location": common_pb2.Path.INSIDE,
                },
            ),
        )
        values.update(kwargs)
        return test_pb2.VmTestRequest(**values)

    def _Output(self):
        return test_pb2.VmTestResponse()

    def testValidateOnly(self):
        """Verify a validate-only call does not execute any logic."""
        test_controller.VmTest(
            self._GetInput(), None, self.validate_only_config
        )
        self.assertEqual(0, self.rc.call_count)

    def testMockCall(self):
        """Test mock call does not execute any logic."""
        request = self._GetInput()
        response = self._Output()
        # VmTest does not return a value, checking mocked value is flagged by
        # lint.
        test_controller.VmTest(request, response, self.mock_call_config)
        self.assertFalse(self.rc.called)

    def testTastAllOptions(self):
        """Test VmTest for Tast with all options set."""
        test_controller.VmTest(self._GetInput(), None, self.api_config)
        self.assertCommandContains(
            [
                "cros_run_test",
                "--debug",
                "--no-display",
                "--copy-on-write",
                "--board",
                "target",
                "--image-path",
                "/path/to/image.bin",
                "--tast",
                "suite",
                "--ssh-port",
                "1234",
                "--private-key",
                "/path/to/id_rsa",
            ]
        )

    def testAutotestAllOptions(self):
        """Test VmTest for Autotest with all options set."""
        input_proto = self._GetInput(
            test_harness=test_pb2.VmTestRequest.AUTOTEST
        )
        test_controller.VmTest(input_proto, None, self.api_config)
        self.assertCommandContains(
            [
                "cros_run_test",
                "--debug",
                "--no-display",
                "--copy-on-write",
                "--board",
                "target",
                "--image-path",
                "/path/to/image.bin",
                "--autotest",
                "suite",
                "--ssh-port",
                "1234",
                "--private-key",
                "/path/to/id_rsa",
                "--test_that-args=--allow-chrome-crashes",
            ]
        )

    def testMissingBuildTarget(self):
        """Test VmTest dies when build_target not set."""
        input_proto = self._GetInput(build_target=None)
        with self.assertRaises(cros_build_lib.DieSystemExit):
            test_controller.VmTest(input_proto, None, self.api_config)

    def testMissingVmImage(self):
        """Test VmTest dies when vm_image not set."""
        input_proto = self._GetInput(vm_path=None)
        with self.assertRaises(cros_build_lib.DieSystemExit):
            test_controller.VmTest(input_proto, None, self.api_config)

    def testMissingTestHarness(self):
        """Test VmTest dies when test_harness not specified."""
        input_proto = self._GetInput(
            test_harness=test_pb2.VmTestRequest.UNSPECIFIED
        )
        with self.assertRaises(cros_build_lib.DieSystemExit):
            test_controller.VmTest(input_proto, None, self.api_config)

    def testMissingVmTests(self):
        """Test VmTest dies when vm_tests not set."""
        input_proto = self._GetInput(vm_tests=[])
        with self.assertRaises(cros_build_lib.DieSystemExit):
            test_controller.VmTest(input_proto, None, self.api_config)

    def testVmTest(self):
        """Call VmTest with valid args and temp dir."""
        request = self._GetInput()
        response = self._Output()
        test_controller.VmTest(request, response, self.api_config)
        self.assertTrue(self.rc.called)


class GetArtifactsTest(cros_test_lib.MockTempDirTestCase):
    """Test GetArtifacts."""

    CODE_COVERAGE_LLVM_ARTIFACT_TYPE = (
        common_pb2.ArtifactsByService.Test.ArtifactType.CODE_COVERAGE_LLVM_JSON
    )

    # pylint: disable=line-too-long
    _artifact_funcs = {
        common_pb2.ArtifactsByService.Test.ArtifactType.CODE_COVERAGE_LLVM_JSON: test_service.BundleCodeCoverageLlvmJson,
        common_pb2.ArtifactsByService.Test.ArtifactType.CODE_COVERAGE_RUST_LLVM_JSON: test_service.BundleCodeCoverageRustLlvmJson,
        common_pb2.ArtifactsByService.Test.ArtifactType.HWQUAL: test_service.BundleHwqualTarball,
        common_pb2.ArtifactsByService.Test.ArtifactType.CODE_COVERAGE_GOLANG: test_service.BundleCodeCoverageGolang,
    }
    # pylint: enable=line-too-long

    def setUp(self):
        """Set up the class for tests."""
        self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)

        self.chroot = chroot_lib.Chroot(
            path=self.tempdir / "chroot",
            out_path=self.tempdir / "out",
        )
        osutils.SafeMakedirs(self.chroot.tmp)

        sysroot_path = self.chroot.full_path("/build/board")
        osutils.SafeMakedirs(sysroot_path)
        self.sysroot = sysroot_lib.Sysroot(sysroot_path)

        self.build_target = build_target_lib.BuildTarget("board")

        self._mocks = {}
        for artifact, func in self._artifact_funcs.items():
            self._mocks[artifact] = self.PatchObject(
                test_service, func.__name__
            )

    def _InputProto(
        self,
        artifact_types=_artifact_funcs.keys(),
    ):
        """Helper to build an input proto instance."""
        return common_pb2.ArtifactsByService.Test(
            output_artifacts=[
                common_pb2.ArtifactsByService.Test.ArtifactInfo(
                    artifact_types=artifact_types
                )
            ]
        )

    def testReturnsEmptyListWhenNoOutputArtifactsProvided(self):
        """Test empty list is returned when there are no output_artifacts."""
        result = test_controller.GetArtifacts(
            common_pb2.ArtifactsByService.Test(output_artifacts=[]),
            self.chroot,
            self.sysroot,
            self.build_target,
            self.tempdir,
        )

        self.assertEqual(len(result), 0)

    def testShouldCallBundleCodeCoverageLlvmJsonForEachValidArtifact(self):
        """Test BundleCodeCoverageLlvmJson is called on each valid artifact."""
        BundleCodeCoverageLlvmJson_mock = self.PatchObject(
            test_service, "BundleCodeCoverageLlvmJson", return_value="test"
        )

        # pylint: disable=line-too-long
        test_controller.GetArtifacts(
            common_pb2.ArtifactsByService.Test(
                output_artifacts=[
                    # Valid
                    common_pb2.ArtifactsByService.Test.ArtifactInfo(
                        artifact_types=[self.CODE_COVERAGE_LLVM_ARTIFACT_TYPE]
                    ),
                    # Invalid
                    common_pb2.ArtifactsByService.Test.ArtifactInfo(
                        artifact_types=[
                            common_pb2.ArtifactsByService.Test.ArtifactType.UNIT_TESTS
                        ]
                    ),
                ]
            ),
            self.chroot,
            self.sysroot,
            self.build_target,
            self.tempdir,
        )
        # pylint: enable=line-too-long

        BundleCodeCoverageLlvmJson_mock.assert_called_once()

    def testShouldReturnValidResult(self):
        """Test result contains paths and code_coverage_llvm_json type."""
        self.PatchObject(
            test_service, "BundleCodeCoverageLlvmJson", return_value="test"
        )

        result = test_controller.GetArtifacts(
            common_pb2.ArtifactsByService.Test(
                output_artifacts=[
                    # Valid
                    common_pb2.ArtifactsByService.Test.ArtifactInfo(
                        artifact_types=[self.CODE_COVERAGE_LLVM_ARTIFACT_TYPE]
                    ),
                ]
            ),
            self.chroot,
            self.sysroot,
            self.build_target,
            self.tempdir,
        )

        self.assertEqual(result[0]["paths"], ["test"])
        self.assertEqual(
            result[0]["type"], self.CODE_COVERAGE_LLVM_ARTIFACT_TYPE
        )

    def testNoArtifacts(self):
        """Test GetArtifacts with no artifact types."""
        in_proto = self._InputProto(artifact_types=[])
        test_controller.GetArtifacts(
            in_proto, None, None, self.build_target, ""
        )

        for _, patch in self._mocks.items():
            patch.assert_not_called()

    def testArtifactsSuccess(self):
        """Test GetArtifacts with all artifact types."""
        test_controller.GetArtifacts(
            self._InputProto(), None, None, self.build_target, ""
        )

        for _, patch in self._mocks.items():
            patch.assert_called_once()

    def testArtifactsException(self):
        """Test with all artifact types when one type throws an exception."""

        self._mocks[
            common_pb2.ArtifactsByService.Test.ArtifactType.CODE_COVERAGE_GOLANG
        ].side_effect = Exception("foo bar")
        generated = test_controller.GetArtifacts(
            self._InputProto(), None, None, self.build_target, ""
        )

        for _, patch in self._mocks.items():
            patch.assert_called_once()

        found_artifact = False
        for data in generated:
            artifact_type = (
                common_pb2.ArtifactsByService.Test.ArtifactType.Name(
                    data["type"]
                )
            )
            if artifact_type == "CODE_COVERAGE_GOLANG":
                found_artifact = True
                self.assertTrue(data["failed"])
                self.assertEqual(data["failure_reason"], "foo bar")
        self.assertTrue(found_artifact)
