Don't bother getting the not-real FileStateValue for a path whose parent doesn't exist.

In addition to saving a filesystem operation, this removes a source of a potential filesystem inconsistency.

--
MOS_MIGRATED_REVID=136355008
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/FileFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/FileFunctionTest.java
index 5257324..6308953 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/FileFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/FileFunctionTest.java
@@ -888,22 +888,13 @@
   }
 
   @Test
-  public void testFilesystemInconsistencies_ParentDoesntExistAndChildIsSymlink() throws Exception {
-    symlink("a/b", "doesntmatter");
-    // Our custom filesystem says "a/b" exists but "a" does not exist.
+  public void testDoesntStatChildIfParentDoesntExist() throws Exception {
+    // Our custom filesystem says "a" does not exist, so FileFunction shouldn't bother trying to
+    // think about "a/b". Test for this by having a stat of "a/b" fail with an io error, and
+    // observing that we don't encounter the error.
     fs.stubStat(path("a"), null);
-    SequentialBuildDriver driver = makeDriver();
-    SkyKey skyKey = skyKey("a/b");
-    EvaluationResult<FileValue> result =
-        driver.evaluate(
-            ImmutableList.of(skyKey), false, DEFAULT_THREAD_COUNT, NullEventHandler.INSTANCE);
-    assertTrue(result.hasError());
-    ErrorInfo errorInfo = result.getError(skyKey);
-    assertThat(errorInfo.getException()).isInstanceOf(InconsistentFilesystemException.class);
-    assertThat(errorInfo.getException().getMessage())
-        .contains(
-            "/root/a/b was a symlink to doesntmatter but others made us think it was a "
-                + "nonexistent path");
+    fs.stubStatError(path("a/b"), new IOException("ouch!"));
+    assertThat(valueForPath(path("a/b")).exists()).isFalse();
   }
 
   @Test
@@ -1639,8 +1630,9 @@
 
   private class CustomInMemoryFs extends InMemoryFileSystem {
 
-    private Map<Path, FileStatus> stubbedStats = Maps.newHashMap();
-    private Map<Path, IOException> stubbedFastDigestErrors = Maps.newHashMap();
+    private final Map<Path, FileStatus> stubbedStats = Maps.newHashMap();
+    private final Map<Path, IOException> stubbedStatErrors = Maps.newHashMap();
+    private final Map<Path, IOException> stubbedFastDigestErrors = Maps.newHashMap();
 
     public CustomInMemoryFs(ManualClock manualClock) {
       super(manualClock);
@@ -1667,8 +1659,15 @@
       stubbedStats.put(path, stubbedResult);
     }
 
+    public void stubStatError(Path path, IOException error) {
+      stubbedStatErrors.put(path, error);
+    }
+
     @Override
     public FileStatus stat(Path path, boolean followSymlinks) throws IOException {
+      if (stubbedStatErrors.containsKey(path)) {
+        throw stubbedStatErrors.get(path);
+      }
       if (stubbedStats.containsKey(path)) {
         return stubbedStats.get(path);
       }