// 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.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},
        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 void processForOutputPathMnemonic(OutputDirectoriesContext ctx)
        throws Fragment.OutputDirectoriesContext.AddToMnemonicException {
      ctx.markAsExplicitInOutputPathFor("output_directory_name");
      ctx.addToMnemonic(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("--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", getTargetConfiguration().getCpu() + "-fastbuild-set_by_flag",
            "//path:from_transition",
                getTargetConfiguration().getCpu() + "-fastbuild-set_by_transition",
            "//path:unrelated_transition",
                getTargetConfiguration().getCpu() + "-fastbuild-set_by_flag",
            "//path:outgoing_transition",
                getTargetConfiguration().getCpu() + "-fastbuild-set_by_flag");
  }

  @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(getTargetConfiguration().getCpu() + "-fastbuild-default/bin"),
            "nothing-genfiles",
            getOutputPath()
                .getRelative(getTargetConfiguration().getCpu() + "-fastbuild-default/bin"),
            "nothing-testlogs",
            getOutputPath()
                .getRelative(getTargetConfiguration().getCpu() + "-fastbuild-default/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(getTargetConfiguration().getCpu() + "-fastbuild-default/bin"),
            "ambiguous-genfiles",
            getOutputPath()
                .getRelative(getTargetConfiguration().getCpu() + "-fastbuild-default/genfiles"),
            "ambiguous-testlogs",
            getOutputPath()
                .getRelative(getTargetConfiguration().getCpu() + "-fastbuild-default/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(getTargetConfiguration().getCpu() + "-fastbuild-configured/bin"),
            "same-genfiles",
            getOutputPath()
                .getRelative(getTargetConfiguration().getCpu() + "-fastbuild-configured/genfiles"),
            "same-testlogs",
            getOutputPath()
                .getRelative(getTargetConfiguration().getCpu() + "-fastbuild-configured/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(getTargetConfiguration().getCpu() + "-fastbuild-from_flag/bin"),
            "united-genfiles",
            getOutputPath()
                .getRelative(getTargetConfiguration().getCpu() + "-fastbuild-from_flag/genfiles"),
            "united-testlogs",
            getOutputPath()
                .getRelative(getTargetConfiguration().getCpu() + "-fastbuild-from_flag/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(getTargetConfiguration().getCpu() + "-fastbuild-from_flag/bin"),
            "unchanged-genfiles",
            getOutputPath()
                .getRelative(getTargetConfiguration().getCpu() + "-fastbuild-from_flag/genfiles"),
            "unchanged-testlogs",
            getOutputPath()
                .getRelative(getTargetConfiguration().getCpu() + "-fastbuild-from_flag/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(getTargetConfiguration().getCpu() + "-fastbuild-from_flag/bin"),
            "mixed-genfiles",
            getOutputPath()
                .getRelative(getTargetConfiguration().getCpu() + "-fastbuild-from_flag/genfiles"),
            "mixed-testlogs",
            getOutputPath()
                .getRelative(getTargetConfiguration().getCpu() + "-fastbuild-from_flag/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(getTargetConfiguration().getCpu() + "-fastbuild-from_flag/bin")
                .asFragment());
    assertThat(genfilesLink.readSymbolicLink())
        .isEqualTo(
            getOutputPath()
                .getRelative(getTargetConfiguration().getCpu() + "-fastbuild-from_flag/genfiles")
                .asFragment());
    assertThat(testlogsLink.readSymbolicLink())
        .isEqualTo(
            getOutputPath()
                .getRelative(getTargetConfiguration().getCpu() + "-fastbuild-from_flag/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");
  }
}
