// Copyright 2017 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.exec;

import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.actions.FilesetManifest.RelativeSymlinkBehavior.ERROR;
import static com.google.devtools.build.lib.actions.FilesetManifest.RelativeSymlinkBehavior.IGNORE;
import static com.google.devtools.build.lib.actions.FilesetManifest.RelativeSymlinkBehavior.RESOLVE;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.verifyNoMoreInteractions;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.devtools.build.lib.actions.ActionInput;
import com.google.devtools.build.lib.actions.ActionInputHelper;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.Artifact.ArchivedTreeArtifact;
import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
import com.google.devtools.build.lib.actions.Artifact.SpecialArtifactType;
import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
import com.google.devtools.build.lib.actions.ArtifactRoot;
import com.google.devtools.build.lib.actions.ArtifactRoot.RootType;
import com.google.devtools.build.lib.actions.FilesetManifest;
import com.google.devtools.build.lib.actions.FilesetOutputSymlink;
import com.google.devtools.build.lib.actions.InputMetadataProvider;
import com.google.devtools.build.lib.actions.PathMapper;
import com.google.devtools.build.lib.actions.RunfilesTree;
import com.google.devtools.build.lib.actions.Spawn;
import com.google.devtools.build.lib.actions.cache.VirtualActionInput;
import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
import com.google.devtools.build.lib.analysis.Runfiles;
import com.google.devtools.build.lib.analysis.util.AnalysisTestUtil;
import com.google.devtools.build.lib.exec.SpawnInputExpander.InputSink;
import com.google.devtools.build.lib.exec.util.FakeActionInputFileCache;
import com.google.devtools.build.lib.exec.util.SpawnBuilder;
import com.google.devtools.build.lib.vfs.DigestHashFunction;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.Root;
import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
import java.io.IOException;
import java.util.Map;
import javax.annotation.Nullable;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link SpawnInputExpander}. */
@RunWith(JUnit4.class)
public final class SpawnInputExpanderTest {

  private static final ArtifactExpander NO_ARTIFACT_EXPANDER =
      artifact -> {
        throw new AssertionError(artifact);
      };

  private final FileSystem fs = new InMemoryFileSystem(DigestHashFunction.SHA256);
  private final Path execRoot = fs.getPath("/root");
  private final ArtifactRoot rootDir = ArtifactRoot.asDerivedRoot(execRoot, RootType.Output, "out");

  private SpawnInputExpander expander = new SpawnInputExpander(execRoot);
  private final InputSink inputSink = mock(InputSink.class);

  @After
  public void checkInputSinkVerified() {
    verifyNoMoreInteractions(inputSink);
  }

  @Test
  public void testRunfilesSingleFile() throws Exception {
    Artifact artifact =
        ActionsTestUtil.createArtifact(
            ArtifactRoot.asSourceRoot(Root.fromPath(fs.getPath("/root"))),
            fs.getPath("/root/dir/file"));
    Runfiles runfiles = new Runfiles.Builder("workspace").addArtifact(artifact).build();
    RunfilesTree runfilesTree =
        AnalysisTestUtil.createRunfilesTree(PathFragment.create("runfiles"), runfiles);

    expander.addSingleRunfilesTreeToInputs(
        runfilesTree,
        inputSink,
        NO_ARTIFACT_EXPANDER,
        PathMapper.NOOP,
        PathFragment.EMPTY_FRAGMENT);

    verify(inputSink)
        .acceptMapping(
            PathFragment.create("runfiles/workspace/dir/file"), artifact, /* owner= */ null);
  }

  @Test
  public void testRunfilesWithFileset() throws Exception {
    Artifact fileset = createFilesetArtifact("foo/biz/fs_out");
    Runfiles runfiles = new Runfiles.Builder("workspace").addArtifact(fileset).build();
    RunfilesTree runfilesTree =
        AnalysisTestUtil.createRunfilesTree(PathFragment.create("runfiles"), runfiles);

    ArtifactExpander filesetExpander =
        new ArtifactExpander() {
          @Override
          public ImmutableSortedSet<TreeFileArtifact> expandTreeArtifact(Artifact treeArtifact) {
            throw new IllegalStateException("Unexpected tree expansion");
          }

          @Override
          public ImmutableList<FilesetOutputSymlink> expandFileset(Artifact artifact) {
            return ImmutableList.of(
                FilesetOutputSymlink.createForTesting(
                    PathFragment.create("zizz"),
                    PathFragment.create("/foo/fake_exec/xyz/zizz"),
                    PathFragment.create("/foo/fake_exec/")));
          }
        };

    expander.addSingleRunfilesTreeToInputs(
        runfilesTree, inputSink, filesetExpander, PathMapper.NOOP, PathFragment.EMPTY_FRAGMENT);

    verify(inputSink)
        .acceptMapping(
            PathFragment.create("runfiles/workspace/foo/biz/fs_out/zizz"),
            ActionInputHelper.fromPath("/root/xyz/zizz"),
            fileset);
  }

  @Test
  public void testRunfilesDirectoryNonStrict() throws Exception {
    Artifact artifact =
        ActionsTestUtil.createArtifact(
            ArtifactRoot.asSourceRoot(Root.fromPath(fs.getPath("/root"))),
            fs.getPath("/root/dir/file"));
    Runfiles runfiles = new Runfiles.Builder("workspace").addArtifact(artifact).build();
    RunfilesTree runfilesTree =
        AnalysisTestUtil.createRunfilesTree(PathFragment.create("runfiles"), runfiles);

    expander.addSingleRunfilesTreeToInputs(
        runfilesTree,
        inputSink,
        NO_ARTIFACT_EXPANDER,
        PathMapper.NOOP,
        PathFragment.EMPTY_FRAGMENT);
    verify(inputSink)
        .acceptMapping(
            PathFragment.create("runfiles/workspace/dir/file"), artifact, /* owner= */ null);
  }

  @Test
  public void testRunfilesTwoFiles() throws Exception {
    Artifact artifact1 =
        ActionsTestUtil.createArtifact(
            ArtifactRoot.asSourceRoot(Root.fromPath(fs.getPath("/root"))),
            fs.getPath("/root/dir/file"));
    Artifact artifact2 =
        ActionsTestUtil.createArtifact(
            ArtifactRoot.asSourceRoot(Root.fromPath(fs.getPath("/root"))),
            fs.getPath("/root/dir/baz"));
    Runfiles runfiles =
        new Runfiles.Builder("workspace").addArtifact(artifact1).addArtifact(artifact2).build();
    RunfilesTree runfilesTree =
        AnalysisTestUtil.createRunfilesTree(PathFragment.create("runfiles"), runfiles);

    expander.addSingleRunfilesTreeToInputs(
        runfilesTree,
        inputSink,
        NO_ARTIFACT_EXPANDER,
        PathMapper.NOOP,
        PathFragment.EMPTY_FRAGMENT);
    verify(inputSink)
        .acceptMapping(
            PathFragment.create("runfiles/workspace/dir/file"), artifact1, /* owner= */ null);
    verify(inputSink)
        .acceptMapping(
            PathFragment.create("runfiles/workspace/dir/baz"), artifact2, /* owner= */ null);
  }

  @Test
  public void testRunfilesTwoFiles_pathMapped() throws Exception {
    Artifact artifact1 =
        ActionsTestUtil.createArtifact(
            ArtifactRoot.asSourceRoot(Root.fromPath(fs.getPath("/root"))),
            fs.getPath("/root/dir/file"));
    Artifact artifact2 =
        ActionsTestUtil.createArtifact(
            ArtifactRoot.asSourceRoot(Root.fromPath(fs.getPath("/root"))),
            fs.getPath("/root/dir/baz"));
    Runfiles runfiles =
        new Runfiles.Builder("workspace").addArtifact(artifact1).addArtifact(artifact2).build();
    RunfilesTree runfilesTree =
        AnalysisTestUtil.createRunfilesTree(
            PathFragment.create("bazel-out/k8-opt/bin/foo.runfiles"), runfiles);

    expander.addSingleRunfilesTreeToInputs(
        runfilesTree,
        inputSink,
        NO_ARTIFACT_EXPANDER,
        execPath -> PathFragment.create(execPath.getPathString().replace("k8-opt/", "")),
        PathFragment.EMPTY_FRAGMENT);

    verify(inputSink)
        .acceptMapping(
            PathFragment.create("bazel-out/bin/foo.runfiles/workspace/dir/file"),
            artifact1,
            /* owner= */ null);
    verify(inputSink)
        .acceptMapping(
            PathFragment.create("bazel-out/bin/foo.runfiles/workspace/dir/baz"),
            artifact2,
            /* owner= */ null);
  }

  @Test
  public void testRunfilesSymlink() throws Exception {
    Artifact artifact =
        ActionsTestUtil.createArtifact(
            ArtifactRoot.asSourceRoot(Root.fromPath(fs.getPath("/root"))),
            fs.getPath("/root/dir/file"));
    Runfiles runfiles =
        new Runfiles.Builder("workspace")
            .addSymlink(PathFragment.create("symlink"), artifact)
            .build();
    RunfilesTree runfilesTree =
        AnalysisTestUtil.createRunfilesTree(PathFragment.create("runfiles"), runfiles);

    expander.addSingleRunfilesTreeToInputs(
        runfilesTree,
        inputSink,
        NO_ARTIFACT_EXPANDER,
        PathMapper.NOOP,
        PathFragment.EMPTY_FRAGMENT);

    verify(inputSink)
        .acceptMapping(
            PathFragment.create("runfiles/workspace/symlink"), artifact, /* owner= */ null);
  }

  @Test
  public void testRunfilesRootSymlink() throws Exception {
    Artifact artifact =
        ActionsTestUtil.createArtifact(
            ArtifactRoot.asSourceRoot(Root.fromPath(fs.getPath("/root"))),
            fs.getPath("/root/dir/file"));
    Runfiles runfiles =
        new Runfiles.Builder("workspace")
            .addRootSymlink(PathFragment.create("symlink"), artifact)
            .build();
    RunfilesTree runfilesTree =
        AnalysisTestUtil.createRunfilesTree(PathFragment.create("runfiles"), runfiles);

    expander.addSingleRunfilesTreeToInputs(
        runfilesTree,
        inputSink,
        NO_ARTIFACT_EXPANDER,
        PathMapper.NOOP,
        PathFragment.EMPTY_FRAGMENT);

    verify(inputSink)
        .acceptMapping(PathFragment.create("runfiles/symlink"), artifact, /* owner= */ null);
    // If there's no other entry, Runfiles adds an empty file in the workspace to make sure the
    // directory gets created.
    verify(inputSink)
        .acceptMapping(
            PathFragment.create("runfiles/workspace/.runfile"),
            VirtualActionInput.EMPTY_MARKER,
            /* owner= */ null);
  }

  @Test
  public void testRunfilesWithTreeArtifacts() throws Exception {
    SpecialArtifact treeArtifact = createTreeArtifact("treeArtifact");
    TreeFileArtifact file1 = TreeFileArtifact.createTreeOutput(treeArtifact, "file1");
    TreeFileArtifact file2 = TreeFileArtifact.createTreeOutput(treeArtifact, "file2");
    FileSystemUtils.writeContentAsLatin1(file1.getPath(), "foo");
    FileSystemUtils.writeContentAsLatin1(file2.getPath(), "bar");

    Runfiles runfiles = new Runfiles.Builder("workspace").addArtifact(treeArtifact).build();
    ArtifactExpander artifactExpander =
        artifact ->
            artifact.equals(treeArtifact)
                ? ImmutableSortedSet.of(file1, file2)
                : ImmutableSortedSet.of();
    RunfilesTree runfilesTree =
        AnalysisTestUtil.createRunfilesTree(PathFragment.create("runfiles"), runfiles);

    expander.addSingleRunfilesTreeToInputs(
        runfilesTree, inputSink, artifactExpander, PathMapper.NOOP, PathFragment.EMPTY_FRAGMENT);

    verify(inputSink)
        .acceptMapping(
            PathFragment.create("runfiles/workspace/treeArtifact/file1"), file1, treeArtifact);
    verify(inputSink)
        .acceptMapping(
            PathFragment.create("runfiles/workspace/treeArtifact/file2"), file2, treeArtifact);
  }

  @Test
  public void testRunfilesWithTreeArtifacts_pathMapped() throws Exception {
    SpecialArtifact treeArtifact = createTreeArtifact("treeArtifact");
    TreeFileArtifact file1 = TreeFileArtifact.createTreeOutput(treeArtifact, "file1");
    TreeFileArtifact file2 = TreeFileArtifact.createTreeOutput(treeArtifact, "file2");
    FileSystemUtils.writeContentAsLatin1(file1.getPath(), "foo");
    FileSystemUtils.writeContentAsLatin1(file2.getPath(), "bar");

    Runfiles runfiles = new Runfiles.Builder("workspace").addArtifact(treeArtifact).build();
    ArtifactExpander artifactExpander =
        artifact ->
            artifact.equals(treeArtifact)
                ? ImmutableSortedSet.of(file1, file2)
                : ImmutableSortedSet.of();
    RunfilesTree runfilesTree =
        AnalysisTestUtil.createRunfilesTree(
            PathFragment.create("bazel-out/k8-opt/bin/foo.runfiles"), runfiles);

    PathMapper pathMapper =
        execPath -> {
          // Replace the config segment "k8-opt" in "bazel-bin/k8-opt/bin" with a hash of the full
          // path to verify that the new paths are constructed by appending the child paths to the
          // mapped parent path, not by mapping the child paths directly.
          PathFragment runfilesPath = execPath.subFragment(3);
          String runfilesPathHash =
              DigestHashFunction.SHA256
                  .getHashFunction()
                  .hashString(runfilesPath.getPathString(), UTF_8)
                  .toString();
          return execPath
              .subFragment(0, 1)
              .getRelative(runfilesPathHash.substring(0, 8))
              .getRelative(execPath.subFragment(2));
        };

    expander.addSingleRunfilesTreeToInputs(
        runfilesTree, inputSink, artifactExpander, pathMapper, PathFragment.EMPTY_FRAGMENT);

    verify(inputSink)
        .acceptMapping(
            PathFragment.create("bazel-out/2c26b46b/bin/foo.runfiles/workspace/treeArtifact/file1"),
            file1,
            treeArtifact);
    verify(inputSink)
        .acceptMapping(
            PathFragment.create("bazel-out/2c26b46b/bin/foo.runfiles/workspace/treeArtifact/file2"),
            file2,
            treeArtifact);
  }

  @Test
  public void testRunfilesWithArchivedTreeArtifacts() throws Exception {
    SpecialArtifact treeArtifact = createTreeArtifact("treeArtifact");
    ArchivedTreeArtifact archivedTreeArtifact = ArchivedTreeArtifact.createForTree(treeArtifact);

    Runfiles runfiles = new Runfiles.Builder("workspace").addArtifact(treeArtifact).build();
    ArtifactExpander artifactExpander =
        new ArtifactExpander() {
          @Override
          public ImmutableSortedSet<TreeFileArtifact> expandTreeArtifact(Artifact treeArtifact) {
            throw new IllegalStateException("Should not do expansion for archived tree");
          }

          @Nullable
          @Override
          public ArchivedTreeArtifact getArchivedTreeArtifact(Artifact treeArtifact) {
            return archivedTreeArtifact;
          }
        };
    RunfilesTree runfilesTree =
        AnalysisTestUtil.createRunfilesTree(PathFragment.create("runfiles"), runfiles);

    expander = new SpawnInputExpander(execRoot, IGNORE, /* expandArchivedTreeArtifacts= */ false);
    expander.addSingleRunfilesTreeToInputs(
        runfilesTree, inputSink, artifactExpander, PathMapper.NOOP, PathFragment.EMPTY_FRAGMENT);

    verify(inputSink)
        .acceptMapping(
            PathFragment.create("runfiles/workspace/treeArtifact"),
            archivedTreeArtifact,
            treeArtifact);
  }

  @Test
  public void testRunfilesWithTreeArtifactsInSymlinks() throws Exception {
    SpecialArtifact treeArtifact = createTreeArtifact("treeArtifact");
    TreeFileArtifact file1 = TreeFileArtifact.createTreeOutput(treeArtifact, "file1");
    TreeFileArtifact file2 = TreeFileArtifact.createTreeOutput(treeArtifact, "file2");
    FileSystemUtils.writeContentAsLatin1(file1.getPath(), "foo");
    FileSystemUtils.writeContentAsLatin1(file2.getPath(), "bar");
    Runfiles runfiles =
        new Runfiles.Builder("workspace")
            .addSymlink(PathFragment.create("symlink"), treeArtifact)
            .build();

    ArtifactExpander artifactExpander =
        artifact ->
            artifact.equals(treeArtifact)
                ? ImmutableSortedSet.of(file1, file2)
                : ImmutableSortedSet.of();
    RunfilesTree runfilesTree =
        AnalysisTestUtil.createRunfilesTree(PathFragment.create("runfiles"), runfiles);

    expander.addSingleRunfilesTreeToInputs(
        runfilesTree, inputSink, artifactExpander, PathMapper.NOOP, PathFragment.EMPTY_FRAGMENT);

    verify(inputSink)
        .acceptMapping(
            PathFragment.create("runfiles/workspace/symlink/file1"), file1, treeArtifact);
    verify(inputSink)
        .acceptMapping(
            PathFragment.create("runfiles/workspace/symlink/file2"), file2, treeArtifact);
  }

  @Test
  public void testTreeArtifactsInInputs() throws Exception {
    SpecialArtifact treeArtifact = createTreeArtifact("treeArtifact");
    TreeFileArtifact file1 = TreeFileArtifact.createTreeOutput(treeArtifact, "file1");
    TreeFileArtifact file2 = TreeFileArtifact.createTreeOutput(treeArtifact, "file2");
    InputMetadataProvider inputMetadataProvider = new FakeActionInputFileCache();
    FileSystemUtils.writeContentAsLatin1(file1.getPath(), "foo");
    FileSystemUtils.writeContentAsLatin1(file2.getPath(), "bar");

    ArtifactExpander artifactExpander =
        artifact ->
            artifact.equals(treeArtifact)
                ? ImmutableSortedSet.of(file1, file2)
                : ImmutableSortedSet.of();

    Spawn spawn = new SpawnBuilder("/bin/echo", "Hello World").withInput(treeArtifact).build();
    Map<PathFragment, ActionInput> inputMappings =
        expander.getInputMapping(
            spawn, artifactExpander, inputMetadataProvider, PathFragment.EMPTY_FRAGMENT);

    assertThat(inputMappings).hasSize(2);
    assertThat(inputMappings).containsEntry(PathFragment.create("out/treeArtifact/file1"), file1);
    assertThat(inputMappings).containsEntry(PathFragment.create("out/treeArtifact/file2"), file2);
  }

  private SpecialArtifact createTreeArtifact(String relPath) throws IOException {
    SpecialArtifact treeArtifact = createSpecialArtifact(relPath, SpecialArtifactType.TREE);
    treeArtifact.setGeneratingActionKey(ActionsTestUtil.NULL_ACTION_LOOKUP_DATA);
    return treeArtifact;
  }

  private SpecialArtifact createFilesetArtifact(String relPath) throws IOException {
    return createSpecialArtifact(relPath, SpecialArtifactType.FILESET);
  }

  private SpecialArtifact createSpecialArtifact(String relPath, SpecialArtifactType type)
      throws IOException {
    String outputSegment = "out";
    Path outputDir = execRoot.getRelative(outputSegment);
    Path outputPath = outputDir.getRelative(relPath);
    outputPath.createDirectoryAndParents();
    ArtifactRoot derivedRoot = ArtifactRoot.asDerivedRoot(execRoot, RootType.Output, outputSegment);
    return SpecialArtifact.create(
        derivedRoot,
        derivedRoot.getExecPath().getRelative(derivedRoot.getRoot().relativize(outputPath)),
        ActionsTestUtil.NULL_ARTIFACT_OWNER,
        type);
  }

  @Test
  public void testEmptyManifest() throws Exception {
    Map<Artifact, ImmutableList<FilesetOutputSymlink>> filesetMappings =
        ImmutableMap.of(createFileset("out"), ImmutableList.of());

    expander.addFilesetManifests(filesetMappings, inputSink, PathFragment.EMPTY_FRAGMENT);

    verifyNoInteractions(inputSink);
  }

  @Test
  public void testManifestWithSingleFile() throws Exception {
    Artifact fileset = createFileset("out");
    Map<Artifact, ImmutableList<FilesetOutputSymlink>> filesetMappings =
        ImmutableMap.of(fileset, ImmutableList.of(filesetSymlink("foo/bar", "/dir/file")));

    expander.addFilesetManifests(filesetMappings, inputSink, PathFragment.EMPTY_FRAGMENT);

    verify(inputSink)
        .acceptMapping(
            PathFragment.create("out/foo/bar"), ActionInputHelper.fromPath("/dir/file"), fileset);
  }

  @Test
  public void testManifestWithTwoFiles() throws Exception {
    Artifact fileset = createFileset("out");
    Map<Artifact, ImmutableList<FilesetOutputSymlink>> filesetMappings =
        ImmutableMap.of(
            fileset,
            ImmutableList.of(
                filesetSymlink("foo/bar", "/dir/file"), filesetSymlink("foo/baz", "/dir/file")));

    expander.addFilesetManifests(filesetMappings, inputSink, PathFragment.EMPTY_FRAGMENT);

    verify(inputSink)
        .acceptMapping(
            PathFragment.create("out/foo/bar"), ActionInputHelper.fromPath("/dir/file"), fileset);
    verify(inputSink)
        .acceptMapping(
            PathFragment.create("out/foo/baz"), ActionInputHelper.fromPath("/dir/file"), fileset);
  }

  @Test
  public void testManifestWithDirectory() throws Exception {
    Artifact fileset = createFileset("out");
    Map<Artifact, ImmutableList<FilesetOutputSymlink>> filesetMappings =
        ImmutableMap.of(fileset, ImmutableList.of(filesetSymlink("foo/bar", "/some")));

    expander.addFilesetManifests(filesetMappings, inputSink, PathFragment.EMPTY_FRAGMENT);

    verify(inputSink)
        .acceptMapping(
            PathFragment.create("out/foo/bar"), ActionInputHelper.fromPath("/some"), fileset);
  }

  private static FilesetOutputSymlink filesetSymlink(String from, String to) {
    return FilesetOutputSymlink.createForTesting(
        PathFragment.create(from), PathFragment.create(to), PathFragment.create("/root"));
  }

  private SpecialArtifact createFileset(String execPath) {
    return SpecialArtifact.create(
        rootDir,
        PathFragment.create(execPath),
        ActionsTestUtil.NULL_ARTIFACT_OWNER,
        SpecialArtifactType.FILESET);
  }

  @Test
  public void testManifestWithErrorOnRelativeSymlink() {
    expander = new SpawnInputExpander(execRoot, ERROR);
    Artifact fileset = createFileset("out");
    ImmutableMap<Artifact, ImmutableList<FilesetOutputSymlink>> filesetMappings =
        ImmutableMap.of(
            fileset,
            ImmutableList.of(
                filesetSymlink("workspace/bar", "foo"),
                filesetSymlink("workspace/foo", "/root/bar")));

    FilesetManifest.ForbiddenRelativeSymlinkException e =
        assertThrows(
            FilesetManifest.ForbiddenRelativeSymlinkException.class,
            () ->
                expander.addFilesetManifests(
                    filesetMappings, inputSink, PathFragment.EMPTY_FRAGMENT));

    assertThat(e).hasMessageThat().contains("Fileset symlink foo is not absolute");
  }

  @Test
  public void testManifestWithIgnoredRelativeSymlink() throws Exception {
    expander = new SpawnInputExpander(execRoot, IGNORE);
    Artifact fileset = createFileset("out");
    ImmutableMap<Artifact, ImmutableList<FilesetOutputSymlink>> filesetMappings =
        ImmutableMap.of(
            fileset,
            ImmutableList.of(
                filesetSymlink("workspace/bar", "foo"),
                filesetSymlink("workspace/foo", "/root/bar")));

    expander.addFilesetManifests(filesetMappings, inputSink, PathFragment.EMPTY_FRAGMENT);

    verify(inputSink)
        .acceptMapping(
            PathFragment.create("out/workspace/foo"),
            ActionInputHelper.fromPath("/root/bar"),
            fileset);
  }

  @Test
  public void testManifestWithResolvedRelativeSymlink() throws Exception {
    expander = new SpawnInputExpander(execRoot, RESOLVE);
    Artifact fileset = createFileset("out");
    ImmutableMap<Artifact, ImmutableList<FilesetOutputSymlink>> filesetMappings =
        ImmutableMap.of(
            fileset,
            ImmutableList.of(
                filesetSymlink("workspace/bar", "foo"),
                filesetSymlink("workspace/foo", "/root/bar")));

    expander.addFilesetManifests(filesetMappings, inputSink, PathFragment.EMPTY_FRAGMENT);

    verify(inputSink)
        .acceptMapping(
            PathFragment.create("out/workspace/bar"),
            ActionInputHelper.fromPath("/root/bar"),
            fileset);
    verify(inputSink)
        .acceptMapping(
            PathFragment.create("out/workspace/foo"),
            ActionInputHelper.fromPath("/root/bar"),
            fileset);
  }
}
