// Copyright 2019 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.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.devtools.build.lib.cmdline.LabelConstants;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.testutil.ManualClock;
import com.google.devtools.build.lib.testutil.TestConstants;
import com.google.devtools.build.lib.util.AbruptExitException;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.Root;
import com.google.devtools.build.lib.vfs.Symlinks;
import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests {@link SymlinkForest}.
 */
@RunWith(JUnit4.class)
public class SymlinkForestTest {
  private FileSystem fileSystem;

  private Path topDir;
  private Path file1;
  private Path file2;
  private Path aDir;

  // The execution root.
  private Path linkRoot;

  @Before
  public final void initializeFileSystem() throws Exception {
    ManualClock clock = new ManualClock();
    fileSystem = new InMemoryFileSystem(clock);
    linkRoot = fileSystem.getPath("/linkRoot");
    linkRoot.createDirectoryAndParents();
  }

  /*
   * Build a directory tree that looks like:
   *   top-dir/
   *     file-1
   *     file-2
   *     a-dir/
   *       file-3
   *       inner-dir/
   *         link-1 => file-4
   *         dir-link => b-dir
   *   file-4
   */
  private void createTestDirectoryTree() throws IOException {
    topDir = fileSystem.getPath("/top-dir");
    file1 = fileSystem.getPath("/top-dir/file-1");
    file2 = fileSystem.getPath("/top-dir/file-2");
    aDir = fileSystem.getPath("/top-dir/a-dir");
    Path bDir = fileSystem.getPath("/top-dir/b-dir");
    Path file3 = fileSystem.getPath("/top-dir/a-dir/file-3");
    Path innerDir = fileSystem.getPath("/top-dir/a-dir/inner-dir");
    Path link1 = fileSystem.getPath("/top-dir/a-dir/inner-dir/link-1");
    Path dirLink = fileSystem.getPath("/top-dir/a-dir/inner-dir/dir-link");
    Path file4 = fileSystem.getPath("/file-4");
    Path file5 = fileSystem.getPath("/top-dir/b-dir/file-5");

    topDir.createDirectory();
    FileSystemUtils.createEmptyFile(file1);
    FileSystemUtils.createEmptyFile(file2);
    aDir.createDirectory();
    bDir.createDirectory();
    FileSystemUtils.createEmptyFile(file3);
    innerDir.createDirectory();
    link1.createSymbolicLink(file4);  // simple symlink
    dirLink.createSymbolicLink(bDir);
    FileSystemUtils.createEmptyFile(file4);
    FileSystemUtils.createEmptyFile(file5);
  }

  private static PathFragment longestPathPrefix(String path, String... prefixStrs) {
    ImmutableSet.Builder<PackageIdentifier> prefixes = ImmutableSet.builder();
    for (String prefix : prefixStrs) {
      prefixes.add(PackageIdentifier.createInMainRepo(prefix));
    }
    PackageIdentifier longest = SymlinkForest.longestPathPrefix(
        PackageIdentifier.createInMainRepo(path), prefixes.build());
    return longest != null ? longest.getPackageFragment() : null;
  }

  @Test
  public void testLongestPathPrefix() {
    PathFragment a = PathFragment.create("A");
    assertThat(longestPathPrefix("A/b", "A", "B")).isEqualTo(a); // simple parent
    assertThat(longestPathPrefix("A", "A", "B")).isEqualTo(a); // self
    assertThat(longestPathPrefix("A/B/c", "A", "A/B"))
        .isEqualTo(a.getRelative("B")); // want longest
    assertThat(longestPathPrefix("C/b", "A", "B")).isNull(); // not found in other parents
    assertThat(longestPathPrefix("A", "A/B", "B")).isNull(); // not found in child
    assertThat(longestPathPrefix("A/B/C/d/e/f.h", "A/B/C", "B/C/d"))
        .isEqualTo(a.getRelative("B/C"));
    assertThat(longestPathPrefix("A/f.h", "", "B/C/d")).isEqualTo(PathFragment.EMPTY_FRAGMENT);
  }

  @Test
  public void testDeleteTreesBelowNotPrefixed() throws IOException {
    createTestDirectoryTree();
    new SymlinkForest(ImmutableMap.of(), topDir, "").deleteTreesBelowNotPrefixed(topDir, "file-");
    assertThat(file1.exists()).isTrue();
    assertThat(file2.exists()).isTrue();
    assertThat(aDir.exists()).isFalse();
  }

  // Create same package under two different roots
  private static PackageIdentifier createPkg(Root rootA, Root rootB, String pkg)
      throws IOException {
    if (rootA != null) {
      rootA.getRelative(pkg).createDirectoryAndParents();
      FileSystemUtils.createEmptyFile(rootA.getRelative(pkg).getChild("file"));
    }
    if (rootB != null) {
      rootB.getRelative(pkg).createDirectoryAndParents();
      FileSystemUtils.createEmptyFile(rootB.getRelative(pkg).getChild("file"));
    }
    return PackageIdentifier.createInMainRepo(pkg);
  }

  // Create package for external repo
  private static PackageIdentifier createExternalPkg(Root root, String repo, String pkg)
      throws IOException, LabelSyntaxException {
    if (root != null) {
      Path repoRoot = root.getRelative(LabelConstants.EXTERNAL_PACKAGE_NAME).getRelative(repo);
      repoRoot.getRelative(pkg).createDirectoryAndParents();
      FileSystemUtils.createEmptyFile(repoRoot.getRelative(pkg).getChild("file"));
    }
    return PackageIdentifier.create(RepositoryName.create("@" + repo), PathFragment.create(pkg));
  }

  // Create package for main repo
  private static PackageIdentifier createMainPkg(Root repoRoot, String pkg)
      throws IOException, LabelSyntaxException {
    if (repoRoot != null) {
      repoRoot.getRelative(pkg).createDirectoryAndParents();
      FileSystemUtils.createEmptyFile(repoRoot.getRelative(pkg).getChild("file"));
    }
    return PackageIdentifier.create(RepositoryName.create("@"), PathFragment.create(pkg));
  }

  private static void assertLinksTo(Path fromRoot, Root toRoot, String relpart) throws IOException {
    assertLinksTo(fromRoot.getRelative(relpart), toRoot.getRelative(relpart));
  }

  private static void assertLinksTo(Path fromRoot, Path toRoot) throws IOException {
    assertWithMessage("stat: " + fromRoot.stat()).that(fromRoot.isSymbolicLink()).isTrue();
    assertThat(fromRoot.readSymbolicLink()).isEqualTo(toRoot.asFragment());
  }

  private static void assertIsDir(Path root, String relpart) {
    assertThat(root.getRelative(relpart).isDirectory(Symlinks.NOFOLLOW)).isTrue();
  }

  @Test
  public void testPlantLinkForestWithMultiplePackagePath() throws Exception {
    Root rootA = Root.fromPath(fileSystem.getPath("/A"));
    Root rootB = Root.fromPath(fileSystem.getPath("/B"));

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createPkg(rootA, rootB, "pkgA"), rootA)
            .put(createPkg(rootA, rootB, "dir1/pkgA"), rootA)
            .put(createPkg(rootA, rootB, "dir1/pkgB"), rootB)
            .put(createPkg(rootA, rootB, "dir2/pkg"), rootA)
            .put(createPkg(rootA, rootB, "dir2/pkg/pkg"), rootB)
            .put(createPkg(rootA, rootB, "pkgB"), rootB)
            .put(createPkg(rootA, rootB, "pkgB/dir/pkg"), rootA)
            .put(createPkg(rootA, rootB, "pkgB/pkg"), rootA)
            .put(createPkg(rootA, rootB, "pkgB/pkg/pkg"), rootA)
            .build();
    createPkg(rootA, rootB, "pkgB/dir");  // create a file in there

    Path linkRoot = fileSystem.getPath("/linkRoot");
    linkRoot.createDirectoryAndParents();
    new SymlinkForest(
            packageRootMap, linkRoot, TestConstants.PRODUCT_NAME, ImmutableSortedSet.of(), false)
        .plantSymlinkForest();

    assertLinksTo(linkRoot, rootA, "pkgA");
    assertIsDir(linkRoot, "dir1");
    assertLinksTo(linkRoot, rootA, "dir1/pkgA");
    assertLinksTo(linkRoot, rootB, "dir1/pkgB");
    assertIsDir(linkRoot, "dir2");
    assertIsDir(linkRoot, "dir2/pkg");
    assertLinksTo(linkRoot, rootA, "dir2/pkg/file");
    assertLinksTo(linkRoot, rootB, "dir2/pkg/pkg");
    assertIsDir(linkRoot, "pkgB");
    assertIsDir(linkRoot, "pkgB/dir");
    assertLinksTo(linkRoot, rootB, "pkgB/dir/file");
    assertLinksTo(linkRoot, rootA, "pkgB/dir/pkg");
    assertLinksTo(linkRoot, rootA, "pkgB/pkg");
  }

  @Test
  public void testTopLevelPackage() throws Exception {
    Root rootX = Root.fromPath(fileSystem.getPath("/X"));
    Root rootY = Root.fromPath(fileSystem.getPath("/Y"));
    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createPkg(rootX, rootY, ""), rootX)
            .put(createPkg(rootX, rootY, "foo"), rootX)
            .build();

    new SymlinkForest(
            packageRootMap, linkRoot, TestConstants.PRODUCT_NAME, ImmutableSortedSet.of(), false)
        .plantSymlinkForest();
    assertLinksTo(linkRoot, rootX, "file");
  }

  @Test
  public void testPlantSymlinkForest() throws Exception {
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    mainRepo.asPath().createDirectoryAndParents();
    linkRoot.createDirectoryAndParents();

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createMainPkg(mainRepo, "dir_main"), mainRepo)
            .put(createMainPkg(mainRepo, "dir_lib/pkg"), mainRepo)
            .put(createMainPkg(mainRepo, ""), mainRepo)
            // Remote repo without top-level package.
            .put(createExternalPkg(outputBase, "X", "dir_x/pkg"), outputBase)
            // Remote repo with and without top-level package.
            .put(createExternalPkg(outputBase, "Y", ""), outputBase)
            .put(createExternalPkg(outputBase, "Y", "dir_y/pkg"), outputBase)
            // Only top-level pkg.
            .put(createExternalPkg(outputBase, "Z", ""), outputBase)
            .build();

    new SymlinkForest(
            packageRootMap, linkRoot, TestConstants.PRODUCT_NAME, ImmutableSortedSet.of(), false)
        .plantSymlinkForest();

    assertLinksTo(linkRoot, mainRepo, "dir_main");
    assertLinksTo(linkRoot, mainRepo, "dir_lib");
    assertLinksTo(linkRoot, mainRepo, "file");
    assertLinksTo(linkRoot, outputBase, LabelConstants.EXTERNAL_PATH_PREFIX + "/X");
    assertLinksTo(linkRoot, outputBase, LabelConstants.EXTERNAL_PATH_PREFIX + "/Y");
    assertLinksTo(linkRoot, outputBase, LabelConstants.EXTERNAL_PATH_PREFIX + "/Z");
    assertThat(
            linkRoot
                .getRelative(LabelConstants.EXTERNAL_PACKAGE_NAME)
                .getRelative("Y/file")
                .exists())
        .isTrue();
    assertThat(
            linkRoot
                .getRelative(LabelConstants.EXTERNAL_PACKAGE_NAME)
                .getRelative("Z/file")
                .exists())
        .isTrue();
  }

  @Test
  public void test_withSiblingRepoLayout_plantSymlinkForest() throws Exception {
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    mainRepo.asPath().createDirectoryAndParents();
    linkRoot.createDirectoryAndParents();

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createMainPkg(mainRepo, "dir_main"), mainRepo)
            .put(createMainPkg(mainRepo, "dir_lib/pkg"), mainRepo)
            .put(createMainPkg(mainRepo, ""), mainRepo)
            // Remote repo without top-level package.
            .put(createExternalPkg(outputBase, "X", "dir_x/pkg"), outputBase)
            // Remote repo with and without top-level package.
            .put(createExternalPkg(outputBase, "Y", ""), outputBase)
            .put(createExternalPkg(outputBase, "Y", "dir_y/pkg"), outputBase)
            // Only top-level pkg.
            .put(createExternalPkg(outputBase, "Z", ""), outputBase)
            .build();

    new SymlinkForest(
            packageRootMap, linkRoot, TestConstants.PRODUCT_NAME, ImmutableSortedSet.of(), true)
        .plantSymlinkForest();

    // Expected sibling repository layout (X, Y and Z are siblings of ws_name):
    //
    // .
    // ├── execroot
    // │   ├── ws_name { ... }
    // │   ├── X -> external/X
    // │   ├── Y -> external/Y
    // │   └── Z -> external/Z
    // └── external
    //     ├── X
    //     ├── Y
    //     └── Z

    assertLinksTo(linkRoot, mainRepo, "dir_main");
    assertLinksTo(linkRoot, mainRepo, "dir_lib");
    assertLinksTo(linkRoot, mainRepo, "file");
    assertLinksTo(
        linkRoot.getParentDirectory().getRelative("X"),
        outputBase.getRelative(LabelConstants.EXTERNAL_PATH_PREFIX + "/X"));
    assertLinksTo(
        linkRoot.getParentDirectory().getRelative("Y"),
        outputBase.getRelative(LabelConstants.EXTERNAL_PATH_PREFIX + "/Y"));
    assertLinksTo(
        linkRoot.getParentDirectory().getRelative("Z"),
        outputBase.getRelative(LabelConstants.EXTERNAL_PATH_PREFIX + "/Z"));
    assertThat(linkRoot.getParentDirectory().getRelative("Y/file").exists()).isTrue();
    assertThat(linkRoot.getParentDirectory().getRelative("Z/file").exists()).isTrue();
  }

  @Test
  public void testPlantSymlinkForestForMainRepo() throws Exception {
    // For the main repo, plantSymlinkForest function should only link all files and dirs under
    // main repo root that're presented in packageRootMap.
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    linkRoot.createDirectoryAndParents();
    mainRepo.asPath().createDirectoryAndParents();
    mainRepo.getRelative("dir4").createDirectoryAndParents();
    FileSystemUtils.createEmptyFile(mainRepo.getRelative("file"));

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createMainPkg(mainRepo, "dir1/pkg/foo"), mainRepo)
            .put(createMainPkg(mainRepo, "dir2/pkg"), mainRepo)
            .put(createMainPkg(mainRepo, "dir3"), mainRepo)
            .put(createExternalPkg(outputBase, "X", "dir_x/pkg"), outputBase)
            .build();

    new SymlinkForest(
            packageRootMap, linkRoot, TestConstants.PRODUCT_NAME, ImmutableSortedSet.of(), false)
        .plantSymlinkForest();

    assertLinksTo(linkRoot, mainRepo, "dir1");
    assertLinksTo(linkRoot, mainRepo, "dir2");
    assertLinksTo(linkRoot, mainRepo, "dir3");
    // dir4 and the file under main repo root should not be linked
    // because they are not presented in packageRootMap.
    assertThat(linkRoot.getChild("dir4").exists()).isFalse();
    assertThat(linkRoot.getChild("file").exists()).isFalse();
    assertLinksTo(linkRoot, outputBase, LabelConstants.EXTERNAL_PATH_PREFIX + "/X");
  }

  @Test
  public void test_withSubdirRepoLayout_TestExternalDirInMainRepoIsIgnored1() throws Exception {
    // Test external/ is ignored even when packages like "//external/foo" is specified.
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    linkRoot.createDirectoryAndParents();
    mainRepo.asPath().createDirectoryAndParents();

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createMainPkg(mainRepo, "dir1/pkg/foo"), mainRepo)
            .put(createMainPkg(mainRepo, "dir2/pkg"), mainRepo)
            .put(createMainPkg(mainRepo, "dir3"), mainRepo)
            // external/ should not be linked even we have "//external/foo" package
            .put(createMainPkg(mainRepo, "external/foo"), mainRepo)
            .put(createExternalPkg(outputBase, "X", "dir_x/pkg"), outputBase)
            .build();

    new SymlinkForest(
            packageRootMap, linkRoot, TestConstants.PRODUCT_NAME, ImmutableSortedSet.of(), false)
        .plantSymlinkForest();

    assertLinksTo(linkRoot, mainRepo, "dir1");
    assertLinksTo(linkRoot, mainRepo, "dir2");
    assertLinksTo(linkRoot, mainRepo, "dir3");
    assertLinksTo(linkRoot, outputBase, LabelConstants.EXTERNAL_PATH_PREFIX + "/X");
    assertThat(outputBase.getRelative("external/foo").exists()).isFalse();
  }

  @Test
  public void test_withSubDirRepoLayout_TestExternalDirInMainRepoIsIgnored2() throws Exception {
    // Test external/ is ignored when root package "//:" is specified.
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    linkRoot.createDirectoryAndParents();
    mainRepo.asPath().createDirectoryAndParents();
    mainRepo.getRelative("dir3").createDirectoryAndParents();
    mainRepo.getRelative("external/foo").createDirectoryAndParents();

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createMainPkg(mainRepo, "dir1/pkg/foo"), mainRepo)
            .put(createMainPkg(mainRepo, "dir2/pkg"), mainRepo)
            // Empty package will cause every top-level files to be linked, except external/
            .put(createMainPkg(mainRepo, ""), mainRepo)
            .put(createExternalPkg(outputBase, "X", "dir_x/pkg"), outputBase)
            .build();

    new SymlinkForest(
            packageRootMap, linkRoot, TestConstants.PRODUCT_NAME, ImmutableSortedSet.of(), false)
        .plantSymlinkForest();

    assertLinksTo(linkRoot, mainRepo, "dir1");
    assertLinksTo(linkRoot, mainRepo, "dir2");
    assertLinksTo(linkRoot, mainRepo, "dir3");
    assertLinksTo(linkRoot, outputBase, LabelConstants.EXTERNAL_PATH_PREFIX + "/X");
    assertThat(outputBase.getRelative("external/foo").exists()).isFalse();
  }

  @Test
  public void test_withSiblingRepoLayout_TestExternalDirInMainRepoExists() throws Exception {
    // Test external/ is ignored even when packages like "//external/foo" is specified.
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    linkRoot.createDirectoryAndParents();
    mainRepo.asPath().createDirectoryAndParents();

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createMainPkg(mainRepo, "dir1/pkg/foo"), mainRepo)
            .put(createMainPkg(mainRepo, "dir2/pkg"), mainRepo)
            .put(createMainPkg(mainRepo, "dir3"), mainRepo)
            // external/ should not be linked even we have "//external/foo" package
            .put(createMainPkg(mainRepo, "external/foo"), mainRepo)
            .put(createExternalPkg(outputBase, "X", "dir_x/pkg"), outputBase)
            .build();

    new SymlinkForest(
            packageRootMap, linkRoot, TestConstants.PRODUCT_NAME, ImmutableSortedSet.of(), true)
        .plantSymlinkForest();

    // Expected output base layout with sibling repositories in the execroot where
    // ws_name and X are siblings:
    //
    // /ob
    // ├── execroot
    // │   ├── ws_name
    // │   │   ├── dir1
    // │   │   │   └── pkg
    // │   │   │       └── foo -> /my_repo/dir1/pkg/foo
    // │   │   ├── dir2
    // │   │   │   └── pkg -> /my_repo/dir2/pkg
    // │   │   ├── dir3 -> /my_repo/dir3
    // │   │   └── external
    // │   │       └── foo -> /my_repo/external/foo
    // │   └── X -> /ob/external/X
    // └── external
    //     └── X

    assertLinksTo(linkRoot, mainRepo, "dir1");
    assertLinksTo(linkRoot, mainRepo, "dir2");
    assertLinksTo(linkRoot, mainRepo, "dir3");

    assertThat(
            outputBase.getRelative(LabelConstants.EXTERNAL_PATH_PREFIX).getRelative("X").exists())
        .isTrue();
    assertThat(outputBase.getRelative("execroot/X").exists()).isTrue();
    assertLinksTo(
        linkRoot.getParentDirectory().getRelative("X"), // Sibling of the main repo.
        outputBase.getRelative(LabelConstants.EXTERNAL_PATH_PREFIX).getRelative("X"));

    assertThat(linkRoot.getRelative("external/foo").exists()).isTrue();
  }

  @Test
  public void test_withSiblingRepoLayoutAndRootPackageInRoots_TestExternalDirInMainRepoExists()
      throws Exception {
    // Test external/ is ignored when root package "//:" is specified.
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    linkRoot.createDirectoryAndParents();
    mainRepo.asPath().createDirectoryAndParents();
    mainRepo.getRelative("external/foo").createDirectoryAndParents();

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            // Empty package will cause every top-level files to be linked, except external/
            .put(createMainPkg(mainRepo, ""), mainRepo)
            .put(createExternalPkg(outputBase, "X", "dir_x/pkg"), outputBase)
            .build();

    new SymlinkForest(
            packageRootMap, linkRoot, TestConstants.PRODUCT_NAME, ImmutableSortedSet.of(), true)
        .plantSymlinkForest();

    // Expected output base layout with sibling repositories in the execroot where
    // ws_name and X are siblings:
    //
    // /ob
    // ├── execroot
    // │   ├── ws_name
    // │   │   └── external
    // │   │       └── foo -> /my_repo/external/foo
    // │   └── X -> /ob/external/X
    // └── external
    //     └── X

    assertThat(
            outputBase.getRelative(LabelConstants.EXTERNAL_PATH_PREFIX).getRelative("X").exists())
        .isTrue();
    assertThat(outputBase.getRelative("execroot/X").exists()).isTrue();
    assertLinksTo(
        linkRoot.getParentDirectory().getRelative("X"), // Sibling of the main repo.
        outputBase.getRelative(LabelConstants.EXTERNAL_PATH_PREFIX).getRelative("X"));

    assertThat(linkRoot.getRelative("external/foo").exists()).isTrue();
  }

  @Test
  public void testExternalPackage() throws Exception {
    Path linkRoot = fileSystem.getPath("/linkRoot");
    linkRoot.createDirectoryAndParents();

    Root root = Root.fromPath(fileSystem.getPath("/src"));
    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            // Virtual root, shouldn't actually be linked in.
            .put(LabelConstants.EXTERNAL_PACKAGE_IDENTIFIER, root)
            .build();

    new SymlinkForest(
            packageRootMap, linkRoot, TestConstants.PRODUCT_NAME, ImmutableSortedSet.of(), false)
        .plantSymlinkForest();
    assertThat(linkRoot.getRelative(LabelConstants.EXTERNAL_PATH_PREFIX).exists()).isFalse();
  }

  @Test
  public void testNotSymlinkedDirectoriesInExecRootAllInMainRepo() throws Exception {
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    linkRoot.createDirectoryAndParents();
    mainRepo.asPath().createDirectoryAndParents();
    mainRepo.getRelative("dir3").createDirectoryAndParents();
    mainRepo.getRelative("build").createDirectoryAndParents();

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createMainPkg(mainRepo, "dir1/pkg/foo"), mainRepo)
            .put(createMainPkg(mainRepo, "dir2/pkg"), mainRepo)
            // Empty package will cause every top-level files to be linked, except external/
            .put(createMainPkg(mainRepo, ""), mainRepo)
            .put(createExternalPkg(outputBase, "X", "dir_x/pkg"), outputBase)
            .build();

    new SymlinkForest(
            packageRootMap,
            linkRoot,
            TestConstants.PRODUCT_NAME,
            ImmutableSortedSet.of("build"),
            false)
        .plantSymlinkForest();

    assertLinksTo(linkRoot, mainRepo, "dir1");
    assertLinksTo(linkRoot, mainRepo, "dir2");
    assertLinksTo(linkRoot, mainRepo, "dir3");
    assertLinksTo(linkRoot, outputBase, LabelConstants.EXTERNAL_PATH_PREFIX + "/X");
    assertThat(linkRoot.getChild("build").exists()).isFalse();
  }

  @Test
  public void testNotSymlinkedDirectoriesNotDeletedBetweenCommands() throws Exception {
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    linkRoot.createDirectoryAndParents();
    mainRepo.asPath().createDirectoryAndParents();
    mainRepo.getRelative("build").createDirectoryAndParents();

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createMainPkg(mainRepo, "dir1/pkg"), mainRepo)
            // Empty package will cause every top-level files to be linked, except external/
            .put(createMainPkg(mainRepo, ""), mainRepo)
            .build();

    SymlinkForest symlinkForest =
        new SymlinkForest(
            packageRootMap,
            linkRoot,
            TestConstants.PRODUCT_NAME,
            ImmutableSortedSet.of("build"),
            false);
    symlinkForest.plantSymlinkForest();

    assertLinksTo(linkRoot, mainRepo, "dir1");
    assertThat(linkRoot.getChild("build").exists()).isFalse();

    // Create some file in 'build' directory under exec root.
    Path notSymlinkedDir = linkRoot.getChild("build");
    notSymlinkedDir.createDirectoryAndParents();

    byte[] bytes = "text".getBytes(StandardCharsets.ISO_8859_1);
    Path childPath = notSymlinkedDir.getChild("child.txt");
    FileSystemUtils.writeContent(childPath, bytes);

    symlinkForest.plantSymlinkForest();

    assertLinksTo(linkRoot, mainRepo, "dir1");
    // Exists because it was explicitly created.
    assertThat(linkRoot.getChild("build").exists()).isTrue();
    // The presence of the manually added file indicates that SymlinkForest did not delete
    // the directory it's in.
    assertThat(childPath.exists()).isTrue();
    assertThat(FileSystemUtils.readContent(childPath, StandardCharsets.ISO_8859_1))
        .isEqualTo("text");
  }

  @Test
  public void testNotSymlinkedDirectoriesInExecRootPartialMainRepo1() throws Exception {
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    linkRoot.createDirectoryAndParents();
    mainRepo.asPath().createDirectoryAndParents();
    mainRepo.getRelative("dir3").createDirectoryAndParents();
    mainRepo.getRelative("build").createDirectoryAndParents();

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createMainPkg(mainRepo, "dir1/pkg/foo"), mainRepo)
            .put(createMainPkg(mainRepo, "dir2/pkg"), mainRepo)
            .put(createExternalPkg(outputBase, "X", "dir_x/pkg"), outputBase)
            .build();

    new SymlinkForest(
            packageRootMap,
            linkRoot,
            TestConstants.PRODUCT_NAME,
            ImmutableSortedSet.of("build"),
            false)
        .plantSymlinkForest();

    assertLinksTo(linkRoot, mainRepo, "dir1");
    assertLinksTo(linkRoot, mainRepo, "dir2");
    assertLinksTo(linkRoot, outputBase, LabelConstants.EXTERNAL_PATH_PREFIX + "/X");
    assertThat(linkRoot.getChild("build").exists()).isFalse();
    // Not part of the package roots.
    assertThat(linkRoot.getChild("dir3").exists()).isFalse();
  }

  @Test
  public void testNotSymlinkedDirectoriesInExecRootPartialMainRepo2() throws Exception {
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    linkRoot.createDirectoryAndParents();
    mainRepo.asPath().createDirectoryAndParents();

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.of(createMainPkg(mainRepo, "build"), mainRepo);

    AbruptExitException exception =
        assertThrows(
            AbruptExitException.class,
            () ->
                new SymlinkForest(
                        packageRootMap,
                        linkRoot,
                        TestConstants.PRODUCT_NAME,
                        ImmutableSortedSet.of("build"),
                        false)
                    .plantSymlinkForest());
    assertThat(exception)
        .hasMessageThat()
        .isEqualTo(
            "Directories specified with dont_symlink_directories_in_execroot should be "
                + "ignored and can not be used as sources.");
  }

  @Test
  public void testNotSymlinkedDirectoriesInExecRootMultiplePackageRoots() throws Exception {
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Root otherRepo = Root.fromPath(fileSystem.getPath("/other_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    mainRepo.getRelative("build").createDirectoryAndParents();

    linkRoot.createDirectoryAndParents();
    mainRepo.asPath().createDirectoryAndParents();
    otherRepo.asPath().createDirectoryAndParents();

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createMainPkg(mainRepo, "dir1"), mainRepo)
            .put(createMainPkg(otherRepo, "dir2"), otherRepo)
            .build();

    AbruptExitException exception =
        assertThrows(
            AbruptExitException.class,
            () ->
                new SymlinkForest(
                        packageRootMap,
                        linkRoot,
                        TestConstants.PRODUCT_NAME,
                        ImmutableSortedSet.of("build"),
                        false)
                    .plantSymlinkForest());
    assertThat(exception)
        .hasMessageThat()
        .isEqualTo(
            "dont_symlink_directories_in_execroot is not supported together "
                + "with --package_path option.");
  }
}
