// Copyright 2023 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.buildtool;

import static com.google.common.collect.ImmutableMap.toImmutableMap;
import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
import static com.google.devtools.build.lib.packages.Type.STRING;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.analysis.actions.FileWriteActionContext;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.BuildOptionsView;
import com.google.devtools.build.lib.analysis.config.Fragment;
import com.google.devtools.build.lib.analysis.config.FragmentOptions;
import com.google.devtools.build.lib.analysis.config.RequiresOptions;
import com.google.devtools.build.lib.analysis.config.TransitionFactories;
import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition;
import com.google.devtools.build.lib.analysis.config.transitions.TransitionFactory;
import com.google.devtools.build.lib.analysis.util.MockRule;
import com.google.devtools.build.lib.buildtool.util.BuildIntegrationTestCase;
import com.google.devtools.build.lib.buildtool.util.TestRuleModule;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.exec.FileWriteStrategy;
import com.google.devtools.build.lib.exec.ModuleActionContextRegistry;
import com.google.devtools.build.lib.packages.ImplicitOutputsFunction;
import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper;
import com.google.devtools.build.lib.packages.RuleTransitionData;
import com.google.devtools.build.lib.runtime.BlazeModule;
import com.google.devtools.build.lib.runtime.CommandEnvironment;
import com.google.devtools.build.lib.testutil.TestConstants;
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.Symlinks;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionDocumentationCategory;
import com.google.devtools.common.options.OptionEffectTag;
import com.google.devtools.common.options.OptionMetadataTag;
import com.google.testing.junit.testparameterinjector.TestParameter;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import java.io.IOException;
import java.util.Optional;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(TestParameterInjector.class)
public final class ConvenienceSymlinkTest extends BuildIntegrationTestCase {

  /** test options to cause the output directory to change */
  public static final class PathTestOptions extends FragmentOptions {
    @Option(
        name = "output_directory_name",
        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
        effectTags = {OptionEffectTag.AFFECTS_OUTPUTS},
        metadataTags = {OptionMetadataTag.EXPLICIT_IN_OUTPUT_PATH},
        defaultValue = "default")
    public String outputDirectoryName;

    @Option(
        name = "useless_option",
        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
        effectTags = {OptionEffectTag.NO_OP},
        defaultValue = "default")
    public String uselessOption;
  }

  /** Test fragment. */
  @RequiresOptions(options = {PathTestOptions.class})
  public static final class PathTestConfiguration extends Fragment {
    private final String outputDirectoryName;

    public PathTestConfiguration(BuildOptions buildOptions) {
      this.outputDirectoryName = buildOptions.get(PathTestOptions.class).outputDirectoryName;
    }

    @Override
    public String getOutputDirectoryName() {
      return outputDirectoryName;
    }
  }

  private static final class PathTransition implements PatchTransition {
    private final String newPath;

    PathTransition(String newPath) {
      this.newPath = newPath;
    }

    @Override
    public ImmutableSet<Class<? extends FragmentOptions>> requiresOptionFragments() {
      return ImmutableSet.of(PathTestOptions.class);
    }

    @Override
    public BuildOptions patch(BuildOptionsView options, EventHandler eventHandler) {
      BuildOptionsView clone = options.clone();
      clone.get(PathTestOptions.class).outputDirectoryName = newPath;
      return clone.underlying();
    }
  }

  private static final class PathTransitionFactory
      implements TransitionFactory<RuleTransitionData> {
    @Override
    public PatchTransition create(RuleTransitionData ruleData) {
      return new PathTransition(
          NonconfigurableAttributeMapper.of(ruleData.rule()).get("path", STRING));
    }
  }

  private static final class UselessOptionTransition implements PatchTransition {
    private final String newValue;

    UselessOptionTransition(String newValue) {
      this.newValue = newValue;
    }

    @Override
    public ImmutableSet<Class<? extends FragmentOptions>> requiresOptionFragments() {
      return ImmutableSet.of(PathTestOptions.class);
    }

    @Override
    public BuildOptions patch(BuildOptionsView options, EventHandler eventHandler) {
      BuildOptionsView clone = options.clone();
      clone.get(PathTestOptions.class).uselessOption = newValue;
      return clone.underlying();
    }
  }

  private static final class UselessOptionTransitionFactory
      implements TransitionFactory<RuleTransitionData> {
    @Override
    public PatchTransition create(RuleTransitionData ruleData) {
      return new UselessOptionTransition(
          NonconfigurableAttributeMapper.of(ruleData.rule()).get("value", STRING));
    }
  }

  private static final class PathTestRulesModule extends BlazeModule {
    @Override
    public void registerActionContexts(
        ModuleActionContextRegistry.Builder registryBuilder,
        CommandEnvironment env,
        BuildRequest buildRequest) {
      // we need an implementation of FileWriteActionContext to get our file writes to succeed
      registryBuilder.register(FileWriteActionContext.class, new FileWriteStrategy());
      // we need something to consume FileWriteActionContext or the registration will have no effect
      registryBuilder.restrictTo(FileWriteActionContext.class, "local");
    }

    @Override
    public void initializeRuleClasses(ConfiguredRuleClassProvider.Builder builder) {
      TestRuleModule.getModule().initializeRuleClasses(builder);

      MockRule basicRule =
          () ->
              MockRule.define(
                  "basic_rule",
                  (ruleBuilder, env) ->
                      ruleBuilder
                          .add(attr("deps", LABEL_LIST).allowedFileTypes())
                          .setImplicitOutputsFunction(
                              ImplicitOutputsFunction.fromTemplates("%{name}.bin")));
      MockRule incomingTransitionRule =
          () ->
              MockRule.define(
                  "incoming_transition_rule",
                  (ruleBuilder, env) ->
                      ruleBuilder
                          .add(
                              attr("path", STRING)
                                  .mandatory()
                                  .nonconfigurable("used in transition"))
                          .add(attr("deps", LABEL_LIST).allowedFileTypes())
                          .setImplicitOutputsFunction(
                              ImplicitOutputsFunction.fromTemplates("%{name}.bin"))
                          .cfg(new PathTransitionFactory()));
      MockRule incomingUnrelatedTransitionRule =
          () ->
              MockRule.define(
                  "incoming_unrelated_transition_rule",
                  (ruleBuilder, env) ->
                      ruleBuilder
                          .add(
                              attr("value", STRING)
                                  .mandatory()
                                  .nonconfigurable("used in transition"))
                          .add(attr("deps", LABEL_LIST).allowedFileTypes())
                          .setImplicitOutputsFunction(
                              ImplicitOutputsFunction.fromTemplates("%{name}.bin"))
                          .cfg(new UselessOptionTransitionFactory()));

      MockRule outgoingTransitionRule =
          () ->
              MockRule.define(
                  "outgoing_transition_rule",
                  (ruleBuilder, env) ->
                      ruleBuilder
                          .add(
                              attr("deps", LABEL_LIST)
                                  .allowedFileTypes()
                                  .cfg(
                                      TransitionFactories.of(
                                          new PathTransition("set_by_outgoing_transition_rule"))))
                          .setImplicitOutputsFunction(
                              ImplicitOutputsFunction.fromTemplates("%{name}.bin")));

      builder
          .addConfigurationFragment(PathTestConfiguration.class)
          .addRuleDefinition(basicRule)
          .addRuleDefinition(incomingTransitionRule)
          .addRuleDefinition(incomingUnrelatedTransitionRule)
          .addRuleDefinition(outgoingTransitionRule);
    }
  }

  @TestParameter boolean mergedAnalysisExecution;

  @Override
  protected void setupOptions() throws Exception {
    super.setupOptions();

    addOptions(
        // Turn on the new symlink behavior
        "--use_top_level_targets_for_symlinks",
        "--experimental_merged_skyframe_analysis_execution=" + mergedAnalysisExecution);
  }

  @Override
  protected BlazeModule getRulesModule() {
    return new PathTestRulesModule();
  }

  private Path getExecRoot() {
    return getBlazeWorkspace().getDirectories().getExecRoot(TestConstants.WORKSPACE_NAME);
  }

  private Path getOutputPath() {
    return getBlazeWorkspace().getDirectories().getOutputPath(TestConstants.WORKSPACE_NAME);
  }

  /** Gets a mapping from the workspace-relative paths of symlinks to the paths they point to. */
  private ImmutableMap<String, Path> getConvenienceSymlinks() throws IOException {
    return getWorkspace().getDirectoryEntries().stream()
        .filter(Path::isSymbolicLink)
        .collect(
            toImmutableMap(
                (path) -> path.relativeTo(getWorkspace()).toString(),
                (path) -> {
                  try {
                    return getWorkspace().getRelative(path.readSymbolicLinkUnchecked());
                  } catch (IOException ex) {
                    throw new RuntimeException(ex);
                  }
                }));
  }

  @Test
  public void sanityCheckFilesHaveNullConfigurations() throws Exception {
    // Other tests in this file expect that files will have a null configuration.
    write("files/BUILD", "exports_files(['foo.txt', 'bar.txt'])");
    write("files/foo.txt", "This is just a test file to pretend to build.");
    write("files/bar.txt", "This is just a test file to pretend to build.");
    BuildResult result = buildTarget("//files:foo.txt", "//files:bar.txt");

    assertThat(
            result.getActualTargets().stream()
                .collect(
                    toImmutableMap(
                        target -> target.getLabel().toString(),
                        target -> Optional.ofNullable(target.getConfigurationKey()))))
        .containsExactly(
            "//files:foo.txt", Optional.empty(),
            "//files:bar.txt", Optional.empty());
  }

  @Test
  public void sanityCheckOutputDirectory() throws Exception {
    // Other tests in this file expect that changing the output_directory_name flag changes the
    // output directory of the configuration to the same value.

    // This test relies on hard-coded paths for intermediate artifacts so
    // must force output directory naming into legacy behaviors for now.
    addOptions(
        "--output_directory_name=set_by_flag",
        "--compilation_mode=fastbuild",
        "--experimental_output_directory_naming_scheme=legacy",
        "--experimental_exec_configuration_distinguisher=legacy");

    write(
        "path/BUILD",
        "basic_rule(name='from_flag')",
        "incoming_transition_rule(name='from_transition', path='set_by_transition')",
        "incoming_unrelated_transition_rule(name='unrelated_transition', value='whatever')",
        "outgoing_transition_rule(name='outgoing_transition')");
    BuildResult result =
        buildTarget(
            "//path:from_flag",
            "//path:from_transition",
            "//path:unrelated_transition",
            "//path:outgoing_transition");

    assertThat(
            result.getActualTargets().stream()
                .collect(
                    toImmutableMap(
                        (target) -> target.getLabel().toString(),
                        (target) ->
                            getConfiguration(target)
                                .getOutputDirectory(RepositoryName.MAIN)
                                .getRoot()
                                .asPath()
                                .relativeTo(getOutputPath())
                                .toString())))
        .containsExactly(
            "//path:from_flag", "set_by_flag-" + getTargetConfiguration().getCpu() + "-fastbuild",
            "//path:from_transition",
                "set_by_transition-" + getTargetConfiguration().getCpu() + "-fastbuild",
            "//path:unrelated_transition",
                "set_by_flag-" + getTargetConfiguration().getCpu() + "-fastbuild",
            "//path:outgoing_transition",
                "set_by_flag-" + getTargetConfiguration().getCpu() + "-fastbuild");
  }

  @Test
  public void buildingNothing_unsetsSymlinks() throws Exception {
    addOptions("--symlink_prefix=nothing-", "--incompatible_skip_genfiles_symlink=false");

    Path config = getOutputBase().getRelative("some-imaginary-config");
    // put symlinks at the convenience symlinks spots to simulate a prior build
    Path binLink = getWorkspace().getChild("nothing-bin");
    binLink.createSymbolicLink(config.getChild("bin"));
    Path genfilesLink = getWorkspace().getChild("nothing-genfiles");
    genfilesLink.createSymbolicLink(config.getChild("genfiles"));
    Path testlogsLink = getWorkspace().getChild("nothing-testlogs");
    testlogsLink.createSymbolicLink(config.getChild("testlogs"));

    buildTarget();

    // there should be nothing at any of the convenience symlinks which depend on configuration -
    // the symlinks put there during the simulated prior build should have been deleted
    assertThat(binLink.exists(Symlinks.NOFOLLOW)).isTrue();
    assertThat(genfilesLink.exists(Symlinks.NOFOLLOW)).isTrue();
    assertThat(testlogsLink.exists(Symlinks.NOFOLLOW)).isTrue();

    // the execroot and output path symlinks should have been created because they don't depend on
    // configuration, but no other symlinks should have been created
    assertThat(getConvenienceSymlinks())
        .containsExactly(
            // notably absent: nothing-bin, nothing-genfiles, nothing-testlogs
            // these were also not created under other names
            "nothing-bin",
            getOutputPath()
                .getRelative("default-" + getTargetConfiguration().getCpu() + "-fastbuild/bin"),
            "nothing-genfiles",
            getOutputPath()
                .getRelative("default-" + getTargetConfiguration().getCpu() + "-fastbuild/bin"),
            "nothing-testlogs",
            getOutputPath()
                .getRelative(
                    "default-" + getTargetConfiguration().getCpu() + "-fastbuild/testlogs"),
            "nothing-" + TestConstants.WORKSPACE_NAME,
            getExecRoot(),
            "nothing-out",
            getOutputPath());
  }

  @Test
  public void buildingOnlyTargetsWithNullConfigurations_unsetsSymlinks() throws Exception {
    addOptions("--symlink_prefix=nulled-", "--incompatible_skip_genfiles_symlink=false");

    Path config = getOutputBase().getRelative("some-imaginary-config");
    // put symlinks at the convenience symlinks spots to simulate a prior build
    Path binLink = getWorkspace().getChild("nulled-bin");
    binLink.createSymbolicLink(config.getChild("bin"));
    Path genfilesLink = getWorkspace().getChild("nulled-genfiles");
    genfilesLink.createSymbolicLink(config.getChild("genfiles"));
    Path testlogsLink = getWorkspace().getChild("nulled-testlogs");
    testlogsLink.createSymbolicLink(config.getChild("testlogs"));

    write("files/BUILD", "exports_files(['foo.txt', 'bar.txt'])");
    write("files/foo.txt", "This is just a test file to pretend to build.");
    write("files/bar.txt", "This is just a test file to pretend to build.");
    buildTarget("//files:foo.txt", "//files:bar.txt");

    // there should be nothing at any of the convenience symlinks which depend on configuration -
    // the symlinks put there during the simulated prior build should have been deleted
    assertThat(binLink.exists(Symlinks.NOFOLLOW)).isFalse();
    assertThat(genfilesLink.exists(Symlinks.NOFOLLOW)).isFalse();
    assertThat(testlogsLink.exists(Symlinks.NOFOLLOW)).isFalse();

    // the execroot and output path symlinks should have been created because they don't depend on
    // configuration, but no other symlinks should have been created
    assertThat(getConvenienceSymlinks())
        .containsExactly(
            // notably absent: nulled-bin, nulled-genfiles, nulled-testlogs
            // these were also not created under other names
            "nulled-" + TestConstants.WORKSPACE_NAME, getExecRoot(), "nulled-out", getOutputPath());
  }

  @Test
  public void buildingTargetsWithDifferentOutputDirectories_unsetsSymlinksIfNoneAreTopLevel()
      throws Exception {
    addOptions("--symlink_prefix=ambiguous-", "--incompatible_skip_genfiles_symlink=false");

    Path config = getOutputPath().getRelative("some-imaginary-config");
    // put symlinks at the convenience symlinks spots to simulate a prior build
    Path binLink = getWorkspace().getChild("ambiguous-bin");
    binLink.createSymbolicLink(config.getChild("bin"));
    Path genfilesLink = getWorkspace().getChild("ambiguous-genfiles");
    genfilesLink.createSymbolicLink(config.getChild("genfiles"));
    Path testlogsLink = getWorkspace().getChild("ambiguous-testlogs");
    testlogsLink.createSymbolicLink(config.getChild("testlogs"));

    write(
        "targets/BUILD",
        "incoming_transition_rule(name='config1', path='set_from_config1')",
        "incoming_transition_rule(name='config2', path='set_from_config2')");
    buildTarget("//targets:config1", "//targets:config2");

    // there should be nothing at any of the convenience symlinks which depend on configuration -
    // the symlinks put there during the simulated prior build should have been deleted
    assertThat(binLink.exists(Symlinks.NOFOLLOW)).isFalse();
    assertThat(genfilesLink.exists(Symlinks.NOFOLLOW)).isFalse();
    assertThat(testlogsLink.exists(Symlinks.NOFOLLOW)).isFalse();

    // the execroot and output path symlinks should have been created because they don't depend on
    // configuration, but no other symlinks should have been created
    assertThat(getConvenienceSymlinks())
        .containsExactly(
            // notably absent: ambiguous-bin, ambiguous-genfiles, ambiguous-testlogs
            // these were also not created under other names
            "ambiguous-" + TestConstants.WORKSPACE_NAME,
            getExecRoot(),
            "ambiguous-out",
            getOutputPath());
  }

  @Test
  public void buildingTargetsWithDifferentOutputDirectories_setsSymlinksIfAnyAreTopLevel()
      throws Exception {
    addOptions(
        "--symlink_prefix=ambiguous-",
        "--incompatible_skip_genfiles_symlink=false",
        "--incompatible_merge_genfiles_directory=false",
        "--incompatible_skip_genfiles_symlink=false");

    Path config = getOutputPath().getRelative("some-imaginary-config");
    // put symlinks at the convenience symlinks spots to simulate a prior build
    Path binLink = getWorkspace().getChild("ambiguous-bin");
    binLink.createSymbolicLink(config.getChild("bin"));
    Path genfilesLink = getWorkspace().getChild("ambiguous-genfiles");
    genfilesLink.createSymbolicLink(config.getChild("genfiles"));
    Path testlogsLink = getWorkspace().getChild("ambiguous-testlogs");
    testlogsLink.createSymbolicLink(config.getChild("testlogs"));

    write(
        "targets/BUILD",
        "basic_rule(name='default')",
        "incoming_transition_rule(name='config1', path='set_from_config1')");
    buildTarget("//targets:default", "//targets:config1");

    assertThat(getConvenienceSymlinks())
        .containsExactly(
            "ambiguous-bin",
            getOutputPath()
                .getRelative("default-" + getTargetConfiguration().getCpu() + "-fastbuild/bin"),
            "ambiguous-genfiles",
            getOutputPath()
                .getRelative(
                    "default-" + getTargetConfiguration().getCpu() + "-fastbuild/genfiles"),
            "ambiguous-testlogs",
            getOutputPath()
                .getRelative(
                    "default-" + getTargetConfiguration().getCpu() + "-fastbuild/testlogs"),
            "ambiguous-" + TestConstants.WORKSPACE_NAME,
            getExecRoot(),
            "ambiguous-out",
            getOutputPath());
  }

  @Test
  public void buildingTargetsWithSameConfiguration_setsSymlinks() throws Exception {
    addOptions(
        "--symlink_prefix=same-",
        "--compilation_mode=fastbuild",
        "--incompatible_merge_genfiles_directory=false",
        "--incompatible_skip_genfiles_symlink=false");

    write(
        "targets/BUILD",
        "incoming_transition_rule(name='configged1', path='configured')",
        "incoming_transition_rule(name='configged2', path='configured')");
    buildTarget("//targets:configged1", "//targets:configged2");

    assertThat(getConvenienceSymlinks())
        .containsExactly(
            "same-bin",
            getOutputPath()
                .getRelative("configured-" + getTargetConfiguration().getCpu() + "-fastbuild/bin"),
            "same-genfiles",
            getOutputPath()
                .getRelative(
                    "configured-" + getTargetConfiguration().getCpu() + "-fastbuild/genfiles"),
            "same-testlogs",
            getOutputPath()
                .getRelative(
                    "configured-" + getTargetConfiguration().getCpu() + "-fastbuild/testlogs"),
            "same-" + TestConstants.WORKSPACE_NAME,
            getExecRoot(),
            "same-out",
            getOutputPath());
  }

  @Test
  public void buildingSameConfigurationTargetsWithDifferentConfigurationDeps_setsSymlinks()
      throws Exception {
    addOptions(
        "--output_directory_name=from_flag",
        "--symlink_prefix=united-",
        "--compilation_mode=fastbuild",
        "--incompatible_merge_genfiles_directory=false",
        "--incompatible_skip_genfiles_symlink=false");

    write(
        "targets/BUILD",
        "outgoing_transition_rule(name='configged1', deps=[':alternate1'])",
        "outgoing_transition_rule(name='configged2', deps=[':alternate2'])",
        "basic_rule(name='alternate1')",
        "incoming_transition_rule(name='alternate2', path='alternate_transition')");
    buildTarget("//targets:configged1", "//targets:configged2");

    assertThat(getConvenienceSymlinks())
        .containsExactly(
            "united-bin",
            getOutputPath()
                .getRelative("from_flag-" + getTargetConfiguration().getCpu() + "-fastbuild/bin"),
            "united-genfiles",
            getOutputPath()
                .getRelative(
                    "from_flag-" + getTargetConfiguration().getCpu() + "-fastbuild/genfiles"),
            "united-testlogs",
            getOutputPath()
                .getRelative(
                    "from_flag-" + getTargetConfiguration().getCpu() + "-fastbuild/testlogs"),
            "united-" + TestConstants.WORKSPACE_NAME,
            getExecRoot(),
            "united-out",
            getOutputPath());
  }

  @Test
  public void differentConfigurationSameOutputDirectory_setsSymlinks() throws Exception {
    // TODO(blaze-configurability-team): Remove when `--experimental_output_directory_naming_scheme`
    //    is universally set to `diff_from_baseline`
    addOptions(
        "--output_directory_name=from_flag",
        "--symlink_prefix=unchanged-",
        "--compilation_mode=fastbuild",
        "--incompatible_merge_genfiles_directory=false",
        "--incompatible_skip_genfiles_symlink=false",
        "--experimental_output_directory_naming_scheme=legacy");

    write(
        "targets/BUILD",
        "basic_rule(name='from_flag')",
        "incoming_unrelated_transition_rule(name='configged1', value='one_transition')",
        "incoming_unrelated_transition_rule(name='configged2', value='alternate_transition')");
    buildTarget("//targets:from_flag", "//targets:configged1", "//targets:configged2");

    assertThat(getConvenienceSymlinks())
        .containsExactly(
            "unchanged-bin",
            getOutputPath()
                .getRelative("from_flag-" + getTargetConfiguration().getCpu() + "-fastbuild/bin"),
            "unchanged-genfiles",
            getOutputPath()
                .getRelative(
                    "from_flag-" + getTargetConfiguration().getCpu() + "-fastbuild/genfiles"),
            "unchanged-testlogs",
            getOutputPath()
                .getRelative(
                    "from_flag-" + getTargetConfiguration().getCpu() + "-fastbuild/testlogs"),
            "unchanged-" + TestConstants.WORKSPACE_NAME,
            getExecRoot(),
            "unchanged-out",
            getOutputPath());
  }

  @Test
  public void nullConfigurationWithOtherMatchingOutputDir_setsSymlinks() throws Exception {
    addOptions(
        "--output_directory_name=from_flag",
        "--symlink_prefix=mixed-",
        "--compilation_mode=fastbuild",
        "--incompatible_merge_genfiles_directory=false",
        "--incompatible_skip_genfiles_symlink=false");

    write(
        "targets/BUILD",
        "exports_files(['null'])",
        "basic_rule(name='configured1')",
        "basic_rule(name='configured2')");
    write("targets/null", "This is just a test file to pretend to build.");
    buildTarget("//targets:null", "//targets:configured1", "//targets:configured2");

    assertThat(getConvenienceSymlinks())
        .containsExactly(
            "mixed-bin",
            getOutputPath()
                .getRelative("from_flag-" + getTargetConfiguration().getCpu() + "-fastbuild/bin"),
            "mixed-genfiles",
            getOutputPath()
                .getRelative(
                    "from_flag-" + getTargetConfiguration().getCpu() + "-fastbuild/genfiles"),
            "mixed-testlogs",
            getOutputPath()
                .getRelative(
                    "from_flag-" + getTargetConfiguration().getCpu() + "-fastbuild/testlogs"),
            "mixed-" + TestConstants.WORKSPACE_NAME,
            getExecRoot(),
            "mixed-out",
            getOutputPath());
  }

  @Test
  public void settingSymlinksReplacesSymlinksAlreadyPresent() throws Exception {
    addOptions(
        "--output_directory_name=from_flag",
        "--symlink_prefix=replaced-",
        "--compilation_mode=fastbuild",
        "--incompatible_skip_genfiles_symlink=false");

    Path binLink = getWorkspace().getChild("replaced-bin");
    Path genfilesLink = getWorkspace().getChild("replaced-genfiles");
    Path testlogsLink = getWorkspace().getChild("replaced-testlogs");
    Path workspaceLink = getWorkspace().getChild("replaced-" + TestConstants.WORKSPACE_NAME);
    Path outLink = getWorkspace().getChild("replaced-out");

    PathFragment original = getOutputPath().getRelative("original/destination").asFragment();
    binLink.createSymbolicLink(original);
    genfilesLink.createSymbolicLink(original);
    testlogsLink.createSymbolicLink(original);
    workspaceLink.createSymbolicLink(original);
    outLink.createSymbolicLink(original);

    write("target/BUILD", "basic_rule(name='target')");
    buildTarget("//target:target");

    // Implicitly test for symlink-ness; readSymbolicLink would throw if they are not symlinks.
    assertThat(binLink.readSymbolicLink()).isNotEqualTo(original);
    assertThat(genfilesLink.readSymbolicLink()).isNotEqualTo(original);
    assertThat(testlogsLink.readSymbolicLink()).isNotEqualTo(original);
    assertThat(workspaceLink.readSymbolicLink()).isNotEqualTo(original);
    assertThat(outLink.readSymbolicLink()).isNotEqualTo(original);
  }

  @Test
  public void settingSymlinksCreatesSymlinksIfNotAlreadyPresent() throws Exception {
    addOptions(
        "--output_directory_name=from_flag",
        "--symlink_prefix=created-",
        "--compilation_mode=fastbuild",
        "--incompatible_skip_genfiles_symlink=false");

    write("target/BUILD", "basic_rule(name='target')");
    buildTarget("//target:target");

    assertThat(getWorkspace().getChild("created-bin").isSymbolicLink()).isTrue();
    assertThat(getWorkspace().getChild("created-genfiles").isSymbolicLink()).isTrue();
    assertThat(getWorkspace().getChild("created-testlogs").isSymbolicLink()).isTrue();
    assertThat(getWorkspace().getChild("created-" + TestConstants.WORKSPACE_NAME).isSymbolicLink())
        .isTrue();
    assertThat(getWorkspace().getChild("created-out").isSymbolicLink()).isTrue();
  }

  @Test
  public void genfilesLink_omittedWithIncompatibleFlag() throws Exception {
    addOptions(
        "--output_directory_name=from_flag",
        "--symlink_prefix=prefix-",
        "--compilation_mode=fastbuild",
        "--incompatible_skip_genfiles_symlink=true");

    // Simulate leftover symlink from prior build.
    Path config = getOutputPath().getRelative("some-imaginary-config");
    Path genfilesLink = getWorkspace().getChild("prefix-genfiles");
    genfilesLink.createSymbolicLink(config.getChild("genfiles"));

    write("target/BUILD", "basic_rule(name='target')");
    buildTarget("//target:target");

    assertThat(getWorkspace().getChild("prefix-genfiles").isSymbolicLink()).isFalse();
  }

  @Test
  public void genfilesLink_presentWithoutIncompatibleFlag() throws Exception {
    addOptions(
        "--output_directory_name=from_flag",
        "--symlink_prefix=prefix-",
        "--compilation_mode=fastbuild",
        "--incompatible_skip_genfiles_symlink=false");

    write("target/BUILD", "basic_rule(name='target')");
    buildTarget("//target:target");

    assertThat(getWorkspace().getChild("prefix-genfiles").isSymbolicLink()).isTrue();
  }

  @Test
  public void settingSymlinksDoesNotReplaceNormalFilesAlreadyPresent() throws Exception {
    addOptions(
        "--output_directory_name=from_flag",
        "--symlink_prefix=blocked-",
        "--compilation_mode=fastbuild");

    Path binLink = getWorkspace().getChild("blocked-bin");
    Path genfilesLink = getWorkspace().getChild("blocked-genfiles");
    Path testlogsLink = getWorkspace().getChild("blocked-testlogs");
    Path workspaceLink = getWorkspace().getChild("blocked-" + TestConstants.WORKSPACE_NAME);
    Path outLink = getWorkspace().getChild("blocked-out");

    FileSystemUtils.writeIsoLatin1(binLink, "this file is not a symlink");
    FileSystemUtils.writeIsoLatin1(genfilesLink, "this file is not a symlink");
    FileSystemUtils.writeIsoLatin1(testlogsLink, "this file is not a symlink");
    FileSystemUtils.writeIsoLatin1(workspaceLink, "this file is not a symlink");
    FileSystemUtils.writeIsoLatin1(outLink, "this file is not a symlink");

    write("target/BUILD", "basic_rule(name='target')");
    buildTarget("//target:target");

    assertThat(binLink.isFile(Symlinks.NOFOLLOW)).isTrue();
    assertThat(genfilesLink.isFile(Symlinks.NOFOLLOW)).isTrue();
    assertThat(testlogsLink.isFile(Symlinks.NOFOLLOW)).isTrue();
    assertThat(workspaceLink.isFile(Symlinks.NOFOLLOW)).isTrue();
    assertThat(outLink.isFile(Symlinks.NOFOLLOW)).isTrue();
  }

  @Test
  public void settingSymlinksDoesNotReplaceDirectoriesAlreadyPresent() throws Exception {
    addOptions(
        "--output_directory_name=from_flag",
        "--symlink_prefix=blocked-",
        "--compilation_mode=fastbuild");

    Path binLink = getWorkspace().getChild("blocked-bin");
    Path genfilesLink = getWorkspace().getChild("blocked-genfiles");
    Path testlogsLink = getWorkspace().getChild("blocked-testlogs");
    Path workspaceLink = getWorkspace().getChild("blocked-" + TestConstants.WORKSPACE_NAME);
    Path outLink = getWorkspace().getChild("blocked-out");

    binLink.createDirectory();
    genfilesLink.createDirectory();
    testlogsLink.createDirectory();
    workspaceLink.createDirectory();
    outLink.createDirectory();

    write("target/BUILD", "basic_rule(name='target')");
    buildTarget("//target:target");

    assertThat(binLink.isDirectory(Symlinks.NOFOLLOW)).isTrue();
    assertThat(genfilesLink.isDirectory(Symlinks.NOFOLLOW)).isTrue();
    assertThat(testlogsLink.isDirectory(Symlinks.NOFOLLOW)).isTrue();
    assertThat(workspaceLink.isDirectory(Symlinks.NOFOLLOW)).isTrue();
    assertThat(outLink.isDirectory(Symlinks.NOFOLLOW)).isTrue();
  }

  @Test
  public void settingSymlinksReplacesSymlinksEvenIfNotPointingInsideExecRoot() throws Exception {
    addOptions(
        "--output_directory_name=from_flag",
        "--symlink_prefix=replaced-",
        "--compilation_mode=fastbuild",
        "--incompatible_merge_genfiles_directory=false",
        "--incompatible_skip_genfiles_symlink=false");

    Path binLink = getWorkspace().getChild("replaced-bin");
    Path genfilesLink = getWorkspace().getChild("replaced-genfiles");
    Path testlogsLink = getWorkspace().getChild("replaced-testlogs");
    Path workspaceLink = getWorkspace().getChild("replaced-" + TestConstants.WORKSPACE_NAME);
    Path outLink = getWorkspace().getChild("replaced-out");

    Path original = getWorkspace().getRelative("/arbitrary/somewhere/else/in/the/filesystem");
    binLink.createSymbolicLink(original);
    genfilesLink.createSymbolicLink(original);
    testlogsLink.createSymbolicLink(original);
    workspaceLink.createSymbolicLink(original);
    outLink.createSymbolicLink(original);

    write("target/BUILD", "basic_rule(name='target')");
    buildTarget("//target:target");

    // Implicitly test for symlink-ness; readSymbolicLink would throw if they are not symlinks.
    assertThat(binLink.readSymbolicLink())
        .isEqualTo(
            getOutputPath()
                .getRelative("from_flag-" + getTargetConfiguration().getCpu() + "-fastbuild/bin")
                .asFragment());
    assertThat(genfilesLink.readSymbolicLink())
        .isEqualTo(
            getOutputPath()
                .getRelative(
                    "from_flag-" + getTargetConfiguration().getCpu() + "-fastbuild/genfiles")
                .asFragment());
    assertThat(testlogsLink.readSymbolicLink())
        .isEqualTo(
            getOutputPath()
                .getRelative(
                    "from_flag-" + getTargetConfiguration().getCpu() + "-fastbuild/testlogs")
                .asFragment());
    assertThat(workspaceLink.readSymbolicLink()).isEqualTo(getExecRoot().asFragment());
    assertThat(outLink.readSymbolicLink()).isEqualTo(getOutputPath().asFragment());
  }

  @Test
  public void settingSymlinksCreatesDirectoriesIfNeeded() throws Exception {
    addOptions(
        "--output_directory_name=from_flag",
        "--symlink_prefix=created/",
        "--compilation_mode=fastbuild",
        "--incompatible_skip_genfiles_symlink=false");

    write("target/BUILD", "basic_rule(name='target')");
    buildTarget("//target:target");

    assertThat(getWorkspace().getChild("created").isDirectory()).isTrue();
    assertThat(getWorkspace().getRelative("created/bin").isSymbolicLink()).isTrue();
    assertThat(getWorkspace().getRelative("created/genfiles").isSymbolicLink()).isTrue();
    assertThat(getWorkspace().getRelative("created/testlogs").isSymbolicLink()).isTrue();
    assertThat(
            getWorkspace().getRelative("created/" + TestConstants.WORKSPACE_NAME).isSymbolicLink())
        .isTrue();
    assertThat(getWorkspace().getRelative("created/out").isSymbolicLink()).isTrue();
  }

  @Test
  public void settingSymlinksDoesNothingWhenParentExistsAndIsNotADirectory() throws Exception {
    addOptions(
        "--output_directory_name=from_flag",
        "--symlink_prefix=blocked/",
        "--compilation_mode=fastbuild");

    Path parentDir = getWorkspace().getChild("blocked");
    FileSystemUtils.writeIsoLatin1(parentDir, "this file is not a directory");

    write("target/BUILD", "basic_rule(name='target')");
    buildTarget("//target:target");

    assertThat(getWorkspace().getChild("blocked").isFile(Symlinks.NOFOLLOW)).isTrue();
  }

  @Test
  public void settingSymlinksUsesExistingOrPopulatedParentDirectoryAsNormal() throws Exception {
    addOptions(
        "--output_directory_name=from_flag",
        "--symlink_prefix=cooperating/",
        "--compilation_mode=fastbuild",
        "--incompatible_skip_genfiles_symlink=false");
    write("target/BUILD", "basic_rule(name='target')");
    write("cooperating/original", "this file makes the directory come to life");
    buildTarget("//target:target");

    assertThat(getWorkspace().getChild("cooperating").isDirectory()).isTrue();
    assertThat(getWorkspace().getRelative("cooperating/bin").isSymbolicLink()).isTrue();
    assertThat(getWorkspace().getRelative("cooperating/genfiles").isSymbolicLink()).isTrue();
    assertThat(getWorkspace().getRelative("cooperating/testlogs").isSymbolicLink()).isTrue();
    assertThat(
            getWorkspace()
                .getRelative("cooperating/" + TestConstants.WORKSPACE_NAME)
                .isSymbolicLink())
        .isTrue();
    assertThat(getWorkspace().getRelative("cooperating/out").isSymbolicLink()).isTrue();
    assertThat(getWorkspace().getRelative("cooperating/original").isFile()).isTrue();
  }

  @Test
  public void settingSymlinksIgnoresSymlinksWithDifferentPrefix() throws Exception {
    addOptions(
        "--output_directory_name=from_flag",
        "--symlink_prefix=new-prefix-",
        "--compilation_mode=fastbuild");
    Path binLink = getWorkspace().getChild("other-prefix-bin");
    Path genfilesLink = getWorkspace().getChild("other-prefix-genfiles");
    Path testlogsLink = getWorkspace().getChild("other-prefix-testlogs");
    Path workspaceLink = getWorkspace().getChild("other-prefix-" + TestConstants.WORKSPACE_NAME);
    Path outLink = getWorkspace().getChild("other-prefix-out");

    PathFragment original = getOutputPath().getRelative("original/destination").asFragment();
    binLink.createSymbolicLink(original);
    genfilesLink.createSymbolicLink(original);
    testlogsLink.createSymbolicLink(original);
    workspaceLink.createSymbolicLink(original);
    outLink.createSymbolicLink(original);

    write("target/BUILD", "basic_rule(name='target')");
    buildTarget("//target:target");

    // Implicitly test for symlink-ness; readSymbolicLink would throw if they are not symlinks.
    assertThat(binLink.readSymbolicLink()).isEqualTo(original);
    assertThat(genfilesLink.readSymbolicLink()).isEqualTo(original);
    assertThat(testlogsLink.readSymbolicLink()).isEqualTo(original);
    assertThat(workspaceLink.readSymbolicLink()).isEqualTo(original);
    assertThat(outLink.readSymbolicLink()).isEqualTo(original);
  }

  @Test
  public void unsettingSymlinksRemovesConfigurationSymlinksIfAlreadyPresent() throws Exception {
    addOptions(
        "--output_directory_name=from_flag",
        "--symlink_prefix=deleted-",
        "--compilation_mode=fastbuild",
        "--incompatible_skip_genfiles_symlink=false");
    Path binLink = getWorkspace().getChild("deleted-bin");
    Path genfilesLink = getWorkspace().getChild("deleted-genfiles");
    Path testlogsLink = getWorkspace().getChild("deleted-testlogs");
    Path workspaceLink = getWorkspace().getChild("deleted-" + TestConstants.WORKSPACE_NAME);
    Path outLink = getWorkspace().getChild("deleted-out");

    Path config = getOutputPath().getRelative("some-imaginary-config");
    // put symlinks at the convenience symlinks spots to simulate a prior build
    binLink.createSymbolicLink(config.getChild("bin"));
    genfilesLink.createSymbolicLink(config.getChild("genfiles"));
    testlogsLink.createSymbolicLink(config.getChild("testlogs"));

    write("file/BUILD", "exports_files(['file'])");
    write("file/file", "this is just a file to pretend to build");
    buildTarget("//file:file");

    assertThat(binLink.exists(Symlinks.NOFOLLOW)).isFalse();
    assertThat(genfilesLink.exists(Symlinks.NOFOLLOW)).isFalse();
    assertThat(testlogsLink.exists(Symlinks.NOFOLLOW)).isFalse();

    assertThat(workspaceLink.isSymbolicLink()).isTrue();
    assertThat(outLink.isSymbolicLink()).isTrue();
  }

  @Test
  public void unsettingSymlinksSucceedsIfNotAlreadyPresent() throws Exception {
    addOptions(
        "--output_directory_name=from_flag",
        "--symlink_prefix=already-absent-",
        "--compilation_mode=fastbuild");
    Path binLink = getWorkspace().getChild("already-absent-bin");
    Path genfilesLink = getWorkspace().getChild("already-absent-genfiles");
    Path testlogsLink = getWorkspace().getChild("already-absent-testlogs");
    Path workspaceLink = getWorkspace().getChild("already-absent-" + TestConstants.WORKSPACE_NAME);
    Path outLink = getWorkspace().getChild("already-absent-out");

    write("file/BUILD", "exports_files(['file'])");
    write("file/file", "this is just a file to pretend to build");
    buildTarget("//file:file");

    assertThat(binLink.exists(Symlinks.NOFOLLOW)).isFalse();
    assertThat(genfilesLink.exists(Symlinks.NOFOLLOW)).isFalse();
    assertThat(testlogsLink.exists(Symlinks.NOFOLLOW)).isFalse();

    assertThat(workspaceLink.isSymbolicLink()).isTrue();
    assertThat(outLink.isSymbolicLink()).isTrue();
  }

  @Test
  public void unsettingSymlinksDoesNotRemoveNormalFilesAlreadyPresent() throws Exception {
    addOptions(
        "--output_directory_name=from_flag",
        "--symlink_prefix=blocked-",
        "--compilation_mode=fastbuild");
    Path binLink = getWorkspace().getChild("blocked-bin");
    Path genfilesLink = getWorkspace().getChild("blocked-genfiles");
    Path testlogsLink = getWorkspace().getChild("blocked-testlogs");
    Path workspaceLink = getWorkspace().getChild("blocked-" + TestConstants.WORKSPACE_NAME);
    Path outLink = getWorkspace().getChild("blocked-out");

    FileSystemUtils.writeIsoLatin1(binLink, "this file is not a symlink");
    FileSystemUtils.writeIsoLatin1(genfilesLink, "this file is not a symlink");
    FileSystemUtils.writeIsoLatin1(testlogsLink, "this file is not a symlink");
    FileSystemUtils.writeIsoLatin1(workspaceLink, "this file is not a symlink");
    FileSystemUtils.writeIsoLatin1(outLink, "this file is not a symlink");

    write("file/BUILD", "exports_files(['file'])");
    write("file/file", "this is just a file to pretend to build");
    buildTarget("//file:file");

    assertThat(binLink.isFile(Symlinks.NOFOLLOW)).isTrue();
    assertThat(genfilesLink.isFile(Symlinks.NOFOLLOW)).isTrue();
    assertThat(testlogsLink.isFile(Symlinks.NOFOLLOW)).isTrue();
    assertThat(workspaceLink.isFile(Symlinks.NOFOLLOW)).isTrue();
    assertThat(outLink.isFile(Symlinks.NOFOLLOW)).isTrue();
  }

  @Test
  public void unsettingSymlinksDoesNotRemoveDirectoriesAlreadyPresent() throws Exception {
    addOptions(
        "--output_directory_name=from_flag",
        "--symlink_prefix=blocked-",
        "--compilation_mode=fastbuild");
    Path binLink = getWorkspace().getChild("blocked-bin");
    Path genfilesLink = getWorkspace().getChild("blocked-genfiles");
    Path testlogsLink = getWorkspace().getChild("blocked-testlogs");
    Path workspaceLink = getWorkspace().getChild("blocked-" + TestConstants.WORKSPACE_NAME);
    Path outLink = getWorkspace().getChild("blocked-out");

    binLink.createDirectory();
    genfilesLink.createDirectory();
    testlogsLink.createDirectory();
    workspaceLink.createDirectory();
    outLink.createDirectory();

    write("file/BUILD", "exports_files(['file'])");
    write("file/file", "this is just a file to pretend to build");
    buildTarget("//file:file");

    assertThat(binLink.isDirectory(Symlinks.NOFOLLOW)).isTrue();
    assertThat(genfilesLink.isDirectory(Symlinks.NOFOLLOW)).isTrue();
    assertThat(testlogsLink.isDirectory(Symlinks.NOFOLLOW)).isTrue();
    assertThat(workspaceLink.isDirectory(Symlinks.NOFOLLOW)).isTrue();
    assertThat(outLink.isDirectory(Symlinks.NOFOLLOW)).isTrue();
  }

  @Test
  public void unsettingSymlinksRemovesSymlinksEvenIfNotPointingInsideExecRoot() throws Exception {
    addOptions(
        "--output_directory_name=from_flag",
        "--symlink_prefix=deleted-",
        "--compilation_mode=fastbuild",
        "--incompatible_skip_genfiles_symlink=false");
    Path binLink = getWorkspace().getChild("deleted-bin");
    Path genfilesLink = getWorkspace().getChild("deleted-genfiles");
    Path testlogsLink = getWorkspace().getChild("deleted-testlogs");
    Path workspaceLink = getWorkspace().getChild("deleted-" + TestConstants.WORKSPACE_NAME);
    Path outLink = getWorkspace().getChild("deleted-out");

    Path original = getWorkspace().getRelative("/arbitrary/somewhere/else/in/the/filesystem");
    binLink.createSymbolicLink(original);
    genfilesLink.createSymbolicLink(original);
    testlogsLink.createSymbolicLink(original);
    workspaceLink.createSymbolicLink(original);
    outLink.createSymbolicLink(original);

    write("file/BUILD", "exports_files(['file'])");
    write("file/file", "this is just a file to pretend to build");
    buildTarget("//file:file");

    assertThat(binLink.exists(Symlinks.NOFOLLOW)).isFalse();
    assertThat(genfilesLink.exists(Symlinks.NOFOLLOW)).isFalse();
    assertThat(testlogsLink.exists(Symlinks.NOFOLLOW)).isFalse();

    assertThat(workspaceLink.isSymbolicLink()).isTrue();
    assertThat(outLink.isSymbolicLink()).isTrue();
  }

  @Test
  public void unsettingSymlinksIgnoresSymlinksWithDifferentPrefix() throws Exception {
    addOptions(
        "--output_directory_name=from_flag",
        "--symlink_prefix=new-prefix-",
        "--compilation_mode=fastbuild");
    Path binLink = getWorkspace().getChild("other-prefix-bin");
    Path genfilesLink = getWorkspace().getChild("other-prefix-genfiles");
    Path testlogsLink = getWorkspace().getChild("other-prefix-testlogs");
    Path workspaceLink = getWorkspace().getChild("other-prefix-" + TestConstants.WORKSPACE_NAME);
    Path outLink = getWorkspace().getChild("other-prefix-out");

    PathFragment original = getOutputPath().getRelative("original/destination").asFragment();
    binLink.createSymbolicLink(original);
    genfilesLink.createSymbolicLink(original);
    testlogsLink.createSymbolicLink(original);
    workspaceLink.createSymbolicLink(original);
    outLink.createSymbolicLink(original);

    write("file/BUILD", "exports_files(['file'])");
    write("file/file", "this is just a file to pretend to build");
    buildTarget("//file:file");

    // Implicitly test for symlink-ness; readSymbolicLink would throw if they are not symlinks.
    assertThat(binLink.readSymbolicLink()).isEqualTo(original);
    assertThat(genfilesLink.readSymbolicLink()).isEqualTo(original);
    assertThat(testlogsLink.readSymbolicLink()).isEqualTo(original);
    assertThat(workspaceLink.readSymbolicLink()).isEqualTo(original);
    assertThat(outLink.readSymbolicLink()).isEqualTo(original);
  }

  @Test
  public void symlinkPrefix_specialNoCreateValue_doesNotCreateOrDeleteSymlinks() throws Exception {
    addOptions("--symlink_prefix=/");

    write("foo/BUILD", "exports_files(['bar.txt'])");
    write("foo/bar.txt", "This is just a test file to pretend to build.");

    // This will be a preexisting symlink and when --symlink_prefix=/ is used, assert that this
    // preexisting symlink still exists.
    Path binLink = getWorkspace().getChild("blaze-" + TestConstants.WORKSPACE_NAME);
    binLink.createSymbolicLink(PathFragment.create("foo/"));

    buildTarget("//foo:bar.txt");

    ImmutableMap<String, Path> symlinks = getConvenienceSymlinks();
    assertThat(symlinks).containsKey("blaze-" + TestConstants.WORKSPACE_NAME);
  }

  @Test
  public void convenienceSymlinks_ignore_leaveSymlinksUntouched() throws Exception {
    addOptions("--experimental_convenience_symlinks=ignore");

    write("foo/BUILD", "exports_files(['bar.txt'])");
    write("foo/bar.txt", "This is just a test file to pretend to build.");
    buildTarget("//foo:bar.txt");

    // This will be a preexisting symlink that will remain after the build
    Path binLink = getWorkspace().getChild("blaze-" + TestConstants.WORKSPACE_NAME);
    binLink.createSymbolicLink(PathFragment.create("foo/"));

    ImmutableMap<String, Path> symlinks = getConvenienceSymlinks();
    assertThat(symlinks).containsKey("blaze-" + TestConstants.WORKSPACE_NAME);
  }

  @Test
  public void convenienceSymlinks_normal_createSymlinks() throws Exception {
    addOptions("--symlink_prefix=test-", "--experimental_convenience_symlinks=normal");

    write("foo/BUILD", "exports_files(['bar.txt'])");
    write("foo/bar.txt", "This is just a test file to pretend to build.");
    buildTarget("//foo:bar.txt");

    ImmutableMap<String, Path> symlinks = getConvenienceSymlinks();
    assertThat(symlinks).containsKey("test-" + TestConstants.WORKSPACE_NAME);
    assertThat(symlinks).containsKey("test-out");
  }

  @Test
  public void convenienceSymlinks_clean_deletesAndDoesNotCreateSymlinks() throws Exception {
    addOptions("--symlink_prefix=test-", "--experimental_convenience_symlinks=clean");

    write("foo/BUILD", "exports_files(['bar.txt'])");
    write("foo/bar.txt", "This is just a test file to pretend to build.");

    // This will be a preexisting symlink that will be deleted after the build
    Path binLink = getWorkspace().getChild("test-" + TestConstants.WORKSPACE_NAME);
    binLink.createSymbolicLink(PathFragment.create("foo"));

    buildTarget("//foo:bar.txt");

    ImmutableMap<String, Path> symlinks = getConvenienceSymlinks();
    assertThat(symlinks).doesNotContainKey("test-" + TestConstants.WORKSPACE_NAME);
    assertThat(symlinks).doesNotContainKey("test-out");
  }
}
