#!/usr/bin/env fuchsia-vendored-python
# Copyright 2023 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import contextlib
import copy
import io
import os
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
from unittest import mock

import fuchsia
import remote_action
import cl_utils
import output_leak_scanner
import remotetool

from typing import Any, Collection, Dict, Sequence, Tuple

_HAVE_XATTR = hasattr(os, "setxattr")


class ImmediateExit(Exception):
    """For mocking functions that do not return."""

    pass


def _write_file_contents(path: Path, contents: str) -> None:
    with open(path, "w") as f:
        f.write(contents)


def _read_file_contents(path: Path) -> str:
    with open(path, "r") as f:
        return f.read()


def _strs(items: Sequence[Any]) -> Sequence[str]:
    return [str(i) for i in items]


def _paths(items: Collection[Any]) -> Collection[Path]:
    if isinstance(items, list):
        return [Path(i) for i in items]
    elif isinstance(items, set):
        return {Path(i) for i in items}
    elif isinstance(items, tuple):
        return tuple(Path(i) for i in items)

    t = type(items)
    raise TypeError(f"Unhandled sequence type: {t}")


def _fake_download_output(
    packed_args: Tuple[
        remote_action.DownloadStubInfo,
        remotetool.RemoteTool,
        Path,
        bool,
    ]
) -> Tuple[Path, cl_utils.SubprocessResult]:
    # For mocking remote_action._download_output_for_mp.
    # defined because multiprocessing cannot serialize mocks
    stub_info, downloader, working_dir_abs, verbose = packed_args
    # Don't actually try to download.
    return (stub_info.path, cl_utils.SubprocessResult(0))


def _fake_download_output_fail(
    packed_args: Tuple[
        remote_action.DownloadStubInfo,
        remotetool.RemoteTool,
        Path,
        bool,
    ]
) -> Tuple[Path, cl_utils.SubprocessResult]:
    # For mocking remote_action._download_output_for_mp.
    # defined because multiprocessing cannot serialize mocks
    stub_info, downloader, working_dir_abs, verbose = packed_args
    # Don't actually try to download.
    return (stub_info.path, cl_utils.SubprocessResult(1))


def _fake_download_input(
    packed_args: Tuple[
        Path,
        remotetool.RemoteTool,
        Path,
        bool,
    ]
) -> Tuple[Path, cl_utils.SubprocessResult]:
    # For mocking remote_action._download_input_for_mp.
    # defined because multiprocessing cannot serialize mocks
    stub_path, downloader, working_dir_abs, verbose = packed_args
    # Don't actually try to download.
    return (stub_path, cl_utils.SubprocessResult(0))


def _fake_download_input_fail(
    packed_args: Tuple[
        Path,
        remotetool.RemoteTool,
        Path,
        bool,
    ]
) -> Tuple[Path, cl_utils.SubprocessResult]:
    # For mocking remote_action._download_input_for_mp.
    # defined because multiprocessing cannot serialize mocks
    stub_path, downloader, working_dir_abs, verbose = packed_args
    # Don't actually try to download.
    return (stub_path, cl_utils.SubprocessResult(1))


class PathToDownloadStubTests(unittest.TestCase):
    def test_is_stub(self) -> None:
        path = Path("obj/stubby.stub")
        fake_stub_info = remote_action.DownloadStubInfo(
            path=path,
            type="file",
            blob_digest="0a97a6sbed/7711",
            action_digest="bed977abaac/32",
            build_id="random-id0348718",
        )
        with mock.patch.object(
            remote_action, "is_download_stub_file", return_value=True
        ) as mock_check_stub:
            with mock.patch.object(
                remote_action.DownloadStubInfo,
                "read_from_file",
                return_value=fake_stub_info,
            ) as mock_read_stub:
                stub = remote_action.path_to_download_stub(path)
        self.assertEqual(stub, fake_stub_info)
        mock_check_stub.assert_called_once_with(path)
        mock_read_stub.assert_called_once_with(path)

    def test_not_stub(self) -> None:
        path = Path("not/stubby.o")
        with mock.patch.object(
            remote_action, "is_download_stub_file", return_value=False
        ) as mock_check_stub:
            stub = remote_action.path_to_download_stub(path)

        self.assertIsNone(stub)
        mock_check_stub.assert_called_once_with(path)


class DownloadFromStubPathTests(unittest.TestCase):
    def test_stub_does_not_exist_ignored(self) -> None:
        with tempfile.TemporaryDirectory() as td:
            stub_path = Path(td) / "stub-not-exist"
            with mock.patch.object(
                Path, "exists", return_value=False
            ) as mock_exists:
                subprocess_result = remote_action.download_from_stub_path(
                    stub_path,
                    downloader=None,  # type: ignore[arg-type]
                    working_dir_abs=Path(td),
                )
        self.assertEqual(subprocess_result.returncode, 0)

    def test_stub_using_invoked_path(self) -> None:
        with tempfile.TemporaryDirectory() as td:
            tdp = Path(td)
            stub_path = tdp / "foo.exe"
            stub_info = remote_action.DownloadStubInfo(
                path=Path("some/where/else"),
                type="file",
                blob_digest="8712fed1/44",
                action_digest="098761/145",
                build_id="do-not-care",
            )
            stub_info.create(
                working_dir_abs=tdp,
                dest=stub_path,
            )
            with mock.patch.object(
                remote_action.DownloadStubInfo,
                "download",
                return_value=cl_utils.SubprocessResult(0),
            ) as mock_download:
                subprocess_result = remote_action.download_from_stub_path(
                    stub_path,
                    downloader=None,  # type: ignore[arg-type]
                    working_dir_abs=Path(td),
                )
            # Ensure that we use the invoked path,
            # and not the path that is inside the stub_info.
            mock_download.assert_called_once_with(
                downloader=None,
                working_dir_abs=tdp,
                dest=stub_path,
            )
        self.assertEqual(subprocess_result.returncode, 0)


class UndownloadTests(unittest.TestCase):
    def test_undownload_non_stub_ignored(self) -> None:
        path = Path("foo/barf.baz")
        with tempfile.TemporaryDirectory() as td:
            tdp = Path(td)
            (tdp / path.parent).mkdir(parents=True)
            (tdp / path).write_text("bye\n")
            # path points to a non-stub
            self.assertFalse(remote_action.is_download_stub_file(tdp / path))
            remote_action.undownload(tdp / path)
            # nothing changes
            self.assertFalse(remote_action.is_download_stub_file(tdp / path))

    def test_undownload_restored(self) -> None:
        path = Path("foo/barf.baz")
        stub = remote_action.DownloadStubInfo(
            path=path,
            type="file",
            blob_digest="82828abf872/453",
            action_digest="2332df093d1/98",
            build_id="random-id777",
        )
        with tempfile.TemporaryDirectory() as td:
            tdp = Path(td)
            stub.create(tdp)
            # Pretend to download first.
            download_status = 0

            def fake_download_file(
                downloader_self: object, path: Path, digest: str, **kwargs: Any
            ) -> cl_utils.SubprocessResult:
                path.write_text("greetings\n")
                return cl_utils.SubprocessResult(download_status)

            with mock.patch.object(
                remotetool.RemoteTool, "download_blob", new=fake_download_file
            ) as mock_download:
                status = stub.download(
                    downloader=_FAKE_DOWNLOADER, working_dir_abs=tdp
                )

            # path points to a non-stub
            self.assertFalse(remote_action.is_download_stub_file(tdp / path))

            remote_action.undownload(tdp / path)
            # now path points to a restored stub
            self.assertTrue(remote_action.is_download_stub_file(tdp / path))


class DownloadOutputStubInfosBatchTests(unittest.TestCase):
    def test_empty_list(self) -> None:
        statuses = remote_action.download_output_stub_infos_batch(
            downloader=_FAKE_DOWNLOADER,
            stub_infos=[],
            working_dir_abs=Path("."),
        )
        self.assertEqual(statuses, {})

    def test_one_download_stub_downloaded_success(self) -> None:
        path = Path("foo/bar.o")
        fake_stub_info = remote_action.DownloadStubInfo(
            path=path,
            type="file",
            blob_digest="1112313123/912",
            action_digest="a7a77ed7f98/332",
            build_id="random-id987198129",
        )
        with mock.patch.object(
            remote_action, "_download_output_for_mp", new=_fake_download_output
        ) as mock_download:  # success
            statuses = remote_action.download_output_stub_infos_batch(
                downloader=_FAKE_DOWNLOADER,
                stub_infos=[fake_stub_info],
                working_dir_abs=Path("."),
            )

        self.assertEqual(statuses[path].returncode, 0)

    def test_one_download_stub_downloaded_failure(self) -> None:
        path = Path("foo/bar.o")
        fake_stub_info = remote_action.DownloadStubInfo(
            path=path,
            type="file",
            blob_digest="1112313123/912",
            action_digest="a7a77ed7f98/332",
            build_id="random-id987198129",
        )
        with mock.patch.object(
            remote_action,
            "_download_output_for_mp",
            new=_fake_download_output_fail,
        ) as mock_download:
            statuses = remote_action.download_output_stub_infos_batch(
                downloader=_FAKE_DOWNLOADER,
                stub_infos=[fake_stub_info],
                working_dir_abs=Path("."),
            )

        self.assertEqual(statuses[path].returncode, 1)

    def test_multiple_download_stub_downloaded_success(self) -> None:
        path1 = Path("foo/bar.o")
        path2 = Path("baz/quux.o")
        fake_stub_infos = [
            remote_action.DownloadStubInfo(
                path=path1,
                type="file",
                blob_digest="767676767a767/912",
                action_digest="a7a77ed7f98/332",
                build_id="random-id0010129",
            ),
            remote_action.DownloadStubInfo(
                path=path2,
                type="file",
                blob_digest="3e3e3e3e3e/712",
                action_digest="1122777eecca/32",
                build_id="random-id0012397",
            ),
        ]
        with mock.patch.object(
            remote_action, "_download_output_for_mp", new=_fake_download_output
        ) as mock_download:  # success
            statuses = remote_action.download_output_stub_infos_batch(
                downloader=_FAKE_DOWNLOADER,
                stub_infos=fake_stub_infos,
                working_dir_abs=Path("."),
            )

        self.assertEqual(statuses[path1].returncode, 0)
        self.assertEqual(statuses[path2].returncode, 0)


class DownloadInputStubPathsBatchTests(unittest.TestCase):
    def test_empty_list(self) -> None:
        statuses = remote_action.download_input_stub_paths_batch(
            downloader=_FAKE_DOWNLOADER,
            stub_paths=[],
            working_dir_abs=Path("."),
        )
        self.assertEqual(statuses, {})

    def test_one_download_path_downloaded_success(self) -> None:
        path = Path("foo/bar.o")
        with mock.patch.object(
            remote_action, "_download_input_for_mp", new=_fake_download_input
        ) as mock_download:  # success
            statuses = remote_action.download_input_stub_paths_batch(
                downloader=_FAKE_DOWNLOADER,
                stub_paths=[path],
                working_dir_abs=Path("."),
            )

        self.assertEqual(statuses[path].returncode, 0)

    def test_one_download_path_downloaded_failure(self) -> None:
        path = Path("foo/bar.o")
        with mock.patch.object(
            remote_action,
            "_download_input_for_mp",
            new=_fake_download_input_fail,
        ) as mock_download:
            statuses = remote_action.download_input_stub_paths_batch(
                downloader=_FAKE_DOWNLOADER,
                stub_paths=[path],
                working_dir_abs=Path("."),
            )

        self.assertEqual(statuses[path].returncode, 1)

    def test_multiple_download_stub_downloaded_success(self) -> None:
        path1 = Path("foo/bar.o")
        path2 = Path("baz/quux.o")
        with mock.patch.object(
            remote_action, "_download_input_for_mp", new=_fake_download_input
        ) as mock_download:  # success
            statuses = remote_action.download_input_stub_paths_batch(
                downloader=_FAKE_DOWNLOADER,
                stub_paths=[path1, path2],
                working_dir_abs=Path("."),
            )

        self.assertEqual(statuses[path1].returncode, 0)
        self.assertEqual(statuses[path2].returncode, 0)


class FakeReproxyLogEntry(remote_action.ReproxyLogEntry):
    """Mimic a ReproxyLogEntry by setting properties without parsing."""

    def __init__(self, **kwargs: Any):
        self._execution_id: str
        self._action_digest: str
        self._output_file_digests: Dict[Path, str]
        self._output_directory_digests: Dict[Path, str]
        self._completion_status: str
        # intentionally does not call super().__init__(), but instead
        # sets property attributes.
        for k, v in kwargs.items():
            setattr(self, "_" + k, v)

    @property
    def execution_id(self) -> str:
        return self._execution_id

    @property
    def action_digest(self) -> str:
        return self._action_digest

    @property
    def output_file_digests(self) -> Dict[Path, str]:
        return self._output_file_digests

    @property
    def output_directory_digests(self) -> Dict[Path, str]:
        return self._output_directory_digests

    @property
    def completion_status(self) -> str:
        return self._completion_status


class FileMatchTests(unittest.TestCase):
    def test_match(self) -> None:
        with tempfile.TemporaryDirectory() as td:
            f1path = Path(td, "left.txt")
            f2path = Path(td, "right.txt")
            _write_file_contents(f1path, "a\n")
            _write_file_contents(f2path, "a\n")
            self.assertTrue(remote_action._files_match(f1path, f2path))
            self.assertTrue(remote_action._files_match(f2path, f1path))

    def test_not_match(self) -> None:
        with tempfile.TemporaryDirectory() as td:
            f1path = Path(td, "left.txt")
            f2path = Path(td, "right.txt")
            _write_file_contents(f1path, "a\n")
            _write_file_contents(f2path, "b\n")
            self.assertFalse(remote_action._files_match(f1path, f2path))
            self.assertFalse(remote_action._files_match(f2path, f1path))


class DetailDiffTests(unittest.TestCase):
    def test_called(self) -> None:
        with mock.patch.object(
            cl_utils,
            "subprocess_call",
            return_value=cl_utils.SubprocessResult(0),
        ) as mock_call:
            self.assertEqual(
                remote_action._detail_diff(
                    Path("file1.txt"), Path("file2.txt")
                ).returncode,
                0,
            )
        mock_call.assert_called_once()
        first_call = mock_call.call_args_list[0]
        args, unused_kwargs = first_call
        command = args[0]  # list
        self.assertTrue(
            command[0].endswith(str(remote_action._DETAIL_DIFF_SCRIPT))
        )

    def test_filtered(self) -> None:
        def _filter_for_compare(
            file1: Path, filtered1: Path, file2: Path, filtered2: Path
        ) -> bool:
            # Pretend we wrote filtered views to filtered1 and filtered2.
            return True

        with mock.patch.object(
            cl_utils,
            "subprocess_call",
            return_value=cl_utils.SubprocessResult(0),
        ) as mock_call:
            self.assertEqual(
                remote_action._detail_diff_filtered(
                    Path("file1.txt"),
                    Path("file2.txt"),
                    maybe_transform_pair=_filter_for_compare,
                ).returncode,
                0,
            )
        mock_call.assert_called_once()
        first_call = mock_call.call_args_list[0]
        args, unused_kwargs = first_call
        command = args[0]  # list
        self.assertTrue(
            command[0].endswith(str(remote_action._DETAIL_DIFF_SCRIPT))
        )
        self.assertEqual(command[1], "file1.txt.filtered")
        self.assertEqual(command[2], "file2.txt.filtered")


class TextDiffTests(unittest.TestCase):
    def test_called(self) -> None:
        result = cl_utils.SubprocessResult(0)
        with mock.patch.object(
            cl_utils, "subprocess_call", return_value=result
        ) as mock_call:
            self.assertEqual(
                remote_action._text_diff(Path("file1.txt"), Path("file2.txt")),
                result,
            )
        mock_call.assert_called_once()
        first_call = mock_call.call_args_list[0]
        args, unused_kwargs = first_call
        command = args[0]  # list
        self.assertEqual(command[0], "diff")
        self.assertEqual(command[-2:], ["file1.txt", "file2.txt"])

    def test_matches(self) -> None:  # no mocking
        with tempfile.TemporaryDirectory() as td:
            f1 = Path(td) / "left.txt"
            f2 = Path(td) / "right.txt"
            contents = "The quick brown fox\njumped over the lazy\ndogs.\n"
            _write_file_contents(f1, contents)
            _write_file_contents(f2, contents)
            result = remote_action._text_diff(f1, f2)
            self.assertEqual(result.returncode, 0)
            self.assertEqual(result.stdout, [])

    def test_not_matches(self) -> None:  # no mocking
        with tempfile.TemporaryDirectory() as td:
            f1 = Path(td) / "left.txt"
            f2 = Path(td) / "right.txt"
            contents = "The quick brown fox\njumped over the lazy\ndogs.\n"
            _write_file_contents(f1, contents)
            _write_file_contents(f2, contents.replace("m", "M"))
            result = remote_action._text_diff(f1, f2)
            self.assertEqual(result.returncode, 1)
            self.assertNotEqual(result.stdout, [])


class FilesUnderDirTests(unittest.TestCase):
    def test_walk(self) -> None:
        with tempfile.TemporaryDirectory() as td:
            f1path = Path(td) / "left.txt"
            subdir = Path(td) / "sub"
            os.mkdir(subdir)
            f2path = subdir / "right.txt"
            _write_file_contents(f1path, "\n")
            _write_file_contents(f2path, "\n")
            self.assertEqual(
                set(remote_action._files_under_dir(Path(td))),
                _paths({"left.txt", "sub/right.txt"}),
            )


class CommonFilesUnderDirsTests(unittest.TestCase):
    def test_none_in_common(self) -> None:
        with mock.patch.object(
            remote_action,
            "_files_under_dir",
            side_effect=[iter(["a", "b", "c"]), iter(["d", "e", "f"])],
        ) as mock_lsr:
            self.assertEqual(
                remote_action._common_files_under_dirs(
                    Path("foo-dir"), Path("bar-dir")
                ),
                set(),
            )

    def test_some_in_common(self) -> None:
        with mock.patch.object(
            remote_action,
            "_files_under_dir",
            side_effect=[
                iter(_paths(["a", "b/x", "c"])),
                iter(_paths(["d", "c", "b/x"])),
            ],
        ) as mock_lsr:
            self.assertEqual(
                set(
                    remote_action._common_files_under_dirs(
                        Path("foo-dir"), Path("bar-dir")
                    )
                ),
                _paths({"b/x", "c"}),
            )


class ExpandCommonFilesBetweenDirs(unittest.TestCase):
    def test_common(self) -> None:
        # Normally returns a set, but mock-return a list for deterministic
        # ordering.
        with mock.patch.object(
            remote_action,
            "_common_files_under_dirs",
            return_value=_paths(["y/z", "x"]),
        ) as mock_ls:
            self.assertEqual(
                list(
                    remote_action._expand_common_files_between_dirs(
                        [(Path("c"), Path("d")), (Path("a"), Path("b"))]
                    )
                ),
                [
                    _paths(("c/x", "d/x")),
                    _paths(("c/y/z", "d/y/z")),
                    _paths(("a/x", "b/x")),
                    _paths(("a/y/z", "b/y/z")),
                ],
            )


class FileLinesMatchingTests(unittest.TestCase):
    def test_empty(self) -> None:
        with mock.patch(
            "builtins.open", mock.mock_open(read_data="")
        ) as mock_file:
            self.assertEqual(
                list(
                    remote_action._file_lines_matching(
                        Path("log.txt"), "never-match"
                    )
                ),
                [],
            )

    def test_matches(self) -> None:
        with mock.patch(
            "builtins.open", mock.mock_open(read_data="ab\nbc\ncd\n")
        ) as mock_file:
            self.assertEqual(
                list(remote_action._file_lines_matching(Path("file.txt"), "c")),
                ["bc\n", "cd\n"],
            )


class TransformFileByLines(unittest.TestCase):
    def test_no_change(self) -> None:
        with tempfile.TemporaryDirectory() as td:
            f1 = Path(td) / "in.txt"
            f2 = Path(td) / "out.txt"
            _write_file_contents(
                f1, "aa\n\n\nbb\ncc dd\n\ne f \n gh ij\n  k  l  \n"
            )
            remote_action._transform_file_by_lines(f1, f2, lambda x: x)
            s1 = _read_file_contents(f1)
            s2 = _read_file_contents(f2)
            self.assertEqual(s1, s2)


class ReclientCanonicalWorkingDirTests(unittest.TestCase):
    def test_empty(self) -> None:
        self.assertEqual(
            remote_action.reclient_canonical_working_dir(Path("")), Path("")
        )

    def test_one_level(self) -> None:
        self.assertEqual(
            remote_action.reclient_canonical_working_dir(Path("build-here")),
            Path("set_by_reclient"),
        )

    def test_two_levels(self) -> None:
        self.assertEqual(
            remote_action.reclient_canonical_working_dir(Path("build/there")),
            Path("set_by_reclient/a"),
        )

    def test_three_levels(self) -> None:
        self.assertEqual(
            remote_action.reclient_canonical_working_dir(
                Path("build/inside/there")
            ),
            Path("set_by_reclient/a/a"),
        )


class RewriteDepfileTests(unittest.TestCase):
    def test_depfile_in_place(self) -> None:
        with tempfile.TemporaryDirectory() as td:
            depfile = Path(td) / "dep.d"

            wd = Path("/home/base/out/inside/here")
            _write_file_contents(
                depfile, f"obj/foo.o: {wd}/foo/bar.h {wd}/baz/quux.h\n"
            )
            remote_action.rewrite_depfile(
                depfile,
                transform=lambda x: remote_action._remove_prefix(x, f"{wd}/"),
            )  # write in-place
            self.assertEqual(
                _read_file_contents(depfile),
                "obj/foo.o: foo/bar.h baz/quux.h\n",
            )

    def test_depfile_new_file(self) -> None:
        with tempfile.TemporaryDirectory() as td:
            depfile = Path(td) / "dep.d"
            output = depfile.with_suffix(".new")

            wd = Path("/all/your/base")
            _write_file_contents(
                depfile, f"obj/foo.o: {wd}/foo/bar.h {wd}/baz/quux.h\n"
            )
            remote_action.rewrite_depfile(
                depfile,
                transform=lambda x: remote_action._remove_prefix(x, f"{wd}/"),
                output=output,
            )  # write new file
            self.assertEqual(
                _read_file_contents(output),
                "obj/foo.o: foo/bar.h baz/quux.h\n",
            )


class ResolvedShlibsFromLddTests(unittest.TestCase):
    def test_sample(self) -> None:
        ldd_output = """
	linux-vdso.so.1 (0x00007ffd653b2000)
	librustc_driver-897e90da9cc472c4.so => /usr/home/janedoe/my_project/tools/rust/linux-x64/bin/../lib/librustc_driver-897e90da9cc472c4.so (0x00007f6fdf600000)
	libstd-374958b5d3497a8f.so => /usr/home/janedoe/my_project/tools/rust/linux-x64/bin/../lib/libstd-374958b5d3497a8f.so (0x00007f6fdf45c000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f6fe2cc6000)
	librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f6fe2cc1000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f6fe2cba000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6fdf27b000)
	libLLVM-15-rust-1.70.0-nightly.so => /usr/home/janedoe/my_project/tools/rust/linux-x64/bin/../lib/../lib/libLLVM-15-rust-1.70.0-nightly.so (0x00007f6fdb000000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f6fe2921000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f6fe2ce6000)
"""
        self.assertEqual(
            list(
                remote_action.resolved_shlibs_from_ldd(ldd_output.splitlines())
            ),
            _paths(
                [
                    "/usr/home/janedoe/my_project/tools/rust/linux-x64/bin/../lib/librustc_driver-897e90da9cc472c4.so",
                    "/usr/home/janedoe/my_project/tools/rust/linux-x64/bin/../lib/libstd-374958b5d3497a8f.so",
                    "/lib/x86_64-linux-gnu/libdl.so.2",
                    "/lib/x86_64-linux-gnu/librt.so.1",
                    "/lib/x86_64-linux-gnu/libpthread.so.0",
                    "/lib/x86_64-linux-gnu/libc.so.6",
                    "/usr/home/janedoe/my_project/tools/rust/linux-x64/bin/../lib/../lib/libLLVM-15-rust-1.70.0-nightly.so",
                    "/lib/x86_64-linux-gnu/libm.so.6",
                ]
            ),
        )


class HostToolNonsystemShlibsTests(unittest.TestCase):
    def test_sample(self) -> None:
        unfiltered_shlibs = _paths(
            [
                "/usr/home/janedoe/my_project/tools/rust/linux-x64/bin/../lib/librustc_driver-897e90da9cc472c4.so",
                "/usr/home/janedoe/my_project/tools/rust/linux-x64/bin/../lib/libstd-374958b5d3497a8f.so",
                "/lib/x86_64-linux-gnu/libdl.so.2",
                "/lib/x86_64-linux-gnu/librt.so.1",
                "/lib/x86_64-linux-gnu/libpthread.so.0",
                "/lib/x86_64-linux-gnu/libc.so.6",
                "/usr/home/janedoe/my_project/tools/rust/linux-x64/bin/../lib/../lib/libLLVM-15-rust-1.70.0-nightly.so",
                "/lib/x86_64-linux-gnu/libm.so.6",
                "/usr/lib/something_else.so",
            ]
        )
        with mock.patch.object(
            remote_action, "host_tool_shlibs", return_value=unfiltered_shlibs
        ) as mock_host_tool_shlibs:
            self.assertEqual(
                list(
                    remote_action.host_tool_nonsystem_shlibs(
                        Path("../path/to/rustc")
                    )
                ),
                _paths(
                    [
                        "/usr/home/janedoe/my_project/tools/rust/linux-x64/bin/../lib/librustc_driver-897e90da9cc472c4.so",
                        "/usr/home/janedoe/my_project/tools/rust/linux-x64/bin/../lib/libstd-374958b5d3497a8f.so",
                        "/usr/home/janedoe/my_project/tools/rust/linux-x64/bin/../lib/../lib/libLLVM-15-rust-1.70.0-nightly.so",
                    ]
                ),
            )
        mock_host_tool_shlibs.assert_called_once()


class RewrapperArgParserTests(unittest.TestCase):
    @property
    def _parser(self) -> argparse.ArgumentParser:
        return remote_action._REWRAPPER_ARG_PARSER

    def test_default(self) -> None:
        args, _ = self._parser.parse_known_args([])
        self.assertIsNone(args.exec_root)
        self.assertIsNone(args.canonicalize_working_dir)

    def test_exec_root(self) -> None:
        args, _ = self._parser.parse_known_args(["--exec_root=/foo/bar"])
        self.assertEqual(args.exec_root, "/foo/bar")

    def test_canonicalize_working_dir_true(self) -> None:
        args, _ = self._parser.parse_known_args(
            ["--canonicalize_working_dir=true"]
        )
        self.assertTrue(args.canonicalize_working_dir)

    def test_canonicalize_working_dir_false(self) -> None:
        args, _ = self._parser.parse_known_args(
            ["--canonicalize_working_dir=false"]
        )
        self.assertFalse(args.canonicalize_working_dir)

    def test_help_unwanted(self) -> None:
        for opt in ("-h", "--help"):
            with mock.patch.object(sys, "exit") as mock_exit:
                self._parser.parse_known_args([opt])
            mock_exit.assert_not_called()


class RemoteActionMainParserTests(unittest.TestCase):
    @property
    def default_cfg(self) -> Path:
        return Path("default.cfg")

    @property
    def default_bindir(self) -> Path:
        return Path("/opt/reclient/bin")

    def _make_main_parser(self) -> argparse.ArgumentParser:
        parser = argparse.ArgumentParser()
        remote_action.inherit_main_arg_parser_flags(
            parser,
            default_cfg=self.default_cfg,
            default_bindir=self.default_bindir,
        )
        return parser

    def test_defaults(self) -> None:
        p = self._make_main_parser()
        main_args, other = p.parse_known_args(["--", "echo", "hello"])
        self.assertEqual(main_args.cfg, self.default_cfg)
        self.assertEqual(main_args.bindir, self.default_bindir)
        self.assertFalse(main_args.dry_run)
        self.assertFalse(main_args.verbose)
        self.assertEqual(main_args.label, "")
        self.assertEqual(main_args.remote_log, "")
        self.assertFalse(main_args.save_temps)
        self.assertIsNone(main_args.fsatrace_path)
        self.assertFalse(main_args.compare)
        self.assertFalse(main_args.diagnose_nonzero)
        self.assertEqual(main_args.command, ["echo", "hello"])
        self.assertIsNone(main_args.remote_debug_command)

    def test_cfg(self) -> None:
        p = self._make_main_parser()
        cfg = Path("other.cfg")
        main_args, other = p.parse_known_args([f"--cfg={cfg}", "--", "echo"])
        self.assertEqual(main_args.cfg, cfg)
        self.assertEqual(other, [])
        action = remote_action.remote_action_from_args(main_args)
        self.assertEqual(action.config, cfg)
        self.assertEqual(action.local_only_command, ["echo"])
        self.assertEqual(action.options, ["--cfg", str(cfg)])

    def test_platform_merge_override_no_env(self) -> None:
        p = self._make_main_parser()
        cfg = Path("other.cfg")
        platform_value = "foo=zoo,alice=bob"
        # Test both styles of flags.
        test_flag_variants = (
            [f"--platform={platform_value}"],
            ["--platform", platform_value],
        )
        for flags in test_flag_variants:
            main_args, remote_options = p.parse_known_args(
                [f"--cfg={cfg}"] + flags + ["--", "echo"]
            )
            self.assertEqual(main_args.cfg, cfg)
            self.assertEqual(main_args.platform, platform_value)
            action = remote_action.remote_action_from_args(
                main_args=main_args,
                remote_options=remote_options,
            )
            self.assertEqual(action.config, cfg)
            self.assertEqual(action.platform, platform_value)
            self.assertEqual(action.local_only_command, ["echo"])
            with mock.patch.object(
                Path,
                "read_text",
                return_value="\n".join(
                    [
                        "parameter_this=1",
                        "parameter_that=do_not_care",
                        "platform=foo=bar,baz=quux",
                    ]
                ),
            ) as mock_read_cfg:
                with mock.patch.object(
                    remote_action, "_rewrapper_platform_env", return_value=None
                ) as mock_env:
                    self.assertEqual(
                        action.options,
                        [
                            "--cfg",
                            str(cfg),
                            "--platform=alice=bob,baz=quux,foo=zoo",
                        ],
                    )

            mock_read_cfg.assert_called_once_with()
            mock_env.assert_called_once_with()

    def test_platform_merge_env_no_flag(self) -> None:
        p = self._make_main_parser()
        cfg = Path("other.cfg")
        platform_env = "foo=notfoo,alice=joe"
        # Test both styles of flags.
        main_args, remote_options = p.parse_known_args(
            [f"--cfg={cfg}", "--", "echo"]
        )
        self.assertEqual(main_args.cfg, cfg)
        action = remote_action.remote_action_from_args(
            main_args=main_args,
            remote_options=remote_options,
        )
        self.assertEqual(action.config, cfg)
        self.assertEqual(action.local_only_command, ["echo"])
        with mock.patch.object(
            Path,
            "read_text",
            return_value="\n".join(
                [
                    "parameter_this=1",
                    "parameter_that=do_not_care",
                    "platform=foo=bar,baz=quux",
                ]
            ),
        ) as mock_read_cfg:
            with mock.patch.object(
                remote_action,
                "_rewrapper_platform_env",
                return_value=platform_env,
            ) as mock_env:
                self.assertEqual(
                    action.options,
                    [
                        "--cfg",
                        str(cfg),
                        # no need to rewrite --platform flag
                    ],
                )
                self.assertEqual(
                    action.merged_platform,
                    # did not use cfg's platform values
                    {
                        "alice": "joe",
                        "foo": "notfoo",
                    },
                )

        mock_read_cfg.assert_not_called()  # used env, not cfg
        mock_env.assert_called_once_with()

    def test_platform_merge_override_with_env(self) -> None:
        p = self._make_main_parser()
        cfg = Path("other.cfg")
        platform_value = "foo=zoo,alice=bob"
        # Test both styles of flags.
        test_flag_variants = (
            [f"--platform={platform_value}"],
            ["--platform", platform_value],
        )
        for flags in test_flag_variants:
            main_args, remote_options = p.parse_known_args(
                [f"--cfg={cfg}"] + flags + ["--", "echo"]
            )
            self.assertEqual(main_args.cfg, cfg)
            self.assertEqual(main_args.platform, platform_value)
            action = remote_action.remote_action_from_args(
                main_args=main_args,
                remote_options=remote_options,
            )
            self.assertEqual(action.config, cfg)
            self.assertEqual(action.platform, platform_value)
            self.assertEqual(action.local_only_command, ["echo"])
            with mock.patch.object(
                Path,
                "read_text",
                return_value="\n".join(
                    [
                        "parameter_this=1",
                        "parameter_that=do_not_care",
                        "platform=foo=bar,baz=quux",
                    ]
                ),
            ) as mock_read_cfg:
                with mock.patch.object(
                    remote_action,
                    "_rewrapper_platform_env",
                    return_value="foo=env_foo,baz=env_baz",
                ) as mock_env:
                    self.assertEqual(
                        action.options,
                        [
                            "--cfg",
                            str(cfg),
                            "--platform=alice=bob,baz=env_baz,foo=zoo",
                        ],
                    )

            mock_read_cfg.assert_not_called()  # because env was used
            mock_env.assert_called_once_with()

    def test_bindir(self) -> None:
        p = self._make_main_parser()
        bindir = Path("/usr/local/bin")
        main_args, other = p.parse_known_args(
            ["--bindir", str(bindir), "--", "echo"]
        )
        self.assertEqual(main_args.bindir, bindir)
        action = remote_action.remote_action_from_args(main_args)
        self.assertEqual(action.local_only_command, ["echo"])

    def test_local_command_with_env(self) -> None:
        local_command = ["FOO=BAR", "echo"]
        p = self._make_main_parser()
        main_args, other = p.parse_known_args(["--"] + local_command)
        action = remote_action.remote_action_from_args(main_args)
        self.assertEqual(
            action.local_only_command, [cl_utils._ENV] + local_command
        )
        self.assertEqual(
            action.remote_only_command, [cl_utils._ENV] + local_command
        )

    def test_verbose(self) -> None:
        p = self._make_main_parser()
        main_args, other = p.parse_known_args(["--verbose", "--", "echo"])
        self.assertTrue(main_args.verbose)

    def test_dry_run(self) -> None:
        p = self._make_main_parser()
        main_args, other = p.parse_known_args(["--dry-run", "--", "echo"])
        self.assertTrue(main_args.dry_run)
        action = remote_action.remote_action_from_args(main_args)
        with mock.patch.object(remote_action.RemoteAction, "run") as mock_run:
            exit_code = action.run_with_main_args(main_args)
        self.assertEqual(exit_code, 0)
        mock_run.assert_not_called()

    @mock.patch.object(fuchsia, "REPROXY_WRAP", "/path/to/reproxy-wrap.sh")
    def test_auto_reproxy(self) -> None:
        # --auto-reproxy is now obsolete, and will be removed in the future
        p = self._make_main_parser()
        main_args, other = p.parse_known_args(["--auto-reproxy", "--", "echo"])
        self.assertTrue(main_args.auto_reproxy)
        action = remote_action.remote_action_from_args(main_args)
        self.assertEqual(action.local_only_command, ["echo"])
        rewrapper_prefix, _, remote_command = cl_utils.partition_sequence(
            action.launch_command, "--"
        )
        self.assertEqual(Path(rewrapper_prefix[0]).name, "rewrapper")
        self.assertEqual(remote_command, ["echo"])

    def test_save_temps(self) -> None:
        p = self._make_main_parser()
        main_args, other = p.parse_known_args(["--save-temps", "--", "echo"])
        self.assertTrue(main_args.save_temps)
        action = remote_action.remote_action_from_args(main_args)
        self.assertEqual(action.local_only_command, ["echo"])
        self.assertTrue(action.save_temps)

    def test_label(self) -> None:
        p = self._make_main_parser()
        main_args, other = p.parse_known_args(
            ["--label=//build/this:that", "--", "echo"]
        )
        self.assertEqual(main_args.label, "//build/this:that")

    def test_diagnose_nonzero(self) -> None:
        p = self._make_main_parser()
        main_args, other = p.parse_known_args(
            ["--diagnose-nonzero", "--", "echo"]
        )
        self.assertTrue(main_args.diagnose_nonzero)
        action = remote_action.remote_action_from_args(main_args)
        self.assertTrue(action.diagnose_nonzero)

    def test_input_list_paths(self) -> None:
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        input1 = Path("hello.txt")
        input2 = Path("goodbye.txt")
        with tempfile.TemporaryDirectory() as td:
            rspfile1 = Path(td) / "inputs.rsp"
            _write_file_contents(rspfile1, f"{input1}\n")
            rspfile2 = Path(td) / "more-inputs.rsp"
            _write_file_contents(rspfile2, f"{input2}\n")

            p = self._make_main_parser()
            main_args, other = p.parse_known_args(
                _strs(
                    [
                        f"--input_list_paths={rspfile1},{rspfile2}",
                        "--",
                        "cat",
                        input1,
                        input2,
                    ]
                )
            )
            action = remote_action.remote_action_from_args(
                main_args,
                exec_root=exec_root,
                working_dir=working_dir,
            )

            self.assertEqual(
                set(action.inputs_relative_to_project_root),
                {
                    build_dir / input1,
                    build_dir / input2,
                },  # relative to exec_root
            )

    def test_remote_debug_command(self) -> None:
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        input = Path("hello.txt")
        debug = "ls -l -R .."
        p = self._make_main_parser()
        main_args, other = p.parse_known_args(
            _strs([f"--remote-debug-command={debug}", "--", "cat", input])
        )
        action = remote_action.remote_action_from_args(
            main_args,
            inputs=[input],
            exec_root=exec_root,
            working_dir=working_dir,
        )

        self.assertEqual(action.remote_debug_command, debug.split())
        self.assertEqual(
            {build_dir / input}, set(action.inputs_relative_to_project_root)
        )
        with mock.patch.object(cl_utils, "subprocess_call") as mock_remote:
            self.assertEqual(action.run(), 1)
        mock_remote.assert_called_once()
        arg, kwargs = mock_remote.call_args_list[0]
        full_command = arg[0]
        rewrapper_prefix, sep, remote_command = cl_utils.partition_sequence(
            full_command, "--"
        )
        self.assertEqual(remote_command, debug.split())

    def test_remote_log_named(self) -> None:
        p = self._make_main_parser()
        main_args, other = p.parse_known_args(
            ["--log", "bar.remote-log", "--", "echo"]
        )
        self.assertEqual(main_args.remote_log, "bar.remote-log")

    def test_remote_log_unnamed(self) -> None:
        p = self._make_main_parser()
        main_args, other = p.parse_known_args(["--log", "--", "echo"])
        self.assertEqual(main_args.remote_log, "<AUTO>")

    def test_remote_log_from_main_args_auto_named(self) -> None:
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        output = Path("hello.txt")
        command = ["touch", str(output)]
        p = self._make_main_parser()
        main_args, other = p.parse_known_args(["--log", "--"] + command)
        action = remote_action.remote_action_from_args(
            main_args,
            output_files=[output],
            exec_root=exec_root,
            working_dir=working_dir,
        )

        self.assertEqual(
            [remote_action._REMOTE_LOG_SCRIPT],
            action.inputs_relative_to_project_root,
        )
        self.assertEqual(
            {build_dir / output, build_dir / (str(output) + ".remote-log")},
            set(action.output_files_relative_to_project_root),
        )
        # Ignore the rewrapper portion of the command
        full_command = action.launch_command
        command_slices = list(
            cl_utils.split_into_subsequences(full_command, "--")
        )
        prefix, log_wrapper, main_command = command_slices
        # Confirm that the remote command is wrapped with the logger script.
        self.assertEqual(
            log_wrapper,
            _strs(
                [
                    Path("..", remote_action._REMOTE_LOG_SCRIPT),
                    "--log",
                    str(output) + ".remote-log",
                ]
            ),
        )
        self.assertEqual(main_command, command)

    def test_remote_log_from_main_args_explicitly_named(self) -> None:
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        output = Path("hello.txt")
        log_base = "debug"
        p = self._make_main_parser()
        command = ["touch", str(output)]
        main_args, other = p.parse_known_args(
            ["--log", log_base, "--"] + command
        )
        action = remote_action.remote_action_from_args(
            main_args,
            output_files=[output],
            exec_root=exec_root,
            working_dir=working_dir,
        )

        self.assertEqual(
            [remote_action._REMOTE_LOG_SCRIPT],
            action.inputs_relative_to_project_root,
        )
        self.assertEqual(
            {
                build_dir / output,
                build_dir / (log_base + ".remote-log"),
            },
            set(action.output_files_relative_to_project_root),
        )
        # Ignore the rewrapper portion of the command
        command_slices = list(
            cl_utils.split_into_subsequences(action.launch_command, "--")
        )
        prefix, log_wrapper, main_command = command_slices
        # Confirm that the remote command is wrapped with the logger script.
        self.assertEqual(
            log_wrapper,
            _strs(
                [
                    Path("..", remote_action._REMOTE_LOG_SCRIPT),
                    "--log",
                    log_base + ".remote-log",
                ]
            ),
        )
        self.assertEqual(main_command, command)

    def test_remote_fsatrace_path_default(self) -> None:
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        output = Path("hello.txt")
        fake_fsatrace = fuchsia.FSATRACE_PATH
        fake_fsatrace_rel = Path(f"../{fake_fsatrace}")
        p = self._make_main_parser()
        command = ["touch", str(output)]
        # Pass "" to use the default fuchsia.FSATRACE_PATH
        main_args, other = p.parse_known_args(
            ["--fsatrace-path=", "--"] + command
        )
        self.assertEqual(main_args.fsatrace_path, Path(""))
        action = remote_action.remote_action_from_args(
            main_args,
            output_files=[output],
            exec_root=exec_root,
            working_dir=working_dir,
        )

        self.assertEqual(
            {fake_fsatrace, fake_fsatrace.with_suffix(".so")},
            set(action.inputs_relative_to_project_root),
        )
        self.assertEqual(
            {
                build_dir / output,  # relative to exec_root
                build_dir / (str(output) + ".remote-fsatrace"),
            },
            set(action.output_files_relative_to_project_root),
        )
        # Ignore the rewrapper portion of the command
        cmd_slices = cl_utils.split_into_subsequences(
            action.launch_command, "--"
        )
        rewrapper_prefix, fsatrace_prefix, remote_command = cmd_slices
        # Confirm that the remote command is wrapped with fsatrace
        self.assertIn(str(fake_fsatrace_rel), fsatrace_prefix)
        self.assertEqual(
            [*fsatrace_prefix, "--"],
            action._fsatrace_command_prefix(
                Path(str(output) + ".remote-fsatrace")
            ),
        )
        self.assertEqual(remote_command, command)

    def test_remote_fsatrace_from_main_args(self) -> None:
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        output = Path("hello.txt")
        fake_fsatrace = Path("tools/debug/fsatrace")
        fake_fsatrace_rel = Path(f"../{fake_fsatrace}")
        p = self._make_main_parser()
        main_args, other = p.parse_known_args(
            _strs(["--fsatrace-path", fake_fsatrace_rel, "--", "touch", output])
        )
        action = remote_action.remote_action_from_args(
            main_args,
            output_files=[output],
            exec_root=exec_root,
            working_dir=working_dir,
        )

        self.assertEqual(
            {fake_fsatrace, fake_fsatrace.with_suffix(".so")},
            set(action.inputs_relative_to_project_root),
        )
        self.assertEqual(
            {
                build_dir / output,
                build_dir / (str(output) + ".remote-fsatrace"),
            },
            set(action.output_files_relative_to_project_root),
        )
        # Ignore the rewrapper portion of the command
        full_command = action.launch_command
        command_slices = list(
            cl_utils.split_into_subsequences(action.launch_command, "--")
        )
        prefix, trace_wrapper, main_command = command_slices
        # Confirm that the remote command is wrapped with fsatrace
        self.assertIn(str(fake_fsatrace_rel), trace_wrapper)
        self.assertEqual(
            [*trace_wrapper, "--"],
            action._fsatrace_command_prefix(
                Path(str(output) + ".remote-fsatrace")
            ),
        )
        self.assertEqual(main_command, ["touch", str(output)])

    def test_remote_log_and_fsatrace_from_main_args(self) -> None:
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        output = Path("hello.txt")
        command = ["touch", str(output)]
        fake_fsatrace = Path("tools/debug/fsatrace")
        fake_fsatrace_rel = Path("..", fake_fsatrace)
        p = self._make_main_parser()
        main_args, other = p.parse_known_args(
            _strs(
                ["--fsatrace-path", fake_fsatrace_rel, "--log", "--"] + command
            )
        )
        action = remote_action.remote_action_from_args(
            main_args,
            output_files=[output],
            exec_root=exec_root,
            working_dir=working_dir,
        )

        self.assertEqual(
            {
                remote_action._REMOTE_LOG_SCRIPT,
                fake_fsatrace,
                fake_fsatrace.with_suffix(".so"),
            },
            set(action.inputs_relative_to_project_root),
        )
        self.assertEqual(
            {
                build_dir / output,
                build_dir / (str(output) + ".remote-log"),
                build_dir / (str(output) + ".remote-fsatrace"),
            },
            set(action.output_files_relative_to_project_root),
        )
        # Ignore the rewrapper portion of the command
        command_slices = list(
            cl_utils.split_into_subsequences(action.launch_command, "--")
        )
        (
            rewrapper_prefix,
            log_wrapper,
            trace_wrapper,
            main_command,
        ) = command_slices
        # Confirm that the outer wrapper is for logging
        self.assertEqual(
            log_wrapper,
            _strs(
                [
                    Path("..", remote_action._REMOTE_LOG_SCRIPT),
                    "--log",
                    str(output) + ".remote-log",
                ]
            ),
        )
        # Confirm that the inner wrapper is for fsatrace
        self.assertEqual(
            [*trace_wrapper, "--"],
            action._fsatrace_command_prefix(
                Path(str(output) + ".remote-fsatrace")
            ),
        )
        self.assertEqual(main_command, command)

    def test_local_only_no_compare(self) -> None:
        # --compare does nothing with --local
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        output = Path("hello.txt")
        base_command = ["touch", str(output)]
        p = self._make_main_parser()
        main_args, other = p.parse_known_args(
            ["--compare", "--local", "--"] + base_command
        )
        action = remote_action.remote_action_from_args(
            main_args,
            output_files=[output],
            exec_root=exec_root,
            working_dir=working_dir,
        )
        self.assertTrue(action.remote_disable)
        self.assertTrue(action.compare_with_local)

        with mock.patch.object(
            remote_action.RemoteAction, "run", return_value=0
        ) as mock_run:
            with mock.patch.object(
                remote_action.RemoteAction, "_compare_against_local"
            ) as mock_compare:
                exit_code = action.run_with_main_args(main_args)

        self.assertEqual(exit_code, 0)
        mock_run.assert_called_once()
        mock_compare.assert_not_called()

    def test_compare_forces_remote(self) -> None:
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        output = Path("hello.txt")
        base_command = ["touch", str(output)]
        p = self._make_main_parser()
        main_args, other = p.parse_known_args(
            ["--compare", "--exec_strategy=local", "--"] + base_command
        )
        action = remote_action.remote_action_from_args(
            main_args,
            output_files=[output],
            exec_root=exec_root,
            working_dir=working_dir,
        )
        self.assertFalse(action.remote_disable)
        self.assertTrue(action.compare_with_local)
        self.assertEqual(action.exec_strategy, "remote")  # forced

    def test_compare_fsatraces_acceptable_match(self) -> None:
        exec_root = Path("/home/project")
        build_dir = Path("build/out/here")
        working_dir = exec_root / build_dir
        p = self._make_main_parser()
        action = remote_action.RemoteAction(
            rewrapper=Path("/test-build/rewrapper"),
            command=["sleep", "1h"],
            options=["--canonicalize_working_dir=true"],
            exec_root=exec_root,
            working_dir=working_dir,
        )
        self.assertTrue(action.canonicalize_working_dir)
        local_trace_contents = f"""r|{exec_root}/src/input.c
w|{working_dir}/obj/input.o
"""
        remote_root = remote_action._REMOTE_PROJECT_ROOT
        remote_trace_contents = f"""r|{remote_root}/src/input.c
w|{remote_root}/set_by_reclient/a/a/obj/input.o
"""
        self.assertNotEqual(local_trace_contents, remote_trace_contents)
        with tempfile.TemporaryDirectory() as td:
            local_trace = Path(td) / "local.trace"
            remote_trace = Path(td) / "remote.trace"
            _write_file_contents(local_trace, local_trace_contents)
            _write_file_contents(remote_trace, remote_trace_contents)
            diff_text = io.StringIO()
            with contextlib.redirect_stdout(diff_text):
                status = action._compare_fsatraces_select_logs(
                    local_trace=local_trace,
                    remote_trace=remote_trace,
                )
        self.assertEqual(status.returncode, 0)  # contents are equivalent

    def test_compare_fsatraces_with_difference(self) -> None:
        exec_root = Path("/home/project")
        build_dir = Path("build/out/here")
        working_dir = exec_root / build_dir
        p = self._make_main_parser()
        action = remote_action.RemoteAction(
            rewrapper=Path("/test-build/rewrapper"),
            command=["sleep", "1h"],
            options=["--canonicalize_working_dir=true"],
            exec_root=exec_root,
            working_dir=working_dir,
        )
        self.assertTrue(action.canonicalize_working_dir)
        local_trace_contents = f"""r|{exec_root}/src/input.c
w|{working_dir}/obj/input.o
"""
        remote_root = remote_action._REMOTE_PROJECT_ROOT
        remote_trace_contents = f"""r|{remote_root}/src/input.c
r|{remote_root}/includes/input.h
w|{remote_root}/set_by_reclient/a/a/obj/input.o
"""
        self.assertNotEqual(local_trace_contents, remote_trace_contents)
        with tempfile.TemporaryDirectory() as td:
            local_trace = Path(td) / "local.trace"
            remote_trace = Path(td) / "remote.trace"
            _write_file_contents(local_trace, local_trace_contents)
            _write_file_contents(remote_trace, remote_trace_contents)
            diff_text = io.StringIO()
            with contextlib.redirect_stdout(diff_text):
                result = action._compare_fsatraces_select_logs(
                    local_trace=local_trace,
                    remote_trace=remote_trace,
                )
        self.assertEqual(result.returncode, 1)  # traces differ

    def test_local_remote_compare_no_diffs_from_main_args(self) -> None:
        # Same as test_remote_fsatrace_from_main_args, but with --compare
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        output = Path("hello.txt")
        base_command = ["touch", str(output)]
        p = self._make_main_parser()
        main_args, other = p.parse_known_args(
            ["--compare", "--"] + base_command
        )
        action = remote_action.remote_action_from_args(
            main_args,
            output_files=[output],
            exec_root=exec_root,
            working_dir=working_dir,
        )
        self.assertTrue(action.compare_with_local)

        unnamed_mocks = [
            # we don't bother to check the call details of these mocks
            mock.patch.object(Path, "rename"),
            mock.patch.object(Path, "is_file", return_value=True),
            # Pretend comparison finds no differences
            mock.patch.object(remote_action, "_files_match", return_value=True),
        ]
        with contextlib.ExitStack() as stack:
            for m in unnamed_mocks:
                stack.enter_context(m)

            # both local and remote commands succeed
            with mock.patch.object(
                remote_action.RemoteAction, "_run_locally", return_value=0
            ) as mock_local_launch:
                with mock.patch.object(
                    remote_action.RemoteAction,
                    "_run_maybe_remotely",
                    return_value=cl_utils.SubprocessResult(0),
                ) as mock_remote_launch:
                    with mock.patch.object(
                        remote_action.RemoteAction, "_compare_fsatraces"
                    ) as mock_compare_traces:
                        with mock.patch.object(os, "remove") as mock_cleanup:
                            exit_code = action.run_with_main_args(main_args)

        remote_command = action.launch_command
        self.assertEqual(exit_code, 0)  # remote success and compare success
        mock_compare_traces.assert_not_called()
        mock_local_launch.assert_called_once()
        mock_remote_launch.assert_called_once()
        self.assertEqual(remote_command[-2:], base_command)
        mock_cleanup.assert_called_with(Path(str(output) + ".remote"))

    def test_local_remote_compare_found_diffs_from_main_args(self) -> None:
        # Same as test_remote_fsatrace_from_main_args, but with --compare
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        output = Path("hello.txt")
        base_command = ["touch", str(output)]
        p = self._make_main_parser()
        main_args, other = p.parse_known_args(
            ["--compare", "--"] + base_command
        )
        action = remote_action.remote_action_from_args(
            main_args,
            output_files=[output],
            exec_root=exec_root,
            working_dir=working_dir,
        )
        self.assertTrue(action.compare_with_local)

        unnamed_mocks = [
            # we don't bother to check the call details of these mocks
            mock.patch.object(Path, "rename"),
            mock.patch.object(Path, "is_file", return_value=True),
            # Pretend comparison finds differences
            mock.patch.object(
                remote_action, "_files_match", return_value=False
            ),
            mock.patch.object(remote_action, "_detail_diff"),
        ]
        with contextlib.ExitStack() as stack:
            for m in unnamed_mocks:
                stack.enter_context(m)

            # both local and remote commands succeed
            with mock.patch.object(
                remote_action.RemoteAction, "_run_locally", return_value=0
            ) as mock_local_launch:
                with mock.patch.object(
                    remote_action.RemoteAction,
                    "_run_maybe_remotely",
                    return_value=cl_utils.SubprocessResult(0),
                ) as mock_remote_launch:
                    with mock.patch.object(
                        remote_action.RemoteAction, "_compare_fsatraces"
                    ) as mock_compare_traces:
                        exit_code = action.run_with_main_args(main_args)

        remote_command = action.launch_command
        self.assertEqual(exit_code, 1)  # remote success, but compare failure
        mock_compare_traces.assert_not_called()
        mock_local_launch.assert_called_once()
        mock_remote_launch.assert_called_once()
        self.assertEqual(remote_command[-2:], base_command)

    def test_local_remote_compare_found_diffs_exported_files(self) -> None:
        # Checks that miscompared files are exported.
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        output = Path("hello.txt")
        input = Path("../greet.in")
        export_dir = Path("naughty/diffs")  # relative to working dir
        export_dir_abs = working_dir / export_dir
        base_command = ["touch", str(output)]
        p = self._make_main_parser()
        main_args, other = p.parse_known_args(
            ["--compare", f"--miscomparison-export-dir={export_dir}", "--"]
            + base_command
        )
        action = remote_action.remote_action_from_args(
            main_args,
            inputs=[input],
            output_files=[output],
            exec_root=exec_root,
            working_dir=working_dir,
        )
        self.assertTrue(action.compare_with_local)
        self.assertEqual(
            action.miscomparison_export_dir, working_dir / export_dir
        )

        unnamed_mocks = [
            # we don't bother to check the call details of these mocks
            mock.patch.object(Path, "rename"),
            mock.patch.object(Path, "is_file", return_value=True),
            # Pretend comparison finds differences
            mock.patch.object(
                remote_action, "_files_match", return_value=False
            ),
            mock.patch.object(remote_action, "_detail_diff"),
        ]
        with contextlib.ExitStack() as stack:
            for m in unnamed_mocks:
                stack.enter_context(m)

            # both local and remote commands succeed
            with mock.patch.object(
                remote_action.RemoteAction, "_run_locally", return_value=0
            ) as mock_local_launch:
                with mock.patch.object(
                    remote_action.RemoteAction,
                    "_run_maybe_remotely",
                    return_value=cl_utils.SubprocessResult(0),
                ) as mock_remote_launch:
                    with mock.patch.object(
                        remote_action.RemoteAction, "_compare_fsatraces"
                    ) as mock_compare_traces:
                        with mock.patch.object(
                            cl_utils,
                            "chdir_cm",
                            return_value=contextlib.nullcontext(),
                        ) as mock_chdir:
                            with mock.patch.object(
                                cl_utils, "copy_preserve_subpath"
                            ) as mock_export:
                                exit_code = action.run_with_main_args(main_args)

        remote_command = action.launch_command
        self.assertEqual(exit_code, 1)  # remote success, but compare failure
        mock_compare_traces.assert_not_called()
        mock_local_launch.assert_called_once()
        mock_remote_launch.assert_called_once()
        self.assertEqual(remote_command[-2:], base_command)
        # Make sure we copied the differences to the export dir
        mock_export.assert_has_calls(
            [
                mock.call(build_dir / output, export_dir_abs),
                mock.call(
                    build_dir / Path(str(output) + ".remote"), export_dir_abs
                ),
                mock.call(Path("greet.in"), export_dir_abs),
            ],
            any_order=True,
        )
        mock_chdir.assert_called_with(exec_root)

    def test_local_remote_compare_with_fsatrace_from_main_args(self) -> None:
        # Same as test_remote_fsatrace_from_main_args, but with --compare
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        output = Path("hello.txt")
        fake_fsatrace = Path("tools/debug/fsatrace")
        fake_fsatrace_rel = Path("..", fake_fsatrace)
        p = self._make_main_parser()
        main_args, other = p.parse_known_args(
            _strs(
                [
                    "--compare",
                    "--fsatrace-path",
                    fake_fsatrace_rel,
                    "--",
                    "touch",
                    output,
                ]
            )
        )
        action = remote_action.remote_action_from_args(
            main_args,
            output_files=[output],
            exec_root=exec_root,
            working_dir=working_dir,
        )

        # not repeating the same asserts from
        #   test_remote_fsatrace_from_main_args:

        unnamed_mocks = [
            # we don't bother to check the call details of these mocks
            mock.patch.object(Path, "rename"),
            mock.patch.object(Path, "is_file", return_value=True),
            # Pretend comparison finds differences
            mock.patch.object(
                remote_action, "_files_match", return_value=False
            ),
            mock.patch.object(remote_action, "_detail_diff"),
            # in RemoteAction._compare_fsatraces:
            mock.patch.object(remote_action, "_transform_file_by_lines"),
        ]
        with contextlib.ExitStack() as stack:
            for m in unnamed_mocks:
                stack.enter_context(m)

            # both local and remote commands succeed
            with mock.patch.object(
                remote_action.RemoteAction, "_run_locally", return_value=0
            ) as mock_local_launch:
                with mock.patch.object(
                    remote_action.RemoteAction,
                    "_run_maybe_remotely",
                    return_value=cl_utils.SubprocessResult(0),
                ) as mock_remote_launch:
                    with mock.patch.object(
                        remote_action,
                        "_text_diff",
                        return_value=cl_utils.SubprocessResult(0),
                    ) as mock_trace_diff:
                        exit_code = action.run_with_main_args(main_args)

        remote_command = action.launch_command
        # make sure local command is also traced
        local_command = list(action._generate_local_launch_command())
        self.assertEqual(exit_code, 1)  # remote success, but compare failure
        mock_remote_launch.assert_called_once()
        mock_local_launch.assert_called_once()
        self.assertIn(str(fake_fsatrace_rel), remote_command)
        self.assertIn(str(fake_fsatrace_rel), local_command)
        remote_trace = str(output) + ".remote-fsatrace"
        local_trace = str(output) + ".local-fsatrace"
        self.assertIn(remote_trace, remote_command)
        self.assertIn(local_trace, local_command)
        mock_trace_diff.assert_called_with(
            Path(local_trace + ".norm"), Path(remote_trace + ".norm")
        )

    def test_local_check_determinism(self) -> None:
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        exec_root_rel = cl_utils.relpath(exec_root, start=working_dir)
        output = Path("hello.txt")
        base_command = ["touch", str(output)]
        p = self._make_main_parser()
        main_args, other = p.parse_known_args(
            ["--check-determinism", "--local", "--"] + base_command
        )
        action = remote_action.remote_action_from_args(
            main_args,
            output_files=[output],
            exec_root=exec_root,
            working_dir=working_dir,
        )
        self.assertTrue(action.remote_disable)

        with mock.patch.object(
            cl_utils,
            "subprocess_call",
            return_value=cl_utils.SubprocessResult(0),
        ) as mock_run:
            exit_code = action.run_with_main_args(main_args)

        self.assertEqual(exit_code, 0)
        mock_run.assert_called_once()
        args, kwargs = mock_run.call_args_list[0]
        launch_command = args[0]
        self.assertEqual(kwargs["cwd"], working_dir)
        check_prefix, sep, main_command = cl_utils.partition_sequence(
            launch_command, "--"
        )
        self.assertEqual(check_prefix[0], sys.executable)
        self.assertIn(
            str(exec_root_rel / fuchsia._CHECK_DETERMINISM_SCRIPT), check_prefix
        )
        self.assertIn("--check-repeatability", check_prefix)
        _, _, output_list = cl_utils.partition_sequence(
            check_prefix, "--outputs"
        )
        self.assertEqual(output_list, [str(output)])
        self.assertEqual(main_command, base_command)

    def test_local_check_determinism_with_export(self) -> None:
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        exec_root_rel = cl_utils.relpath(exec_root, start=working_dir)
        output = Path("hello.txt")
        base_command = ["touch", str(output)]
        p = self._make_main_parser()
        export_dir = Path("saved-diffs")  # relative to working dir
        export_dir_abs = working_dir / export_dir
        main_args, other = p.parse_known_args(
            [
                "--check-determinism",
                "--local",
                # request that differences be saved to an export dir
                f"--miscomparison-export-dir={export_dir}",
                "--",
            ]
            + base_command
        )
        action = remote_action.remote_action_from_args(
            main_args,
            output_files=[output],
            exec_root=exec_root,
            working_dir=working_dir,
        )
        self.assertTrue(action.remote_disable)
        self.assertEqual(
            action.miscomparison_export_dir, working_dir / export_dir
        )

        with mock.patch.object(
            cl_utils,
            "subprocess_call",
            return_value=cl_utils.SubprocessResult(0),
        ) as mock_run:
            exit_code = action.run_with_main_args(main_args)

        self.assertEqual(exit_code, 0)
        mock_run.assert_called_once()
        args, kwargs = mock_run.call_args_list[0]
        launch_command = args[0]
        self.assertEqual(kwargs["cwd"], working_dir)
        check_prefix, sep, main_command = cl_utils.partition_sequence(
            launch_command, "--"
        )
        self.assertEqual(check_prefix[0], sys.executable)
        self.assertIn(
            str(exec_root_rel / fuchsia._CHECK_DETERMINISM_SCRIPT), check_prefix
        )
        self.assertIn("--check-repeatability", check_prefix)
        # Make sure export dir argument is forwarded.
        export_out_dir = export_dir_abs / build_dir
        self.assertIn(
            f"--miscomparison-export-dir={export_out_dir}", check_prefix
        )
        _, _, output_list = cl_utils.partition_sequence(
            check_prefix, "--outputs"
        )
        self.assertEqual(output_list, [str(output)])
        self.assertEqual(main_command, base_command)

    def test_output_leak_scan_with_canonical_working_dir_mocked(self) -> None:
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        canonical_dir_option = "--canonicalize_working_dir=true"
        p = self._make_main_parser()
        command = ["echo"]
        main_args, other = p.parse_known_args(
            [canonical_dir_option, "--"] + command
        )
        action = remote_action.remote_action_from_args(
            main_args,
            remote_options=other,
            exec_root=exec_root,
            working_dir=working_dir,
        )
        self.assertEqual(action.local_only_command, command)
        self.assertTrue(action.canonicalize_working_dir)
        self.assertIn(canonical_dir_option, action.options)
        with mock.patch.object(
            output_leak_scanner, "preflight_checks", return_value=0
        ) as mock_scan:
            with mock.patch.object(
                remote_action.RemoteAction,
                "_run_maybe_remotely",
                return_value=cl_utils.SubprocessResult(0),
            ) as mock_run:
                exit_code = action.run()
        self.assertEqual(exit_code, 0)
        mock_scan.assert_called_with(
            paths=[],
            command=command,
            pattern=output_leak_scanner.PathPattern(action.build_subdir),
        )
        mock_run.assert_called()

    def test_output_leak_scan_skipped_when_build_subdir_is_dot(self) -> None:
        exec_root = Path("/home/project")
        working_dir = exec_root  # build_subdir == '.'
        canonical_dir_option = "--canonicalize_working_dir=true"
        p = self._make_main_parser()
        command = ["echo"]
        main_args, other = p.parse_known_args(
            [canonical_dir_option, "--"] + command
        )
        action = remote_action.remote_action_from_args(
            main_args,
            remote_options=other,
            exec_root=exec_root,
            working_dir=working_dir,
        )
        self.assertEqual(action.local_only_command, command)
        self.assertTrue(action.canonicalize_working_dir)
        self.assertIn(canonical_dir_option, action.options)
        with mock.patch.object(
            output_leak_scanner, "preflight_checks", return_value=0
        ) as mock_scan:
            with mock.patch.object(
                remote_action.RemoteAction,
                "_run_maybe_remotely",
                return_value=cl_utils.SubprocessResult(0),
            ) as mock_run:
                exit_code = action.run()
        self.assertEqual(exit_code, 0)
        mock_scan.assert_not_called()
        mock_run.assert_called()

    def test_output_leak_scan_with_canonical_working_dir_called(self) -> None:
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        canonical_dir_option = "--canonicalize_working_dir=true"
        p = self._make_main_parser()
        command = ["echo"]
        main_args, other = p.parse_known_args(
            [canonical_dir_option, "--"] + command
        )
        action = remote_action.remote_action_from_args(
            main_args,
            remote_options=other,
            exec_root=exec_root,
            working_dir=working_dir,
        )
        self.assertEqual(action.local_only_command, command)
        self.assertTrue(action.canonicalize_working_dir)
        self.assertIn(canonical_dir_option, action.options)
        with mock.patch.object(
            remote_action.RemoteAction,
            "_run_maybe_remotely",
            return_value=cl_utils.SubprocessResult(0),
        ) as mock_run:
            exit_code = action.run()
        self.assertEqual(exit_code, 0)
        mock_run.assert_called()

    def test_output_leak_scan_with_error_stops_run(self) -> None:
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        canonical_dir_option = "--canonicalize_working_dir=true"
        p = self._make_main_parser()
        command = ["echo", str(build_dir)]  # command leaks build_dir
        main_args, other = p.parse_known_args(
            [canonical_dir_option, "--"] + command
        )
        action = remote_action.remote_action_from_args(
            main_args,
            remote_options=other,
            exec_root=exec_root,
            working_dir=working_dir,
        )
        self.assertEqual(action.local_only_command, command)
        self.assertTrue(action.canonicalize_working_dir)
        self.assertIn(canonical_dir_option, action.options)
        with mock.patch.object(
            remote_action.RemoteAction,
            "_run_maybe_remotely",
            return_value=cl_utils.SubprocessResult(0),
        ) as mock_run:
            exit_code = action.run()
        self.assertEqual(exit_code, 1)  # due to output_leak_scanner
        # The output_leak_scan error stopped execution.
        mock_run.assert_not_called()


class RemoteActionFlagParserTests(unittest.TestCase):
    def _forward_and_parse(
        self, command: Sequence[str]
    ) -> tuple[argparse.Namespace, list[str], Sequence[str]]:
        forwarded, filtered = remote_action.forward_remote_flags(
            ["--", *command]
        )
        main_args, unknown = remote_action._MAIN_ARG_PARSER.parse_known_args(
            forwarded
        )
        return main_args, unknown, filtered

    def test_defaults(self) -> None:
        remote_args, unknown, other = self._forward_and_parse([])
        self.assertFalse(remote_args.local)
        self.assertEqual(remote_args.inputs, [])
        self.assertEqual(remote_args.output_files, [])
        self.assertEqual(remote_args.output_directories, [])
        self.assertEqual(unknown, [])
        self.assertEqual(other, [])

    def test_command_without_forwarding(self) -> None:
        command = [
            "clang++",
            "--target=powerpc-apple-darwin8",
            "-fcrash-diagnostics-dir=nothing/to/see/here",
            "-c",
            "hello.cxx",
            "-o",
            "hello.o",
        ]
        remote_args, unknown, other = self._forward_and_parse(command)
        self.assertFalse(remote_args.local)
        self.assertEqual(remote_args.inputs, [])
        self.assertEqual(remote_args.output_files, [])
        self.assertEqual(remote_args.output_directories, [])
        self.assertEqual(unknown, [])
        self.assertEqual(other, command)

    def test_disable(self) -> None:
        remote_args, unknown, other = self._forward_and_parse(
            ["cat", "foo.txt", "--remote-disable"]
        )
        self.assertTrue(remote_args.local)
        self.assertEqual(unknown, [])
        self.assertEqual(other, ["cat", "foo.txt"])

    def test_inputs(self) -> None:
        remote_args, unknown, other = self._forward_and_parse(
            [
                "cat",
                "--remote-inputs=bar.txt",
                "bar.txt",
                "--remote-inputs=quux.txt",
                "quux.txt",
            ]
        )
        self.assertEqual(remote_args.inputs, ["bar.txt", "quux.txt"])
        self.assertEqual(unknown, [])
        self.assertEqual(other, ["cat", "bar.txt", "quux.txt"])

    def test_inputs_comma(self) -> None:
        remote_args, unknown, other = self._forward_and_parse(
            [
                "cat",
                "--remote-inputs=w,x",
                "bar.txt",
                "--remote-inputs=y,z",
                "quux.txt",
            ]
        )
        self.assertEqual(
            list(cl_utils.flatten_comma_list(remote_args.inputs)),
            ["w", "x", "y", "z"],
        )
        self.assertEqual(unknown, [])
        self.assertEqual(other, ["cat", "bar.txt", "quux.txt"])

    def test_output_files_comma(self) -> None:
        remote_args, unknown, other = self._forward_and_parse(
            [
                "./generate.sh",
                "--remote-outputs=w,x",
                "bar.txt",
                "--remote-outputs=y,z",
                "quux.txt",
            ]
        )
        self.assertEqual(
            list(cl_utils.flatten_comma_list(remote_args.output_files)),
            ["w", "x", "y", "z"],
        )
        self.assertEqual(unknown, [])
        self.assertEqual(other, ["./generate.sh", "bar.txt", "quux.txt"])

    def test_output_dirs_comma(self) -> None:
        remote_args, unknown, other = self._forward_and_parse(
            [
                "./generate_dirs.sh",
                "--remote-output-dirs=w,x",
                "bar.txt",
                "--remote-output-dirs=y,z",
                "quux.txt",
            ]
        )
        self.assertEqual(
            list(cl_utils.flatten_comma_list(remote_args.output_directories)),
            ["w", "x", "y", "z"],
        )
        self.assertEqual(unknown, [])
        self.assertEqual(other, ["./generate_dirs.sh", "bar.txt", "quux.txt"])

    def test_flags(self) -> None:
        remote_args, unknown, other = self._forward_and_parse(
            [
                "cat",
                "--remote-flag=--foo=bar",
                "bar.txt",
                "--remote-flag=--opt=quux",
                "quux.txt",
            ]
        )
        self.assertEqual(unknown, ["--foo=bar", "--opt=quux"])
        self.assertEqual(other, ["cat", "bar.txt", "quux.txt"])


class RemoteActionConstructionTests(unittest.TestCase):
    _PROJECT_ROOT = Path("/my/project/root")
    _WORKING_DIR = _PROJECT_ROOT / "build_dir"

    @property
    def _rewrapper(self) -> Path:
        return Path("/path/to/rewrapper")

    def _make_remote_action(
        self,
        rewrapper: Path | None = None,
        command: Sequence[str] | None = None,
        exec_root: Path | None = None,
        working_dir: Path | None = None,
        **kwargs: Any,  # RemoteAction params
    ) -> remote_action.RemoteAction:
        """Create a RemoteAction for testing with some defaults."""
        return remote_action.RemoteAction(
            rewrapper=rewrapper or self._rewrapper,
            command=command,  # type: ignore[arg-type]
            exec_root=exec_root or self._PROJECT_ROOT,
            working_dir=working_dir or self._WORKING_DIR,
            **kwargs,
        )

    def test_minimal(self) -> None:
        command = ["cat", "meow.txt"]
        action = self._make_remote_action(command=command)
        self.assertEqual(action.remote_only_command, command)
        self.assertEqual(action.local_only_command, command)
        self.assertEqual(action.exec_root, self._PROJECT_ROOT)
        self.assertEqual(action.exec_root_rel, Path(".."))
        self.assertFalse(action.save_temps)
        self.assertFalse(action.remote_disable)
        self.assertEqual(action.build_subdir, Path("build_dir"))
        self.assertEqual(
            action.launch_command,
            [str(self._rewrapper), f"--exec_root={self._PROJECT_ROOT}", "--"]
            + command,
        )
        self.assertFalse(action.compare_with_local)
        self.assertFalse(action.check_determinism)
        self.assertFalse(action.diagnose_nonzero)
        self.assertTrue(action.download_outputs)

    def test_path_setup_implicit(self) -> None:
        command = ["beep", "boop"]
        fake_root = Path("/home/project")
        fake_builddir = Path("out/not-default")
        fake_cwd = fake_root / fake_builddir
        with mock.patch.object(os, "curdir", fake_cwd):
            with mock.patch.object(remote_action, "PROJECT_ROOT", fake_root):
                action = remote_action.RemoteAction(
                    rewrapper=self._rewrapper,
                    command=command,
                )
                self.assertEqual(action.exec_root, fake_root)
                self.assertEqual(action.exec_root_rel, Path("../.."))
                self.assertEqual(action.build_subdir, fake_builddir)

    def test_path_setup_explicit_exec_root(self) -> None:
        command = ["beep", "boop"]
        fake_root = Path("/home/project")
        fake_builddir = Path("out/not-default")
        fake_cwd = fake_root / fake_builddir
        with mock.patch.object(os, "curdir", fake_cwd):
            action = remote_action.RemoteAction(
                rewrapper=self._rewrapper,
                command=command,
                exec_root=fake_root,
            )
            self.assertEqual(action.exec_root, fake_root)
            self.assertEqual(action.exec_root_rel, Path("../.."))
            self.assertEqual(action.build_subdir, fake_builddir)

    def test_path_setup_explicit_exec_root_and_working_dir(self) -> None:
        command = ["beep", "boop"]
        fake_root = Path("/home/project")
        fake_builddir = Path("out/not-default")
        fake_cwd = fake_root / fake_builddir
        action = remote_action.RemoteAction(
            rewrapper=self._rewrapper,
            command=command,
            exec_root=fake_root,
            working_dir=fake_cwd,
        )
        self.assertEqual(action.exec_root, fake_root)
        self.assertEqual(action.exec_root_rel, Path("../.."))
        self.assertEqual(action.build_subdir, fake_builddir)
        self.assertEqual(action.working_dir, fake_cwd)
        self.assertFalse(action.canonicalize_working_dir)
        self.assertEqual(action.remote_build_subdir, fake_builddir)
        self.assertEqual(
            action.remote_working_dir,
            remote_action._REMOTE_PROJECT_ROOT / fake_builddir,
        )

    def test_path_setup_explicit_canonicalize_working_dir(self) -> None:
        command = ["b33p", "b00p"]
        fake_root = Path("/home/project")
        fake_builddir = Path("out/not-default")
        fake_cwd = fake_root / fake_builddir
        action = remote_action.RemoteAction(
            rewrapper=self._rewrapper,
            options=["--canonicalize_working_dir=true"],
            command=command,
            exec_root=fake_root,
            working_dir=fake_cwd,
        )
        self.assertEqual(action.exec_root, fake_root)
        self.assertEqual(action.exec_root_rel, Path("../.."))
        self.assertEqual(action.build_subdir, fake_builddir)
        self.assertEqual(action.working_dir, fake_cwd)
        self.assertTrue(action.canonicalize_working_dir)
        remote_builddir = Path("set_by_reclient/a")
        self.assertEqual(action.remote_build_subdir, remote_builddir)
        self.assertEqual(
            action.remote_working_dir,
            remote_action._REMOTE_PROJECT_ROOT / remote_builddir,
        )

    def test_inputs_outputs(self) -> None:
        command = ["cat", "../src/meow.txt"]
        action = self._make_remote_action(
            command=command,
            inputs=_paths(["../src/meow.txt"]),
            output_files=_paths(["obj/woof.txt"]),
            output_dirs=_paths([".debug"]),
        )
        self.assertEqual(action.build_subdir, Path("build_dir"))
        self.assertEqual(
            action.inputs_relative_to_project_root, _paths(["src/meow.txt"])
        )
        self.assertEqual(
            action.output_files_relative_to_project_root,
            _paths(["build_dir/obj/woof.txt"]),
        )
        self.assertEqual(
            action.output_dirs_relative_to_project_root,
            _paths(["build_dir/.debug"]),
        )
        with mock.patch.object(
            remote_action.RemoteAction,
            "_generated_inputs_list_file",
            return_value=Path("obj/woof.txt.inputs"),
        ) as mock_input_list_file:
            self.assertEqual(
                action.launch_command,
                [
                    "/path/to/rewrapper",
                    f"--exec_root={self._PROJECT_ROOT}",
                    "--input_list_paths=obj/woof.txt.inputs",
                    "--output_files=build_dir/obj/woof.txt",
                    "--output_directories=build_dir/.debug",
                    "--",
                    "cat",
                    "../src/meow.txt",
                ],
            )
            mock_input_list_file.assert_called_once()
            with mock.patch.object(
                remote_action.RemoteAction,
                "_run_maybe_remotely",
                return_value=cl_utils.SubprocessResult(0),
            ) as mock_call:
                with mock.patch.object(
                    remote_action.RemoteAction, "_cleanup"
                ) as mock_cleanup:
                    self.assertEqual(action.run(), 0)
                    mock_call.assert_called_once()
                    mock_cleanup.assert_called_once()

    def test_save_temps(self) -> None:
        command = ["echo", "hello"]
        action = self._make_remote_action(
            command=command,
            save_temps=True,
        )
        self.assertEqual(action.local_only_command, command)
        self.assertEqual(action.exec_root, self._PROJECT_ROOT)
        self.assertTrue(action.save_temps)
        with mock.patch.object(
            remote_action.RemoteAction,
            "_run_maybe_remotely",
            return_value=cl_utils.SubprocessResult(0),
        ) as mock_call:
            with mock.patch.object(
                remote_action.RemoteAction, "_cleanup"
            ) as mock_cleanup:
                self.assertEqual(action.run(), 0)
                mock_call.assert_called_once()
                mock_cleanup.assert_not_called()

    def test_flag_forwarding_pass_through_remote(self) -> None:
        # RemoteAction construction no longer forwards --remote-* flags;
        # that responsibility has been moved to
        # remote_action.forward_remote_flags().
        command = [
            "cat",
            "--remote-flag=--exec_strategy=racing",
            "../src/cow/moo.txt",
        ]
        action = self._make_remote_action(command=command)
        self.assertEqual(action.local_only_command, command)
        self.assertEqual(action.local_only_flags, [])
        self.assertEqual(action.options, [])

    def test_local_only_flag_forwarding(self) -> None:
        local_file = Path("local_preamble.txt")
        command = [
            "cat",
            f"--local-only={local_file}",
            "main.txt",
        ]
        output_files = [Path("out/banner.txt")]
        action = self._make_remote_action(
            command=command, output_files=output_files
        )
        self.assertEqual(action.local_only_command, command)
        self.assertEqual(action.local_only_flags, [str(local_file)])
        self.assertIn(str(local_file), action.local_wrapper_text)
        self.assertEqual(action.options, [])
        rewrapper_prefix = list(action._generate_remote_command_prefix())
        # --local-only options are sifted into the --local_wrapper script,
        # which is generated and cleaned up.
        self.assertIn("--local_wrapper=./out/banner.local.sh", rewrapper_prefix)

    def test_relativize_local_deps(self) -> None:
        exec_root = Path("/exec/root")
        working_dir = exec_root / "work"
        action = self._make_remote_action(
            command=["cat"],
            exec_root=exec_root,
            working_dir=working_dir,
        )
        self.assertEqual(
            action._relativize_remote_or_local_deps(
                str(exec_root / "project" / "include" / "foo.h")
            ),
            "../project/include/foo.h",
        )
        self.assertEqual(
            action._relativize_remote_or_local_deps(
                str(working_dir / "gen" / "include" / "foo.h")
            ),
            "gen/include/foo.h",
        )

    def test_relativize_remote_deps(self) -> None:
        exec_root = Path("/exec/root")
        working_dir = exec_root / "work" / "out"
        action = self._make_remote_action(
            command=["cat"],
            exec_root=exec_root,
            working_dir=working_dir,
        )
        self.assertEqual(
            action._relativize_remote_or_local_deps(
                str(
                    remote_action._REMOTE_PROJECT_ROOT
                    / "project"
                    / "include"
                    / "foo.h"
                )
            ),
            "../../project/include/foo.h",
        )
        self.assertEqual(
            action._relativize_remote_or_local_deps(
                str(
                    remote_action._REMOTE_PROJECT_ROOT
                    / "work"
                    / "out"
                    / "jen"
                    / "project"
                    / "include"
                    / "foo.h"
                )
            ),
            "jen/project/include/foo.h",
        )

    def test_remote_fail_no_retry(self) -> None:
        command = ["echo", "hello"]
        action = self._make_remote_action(command=command)
        self.assertEqual(action.local_only_command, command)
        self.assertEqual(action.exec_root, self._PROJECT_ROOT)

        for exit_code in (1, 2):
            with mock.patch.object(
                remote_action.RemoteAction,
                "_run_maybe_remotely",
                return_value=cl_utils.SubprocessResult(exit_code),
            ) as mock_call:
                with mock.patch.object(
                    remote_action.RemoteAction, "_cleanup"
                ) as mock_cleanup:
                    self.assertEqual(action.run(), exit_code)

            mock_cleanup.assert_called_once()
            mock_call.assert_called_once()  # no retry

    def test_local_fail_no_retry(self) -> None:
        command = ["echo", "hello"]
        action = self._make_remote_action(
            command=command,
            disable=True,  # local-only
        )
        self.assertTrue(action.remote_disable)
        self.assertEqual(action.local_only_command, command)
        self.assertEqual(action.launch_command, command)  # no rewrapper
        self.assertEqual(action.exec_root, self._PROJECT_ROOT)

        exit_code = 4
        with mock.patch.object(
            remote_action.RemoteAction,
            "_run_maybe_remotely",
            return_value=cl_utils.SubprocessResult(exit_code),
        ) as mock_call:
            with mock.patch.object(
                remote_action.RemoteAction, "_cleanup"
            ) as mock_cleanup:
                self.assertEqual(action.run(), exit_code)

        mock_cleanup.assert_called_once()
        mock_call.assert_called_once()  # no retry

    def test_file_not_found_no_retry(self) -> None:
        command = ["echo", "hello"]
        action = self._make_remote_action(command=command)
        self.assertEqual(action.local_only_command, command)
        self.assertEqual(action.exec_root, self._PROJECT_ROOT)

        exit_code = 2
        with mock.patch.object(
            remote_action.RemoteAction,
            "_run_maybe_remotely",
            return_value=cl_utils.SubprocessResult(
                returncode=exit_code,
                stderr=["ERROR: file not found: /bin/smash", "going home now"],
            ),
        ) as mock_call:
            with mock.patch.object(
                remote_action.RemoteAction, "_cleanup"
            ) as mock_cleanup:
                self.assertEqual(action.run(), exit_code)

        mock_cleanup.assert_called_once()
        mock_call.assert_called_once()  # no retry

    def test_fail_to_dial_retry(self) -> None:
        command = ["echo", "hello"]
        action = self._make_remote_action(command=command)
        self.assertEqual(action.local_only_command, command)
        self.assertEqual(action.exec_root, self._PROJECT_ROOT)

        exit_code = 5
        with mock.patch.object(
            remote_action.RemoteAction,
            "_run_maybe_remotely",
            return_value=cl_utils.SubprocessResult(
                returncode=exit_code,
                stderr=[
                    "F0424 15:20:57.829003 1410923 main.go:112] Fail to dial unix:///b/s/w/ir/x/w/recipe_cleanup/rbedt_5k30r/reproxy.sock: context deadline exceeded",
                    "other uninteresting log message",
                ],
            ),
        ) as mock_call:
            with mock.patch.object(
                remote_action.RemoteAction, "_cleanup"
            ) as mock_cleanup:
                self.assertEqual(action.run(), exit_code)

        mock_cleanup.assert_called_once()
        mock_call.assert_called()
        self.assertEqual(len(mock_call.call_args_list), 2)

    def test_retry_once_successful(self) -> None:
        command = ["echo", "hello"]
        action = self._make_remote_action(command=command)
        self.assertEqual(action.local_only_command, command)
        self.assertEqual(action.exec_root, self._PROJECT_ROOT)

        for exit_code in remote_action._RETRIABLE_REWRAPPER_STATUSES:
            with mock.patch.object(
                remote_action.RemoteAction,
                "_run_maybe_remotely",
                side_effect=[
                    # If at first you don't succeed,
                    cl_utils.SubprocessResult(exit_code),
                    # try, try again (and succeed).
                    cl_utils.SubprocessResult(0),
                ],
            ) as mock_call:
                with mock.patch.object(
                    remote_action.RemoteAction, "_cleanup"
                ) as mock_cleanup:
                    self.assertEqual(action.run(), 0)

            mock_cleanup.assert_called_once()
            # expect called twice, second time is the retry
            self.assertEqual(len(mock_call.call_args_list), 2)

    def test_retry_once_fails_again(self) -> None:
        command = ["echo", "hello"]
        action = self._make_remote_action(command=command)
        self.assertEqual(action.local_only_command, command)
        self.assertEqual(action.exec_root, self._PROJECT_ROOT)

        for exit_code in remote_action._RETRIABLE_REWRAPPER_STATUSES:
            with mock.patch.object(
                remote_action.RemoteAction,
                "_run_maybe_remotely",
                side_effect=[
                    # If at first you don't succeed,
                    cl_utils.SubprocessResult(exit_code),
                    # try, try again (and fail again).
                    cl_utils.SubprocessResult(exit_code),
                ],
            ) as mock_call:
                with mock.patch.object(
                    remote_action.RemoteAction, "_cleanup"
                ) as mock_cleanup:
                    self.assertEqual(action.run(), exit_code)  # fail

            mock_cleanup.assert_called_once()
            # expect called twice, second time is the retry
            self.assertEqual(len(mock_call.call_args_list), 2)

    def _test_local_execution_strategy(
        self, exec_strategy: str, local_status: int
    ) -> None:
        remote_command = ["echo", "hello"]
        local_command = ["repeat-after-me", "hello"]
        action = self._make_remote_action(
            command=remote_command,
            local_only_command=local_command,
            exec_strategy=exec_strategy,
        )
        self.assertEqual(action.local_only_command, local_command)
        self.assertEqual(action.remote_only_command, remote_command)
        self.assertEqual(action.exec_root, self._PROJECT_ROOT)

        with mock.patch.object(
            remote_action.RemoteAction,
            "_run_maybe_remotely",
            return_value=cl_utils.SubprocessResult(2),
        ) as mock_remote:
            with mock.patch.object(
                remote_action.RemoteAction,
                "_run_locally",
                return_value=local_status,
            ) as mock_local:
                with mock.patch.object(
                    remote_action.RemoteAction, "_cleanup"
                ) as mock_cleanup:
                    with mock.patch.object(
                        remote_action.RemoteAction,
                        "downloader",
                        return_value=_FAKE_DOWNLOADER,
                    ) as mock_downloader:
                        self.assertEqual(
                            action.run(), local_status
                        )  # fallback success

        mock_remote.assert_called_with()
        mock_local.assert_called_with()
        mock_cleanup.assert_called_with()
        mock_downloader.assert_called_once_with()

    def test_strategy_local_fallback_different_command_succeeds(self) -> None:
        self._test_local_execution_strategy(
            exec_strategy="remote_local_fallback",
            local_status=0,
        )

    def test_strategy_local_fallback_different_command_fails(self) -> None:
        self._test_local_execution_strategy(
            exec_strategy="remote_local_fallback",
            local_status=1,
        )

    def test_strategy_local_only_different_command_succeeds(self) -> None:
        self._test_local_execution_strategy(
            exec_strategy="local",
            local_status=0,
        )

    def test_strategy_local_only_different_command_fails(self) -> None:
        self._test_local_execution_strategy(
            exec_strategy="local",
            local_status=3,
        )


def _fake_downloader() -> remotetool.RemoteTool:
    return remotetool.RemoteTool(
        reproxy_cfg={
            "service": "foo.buildservice:443",
            "instance": "my-project/remote/instances/default",
        }
    )


_FAKE_DOWNLOADER = _fake_downloader()


class DownloadStubsTests(unittest.TestCase):
    def test_create_stub_for_nonexistent_ignored(self) -> None:
        with tempfile.TemporaryDirectory() as td:
            tdp = Path(td)
            p = Path("crash_logs/optional-log.txt")
            (tdp / p.parent).mkdir(parents=True, exist_ok=True)
            rrpl = tdp / "action_log.rrpl"
            rrpl_contents = """
command: {
}
remote_metadata: {
  action_digest: "bef09123babc23/2037"
}
"""
            _write_file_contents(rrpl, rrpl_contents)
            build_id = "xyzzy"
            log_record = remote_action.ReproxyLogEntry.parse_action_log(rrpl)
            stub_infos = log_record.make_download_stubs(
                files=[p], dirs=[], build_id=build_id
            )
            # `p` was an optional output that was not created by the action.
            self.assertEqual(stub_infos, {})

    def test_create_file_stub_and_download(self) -> None:
        with tempfile.TemporaryDirectory() as td:
            tdp = Path(td)
            p = Path("dir/big-file.txt")
            (tdp / p.parent).mkdir(parents=True, exist_ok=True)
            digest = "abc123abc123/343"
            rrpl = tdp / "action_log.rrpl"
            rrpl_contents = f"""
command: {{
}}
remote_metadata: {{
  action_digest: "feedfacefeedface/1337"
  output_file_digests: {{
    key: "{p}"
    value: "{digest}"
  }}
}}
"""
            _write_file_contents(rrpl, rrpl_contents)
            build_id = "xyzzy"
            log_record = remote_action.ReproxyLogEntry.parse_action_log(rrpl)
            stub_infos = log_record.make_download_stubs(
                files=[p], dirs=[], build_id=build_id
            )

            self.assertEqual(len(stub_infos), 1)
            stub_infos[p].create(tdp)

            destination = tdp / p
            mode = destination.stat().st_mode
            self.assertTrue(remote_action.is_download_stub_file(destination))

            def fake_download_file(
                downloader_self: object, path: Path, digest: str, **kwargs: Any
            ) -> cl_utils.SubprocessResult:
                (tdp / path).write_text("hello\n")
                return cl_utils.SubprocessResult(0)

            with mock.patch.object(
                remotetool.RemoteTool, "download_blob", new=fake_download_file
            ) as mock_download:
                with mock.patch.object(Path, "rename") as mock_rename:
                    remote_action.download_from_stub_path(
                        destination,
                        downloader=_FAKE_DOWNLOADER,
                        working_dir_abs=tdp,
                    )

            mock_rename.assert_called_with(destination)
            self.assertEqual(destination.stat().st_mode, mode)

    def test_create_directory_stub_and_download(self) -> None:
        with tempfile.TemporaryDirectory() as td:
            tdp = Path(td)
            p = Path("bag/of/goodies")
            (tdp / p.parent).mkdir(parents=True, exist_ok=True)
            digest = "09ab9c86d8f001a/6540"
            rrpl = tdp / "action_log-2.rrpl"
            rrpl_contents = f"""
command: {{
}}
remote_metadata: {{
  action_digest: "cafef00dcafef00d/656"
  output_directory_digests: {{
    key: "{p}"
    value: "{digest}"
  }}
}}
"""
            _write_file_contents(rrpl, rrpl_contents)
            build_id = "yzzyx"
            log_record = remote_action.ReproxyLogEntry.parse_action_log(rrpl)
            stub_infos = log_record.make_download_stubs(
                files=[], dirs=[p], build_id=build_id
            )
            self.assertEqual(len(stub_infos), 1)
            stub_infos[p].create(tdp)

            destination = tdp / p
            self.assertTrue(remote_action.is_download_stub_file(destination))

            def fake_download_dir(
                downloader_self: object, path: Path, digest: str, **kwargs: Any
            ) -> cl_utils.SubprocessResult:
                (tdp / path).mkdir()
                (tdp / path / "readme.txt").write_text("hello\n")
                return cl_utils.SubprocessResult(0)

            with mock.patch.object(
                remotetool.RemoteTool, "download_dir", new=fake_download_dir
            ) as mock_download:
                with mock.patch.object(Path, "rename") as mock_rename:
                    remote_action.download_from_stub_path(
                        destination,
                        downloader=_FAKE_DOWNLOADER,
                        working_dir_abs=tdp,
                    )
            mock_rename.assert_called_with(destination)

    def test_read_fail(self) -> None:
        with tempfile.TemporaryDirectory() as td:
            stub_file = Path(td) / "testing.stub"
            _write_file_contents(stub_file, "#!/bin/sh\nnot a stub file\n")
            with self.assertRaises(remote_action.DownloadStubFormatError):
                remote_action.DownloadStubInfo.read_from_file(stub_file)

    def test_stub_write_read_match(self) -> None:
        stub = remote_action.DownloadStubInfo(
            path=Path("foo/bar.baz"),
            type="file",
            blob_digest="abc00101ef/240",
            action_digest="08871bc3d1/18",
            build_id="random-id888",
        )
        with tempfile.TemporaryDirectory() as td:
            stub_file = Path(td) / "identity.stub"
            stub._write(stub_file)
            new_stub = remote_action.DownloadStubInfo.read_from_file(stub_file)

        self.assertEqual(stub, new_stub)

    def test_create(self) -> None:
        path = Path("foo/goes/deeper/bar.baz")
        stub = remote_action.DownloadStubInfo(
            path=path,
            type="file",
            blob_digest="abc00101ef/240",
            action_digest="08871bc3d1/18",
            build_id="random-id888",
        )
        with tempfile.TemporaryDirectory() as td:
            full_path = td / path
            stub.create(working_dir_abs=Path(td))
            self.assertTrue(remote_action.is_download_stub_file(full_path))
            read_back = remote_action.DownloadStubInfo.read_from_file(full_path)
            self.assertEqual(read_back, stub)

    def test_download_to_alt_dest(self) -> None:
        blob_digest = "00111ddeee000aa/24"
        stub = remote_action.DownloadStubInfo(
            path=Path("foo/bar.baz"),
            type="file",
            blob_digest=blob_digest,
            action_digest="bce876da011112/14",
            build_id="random-id777",
        )
        working_dir = Path("/root/work")
        dest = Path("some/where/else.baz")
        download_status = 0
        with mock.patch.object(
            remotetool.RemoteTool,
            "download_blob",
            return_value=cl_utils.SubprocessResult(download_status),
        ) as mock_download:
            with mock.patch.object(Path, "rename") as mock_rename:
                with mock.patch.object(Path, "chmod") as mock_chmod:
                    with mock.patch.object(Path, "stat") as mock_stat:
                        with mock.patch.object(
                            remote_action,
                            "is_download_stub_file",
                            return_value=False,
                        ) as mock_is_stub:
                            status = stub.download(
                                downloader=_FAKE_DOWNLOADER,
                                working_dir_abs=working_dir,
                                dest=dest,
                            )
        self.assertEqual(status.returncode, download_status)
        mock_download.assert_called_with(
            path=remote_action.download_temp_location(working_dir / dest),
            digest=blob_digest,
            cwd=working_dir,
        )
        mock_stat.assert_called()
        mock_chmod.assert_called()
        mock_is_stub.assert_called_once()
        mock_rename.assert_called_with(working_dir / dest)

    def test_download_to_alt_dest_preserving_backup_stub(self) -> None:
        blob_digest = "00111ddeee000aa/24"
        stub = remote_action.DownloadStubInfo(
            path=Path("foo/bar.baz"),
            type="file",
            blob_digest=blob_digest,
            action_digest="bce876da011112/14",
            build_id="random-id777",
        )
        working_dir = Path("/root/work")
        dest = Path("some/where/else.baz")
        download_status = 0
        with mock.patch.object(
            remotetool.RemoteTool,
            "download_blob",
            return_value=cl_utils.SubprocessResult(download_status),
        ) as mock_download:
            with mock.patch.object(Path, "rename") as mock_rename:
                with mock.patch.object(Path, "chmod") as mock_chmod:
                    with mock.patch.object(Path, "stat") as mock_stat:
                        with mock.patch.object(
                            remote_action,
                            "is_download_stub_file",
                            return_value=True,
                        ) as mock_is_stub:
                            status = stub.download(
                                downloader=_FAKE_DOWNLOADER,
                                working_dir_abs=working_dir,
                                dest=dest,
                            )
        self.assertEqual(status.returncode, download_status)
        mock_download.assert_called_with(
            path=remote_action.download_temp_location(working_dir / dest),
            digest=blob_digest,
            cwd=working_dir,
        )
        mock_stat.assert_called()
        mock_chmod.assert_called()
        mock_is_stub.assert_called_once()
        mock_rename.assert_has_calls(
            [
                mock.call(
                    remote_action.download_stub_backup_location(
                        working_dir / dest
                    )
                ),
                mock.call(working_dir / dest),
            ],
            any_order=False,  # order matters
        )

    def test_download_fail(self) -> None:
        stub = remote_action.DownloadStubInfo(
            path=Path("foo/bar.baz"),
            type="file",
            blob_digest="abcef8712/24",
            action_digest="0923d1/21",
            build_id="random-id999",
        )
        download_status = 1
        with mock.patch.object(
            remotetool.RemoteTool,
            "download_blob",
            return_value=cl_utils.SubprocessResult(download_status),
        ) as mock_download:
            with mock.patch.object(Path, "rename") as mock_rename:
                status = stub.download(
                    downloader=_FAKE_DOWNLOADER,
                    working_dir_abs=Path("/root/work"),
                )
        self.assertEqual(status.returncode, download_status)
        mock_download.assert_called_once()
        mock_rename.assert_not_called()

    def test_made_download_stubs_for_remote_execution(self) -> None:
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        download_option = "--download_outputs=false"
        p = remote_action._MAIN_ARG_PARSER
        command = ["echo"]
        output = "out.out"
        main_args, other = p.parse_known_args([download_option, "--"] + command)
        action = remote_action.remote_action_from_args(
            main_args,
            remote_options=other,
            exec_root=exec_root,
            working_dir=working_dir,
            output_files=[Path(output)],
        )
        self.assertEqual(action.local_only_command, command)
        self.assertFalse(action.download_outputs)
        self.assertEqual(action.expected_downloads, [])
        options = action.options
        self.assertIn(download_option, options)
        logdir = "/fake/tmp/rpl/logz.932874"
        fake_log_record = FakeReproxyLogEntry(completion_status="SUCCESS")
        with mock.patch.object(
            remote_action, "_reproxy_log_dir", return_value=logdir
        ) as mock_log_dir:
            with mock.patch.object(
                remote_action.ReproxyLogEntry,
                "parse_action_log",
                return_value=fake_log_record,
            ) as mock_parse_log:
                with mock.patch.object(
                    remote_action.ReproxyLogEntry, "make_download_stubs"
                ) as mock_stub:
                    with mock.patch.object(
                        remote_action.RemoteAction,
                        "_run_maybe_remotely",
                        return_value=cl_utils.SubprocessResult(0),
                    ) as mock_run:
                        exit_code = action.run()
            self.assertEqual(exit_code, 0)
        mock_run.assert_called()
        mock_log_dir.assert_called_once()
        mock_parse_log.assert_called_with(Path(output + ".rrpl"))
        mock_stub.assert_called_with(
            files=[Path(output)],
            dirs=[],
            build_id=Path(logdir).name,
        )

    def test_made_download_stubs_for_racing_remote_win(self) -> None:
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        download_option = "--download_outputs=false"
        p = remote_action._MAIN_ARG_PARSER
        command = ["echo"]
        output = "out.out"
        main_args, other = p.parse_known_args(
            [download_option, "--exec_strategy=racing", "--"] + command
        )
        action = remote_action.remote_action_from_args(
            main_args,
            remote_options=other,
            exec_root=exec_root,
            working_dir=working_dir,
            output_files=[Path(output)],
        )
        self.assertEqual(action.local_only_command, command)
        self.assertFalse(action.download_outputs)
        self.assertEqual(action.expected_downloads, [])
        options = action.options
        self.assertIn(download_option, options)
        logdir = "/fake/tmp/rpl/logz.932875"
        fake_log_record = FakeReproxyLogEntry(
            completion_status="STATUS_CACHE_HIT"
        )
        with mock.patch.object(
            remote_action, "_reproxy_log_dir", return_value=logdir
        ) as mock_log_dir:
            with mock.patch.object(
                remote_action.RemoteAction, "download_inputs", return_value={}
            ) as mock_download_inputs:
                with mock.patch.object(
                    remote_action.ReproxyLogEntry,
                    "parse_action_log",
                    return_value=fake_log_record,
                ) as mock_parse_log:
                    with mock.patch.object(
                        remote_action.ReproxyLogEntry, "make_download_stubs"
                    ) as mock_stub:
                        with mock.patch.object(
                            remote_action.RemoteAction,
                            "_run_maybe_remotely",
                            return_value=cl_utils.SubprocessResult(0),
                        ) as mock_run:
                            exit_code = action.run()
                self.assertEqual(exit_code, 0)
        mock_run.assert_called()
        mock_download_inputs.assert_called_once()
        mock_log_dir.assert_called_once()
        mock_parse_log.assert_called_with(Path(output + ".rrpl"))
        mock_stub.assert_called_with(
            files=[Path(output)],
            dirs=[],
            build_id=Path(logdir).name,
        )

    def test_download_inputs_for_local_execution(self) -> None:
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        p = remote_action._MAIN_ARG_PARSER
        command = ["echo"]
        input_file = Path("in.in")  # pretend this is a download stub
        output = "out.out"
        main_args, other = p.parse_known_args(
            ["--exec_strategy=local", "--"] + command
        )
        action = remote_action.remote_action_from_args(
            main_args,
            remote_options=other,
            exec_root=exec_root,
            working_dir=working_dir,
            inputs=[Path(input_file)],
            output_files=[Path(output)],
        )
        self.assertEqual(action.local_only_command, command)
        options = action.options

        fake_stub_info = remote_action.DownloadStubInfo(
            path=input_file,
            type="file",
            blob_digest="8760ad0b/992",
            action_digest="12987e0d8a77/43",
            build_id="random-id12391",
        )
        with mock.patch.object(
            remote_action.RemoteAction,
            "downloader",
            return_value=_FAKE_DOWNLOADER,
        ) as mock_downloader:
            with mock.patch.object(
                remote_action,
                "download_input_stub_paths_batch",
                return_value={input_file: cl_utils.SubprocessResult(0)},
            ) as mock_download:
                download_statuses = action.download_inputs(lambda path: True)

        self.assertIn(input_file, download_statuses)
        self.assertEqual(download_statuses[input_file].returncode, 0)
        mock_downloader.assert_called_once_with()
        mock_download.assert_called_once()

    def test_no_download_stubs_for_local_execution(self) -> None:
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        download_option = "--download_outputs=false"
        p = remote_action._MAIN_ARG_PARSER
        command = ["echo"]
        output = "out.out"
        main_args, other = p.parse_known_args(
            [download_option, "--exec_strategy=local", "--"] + command
        )
        action = remote_action.remote_action_from_args(
            main_args,
            remote_options=other,
            exec_root=exec_root,
            working_dir=working_dir,
            output_files=[Path(output)],
        )
        self.assertEqual(action.local_only_command, command)
        self.assertFalse(action.download_outputs)
        self.assertEqual(action.expected_downloads, [])
        options = action.options
        self.assertIn(download_option, options)
        logdir = "/fake/tmp/rpl/logz.888222"
        fake_log_record = FakeReproxyLogEntry(
            completion_status="STATUS_LOCAL_EXECUTION"
        )
        with mock.patch.object(
            remote_action.ReproxyLogEntry,
            "parse_action_log",
            return_value=fake_log_record,
        ) as mock_parse_log:
            with mock.patch.object(
                remote_action.ReproxyLogEntry, "make_download_stubs"
            ) as mock_stub:
                with mock.patch.object(
                    remote_action.RemoteAction,
                    "download_inputs",
                    return_value={},
                ) as mock_download_inputs:
                    with mock.patch.object(
                        remote_action.RemoteAction,
                        "_run_maybe_remotely",
                        return_value=cl_utils.SubprocessResult(0),
                    ) as mock_run:
                        exit_code = action.run()
        self.assertEqual(exit_code, 0)
        mock_run.assert_called()
        mock_download_inputs.assert_called_once()
        mock_parse_log.assert_called_with(Path(output + ".rrpl"))
        mock_stub.assert_not_called()

    def test_no_download_stubs_for_racing_local_win(self) -> None:
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        download_option = "--download_outputs=false"
        p = remote_action._MAIN_ARG_PARSER
        command = ["echo"]
        output = "out.out"
        main_args, other = p.parse_known_args(
            [download_option, "--exec_strategy=racing", "--"] + command
        )
        action = remote_action.remote_action_from_args(
            main_args,
            remote_options=other,
            exec_root=exec_root,
            working_dir=working_dir,
            output_files=[Path(output)],
        )
        self.assertEqual(action.local_only_command, command)
        self.assertFalse(action.download_outputs)
        self.assertEqual(action.expected_downloads, [])
        options = action.options
        self.assertIn(download_option, options)
        logdir = "/fake/tmp/rpl/logz.213123"
        fake_log_record = FakeReproxyLogEntry(
            completion_status="STATUS_RACING_LOCAL"
        )
        with mock.patch.object(
            remote_action.ReproxyLogEntry,
            "parse_action_log",
            return_value=fake_log_record,
        ) as mock_parse_log:
            with mock.patch.object(
                remote_action.RemoteAction, "download_inputs", return_value={}
            ) as mock_download_inputs:
                with mock.patch.object(
                    remote_action.ReproxyLogEntry, "make_download_stubs"
                ) as mock_stub:
                    with mock.patch.object(
                        remote_action.RemoteAction,
                        "_run_maybe_remotely",
                        return_value=cl_utils.SubprocessResult(0),
                    ) as mock_run:
                        exit_code = action.run()
        self.assertEqual(exit_code, 0)
        mock_run.assert_called()
        mock_download_inputs.assert_called_once()
        mock_parse_log.assert_called_with(Path(output + ".rrpl"))
        mock_stub.assert_not_called()

    def test_no_download_stubs_for_local_fallback(self) -> None:
        exec_root = Path("/home/project")
        build_dir = Path("build-out")
        working_dir = exec_root / build_dir
        download_option = "--download_outputs=false"
        p = remote_action._MAIN_ARG_PARSER
        command = ["echo"]
        output = "out.out"
        main_args, other = p.parse_known_args(
            [download_option, "--exec_strategy=remote_local_fallback", "--"]
            + command
        )
        action = remote_action.remote_action_from_args(
            main_args,
            remote_options=other,
            exec_root=exec_root,
            working_dir=working_dir,
            output_files=[Path(output)],
        )
        self.assertEqual(action.local_only_command, command)
        self.assertFalse(action.download_outputs)
        self.assertEqual(action.expected_downloads, [])
        options = action.options
        self.assertIn(download_option, options)
        logdir = "/fake/tmp/rpl/logz.81891"
        fake_log_record = FakeReproxyLogEntry(
            completion_status="STATUS_LOCAL_FALLBACK"
        )
        with mock.patch.object(
            remote_action.ReproxyLogEntry,
            "parse_action_log",
            return_value=fake_log_record,
        ) as mock_parse_log:
            with mock.patch.object(
                remote_action.RemoteAction, "download_inputs", return_value={}
            ) as mock_download_inputs:
                with mock.patch.object(
                    remote_action.ReproxyLogEntry, "make_download_stubs"
                ) as mock_stub:
                    with mock.patch.object(
                        remote_action.RemoteAction,
                        "_run_maybe_remotely",
                        return_value=cl_utils.SubprocessResult(0),
                    ) as mock_run:
                        exit_code = action.run()
        self.assertEqual(exit_code, 0)
        mock_run.assert_called()
        mock_download_inputs.assert_called_once()
        mock_parse_log.assert_called_with(Path(output + ".rrpl"))
        mock_stub.assert_not_called()

    def _setup_update_stub_test(
        self, tdp: Path, output_contents: str | None = None
    ) -> Tuple[remote_action.RemoteAction, FakeReproxyLogEntry]:
        exec_root = tdp
        build_dir = Path("build-out")
        self.working_dir = exec_root / build_dir
        download_option = "--download_outputs=false"
        p = remote_action._MAIN_ARG_PARSER
        command = ["echo"]
        self.output = Path("out.out")
        main_args, other = p.parse_known_args(
            [download_option, "--preserve_unchanged_output_mtime", "--"]
            + command
        )
        action = remote_action.remote_action_from_args(
            main_args,
            remote_options=other,
            exec_root=exec_root,
            working_dir=self.working_dir,
            output_files=[self.output],
        )
        self.assertEqual(action.local_only_command, command)
        self.assertFalse(action.download_outputs)
        self.assertEqual(action.expected_downloads, [])
        self.assertTrue(action.preserve_unchanged_output_mtime)
        options = action.options
        self.assertIn(download_option, options)
        logdir = "/fake/tmp/rpl/logz.532874"

        if output_contents is not None:
            self.working_dir.mkdir(parents=True, exist_ok=True)
            (self.working_dir / self.output).write_text(output_contents)
            output_digest = remote_action.get_blob_digest(
                self.working_dir / self.output
            )
        else:
            output_digest = "aa55aa55/33"  # fake

        fake_log_record = FakeReproxyLogEntry(
            completion_status="SUCCESS",
            output_file_digests={self.output: output_digest},
            output_directory_digests={},
            action_digest="765321/44",
        )
        return action, fake_log_record

    def test_update_stub_preserve_unchanged_output_mtime_existing_stub_matches_digest(
        self,
    ) -> None:
        with tempfile.TemporaryDirectory() as td:
            action, fake_log_record = self._setup_update_stub_test(Path(td))

            # create a pre-existing stub-file with the same digest as the new output
            assert fake_log_record is not None
            old_stub_info = fake_log_record.make_download_stub_info(
                self.output, build_id="new-build-id"
            )
            assert old_stub_info is not None
            old_stub_info.create(self.working_dir)
            self.assertTrue(
                remote_action.is_download_stub_file(
                    self.working_dir / old_stub_info.path
                )
            )

            # bypass the remote action running
            with mock.patch.object(
                remote_action.DownloadStubInfo, "create"
            ) as mock_create_stub:
                action._update_stub(old_stub_info)

            mock_create_stub.assert_not_called()

    def test_update_stub_preserve_unchanged_output_mtime_existing_stub_mismatches_digest(
        self,
    ) -> None:
        with tempfile.TemporaryDirectory() as td:
            action, fake_log_record = self._setup_update_stub_test(Path(td))
            # create a pre-existing stub-file with a different digest as the new output
            old_stub_info = fake_log_record.make_download_stub_info(
                self.output, build_id="new-build-id"
            )
            assert old_stub_info is not None
            new_stub_info = copy.deepcopy(old_stub_info)
            old_stub_info._blob_digest = "66776677/33"  # mismatched digest
            old_stub_info.create(self.working_dir)
            self.assertTrue(
                remote_action.is_download_stub_file(
                    self.working_dir / old_stub_info.path
                )
            )

            # bypass the remote action running
            with mock.patch.object(
                remote_action.DownloadStubInfo, "create"
            ) as mock_create_stub:
                action._update_stub(new_stub_info)

            mock_create_stub.assert_called_with(self.working_dir)

    def test_update_stub_preserve_unchanged_output_mtime_existing_file_matches_digest_with_backup_stub(
        self,
    ) -> None:
        with tempfile.TemporaryDirectory() as td:
            action, fake_log_record = self._setup_update_stub_test(
                Path(td), output_contents="h3llo"
            )

            # pre-existing output file's digest matches that from the remote
            # action, along with its backup download stub.
            stub_location = remote_action.download_stub_backup_location(
                self.output
            )
            old_stub_info = fake_log_record.make_download_stub_info(
                self.output, build_id="new-build-id"
            )
            assert old_stub_info is not None
            old_stub_info.create(self.working_dir, dest=stub_location)
            self.assertTrue(
                remote_action.is_download_stub_file(
                    self.working_dir / stub_location
                )
            )

            # bypass the remote action running
            with mock.patch.object(
                remote_action.DownloadStubInfo, "create"
            ) as mock_create_stub:
                with mock.patch.object(Path, "unlink") as mock_remove:
                    action._update_stub(old_stub_info)

            # old file (and its stub) are left untouched
            mock_remove.assert_not_called()
            mock_create_stub.assert_not_called()

    def test_update_stub_preserve_unchanged_output_mtime_existing_file_matches_digest_without_backup_stub(
        self,
    ) -> None:
        with tempfile.TemporaryDirectory() as td:
            action, fake_log_record = self._setup_update_stub_test(
                Path(td), output_contents="h3llo"
            )

            # pre-existing output file's digest matches that from the remote
            # action, without backup download stub.
            old_stub_info = fake_log_record.make_download_stub_info(
                self.output, build_id="new-build-id"
            )
            assert old_stub_info is not None

            # bypass the remote action running
            with mock.patch.object(
                remote_action.DownloadStubInfo, "create"
            ) as mock_create_stub:
                with mock.patch.object(Path, "unlink") as mock_remove:
                    action._update_stub(old_stub_info)

            # old file is left untouched
            mock_remove.assert_not_called()
            mock_create_stub.assert_not_called()

    def test_make_download_stub_info_not_found(self) -> None:
        with tempfile.TemporaryDirectory() as td:
            action, fake_log_record = self._setup_update_stub_test(
                Path(td), output_contents="h3llo"
            )
            # Reference some path that is not among the recorded
            # output file/directory digests.
            stub_info = fake_log_record.make_download_stub_info(
                Path("some/optional/output"), build_id="new-build-id"
            )
            self.assertIsNone(stub_info)

    def test_update_stub_preserve_unchanged_output_mtime_existing_file_mismatches_digest_with_backup_stub(
        self,
    ) -> None:
        with tempfile.TemporaryDirectory() as td:
            action, fake_log_record = self._setup_update_stub_test(
                Path(td), output_contents="h3llo"
            )

            # pre-existing output file's digest does not match that from the
            # remote action.
            stub_location = remote_action.download_stub_backup_location(
                self.output
            )
            old_stub_info = fake_log_record.make_download_stub_info(
                self.output, build_id="new-build-id"
            )
            assert old_stub_info is not None
            new_stub_info = copy.deepcopy(old_stub_info)
            old_stub_info.create(self.working_dir, dest=stub_location)
            new_stub_info._blob_digest = "43218765/11"  # mismatched digest
            self.assertTrue(
                remote_action.is_download_stub_file(
                    self.working_dir / stub_location
                )
            )

            # bypass the remote action running
            with mock.patch.object(
                remote_action.DownloadStubInfo, "create"
            ) as mock_create_stub:
                with mock.patch.object(Path, "unlink") as mock_remove:
                    action._update_stub(new_stub_info)

            # old file is replaced with new stub, old stub is removed
            mock_remove.assert_called_with()
            mock_create_stub.assert_called_with(self.working_dir)

    def test_update_stub_preserve_unchanged_output_mtime_existing_file_mismatches_digest_without_backup_stub(
        self,
    ) -> None:
        with tempfile.TemporaryDirectory() as td:
            action, fake_log_record = self._setup_update_stub_test(
                Path(td), output_contents="h3llo"
            )
            # pre-existing output file's digest does not match that from the
            # remote action.
            new_stub_info = fake_log_record.make_download_stub_info(
                self.output, build_id="new-build-id"
            )
            assert new_stub_info is not None
            new_stub_info._blob_digest = "43218765/11"  # mismatched digest

            # bypass the remote action running
            with mock.patch.object(
                remote_action.DownloadStubInfo, "create"
            ) as mock_create_stub:
                with mock.patch.object(Path, "unlink") as mock_remove:
                    action._update_stub(new_stub_info)

            # old file is replaced with new stub
            mock_remove.assert_called_with()
            mock_create_stub.assert_called_with(self.working_dir)


class RbeDiagnosticsTests(unittest.TestCase):
    def _make_remote_action(self, **kwargs: Any) -> remote_action.RemoteAction:
        command = ["echo", "hello"]
        exec_root = Path("/path/to/project/root")
        working_dir = exec_root / "build/stuff/here"
        return remote_action.RemoteAction(
            rewrapper=Path("/path/to/rewrapper"),
            command=command,
            exec_root=exec_root,
            working_dir=working_dir,
            **kwargs,
        )

    def test_analyze_conditions_positive(self) -> None:
        action = self._make_remote_action(diagnose_nonzero=True)

        with mock.patch.object(
            remote_action.RemoteAction,
            "_run_maybe_remotely",
            return_value=cl_utils.SubprocessResult(1),
        ) as mock_run:
            with mock.patch.object(
                remote_action.RemoteAction, "_cleanup"
            ) as mock_cleanup:
                with mock.patch.object(
                    remote_action, "analyze_rbe_logs"
                ) as mock_analyze:
                    self.assertEqual(action.run(), 1)

        mock_cleanup.assert_called_once()
        mock_run.assert_called_once()
        mock_analyze.assert_called_once()
        args, kwargs = mock_analyze.call_args_list[0]
        self.assertEqual(kwargs["action_log"], action._action_log)

    def test_analyzing_not_requested(self) -> None:
        action = self._make_remote_action(diagnose_nonzero=False)

        with mock.patch.object(
            remote_action.RemoteAction,
            "_run_maybe_remotely",
            return_value=cl_utils.SubprocessResult(1),
        ) as mock_run:
            with mock.patch.object(
                remote_action.RemoteAction, "_cleanup"
            ) as mock_cleanup:
                with mock.patch.object(
                    remote_action, "analyze_rbe_logs"
                ) as mock_analyze:
                    self.assertEqual(action.run(), 1)

        mock_cleanup.assert_called_once()
        mock_run.assert_called_once()
        mock_analyze.assert_not_called()

    def test_not_analyzing_on_success(self) -> None:
        action = self._make_remote_action(diagnose_nonzero=True)

        with mock.patch.object(
            remote_action.RemoteAction,
            "_run_maybe_remotely",
            return_value=cl_utils.SubprocessResult(0),
        ) as mock_run:
            with mock.patch.object(
                remote_action.RemoteAction, "_cleanup"
            ) as mock_cleanup:
                with mock.patch.object(
                    remote_action, "analyze_rbe_logs"
                ) as mock_analyze:
                    self.assertEqual(action.run(), 0)

        mock_cleanup.assert_called_once()
        mock_run.assert_called_once()
        mock_analyze.assert_not_called()

    def test_not_analyzing_local_execution(self) -> None:
        action = self._make_remote_action(
            diagnose_nonzero=True,
            exec_strategy="local",
        )

        with mock.patch.object(
            remote_action.RemoteAction,
            "_run_maybe_remotely",
            return_value=cl_utils.SubprocessResult(1),
        ) as mock_run:
            with mock.patch.object(
                remote_action.RemoteAction, "download_inputs", return_value={}
            ) as mock_download_inputs:
                with mock.patch.object(
                    remote_action.RemoteAction, "_cleanup"
                ) as mock_cleanup:
                    with mock.patch.object(
                        remote_action, "analyze_rbe_logs"
                    ) as mock_analyze:
                        self.assertEqual(action.run(), 1)

        mock_download_inputs.assert_called_once()
        mock_cleanup.assert_called_once()
        mock_run.assert_called_once()
        mock_analyze.assert_not_called()

    def test_analyze_flow(self) -> None:
        pid = 6789
        action_log = Path("obj/my_action.rrpl")
        fake_rewrapper_logs = [
            f"/noisy/log/rewrapper.where.who.log.INFO.when.{pid}",
            f"/noisy/log/rewrapper.where.who.log.ERROR.when.{pid}",
        ]
        unnamed_mocks = [
            mock.patch.object(
                remote_action,
                "_reproxy_log_dir",
                return_value="/path/to/tmp/reproxy.999999",
            ),
            mock.patch.object(
                remote_action,
                "_rewrapper_log_dir",
                return_value="/path/to/tmp/reproxy.999999/wrapper/logz",
            ),
            mock.patch.object(Path, "is_file", return_value=True),
        ]
        with contextlib.ExitStack() as stack:
            for m in unnamed_mocks:
                stack.enter_context(m)

            with mock.patch.object(
                Path, "glob", return_value=fake_rewrapper_logs
            ) as mock_glob:
                with mock.patch.object(
                    remote_action.ReproxyLogEntry, "parse_action_log"
                ) as mock_parse_action_log:
                    with mock.patch.object(
                        remote_action,
                        "_file_lines_matching",
                        return_value=["this is interesting"],
                    ) as mock_read_log:
                        with mock.patch.object(
                            remote_action, "_diagnose_reproxy_error_line"
                        ) as mock_diagnose_line:
                            remote_action.analyze_rbe_logs(
                                rewrapper_pid=pid,
                                action_log=action_log,
                            )
        mock_glob.assert_called_once()
        mock_read_log.assert_called_once()
        mock_parse_action_log.assert_called_with(action_log)
        mock_diagnose_line.assert_called()

    def test_parse_reproxy_log_record_lines(self) -> None:
        exec_id = "xx-yy-zzzz"
        action_digest = "2afd98ae7274456b2bfc208e10f4cbe75fca88c2c41e352e57cb6b9ad840bf64/144"
        output_path = Path("obj/sub/lib/foo.o")
        output_digest = "345324aefg983bc0/531"
        log_lines = f"""
command:  {{
        identifiers:  {{
                command_id:  "8ea55c85-0ae36078"
                invocation_id:  "979eedda-4643-45da-af15-0d2f8531ba98"
                tool_name:  "re-client"
                execution_id:  "{exec_id}"
        }}
}}
remote_metadata:  {{
        command_digest:  "e9d024e5dc99438b08f4592a09379e65146149821480e2057c7afc285d30f090/181"
        action_digest:  "{action_digest}"
        output_file_digests: {{
                key: "{output_path}"
                value: "{output_digest}"
        }}
}}
        """.splitlines()
        log_entry = remote_action.ReproxyLogEntry._parse_lines(log_lines)
        self.assertEqual(log_entry.execution_id, exec_id)
        self.assertEqual(log_entry.action_digest, action_digest)
        self.assertEqual(
            log_entry.output_file_digests[output_path], output_digest
        )

    def test_diagnose_uninteresting_log_line(self) -> None:
        line = "This diagnostic does not appear interesting."
        f = io.StringIO()
        with contextlib.redirect_stdout(f):
            remote_action._diagnose_reproxy_error_line(line)
        self.assertEqual(f.getvalue(), "")

    def test_diagnose_fail_to_dial(self) -> None:
        line = "Fail to dial something something unix:///path/to/reproxy.socket"
        f = io.StringIO()
        with contextlib.redirect_stdout(f):
            remote_action._diagnose_reproxy_error_line(line)
        self.assertIn("reproxy is not running", f.getvalue())

    def test_diagnose_rbe_permissions(self) -> None:
        line = "Error connecting to remote execution client: rpc error: code = PermissionDenied.  You have no power here!"
        f = io.StringIO()
        with contextlib.redirect_stdout(f):
            remote_action._diagnose_reproxy_error_line(line)
        self.assertIn(
            "You might not have permssion to access the RBE instance",
            f.getvalue(),
        )

    def test_diagnose_missing_input_file(self) -> None:
        path = "../oops/did/I/forget/this.file"
        line = f"Status:LocalErrorResultStatus ... Err:stat {path}: no such file or directory"
        f = io.StringIO()
        with contextlib.redirect_stdout(f):
            remote_action._diagnose_reproxy_error_line(line)
        self.assertIn(
            f"missing a local input file for uploading: {path} (source)",
            f.getvalue(),
        )


class MainTests(unittest.TestCase):
    def test_help_flag(self) -> None:
        stdout = io.StringIO()
        # Just make sure help exits successfully, without any exceptions
        # due to argument parsing.
        with contextlib.redirect_stdout(stdout):
            with mock.patch.object(
                sys, "exit", side_effect=ImmediateExit
            ) as mock_exit:
                with self.assertRaises(ImmediateExit):
                    remote_action.main(["--help"])
        mock_exit.assert_called_with(0)

    def test_auto_relaunch_with_reproxy_not_needed_for_local(self) -> None:
        command = ["--local", "--", "echo", "hello"]
        exit_code = 7
        with mock.patch.object(
            remote_action.RemoteAction,
            "run_with_main_args",
            return_value=exit_code,
        ):
            self.assertEqual(remote_action.main(command), exit_code)

    def test_auto_relaunch_with_reproxy_not_needed_for_dry_run(self) -> None:
        command = ["--dry-run", "--", "echo", "hello"]
        self.assertEqual(remote_action.main(command), 0)

    def test_auto_relaunch_with_reproxy_not_needed_with_env(self) -> None:
        command = ["--", "echo", "hello"]
        exit_code = 9
        with mock.patch.object(
            os.environ, "get", return_value="/any/value/will/do"
        ) as mock_env:
            with mock.patch.object(
                remote_action.RemoteAction,
                "run_with_main_args",
                return_value=exit_code,
            ) as mock_run:
                self.assertEqual(remote_action.main(command), exit_code)
        mock_env.assert_called()
        mock_run.assert_called_once()

    def test_auto_relaunch_with_reproxy_needed(self) -> None:
        command = ["--", "echo", "hello"]
        # Expect to relaunch because the necessary env variables
        # are absent.
        with mock.patch.object(
            os.environ, "get", return_value=None
        ) as mock_env:
            with mock.patch.object(
                cl_utils, "exec_relaunch", side_effect=ImmediateExit
            ) as mock_relaunch:
                with self.assertRaises(ImmediateExit):
                    remote_action.main(command)
        mock_relaunch.assert_called_once()
        args, kwargs = mock_relaunch.call_args_list[0]
        relaunch_cmd = args[0]
        self.assertEqual(relaunch_cmd[0], str(fuchsia.REPROXY_WRAP))
        cmd_slices = cl_utils.split_into_subsequences(relaunch_cmd[1:], "--")
        reproxy_args, self_script, wrapped_command = cmd_slices
        self.assertEqual(reproxy_args, ["-v"])
        self.assertIn("python", self_script[0])
        self.assertTrue(self_script[-1].endswith("remote_action.py"))
        self.assertEqual(wrapped_command, command[1:])

    def test_main_args_remote_inputs(self) -> None:
        command = ["--inputs", "src/in.txt", "--", "echo", "hello"]
        with mock.patch.object(
            remote_action, "auto_relaunch_with_reproxy"
        ) as mock_relaunch:
            with mock.patch.object(
                remote_action.RemoteAction, "run_with_main_args", return_value=0
            ) as mock_run:
                self.assertEqual(remote_action.main(command), 0)
        mock_relaunch.assert_called_once()
        mock_run.assert_called_once()
        args, kwargs = mock_run.call_args_list[0]
        main_args = args[0]
        self.assertEqual(main_args.inputs, ["src/in.txt"])

    def test_main_args_remote_inputs_repeated(self) -> None:
        command = [
            "--inputs",
            "src/in.txt",
            "--inputs=another.s",
            "--",
            "echo",
            "hello",
        ]
        with mock.patch.object(
            remote_action, "auto_relaunch_with_reproxy"
        ) as mock_relaunch:
            with mock.patch.object(
                remote_action.RemoteAction, "run_with_main_args", return_value=0
            ) as mock_run:
                self.assertEqual(remote_action.main(command), 0)
        mock_relaunch.assert_called_once()
        mock_run.assert_called_once()
        args, kwargs = mock_run.call_args_list[0]
        main_args = args[0]
        self.assertEqual(main_args.inputs, ["src/in.txt", "another.s"])

    def test_main_args_local(self) -> None:
        command = ["--local", "--", "echo", "hello"]
        with mock.patch.object(
            remote_action, "auto_relaunch_with_reproxy"
        ) as mock_relaunch:
            with mock.patch.object(
                remote_action.RemoteAction, "run_with_main_args", return_value=0
            ) as mock_run:
                self.assertEqual(remote_action.main(command), 0)
        mock_relaunch.assert_called_once()
        mock_run.assert_called_once()
        args, kwargs = mock_run.call_args_list[0]
        main_args = args[0]
        self.assertTrue(main_args.local)

    def test_flag_forwarding_remote_disable(self) -> None:
        command = ["--", "echo", "--remote-disable", "hello"]
        with mock.patch.object(
            remote_action, "auto_relaunch_with_reproxy"
        ) as mock_relaunch:
            with mock.patch.object(
                remote_action.RemoteAction, "run_with_main_args", return_value=0
            ) as mock_run:
                self.assertEqual(remote_action.main(command), 0)
        mock_relaunch.assert_called_once()
        mock_run.assert_called_once()
        args, kwargs = mock_run.call_args_list[0]
        main_args = args[0]
        self.assertTrue(main_args.local)

    def test_main_args_local_check_determinism(self) -> None:
        command = ["--local", "--check-determinism", "--", "echo", "hello"]
        with mock.patch.object(
            remote_action, "auto_relaunch_with_reproxy"
        ) as mock_relaunch:
            with mock.patch.object(
                remote_action.RemoteAction, "run_with_main_args", return_value=0
            ) as mock_run:
                self.assertEqual(remote_action.main(command), 0)
        mock_relaunch.assert_called_once()
        mock_run.assert_called_once()
        args, kwargs = mock_run.call_args_list[0]
        main_args = args[0]
        self.assertTrue(main_args.local)
        self.assertTrue(main_args.check_determinism)


if __name__ == "__main__":
    remote_action.init_from_main_once()
    unittest.main()
