// 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 org.junit.Assert.fail;

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() {
    try {
      xDanglingLink.createDirectory();
      fail();
    } catch (IOException e) {
      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() {
    try {
      xLinkToDirectory.createDirectory();
      fail();
    } catch (IOException e) {
      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:
    try {
      linkPath.getRelative("test").resolveSymbolicLinks();
      fail();
    } catch (FileNotFoundException e) { /* ok */ }

    // 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)) {
      try {
        link.resolveSymbolicLinks();
        fail();
      } catch (IOException e) {
        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)) {
      try {
        link1.resolveSymbolicLinks();
        fail();
      } catch (IOException e) {
        assertThat(e).hasMessageThat().isEqualTo(link1 + " (Too many levels of symbolic links)");
      }
    }
  }

  @Test
  public void testResolveSymbolicLinksENOENT() {
    if (testFS.supportsSymbolicLinksNatively(xDanglingLink)) {
      try {
        xDanglingLink.resolveSymbolicLinks();
        fail();
      } catch (IOException e) {
        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);
      try {
        badLink.resolveSymbolicLinks();
        fail();
      } catch (IOException e) {
        // ok.  Ideally we would assert "(Not a directory)" in the error
        // message, but that would require yet another stat in the
        // implementation.
      }
    }
  }

  @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());

    try {
      xFile.readSymbolicLink(); // not a link
      fail();
    } catch (NotASymlinkException e) {
      assertThat(e).hasMessageThat().isEqualTo(xFile.toString() + " is not a symlink");
    }

    try {
      xNothing.readSymbolicLink(); // nothing there
      fail();
    } catch (IOException e) {
      assertThat(e).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)) {
      try {
        xChildOfReadonlyDir.createSymbolicLink(xNothing);
        fail();
      } catch (IOException e) {
        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)) {
      try {
        someLink.resolveSymbolicLinks();
      } catch (FileNotFoundException e) {
        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)) {
      try {
        xChildOfMissingDir.createSymbolicLink(xFile);
        fail();
      } catch (FileNotFoundException e) {
        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() {
    try {
      createSymbolicLink(xEmptyDirectory, xFile);
      fail();
    } catch (IOException e) { // => couldn't be created
      assertThat(e).hasMessageThat().isEqualTo(xEmptyDirectory + " (File exists)");
    }
    assertThat(xEmptyDirectory.isDirectory(Symlinks.NOFOLLOW)).isTrue();
  }

  @Test
  public void testCreateSymbolicLinkWhereFileAlreadyExists() {
    try {
      createSymbolicLink(xFile, xEmptyDirectory);
      fail();
    } catch (IOException e) { // => couldn't be created
      assertThat(e).hasMessageThat().isEqualTo(xFile + " (File exists)");
    }
    assertThat(xFile.isFile(Symlinks.NOFOLLOW)).isTrue();
  }

  @Test
  public void testCreateSymbolicLinkWhereDanglingSymlinkAlreadyExists() {
    try {
      createSymbolicLink(xDanglingLink, xFile);
      fail();
    } catch (IOException e) {
      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() {
    try {
      createSymbolicLink(xLinkToDirectory, xNothing);
      fail();
    } catch (IOException e) {
      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);
  }
}
