// Copyright 2016 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.skyframe;

import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertThrows;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.hash.Hashing;
import com.google.devtools.build.lib.actions.Action;
import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
import com.google.devtools.build.lib.actions.ActionExecutionContext;
import com.google.devtools.build.lib.actions.ActionExecutionException;
import com.google.devtools.build.lib.actions.ActionKeyContext;
import com.google.devtools.build.lib.actions.ActionLookupData;
import com.google.devtools.build.lib.actions.ActionLookupValue.ActionLookupKey;
import com.google.devtools.build.lib.actions.ActionResult;
import com.google.devtools.build.lib.actions.Actions;
import com.google.devtools.build.lib.actions.Artifact;
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.BuildFailedException;
import com.google.devtools.build.lib.actions.FileArtifactValue;
import com.google.devtools.build.lib.actions.FileArtifactValue.RemoteFileArtifactValue;
import com.google.devtools.build.lib.actions.MetadataProvider;
import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
import com.google.devtools.build.lib.actions.cache.MetadataHandler;
import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
import com.google.devtools.build.lib.actions.util.TestAction;
import com.google.devtools.build.lib.actions.util.TestAction.DummyAction;
import com.google.devtools.build.lib.analysis.actions.SpawnActionTemplate;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventCollector;
import com.google.devtools.build.lib.events.EventKind;
import com.google.devtools.build.lib.server.FailureDetails.Crash;
import com.google.devtools.build.lib.server.FailureDetails.Crash.Code;
import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
import com.google.devtools.build.lib.skyframe.ActionTemplateExpansionValue.ActionTemplateExpansionKey;
import com.google.devtools.build.lib.skyframe.serialization.testutils.SerializationDepsUtils;
import com.google.devtools.build.lib.skyframe.serialization.testutils.SerializationTester;
import com.google.devtools.build.lib.testutil.TestUtils;
import com.google.devtools.build.lib.util.CrashFailureDetails;
import com.google.devtools.build.lib.util.DetailedExitCode;
import com.google.devtools.build.lib.vfs.FileStatus;
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.Symlinks;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Timestamp builder tests for TreeArtifacts. */
@RunWith(JUnit4.class)
public final class TreeArtifactBuildTest extends TimestampBuilderTestCase {

  @Test
  public void codec() throws Exception {
    SpecialArtifact parent = createTreeArtifact("parent");
    parent.setGeneratingActionKey(ActionLookupData.create(ACTION_LOOKUP_KEY, 0));
    new SerializationTester(parent, TreeFileArtifact.createTreeOutput(parent, "child"))
        .addDependency(FileSystem.class, scratch.getFileSystem())
        .addDependency(
            Root.RootCodecDependencies.class,
            new Root.RootCodecDependencies(Root.absoluteRoot(scratch.getFileSystem())))
        .addDependencies(SerializationDepsUtils.SERIALIZATION_DEPS_FOR_TEST)
        .runTests();
  }

  /** Simple smoke test. If this isn't passing, something is very wrong... */
  @Test
  public void treeArtifactSimpleCase() throws Exception {
    SpecialArtifact parent = createTreeArtifact("parent");
    TouchingTestAction action = new TouchingTestAction(parent, "out1", "out2");
    registerAction(action);

    TreeArtifactValue result = buildArtifact(parent);

    verifyOutputTree(result, parent, "out1", "out2");
  }

  /** Simple test for the case with dependencies. */
  @Test
  public void dependentTreeArtifacts() throws Exception {
    SpecialArtifact tree1 = createTreeArtifact("tree1");
    TouchingTestAction action1 = new TouchingTestAction(tree1, "out1", "out2");
    registerAction(action1);

    SpecialArtifact tree2 = createTreeArtifact("tree2");
    CopyTreeAction action2 = new CopyTreeAction(tree1, tree2);
    registerAction(action2);

    TreeArtifactValue result = buildArtifact(tree2);

    assertThat(tree1.getPath().getRelative("out1").exists()).isTrue();
    assertThat(tree1.getPath().getRelative("out2").exists()).isTrue();
    verifyOutputTree(result, tree2, "out1", "out2");
  }

  /** Test for tree artifacts with sub directories. */
  @Test
  public void treeArtifactWithSubDirectory() throws Exception {
    SpecialArtifact parent = createTreeArtifact("parent");
    TouchingTestAction action = new TouchingTestAction(parent, "sub1/file1", "sub2/file2");
    registerAction(action);

    TreeArtifactValue result = buildArtifact(parent);

    verifyOutputTree(result, parent, "sub1/file1", "sub2/file2");
  }

  @Test
  public void inputTreeArtifactMetadataProvider() throws Exception {
    SpecialArtifact treeArtifactInput = createTreeArtifact("tree");
    TouchingTestAction action1 = new TouchingTestAction(treeArtifactInput, "out1", "out2");
    registerAction(action1);

    Artifact normalOutput = createDerivedArtifact("normal/out");
    Action testAction =
        new SimpleTestAction(ImmutableList.of(treeArtifactInput), normalOutput) {
          @Override
          void run(ActionExecutionContext actionExecutionContext) throws IOException {
            // Check the metadata provider for input TreeFileArtifacts.
            MetadataProvider metadataProvider = actionExecutionContext.getMetadataProvider();
            assertThat(
                    metadataProvider
                        .getMetadata(TreeFileArtifact.createTreeOutput(treeArtifactInput, "out1"))
                        .getType()
                        .isFile())
                .isTrue();
            assertThat(
                    metadataProvider
                        .getMetadata(TreeFileArtifact.createTreeOutput(treeArtifactInput, "out2"))
                        .getType()
                        .isFile())
                .isTrue();

            // Touch the action output.
            touchFile(normalOutput);
          }
        };

    registerAction(testAction);
    buildArtifact(normalOutput);
  }

  /** Unchanged TreeArtifact outputs should not cause reexecution. */
  @Test
  public void cacheCheckingForTreeArtifactsDoesNotCauseReexecution() throws Exception {
    SpecialArtifact out1 = createTreeArtifact("out1");
    Button button1 = new Button();

    SpecialArtifact out2 = createTreeArtifact("out2");
    Button button2 = new Button();

    TouchingTestAction action1 = new TouchingTestAction(button1, out1, "file_one", "file_two");
    registerAction(action1);

    CopyTreeAction action2 = new CopyTreeAction(button2, out1, out2);
    registerAction(action2);

    button1.pressed = false;
    button2.pressed = false;
    buildArtifact(out2);
    assertThat(button1.pressed).isTrue(); // built
    assertThat(button2.pressed).isTrue(); // built

    button1.pressed = false;
    button2.pressed = false;
    buildArtifact(out2);
    assertThat(button1.pressed).isFalse(); // not built
    assertThat(button2.pressed).isFalse(); // not built
  }

  /** Test rebuilding TreeArtifacts for inputs, outputs, and dependents. Also a test for caching. */
  @Test
  public void transitiveReexecutionForTreeArtifacts() throws Exception {
    Artifact in = createSourceArtifact("input");
    writeFile(in, "input content");

    Button button1 = new Button();
    SpecialArtifact out1 = createTreeArtifact("output1");
    WriteInputToFilesAction action1 =
        new WriteInputToFilesAction(button1, in, out1, "file1", "file2");
    registerAction(action1);

    Button button2 = new Button();
    SpecialArtifact out2 = createTreeArtifact("output2");
    CopyTreeAction action2 = new CopyTreeAction(button2, out1, out2);
    registerAction(action2);

    button1.pressed = false;
    button2.pressed = false;
    buildArtifact(out2);
    assertThat(button1.pressed).isTrue(); // built
    assertThat(button2.pressed).isTrue(); // built

    button1.pressed = false;
    button2.pressed = false;
    writeFile(in, "modified input");
    buildArtifact(out2);
    assertThat(button1.pressed).isTrue(); // built
    assertThat(button2.pressed).isTrue(); // built

    button1.pressed = false;
    button2.pressed = false;
    writeFile(TreeFileArtifact.createTreeOutput(out1, "file1"), "modified output");
    buildArtifact(out2);
    assertThat(button1.pressed).isTrue(); // built
    assertThat(button2.pressed).isFalse(); // should have been cached

    button1.pressed = false;
    button2.pressed = false;
    writeFile(TreeFileArtifact.createTreeOutput(out2, "file1"), "more modified output");
    buildArtifact(out2);
    assertThat(button1.pressed).isFalse(); // not built
    assertThat(button2.pressed).isTrue(); // built
  }

  /** Tests that changing a TreeArtifact directory should cause reexeuction. */
  @Test
  public void directoryContentsCachingForTreeArtifacts() throws Exception {
    Artifact in = createSourceArtifact("input");
    writeFile(in, "input content");

    Button button1 = new Button();
    SpecialArtifact out1 = createTreeArtifact("output1");
    WriteInputToFilesAction action1 =
        new WriteInputToFilesAction(button1, in, out1, "file1", "file2");
    registerAction(action1);

    Button button2 = new Button();
    SpecialArtifact out2 = createTreeArtifact("output2");
    CopyTreeAction action2 = new CopyTreeAction(button2, out1, out2);
    registerAction(action2);

    button1.pressed = false;
    button2.pressed = false;
    buildArtifact(out2);
    // just a smoke test--if these aren't built we have bigger problems!
    assertThat(button1.pressed).isTrue();
    assertThat(button2.pressed).isTrue();

    // Adding a file to a directory should cause reexecution.
    button1.pressed = false;
    button2.pressed = false;
    Path spuriousOutputOne = out1.getPath().getRelative("spuriousOutput");
    touchFile(spuriousOutputOne);
    buildArtifact(out2);
    // Should re-execute, and delete spurious output
    assertThat(spuriousOutputOne.exists()).isFalse();
    assertThat(button1.pressed).isTrue();
    assertThat(button2.pressed).isFalse(); // should have been cached

    button1.pressed = false;
    button2.pressed = false;
    Path spuriousOutputTwo = out2.getPath().getRelative("anotherSpuriousOutput");
    touchFile(spuriousOutputTwo);
    buildArtifact(out2);
    assertThat(spuriousOutputTwo.exists()).isFalse();
    assertThat(button1.pressed).isFalse();
    assertThat(button2.pressed).isTrue();

    // Deleting should cause reexecution.
    button1.pressed = false;
    button2.pressed = false;
    TreeFileArtifact out1File1 = TreeFileArtifact.createTreeOutput(out1, "file1");
    deleteFile(out1File1);
    buildArtifact(out2);
    assertThat(out1File1.getPath().exists()).isTrue();
    assertThat(button1.pressed).isTrue();
    assertThat(button2.pressed).isFalse(); // should have been cached

    button1.pressed = false;
    button2.pressed = false;
    TreeFileArtifact out2File1 = TreeFileArtifact.createTreeOutput(out2, "file1");
    deleteFile(out2File1);
    buildArtifact(out2);
    assertThat(out2File1.getPath().exists()).isTrue();
    assertThat(button1.pressed).isFalse();
    assertThat(button2.pressed).isTrue();
  }

  /** TreeArtifacts don't care about mtime, even when the file is empty. */
  @Test
  public void mTimeForTreeArtifactsDoesNotMatter() throws Exception {
    // For this test, we only touch the input file.
    Artifact in = createSourceArtifact("touchable_input");
    touchFile(in);

    Button button1 = new Button();
    SpecialArtifact out1 = createTreeArtifact("output1");
    WriteInputToFilesAction action1 =
        new WriteInputToFilesAction(button1, in, out1, "file1", "file2");
    registerAction(action1);

    Button button2 = new Button();
    SpecialArtifact out2 = createTreeArtifact("output2");
    CopyTreeAction action2 = new CopyTreeAction(button2, out1, out2);
    registerAction(action2);

    button1.pressed = false;
    button2.pressed = false;
    buildArtifact(out2);
    assertThat(button1.pressed).isTrue(); // built
    assertThat(button2.pressed).isTrue(); // built

    button1.pressed = false;
    button2.pressed = false;
    touchFile(in);
    buildArtifact(out2);
    // mtime does not matter.
    assertThat(button1.pressed).isFalse();
    assertThat(button2.pressed).isFalse();

    // None of the below following should result in anything being built.
    button1.pressed = false;
    button2.pressed = false;
    touchFile(TreeFileArtifact.createTreeOutput(out1, "file1"));
    buildArtifact(out2);
    // Nothing should be built.
    assertThat(button1.pressed).isFalse();
    assertThat(button2.pressed).isFalse();

    button1.pressed = false;
    button2.pressed = false;
    touchFile(TreeFileArtifact.createTreeOutput(out1, "file2"));
    buildArtifact(out2);
    // Nothing should be built.
    assertThat(button1.pressed).isFalse();
    assertThat(button2.pressed).isFalse();
  }

  private static void checkDirectoryPermissions(Path path) throws IOException {
    assertThat(path.isDirectory()).isTrue();
    assertThat(path.isExecutable()).isTrue();
    assertThat(path.isReadable()).isTrue();
    assertThat(path.isWritable()).isFalse();
  }

  private static void checkFilePermissions(Path path) throws IOException {
    assertThat(path.isDirectory()).isFalse();
    assertThat(path.isExecutable()).isTrue();
    assertThat(path.isReadable()).isTrue();
    assertThat(path.isWritable()).isFalse();
  }

  @Test
  public void outputsAreReadOnlyAndExecutable() throws Exception {
    SpecialArtifact out = createTreeArtifact("output");

    Action action =
        new SimpleTestAction(out) {
          @Override
          void run(ActionExecutionContext context) throws IOException {
            writeFile(out.getPath().getChild("one"), "one");
            writeFile(out.getPath().getChild("two"), "two");
            writeFile(out.getPath().getChild("three").getChild("four"), "three/four");
          }
        };

    registerAction(action);
    buildArtifact(out);

    checkDirectoryPermissions(out.getPath());
    checkFilePermissions(out.getPath().getChild("one"));
    checkFilePermissions(out.getPath().getChild("two"));
    checkDirectoryPermissions(out.getPath().getChild("three"));
    checkFilePermissions(out.getPath().getChild("three").getChild("four"));
  }

  @Test
  public void validRelativeSymlinkAccepted() throws Exception {
    SpecialArtifact out = createTreeArtifact("output");

    Action action =
        new SimpleTestAction(out) {
          @Override
          void run(ActionExecutionContext actionExecutionContext) throws IOException {
            writeFile(out.getPath().getChild("one"), "one");
            writeFile(out.getPath().getChild("two"), "two");
            FileSystemUtils.ensureSymbolicLink(
                out.getPath().getChild("links").getChild("link"), "../one");
          }
        };

    registerAction(action);
    buildArtifact(out);
  }

  @Test
  public void invalidSymlinkRejected() {
    // Failure expected
    EventCollector eventCollector = new EventCollector(EventKind.ERROR);
    reporter.removeHandler(failFastHandler);
    reporter.addHandler(eventCollector);

    SpecialArtifact out = createTreeArtifact("output");

    Action action =
        new SimpleTestAction(out) {
          @Override
          void run(ActionExecutionContext actionExecutionContext) throws IOException {
            writeFile(out.getPath().getChild("one"), "one");
            writeFile(out.getPath().getChild("two"), "two");
            FileSystemUtils.ensureSymbolicLink(
                out.getPath().getChild("links").getChild("link"), "../invalid");
          }
        };

    registerAction(action);
    assertThrows(BuildFailedException.class, () -> buildArtifact(out));

    List<Event> errors = ImmutableList.copyOf(eventCollector);
    assertThat(errors).hasSize(2);
    assertThat(errors.get(0).getMessage()).contains("Failed to resolve relative path links/link");
    assertThat(errors.get(1).getMessage()).contains("not all outputs were created or valid");
  }

  @Test
  public void absoluteSymlinkBadTargetRejected() {
    // Failure expected
    EventCollector eventCollector = new EventCollector(EventKind.ERROR);
    reporter.removeHandler(failFastHandler);
    reporter.addHandler(eventCollector);

    SpecialArtifact out = createTreeArtifact("output");

    Action action =
        new SimpleTestAction(out) {
          @Override
          void run(ActionExecutionContext actionExecutionContext) throws IOException {
            writeFile(out.getPath().getChild("one"), "one");
            writeFile(out.getPath().getChild("two"), "two");
            FileSystemUtils.ensureSymbolicLink(
                out.getPath().getChild("links").getChild("link"), "/random/pointer");
          }
        };

    registerAction(action);
    assertThrows(BuildFailedException.class, () -> buildArtifact(out));

    List<Event> errors = ImmutableList.copyOf(eventCollector);
    assertThat(errors).hasSize(2);
    assertThat(errors.get(0).getMessage()).contains("Failed to resolve relative path links/link");
    assertThat(errors.get(1).getMessage()).contains("not all outputs were created or valid");
  }

  @Test
  public void absoluteSymlinkAccepted() throws Exception {
    scratch.overwriteFile("/random/pointer");

    SpecialArtifact out = createTreeArtifact("output");

    Action action =
        new SimpleTestAction(out) {
          @Override
          void run(ActionExecutionContext actionExecutionContext) throws IOException {
            writeFile(out.getPath().getChild("one"), "one");
            writeFile(out.getPath().getChild("two"), "two");
            FileSystemUtils.ensureSymbolicLink(
                out.getPath().getChild("links").getChild("link"), "/random/pointer");
          }
        };

    registerAction(action);
    buildArtifact(out);
  }

  @Test
  public void relativeSymlinkTraversingOutsideOfTreeArtifactRejected() {
    // Failure expected
    EventCollector eventCollector = new EventCollector(EventKind.ERROR);
    reporter.removeHandler(failFastHandler);
    reporter.addHandler(eventCollector);

    SpecialArtifact out = createTreeArtifact("output");

    Action action =
        new SimpleTestAction(out) {
          @Override
          void run(ActionExecutionContext actionExecutionContext) throws IOException {
            writeFile(out.getPath().getChild("one"), "one");
            writeFile(out.getPath().getChild("two"), "two");
            FileSystemUtils.ensureSymbolicLink(
                out.getPath().getChild("links").getChild("link"), "../../output/random/pointer");
          }
        };

    registerAction(action);

    assertThrows(BuildFailedException.class, () -> buildArtifact(out));
    List<Event> errors = ImmutableList.copyOf(eventCollector);
    assertThat(errors).hasSize(2);
    assertThat(errors.get(0).getMessage())
        .contains(
            "A TreeArtifact may not contain relative symlinks whose target paths traverse "
                + "outside of the TreeArtifact");
    assertThat(errors.get(1).getMessage()).contains("not all outputs were created or valid");
  }

  @Test
  public void relativeSymlinkTraversingToDirOutsideOfTreeArtifactRejected() throws Exception {
    // Failure expected
    EventCollector eventCollector = new EventCollector(EventKind.ERROR);
    reporter.removeHandler(failFastHandler);
    reporter.addHandler(eventCollector);

    SpecialArtifact out = createTreeArtifact("output");

    // Create a valid directory that can be referenced
    scratch.dir(out.getRoot().getRoot().getRelative("some/dir").getPathString());

    TestAction action =
        new SimpleTestAction(out) {
          @Override
          void run(ActionExecutionContext actionExecutionContext) throws IOException {
            writeFile(out.getPath().getChild("one"), "one");
            writeFile(out.getPath().getChild("two"), "two");
            FileSystemUtils.ensureSymbolicLink(
                out.getPath().getChild("links").getChild("link"), "../../some/dir");
          }
        };

    registerAction(action);

    assertThrows(BuildFailedException.class, () -> buildArtifact(out));
    List<Event> errors = ImmutableList.copyOf(eventCollector);
    assertThat(errors).hasSize(2);
    assertThat(errors.get(0).getMessage())
        .contains(
            "A TreeArtifact may not contain relative symlinks whose target paths traverse "
                + "outside of the TreeArtifact");
    assertThat(errors.get(1).getMessage()).contains("not all outputs were created or valid");
  }

  @Test
  public void constructMetadataForDigest() throws Exception {
    SpecialArtifact out = createTreeArtifact("output");
    Action action =
        new SimpleTestAction(out) {
          @Override
          void run(ActionExecutionContext actionExecutionContext) throws IOException {
            TreeFileArtifact child1 = TreeFileArtifact.createTreeOutput(out, "one");
            TreeFileArtifact child2 = TreeFileArtifact.createTreeOutput(out, "two");
            writeFile(child1, "one");
            writeFile(child2, "two");

            MetadataHandler md = actionExecutionContext.getMetadataHandler();
            FileStatus stat = child1.getPath().stat(Symlinks.NOFOLLOW);
            FileArtifactValue metadata1 =
                md.constructMetadataForDigest(
                    child1, stat, Hashing.sha256().hashString("one", UTF_8).asBytes());

            stat = child2.getPath().stat(Symlinks.NOFOLLOW);
            FileArtifactValue metadata2 =
                md.constructMetadataForDigest(
                    child2, stat, Hashing.sha256().hashString("two", UTF_8).asBytes());

            // The metadata will not be equal to reading from the filesystem since the filesystem
            // won't have the digest. However, we should be able to detect that nothing could have
            // been modified.
            assertThat(
                    metadata1.couldBeModifiedSince(
                        FileArtifactValue.createForTesting(child1.getPath())))
                .isFalse();
            assertThat(
                    metadata2.couldBeModifiedSince(
                        FileArtifactValue.createForTesting(child2.getPath())))
                .isFalse();
          }
        };

    registerAction(action);
    buildArtifact(out);
  }

  @Test
  public void remoteDirectoryInjection() throws Exception {
    SpecialArtifact out = createTreeArtifact("output");
    RemoteFileArtifactValue remoteFile1 =
        new RemoteFileArtifactValue(
            Hashing.sha256().hashString("one", UTF_8).asBytes(), /*size=*/ 3, /*locationIndex=*/ 1);
    RemoteFileArtifactValue remoteFile2 =
        new RemoteFileArtifactValue(
            Hashing.sha256().hashString("two", UTF_8).asBytes(), /*size=*/ 3, /*locationIndex=*/ 2);

    Action action =
        new SimpleTestAction(out) {
          @Override
          void run(ActionExecutionContext actionExecutionContext) throws IOException {
            TreeFileArtifact child1 = TreeFileArtifact.createTreeOutput(out, "one");
            TreeFileArtifact child2 = TreeFileArtifact.createTreeOutput(out, "two");
            writeFile(child1, "one");
            writeFile(child2, "two");

            actionExecutionContext
                .getMetadataHandler()
                .injectDirectory(out, ImmutableMap.of(child1, remoteFile1, child2, remoteFile2));
          }
        };

    registerAction(action);
    TreeArtifactValue result = buildArtifact(out);

    assertThat(result.getChildValues())
        .containsExactly(
            TreeFileArtifact.createTreeOutput(out, "one"),
            remoteFile1,
            TreeFileArtifact.createTreeOutput(out, "two"),
            remoteFile2);
  }

  @Test
  public void expandedActionsBuildInActionTemplate() throws Exception {
    // artifact1 is a tree artifact generated by a TouchingTestAction.
    SpecialArtifact artifact1 = createTreeArtifact("treeArtifact1");
    registerAction(new TouchingTestAction(artifact1, "file1", "file2"));

    // artifact2 is a tree artifact generated by an action template.
    SpecialArtifact artifact2 = createTreeArtifact("treeArtifact2");
    SpawnActionTemplate actionTemplate =
        ActionsTestUtil.createDummySpawnActionTemplate(artifact1, artifact2);
    registerAction(actionTemplate);

    // We mock out the action template function to expand into two actions that just touch the
    // output files.
    ActionTemplateExpansionKey secondOwner = ActionTemplateExpansionValue.key(ACTION_LOOKUP_KEY, 1);
    TreeFileArtifact expectedExpansionOutput1 =
        TreeFileArtifact.createTemplateExpansionOutput(artifact2, "child1", secondOwner);
    TreeFileArtifact expectedExpansionOutput2 =
        TreeFileArtifact.createTemplateExpansionOutput(artifact2, "child2", secondOwner);
    Action expandedAction1 =
        new DummyAction(
            TreeFileArtifact.createTreeOutput(artifact1, "file1"), expectedExpansionOutput1);
    Action expandedAction2 =
        new DummyAction(
            TreeFileArtifact.createTreeOutput(artifact1, "file2"), expectedExpansionOutput2);

    actionTemplateExpansionFunction =
        new DummyActionTemplateExpansionFunction(
            actionKeyContext, ImmutableList.of(expandedAction1, expandedAction2));

    TreeArtifactValue result = buildArtifact(artifact2);

    assertThat(result.getChildren())
        .containsExactly(expectedExpansionOutput1, expectedExpansionOutput2);
  }

  @Test
  public void expandedActionDoesNotGenerateOutputInActionTemplate() {
    // expect errors
    reporter.removeHandler(failFastHandler);

    // artifact1 is a tree artifact generated by a TouchingTestAction.
    SpecialArtifact artifact1 = createTreeArtifact("treeArtifact1");
    registerAction(new TouchingTestAction(artifact1, "child1", "child2"));

    // artifact2 is a tree artifact generated by an action template.
    SpecialArtifact artifact2 = createTreeArtifact("treeArtifact2");
    SpawnActionTemplate actionTemplate =
        ActionsTestUtil.createDummySpawnActionTemplate(artifact1, artifact2);
    registerAction(actionTemplate);

    // We mock out the action template function to expand into two actions:
    // One Action that touches the output file.
    // The other action that does not generate the output file.
    ActionTemplateExpansionKey secondOwner = ActionTemplateExpansionKey.of(ACTION_LOOKUP_KEY, 1);
    TreeFileArtifact expectedExpansionOutput1 =
        TreeFileArtifact.createTemplateExpansionOutput(artifact2, "child1", secondOwner);
    TreeFileArtifact expectedExpansionOutput2 =
        TreeFileArtifact.createTemplateExpansionOutput(artifact2, "child2", secondOwner);
    Action generateOutputAction =
        new DummyAction(
            TreeFileArtifact.createTreeOutput(artifact1, "child1"), expectedExpansionOutput1);
    Action noGenerateOutputAction =
        new NoOpDummyAction(
            TreeFileArtifact.createTreeOutput(artifact1, "child2"), expectedExpansionOutput2);

    actionTemplateExpansionFunction =
        new DummyActionTemplateExpansionFunction(
            actionKeyContext, ImmutableList.of(generateOutputAction, noGenerateOutputAction));

    BuildFailedException e =
        assertThrows(BuildFailedException.class, () -> buildArtifact(artifact2));
    assertThat(e).hasMessageThat().contains("not all outputs were created or valid");
  }

  @Test
  public void oneExpandedActionThrowsInActionTemplate() {
    // expect errors
    reporter.removeHandler(failFastHandler);

    // artifact1 is a tree artifact generated by a TouchingTestAction.
    SpecialArtifact artifact1 = createTreeArtifact("treeArtifact1");
    registerAction(new TouchingTestAction(artifact1, "child1", "child2"));

    // artifact2 is a tree artifact generated by an action template.
    SpecialArtifact artifact2 = createTreeArtifact("treeArtifact2");
    SpawnActionTemplate actionTemplate =
        ActionsTestUtil.createDummySpawnActionTemplate(artifact1, artifact2);
    registerAction(actionTemplate);

    // We mock out the action template function to expand into two actions:
    // One Action that touches the output file.
    // The other action that just throws when executed.
    ActionTemplateExpansionKey secondOwner = ActionTemplateExpansionKey.of(ACTION_LOOKUP_KEY, 1);
    TreeFileArtifact expectedExpansionOutput1 =
        TreeFileArtifact.createTemplateExpansionOutput(artifact2, "child1", secondOwner);
    TreeFileArtifact expectedExpansionOutput2 =
        TreeFileArtifact.createTemplateExpansionOutput(artifact2, "child2", secondOwner);
    Action generateOutputAction =
        new DummyAction(
            TreeFileArtifact.createTreeOutput(artifact1, "child1"), expectedExpansionOutput1);
    Action throwingAction =
        new ThrowingDummyAction(
            TreeFileArtifact.createTreeOutput(artifact1, "child2"), expectedExpansionOutput2);

    actionTemplateExpansionFunction =
        new DummyActionTemplateExpansionFunction(
            actionKeyContext, ImmutableList.of(generateOutputAction, throwingAction));

    BuildFailedException e =
        assertThrows(BuildFailedException.class, () -> buildArtifact(artifact2));
    assertThat(e).hasMessageThat().contains("Throwing dummy action");
  }

  @Test
  public void allExpandedActionsThrowInActionTemplate() {
    // expect errors
    reporter.removeHandler(failFastHandler);

    // artifact1 is a tree artifact generated by a TouchingTestAction.
    SpecialArtifact artifact1 = createTreeArtifact("treeArtifact1");
    registerAction(new TouchingTestAction(artifact1, "child1", "child2"));

    // artifact2 is a tree artifact generated by an action template.
    SpecialArtifact artifact2 = createTreeArtifact("treeArtifact2");
    SpawnActionTemplate actionTemplate =
        ActionsTestUtil.createDummySpawnActionTemplate(artifact1, artifact2);
    registerAction(actionTemplate);

    // We mock out the action template function to expand into two actions that throw when executed.
    ActionTemplateExpansionKey secondOwner = ActionTemplateExpansionKey.of(ACTION_LOOKUP_KEY, 1);
    TreeFileArtifact expectedExpansionOutput1 =
        TreeFileArtifact.createTemplateExpansionOutput(artifact2, "child1", secondOwner);
    TreeFileArtifact expectedExpansionOutput2 =
        TreeFileArtifact.createTemplateExpansionOutput(artifact2, "child2", secondOwner);
    Action throwingAction =
        new ThrowingDummyAction(
            TreeFileArtifact.createTreeOutput(artifact1, "child1"), expectedExpansionOutput1);
    Action anotherThrowingAction =
        new ThrowingDummyAction(
            TreeFileArtifact.createTreeOutput(artifact1, "child2"), expectedExpansionOutput2);

    actionTemplateExpansionFunction =
        new DummyActionTemplateExpansionFunction(
            actionKeyContext, ImmutableList.of(throwingAction, anotherThrowingAction));

    BuildFailedException e =
        assertThrows(BuildFailedException.class, () -> buildArtifact(artifact2));
    assertThat(e).hasMessageThat().contains("Throwing dummy action");
  }

  @Test
  public void inputTreeArtifactCreationFailedInActionTemplate() {
    // expect errors
    reporter.removeHandler(failFastHandler);

    // artifact1 is created by a action that throws.
    SpecialArtifact artifact1 = createTreeArtifact("treeArtifact1");
    registerAction(new ThrowingDummyAction(artifact1));

    // artifact2 is a tree artifact generated by an action template.
    SpecialArtifact artifact2 = createTreeArtifact("treeArtifact2");
    SpawnActionTemplate actionTemplate =
        ActionsTestUtil.createDummySpawnActionTemplate(artifact1, artifact2);
    registerAction(actionTemplate);

    BuildFailedException e =
        assertThrows(BuildFailedException.class, () -> buildArtifact(artifact2));
    assertThat(e).hasMessageThat().contains("Throwing dummy action");
  }

  @Test
  public void emptyInputAndOutputTreeArtifactInActionTemplate() throws Exception {
    // artifact1 is an empty tree artifact which is generated by a single no-op dummy action.
    SpecialArtifact artifact1 = createTreeArtifact("treeArtifact1");
    registerAction(new NoOpDummyAction(artifact1));

    // artifact2 is a tree artifact generated by an action template that takes artifact1 as input.
    SpecialArtifact artifact2 = createTreeArtifact("treeArtifact2");
    SpawnActionTemplate actionTemplate =
        ActionsTestUtil.createDummySpawnActionTemplate(artifact1, artifact2);
    registerAction(actionTemplate);

    buildArtifact(artifact2);

    assertThat(artifact1.getPath().exists()).isTrue();
    assertThat(artifact1.getPath().getDirectoryEntries()).isEmpty();
    assertThat(artifact2.getPath().exists()).isTrue();
    assertThat(artifact2.getPath().getDirectoryEntries()).isEmpty();
  }

  private abstract static class SimpleTestAction extends TestAction {
    private final Button button;

    SimpleTestAction(Artifact output) {
      this(/*inputs=*/ ImmutableList.of(), output);
    }

    SimpleTestAction(Iterable<Artifact> inputs, Artifact output) {
      this(new Button(), inputs, output);
    }

    SimpleTestAction(Button button, Iterable<Artifact> inputs, Artifact output) {
      super(NO_EFFECT, NestedSetBuilder.wrap(Order.STABLE_ORDER, inputs), ImmutableSet.of(output));
      this.button = button;
    }

    @Override
    public final ActionResult execute(ActionExecutionContext context)
        throws ActionExecutionException {
      button.pressed = true;
      try {
        run(context);
      } catch (IOException e) {
        throw new ActionExecutionException(
            e, this, /*catastrophe=*/ false, CrashFailureDetails.detailedExitCodeForThrowable(e));
      }
      return ActionResult.EMPTY;
    }

    abstract void run(ActionExecutionContext context) throws IOException;
  }

  /** An action that touches some output TreeFileArtifacts. Takes no inputs. */
  private static final class TouchingTestAction extends SimpleTestAction {
    private final ImmutableList<String> outputFiles;

    TouchingTestAction(SpecialArtifact output, String... outputFiles) {
      this(new Button(), output, outputFiles);
    }

    TouchingTestAction(Button button, SpecialArtifact output, String... outputFiles) {
      super(button, /*inputs=*/ ImmutableList.of(), output);
      this.outputFiles = ImmutableList.copyOf(outputFiles);
    }

    @Override
    void run(ActionExecutionContext context) throws IOException {
      for (String file : outputFiles) {
        touchFile(getPrimaryOutput().getPath().getRelative(file));
      }
    }
  }

  /** Takes an input file and populates several copies inside a TreeArtifact. */
  private static final class WriteInputToFilesAction extends SimpleTestAction {
    private final ImmutableList<String> outputFiles;

    WriteInputToFilesAction(
        Button button, Artifact input, SpecialArtifact output, String... outputFiles) {
      super(button, ImmutableList.of(input), output);
      this.outputFiles = ImmutableList.copyOf(outputFiles);
    }

    @Override
    void run(ActionExecutionContext actionExecutionContext) throws IOException {
      for (String file : outputFiles) {
        Path newOutput = getPrimaryOutput().getPath().getRelative(file);
        newOutput.createDirectoryAndParents();
        FileSystemUtils.copyFile(getPrimaryInput().getPath(), newOutput);
      }
    }
  }

  /** Copies the given TreeFileArtifact inputs to the given outputs, in respective order. */
  private static final class CopyTreeAction extends SimpleTestAction {

    CopyTreeAction(SpecialArtifact input, SpecialArtifact output) {
      this(new Button(), input, output);
    }

    CopyTreeAction(Button button, SpecialArtifact input, SpecialArtifact output) {
      super(button, ImmutableList.of(input), output);
    }

    @Override
    void run(ActionExecutionContext context) throws IOException {
      List<Artifact> children = new ArrayList<>();
      context.getArtifactExpander().expand(getPrimaryInput(), children);
      for (Artifact child : children) {
        Path newOutput = getPrimaryOutput().getPath().getRelative(child.getParentRelativePath());
        newOutput.createDirectoryAndParents();
        FileSystemUtils.copyFile(child.getPath(), newOutput);
      }
    }
  }

  private SpecialArtifact createTreeArtifact(String name) {
    FileSystem fs = scratch.getFileSystem();
    Path execRoot =
        fs.getPath(TestUtils.tmpDir()).getRelative("execroot").getRelative("default-exec-root");
    PathFragment execPath = PathFragment.create("out").getRelative(name);
    return new SpecialArtifact(
        ArtifactRoot.asDerivedRoot(execRoot, "out"),
        execPath,
        ACTION_LOOKUP_KEY,
        SpecialArtifactType.TREE);
  }

  private TreeArtifactValue buildArtifact(SpecialArtifact treeArtifact) throws Exception {
    Preconditions.checkArgument(treeArtifact.isTreeArtifact(), treeArtifact);
    BuilderWithResult builder = cachingBuilder();
    buildArtifacts(builder, treeArtifact);
    return (TreeArtifactValue) builder.getLatestResult().get(treeArtifact);
  }

  private void buildArtifact(Artifact normalArtifact) throws Exception {
    buildArtifacts(cachingBuilder(), normalArtifact);
  }

  private static void verifyOutputTree(
      TreeArtifactValue result, SpecialArtifact parent, String... expectedChildPaths) {
    Preconditions.checkArgument(parent.isTreeArtifact(), parent);
    Set<TreeFileArtifact> expectedChildren =
        Arrays.stream(expectedChildPaths)
            .map(path -> TreeFileArtifact.createTreeOutput(parent, path))
            .collect(toImmutableSet());
    for (TreeFileArtifact child : expectedChildren) {
      assertWithMessage(child + " does not exist").that(child.getPath().exists()).isTrue();
    }
    assertThat(result.getChildren()).isEqualTo(expectedChildren);
  }

  private static void writeFile(Path path, String contents) throws IOException {
    path.getParentDirectory().createDirectoryAndParents();
    // sometimes we write read-only files
    if (path.exists()) {
      path.setWritable(true);
    }
    FileSystemUtils.writeContentAsLatin1(path, contents);
  }

  private static void writeFile(Artifact file, String contents) throws IOException {
    writeFile(file.getPath(), contents);
  }

  private static void touchFile(Path path) throws IOException {
    path.getParentDirectory().createDirectoryAndParents();
    path.getParentDirectory().setWritable(true);
    FileSystemUtils.touchFile(path);
  }

  private static void touchFile(Artifact file) throws IOException {
    touchFile(file.getPath());
  }

  private static void deleteFile(Artifact file) throws IOException {
    Path path = file.getPath();
    // sometimes we write read-only files
    path.setWritable(true);
    // work around the sticky bit (this might depend on the behavior of the OS?)
    path.getParentDirectory().setWritable(true);
    path.delete();
  }

  /** A dummy action template expansion function that just returns the injected actions. */
  private static final class DummyActionTemplateExpansionFunction implements SkyFunction {
    private final ActionKeyContext actionKeyContext;
    private final ImmutableList<ActionAnalysisMetadata> actions;

    DummyActionTemplateExpansionFunction(
        ActionKeyContext actionKeyContext, ImmutableList<ActionAnalysisMetadata> actions) {
      this.actionKeyContext = actionKeyContext;
      this.actions = actions;
    }

    @Override
    public SkyValue compute(SkyKey skyKey, Environment env) {
      try {
        return new ActionTemplateExpansionValue(
            Actions.assignOwnersAndFilterSharedActionsAndThrowActionConflict(
                actionKeyContext, actions, (ActionLookupKey) skyKey, /*outputFiles=*/ null));
      } catch (ActionConflictException e) {
        throw new IllegalStateException(e);
      }
    }

    @Override
    public String extractTag(SkyKey skyKey) {
      return null;
    }
  }

  /** No-op action that does not generate the action outputs. */
  private static final class NoOpDummyAction extends SimpleTestAction {

    NoOpDummyAction(Artifact output) {
      super(/*inputs=*/ ImmutableList.of(), output);
    }

    NoOpDummyAction(Artifact input, Artifact output) {
      super(ImmutableList.of(input), output);
    }

    /** Does nothing. */
    @Override
    void run(ActionExecutionContext actionExecutionContext) {}
  }

  /** No-op action that throws when executed. */
  private static final class ThrowingDummyAction extends TestAction {

    ThrowingDummyAction(Artifact output) {
      super(NO_EFFECT, NestedSetBuilder.emptySet(Order.STABLE_ORDER), ImmutableSet.of(output));
    }

    ThrowingDummyAction(Artifact input, Artifact output) {
      super(NO_EFFECT, NestedSetBuilder.create(Order.STABLE_ORDER, input), ImmutableSet.of(output));
    }

    /** Unconditionally throws. */
    @Override
    public ActionResult execute(ActionExecutionContext actionExecutionContext)
        throws ActionExecutionException {
      DetailedExitCode code =
          DetailedExitCode.of(
              FailureDetail.newBuilder()
                  .setCrash(Crash.newBuilder().setCode(Code.CRASH_UNKNOWN))
                  .build());
      throw new ActionExecutionException(
          "Throwing dummy action", this, /*catastrophe=*/ true, code);
    }
  }
}
