public void testSymlinks() throws Exception {
    File scratchDirectory = Files.createTempDir();
    File newFile = createFileIn("New.java", scratchDirectory);
    File rootDirectory = Files.createTempDir();
    File subDirectory = Files.createTempDir();

    ResourceAccumulator resourceAccumulator =
        new ResourceAccumulator(rootDirectory.toPath(), createInclusivePathPrefixSet());

    assertTrue(getResources(resourceAccumulator).isEmpty());

    // Symlink in a subdirectory and then symlink in a contained file.
    java.nio.file.Files.createSymbolicLink(
            new File(rootDirectory, "sublink").toPath(), subDirectory.toPath())
        .toFile();
    java.nio.file.Files.createSymbolicLink(
            new File(subDirectory, "New.java").toPath(), newFile.toPath())
        .toFile();
    waitForFileEvents();

    List<AbstractResource> resources = getResources(resourceAccumulator);
    assertEquals(1, resources.size());
    assertTrue(resources.get(0).getPath().endsWith("sublink/New.java"));

    resourceAccumulator.shutdown();
  }
  public void testSymlinkInfiniteLoop() throws Exception {
    File rootDirectory = Files.createTempDir();
    File subDirectory = Files.createTempDir();

    ResourceAccumulator resourceAccumulator =
        new ResourceAccumulator(rootDirectory.toPath(), createInclusivePathPrefixSet());

    assertTrue(getResources(resourceAccumulator).isEmpty());

    // Symlink in a loop
    java.nio.file.Files.createSymbolicLink(
            new File(rootDirectory, "sublink").toPath(), subDirectory.toPath())
        .toFile();
    java.nio.file.Files.createSymbolicLink(
            new File(subDirectory, "sublink").toPath(), rootDirectory.toPath())
        .toFile();
    createFileIn("New.java", subDirectory);
    waitForFileEvents();

    try {
      // Should throw an error if resourceAccumulator got stuck in an infinite directory scan loop.
      getResources(resourceAccumulator);
      fail();
    } catch (FileSystemException expected) {
      // Expected
    }

    resourceAccumulator.shutdown();
  }
  @BeforeClass
  void setupTestFolder() throws IOException {
    testFolder = TestUtil.createTemporaryDirectory();
    supportsLinks = TestUtil.supportsLinks(testFolder);
    TreeSet<Path> set = new TreeSet<>();

    // Level 1
    Path empty = testFolder.resolve("empty");
    Path file = testFolder.resolve("file");
    Path dir = testFolder.resolve("dir");
    Path dir2 = testFolder.resolve("dir2");
    Files.createDirectory(empty);
    Files.createFile(file);
    Files.createDirectory(dir);
    Files.createDirectory(dir2);
    set.add(empty);
    set.add(file);
    set.add(dir);
    set.add(dir2);
    if (supportsLinks) {
      Path tmp = testFolder.resolve("linkDir");
      Files.createSymbolicLink(tmp, dir);
      set.add(tmp);
      tmp = testFolder.resolve("linkFile");
      Files.createSymbolicLink(tmp, file);
      set.add(tmp);
    }
    level1 = set.toArray(new Path[0]);

    // Level 2
    Path tmp = dir.resolve("d1");
    Files.createDirectory(tmp);
    set.add(tmp);
    tmp = dir.resolve("f1");
    Files.createFile(tmp);
    set.add(tmp);
    if (supportsLinks) {
      tmp = dir.resolve("lnDir2");
      Files.createSymbolicLink(tmp, dir2);
      set.add(tmp);
    }
    // walk include starting folder
    set.add(testFolder);
    all = set.toArray(new Path[0]);

    // Follow links
    if (supportsLinks) {
      tmp = testFolder.resolve("linkDir");
      set.add(tmp.resolve("d1"));
      set.add(tmp.resolve("f1"));
      tmp = tmp.resolve("lnDir2");
      set.add(tmp);
    }
    all_folowLinks = set.toArray(new Path[0]);
  }
  @Test
  public void testResourceBase() throws Exception {
    testdir.ensureEmpty();
    File resBase = testdir.getFile("docroot");
    FS.ensureDirExists(resBase);
    File foobar = new File(resBase, "foobar.txt");
    File link = new File(resBase, "link.txt");
    createFile(foobar, "Foo Bar");

    String resBasePath = resBase.getAbsolutePath();

    ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
    defholder.setInitParameter("resourceBase", resBasePath);
    defholder.setInitParameter("gzip", "false");

    String response;

    response = connector.getResponses("GET /context/foobar.txt HTTP/1.0\r\n\r\n");
    assertResponseContains("Foo Bar", response);

    if (!OS.IS_WINDOWS) {
      Files.createSymbolicLink(link.toPath(), foobar.toPath());
      response = connector.getResponses("GET /context/link.txt HTTP/1.0\r\n\r\n");
      assertResponseContains("404", response);

      context.addAliasCheck(new ContextHandler.ApproveAliases());

      response = connector.getResponses("GET /context/link.txt HTTP/1.0\r\n\r\n");
      assertResponseContains("Foo Bar", response);
    }
  }
  @Test
  public void sanitizeSymlinkedWorkingDirectory() throws IOException {
    TemporaryFolder folder = new TemporaryFolder();
    folder.create();

    // Setup up a symlink to our working directory.
    Path symlinkedRoot = folder.getRoot().toPath().resolve("symlinked-root");
    java.nio.file.Files.createSymbolicLink(symlinkedRoot, tmp.getRootPath());

    // Run the build, setting PWD to the above symlink.  Typically, this causes compilers to use
    // the symlinked directory, even though it's not the right project root.
    Map<String, String> envCopy = Maps.newHashMap(System.getenv());
    envCopy.put("PWD", symlinkedRoot.toString());
    workspace
        .runBuckCommandWithEnvironmentAndContext(
            tmp.getRootPath(),
            Optional.<NGContext>absent(),
            Optional.<BuckEventListener>absent(),
            Optional.of(ImmutableMap.copyOf(envCopy)),
            "build",
            "//:simple#default,static")
        .assertSuccess();

    // Verify that we still sanitized this path correctly.
    Path lib = workspace.getPath("buck-out/gen/simple#default,static/libsimple.a");
    String contents = Files.asByteSource(lib.toFile()).asCharSource(Charsets.ISO_8859_1).read();
    assertFalse(lib.toString(), contents.contains(tmp.getRootPath().toString()));
    assertFalse(lib.toString(), contents.contains(symlinkedRoot.toString()));

    folder.delete();
  }
  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);
    }
  }
 /**
  * Creates a unique symlink to /dev/stdout in a temporary directory, and sets it to delete on
  * exit.
  *
  * @return Path to the symlink.
  * @throws IOException
  */
 private static Path createStdoutSymlink() throws IOException {
   File tempDir = new File(System.getProperty("java.io.tmpdir"));
   final File link =
       new File(tempDir.getAbsolutePath() + "/cantaloupe-" + UUID.randomUUID() + ".tif");
   link.deleteOnExit();
   final File devStdout = new File("/dev/stdout");
   return Files.createSymbolicLink(
       Paths.get(link.getAbsolutePath()), Paths.get(devStdout.getAbsolutePath()));
 }
Exemple #8
0
 /**
  * Creates a symlink at {@code pathToProjectRoot.resolve(pathToDesiredLinkUnderProjectRoot)} that
  * points to {@code pathToProjectRoot.resolve(pathToExistingFileUnderProjectRoot)} using a
  * relative symlink. Both params must be relative to the project root.
  *
  * @param pathToDesiredLinkUnderProjectRoot must reference a file, not a directory.
  * @param pathToExistingFileUnderProjectRoot must reference a file, not a directory.
  * @return the relative path from the new symlink that was created to the existing file.
  */
 public static Path createRelativeSymlink(
     Path pathToDesiredLinkUnderProjectRoot,
     Path pathToExistingFileUnderProjectRoot,
     Path pathToProjectRoot)
     throws IOException {
   Path target =
       getRelativePath(
           pathToExistingFileUnderProjectRoot, pathToDesiredLinkUnderProjectRoot.getParent());
   Files.createSymbolicLink(pathToProjectRoot.resolve(pathToDesiredLinkUnderProjectRoot), target);
   return target;
 }
  /** Create Symbolic Link for the HDFS binary. */
  private void createSymbolicLink() {
    log.info("Creating a symbolic link for HDFS binary");
    try {
      // Find Hdfs binary in sandbox
      File sandboxHdfsBinary = new File(System.getProperty("user.dir"));
      Path sandboxHdfsBinaryPath = Paths.get(sandboxHdfsBinary.getAbsolutePath());

      // Create mesosphere opt dir (parent dir of the symbolic link) if it does not exist
      File frameworkMountDir = new File(hdfsFrameworkConfig.getFrameworkMountPath());
      FileUtils.createDir(frameworkMountDir);

      // Delete and recreate directory for symbolic link every time
      String hdfsBinaryPath =
          hdfsFrameworkConfig.getFrameworkMountPath() + "/" + HDFSConstants.HDFS_BINARY_DIR;
      File hdfsBinaryDir = new File(hdfsBinaryPath);

      // Try to delete the symbolic link in case a dangling link is present
      try {
        ProcessBuilder processBuilder = new ProcessBuilder("unlink", hdfsBinaryPath);
        Process process = processBuilder.start();
        redirectProcess(process);
        int exitCode = process.waitFor();
        if (exitCode != 0) {
          log.info("Unable to unlink old sym link. Link may not exist. Exit code: " + exitCode);
        }
      } catch (IOException e) {
        log.fatal("Could not unlink " + hdfsBinaryPath, e);
        throw e;
      }

      // Delete the file if it exists
      if (hdfsBinaryDir.exists() && !FileUtils.deleteDirectory(hdfsBinaryDir)) {
        String msg = "Unable to delete file: " + hdfsBinaryDir;
        log.error(msg);
        throw new ExecutorException(msg);
      }

      // Create symbolic link
      Path hdfsLinkDirPath = Paths.get(hdfsBinaryPath);
      Files.createSymbolicLink(hdfsLinkDirPath, sandboxHdfsBinaryPath);
      log.info("The linked HDFS binary path is: " + sandboxHdfsBinaryPath);
      log.info("The symbolic link path is: " + hdfsLinkDirPath);
      // Adding binary to the PATH environment variable
      addBinaryToPath(hdfsBinaryPath);
    } catch (IOException | InterruptedException e) {
      String msg = "Error creating the symbolic link to hdfs binary";
      shutdownExecutor(1, msg, e);
    }
  }
Exemple #10
0
  public static void createSymbolicLink(String src, String dest) {
    Path destPath = Paths.get(getPath(dest));
    Path srcPath = Paths.get(src);

    if (Files.notExists(srcPath) || !Files.isDirectory(srcPath)) {
      return;
    }

    if (Files.exists(destPath)) {
      return;
    }

    try {
      Files.createSymbolicLink(destPath, srcPath);
    } catch (IOException e) {
      log.warn(
          String.format("WebdavUtil.createSymbolicLink fail... src : %s, dest : %s", src, dest));
    }
  }
  private void createSoftLinks(String fileName, String logLoc, String gameName) {
    String linkName;
    if (fileName.endsWith("boot.xml")) {
      linkName = String.format("%s%s.boot.xml", logLoc, gameName);
    } else if (fileName.contains("boot")) {
      linkName = String.format("%s%s.boot.tar.gz", logLoc, gameName);
    } else {
      linkName = String.format("%s%s.sim.tar.gz", logLoc, gameName);
    }

    try {
      Path link = Paths.get(linkName);
      Path target = Paths.get(fileName);
      Files.createSymbolicLink(link, target);
    } catch (FileAlreadyExistsException faee) {
      // Ignored
    } catch (IOException | UnsupportedOperationException e) {
      e.printStackTrace();
    }
  }
Exemple #12
0
 public void createSymLink(Path symLink, Path realFile, boolean force) throws IOException {
   symLink = resolve(symLink);
   if (force) {
     Files.deleteIfExists(symLink);
   }
   if (Platform.detect() == Platform.WINDOWS) {
     if (isDirectory(realFile)) {
       // Creating symlinks to directories on Windows requires escalated privileges. We're just
       // going to have to copy things recursively.
       MoreFiles.copyRecursively(realFile, symLink);
     } else {
       // When sourcePath is relative, resolve it from the targetPath. We're creating a hard link
       // anyway.
       realFile = symLink.getParent().resolve(realFile).normalize();
       Files.createLink(symLink, realFile);
     }
   } else {
     Files.createSymbolicLink(symLink, realFile);
   }
 }
Exemple #13
0
  /**
   * Tests that paths containing symbolic links cause a warning
   *
   * @throws Exception
   */
  @Test
  public void testExportWarningForSymbolicLinkPath() throws Exception {
    if (System.getProperty("os.name").startsWith("Win")) {
      // can't create symlinks in windows (borrowed from Apache commonsio)
      return;
    }

    resetInitialState();

    FileUtils.copyFile(SYSTEM_PROPERTIES.toFile(), new File(TEST_FILE));

    Files.createSymbolicLink(symbolicLink, Paths.get(TEST_FILE));

    System.setProperty(KEYSTORE_PROPERTY, symbolicLink.toString());

    String response = console.runCommand(EXPORT_COMMAND);

    assertThat(
        String.format("Should not have been able to export to %s.", getDefaultExportDirectory()),
        response,
        containsString(
            String.format(
                "Failed to export all configurations to %s", getDefaultExportDirectory())));
  }
Exemple #14
0
  public void testSecurityException() throws IOException {
    Path empty = testFolder.resolve("empty");
    Path triggerFile = Files.createFile(empty.resolve("SecurityException"));
    Path sampleFile = Files.createDirectories(empty.resolve("sample"));

    Path dir2 = testFolder.resolve("dir2");
    Path triggerDir = Files.createDirectories(dir2.resolve("SecurityException"));
    Files.createFile(triggerDir.resolve("fileInSE"));
    Path sample = Files.createFile(dir2.resolve("file"));

    Path triggerLink = null;
    Path linkTriggerDir = null;
    Path linkTriggerFile = null;
    if (supportsLinks) {
      Path dir = testFolder.resolve("dir");
      triggerLink = Files.createSymbolicLink(dir.resolve("SecurityException"), empty);
      linkTriggerDir = Files.createSymbolicLink(dir.resolve("lnDirSE"), triggerDir);
      linkTriggerFile = Files.createSymbolicLink(dir.resolve("lnFileSE"), triggerFile);
    }

    FaultyFileSystem.FaultyFSProvider fsp = FaultyFileSystem.FaultyFSProvider.getInstance();
    FaultyFileSystem fs = (FaultyFileSystem) fsp.newFileSystem(testFolder, null);

    try {
      fsp.setFaultyMode(false);
      Path fakeRoot = fs.getRoot();
      // validate setting
      try (Stream<Path> s = Files.list(fakeRoot.resolve("empty"))) {
        String[] result = s.map(path -> path.getFileName().toString()).toArray(String[]::new);
        assertEqualsNoOrder(result, new String[] {"SecurityException", "sample"});
      }

      try (Stream<Path> s = Files.walk(fakeRoot.resolve("dir2"))) {
        String[] result = s.map(path -> path.getFileName().toString()).toArray(String[]::new);
        assertEqualsNoOrder(result, new String[] {"dir2", "SecurityException", "fileInSE", "file"});
      }

      if (supportsLinks) {
        try (Stream<Path> s = Files.list(fakeRoot.resolve("dir"))) {
          String[] result = s.map(path -> path.getFileName().toString()).toArray(String[]::new);
          assertEqualsNoOrder(
              result,
              new String[] {"d1", "f1", "lnDir2", "SecurityException", "lnDirSE", "lnFileSE"});
        }
      }

      // execute test
      fsp.setFaultyMode(true);
      // ignore file cause SecurityException
      try (Stream<Path> s = Files.walk(fakeRoot.resolve("empty"))) {
        String[] result = s.map(path -> path.getFileName().toString()).toArray(String[]::new);
        assertEqualsNoOrder(result, new String[] {"empty", "sample"});
      }
      // skip folder cause SecurityException
      try (Stream<Path> s = Files.walk(fakeRoot.resolve("dir2"))) {
        String[] result = s.map(path -> path.getFileName().toString()).toArray(String[]::new);
        assertEqualsNoOrder(result, new String[] {"dir2", "file"});
      }

      if (supportsLinks) {
        // not following links
        try (Stream<Path> s = Files.walk(fakeRoot.resolve("dir"))) {
          String[] result = s.map(path -> path.getFileName().toString()).toArray(String[]::new);
          assertEqualsNoOrder(
              result, new String[] {"dir", "d1", "f1", "lnDir2", "lnDirSE", "lnFileSE"});
        }

        // following links
        try (Stream<Path> s = Files.walk(fakeRoot.resolve("dir"), FileVisitOption.FOLLOW_LINKS)) {
          String[] result = s.map(path -> path.getFileName().toString()).toArray(String[]::new);
          // ?? Should fileInSE show up?
          // With FaultyFS, it does as no exception thrown for link to "SecurityException" with read
          // on "lnXxxSE"
          assertEqualsNoOrder(
              result,
              new String[] {
                "dir", "d1", "f1", "lnDir2", "file", "lnDirSE", "lnFileSE", "fileInSE"
              });
        }
      }

      // list instead of walk
      try (Stream<Path> s = Files.list(fakeRoot.resolve("empty"))) {
        String[] result = s.map(path -> path.getFileName().toString()).toArray(String[]::new);
        assertEqualsNoOrder(result, new String[] {"sample"});
      }
      try (Stream<Path> s = Files.list(fakeRoot.resolve("dir2"))) {
        String[] result = s.map(path -> path.getFileName().toString()).toArray(String[]::new);
        assertEqualsNoOrder(result, new String[] {"file"});
      }

      // root cause SecurityException should be reported
      try (Stream<Path> s = Files.walk(fakeRoot.resolve("dir2").resolve("SecurityException"))) {
        String[] result = s.map(path -> path.getFileName().toString()).toArray(String[]::new);
        fail("should not reach here due to SecurityException");
      } catch (SecurityException se) {
        assertTrue(se.getCause() instanceof FaultyFileSystem.FaultyException);
      }

      // Walk a file cause SecurityException, we should get SE
      try (Stream<Path> s = Files.walk(fakeRoot.resolve("dir").resolve("SecurityException"))) {
        String[] result = s.map(path -> path.getFileName().toString()).toArray(String[]::new);
        fail("should not reach here due to SecurityException");
      } catch (SecurityException se) {
        assertTrue(se.getCause() instanceof FaultyFileSystem.FaultyException);
      }

      // List a file cause SecurityException, we should get SE as cannot read attribute
      try (Stream<Path> s = Files.list(fakeRoot.resolve("dir2").resolve("SecurityException"))) {
        String[] result = s.map(path -> path.getFileName().toString()).toArray(String[]::new);
        fail("should not reach here due to SecurityException");
      } catch (SecurityException se) {
        assertTrue(se.getCause() instanceof FaultyFileSystem.FaultyException);
      }

      try (Stream<Path> s = Files.list(fakeRoot.resolve("dir").resolve("SecurityException"))) {
        String[] result = s.map(path -> path.getFileName().toString()).toArray(String[]::new);
        fail("should not reach here due to SecurityException");
      } catch (SecurityException se) {
        assertTrue(se.getCause() instanceof FaultyFileSystem.FaultyException);
      }
    } finally {
      // Cleanup
      if (fs != null) {
        fs.close();
      }
      if (supportsLinks) {
        Files.delete(triggerLink);
        Files.delete(linkTriggerDir);
        Files.delete(linkTriggerFile);
      }
      Files.delete(triggerFile);
      Files.delete(sampleFile);
      Files.delete(sample);
      TestUtil.removeAll(triggerDir);
    }
  }
Exemple #15
0
  public static void createSymlink(String targetPathStr, File symlinkFile) throws Exception {
    Path targetPath = Paths.get(targetPathStr);
    Path symlinkPath = Paths.get(symlinkFile.getPath());

    Files.createSymbolicLink(symlinkPath, targetPath);
  }
  /** Tests all possible ways to invoke move */
  static void testMove(Path dir1, Path dir2, boolean supportsLinks) throws IOException {
    Path source, target, entry;

    boolean sameDevice = getFileStore(dir1).equals(getFileStore(dir2));

    // -- regular file --

    /** Test: move regular file, target does not exist */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    moveAndVerify(source, target);
    delete(target);

    /** Test: move regular file, target exists */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    createFile(target);
    try {
      moveAndVerify(source, target);
      throw new RuntimeException("FileAlreadyExistsException expected");
    } catch (FileAlreadyExistsException x) {
    }
    delete(target);
    createDirectory(target);
    try {
      moveAndVerify(source, target);
      throw new RuntimeException("FileAlreadyExistsException expected");
    } catch (FileAlreadyExistsException x) {
    }
    delete(source);
    delete(target);

    /** Test: move regular file, target does not exist */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    moveAndVerify(source, target, REPLACE_EXISTING);
    delete(target);

    /** Test: move regular file, target exists */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    createFile(target);
    moveAndVerify(source, target, REPLACE_EXISTING);
    delete(target);

    /** Test: move regular file, target exists and is empty directory */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    createDirectory(target);
    moveAndVerify(source, target, REPLACE_EXISTING);
    delete(target);

    /** Test: move regular file, target exists and is non-empty directory */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    createDirectory(target);
    entry = target.resolve("foo");
    createFile(entry);
    try {
      moveAndVerify(source, target);
      throw new RuntimeException("FileAlreadyExistsException expected");
    } catch (FileAlreadyExistsException x) {
    }
    delete(entry);
    delete(source);
    delete(target);

    /** Test atomic move of regular file (same file store) */
    source = createSourceFile(dir1);
    target = getTargetFile(dir1);
    moveAndVerify(source, target, ATOMIC_MOVE);
    delete(target);

    /** Test atomic move of regular file (different file store) */
    if (!sameDevice) {
      source = createSourceFile(dir1);
      target = getTargetFile(dir2);
      try {
        moveAndVerify(source, target, ATOMIC_MOVE);
        throw new RuntimeException("AtomicMoveNotSupportedException expected");
      } catch (AtomicMoveNotSupportedException x) {
      }
      delete(source);
    }

    // -- directories --

    /*
     * Test: move empty directory, target does not exist
     */
    source = createSourceDirectory(dir1);
    target = getTargetFile(dir2);
    moveAndVerify(source, target);
    delete(target);

    /** Test: move empty directory, target exists */
    source = createSourceDirectory(dir1);
    target = getTargetFile(dir2);
    createFile(target);
    try {
      moveAndVerify(source, target);
      throw new RuntimeException("FileAlreadyExistsException expected");
    } catch (FileAlreadyExistsException x) {
    }
    delete(target);
    createDirectory(target);
    try {
      moveAndVerify(source, target);
      throw new RuntimeException("FileAlreadyExistsException expected");
    } catch (FileAlreadyExistsException x) {
    }
    delete(source);
    delete(target);

    /** Test: move empty directory, target does not exist */
    source = createSourceDirectory(dir1);
    target = getTargetFile(dir2);
    moveAndVerify(source, target, REPLACE_EXISTING);
    delete(target);

    /** Test: move empty directory, target exists */
    source = createSourceDirectory(dir1);
    target = getTargetFile(dir2);
    createFile(target);
    moveAndVerify(source, target, REPLACE_EXISTING);
    delete(target);

    /** Test: move empty, target exists and is empty directory */
    source = createSourceDirectory(dir1);
    target = getTargetFile(dir2);
    createDirectory(target);
    moveAndVerify(source, target, REPLACE_EXISTING);
    delete(target);

    /** Test: move empty directory, target exists and is non-empty directory */
    source = createSourceDirectory(dir1);
    target = getTargetFile(dir2);
    createDirectory(target);
    entry = target.resolve("foo");
    createFile(entry);
    try {
      moveAndVerify(source, target, REPLACE_EXISTING);
      throw new RuntimeException("DirectoryNotEmptyException expected");
    } catch (DirectoryNotEmptyException x) {
    }
    delete(entry);
    delete(source);
    delete(target);

    /** Test: move non-empty directory (same file system) */
    source = createSourceDirectory(dir1);
    createFile(source.resolve("foo"));
    target = getTargetFile(dir1);
    moveAndVerify(source, target);
    delete(target.resolve("foo"));
    delete(target);

    /** Test: move non-empty directory (different file store) */
    if (!sameDevice) {
      source = createSourceDirectory(dir1);
      createFile(source.resolve("foo"));
      target = getTargetFile(dir2);
      try {
        moveAndVerify(source, target);
        throw new RuntimeException("IOException expected");
      } catch (IOException x) {
      }
      delete(source.resolve("foo"));
      delete(source);
    }

    /** Test atomic move of directory (same file store) */
    source = createSourceDirectory(dir1);
    createFile(source.resolve("foo"));
    target = getTargetFile(dir1);
    moveAndVerify(source, target, ATOMIC_MOVE);
    delete(target.resolve("foo"));
    delete(target);

    // -- symbolic links --

    /** Test: Move symbolic link to file, target does not exist */
    if (supportsLinks) {
      Path tmp = createSourceFile(dir1);
      source = dir1.resolve("link");
      createSymbolicLink(source, tmp);
      target = getTargetFile(dir2);
      moveAndVerify(source, target);
      delete(target);
      delete(tmp);
    }

    /** Test: Move symbolic link to directory, target does not exist */
    if (supportsLinks) {
      source = dir1.resolve("link");
      createSymbolicLink(source, dir2);
      target = getTargetFile(dir2);
      moveAndVerify(source, target);
      delete(target);
    }

    /** Test: Move broken symbolic link, target does not exists */
    if (supportsLinks) {
      Path tmp = Paths.get("doesnotexist");
      source = dir1.resolve("link");
      createSymbolicLink(source, tmp);
      target = getTargetFile(dir2);
      moveAndVerify(source, target);
      delete(target);
    }

    /** Test: Move symbolic link, target exists */
    if (supportsLinks) {
      source = dir1.resolve("link");
      createSymbolicLink(source, dir2);
      target = getTargetFile(dir2);
      createFile(target);
      try {
        moveAndVerify(source, target);
        throw new RuntimeException("FileAlreadyExistsException expected");
      } catch (FileAlreadyExistsException x) {
      }
      delete(source);
      delete(target);
    }

    /** Test: Move regular file, target exists */
    if (supportsLinks) {
      source = dir1.resolve("link");
      createSymbolicLink(source, dir2);
      target = getTargetFile(dir2);
      createFile(target);
      moveAndVerify(source, target, REPLACE_EXISTING);
      delete(target);
    }

    /** Test: move symbolic link, target exists and is empty directory */
    if (supportsLinks) {
      source = dir1.resolve("link");
      createSymbolicLink(source, dir2);
      target = getTargetFile(dir2);
      createDirectory(target);
      moveAndVerify(source, target, REPLACE_EXISTING);
      delete(target);
    }

    /** Test: symbolic link, target exists and is non-empty directory */
    if (supportsLinks) {
      source = dir1.resolve("link");
      createSymbolicLink(source, dir2);
      target = getTargetFile(dir2);
      createDirectory(target);
      entry = target.resolve("foo");
      createFile(entry);
      try {
        moveAndVerify(source, target);
        throw new RuntimeException("FileAlreadyExistsException expected");
      } catch (FileAlreadyExistsException x) {
      }
      delete(entry);
      delete(source);
      delete(target);
    }

    /** Test atomic move of symbolic link (same file store) */
    if (supportsLinks) {
      source = dir1.resolve("link");
      createSymbolicLink(source, dir1);
      target = getTargetFile(dir2);
      createFile(target);
      moveAndVerify(source, target, REPLACE_EXISTING);
      delete(target);
    }

    // -- misc. tests --

    /** Test nulls */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    try {
      move(null, target);
      throw new RuntimeException("NullPointerException expected");
    } catch (NullPointerException x) {
    }
    try {
      move(source, null);
      throw new RuntimeException("NullPointerException expected");
    } catch (NullPointerException x) {
    }
    try {
      move(source, target, (CopyOption[]) null);
      throw new RuntimeException("NullPointerException expected");
    } catch (NullPointerException x) {
    }
    try {
      CopyOption[] opts = {REPLACE_EXISTING, null};
      move(source, target, opts);
      throw new RuntimeException("NullPointerException expected");
    } catch (NullPointerException x) {
    }
    delete(source);

    /** Test UOE */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    try {
      move(source, target, new CopyOption() {});
    } catch (UnsupportedOperationException x) {
    }
    try {
      move(source, target, REPLACE_EXISTING, new CopyOption() {});
    } catch (UnsupportedOperationException x) {
    }
    delete(source);
  }
  /** Tests all possible ways to invoke copy to copy a file to a file */
  static void testCopyFileToFile(Path dir1, Path dir2, boolean supportsLinks) throws IOException {
    Path source, target, link, entry;

    // -- regular file --

    /** Test: move regular file, target does not exist */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    copyAndVerify(source, target);
    delete(source);
    delete(target);

    /** Test: copy regular file, target exists */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    createFile(target);
    try {
      copyAndVerify(source, target);
      throw new RuntimeException("FileAlreadyExistsException expected");
    } catch (FileAlreadyExistsException x) {
    }
    delete(target);
    createDirectory(target);
    try {
      copyAndVerify(source, target);
      throw new RuntimeException("FileAlreadyExistsException expected");
    } catch (FileAlreadyExistsException x) {
    }
    delete(source);
    delete(target);

    /** Test: copy regular file, target does not exist */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    copyAndVerify(source, target, REPLACE_EXISTING);
    delete(source);
    delete(target);

    /** Test: copy regular file, target exists */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    createFile(target);
    copyAndVerify(source, target, REPLACE_EXISTING);
    delete(source);
    delete(target);

    /** Test: copy regular file, target exists and is empty directory */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    createDirectory(target);
    copyAndVerify(source, target, REPLACE_EXISTING);
    delete(source);
    delete(target);

    /** Test: copy regular file, target exists and is non-empty directory */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    createDirectory(target);
    entry = target.resolve("foo");
    createFile(entry);
    try {
      copyAndVerify(source, target);
      throw new RuntimeException("FileAlreadyExistsException expected");
    } catch (FileAlreadyExistsException x) {
    }
    delete(entry);
    delete(source);
    delete(target);

    /** Test: copy regular file + attributes */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    copyAndVerify(source, target, COPY_ATTRIBUTES);
    delete(source);
    delete(target);

    // -- directory --

    /*
     * Test: copy directory, target does not exist
     */
    source = createSourceDirectory(dir1);
    target = getTargetFile(dir2);
    copyAndVerify(source, target);
    delete(source);
    delete(target);

    /** Test: copy directory, target exists */
    source = createSourceDirectory(dir1);
    target = getTargetFile(dir2);
    createFile(target);
    try {
      copyAndVerify(source, target);
      throw new RuntimeException("FileAlreadyExistsException expected");
    } catch (FileAlreadyExistsException x) {
    }
    delete(target);
    createDirectory(target);
    try {
      copyAndVerify(source, target);
      throw new RuntimeException("FileAlreadyExistsException expected");
    } catch (FileAlreadyExistsException x) {
    }
    delete(source);
    delete(target);

    /** Test: copy directory, target does not exist */
    source = createSourceDirectory(dir1);
    target = getTargetFile(dir2);
    copyAndVerify(source, target, REPLACE_EXISTING);
    delete(source);
    delete(target);

    /** Test: copy directory, target exists */
    source = createSourceDirectory(dir1);
    target = getTargetFile(dir2);
    createFile(target);
    copyAndVerify(source, target, REPLACE_EXISTING);
    delete(source);
    delete(target);

    /** Test: copy directory, target exists and is empty directory */
    source = createSourceDirectory(dir1);
    target = getTargetFile(dir2);
    createDirectory(target);
    copyAndVerify(source, target, REPLACE_EXISTING);
    delete(source);
    delete(target);

    /** Test: copy directory, target exists and is non-empty directory */
    source = createSourceDirectory(dir1);
    target = getTargetFile(dir2);
    createDirectory(target);
    entry = target.resolve("foo");
    createFile(entry);
    try {
      copyAndVerify(source, target, REPLACE_EXISTING);
      throw new RuntimeException("DirectoryNotEmptyException expected");
    } catch (DirectoryNotEmptyException x) {
    }
    delete(entry);
    delete(source);
    delete(target);

    /*
     * Test: copy directory + attributes
     */
    source = createSourceDirectory(dir1);
    target = getTargetFile(dir2);
    copyAndVerify(source, target, COPY_ATTRIBUTES);
    delete(source);
    delete(target);

    // -- symbolic links --

    /** Test: Follow link */
    if (supportsLinks) {
      source = createSourceFile(dir1);
      link = dir1.resolve("link");
      createSymbolicLink(link, source);
      target = getTargetFile(dir2);
      copyAndVerify(link, target);
      delete(link);
      delete(source);
    }

    /** Test: Copy link (to file) */
    if (supportsLinks) {
      source = createSourceFile(dir1);
      link = dir1.resolve("link");
      createSymbolicLink(link, source);
      target = getTargetFile(dir2);
      copyAndVerify(link, target, NOFOLLOW_LINKS);
      delete(link);
      delete(source);
    }

    /** Test: Copy link (to directory) */
    if (supportsLinks) {
      source = dir1.resolve("mydir");
      createDirectory(source);
      link = dir1.resolve("link");
      createSymbolicLink(link, source);
      target = getTargetFile(dir2);
      copyAndVerify(link, target, NOFOLLOW_LINKS);
      delete(link);
      delete(source);
    }

    /** Test: Copy broken link */
    if (supportsLinks) {
      assertTrue(notExists(source));
      link = dir1.resolve("link");
      createSymbolicLink(link, source);
      target = getTargetFile(dir2);
      copyAndVerify(link, target, NOFOLLOW_LINKS);
      delete(link);
    }

    /** Test: Copy link to UNC (Windows only) */
    if (supportsLinks && System.getProperty("os.name").startsWith("Windows")) {
      Path unc = Paths.get("\\\\rialto\\share\\file");
      link = dir1.resolve("link");
      createSymbolicLink(link, unc);
      target = getTargetFile(dir2);
      copyAndVerify(link, target, NOFOLLOW_LINKS);
      delete(link);
    }

    // -- misc. tests --

    /** Test nulls */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    try {
      copy(source, null);
      throw new RuntimeException("NullPointerException expected");
    } catch (NullPointerException x) {
    }
    try {
      copy(source, target, (CopyOption[]) null);
      throw new RuntimeException("NullPointerException expected");
    } catch (NullPointerException x) {
    }
    try {
      CopyOption[] opts = {REPLACE_EXISTING, null};
      copy(source, target, opts);
      throw new RuntimeException("NullPointerException expected");
    } catch (NullPointerException x) {
    }
    delete(source);

    /** Test UOE */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    try {
      copy(source, target, new CopyOption() {});
    } catch (UnsupportedOperationException x) {
    }
    try {
      copy(source, target, REPLACE_EXISTING, new CopyOption() {});
    } catch (UnsupportedOperationException x) {
    }
    delete(source);
  }