// 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.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import com.google.devtools.build.lib.vfs.FileSystem.NotASymlinkException;

import org.junit.Before;
import org.junit.Test;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collection;

/**
 * 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);

    assertTrue(linkPath.isSymbolicLink());

    assertTrue(linkPath.isFile());
    assertFalse(linkPath.isFile(Symlinks.NOFOLLOW));
    assertTrue(linkPath.isFile(Symlinks.FOLLOW));

    assertFalse(linkPath.isDirectory());
    assertFalse(linkPath.isDirectory(Symlinks.NOFOLLOW));
    assertFalse(linkPath.isDirectory(Symlinks.FOLLOW));

    if (supportsSymlinks) {
      assertEquals(newPath.toString().length(), linkPath.getFileSize(Symlinks.NOFOLLOW));
      assertEquals(newPath.getFileSize(Symlinks.NOFOLLOW), linkPath.getFileSize());
    }
    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);

    assertTrue(linkPath.isSymbolicLink());
    assertFalse(linkPath.isFile());
    assertTrue(linkPath.isDirectory());
    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 {
    assertEquals(newPath, link1.resolveSymbolicLinks());
    assertEquals(newPath, link2.resolveSymbolicLinks());
  }

  //
  //  createDirectory
  //

  @Test
  public void testCreateDirectoryWhereDanglingSymlinkAlreadyExists() {
    try {
      xDanglingLink.createDirectory();
      fail();
    } catch (IOException e) {
      assertThat(e).hasMessage(xDanglingLink + " (File exists)");
    }
    assertTrue(xDanglingLink.isSymbolicLink()); // still a symbolic link
    assertFalse(xDanglingLink.isDirectory(Symlinks.FOLLOW)); // link still dangles
  }

  @Test
  public void testCreateDirectoryWhereSymlinkAlreadyExists() {
    try {
      xLinkToDirectory.createDirectory();
      fail();
    } catch (IOException e) {
      assertThat(e).hasMessage(xLinkToDirectory + " (File exists)");
    }
    assertTrue(xLinkToDirectory.isSymbolicLink()); // still a symbolic link
    assertTrue(xLinkToDirectory.isDirectory(Symlinks.FOLLOW)); // 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 = new PathFragment(linkTarget);
      linkPath.delete();
      createSymbolicLink(linkPath, relative);
      if (supportsSymlinks) {
        assertEquals(linkTarget.length(), linkPath.getFileSize(Symlinks.NOFOLLOW));
        assertEquals(relative, linkPath.readSymbolicLink());
      }
    }
  }

  @Test
  public void testLinkToRootResolvesCorrectly() throws IOException {
    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 (Path p : testFS.getDirectoryEntries(rootPath)) {
      if (!p.isSymbolicLink() && p.isDirectory()) {
        nonLinkEntry = p.getBaseName();
        break;
      }
    }
    
    assertNotNull(nonLinkEntry);
    Path rootChild = testFS.getPath("/" + nonLinkEntry);
    assertEquals(rootChild, linkPath.getRelative(nonLinkEntry).resolveSymbolicLinks());
  }

  @Test
  public void testLinkToFragmentContainingLinkResolvesCorrectly() throws IOException {
    Path link1 = absolutize("link1");
    PathFragment link1target = new PathFragment("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
    assertEquals(link1.resolveSymbolicLinks(), link2target.getRelative("foo"));
  }

  //
  //  readSymbolicLink / resolveSymbolicLinks
  //

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

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

  @Test
  public void testResolveSymbolicLinksENOENT() {
    if (supportsSymlinks) {
      try {
        xDanglingLink.resolveSymbolicLinks();
        fail();
      } catch (IOException e) {
        assertThat(e).hasMessage(xNothing + " (No such file or directory)");
      }
    }
  }

  @Test
  public void testResolveSymbolicLinksENOTDIR() throws IOException {
    if (supportsSymlinks) {
      Path badLinkTarget = xFile.getChild("bad"); // parent is not a directory!
      Path badLink = absolutize("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 (supportsSymlinks) {
      // 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, new PathFragment(prefix + xFile.relativeTo(ancestor)));
        assertEquals(xFile, xLinkToFile.resolveSymbolicLinks());

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

  @Test
  public void testReadSymbolicLink() throws IOException {
    if (supportsSymlinks) {
      assertEquals(xNothing.toString(),
                   xDanglingLink.readSymbolicLink().toString());
    }

    assertEquals(xFile.toString(),
                 xLinkToFile.readSymbolicLink().toString());

    assertEquals(xEmptyDirectory.toString(),
                 xLinkToDirectory.readSymbolicLink().toString());

    try {
      xFile.readSymbolicLink(); // not a link
      fail();
    } catch (NotASymlinkException e) {
      assertThat(e).hasMessage(xFile.toString());
    }

    try {
      xNothing.readSymbolicLink(); // nothing there
      fail();
    } catch (IOException e) {
      assertThat(e).hasMessage(xNothing + " (No such file or directory)");
    }
  }

  @Test
  public void testCannotCreateSymbolicLinkWithReadOnlyParent()
      throws IOException {
    xEmptyDirectory.setWritable(false);
    Path xChildOfReadonlyDir = xEmptyDirectory.getChild("x");
    if (supportsSymlinks) {
      try {
        xChildOfReadonlyDir.createSymbolicLink(xNothing);
        fail();
      } catch (IOException e) {
        assertThat(e).hasMessage(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);
    assertTrue(someLink.isSymbolicLink());
    assertTrue(someLink.exists(Symlinks.NOFOLLOW)); // the link itself exists
    assertFalse(someLink.exists()); // ...but the referent doesn't
    if (supportsSymlinks) {
      try {
        someLink.resolveSymbolicLinks();
      } catch (FileNotFoundException e) {
        assertThat(e).hasMessage(newPath.getParentDirectory() + " (No such file or directory)");
      }
    }
  }

  @Test
  public void testCannotCreateSymbolicLinkWithoutParent() throws IOException {
    Path xChildOfMissingDir = xNothing.getChild("x");
    if (supportsSymlinks) {
      try {
        xChildOfMissingDir.createSymbolicLink(xFile);
        fail();
      } catch (FileNotFoundException e) {
        assertThat(e.getMessage()).endsWith(" (No such file or directory)");
      }
    }
  }

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

  @Test
  public void testCreateSymbolicLinkWhereDirectoryAlreadyExists() {
    try {
      createSymbolicLink(xEmptyDirectory, xFile);
      fail();
    } catch (IOException e) { // => couldn't be created
      assertThat(e).hasMessage(xEmptyDirectory + " (File exists)");
    }
    assertTrue(xEmptyDirectory.isDirectory(Symlinks.NOFOLLOW));
  }

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

  @Test
  public void testCreateSymbolicLinkWhereDanglingSymlinkAlreadyExists() {
    try {
      createSymbolicLink(xDanglingLink, xFile);
      fail();
    } catch (IOException e) {
      assertThat(e).hasMessage(xDanglingLink + " (File exists)");
    }
    assertTrue(xDanglingLink.isSymbolicLink()); // still a symbolic link
    assertFalse(xDanglingLink.isDirectory()); // link still dangles
  }

  @Test
  public void testCreateSymbolicLinkWhereSymlinkAlreadyExists() {
    try {
      createSymbolicLink(xLinkToDirectory, xNothing);
      fail();
    } catch (IOException e) {
      assertThat(e).hasMessage(xLinkToDirectory + " (File exists)");
    }
    assertTrue(xLinkToDirectory.isSymbolicLink()); // still a symbolic link
    assertTrue(xLinkToDirectory.isDirectory()); // 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);

    assertEquals(xEmptyDirectory.getDirectoryEntries().size(), 2);

    assertTrue(someLink.delete());
    assertEquals(xEmptyDirectory.getDirectoryEntries().size(), 1);

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

  // Testing the links
  @Test
  public void testLinkFollowedToDirectory() throws IOException {
    Path theDirectory = absolutize("foo/");
    assertTrue(theDirectory.createDirectory());
    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);
    assertTrue(newPath2.createDirectory());

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

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

    assertFalse(linkPath1.isFile());
    assertFalse(linkPath2.isDirectory());
  }

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

    assertEquals(testData,resultData);
  }

  //
  // 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"
    assertTrue(a.exists()); // = exists(FOLLOW)
    assertTrue(b.exists()); // = exists(FOLLOW)
    assertTrue(a.exists(Symlinks.FOLLOW));
    assertTrue(b.exists(Symlinks.FOLLOW));
    assertTrue(a.exists(Symlinks.NOFOLLOW));
    assertTrue(b.exists(Symlinks.NOFOLLOW));
    b.delete(); // "a" is now a dangling link
    assertFalse(a.exists()); // = exists(FOLLOW)
    assertFalse(b.exists()); // = exists(FOLLOW)
    assertFalse(a.exists(Symlinks.FOLLOW));
    assertFalse(b.exists(Symlinks.FOLLOW));

    assertTrue(a.exists(Symlinks.NOFOLLOW)); // symlink still exists
    assertFalse(b.exists(Symlinks.NOFOLLOW));
  }

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

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

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

    assertFalse(aliasToChild.exists());
    FileSystemUtils.createEmptyFile(child);
    assertTrue(aliasToChild.exists());
    assertTrue(aliasToChild.isFile());
    assertFalse(aliasToChild.isDirectory());

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

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

    assertFalse(linkToChildDir.exists());
    childDir.createDirectory();
    assertTrue(linkToChildDir.exists());
    assertTrue(linkToChildDir.isDirectory());
    assertFalse(linkToChildDir.isFile());

    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");

    assertFalse(linkToChildDir.exists());
    childDir.createDirectory();
    assertTrue(linkToChildDir.exists());
    assertTrue(linkToChildDir.isDirectory());
    assertFalse(linkToChildDir.isFile());

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

  private void validateLinkedReferenceObeysReadOnly(Path path, Path link) throws IOException {
    path.setWritable(false);
    assertFalse(path.isWritable());
    assertFalse(link.isWritable());
    path.setWritable(true);
    assertTrue(path.isWritable());
    assertTrue(link.isWritable());
    path.setWritable(false);
    assertFalse(path.isWritable());
    assertFalse(link.isWritable());
  }

  private void validateLinkedReferenceObeysExecutable(Path path, Path link) throws IOException {
    path.setExecutable(true);
    assertTrue(path.isExecutable());
    assertTrue(link.isExecutable());
    path.setExecutable(false);
    assertFalse(path.isExecutable());
    assertFalse(link.isExecutable());
    path.setExecutable(true);
    assertTrue(path.isExecutable());
    assertTrue(link.isExecutable());
  }

  @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);
    assertArrayEquals(outputData, inputData);
  }

  @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);
    assertArrayEquals(outputData, inputData);
  }
}
