[JENKINS-39179] [JENKINS-36088] Always use NIO to create and detect symbolic links and Windows junctions (#3133)

* Always use NIO to detect symlinks

* Make assertion failure message consistent

* Catch NoSuchFileException to keep tests passing

* Make method name more specific and simlify assumption

* Remove obsolete comment and reword the main comment in isSymlink

* Deprecate Kernel32Util#isJunctionOrSymlink

* Use assumptions for junction creation and add messages to assumptions

* Replace deprecated code with recommended alternative

* Add comment explaining call to DosFileAttributes#isOther

* Do not fall back to native code when creating symlinks

* Log FileSystemExceptions when creating symbolic links

* Catch InvalidPathException and rethrow as IOException

* Deprecate Kernel32Utils#createSymbolicLink and #getWin32FileAttributes

* Preserve original logging behavior on Windows and remove useless call to Util#displayIOException
This commit is contained in:
Devin Nusbaum authored and Oleg Nenashev committed 2017-11-16 17:08:10 +01:00
1 parent 7d29d4df37
commit 52fa4d90b9
4 files changed
+99 -125

No files matched your search

@@ -44,6 +44,7 @@ import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
@@ -59,7 +60,9 @@ import org.apache.commons.io.FileUtils;
import org.apache.commons.io.output.NullOutputStream;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Chmod;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;
import static org.junit.Assume.assumeThat;
import static org.junit.Assume.assumeTrue;
import static org.junit.Assume.assumeFalse;
import org.junit.Ignore;
@@ -736,4 +739,38 @@ public class FilePathTest {
// and now fail when flush is bad!
tmpDirPath.child("../" + archive.getName()).untar(outDir, TarCompression.NONE);
}
@Test public void deleteRecursiveOnUnix() throws Exception {
assumeFalse("Uses Unix-specific features", Functions.isWindows());
Path targetDir = temp.newFolder("target").toPath();
Path targetContents = Files.createFile(targetDir.resolve("contents.txt"));
Path toDelete = temp.newFolder("toDelete").toPath();
Util.createSymlink(toDelete.toFile(), "../targetDir", "link", TaskListener.NULL);
Files.createFile(toDelete.resolve("foo"));
Files.createFile(toDelete.resolve("bar"));
FilePath f = new FilePath(toDelete.toFile());
f.deleteRecursive();
assertTrue("symlink target should not be deleted", Files.exists(targetDir));
assertTrue("symlink target contents should not be deleted", Files.exists(targetContents));
assertFalse("could not delete target", Files.exists(toDelete));
}
@Test public void deleteRecursiveOnWindows() throws Exception {
assumeTrue("Uses Windows-specific features", Functions.isWindows());
Path targetDir = temp.newFolder("targetDir").toPath();
Path targetContents = Files.createFile(targetDir.resolve("contents.txt"));
Path toDelete = temp.newFolder("toDelete").toPath();
Process p = new ProcessBuilder()
.directory(toDelete.toFile())
.command("cmd.exe", "/C", "mklink /J junction ..\\targetDir")
.start();
assumeThat("unable to create junction", p.waitFor(), is(0));
Files.createFile(toDelete.resolve("foo"));
Files.createFile(toDelete.resolve("bar"));
FilePath f = new FilePath(toDelete.toFile());
f.deleteRecursive();
assertTrue("junction target should not be deleted", Files.exists(targetDir));
assertTrue("junction target contents should not be deleted", Files.exists(targetContents));
assertFalse("could not delete target", Files.exists(toDelete));
}
}