#!/usr/bin/env fuchsia-vendored-python
# Copyright 2020 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 contextlib
import filecmp
import os
import shutil
import tempfile
import time
import unittest
from pathlib import Path
from unittest import mock

import output_cacher


class TempFileTransformTests(unittest.TestCase):
    def test_invalid(self):
        self.assertFalse(output_cacher.TempFileTransform().valid)

    def test_temp_dir_only(self):
        self.assertTrue(
            output_cacher.TempFileTransform(temp_dir="my_tmp").valid
        )
        self.assertTrue(
            output_cacher.TempFileTransform(temp_dir="/my_tmp").valid
        )

    def test_basename_prefix_only(self):
        self.assertTrue(
            output_cacher.TempFileTransform(basename_prefix="temp-").valid
        )

    def test_suffix_only(self):
        self.assertTrue(output_cacher.TempFileTransform(suffix=".tmp").valid)

    def test_temp_dir_and_suffix(self):
        self.assertTrue(
            output_cacher.TempFileTransform(
                temp_dir="throw/away", suffix=".tmp"
            ).valid
        )

    def test_transform_suffix_only(self):
        self.assertEqual(
            output_cacher.TempFileTransform(suffix=".tmp").transform(
                Path("foo/bar.o")
            ),
            Path("foo/bar.o.tmp"),
        )

    def test_transform_temp_dir_only(self):
        self.assertEqual(
            output_cacher.TempFileTransform(temp_dir=Path("t/m/p")).transform(
                Path("foo/bar.o")
            ),
            Path("t/m/p/foo/bar.o"),
        )

    def test_transform_suffix_and_temp_dir(self):
        self.assertEqual(
            output_cacher.TempFileTransform(
                temp_dir=Path("/t/m/p"), suffix=".foo"
            ).transform(Path("foo/bar.o")),
            Path("/t/m/p/foo/bar.o.foo"),
        )

    def test_transform_basename_prefix_only(self):
        self.assertEqual(
            output_cacher.TempFileTransform(basename_prefix="fake.").transform(
                Path("bar.o")
            ),
            Path("fake.bar.o"),
        )
        self.assertEqual(
            output_cacher.TempFileTransform(basename_prefix="fake.").transform(
                Path("foo/bar.o")
            ),
            Path("foo/fake.bar.o"),
        )

    def test_transform_basename_prefix_and_temp_dir(self):
        self.assertEqual(
            output_cacher.TempFileTransform(
                temp_dir="/t/m/p", basename_prefix="xyz-"
            ).transform(Path("foo/bar.o")),
            Path("/t/m/p/foo/xyz-bar.o"),
        )


class SplitTransformJoinTest(unittest.TestCase):
    def test_no_change(self):
        self.assertEqual(
            output_cacher.split_transform_join("text", "=", lambda x: x), "text"
        )

    def test_repeat(self):
        self.assertEqual(
            output_cacher.split_transform_join("text", "=", lambda x: x + x),
            "texttext",
        )

    def test_with_split(self):
        self.assertEqual(
            output_cacher.split_transform_join("a=b", "=", lambda x: x + x),
            "aa=bb",
        )

    def test_with_split_recorded(self):
        renamed_tokens = {}

        def recorded_transform(x):
            new_text = x + x
            renamed_tokens[x] = new_text
            return new_text

        self.assertEqual(
            output_cacher.split_transform_join("a=b", "=", recorded_transform),
            "aa=bb",
        )
        self.assertEqual(renamed_tokens, {"a": "aa", "b": "bb"})


class OutputSubstitutionTest(unittest.TestCase):
    def test_no_prev_opt(self):
        subst = output_cacher.OutputSubstitution("foo")
        self.assertEqual(subst.output_name, "foo")
        self.assertEqual(subst.match_previous_option, "")

    def test_with_prev_opt(self):
        subst = output_cacher.OutputSubstitution("substitute_after:--out:foo")
        self.assertEqual(subst.output_name, "foo")
        self.assertEqual(subst.match_previous_option, "--out")

    def test_malformed_prev_opt(self):
        with self.assertRaises(ValueError):
            output_cacher.OutputSubstitution("substitute_after:--outfoo")


class LexicallyRewriteTokenTest(unittest.TestCase):
    def test_repeat_text(self):
        self.assertEqual(
            output_cacher.lexically_rewrite_token("foo", lambda x: x + x),
            "foofoo",
        )

    def test_delimters_only(self):
        self.assertEqual(
            output_cacher.lexically_rewrite_token(",,==,=,=,", lambda x: x + x),
            ",,==,=,=,",
        )

    def test_flag_with_value(self):
        def transform(x):
            if x.startswith("file"):
                return "tmp-" + x
            else:
                return x

        self.assertEqual(
            output_cacher.lexically_rewrite_token("--foo=file1", transform),
            "--foo=tmp-file1",
        )
        self.assertEqual(
            output_cacher.lexically_rewrite_token(
                "notfile,file1,file2,notfile", transform
            ),
            "notfile,tmp-file1,tmp-file2,notfile",
        )
        self.assertEqual(
            output_cacher.lexically_rewrite_token(
                "--foo=file1,file2", transform
            ),
            "--foo=tmp-file1,tmp-file2",
        )


class EnsureFileExists(unittest.TestCase):
    def test_file_exists(self):
        with mock.patch.object(
            Path, "exists", return_value=True
        ) as mock_exists:
            output_cacher.ensure_file_exists(Path("some/file.txt"))
        mock_exists.assert_called()
        # just make sure no exception raised

    def test_file_not_exists(self):
        with mock.patch.object(
            Path, "exists", return_value=False
        ) as mock_exists:
            with mock.patch.object(time, "sleep") as mock_sleep:
                with self.assertRaises(FileNotFoundError):
                    output_cacher.ensure_file_exists(Path("not/a/file.txt"))
        mock_exists.assert_called()

    def test_file_exists_later(self):
        with mock.patch.object(
            Path, "exists", side_effect=[False, True]
        ) as mock_exists:
            with mock.patch.object(time, "sleep") as mock_sleep:
                output_cacher.ensure_file_exists(Path("late/file.txt"))
        mock_exists.assert_called()
        mock_sleep.assert_called()
        # just make sure no exception raised


@contextlib.contextmanager
def chdir_cm(d: Path):
    """FIXME: replace with contextlib.chdir(), once Python 3.11 is default."""
    save_dir = os.getcwd()
    os.chdir(d)  # could raise OSError
    try:
        yield
    finally:
        os.chdir(save_dir)


class CopyPreserveSubpathTests(unittest.TestCase):
    def test_subpath(self):
        with tempfile.TemporaryDirectory() as td1:
            tdp1 = Path(td1)
            dest_dir = tdp1 / "backups"
            with chdir_cm(tdp1):  # working directory
                srcdir = Path("aa/bb")
                srcdir.mkdir(parents=True, exist_ok=True)
                src_file = srcdir / "c.txt"
                src_file.write_text("hello\n")
                output_cacher.copy_preserve_subpath(src_file, dest_dir)
                dest_file = dest_dir / src_file
                self.assertTrue(filecmp.cmp(src_file, dest_file, shallow=False))


class DefaultDiffActionTests(unittest.TestCase):
    def test_no_copy(self):
        file1 = Path("srcdir-x/file1.bin")
        file2 = Path("srcdir-y/file2.bin")
        with mock.patch.object(output_cacher, "detail_diff") as mock_diff:
            with mock.patch.object(
                output_cacher, "copy_preserve_subpath"
            ) as mock_copy:
                output_cacher.default_diff_action(file1, file2)

        mock_diff.assert_called_with(file1, file2)
        mock_copy.assert_not_called()

    def test_with_copy(self):
        file1 = Path("srcdir-x/file1.bin")
        file2 = Path("srcdir-y/file2.bin")
        export_dir = Path("bad/diffs")
        with mock.patch.object(output_cacher, "detail_diff") as mock_diff:
            with mock.patch.object(
                output_cacher, "copy_preserve_subpath"
            ) as mock_copy:
                output_cacher.default_diff_action(
                    file1, file2, miscomparison_export_dir=export_dir
                )

        mock_diff.assert_called_with(file1, file2)
        mock_copy.assert_has_calls(
            [
                mock.call(file1, export_dir),
                mock.call(file2, export_dir),
            ],
            any_order=True,
        )


class MoveIfDifferentTests(unittest.TestCase):
    def test_nonexistent_source(self):
        with mock.patch.object(
            Path, "exists", return_value=False
        ) as mock_exists:
            with mock.patch.object(Path, "rename") as mock_move:
                with mock.patch.object(Path, "unlink") as mock_remove:
                    with mock.patch.object(time, "sleep") as mock_sleep:
                        with self.assertRaises(FileNotFoundError):
                            output_cacher.move_if_different(
                                Path("source.txt"), Path("dest.txt")
                            )
        mock_exists.assert_called_with()
        mock_move.assert_not_called()
        mock_remove.assert_not_called()

    def test_new_output(self):
        with mock.patch.object(
            Path,
            "exists",
            side_effect=[True, False],  # source.txt, dest.txt
        ) as mock_exists:
            with mock.patch.object(output_cacher, "files_match") as mock_diff:
                with mock.patch.object(Path, "rename") as mock_move:
                    with mock.patch.object(Path, "unlink") as mock_remove:
                        moved = output_cacher.move_if_different(
                            Path("source.txt"), Path("dest.txt")
                        )
        self.assertTrue(moved)
        mock_exists.assert_called_with()
        mock_diff.assert_not_called()
        mock_move.assert_called_with(Path("dest.txt"))
        mock_remove.assert_not_called()

    def test_updating_output(self):
        with mock.patch.object(
            Path, "exists", return_value=True
        ) as mock_exists:
            with mock.patch.object(
                output_cacher, "files_match", return_value=False
            ) as mock_diff:
                with mock.patch.object(Path, "rename") as mock_move:
                    with mock.patch.object(Path, "unlink") as mock_remove:
                        moved = output_cacher.move_if_different(
                            Path("source.txt"), Path("dest.txt")
                        )
        self.assertTrue(moved)
        mock_exists.assert_called_with()
        mock_diff.assert_called_with(Path("dest.txt"), Path("source.txt"))
        mock_move.assert_called_with(Path("dest.txt"))
        mock_remove.assert_not_called()

    def test_cached_output(self):
        with mock.patch.object(
            Path, "exists", return_value=True
        ) as mock_exists:
            with mock.patch.object(
                output_cacher, "files_match", return_value=True
            ) as mock_diff:
                with mock.patch.object(Path, "rename") as mock_move:
                    with mock.patch.object(Path, "unlink") as mock_remove:
                        with mock.patch.object(
                            output_cacher, "ensure_file_exists"
                        ) as mock_exists:
                            moved = output_cacher.move_if_different(
                                Path("source.txt"), Path("dest.txt")
                            )
        self.assertFalse(moved)
        mock_exists.assert_called()
        mock_diff.assert_called()
        mock_move.assert_not_called()
        mock_remove.assert_called_with()


class SubstituteCommandTest(unittest.TestCase):
    def test_no_substitutions(self):
        transform = output_cacher.TempFileTransform(suffix=".tmp")
        action = output_cacher.Action(command=["run.sh"], substitutions={})
        repl, renamed = action.substitute_command(transform)
        self.assertEqual(repl, ["run.sh"])
        self.assertEqual(renamed, {})

    def test_one_suffix(self):
        transform = output_cacher.TempFileTransform(suffix=".tmp")
        action = output_cacher.Action(
            command=["run.sh", "out.txt"], substitutions={"out.txt": ""}
        )
        repl, renamed = action.substitute_command(transform)
        self.assertEqual(repl, ["run.sh", "out.txt.tmp"])
        self.assertEqual(renamed, {Path("out.txt"): Path("out.txt.tmp")})

    def test_require_flag_match_missing_flag(self):
        transform = output_cacher.TempFileTransform(suffix=".tmp")
        action = output_cacher.Action(
            command=["run.sh", "out.txt"], substitutions={"out.txt": "-f"}
        )
        repl, renamed = action.substitute_command(transform)
        self.assertEqual(repl, ["run.sh", "out.txt"])
        self.assertEqual(renamed, {})

    def test_require_flag_match_wrong_flag(self):
        transform = output_cacher.TempFileTransform(suffix=".tmp")
        action = output_cacher.Action(
            command=["run.sh", "-g", "out.txt"], substitutions={"out.txt": "-f"}
        )
        repl, renamed = action.substitute_command(transform)
        self.assertEqual(repl, ["run.sh", "-g", "out.txt"])
        self.assertEqual(renamed, {})

    def test_require_flag_match_have_flag(self):
        transform = output_cacher.TempFileTransform(suffix=".tmp")
        action = output_cacher.Action(
            command=["run.sh", "-f", "out.txt"], substitutions={"out.txt": "-f"}
        )
        repl, renamed = action.substitute_command(transform)
        self.assertEqual(repl, ["run.sh", "-f", "out.txt.tmp"])
        self.assertEqual(renamed, {Path("out.txt"): Path("out.txt.tmp")})

    def test_match_only_one_flag(self):
        transform = output_cacher.TempFileTransform(basename_prefix="tmp-")
        action = output_cacher.Action(
            command=["run.sh", "-x", "out.txt", "-f", "out.txt"],
            substitutions={"out.txt": "-f"},
        )
        repl, renamed = action.substitute_command(transform)
        self.assertEqual(repl, ["run.sh", "-x", "out.txt", "-f", "tmp-out.txt"])
        self.assertEqual(renamed, {Path("out.txt"): Path("tmp-out.txt")})

    def test_match_only_one_flag_first_occurrence(self):
        transform = output_cacher.TempFileTransform(basename_prefix="tmp-")
        action = output_cacher.Action(
            command=["run.sh", "out.txt", "-f", "out.txt", "out.txt"],
            substitutions={"out.txt": "-f"},
        )
        repl, renamed = action.substitute_command(transform)
        self.assertEqual(
            repl, ["run.sh", "out.txt", "-f", "tmp-out.txt", "out.txt"]
        )
        self.assertEqual(renamed, {Path("out.txt"): Path("tmp-out.txt")})


class ReplaceOutputArgsTest(unittest.TestCase):
    def test_dry_run(self):
        transform = output_cacher.TempFileTransform(suffix=".tmp")
        action = output_cacher.Action(command=["run.sh"], substitutions={})
        with mock.patch.object(
            output_cacher, "execute_main_command"
        ) as mock_call:
            self.assertEqual(action.run_cached(transform, dry_run=True), 0)
        mock_call.assert_not_called()

    def test_command_failed(self):
        transform = output_cacher.TempFileTransform(suffix=".tmp")
        action = output_cacher.Action(command=["run.sh"], substitutions={})
        with mock.patch.object(
            output_cacher, "execute_main_command", return_value=1
        ) as mock_call:
            with mock.patch.object(
                output_cacher, "move_if_different"
            ) as mock_update:
                self.assertEqual(action.run_cached(transform), 1)
        mock_call.assert_called_with(["run.sh"])
        mock_update.assert_not_called()

    def test_command_passed_using_suffix(self):
        transform = output_cacher.TempFileTransform(suffix=".tmp")
        action = output_cacher.Action(
            command=["run.sh", "in.put", "out.put"],
            substitutions={"out.put": ""},
        )
        with mock.patch.object(
            output_cacher, "execute_main_command", return_value=0
        ) as mock_call:
            # This test doesn't care if move happened.
            with mock.patch.object(
                output_cacher, "move_if_different", return_value=False
            ) as mock_update:
                self.assertEqual(action.run_cached(transform), 0)
        mock_call.assert_called_with(["run.sh", "in.put", "out.put.tmp"])
        mock_update.assert_called_with(
            src=Path("out.put.tmp"), dest=Path("out.put"), verbose=False
        )

    def test_command_passed_using_relative_temp_dir(self):
        transform = output_cacher.TempFileTransform(temp_dir="temp/temp")
        action = output_cacher.Action(
            command=["run.sh", "in.put", "foo/out.put"],
            substitutions={"foo/out.put": ""},
        )
        with mock.patch.object(
            output_cacher, "execute_main_command", return_value=0
        ) as mock_call:
            # This test doesn't care if move happened.
            with mock.patch.object(
                output_cacher, "move_if_different", return_value=False
            ) as mock_update:
                with mock.patch.object(Path, "mkdir") as mock_mkdir:
                    self.assertEqual(action.run_cached(transform), 0)
        mock_mkdir.assert_called_with(parents=True, exist_ok=True)
        mock_call.assert_called_with(
            ["run.sh", "in.put", "temp/temp/foo/out.put"]
        )
        mock_update.assert_called_with(
            src=Path("temp/temp/foo/out.put"),
            dest=Path("foo/out.put"),
            verbose=False,
        )


def fake_detail_diff(left: Path, right: Path):
    # Don't print anything, or attempt to call a diff script
    pass


class RunRepeatedlyCompareTests(unittest.TestCase):
    def test_command_failed(self):
        transform = output_cacher.TempFileTransform(suffix=".tmp")
        action = output_cacher.Action(command=["run.sh"], substitutions={})
        with mock.patch.object(
            output_cacher, "execute_main_command", return_value=1
        ) as mock_call:
            with mock.patch.object(output_cacher, "files_match") as mock_match:
                with mock.patch.object(
                    os.path, "exists", return_value=True
                ) as mock_exists:
                    with mock.patch.object(shutil, "copy2") as mock_copy:
                        with mock.patch.object(os, "makedirs") as mock_mkdir:
                            with mock.patch.object(time, "sleep") as mock_zzz:
                                self.assertEqual(
                                    action.run_repeatedly_and_compare_outputs(
                                        tempfile_transform=transform,
                                        diff_action=fake_detail_diff,
                                    ),
                                    1,
                                )
        mock_call.assert_called_once_with(["run.sh"])
        mock_match.assert_not_called()
        mock_exists.assert_not_called()
        mock_mkdir.assert_not_called()
        mock_copy.assert_not_called()

    def test_command_passed_and_rerun_matches(self):
        transform = output_cacher.TempFileTransform(suffix=".tmp")
        action = output_cacher.Action(
            command=["run.sh", "in.put", "out.put"],
            substitutions={"out.put": ""},
        )
        with mock.patch.object(
            output_cacher, "execute_main_command", return_value=0
        ) as mock_call:
            with mock.patch.object(
                output_cacher, "files_match", return_value=True
            ) as mock_match:
                with mock.patch.object(
                    Path, "is_file", return_value=True
                ) as mock_isfile:
                    with mock.patch.object(
                        output_cacher, "remove_if_exists"
                    ) as mock_remove:
                        with mock.patch.object(Path, "mkdir") as mock_mkdir:
                            with mock.patch.object(
                                shutil, "copy2"
                            ) as mock_copy:
                                with mock.patch.object(
                                    time, "sleep"
                                ) as mock_zzz:
                                    self.assertEqual(
                                        action.run_repeatedly_and_compare_outputs(
                                            tempfile_transform=transform,
                                            diff_action=fake_detail_diff,
                                            max_attempts=2,
                                        ),
                                        0,
                                    )
        mock_call.assert_has_calls(
            [
                mock.call(["run.sh", "in.put", "out.put"]),  # first run
                mock.call(["run.sh", "in.put", "out.put"]),  # re-run 1
                mock.call(["run.sh", "in.put", "out.put"]),  # re-run 2
            ],
            any_order=True,
        )
        mock_match.assert_called_with(Path("out.put"), Path("out.put.tmp"))
        mock_remove.assert_called_with(Path("out.put.tmp"))
        mock_isfile.assert_called()
        mock_mkdir.assert_not_called()  # using suffix, not temp_dir
        mock_copy.assert_called_once_with(
            Path("out.put"), Path("out.put.tmp"), follow_symlinks=False
        )

    def test_command_passed_and_rerun_differs(self):
        transform = output_cacher.TempFileTransform(suffix=".tmp")
        action = output_cacher.Action(
            command=["run.sh", "in.put", "out.put"],
            substitutions={"out.put": ""},
        )
        with mock.patch.object(
            output_cacher, "execute_main_command", return_value=0
        ) as mock_call:
            with mock.patch.object(
                output_cacher,
                "files_match",
                # mismatch on 2nd attempt
                side_effect=[True, False],
            ) as mock_match:
                with mock.patch.object(
                    Path, "is_file", return_value=True
                ) as mock_isfile:
                    with mock.patch.object(
                        output_cacher, "remove_if_exists"
                    ) as mock_remove:
                        with mock.patch.object(Path, "mkdir") as mock_mkdir:
                            with mock.patch.object(
                                shutil, "copy2"
                            ) as mock_copy:
                                with mock.patch.object(
                                    time, "sleep"
                                ) as mock_zzz:
                                    self.assertEqual(
                                        action.run_repeatedly_and_compare_outputs(
                                            tempfile_transform=transform,
                                            diff_action=fake_detail_diff,
                                            max_attempts=10,
                                        ),
                                        1,
                                    )
        mock_call.assert_has_calls(
            [
                mock.call(["run.sh", "in.put", "out.put"]),
                mock.call(["run.sh", "in.put", "out.put"]),
                mock.call(["run.sh", "in.put", "out.put"]),
                # Stop after first miscomparison, before max_attempts reached.
            ],
            any_order=True,
        )
        mock_match.assert_called_with(Path("out.put"), Path("out.put.tmp"))
        mock_remove.assert_not_called()  # mismatches kept
        mock_isfile.assert_called()
        mock_mkdir.assert_not_called()  # using suffix, not temp_dir
        mock_copy.assert_called_once_with(
            Path("out.put"), Path("out.put.tmp"), follow_symlinks=False
        )

    def test_command_passed_and_some_outputs_differ(self):
        def fake_match(file1: Path, file2: Path) -> bool:
            if file1 == Path("out.put"):
                return True
            elif file1 == Path("out2.put"):
                return False
            raise ValueError(f"Unhandled file name: {file1}")

        transform = output_cacher.TempFileTransform(suffix=".tmp")
        action = output_cacher.Action(
            command=["run.sh", "in.put", "out.put", "out2.put"],
            substitutions={"out.put": "", "out2.put": ""},
        )
        with mock.patch.object(
            output_cacher, "execute_main_command", return_value=0
        ) as mock_call:
            with mock.patch.object(
                output_cacher, "files_match", wraps=fake_match
            ) as mock_match:
                with mock.patch.object(
                    Path, "is_file", return_value=True
                ) as mock_isfile:
                    with mock.patch.object(
                        output_cacher, "remove_if_exists"
                    ) as mock_remove:
                        with mock.patch.object(Path, "mkdir") as mock_mkdir:
                            with mock.patch.object(
                                shutil, "copy2"
                            ) as mock_copy:
                                with mock.patch.object(
                                    time, "sleep"
                                ) as mock_zzz:
                                    self.assertEqual(
                                        action.run_repeatedly_and_compare_outputs(
                                            tempfile_transform=transform,
                                            diff_action=fake_detail_diff,
                                        ),
                                        1,
                                    )
        mock_call.assert_has_calls(
            [
                mock.call(["run.sh", "in.put", "out.put", "out2.put"]),
                mock.call(["run.sh", "in.put", "out.put", "out2.put"]),
            ],
            any_order=True,
        )
        mock_match.assert_has_calls(
            [
                mock.call(Path("out.put"), Path("out.put.tmp")),
                mock.call(Path("out2.put"), Path("out2.put.tmp")),
            ],
            any_order=True,
        )
        mock_remove.assert_not_called()  # keep around mismatches
        mock_isfile.assert_called()
        mock_mkdir.assert_not_called()  # using suffix, not temp_dir
        mock_copy.assert_has_calls(
            [
                mock.call(
                    Path("out.put"), Path("out.put.tmp"), follow_symlinks=False
                ),
                mock.call(
                    Path("out2.put"),
                    Path("out2.put.tmp"),
                    follow_symlinks=False,
                ),
            ],
            any_order=True,
        )


class RunTwiceWithSubstitutionCompareTests(unittest.TestCase):
    def test_command_failed(self):
        transform = output_cacher.TempFileTransform(suffix=".tmp")
        action = output_cacher.Action(command=["run.sh"], substitutions={})
        with mock.patch.object(
            output_cacher, "execute_main_command", return_value=1
        ) as mock_call:
            with mock.patch.object(output_cacher, "files_match") as mock_match:
                self.assertEqual(
                    action.run_twice_with_substitution_and_compare_outputs(
                        tempfile_transform=transform,
                        diff_action=fake_detail_diff,
                    ),
                    1,
                )
        mock_call.assert_called_once_with(["run.sh"])
        mock_match.assert_not_called()

    def test_command_passed_and_rerun_matches(self):
        transform = output_cacher.TempFileTransform(suffix=".tmp")
        action = output_cacher.Action(
            command=["run.sh", "in.put", "out.put"],
            substitutions={"out.put": ""},
        )
        with mock.patch.object(
            output_cacher, "execute_main_command", return_value=0
        ) as mock_call:
            with mock.patch.object(
                output_cacher, "files_match", return_value=True
            ) as mock_match:
                with mock.patch.object(Path, "unlink") as mock_remove:
                    self.assertEqual(
                        action.run_twice_with_substitution_and_compare_outputs(
                            tempfile_transform=transform,
                            diff_action=fake_detail_diff,
                        ),
                        0,
                    )
        mock_call.assert_has_calls(
            [
                mock.call(["run.sh", "in.put", "out.put"]),
                mock.call(["run.sh", "in.put", "out.put.tmp"]),
            ],
            any_order=True,
        )
        mock_match.assert_called_with(Path("out.put"), Path("out.put.tmp"))
        mock_remove.assert_called_with()

    def test_command_passed_and_rerun_differs(self):
        transform = output_cacher.TempFileTransform(suffix=".tmp")
        action = output_cacher.Action(
            command=["run.sh", "in.put", "out.put"],
            substitutions={"out.put": ""},
        )
        with mock.patch.object(
            output_cacher, "execute_main_command", return_value=0
        ) as mock_call:
            with mock.patch.object(
                output_cacher, "files_match", return_value=False
            ) as mock_match:
                with mock.patch.object(os, "remove") as mock_remove:
                    self.assertEqual(
                        action.run_twice_with_substitution_and_compare_outputs(
                            tempfile_transform=transform,
                            diff_action=fake_detail_diff,
                        ),
                        1,
                    )
        mock_call.assert_has_calls(
            [
                mock.call(["run.sh", "in.put", "out.put"]),
                mock.call(["run.sh", "in.put", "out.put.tmp"]),
            ],
            any_order=True,
        )
        mock_match.assert_called_with(Path("out.put"), Path("out.put.tmp"))
        mock_remove.assert_not_called()

    def test_command_passed_and_some_outptus_differ(self):
        def fake_match(file1: Path, file2: Path) -> bool:
            if file1 == Path("out.put"):
                return True
            elif file1 == Path("out2.put"):
                return False
            raise ValueError(f"Unhandled file name: {file1}")

        transform = output_cacher.TempFileTransform(suffix=".tmp")
        action = output_cacher.Action(
            command=["run.sh", "in.put", "out.put", "out2.put"],
            substitutions={"out.put": "", "out2.put": ""},
        )
        with mock.patch.object(
            output_cacher, "execute_main_command", return_value=0
        ) as mock_call:
            with mock.patch.object(
                output_cacher, "files_match", wraps=fake_match
            ) as mock_match:
                with mock.patch.object(Path, "unlink") as mock_remove:
                    self.assertEqual(
                        action.run_twice_with_substitution_and_compare_outputs(
                            tempfile_transform=transform,
                            diff_action=fake_detail_diff,
                        ),
                        1,
                    )
        mock_call.assert_has_calls(
            [
                mock.call(["run.sh", "in.put", "out.put", "out2.put"]),
                mock.call(["run.sh", "in.put", "out.put.tmp", "out2.put.tmp"]),
            ],
            any_order=True,
        )
        mock_match.assert_has_calls(
            [
                mock.call(Path("out.put"), Path("out.put.tmp")),
                mock.call(Path("out2.put"), Path("out2.put.tmp")),
            ],
            any_order=True,
        )
        mock_remove.assert_has_calls([mock.call()])


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