// Copyright 2022 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.remote;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;

import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.ActionInputMap;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.vfs.Dirent;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.Symlinks;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.junit.Test;

public abstract class RemoteActionFileSystemTestBase {
  protected abstract FileSystem createActionFileSystem(
      ActionInputMap inputs, Iterable<Artifact> outputs) throws IOException;

  protected FileSystem createActionFileSystem() throws IOException {
    ActionInputMap inputs = new ActionInputMap(0);
    return createActionFileSystem(inputs);
  }

  protected FileSystem createActionFileSystem(ActionInputMap inputs) throws IOException {
    return createActionFileSystem(inputs, ImmutableList.of());
  }

  protected abstract FileSystem getLocalFileSystem(FileSystem actionFs);

  protected abstract FileSystem getRemoteFileSystem(FileSystem actionFs);

  protected abstract PathFragment getOutputPath(String outputRootRelativePath);

  protected abstract void writeLocalFile(FileSystem actionFs, PathFragment path, String content)
      throws IOException;

  protected abstract void injectRemoteFile(FileSystem actionFs, PathFragment path, String content)
      throws IOException;

  @Test
  public void exists_fileDoesNotExist_returnsFalse() throws Exception {
    FileSystem actionFs = createActionFileSystem();
    PathFragment path = getOutputPath("file");

    boolean exists = actionFs.exists(path);

    assertThat(exists).isFalse();
  }

  @Test
  public void exists_localFile_returnsTrue() throws Exception {
    FileSystem actionFs = createActionFileSystem();
    PathFragment path = getOutputPath("file");

    writeLocalFile(actionFs, path, "local contents");

    assertThat(actionFs.exists(path)).isTrue();
  }

  @Test
  public void exists_remoteFile_returnsTrue() throws Exception {
    FileSystem actionFs = createActionFileSystem();
    PathFragment path = getOutputPath("file");

    injectRemoteFile(actionFs, path, "remote contents");

    assertThat(actionFs.exists(path)).isTrue();
  }

  @Test
  public void exists_localAndRemoteFile_returnsTrue() throws Exception {
    FileSystem actionFs = createActionFileSystem();
    PathFragment path = getOutputPath("file");

    writeLocalFile(actionFs, path, "local contents");
    injectRemoteFile(actionFs, path, "remote contents");

    assertThat(actionFs.exists(path)).isTrue();
  }

  @Test
  public void delete_fileDoesNotExist_returnsFalse() throws Exception {
    FileSystem actionFs = createActionFileSystem();
    PathFragment path = getOutputPath("file");

    boolean success = actionFs.getPath(path).delete();

    assertThat(success).isFalse();
  }

  @Test
  public void delete_localFile_succeeds() throws Exception {
    FileSystem actionFs = createActionFileSystem();
    PathFragment path = getOutputPath("file");
    writeLocalFile(actionFs, path, "local contents");
    assertThat(getLocalFileSystem(actionFs).exists(path)).isTrue();

    boolean success = actionFs.getPath(path).delete();

    assertThat(success).isTrue();
    assertThat(getLocalFileSystem(actionFs).exists(path)).isFalse();
  }

  @Test
  public void delete_remoteFile_succeeds() throws Exception {
    FileSystem actionFs = createActionFileSystem();
    PathFragment path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote contents");
    assertThat(getRemoteFileSystem(actionFs).exists(path)).isTrue();

    boolean success = actionFs.getPath(path).delete();

    assertThat(success).isTrue();
    assertThat(actionFs.exists(path)).isFalse();
    assertThat(getRemoteFileSystem(actionFs).exists(path)).isFalse();
  }

  @Test
  public void delete_localAndRemoteFile_succeeds() throws Exception {
    FileSystem actionFs = createActionFileSystem();
    PathFragment path = getOutputPath("file");
    writeLocalFile(actionFs, path, "local contents");
    injectRemoteFile(actionFs, path, "remote contents");
    assertThat(getLocalFileSystem(actionFs).exists(path)).isTrue();
    assertThat(getRemoteFileSystem(actionFs).exists(path)).isTrue();

    boolean success = actionFs.getPath(path).delete();

    assertThat(success).isTrue();
    assertThat(actionFs.exists(path)).isFalse();
    assertThat(getLocalFileSystem(actionFs).exists(path)).isFalse();
    assertThat(getRemoteFileSystem(actionFs).exists(path)).isFalse();
  }

  @Test
  public void renameTo_fileDoesNotExist_throwError() throws Exception {
    FileSystem actionFs = createActionFileSystem();
    PathFragment path = getOutputPath("file");
    PathFragment newPath = getOutputPath("file-new");

    assertThrows(FileNotFoundException.class, () -> actionFs.renameTo(path, newPath));
  }

  @Test
  public void renameTo_onlyRemoteFile_renameRemoteFile() throws Exception {
    FileSystem actionFs = createActionFileSystem();
    PathFragment path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");
    PathFragment newPath = getOutputPath("file-new");

    actionFs.renameTo(path, newPath);

    assertThat(actionFs.exists(path)).isFalse();
    assertThat(actionFs.exists(newPath)).isTrue();
    assertThat(getRemoteFileSystem(actionFs).exists(path)).isFalse();
    assertThat(getRemoteFileSystem(actionFs).exists(newPath)).isTrue();
  }

  @Test
  public void renameTo_localAndRemoteFile_renameBoth() throws Exception {
    FileSystem actionFs = createActionFileSystem();
    PathFragment path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");
    writeLocalFile(actionFs, path, "local-content");
    PathFragment newPath = getOutputPath("file-new");

    actionFs.renameTo(path, newPath);

    assertThat(actionFs.exists(path)).isFalse();
    assertThat(actionFs.exists(newPath)).isTrue();
    assertThat(getRemoteFileSystem(actionFs).exists(path)).isFalse();
    assertThat(getRemoteFileSystem(actionFs).exists(newPath)).isTrue();
    assertThat(getLocalFileSystem(actionFs).exists(path)).isFalse();
    assertThat(getLocalFileSystem(actionFs).exists(newPath)).isTrue();
  }

  @Test
  public void createDirectoryAndParents_createLocallyAndRemotely() throws Exception {
    FileSystem actionFs = createActionFileSystem();
    PathFragment path = getOutputPath("dir");

    actionFs.createDirectoryAndParents(path);

    assertThat(getRemoteFileSystem(actionFs).getPath(path).isDirectory()).isTrue();
    assertThat(getLocalFileSystem(actionFs).getPath(path).isDirectory()).isTrue();
  }

  @Test
  public void createDirectory_createLocallyAndRemotely() throws Exception {
    FileSystem actionFs = createActionFileSystem();
    actionFs.createDirectoryAndParents(getOutputPath("parent"));
    PathFragment path = getOutputPath("parent/dir");

    actionFs.createDirectory(path);

    assertThat(getRemoteFileSystem(actionFs).getPath(path).isDirectory()).isTrue();
    assertThat(getLocalFileSystem(actionFs).getPath(path).isDirectory()).isTrue();
  }

  interface DirectoryEntriesProvider {
    ImmutableList<String> getDirectoryEntries(Path path) throws IOException;
  }

  private void readdirNonEmptyLocalDirectoryReadFromLocal(
      DirectoryEntriesProvider directoryEntriesProvider) throws IOException {
    FileSystem actionFs = createActionFileSystem();
    PathFragment dir = getOutputPath("parent/dir");
    actionFs.getPath(dir).createDirectoryAndParents();
    writeLocalFile(actionFs, dir.getChild("file1"), "content1");
    writeLocalFile(actionFs, dir.getChild("file2"), "content2");

    ImmutableList<String> entries =
        directoryEntriesProvider.getDirectoryEntries(actionFs.getPath(dir));

    assertThat(entries).containsExactly("file1", "file2");
  }

  private void readdirNonEmptyInMemoryDirectoryReadFromMemory(
      DirectoryEntriesProvider directoryEntriesProvider) throws IOException {
    FileSystem actionFs = createActionFileSystem();
    PathFragment dir = getOutputPath("parent/dir");
    actionFs.getPath(dir).createDirectoryAndParents();
    injectRemoteFile(actionFs, dir.getChild("file1"), "content1");
    injectRemoteFile(actionFs, dir.getChild("file2"), "content2");

    ImmutableList<String> entries =
        directoryEntriesProvider.getDirectoryEntries(actionFs.getPath(dir));

    assertThat(entries).containsExactly("file1", "file2");
  }

  private void readdirNonEmptyLocalAndInMemoryDirectoryCombineThem(
      DirectoryEntriesProvider directoryEntriesProvider) throws IOException {
    FileSystem actionFs = createActionFileSystem();
    PathFragment dir = getOutputPath("parent/dir");
    actionFs.getPath(dir).createDirectoryAndParents();
    writeLocalFile(actionFs, dir.getChild("file1"), "content1");
    writeLocalFile(actionFs, dir.getChild("file2"), "content2");
    injectRemoteFile(actionFs, dir.getChild("file2"), "content2inmemory");
    injectRemoteFile(actionFs, dir.getChild("file3"), "content3");

    ImmutableList<String> entries =
        directoryEntriesProvider.getDirectoryEntries(actionFs.getPath(dir));

    assertThat(entries).containsExactly("file1", "file2", "file3");
  }

  private void readdirNothingThereThrowsFileNotFound(
      DirectoryEntriesProvider directoryEntriesProvider) throws IOException {
    FileSystem actionFs = createActionFileSystem();
    PathFragment dir = getOutputPath("parent/dir");

    assertThrows(
        FileNotFoundException.class,
        () -> directoryEntriesProvider.getDirectoryEntries(actionFs.getPath(dir)));
  }

  @Test
  public void readdir_nonEmptyLocalDirectory_readFromLocal() throws IOException {
    readdirNonEmptyLocalDirectoryReadFromLocal(
        path ->
            path.readdir(Symlinks.FOLLOW).stream().map(Dirent::getName).collect(toImmutableList()));
  }

  @Test
  public void readdir_nonEmptyInMemoryDirectory_readFromMemory() throws IOException {
    readdirNonEmptyInMemoryDirectoryReadFromMemory(
        path ->
            path.readdir(Symlinks.FOLLOW).stream().map(Dirent::getName).collect(toImmutableList()));
  }

  @Test
  public void readdir_nonEmptyLocalAndInMemoryDirectory_combineThem() throws IOException {
    readdirNonEmptyLocalAndInMemoryDirectoryCombineThem(
        path ->
            path.readdir(Symlinks.FOLLOW).stream().map(Dirent::getName).collect(toImmutableList()));
  }

  @Test
  public void readdir_nothingThere_throwsFileNotFound() throws IOException {
    readdirNothingThereThrowsFileNotFound(
        path ->
            path.readdir(Symlinks.FOLLOW).stream().map(Dirent::getName).collect(toImmutableList()));
  }

  @Test
  public void getDirectoryEntries_nonEmptyLocalDirectory_readFromLocal() throws IOException {
    readdirNonEmptyLocalDirectoryReadFromLocal(
        path ->
            path.getDirectoryEntries().stream().map(Path::getBaseName).collect(toImmutableList()));
  }

  @Test
  public void getDirectoryEntries_nonEmptyInMemoryDirectory_readFromMemory() throws IOException {
    readdirNonEmptyInMemoryDirectoryReadFromMemory(
        path ->
            path.getDirectoryEntries().stream().map(Path::getBaseName).collect(toImmutableList()));
  }

  @Test
  public void getDirectoryEntries_nonEmptyLocalAndInMemoryDirectory_combineThem()
      throws IOException {
    readdirNonEmptyLocalAndInMemoryDirectoryCombineThem(
        path ->
            path.getDirectoryEntries().stream().map(Path::getBaseName).collect(toImmutableList()));
  }

  @Test
  public void getDirectoryEntries_nothingThere_throwsFileNotFound() throws IOException {
    readdirNothingThereThrowsFileNotFound(
        path ->
            path.getDirectoryEntries().stream().map(Path::getBaseName).collect(toImmutableList()));
  }

  @Test
  public void isReadable_fileDoesNotExist_throwError() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");

    assertThrows(FileNotFoundException.class, () -> actionFs.getPath(path).isReadable());
  }

  @Test
  public void isReadable_onlyRemoteFile_returnsTrue() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");

    var readable = actionFs.getPath(path).isReadable();

    assertThat(readable).isTrue();
  }

  @Test
  public void isReadable_onlyRemoteDirectory_returnsTrue() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("dir");
    getRemoteFileSystem(actionFs).createDirectoryAndParents(path);

    var readable = actionFs.getPath(path).isReadable();

    assertThat(readable).isTrue();
  }

  @Test
  public void isReadable_localReadableFile_returnsTrue() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    writeLocalFile(actionFs, path, "local-content");

    var readable = actionFs.getPath(path).isReadable();

    assertThat(readable).isTrue();
  }

  @Test
  public void isReadable_localNonReadableFile_returnsFalse() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    writeLocalFile(actionFs, path, "local-content");
    getLocalFileSystem(actionFs).getPath(path).setReadable(false);

    var readable = actionFs.getPath(path).isReadable();

    assertThat(readable).isFalse();
  }

  @Test
  public void isReadable_localReadableFileAndRemoteFile_returnsTrue() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");
    writeLocalFile(actionFs, path, "local-content");

    var readable = actionFs.getPath(path).isReadable();

    assertThat(readable).isTrue();
  }

  @Test
  public void isReadable_localNonReadableFileAndRemoteFile_returnsTrue() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");
    writeLocalFile(actionFs, path, "local-content");
    getLocalFileSystem(actionFs).getPath(path).setReadable(false);

    var readable = actionFs.getPath(path).isReadable();

    assertThat(readable).isTrue();
  }

  @Test
  public void isWritable_fileDoesNotExist_throwError() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");

    assertThrows(FileNotFoundException.class, () -> actionFs.getPath(path).isWritable());
  }

  @Test
  public void isWritable_onlyRemoteFile_returnsTrue() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");

    var writable = actionFs.getPath(path).isWritable();

    assertThat(writable).isTrue();
  }

  @Test
  public void isWritable_onlyRemoteDirectory_returnsTrue() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("dir");
    getRemoteFileSystem(actionFs).createDirectoryAndParents(path);

    var writable = actionFs.getPath(path).isWritable();

    assertThat(writable).isTrue();
  }

  @Test
  public void isWritable_localWritableFile_returnsTrue() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    writeLocalFile(actionFs, path, "local-content");

    var writable = actionFs.getPath(path).isWritable();

    assertThat(writable).isTrue();
  }

  @Test
  public void isWritable_localNonWritableFile_returnsFalse() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    writeLocalFile(actionFs, path, "local-content");
    getLocalFileSystem(actionFs).getPath(path).setWritable(false);

    var writable = actionFs.getPath(path).isWritable();

    assertThat(writable).isFalse();
  }

  @Test
  public void isWritable_localWritableFileAndRemoteFile_returnsTrue() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");
    writeLocalFile(actionFs, path, "local-content");

    var writable = actionFs.getPath(path).isWritable();

    assertThat(writable).isTrue();
  }

  @Test
  public void isWritable_localNonWritableFileAndRemoteFile_returnsFalse() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");
    writeLocalFile(actionFs, path, "local-content");
    getLocalFileSystem(actionFs).getPath(path).setWritable(false);

    var writable = actionFs.getPath(path).isWritable();

    assertThat(writable).isFalse();
  }

  @Test
  public void isWritable_localNonWritableDirectoryAndRemoteDirectory_returnsFalse()
      throws Exception {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("dir");
    getRemoteFileSystem(actionFs).getPath(path).createDirectoryAndParents();
    getLocalFileSystem(actionFs).getPath(path).createDirectoryAndParents();
    getLocalFileSystem(actionFs).getPath(path).setWritable(false);

    boolean writable = actionFs.getPath(path).isWritable();

    assertThat(writable).isFalse();
  }

  @Test
  public void isExecutable_fileDoesNotExist_throwError() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");

    assertThrows(FileNotFoundException.class, () -> actionFs.getPath(path).isExecutable());
  }

  @Test
  public void isExecutable_onlyRemoteFile_returnsTrue() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");

    var executable = actionFs.getPath(path).isExecutable();

    assertThat(executable).isTrue();
  }

  @Test
  public void isExecutable_onlyRemoteDirecotry_returnsTrue() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("dir");
    getRemoteFileSystem(actionFs).createDirectoryAndParents(path);

    var executable = actionFs.getPath(path).isExecutable();

    assertThat(executable).isTrue();
  }

  @Test
  public void isExecutable_localExecutableFile_returnsTrue() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    writeLocalFile(actionFs, path, "local-content");
    getLocalFileSystem(actionFs).getPath(path).setExecutable(true);

    var executable = actionFs.getPath(path).isExecutable();

    assertThat(executable).isTrue();
  }

  @Test
  public void isExecutable_localNonExecutableFile_returnsFalse() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    writeLocalFile(actionFs, path, "local-content");

    var executable = actionFs.getPath(path).isExecutable();

    assertThat(executable).isFalse();
  }

  @Test
  public void isExecutable_localExecutableFileAndRemoteFile_returnsTrue() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");
    writeLocalFile(actionFs, path, "local-content");
    getLocalFileSystem(actionFs).getPath(path).setExecutable(true);

    var executable = actionFs.getPath(path).isExecutable();

    assertThat(executable).isTrue();
  }

  @Test
  public void isExecutable_localNonExecutableFileAndRemoteFile_returnsTrue() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");
    writeLocalFile(actionFs, path, "local-content");

    var executable = actionFs.getPath(path).isExecutable();

    assertThat(executable).isTrue();
  }

  @Test
  public void setReadable_fileDoesNotExist_throwError() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");

    assertThrows(FileNotFoundException.class, () -> actionFs.getPath(path).setReadable(false));
  }

  @Test
  public void setReadable_onlyRemoteFile_remainsReadable() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");

    actionFs.getPath(path).setReadable(false);

    assertThat(actionFs.getPath(path).isReadable()).isTrue();
  }

  @Test
  public void setReadable_onlyRemoteDirecotry_remainsReadable() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("dir");
    getRemoteFileSystem(actionFs).createDirectoryAndParents(path);

    actionFs.getPath(path).setReadable(false);

    assertThat(actionFs.getPath(path).isReadable()).isTrue();
  }

  @Test
  public void setReadable_localFile_change() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    writeLocalFile(actionFs, path, "local-content");
    assertThat(actionFs.getPath(path).isReadable()).isTrue();

    actionFs.getPath(path).setReadable(false);

    assertThat(actionFs.getPath(path).isReadable()).isFalse();
  }

  @Test
  public void setReadable_localFileAndRemoteFile_changeLocal() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");
    writeLocalFile(actionFs, path, "local-content");
    assertThat(actionFs.getPath(path).isReadable()).isTrue();
    assertThat(getLocalFileSystem(actionFs).getPath(path).isReadable()).isTrue();

    actionFs.getPath(path).setReadable(false);

    assertThat(actionFs.getPath(path).isReadable()).isTrue();
    assertThat(getLocalFileSystem(actionFs).getPath(path).isReadable()).isFalse();
  }

  @Test
  public void setWritable_fileDoesNotExist_throwError() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");

    assertThrows(FileNotFoundException.class, () -> actionFs.getPath(path).setWritable(false));
  }

  @Test
  public void setWritable_onlyRemoteFile_remainsWritable() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");

    actionFs.getPath(path).setWritable(false);

    assertThat(actionFs.getPath(path).isWritable()).isTrue();
  }

  @Test
  public void setWritable_onlyRemoteDirecotry_remainsWritable() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("dir");
    getRemoteFileSystem(actionFs).createDirectoryAndParents(path);

    actionFs.getPath(path).setWritable(false);

    assertThat(actionFs.getPath(path).isWritable()).isTrue();
  }

  @Test
  public void setWritable_localFile_change() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    writeLocalFile(actionFs, path, "local-content");
    assertThat(actionFs.getPath(path).isWritable()).isTrue();

    actionFs.getPath(path).setWritable(false);

    assertThat(actionFs.getPath(path).isWritable()).isFalse();
  }

  @Test
  public void setWritable_localFileAndRemoteFile_changeLocal() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");
    writeLocalFile(actionFs, path, "local-content");
    assertThat(actionFs.getPath(path).isWritable()).isTrue();
    assertThat(getLocalFileSystem(actionFs).getPath(path).isWritable()).isTrue();

    actionFs.getPath(path).setWritable(false);

    assertThat(actionFs.getPath(path).isWritable()).isFalse();
    assertThat(getLocalFileSystem(actionFs).getPath(path).isWritable()).isFalse();
  }

  @Test
  public void setExecutable_fileDoesNotExist_throwError() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");

    assertThrows(FileNotFoundException.class, () -> actionFs.getPath(path).setExecutable(false));
  }

  @Test
  public void setExecutable_onlyRemoteFile_remainsExecutable() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");

    actionFs.getPath(path).setExecutable(false);

    assertThat(actionFs.getPath(path).isExecutable()).isTrue();
  }

  @Test
  public void setExecutable_onlyRemoteDirecotry_remainsExecutable() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("dir");
    getRemoteFileSystem(actionFs).createDirectoryAndParents(path);

    actionFs.getPath(path).setExecutable(false);

    assertThat(actionFs.getPath(path).isExecutable()).isTrue();
  }

  @Test
  public void setExecutable_localFile_change() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    writeLocalFile(actionFs, path, "local-content");
    assertThat(actionFs.getPath(path).isExecutable()).isFalse();

    actionFs.getPath(path).setExecutable(true);

    assertThat(actionFs.getPath(path).isExecutable()).isTrue();
  }

  @Test
  public void setExecutable_localFileAndRemoteFile_changeLocal() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");
    writeLocalFile(actionFs, path, "local-content");
    assertThat(actionFs.getPath(path).isExecutable()).isTrue();
    assertThat(getLocalFileSystem(actionFs).getPath(path).isExecutable()).isFalse();

    actionFs.getPath(path).setExecutable(true);

    assertThat(actionFs.getPath(path).isExecutable()).isTrue();
    assertThat(getLocalFileSystem(actionFs).getPath(path).isExecutable()).isTrue();
  }

  @Test
  public void chmod_fileDoesNotExist_throwError() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");

    assertThrows(FileNotFoundException.class, () -> actionFs.getPath(path).chmod(000));
  }

  @Test
  public void chmod_onlyRemoteFile_remainsSame() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");
    assertThat(actionFs.getPath(path).isReadable()).isTrue();
    assertThat(actionFs.getPath(path).isWritable()).isTrue();
    assertThat(actionFs.getPath(path).isExecutable()).isTrue();

    actionFs.getPath(path).chmod(000);

    assertThat(actionFs.getPath(path).isReadable()).isTrue();
    assertThat(actionFs.getPath(path).isWritable()).isTrue();
    assertThat(actionFs.getPath(path).isExecutable()).isTrue();
  }

  @Test
  public void chmod_onlyRemoteDirectory_remainsSame() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("dir");
    getRemoteFileSystem(actionFs).createDirectoryAndParents(path);
    assertThat(actionFs.getPath(path).isReadable()).isTrue();
    assertThat(actionFs.getPath(path).isWritable()).isTrue();
    assertThat(actionFs.getPath(path).isExecutable()).isTrue();

    actionFs.getPath(path).chmod(000);

    assertThat(actionFs.getPath(path).isReadable()).isTrue();
    assertThat(actionFs.getPath(path).isWritable()).isTrue();
    assertThat(actionFs.getPath(path).isExecutable()).isTrue();
  }

  @Test
  public void chmod_localFile_change() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    writeLocalFile(actionFs, path, "local-content");
    assertThat(actionFs.getPath(path).isReadable()).isTrue();
    assertThat(actionFs.getPath(path).isWritable()).isTrue();
    assertThat(actionFs.getPath(path).isExecutable()).isFalse();

    actionFs.getPath(path).chmod(0111);

    assertThat(actionFs.getPath(path).isReadable()).isFalse();
    assertThat(actionFs.getPath(path).isWritable()).isFalse();
    assertThat(actionFs.getPath(path).isExecutable()).isTrue();
  }

  @Test
  public void chmod_localFileAndRemoteFile_changeLocal() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");
    writeLocalFile(actionFs, path, "local-content");
    assertThat(actionFs.getPath(path).isReadable()).isTrue();
    assertThat(actionFs.getPath(path).isWritable()).isTrue();
    assertThat(actionFs.getPath(path).isExecutable()).isTrue();
    assertThat(getLocalFileSystem(actionFs).getPath(path).isReadable()).isTrue();
    assertThat(getLocalFileSystem(actionFs).getPath(path).isWritable()).isTrue();
    assertThat(getLocalFileSystem(actionFs).getPath(path).isExecutable()).isFalse();

    actionFs.getPath(path).chmod(0111);

    assertThat(actionFs.getPath(path).isReadable()).isTrue();
    assertThat(actionFs.getPath(path).isWritable()).isFalse();
    assertThat(actionFs.getPath(path).isExecutable()).isTrue();
    assertThat(getLocalFileSystem(actionFs).getPath(path).isReadable()).isFalse();
    assertThat(getLocalFileSystem(actionFs).getPath(path).isWritable()).isFalse();
    assertThat(getLocalFileSystem(actionFs).getPath(path).isExecutable()).isTrue();
  }

  @Test
  public void getLastModifiedTime_fileDoesNotExist_throwError() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");

    assertThrows(FileNotFoundException.class, () -> actionFs.getPath(path).getLastModifiedTime());
  }

  @Test
  public void getLastModifiedTime_onlyRemoteFile_returnRemote() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");

    var mtime = actionFs.getPath(path).getLastModifiedTime();

    assertThat(mtime).isEqualTo(getRemoteFileSystem(actionFs).getPath(path).getLastModifiedTime());
  }

  @Test
  public void getLastModifiedTime_onlyLocalFile_returnLocal() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    writeLocalFile(actionFs, path, "local-content");

    var mtime = actionFs.getPath(path).getLastModifiedTime();

    assertThat(mtime).isEqualTo(getLocalFileSystem(actionFs).getPath(path).getLastModifiedTime());
  }

  @Test
  public void getLastModifiedTime_localAndRemoteFile_returnRemote() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");
    writeLocalFile(actionFs, path, "local-content");

    var mtime = actionFs.getPath(path).getLastModifiedTime();

    assertThat(mtime).isEqualTo(getRemoteFileSystem(actionFs).getPath(path).getLastModifiedTime());
  }

  @Test
  public void setLastModifiedTime_fileDoesNotExist_throwError() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");

    assertThrows(FileNotFoundException.class, () -> actionFs.getPath(path).setLastModifiedTime(0));
  }

  @Test
  public void setLastModifiedTime_onlyRemoteFile_successfullySet() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");
    assertThat(actionFs.getPath(path).getLastModifiedTime()).isNotEqualTo(0);

    actionFs.getPath(path).setLastModifiedTime(0);

    assertThat(actionFs.getPath(path).getLastModifiedTime()).isEqualTo(0);
  }

  @Test
  public void setLastModifiedTime_onlyLocalFile_successfullySet() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    writeLocalFile(actionFs, path, "local-content");
    assertThat(actionFs.getPath(path).getLastModifiedTime()).isNotEqualTo(0);

    actionFs.getPath(path).setLastModifiedTime(0);

    assertThat(actionFs.getPath(path).getLastModifiedTime()).isEqualTo(0);
  }

  @Test
  public void setLastModifiedTime_localAndRemoteFile_changeBoth() throws IOException {
    var actionFs = createActionFileSystem();
    var path = getOutputPath("file");
    injectRemoteFile(actionFs, path, "remote-content");
    writeLocalFile(actionFs, path, "local-content");
    assertThat(getLocalFileSystem(actionFs).getPath(path).getLastModifiedTime()).isNotEqualTo(0);
    assertThat(getRemoteFileSystem(actionFs).getPath(path).getLastModifiedTime()).isNotEqualTo(0);

    actionFs.getPath(path).setLastModifiedTime(0);

    assertThat(getLocalFileSystem(actionFs).getPath(path).getLastModifiedTime()).isEqualTo(0);
    assertThat(getRemoteFileSystem(actionFs).getPath(path).getLastModifiedTime()).isEqualTo(0);
  }
}
