// Copyright 2014 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.vfs;

import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows;

import com.google.devtools.build.lib.util.OS;
import com.google.devtools.build.lib.vfs.FileSystem.NotASymlinkException;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collection;
import org.junit.Before;
import org.junit.Test;

/**
 * This class handles the generic tests that any filesystem must pass.
 *
 * <p>Each filesystem-test should inherit from this class, thereby obtaining
 * all the tests.
 */
public abstract class SymlinkAwareFileSystemTest extends FileSystemTest {

  protected Path xLinkToFile;
  protected Path xLinkToLinkToFile;
  protected Path xLinkToDirectory;
  protected Path xDanglingLink;

  @Before
  public final void createSymbolicLinks() throws Exception  {
    // % ls -lR
    // -rw-rw-r-- xFile
    // drwxrwxr-x xNonEmptyDirectory
    // -rw-rw-r-- xNonEmptyDirectory/foo
    // drwxrwxr-x xEmptyDirectory
    // lrwxrwxr-x xLinkToFile -> xFile
    // lrwxrwxr-x xLinkToDirectory -> xEmptyDirectory
    // lrwxrwxr-x xLinkToLinkToFile -> xLinkToFile
    // lrwxrwxr-x xDanglingLink -> xNothing

    xLinkToFile = absolutize("xLinkToFile");
    xLinkToLinkToFile = absolutize("xLinkToLinkToFile");
    xLinkToDirectory = absolutize("xLinkToDirectory");
    xDanglingLink = absolutize("xDanglingLink");

    createSymbolicLink(xLinkToFile, xFile);
    createSymbolicLink(xLinkToLinkToFile, xLinkToFile);
    createSymbolicLink(xLinkToDirectory, xEmptyDirectory);
    createSymbolicLink(xDanglingLink, xNothing);
  }

  @Test
  public void testCreateLinkToFile() throws IOException {
    Path newPath = xEmptyDirectory.getChild("new-file");
    FileSystemUtils.createEmptyFile(newPath);

    Path linkPath = xEmptyDirectory.getChild("some-link");

    createSymbolicLink(linkPath, newPath);

    assertThat(linkPath.isSymbolicLink()).isTrue();

    assertThat(linkPath.isFile()).isTrue();
    assertThat(linkPath.isFile(Symlinks.NOFOLLOW)).isFalse();
    assertThat(linkPath.isFile(Symlinks.FOLLOW)).isTrue();

    assertThat(linkPath.isDirectory()).isFalse();
    assertThat(linkPath.isDirectory(Symlinks.NOFOLLOW)).isFalse();
    assertThat(linkPath.isDirectory(Symlinks.FOLLOW)).isFalse();

    if (testFS.supportsSymbolicLinksNatively(linkPath)) {
      assertThat(linkPath.getFileSize(Symlinks.NOFOLLOW)).isEqualTo(newPath.toString().length());
      assertThat(linkPath.getFileSize()).isEqualTo(newPath.getFileSize(Symlinks.NOFOLLOW));
    }
    assertThat(linkPath.getParentDirectory().getDirectoryEntries()).hasSize(2);
    assertThat(linkPath.getParentDirectory().getDirectoryEntries()).containsExactly(newPath,
        linkPath);
  }

  @Test
  public void testCreateLinkToDirectory() throws IOException {
    Path newPath = xEmptyDirectory.getChild("new-file");
    newPath.createDirectory();

    Path linkPath = xEmptyDirectory.getChild("some-link");

    createSymbolicLink(linkPath, newPath);

    assertThat(linkPath.isSymbolicLink()).isTrue();
    assertThat(linkPath.isFile()).isFalse();
    assertThat(linkPath.isDirectory()).isTrue();
    assertThat(linkPath.getParentDirectory().getDirectoryEntries()).hasSize(2);
    assertThat(linkPath.getParentDirectory().
      getDirectoryEntries()).containsExactly(newPath, linkPath);
  }

  @Test
  public void testFileCanonicalPath() throws IOException {
    Path newPath = absolutize("new-file");
    FileSystemUtils.createEmptyFile(newPath);
    newPath = newPath.resolveSymbolicLinks();

    Path link1 = absolutize("some-link");
    Path link2 = absolutize("some-link2");

    createSymbolicLink(link1, newPath);
    createSymbolicLink(link2, link1);

    assertCanonicalPathsMatch(newPath, link1, link2);
  }

  @Test
  public void testDirectoryCanonicalPath() throws IOException {
    Path newPath = absolutize("new-folder");
    newPath.createDirectory();
    newPath = newPath.resolveSymbolicLinks();

    Path newFile = newPath.getChild("file");
    FileSystemUtils.createEmptyFile(newFile);

    Path link1 = absolutize("some-link");
    Path link2 = absolutize("some-link2");

    createSymbolicLink(link1, newPath);
    createSymbolicLink(link2, link1);

    Path linkFile1 = link1.getChild("file");
    Path linkFile2 = link2.getChild("file");

    assertCanonicalPathsMatch(newFile, linkFile1, linkFile2);
  }

  private void assertCanonicalPathsMatch(Path newPath, Path link1, Path link2)
      throws IOException {
    assertThat(link1.resolveSymbolicLinks()).isEqualTo(newPath);
    assertThat(link2.resolveSymbolicLinks()).isEqualTo(newPath);
  }

  //
  //  createDirectory
  //

  @Test
  public void testCreateDirectoryWhereDanglingSymlinkAlreadyExists() {
    IOException e = assertThrows(IOException.class, () -> xDanglingLink.createDirectory());
    assertThat(e).hasMessageThat().isEqualTo(xDanglingLink + " (File exists)");
    assertThat(xDanglingLink.isSymbolicLink()).isTrue(); // still a symbolic link
    assertThat(xDanglingLink.isDirectory(Symlinks.FOLLOW)).isFalse(); // link still dangles
  }

  @Test
  public void testCreateDirectoryWhereSymlinkAlreadyExists() {
    IOException e = assertThrows(IOException.class, () -> xLinkToDirectory.createDirectory());
    assertThat(e).hasMessageThat().isEqualTo(xLinkToDirectory + " (File exists)");
    assertThat(xLinkToDirectory.isSymbolicLink()).isTrue(); // still a symbolic link
    assertThat(xLinkToDirectory.isDirectory(Symlinks.FOLLOW)).isTrue(); // link still points to dir
  }

  //  createSymbolicLink(PathFragment)

  @Test
  public void testCreateSymbolicLinkFromFragment() throws IOException {
    String[] linkTargets = {
      "foo",
      "foo/bar",
      ".",
      "..",
      "../foo",
      "../../foo",
      "../../../../../../../../../../../../../../../../../../../../../foo",
      "/foo",
      "/foo/bar",
      "/..",
      "/foo/../bar",
    };
    Path linkPath = absolutize("link");
    for (String linkTarget : linkTargets) {
      PathFragment relative = PathFragment.create(linkTarget);
      linkPath.delete();
      createSymbolicLink(linkPath, relative);
      if (testFS.supportsSymbolicLinksNatively(linkPath)) {
        assertThat(linkPath.getFileSize(Symlinks.NOFOLLOW))
            .isEqualTo(relative.getSafePathString().length());
        assertThat(linkPath.readSymbolicLink()).isEqualTo(relative);
      }
    }
  }

  @Test
  public void testLinkToRootResolvesCorrectly() throws IOException {
    if (OS.getCurrent() == OS.WINDOWS) {
      // This test cannot be run on Windows, it mixes "/" paths with "C:/" paths
      return;
    }
    Path rootPath = testFS.getPath("/");

    try {
      rootPath.getChild("testDir").createDirectory();
    } catch (IOException e) {
      // Do nothing. This is a real FS, and we don't have permission.
    }

    Path linkPath = absolutize("link");
    createSymbolicLink(linkPath, rootPath);

    // resolveSymbolicLinks requires an existing path:
    assertThrows(
        FileNotFoundException.class, () -> linkPath.getRelative("test").resolveSymbolicLinks());

    // The path may not be a symlink, neither on Darwin nor on Linux.
    String nonLinkEntry = null;
    for (String child : testFS.getDirectoryEntries(rootPath)) {
      Path p = rootPath.getChild(child);
      if (!p.isSymbolicLink() && p.isDirectory()) {
        nonLinkEntry = p.getBaseName();
        break;
      }
    }

    assertThat(nonLinkEntry).isNotNull();
    Path rootChild = testFS.getPath("/" + nonLinkEntry);
    assertThat(linkPath.getRelative(nonLinkEntry).resolveSymbolicLinks()).isEqualTo(rootChild);
  }

  @Test
  public void testLinkToFragmentContainingLinkResolvesCorrectly() throws IOException {
    Path link1 = absolutize("link1");
    PathFragment link1target = PathFragment.create("link2/foo");
    Path link2 = absolutize("link2");
    Path link2target = xNonEmptyDirectory;

    createSymbolicLink(link1, link1target); // ln -s link2/foo link1
    createSymbolicLink(link2, link2target); // ln -s xNonEmptyDirectory link2
    // link1 --> xNonEmptyDirectory/foo
    assertThat(link2target.getRelative("foo")).isEqualTo(link1.resolveSymbolicLinks());
  }

  //
  //  readSymbolicLink / resolveSymbolicLinks
  //

  @Test
  public void testRecursiveSymbolicLink() throws IOException {
    Path link = absolutize("recursive-link");
    createSymbolicLink(link, link);

    if (testFS.supportsSymbolicLinksNatively(link)) {
      IOException e = assertThrows(IOException.class, () -> link.resolveSymbolicLinks());
      assertThat(e).hasMessageThat().isEqualTo(link + " (Too many levels of symbolic links)");
    }
  }

  @Test
  public void testMutuallyRecursiveSymbolicLinks() throws IOException {
    Path link1 = absolutize("link1");
    Path link2 = absolutize("link2");
    createSymbolicLink(link2, link1);
    createSymbolicLink(link1, link2);

    if (testFS.supportsSymbolicLinksNatively(link1)) {
      IOException e = assertThrows(IOException.class, () -> link1.resolveSymbolicLinks());
      assertThat(e).hasMessageThat().isEqualTo(link1 + " (Too many levels of symbolic links)");
    }
  }

  @Test
  public void testResolveSymbolicLinksENOENT() {
    if (testFS.supportsSymbolicLinksNatively(xDanglingLink)) {
      IOException e = assertThrows(IOException.class, () -> xDanglingLink.resolveSymbolicLinks());
      assertThat(e).hasMessageThat().isEqualTo(xNothing + " (No such file or directory)");
    }
  }

  @Test
  public void testResolveSymbolicLinksENOTDIR() throws IOException {
    Path badLinkTarget = xFile.getChild("bad"); // parent is not a directory!
    Path badLink = absolutize("badLink");
    if (testFS.supportsSymbolicLinksNatively(badLink)) {
      createSymbolicLink(badLink, badLinkTarget);
      assertThrows(IOException.class, () -> badLink.resolveSymbolicLinks());
    }
  }

  @Test
  public void testResolveSymbolicLinksWithUplevelRefs() throws IOException {
    if (testFS.supportsSymbolicLinksNatively(xLinkToFile)) {
      // Create a series of links that refer to xFile as ./xFile,
      // ./../foo/xFile, ./../../bar/foo/xFile, etc.  They should all resolve
      // to xFile.
      Path ancestor = xFile;
      String prefix = "./";
      while ((ancestor = ancestor.getParentDirectory()) != null) {
        xLinkToFile.delete();
        createSymbolicLink(xLinkToFile, PathFragment.create(prefix + xFile.relativeTo(ancestor)));
        assertThat(xLinkToFile.resolveSymbolicLinks()).isEqualTo(xFile);

        prefix += "../";
      }
    }
  }

  @Test
  public void testReadSymbolicLink() throws IOException {
    if (testFS.supportsSymbolicLinksNatively(xDanglingLink)) {
      assertThat(xDanglingLink.readSymbolicLink().toString()).isEqualTo(xNothing.toString());
    }

    assertThat(xLinkToFile.readSymbolicLink().toString()).isEqualTo(xFile.toString());

    assertThat(xLinkToDirectory.readSymbolicLink().toString())
        .isEqualTo(xEmptyDirectory.toString());

    NotASymlinkException nase =
        assertThrows(NotASymlinkException.class, () -> xFile.readSymbolicLink());
    assertThat(nase).hasMessageThat().isEqualTo(xFile.toString() + " is not a symlink");

    FileNotFoundException fnfe =
        assertThrows(FileNotFoundException.class, () -> xNothing.readSymbolicLink());
    assertThat(fnfe).hasMessageThat().isEqualTo(xNothing + " (No such file or directory)");
  }

  @Test
  public void testCannotCreateSymbolicLinkWithReadOnlyParent()
      throws IOException {
    xEmptyDirectory.setWritable(false);
    Path xChildOfReadonlyDir = xEmptyDirectory.getChild("x");
    if (testFS.supportsSymbolicLinksNatively(xChildOfReadonlyDir)) {
      IOException e =
          assertThrows(IOException.class, () -> xChildOfReadonlyDir.createSymbolicLink(xNothing));
      assertThat(e).hasMessageThat().isEqualTo(xChildOfReadonlyDir + " (Permission denied)");
    }
  }

  //
  // createSymbolicLink
  //

  @Test
  public void testCanCreateDanglingLink() throws IOException {
    Path newPath = absolutize("non-existing-dir/new-file");
    Path someLink = absolutize("dangling-link");
    createSymbolicLink(someLink, newPath);
    assertThat(someLink.isSymbolicLink()).isTrue();
    assertThat(someLink.exists(Symlinks.NOFOLLOW)).isTrue(); // the link itself exists
    assertThat(someLink.exists()).isFalse(); // ...but the referent doesn't
    if (testFS.supportsSymbolicLinksNatively(someLink)) {
      FileNotFoundException e =
          assertThrows(FileNotFoundException.class, () -> someLink.resolveSymbolicLinks());
      assertThat(e)
          .hasMessageThat()
          .isEqualTo(newPath.getParentDirectory() + " (No such file or directory)");
    }
  }

  @Test
  public void testCannotCreateSymbolicLinkWithoutParent() throws IOException {
    Path xChildOfMissingDir = xNothing.getChild("x");
    if (testFS.supportsSymbolicLinksNatively(xChildOfMissingDir)) {
      FileNotFoundException e =
          assertThrows(
              FileNotFoundException.class, () -> xChildOfMissingDir.createSymbolicLink(xFile));
      assertThat(e).hasMessageThat().endsWith(" (No such file or directory)");
    }
  }

  @Test
  public void testCreateSymbolicLinkWhereNothingExists() throws IOException {
    createSymbolicLink(xNothing, xFile);
    assertThat(xNothing.isSymbolicLink()).isTrue();
  }

  @Test
  public void testCreateSymbolicLinkWhereDirectoryAlreadyExists() {
    IOException e =
        assertThrows(IOException.class, () -> createSymbolicLink(xEmptyDirectory, xFile));
    assertThat(e).hasMessageThat().isEqualTo(xEmptyDirectory + " (File exists)");
    assertThat(xEmptyDirectory.isDirectory(Symlinks.NOFOLLOW)).isTrue();
  }

  @Test
  public void testCreateSymbolicLinkWhereFileAlreadyExists() {
    IOException e =
        assertThrows(IOException.class, () -> createSymbolicLink(xFile, xEmptyDirectory));
    assertThat(e).hasMessageThat().isEqualTo(xFile + " (File exists)");
    assertThat(xFile.isFile(Symlinks.NOFOLLOW)).isTrue();
  }

  @Test
  public void testCreateSymbolicLinkWhereDanglingSymlinkAlreadyExists() {
    IOException e = assertThrows(IOException.class, () -> createSymbolicLink(xDanglingLink, xFile));
    assertThat(e).hasMessageThat().isEqualTo(xDanglingLink + " (File exists)");
    assertThat(xDanglingLink.isSymbolicLink()).isTrue(); // still a symbolic link
    assertThat(xDanglingLink.isDirectory()).isFalse(); // link still dangles
  }

  @Test
  public void testCreateSymbolicLinkWhereSymlinkAlreadyExists() {
    IOException e =
        assertThrows(IOException.class, () -> createSymbolicLink(xLinkToDirectory, xNothing));
    assertThat(e).hasMessageThat().isEqualTo(xLinkToDirectory + " (File exists)");
    assertThat(xLinkToDirectory.isSymbolicLink()).isTrue(); // still a symbolic link
    assertThat(xLinkToDirectory.isDirectory()).isTrue(); // link still points to dir
  }

  @Test
  public void testDeleteLink() throws IOException {
    Path newPath = xEmptyDirectory.getChild("new-file");
    Path someLink = xEmptyDirectory.getChild("a-link");
    FileSystemUtils.createEmptyFile(newPath);
    createSymbolicLink(someLink, newPath);

    assertThat(xEmptyDirectory.getDirectoryEntries()).hasSize(2);

    assertThat(someLink.delete()).isTrue();
    assertThat(xEmptyDirectory.getDirectoryEntries()).hasSize(1);

    assertThat(xEmptyDirectory.getDirectoryEntries()).containsExactly(newPath);
  }

  // Testing the links
  @Test
  public void testLinkFollowedToDirectory() throws IOException {
    Path theDirectory = absolutize("foo/");
    assertThat(theDirectory.createDirectory()).isTrue();
    Path newPath1 = absolutize("foo/new-file-1");
    Path newPath2 = absolutize("foo/new-file-2");
    Path newPath3 = absolutize("foo/new-file-3");

    FileSystemUtils.createEmptyFile(newPath1);
    FileSystemUtils.createEmptyFile(newPath2);
    FileSystemUtils.createEmptyFile(newPath3);

    Path linkPath = absolutize("link");
    createSymbolicLink(linkPath, theDirectory);

    Path resultPath1 = absolutize("link/new-file-1");
    Path resultPath2 = absolutize("link/new-file-2");
    Path resultPath3 = absolutize("link/new-file-3");
    assertThat(linkPath.getDirectoryEntries()).containsExactly(resultPath1, resultPath2,
        resultPath3);
  }

  @Test
  public void testDanglingLinkIsNoFile() throws IOException {
    Path newPath1 = absolutize("new-file-1");
    Path newPath2 = absolutize("new-file-2");
    FileSystemUtils.createEmptyFile(newPath1);
    assertThat(newPath2.createDirectory()).isTrue();

    Path linkPath1 = absolutize("link1");
    Path linkPath2 = absolutize("link2");
    createSymbolicLink(linkPath1, newPath1);
    createSymbolicLink(linkPath2, newPath2);

    newPath1.delete();
    newPath2.delete();

    assertThat(linkPath1.isFile()).isFalse();
    assertThat(linkPath2.isDirectory()).isFalse();
  }

  @Test
  public void testWriteOnLinkChangesFile() throws IOException {
    Path testFile = absolutize("test-file");
    FileSystemUtils.createEmptyFile(testFile);
    String testData = "abc19";

    Path testLink = absolutize("a-link");
    createSymbolicLink(testLink, testFile);

    FileSystemUtils.writeContentAsLatin1(testLink, testData);
    String resultData =
      new String(FileSystemUtils.readContentAsLatin1(testFile));

    assertThat(resultData).isEqualTo(testData);
  }

  //
  // Symlink tests:
  //

  @Test
  public void testExistsWithSymlinks() throws IOException {
    Path a = absolutize("a");
    Path b = absolutize("b");
    FileSystemUtils.createEmptyFile(b);
    createSymbolicLink(a, b);  // ln -sf "b" "a"
    assertThat(a.exists()).isTrue(); // = exists(FOLLOW)
    assertThat(b.exists()).isTrue(); // = exists(FOLLOW)
    assertThat(a.exists(Symlinks.FOLLOW)).isTrue();
    assertThat(b.exists(Symlinks.FOLLOW)).isTrue();
    assertThat(a.exists(Symlinks.NOFOLLOW)).isTrue();
    assertThat(b.exists(Symlinks.NOFOLLOW)).isTrue();
    b.delete(); // "a" is now a dangling link
    assertThat(a.exists()).isFalse(); // = exists(FOLLOW)
    assertThat(b.exists()).isFalse(); // = exists(FOLLOW)
    assertThat(a.exists(Symlinks.FOLLOW)).isFalse();
    assertThat(b.exists(Symlinks.FOLLOW)).isFalse();

    assertThat(a.exists(Symlinks.NOFOLLOW)).isTrue(); // symlink still exists
    assertThat(b.exists(Symlinks.NOFOLLOW)).isFalse();
  }

  @Test
  public void testIsDirectoryWithSymlinks() throws IOException {
    Path a = absolutize("a");
    Path b = absolutize("b");
    b.createDirectory();
    createSymbolicLink(a, b);  // ln -sf "b" "a"
    assertThat(a.isDirectory()).isTrue(); // = isDirectory(FOLLOW)
    assertThat(b.isDirectory()).isTrue(); // = isDirectory(FOLLOW)
    assertThat(a.isDirectory(Symlinks.FOLLOW)).isTrue();
    assertThat(b.isDirectory(Symlinks.FOLLOW)).isTrue();
    assertThat(a.isDirectory(Symlinks.NOFOLLOW)).isFalse(); // it's a link!
    assertThat(b.isDirectory(Symlinks.NOFOLLOW)).isTrue();
    b.delete(); // "a" is now a dangling link
    assertThat(a.isDirectory()).isFalse(); // = isDirectory(FOLLOW)
    assertThat(b.isDirectory()).isFalse(); // = isDirectory(FOLLOW)
    assertThat(a.isDirectory(Symlinks.FOLLOW)).isFalse();
    assertThat(b.isDirectory(Symlinks.FOLLOW)).isFalse();
    assertThat(a.isDirectory(Symlinks.NOFOLLOW)).isFalse();
    assertThat(b.isDirectory(Symlinks.NOFOLLOW)).isFalse();
  }

  @Test
  public void testIsFileWithSymlinks() throws IOException {
    Path a = absolutize("a");
    Path b = absolutize("b");
    FileSystemUtils.createEmptyFile(b);
    createSymbolicLink(a, b);  // ln -sf "b" "a"
    assertThat(a.isFile()).isTrue(); // = isFile(FOLLOW)
    assertThat(b.isFile()).isTrue(); // = isFile(FOLLOW)
    assertThat(a.isFile(Symlinks.FOLLOW)).isTrue();
    assertThat(b.isFile(Symlinks.FOLLOW)).isTrue();
    assertThat(a.isFile(Symlinks.NOFOLLOW)).isFalse(); // it's a link!
    assertThat(b.isFile(Symlinks.NOFOLLOW)).isTrue();
    b.delete(); // "a" is now a dangling link
    assertThat(a.isFile()).isFalse(); // = isFile()
    assertThat(b.isFile()).isFalse(); // = isFile()
    assertThat(a.isFile()).isFalse();
    assertThat(b.isFile()).isFalse();
    assertThat(a.isFile(Symlinks.NOFOLLOW)).isFalse();
    assertThat(b.isFile(Symlinks.NOFOLLOW)).isFalse();
  }

  @Test
  public void testGetDirectoryEntriesOnLinkToDirectory() throws Exception {
    Path fooAlias = xNothing.getChild("foo");
    createSymbolicLink(xNothing, xNonEmptyDirectory);
    Collection<Path> dirents = xNothing.getDirectoryEntries();
    assertThat(dirents).containsExactly(fooAlias);
  }

  @Test
  public void testFilesOfLinkedDirectories() throws Exception {
    Path child = xEmptyDirectory.getChild("child");
    Path aliasToChild = xLinkToDirectory.getChild("child");

    assertThat(aliasToChild.exists()).isFalse();
    FileSystemUtils.createEmptyFile(child);
    assertThat(aliasToChild.exists()).isTrue();
    assertThat(aliasToChild.isFile()).isTrue();
    assertThat(aliasToChild.isDirectory()).isFalse();

    validateLinkedReferenceObeysReadOnly(child, aliasToChild);
    validateLinkedReferenceObeysExecutable(child, aliasToChild);
  }

  @Test
  public void testDirectoriesOfLinkedDirectories() throws Exception {
    Path childDir = xEmptyDirectory.getChild("childDir");
    Path linkToChildDir = xLinkToDirectory.getChild("childDir");

    assertThat(linkToChildDir.exists()).isFalse();
    childDir.createDirectory();
    assertThat(linkToChildDir.exists()).isTrue();
    assertThat(linkToChildDir.isDirectory()).isTrue();
    assertThat(linkToChildDir.isFile()).isFalse();

    validateLinkedReferenceObeysReadOnly(childDir, linkToChildDir);
    validateLinkedReferenceObeysExecutable(childDir, linkToChildDir);
  }

  @Test
  public void testDirectoriesOfLinkedDirectoriesOfLinkedDirectories() throws Exception {
    Path childDir = xEmptyDirectory.getChild("childDir");
    Path linkToLinkToDirectory = absolutize("xLinkToLinkToDirectory");
    createSymbolicLink(linkToLinkToDirectory, xLinkToDirectory);
    Path linkToChildDir = linkToLinkToDirectory.getChild("childDir");

    assertThat(linkToChildDir.exists()).isFalse();
    childDir.createDirectory();
    assertThat(linkToChildDir.exists()).isTrue();
    assertThat(linkToChildDir.isDirectory()).isTrue();
    assertThat(linkToChildDir.isFile()).isFalse();

    validateLinkedReferenceObeysReadOnly(childDir, linkToChildDir);
    validateLinkedReferenceObeysExecutable(childDir, linkToChildDir);
  }

  private void validateLinkedReferenceObeysReadOnly(Path path, Path link) throws IOException {
    path.setWritable(false);
    assertThat(path.isWritable()).isFalse();
    assertThat(link.isWritable()).isFalse();
    path.setWritable(true);
    assertThat(path.isWritable()).isTrue();
    assertThat(link.isWritable()).isTrue();
    path.setWritable(false);
    assertThat(path.isWritable()).isFalse();
    assertThat(link.isWritable()).isFalse();
  }

  private void validateLinkedReferenceObeysExecutable(Path path, Path link) throws IOException {
    path.setExecutable(true);
    assertThat(path.isExecutable()).isTrue();
    assertThat(link.isExecutable()).isTrue();
    path.setExecutable(false);
    assertThat(path.isExecutable()).isFalse();
    assertThat(link.isExecutable()).isFalse();
    path.setExecutable(true);
    assertThat(path.isExecutable()).isTrue();
    assertThat(link.isExecutable()).isTrue();
  }

  @Test
  public void testReadingFileFromLinkedDirectory() throws Exception {
    Path linkedTo = absolutize("linkedTo");
    linkedTo.createDirectory();
    Path child = linkedTo.getChild("child");
    FileSystemUtils.createEmptyFile(child);

    byte[] outputData = "This is a test".getBytes();
    FileSystemUtils.writeContent(child, outputData);

    Path link = absolutize("link");
    createSymbolicLink(link, linkedTo);
    Path linkedChild = link.getChild("child");
    byte[] inputData = FileSystemUtils.readContent(linkedChild);
    assertThat(inputData).isEqualTo(outputData);
  }

  @Test
  public void testCreatingFileInLinkedDirectory() throws Exception {
    Path linkedTo = absolutize("linkedTo");
    linkedTo.createDirectory();
    Path child = linkedTo.getChild("child");

    Path link = absolutize("link");
    createSymbolicLink(link, linkedTo);
    Path linkedChild = link.getChild("child");
    byte[] outputData = "This is a test".getBytes();
    FileSystemUtils.writeContent(linkedChild, outputData);

    byte[] inputData = FileSystemUtils.readContent(child);
    assertThat(inputData).isEqualTo(outputData);
  }
}
