Java Code Examples for java.nio.file.Files#createSymbolicLink()

The following examples show how to use java.nio.file.Files#createSymbolicLink() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: TransformWorkTest.java    From copybara with Apache License 2.0 6 votes vote down vote up
@Test
public void testSymlinks_outside() throws IOException, ValidationException {
  Path base = Files.createDirectories(workdir.resolve("foo"));
  Path tempFile = Files.createTempFile("foo", "bar");

  Files.write(tempFile, "THE CONTENT".getBytes(UTF_8));
  Files.createSymbolicLink(base.resolve("symlink"), tempFile);

  Transformation transformation = skylark.eval("transformation", ""
      + "def test(ctx):\n"
      + "    ctx.new_path('foo/symlink').read_symlink()\n"
      + "\n"
      + "transformation = core.transform([test])");

  ValidationException e =
      assertThrows(
          ValidationException.class,
          () -> transformation.transform(TransformWorks.of(workdir, "test", console)));
  assertThat(e).hasMessageThat().contains("points to a file outside the checkout dir");
}
 
Example 2
Source File: CompressArchiveUtilTest.java    From docker-java with Apache License 2.0 6 votes vote down vote up
@Test
public void tarWithfolderAsInputAndNestedSymbolicLinkFile() throws Exception {
    Path archiveSourceDir = tempFolder.newFolder("archive-source").toPath();
    Path linkTargetFile = tempFolder.newFile("link-target").toPath();
    Path symlinkFile = archiveSourceDir.resolve("symlinkFile");
    Files.createSymbolicLink(symlinkFile, linkTargetFile);

    // ChildrenOnly = false
    Path tarGzFile = tempFolder.newFile("archive.tar.gz").toPath();
    CompressArchiveUtil.tar(archiveSourceDir, tarGzFile, true, false);
    assertEquals(2, getNumberOfEntryInArchive(tarGzFile.toFile()));
    assertTarArchiveEntryIsDirectory(tarGzFile.toFile(), "archive-source");
    assertTarArchiveEntryIsSymlink(tarGzFile.toFile(), "symlinkFile", linkTargetFile.toString());

    // ChildrenOnly = true
    tarGzFile = tempFolder.newFile("archiveChildrenOnly.tar.gz").toPath();
    CompressArchiveUtil.tar(archiveSourceDir, tarGzFile, true, true);
    assertEquals(1, getNumberOfEntryInArchive(tarGzFile.toFile()));
    assertTarArchiveEntryIsSymlink(tarGzFile.toFile(), "symlinkFile", linkTargetFile.toString());
}
 
Example 3
Source File: LinksTest.java    From openjdk-jdk8u with GNU General Public License v2.0 6 votes vote down vote up
public static void main(String args[])
            throws Exception {
//      mkdir tmp
//      cp ${TESTSRC}/b/B.java tmp
        ToolBox.writeFile(Paths.get("tmp/B.java"), BSrc);

        // Try to set up a symbolic link for the test.
//        ln -s `pwd`/tmp "${TESTCLASSES}/a"
        try {
            Files.createSymbolicLink(Paths.get("a"), Paths.get("tmp"));
            System.err.println("Created symbolic link");
        } catch (UnsupportedOperationException | IOException e) {
            System.err.println("Problem creating symbolic link: " + e);
            System.err.println("Test cannot continue; test passed by default");
            return;
        }

        // If symbolic link was successfully created,
        // try a compilation that will use it.
        ////"${TESTJAVA}/bin/javac" ${TESTTOOLVMOPTS} -sourcepath "${TESTCLASSES}" -d "${TESTCLASSES}/classes" "${TESTSRC}/T.java" 2>&1
        ToolBox.JavaToolArgs javacArgs =
                new ToolBox.JavaToolArgs()
                .setOptions("-sourcepath", ".", "-d", ".").setSources(TSrc);
        ToolBox.javac(javacArgs);
    }
 
Example 4
Source File: LinksTest.java    From hottub with GNU General Public License v2.0 6 votes vote down vote up
public static void main(String args[])
            throws Exception {
//      mkdir tmp
//      cp ${TESTSRC}/b/B.java tmp
        ToolBox.writeFile(Paths.get("tmp/B.java"), BSrc);

        // Try to set up a symbolic link for the test.
//        ln -s `pwd`/tmp "${TESTCLASSES}/a"
        try {
            Files.createSymbolicLink(Paths.get("a"), Paths.get("tmp"));
            System.err.println("Created symbolic link");
        } catch (UnsupportedOperationException | IOException e) {
            System.err.println("Problem creating symbolic link: " + e);
            System.err.println("Test cannot continue; test passed by default");
            return;
        }

        // If symbolic link was successfully created,
        // try a compilation that will use it.
        ////"${TESTJAVA}/bin/javac" ${TESTTOOLVMOPTS} -sourcepath "${TESTCLASSES}" -d "${TESTCLASSES}/classes" "${TESTSRC}/T.java" 2>&1
        ToolBox.JavaToolArgs javacArgs =
                new ToolBox.JavaToolArgs()
                .setOptions("-sourcepath", ".", "-d", ".").setSources(TSrc);
        ToolBox.javac(javacArgs);
    }
 
Example 5
Source File: FileUtilTest.java    From copybara with Apache License 2.0 6 votes vote down vote up
@Test
public void testCopyFilesRecursively_symlink_to_other_root() throws Exception{
  Path orig = Files.createDirectory(temp.resolve("orig"));
  Path dest = Files.createDirectory(temp.resolve("dest"));

  Files.createDirectory(orig.resolve("foo"));
  Files.createDirectory(orig.resolve("bar"));

  Files.write(orig.resolve("bar/bar.txt"), new byte[]{});
  Files.createSymbolicLink(orig.resolve("foo/foo.txt"),
      orig.getFileSystem().getPath("../bar/bar.txt"));

  FileUtil.copyFilesRecursively(orig, dest, FAIL_OUTSIDE_SYMLINKS,
      Glob.createGlob(ImmutableList.of("foo/**", "bar/**")));

}
 
Example 6
Source File: SimpleFileFinderTest.java    From synopsys-detect with Apache License 2.0 6 votes vote down vote up
@UnitTest
@DisabledOnOs(WINDOWS)
public void testSymlinksNotFollowed() throws IOException {
    // Create a subDir with a symlink that loops back to its parent
    final File initialDirectory = initialDirectoryPath.toFile();
    final File subDir = new File(initialDirectory, "sub");
    subDir.mkdirs();
    final File link = new File(subDir, "linkToInitial");
    final Path linkPath = link.toPath();
    Files.createSymbolicLink(linkPath, initialDirectoryPath);

    final File regularDir = new File(subDir, "regularDir");
    regularDir.mkdir();
    final File regularFile = new File(subDir, "regularFile");
    regularFile.createNewFile();

    final SimpleFileFinder finder = new SimpleFileFinder();
    final List<String> filenamePatterns = Arrays.asList("sub", "linkToInitial", "regularDir", "regularFile");
    final List<File> foundFiles = finder.findFiles(initialDirectoryPath.toFile(), filenamePatterns, 10);

    // make sure symlink not followed during dir traversal
    assertEquals(4, foundFiles.size());
}
 
Example 7
Source File: CliArchiveIT.java    From digdag with Apache License 2.0 5 votes vote down vote up
@Test
public void rejectSymlinksPointingParentFiles()
        throws Exception
{
    Path sub = Files.createDirectories(projectDir.resolve("sub"));

    // sub/from1 points ../to1 => should success
    Files.createSymbolicLink(sub.resolve("from1"), Paths.get("..").resolve("to1"));
    CommandStatus status1 = main(
            "archive",
            "--project", projectDir.toString(),
            "--output", "test_archive.tar.gz",
            "-c", config.toString()
    );
    assertThat(status1.errUtf8(), status1.code(), is(0));

    // sub/from1 points ../../to1 => should fail
    Files.createSymbolicLink(sub.resolve("from2"), Paths.get("..").resolve("..").resolve("to2"));
    CommandStatus status2 = main(
            "archive",
            "--project", projectDir.toString(),
            "--output", "test_archive.tar.gz",
            "-c", config.toString()
    );
    assertThat(status2.errUtf8(), status2.code(), is(1));
    assertThat(status2.errUtf8(), containsString("is outside of project directory"));
}
 
Example 8
Source File: DefaultImageBuilder.java    From openjdk-jdk9 with GNU General Public License v2.0 5 votes vote down vote up
private void writeSymLinkEntry(Path dstFile, Path target) throws IOException {
    Objects.requireNonNull(dstFile);
    Objects.requireNonNull(target);
    Files.createDirectories(Objects.requireNonNull(dstFile.getParent()));
    if (!isWindows() && root.getFileSystem()
                            .supportedFileAttributeViews()
                            .contains("posix")) {
        Files.createSymbolicLink(dstFile, target);
    } else {
        try (BufferedWriter writer = Files.newBufferedWriter(dstFile)) {
            writer.write(String.format("Please see %s%n", target.toString()));
        }
    }
}
 
Example 9
Source File: SymbolicLinkReconcileTest.java    From p4ic4idea with Apache License 2.0 5 votes vote down vote up
@Test
public void testReconcileDoesNotChangeFolderPermissions() throws Exception {
	attemptCleanupFiles(client);
	Path folderName = Paths.get(client.getRoot() + File.separator + "symlinks" + File.separator + "subfolder");
	Path testFilePath = Paths.get(folderName + File.separator + "test1.txt");
	createFileOnDisk(testFilePath.toString());
	File testFile = createFileObject(testFilePath.toString());

	// Create symbolic link
	Path symlinkFilePath = Paths.get(client.getRoot() + File.separator + "symlinks" + File.separator + "symlink");
	Files.createSymbolicLink(symlinkFilePath, folderName);
	File symlinkFile = createFileObject(symlinkFilePath.toString());
	IChangelist change = createNewChangelist(client, "Create sym link, a folder and a file in that folder");
	AddFileToChangelist(testFile, change, client);
	AddFileToChangelist(symlinkFile, change, client);
	submitChangelist(change);

	// Run reconcile.
	List<IFileSpec> files = client.reconcileFiles(
			FileSpecBuilder.makeFileSpecList(depotTestPath),
			new ReconcileFilesOptions().setUseWildcards(true).setOutsideAdd(true).setOutsideEdit(true));
	assertNotNull(files);

	assertTrue(files.get(0).getOpStatus().toString().equals("ERROR"));

	Path testP = Paths.get(client.getRoot() + File.separator + File.separator + "symlinks");
	assertTrue(testP.toFile().isDirectory());
	assertTrue(testP.toFile().canExecute());
}
 
Example 10
Source File: DatabaseUtilsTest.java    From aion with MIT License 5 votes vote down vote up
@Test
public void testVerifyLevelDBfileTypeWithLinkDBPath() throws IOException, InvalidFileTypeException {

    File options = new File(linkedDB, "123.ldb");
    options.createNewFile();

    File symbolicLink = new File(testDB, dbName);

    Files.createSymbolicLink(symbolicLink.toPath(), linkedDB.toPath());
    DatabaseUtils.verifyDBfileType(testDB, levelDB);
}
 
Example 11
Source File: LocalJobExecutor.java    From jobson with Apache License 2.0 5 votes vote down vote up
private static void softLinkJobDependency(Path source, Path destination) {
    log.debug("softlink dependency: " + source.toString() + " -> " + destination.toString());
    try {
        Files.createSymbolicLink(destination, source);
    } catch (UnsupportedOperationException | IOException ex) {
        log.error(source.toString() + ": cannot create soft link: " + ex.toString());
    }
}
 
Example 12
Source File: JimfsWindowsLikeFileSystemTest.java    From jimfs with Apache License 2.0 5 votes vote down vote up
@Test
public void testPaths_toRealPath() throws IOException {
  Files.createDirectories(path("C:\\foo\\bar"));
  Files.createSymbolicLink(path("C:\\link"), path("C:\\"));

  assertThatPath(path("C:\\link\\foo\\bar").toRealPath()).isEqualTo(path("C:\\foo\\bar"));

  assertThatPath(path("").toRealPath()).isEqualTo(path("C:\\work"));
  assertThatPath(path(".").toRealPath()).isEqualTo(path("C:\\work"));
  assertThatPath(path("..").toRealPath()).isEqualTo(path("C:\\"));
  assertThatPath(path("..\\..").toRealPath()).isEqualTo(path("C:\\"));
  assertThatPath(path(".\\..\\.\\..").toRealPath()).isEqualTo(path("C:\\"));
  assertThatPath(path(".\\..\\.\\..\\.").toRealPath()).isEqualTo(path("C:\\"));
}
 
Example 13
Source File: DatabaseUtilsTest.java    From aion with MIT License 5 votes vote down vote up
@Test
public void testVerifyRocksDBfileTypeWithLinkDBPath() throws IOException, InvalidFileTypeException {

    File options = new File(linkedDB, "OPTIONS-123");
    options.createNewFile();

    File symbolicLink = new File(testDB, dbName);

    Files.createSymbolicLink(symbolicLink.toPath(), linkedDB.toPath());
    DatabaseUtils.verifyDBfileType(testDB, rocksDB);
}
 
Example 14
Source File: EurostagDDBTest.java    From ipst with Mozilla Public License 2.0 5 votes vote down vote up
@Test
public void testLinkDirectory() throws IOException {
    try (FileSystem fs = Jimfs.newFileSystem(Configuration.unix())) {
        Path folder = Files.createDirectory(fs.getPath("/folder"));
        Path file = Files.createFile(folder.resolve("generator.tg"));
        Path linkFolder = Files.createSymbolicLink(fs.getPath("/work/folder.link"), folder);

        EurostagDDB eurostagDDB = new EurostagDDB(Collections.singletonList(linkFolder));
        assertEquals(file, eurostagDDB.findGenerator("generator"));
    }
}
 
Example 15
Source File: JimfsUnixLikeFileSystemTest.java    From jimfs with Apache License 2.0 5 votes vote down vote up
@Test
public void testDirectories_creatingNonDirectoryDoesNotAddLinkToParent() throws IOException {
  Files.createDirectory(path("/foo"));
  Files.createFile(path("/foo/file"));
  Files.createSymbolicLink(path("/foo/fileSymlink"), path("file"));
  Files.createLink(path("/foo/link"), path("/foo/file"));
  Files.createSymbolicLink(path("/foo/fooSymlink"), path("/foo"));

  assertThatPath("/foo").hasLinkCount(2);
}
 
Example 16
Source File: IOUtilsTest.java    From google-http-java-client with Apache License 2.0 5 votes vote down vote up
public void testIsSymbolicLink_true() throws IOException {
  File file = File.createTempFile("tmp", null);
  file.deleteOnExit();
  File file2 = new File(file.getCanonicalPath() + "2");
  file2.deleteOnExit();
  Files.createSymbolicLink(file2.toPath(), file.toPath());

  assertTrue(IOUtils.isSymbolicLink(file2));
}
 
Example 17
Source File: WorkspaceTest.java    From WebIDE-Backend with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
@Test
public void testCheckLinkForNestedLink() throws IOException {

    ws.create("a");

    Files.createSymbolicLink(Paths.get(ws.getWorkingDir().getAbsolutePath(), "0"),
            Paths.get(ws.getWorkingDir().getAbsolutePath(), "a").toAbsolutePath());

    for (int i = 0; i < 30; i++) {

        Files.createSymbolicLink(Paths.get(ws.getWorkingDir().getAbsolutePath(), "" + (i + 1)),
                Paths.get(ws.getWorkingDir().getAbsolutePath(), "" + i).toAbsolutePath());

    }

    exception.expect(WorkspaceIOException.class);
    exception.expectMessage("It's a illegal link: too many nested symlinks.");
    ws.linkTargetExist(ws.getPath("30"));
}
 
Example 18
Source File: TestAppBundleGenerator.java    From dremio-oss with Apache License 2.0 4 votes vote down vote up
@Test
public void testJarBundle() throws IOException {
  // Create several files under a temporary folder
  Path mainFolder = temporaryFolder.newFolder().toPath();
  Path outsideFolder = temporaryFolder.newFolder().toPath();

  Files.write(outsideFolder.resolve("linktofoo.jar"), Arrays.asList("some random content"), UTF_8);
  Files.write(mainFolder.resolve("bar.jar"), Arrays.asList("different random content"), UTF_8);
  Files.createSymbolicLink(mainFolder.resolve("foo.jar"), outsideFolder.resolve("linktofoo.jar"));
  Files.createDirectory(mainFolder.resolve("dir"));
  Files.write(mainFolder.resolve("dir/a.class"), Arrays.asList("random stuff"), UTF_8);
  Files.write(mainFolder.resolve("dir/b.class"), Arrays.asList("more random stuff"), UTF_8);
  Files.write(mainFolder.resolve("prefix.jar"), Arrays.asList("extra random stuff"), UTF_8);
  Files.write(mainFolder.resolve("suffix.jar"), Arrays.asList("more extra random stuff"), UTF_8);
  Files.createDirectory(mainFolder.resolve("lib"));
  Files.createDirectory(mainFolder.resolve("plugins"));
  Files.createDirectory(mainFolder.resolve("plugins/connectors"));
  Files.write(mainFolder.resolve("plugins/connectors/test-pf4j.jar"), Arrays.asList("fake pf4j stuff"), UTF_8);
  Files.write(mainFolder.resolve("lib/a.so"), Arrays.asList("some fake stuff"), UTF_8);
  Files.write(mainFolder.resolve("lib/b.so"), Arrays.asList("more fake stuff"), UTF_8);

  final Path jarPath;
  try(
      URLClassLoader classLoader = new URLClassLoader(new URL[] {
          mainFolder.resolve("foo.jar").toUri().toURL(),
          mainFolder.resolve("bar.jar").toUri().toURL(),
          mainFolder.resolve("dir").toUri().toURL(),
          }, null)) {
    AppBundleGenerator generator = new AppBundleGenerator(
        classLoader,
        ImmutableList.of(mainFolder.resolve("prefix.jar").toString()),
        ImmutableList.of(mainFolder.resolve("suffix.jar").toString()),
        ImmutableList.of(mainFolder.resolve("lib").toString()),
        mainFolder.resolve("plugins")
    );

    jarPath = generator.generateBundle();
  }

  try(JarFile jarFile = new JarFile(jarPath.toFile())) {
    // verify manifest
    Manifest mf = jarFile.getManifest();
    assertThat(mf, is(CoreMatchers.notNullValue()));
    assertThat(mf.getMainAttributes().get(Attributes.Name.CLASS_PATH),
        is(Arrays.asList("prefix.jar", "foo.jar", "bar.jar", "dir", "suffix.jar").stream()
            .map(s -> "dremio.app".concat(mainFolder.resolve(s).toAbsolutePath().toString()))
            .collect(Collectors.joining(" "))));
    assertThat(mf.getMainAttributes().getValue(AppBundleGenerator.X_DREMIO_LIBRARY_PATH_MANIFEST_ATTRIBUTE),
        is(Arrays.asList("lib").stream()
            .map(s -> "dremio.app".concat(mainFolder.resolve(s).toAbsolutePath().toString()))
            .collect(Collectors.joining(" "))));
    assertThat(mf.getMainAttributes().getValue(AppBundleGenerator.X_DREMIO_PLUGINS_PATH_MANIFEST_ATTRIBUTE),
        is("dremio.app".concat(mainFolder.resolve("plugins").toAbsolutePath().toString()))
      );

    // verify content
    ImmutableMap<String, String> content = ImmutableMap.<String, String> builder()
        .put("foo.jar", "some random content\n")
        .put("bar.jar", "different random content\n")
        .put("dir/a.class", "random stuff\n")
        .put("dir/b.class", "more random stuff\n")
        .put("prefix.jar", "extra random stuff\n")
        .put("suffix.jar", "more extra random stuff\n")
        .put("lib/a.so", "some fake stuff\n")
        .put("lib/b.so", "more fake stuff\n")
        .put("plugins/connectors/test-pf4j.jar", "fake pf4j stuff\n")
      .build();

    for(Map.Entry<String, String> entry: content.entrySet()) {
      assertThat(format("Invalid content for %s", entry.getKey()),
          ByteStreams.toByteArray(
          jarFile.getInputStream(new JarEntry("dremio.app".concat(mainFolder.resolve(entry.getKey()).toAbsolutePath().toString())))),
          is(entry.getValue().getBytes(UTF_8)));
    }
  }
}
 
Example 19
Source File: PreserveFiltersTest.java    From ecs-sync with Apache License 2.0 4 votes vote down vote up
@Test
    public void testRestoreSymLink() throws Exception {
        // can only change ownership if root
        boolean isRoot = "root".equals(System.getProperty("user.name"));
        if (isRoot) log.warn("detected root execution");

        String file = "concrete-file", link = "sym-link";
        int gid = 10;
        // write concrete file
        try (OutputStream out = new FileOutputStream(new File(sourceDir, file))) {
            StreamUtil.copy(new RandomInputStream(1024), out, 1024);
        }

        Files.createSymbolicLink(Paths.get(sourceDir.getPath(), link), Paths.get(file));

        if (isRoot) {
            Files.setAttribute(Paths.get(sourceDir.getPath(), file), "unix:gid", gid, LinkOption.NOFOLLOW_LINKS);
            Files.setAttribute(Paths.get(sourceDir.getPath(), link), "unix:gid", gid, LinkOption.NOFOLLOW_LINKS);
        }

        Date fileMtime = new Date(Files.getLastModifiedTime(Paths.get(sourceDir.getPath(), file)).toMillis());
        Date linkMtime = new Date(Files.getLastModifiedTime(Paths.get(sourceDir.getPath(), link), LinkOption.NOFOLLOW_LINKS).toMillis());

        Thread.sleep(5000);

        FilesystemConfig fsConfig = new FilesystemConfig();
        fsConfig.setPath(sourceDir.getPath());
        TestConfig testConfig = new TestConfig().withReadData(true).withDiscardData(false);
        PreserveFileAttributesConfig preserveConfig = new PreserveFileAttributesConfig();

        EcsSync sync = new EcsSync();
        sync.setSyncConfig(new SyncConfig().withSource(fsConfig).withTarget(testConfig)
                .withFilters(Collections.singletonList(preserveConfig)));
        sync.run();

        TestStorage testStorage = (TestStorage) sync.getTarget();

        Assert.assertEquals(2, sync.getStats().getObjectsComplete());
        Assert.assertEquals(0, sync.getStats().getObjectsFailed());

        fsConfig.setPath(targetDir.getPath());

        sync = new EcsSync();
        sync.setSyncConfig(new SyncConfig().withTarget(fsConfig)
                .withFilters(Collections.singletonList(new RestoreFileAttributesConfig())));
        sync.setSource(testStorage);
        sync.run();

        Assert.assertEquals(2, sync.getStats().getObjectsComplete());
        Assert.assertEquals(0, sync.getStats().getObjectsFailed());

        Thread.sleep(2000); // make sure cache is settled (avoid stale attributes)

        if (isRoot) {
            Assert.assertEquals(gid, Files.getAttribute(Paths.get(targetDir.getPath(), file), "unix:gid", LinkOption.NOFOLLOW_LINKS));
            Assert.assertEquals(gid, Files.getAttribute(Paths.get(targetDir.getPath(), link), "unix:gid", LinkOption.NOFOLLOW_LINKS));
        }

        Date tFileMtime = new Date(Files.getLastModifiedTime(Paths.get(targetDir.getPath(), file)).toMillis());
        Date tLinkMtime = new Date(Files.getLastModifiedTime(Paths.get(targetDir.getPath(), link), LinkOption.NOFOLLOW_LINKS).toMillis());

        Assert.assertEquals(fileMtime.getTime() / 10, tFileMtime.getTime() / 10);
//        Assert.assertEquals(linkMtime, tLinkMtime); // TODO: figure out a way to set mtime on a link in Java
    }
 
Example 20
Source File: StreamTest.java    From jdk8u-jdk with GNU General Public License v2.0 4 votes vote down vote up
public void testWalkFollowLinkLoop() {
    if (!supportsLinks) {
        return;
    }

    // Loops.
    try {
        Path dir = testFolder.resolve("dir");
        Path linkdir = testFolder.resolve("linkDir");
        Path d1 = dir.resolve("d1");
        Path cause = d1.resolve("lnSelf");
        Files.createSymbolicLink(cause, d1);

        // loop in descendant.
        validateFileSystemLoopException(dir, cause);
        // loop in self
        validateFileSystemLoopException(d1, cause);
        // start from other place via link
        validateFileSystemLoopException(linkdir,
                linkdir.resolve(Paths.get("d1", "lnSelf")));
        Files.delete(cause);

        // loop to parent.
        cause = d1.resolve("lnParent");
        Files.createSymbolicLink(cause, dir);

        // loop should be detected at test/dir/d1/lnParent/d1
        validateFileSystemLoopException(d1, cause.resolve("d1"));
        // loop should be detected at link
        validateFileSystemLoopException(dir, cause);
        // loop should be detected at test/linkdir/d1/lnParent
        // which is test/dir we have visited via test/linkdir
        validateFileSystemLoopException(linkdir,
                linkdir.resolve(Paths.get("d1", "lnParent")));
        Files.delete(cause);

        // cross loop
        Path dir2 = testFolder.resolve("dir2");
        cause = dir2.resolve("lnDir");
        Files.createSymbolicLink(cause, dir);
        validateFileSystemLoopException(dir,
                dir.resolve(Paths.get("lnDir2", "lnDir")));
        validateFileSystemLoopException(dir2,
                dir2.resolve(Paths.get("lnDir", "lnDir2")));
        validateFileSystemLoopException(linkdir,
                linkdir.resolve(Paths.get("lnDir2", "lnDir")));
    } catch(IOException ioe) {
        fail("Unexpected IOException " + ioe);
    }
}