Windows: add a Java-native isJunction method

Also add tests for WindowsFileSystem and some for
WindowsFileOperations, so we test both the
JNI-based and Java-native isJunction function, as
well as handling of dangling symlinks/junctions.

Having a Java-native version of this method means
we don't need to use windows_jni.dll for any tests
or for bootstrapping.

This change could help with
https://github.com/bazelbuild/bazel/issues/1735

--
MOS_MIGRATED_REVID=132556440
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 44cd07b..c899f4d 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
@@ -20,9 +20,11 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.testutil.TestSpec;
 import com.google.devtools.build.lib.util.OS;
+import com.google.devtools.build.lib.vfs.WindowsFileSystem;
 import com.google.devtools.build.lib.windows.util.WindowsTestUtil;
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.Files;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
@@ -132,4 +134,29 @@
     assertThat(Arrays.asList(new File(root + "/abbreviated/c").list()))
         .containsExactly("file2.txt");
   }
+
+  @Test
+  public void testIsJunctionIsTrueForDanglingJunction() throws Exception {
+    java.nio.file.Path helloPath = testUtil.scratchFile("target\\hello.txt", "hello");
+    testUtil.createJunctions(ImmutableMap.of("link", "target"));
+
+    File linkPath = new File(helloPath.getParent().getParent().toFile(), "link");
+    assertThat(Arrays.asList(linkPath.list())).containsExactly("hello.txt");
+    assertThat(WindowsFileOperations.isJunction(linkPath.getAbsolutePath())).isTrue();
+
+    assertThat(helloPath.toFile().delete()).isTrue();
+    assertThat(helloPath.getParent().toFile().delete()).isTrue();
+    assertThat(helloPath.getParent().toFile().exists()).isFalse();
+    assertThat(Arrays.asList(linkPath.getParentFile().list())).containsExactly("link");
+
+    assertThat(WindowsFileOperations.isJunction(linkPath.getAbsolutePath())).isTrue();
+    assertThat(
+            Files.exists(
+                linkPath.toPath(), WindowsFileSystem.symlinkOpts(/* followSymlinks */ false)))
+        .isTrue();
+    assertThat(
+            Files.exists(
+                linkPath.toPath(), WindowsFileSystem.symlinkOpts(/* followSymlinks */ true)))
+        .isFalse();
+  }
 }