diff options
author | 2016-12-15 11:16:44 +0000 | |
---|---|---|
committer | 2016-12-15 20:37:48 +0000 | |
commit | aa1614b6a081ea435c536ef2b93c270dd5b071b8 (patch) | |
tree | 64e250114685ca07827c04317e17afb8bc1ea074 /src/test | |
parent | f00cee8a049ee0456f3aab7128ba06d33b7583b3 (diff) |
Windows, JNI: implement nativeGetLongPath
Implement a JNI method that can resolve 8dot3
style paths. This is necessary because we need to
be able to compare 8dot3 style paths and long
paths [1], and because implementing this correctly
in Java seems to be impossible [2].
This change also adds tests for the JNI isJunction
implementation.
See https://github.com/bazelbuild/bazel/issues/2101
[1] https://github.com/bazelbuild/bazel/issues/2145
[2] https://github.com/bazelbuild/bazel/issues/2145#issuecomment-266766716
--
PiperOrigin-RevId: 142123750
MOS_MIGRATED_REVID=142123750
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/vfs/WindowsFileSystemTest.java | 19 | ||||
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/windows/WindowsFileOperationsTest.java | 95 |
2 files changed, 114 insertions, 0 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/WindowsFileSystemTest.java b/src/test/java/com/google/devtools/build/lib/vfs/WindowsFileSystemTest.java index e0b62f1a78..8f25ff82ff 100644 --- a/src/test/java/com/google/devtools/build/lib/vfs/WindowsFileSystemTest.java +++ b/src/test/java/com/google/devtools/build/lib/vfs/WindowsFileSystemTest.java @@ -200,4 +200,23 @@ public class WindowsFileSystemTest { linkPath.toPath(), WindowsFileSystem.symlinkOpts(/* followSymlinks */ true))) .isFalse(); } + + @Test + public void testIsJunctionHandlesFilesystemChangesCorrectly() throws Exception { + File longPath = + testUtil.scratchFile("target\\helloworld.txt", "hello").toAbsolutePath().toFile(); + File shortPath = new File(longPath.getParentFile(), "hellow~1.txt"); + assertThat(WindowsFileSystem.isJunction(longPath)).isFalse(); + assertThat(WindowsFileSystem.isJunction(shortPath)).isFalse(); + + assertThat(longPath.delete()).isTrue(); + testUtil.createJunctions(ImmutableMap.of("target\\helloworld.txt", "target")); + assertThat(WindowsFileSystem.isJunction(longPath)).isTrue(); + assertThat(WindowsFileSystem.isJunction(shortPath)).isTrue(); + + assertThat(longPath.delete()).isTrue(); + assertThat(longPath.mkdir()).isTrue(); + assertThat(WindowsFileSystem.isJunction(longPath)).isFalse(); + assertThat(WindowsFileSystem.isJunction(shortPath)).isFalse(); + } } diff --git a/src/test/java/com/google/devtools/build/lib/windows/WindowsFileOperationsTest.java b/src/test/java/com/google/devtools/build/lib/windows/WindowsFileOperationsTest.java index 84f7752e3b..773daee80f 100644 --- a/src/test/java/com/google/devtools/build/lib/windows/WindowsFileOperationsTest.java +++ b/src/test/java/com/google/devtools/build/lib/windows/WindowsFileOperationsTest.java @@ -159,4 +159,99 @@ public class WindowsFileOperationsTest { linkPath.toPath(), WindowsFileSystem.symlinkOpts(/* followSymlinks */ true))) .isFalse(); } + + @Test + public void testIsJunctionHandlesFilesystemChangesCorrectly() throws Exception { + File helloFile = + testUtil.scratchFile("target\\helloworld.txt", "hello").toAbsolutePath().toFile(); + + // Assert that a file is identified as not a junction. + String longPath = helloFile.getAbsolutePath(); + String shortPath = new File(helloFile.getParentFile(), "hellow~1.txt").getAbsolutePath(); + assertThat(WindowsFileOperations.isJunction(longPath)).isFalse(); + assertThat(WindowsFileOperations.isJunction(shortPath)).isFalse(); + + // Assert that after deleting the file and creating a junction with the same path, it is + // identified as a junction. + assertThat(helloFile.delete()).isTrue(); + testUtil.createJunctions(ImmutableMap.of("target\\helloworld.txt", "target")); + assertThat(WindowsFileOperations.isJunction(longPath)).isTrue(); + assertThat(WindowsFileOperations.isJunction(shortPath)).isTrue(); + + // Assert that after deleting the file and creating a directory with the same path, it is + // identified as not a junction. + assertThat(helloFile.delete()).isTrue(); + assertThat(helloFile.mkdir()).isTrue(); + assertThat(WindowsFileOperations.isJunction(longPath)).isFalse(); + assertThat(WindowsFileOperations.isJunction(shortPath)).isFalse(); + } + + @Test + public void testGetLongPath() throws Exception { + File foo = testUtil.scratchDir("foo").toAbsolutePath().toFile(); + assertThat(foo.exists()).isTrue(); + assertThat(WindowsFileOperations.getLongPath(foo.getAbsolutePath())).endsWith("foo"); + + String longPath = foo.getAbsolutePath() + "\\will.exist\\helloworld.txt"; + String shortPath = foo.getAbsolutePath() + "\\will~1.exi\\hellow~1.txt"; + + // Assert that the long path resolution fails for non-existent file. + try { + WindowsFileOperations.getLongPath(longPath); + fail("expected to throw"); + } catch (IOException e) { + assertThat(e.getMessage()).contains("GetLongPathName"); + } + try { + WindowsFileOperations.getLongPath(shortPath); + fail("expected to throw"); + } catch (IOException e) { + assertThat(e.getMessage()).contains("GetLongPathName"); + } + + // Create the file, assert that long path resolution works and is correct. + File helloFile = + testUtil.scratchFile("foo/will.exist/helloworld.txt", "hello").toAbsolutePath().toFile(); + assertThat(helloFile.getAbsolutePath()).isEqualTo(longPath); + assertThat(helloFile.exists()).isTrue(); + assertThat(new File(longPath).exists()).isTrue(); + assertThat(new File(shortPath).exists()).isTrue(); + assertThat(WindowsFileOperations.getLongPath(longPath)).endsWith("will.exist\\helloworld.txt"); + assertThat(WindowsFileOperations.getLongPath(shortPath)).endsWith("will.exist\\helloworld.txt"); + + // Delete the file and the directory, assert that long path resolution fails for them. + assertThat(helloFile.delete()).isTrue(); + assertThat(helloFile.getParentFile().delete()).isTrue(); + try { + WindowsFileOperations.getLongPath(longPath); + fail("expected to throw"); + } catch (IOException e) { + assertThat(e.getMessage()).contains("GetLongPathName"); + } + try { + WindowsFileOperations.getLongPath(shortPath); + fail("expected to throw"); + } catch (IOException e) { + assertThat(e.getMessage()).contains("GetLongPathName"); + } + + // Create the directory and file with different names, but same 8dot3 names, assert that the + // resolution is still correct. + helloFile = + testUtil + .scratchFile("foo/will.exist_again/hellowelt.txt", "hello") + .toAbsolutePath() + .toFile(); + assertThat(new File(shortPath).exists()).isTrue(); + assertThat(WindowsFileOperations.getLongPath(shortPath)) + .endsWith("will.exist_again\\hellowelt.txt"); + assertThat(WindowsFileOperations.getLongPath(foo + "\\will.exist_again\\hellowelt.txt")) + .endsWith("will.exist_again\\hellowelt.txt"); + try { + WindowsFileOperations.getLongPath(longPath); + fail("expected to throw"); + } catch (IOException e) { + assertThat(e.getMessage()).contains("GetLongPathName"); + } + } } |