diff --git a/src/test/java/com/google/devtools/build/lib/BUILD b/src/test/java/com/google/devtools/build/lib/BUILD
index f3d0b6a..888f231 100644
--- a/src/test/java/com/google/devtools/build/lib/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/BUILD
@@ -59,10 +59,12 @@
         "//src/main/java/com/google/devtools/build/lib/actions",
         "//src/main/java/com/google/devtools/build/skyframe",
         "//src/test/java/com/google/devtools/build/lib:packages_testutil",
+        "//src/test/java/com/google/devtools/build/skyframe:testutil",
         "//third_party:guava",
         "//third_party:guava-testlib",
         "//third_party:jsr305",
         "//third_party:junit4",
+        "//third_party:mockito",
         "//third_party:truth",
     ],
 )
@@ -99,6 +101,7 @@
         "//third_party:guava-testlib",
         "//third_party:jsr305",
         "//third_party:junit4",
+        "//third_party:mockito",
         "//third_party:truth",
     ],
 )
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java
new file mode 100644
index 0000000..8fe6c9d
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java
@@ -0,0 +1,557 @@
+// Copyright 2015 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.skyframe;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.cmdline.PackageIdentifier;
+import com.google.devtools.build.lib.packages.ConstantRuleVisibility;
+import com.google.devtools.build.lib.packages.Preprocessor;
+import com.google.devtools.build.lib.packages.util.SubincludePreprocessor;
+import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
+import com.google.devtools.build.lib.skyframe.util.SkyframeExecutorTestUtils;
+import com.google.devtools.build.lib.testutil.ManualClock;
+import com.google.devtools.build.lib.vfs.Dirent;
+import com.google.devtools.build.lib.vfs.FileStatus;
+import com.google.devtools.build.lib.vfs.FileSystem;
+import com.google.devtools.build.lib.vfs.FileSystemUtils;
+import com.google.devtools.build.lib.vfs.ModifiedFileSet;
+import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.lib.vfs.PathFragment;
+import com.google.devtools.build.lib.vfs.RootedPath;
+import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
+import com.google.devtools.build.skyframe.ErrorInfo;
+import com.google.devtools.build.skyframe.EvaluationResult;
+import com.google.devtools.build.skyframe.RecordingDifferencer;
+import com.google.devtools.build.skyframe.SkyKey;
+import com.google.devtools.build.skyframe.SkyValue;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+/**
+ * Unit tests of specific functionality of PackageFunction. Note that it's already tested
+ * indirectly in several other places.
+ */
+public class PackageFunctionTest extends BuildViewTestCase {
+
+  private CustomInMemoryFs fs = new CustomInMemoryFs(new ManualClock());
+
+  @Override
+  protected Preprocessor.Factory.Supplier getPreprocessorFactorySupplier() {
+    return new SubincludePreprocessor.FactorySupplier(scratch.getFileSystem());
+  }
+
+  @Override
+  protected FileSystem createFileSystem() {
+    return fs;
+  }
+
+  private PackageValue validPackage(SkyKey skyKey) throws InterruptedException {
+    EvaluationResult<PackageValue> result = SkyframeExecutorTestUtils.evaluate(
+        getSkyframeExecutor(), skyKey, /*keepGoing=*/false, reporter);
+    if (result.hasError()) {
+      fail(result.getError(skyKey).getException().getMessage());
+    }
+    PackageValue value = result.get(skyKey);
+    assertFalse(value.getPackage().containsErrors());
+    return value;
+  }
+
+  public void testInconsistentNewPackage() throws Exception {
+    scratch.file("pkg/BUILD", "subinclude('//foo:sub')");
+    scratch.file("foo/sub");
+
+    getSkyframeExecutor().preparePackageLoading(
+        new PathPackageLocator(outputBase, ImmutableList.of(rootDirectory)),
+        ConstantRuleVisibility.PUBLIC, true,
+        7, "", UUID.randomUUID());
+
+    SkyKey pkgLookupKey = PackageLookupValue.key(new PathFragment("foo"));
+    EvaluationResult<PackageLookupValue> result = SkyframeExecutorTestUtils.evaluate(
+        getSkyframeExecutor(), pkgLookupKey, /*keepGoing=*/false, reporter);
+    assertFalse(result.hasError());
+    assertFalse(result.get(pkgLookupKey).packageExists());
+
+    scratch.file("foo/BUILD");
+
+    SkyKey skyKey = PackageValue.key(PackageIdentifier.parse("pkg"));
+    result = SkyframeExecutorTestUtils.evaluate(getSkyframeExecutor(),
+        skyKey, /*keepGoing=*/false, reporter);
+    assertTrue(result.hasError());
+    Throwable exception = result.getError(skyKey).getException();
+    assertThat(exception.getMessage()).contains("Inconsistent filesystem operations");
+    assertThat(exception.getMessage()).contains("Unexpected package");
+  }
+
+  public void testInconsistentMissingPackage() throws Exception {
+    reporter.removeHandler(failFastHandler);
+    Path root1 = fs.getPath("/root1");
+    scratch.file("/root1/WORKSPACE");
+    scratch.file("/root1/foo/sub");
+    scratch.file("/root1/pkg/BUILD", "subinclude('//foo:sub')");
+
+    Path root2 = fs.getPath("/root2");
+    scratch.file("/root2/foo/BUILD");
+    scratch.file("/root2/foo/sub");
+
+    getSkyframeExecutor().preparePackageLoading(
+        new PathPackageLocator(outputBase, ImmutableList.of(root1, root2)),
+        ConstantRuleVisibility.PUBLIC, true,
+        7, "", UUID.randomUUID());
+
+    SkyKey pkgLookupKey = PackageLookupValue.key(PackageIdentifier.parse("foo"));
+    EvaluationResult<PackageLookupValue> result = SkyframeExecutorTestUtils.evaluate(
+        getSkyframeExecutor(), pkgLookupKey, /*keepGoing=*/false, reporter);
+    assertFalse(result.hasError());
+    assertEquals(root2, result.get(pkgLookupKey).getRoot());
+
+    scratch.file("/root1/foo/BUILD");
+
+    SkyKey skyKey = PackageValue.key(PackageIdentifier.parse("pkg"));
+    result = SkyframeExecutorTestUtils.evaluate(getSkyframeExecutor(),
+        skyKey, /*keepGoing=*/false, reporter);
+    assertTrue(result.hasError());
+    Throwable exception = result.getError(skyKey).getException();
+    System.out.println("exception: " + exception.getMessage());
+    assertThat(exception.getMessage()).contains("Inconsistent filesystem operations");
+    assertThat(exception.getMessage()).contains("Inconsistent package location");
+  }
+
+  public void testPropagatesFilesystemInconsistencies() throws Exception {
+    reporter.removeHandler(failFastHandler);
+    RecordingDifferencer differencer = getSkyframeExecutor().getDifferencerForTesting();
+    Path pkgRoot = getSkyframeExecutor().getPathEntries().get(0);
+    Path fooBuildFile = scratch.file("foo/BUILD");
+    Path fooDir = fooBuildFile.getParentDirectory();
+
+    // Our custom filesystem says "foo/BUILD" exists but its parent "foo" is a file.
+    FileStatus inconsistentParentFileStatus = new FileStatus() {
+      @Override
+      public boolean isFile() {
+        return true;
+      }
+
+      @Override
+      public boolean isDirectory() {
+        return false;
+      }
+
+      @Override
+      public boolean isSymbolicLink() {
+        return false;
+      }
+
+      @Override
+      public boolean isSpecialFile() {
+        return false;
+      }
+
+      @Override
+      public long getSize() throws IOException {
+        return 0;
+      }
+
+      @Override
+      public long getLastModifiedTime() throws IOException {
+        return 0;
+      }
+
+      @Override
+      public long getLastChangeTime() throws IOException {
+        return 0;
+      }
+
+      @Override
+      public long getNodeId() throws IOException {
+        return 0;
+      }
+    };
+    fs.stubStat(fooDir, inconsistentParentFileStatus);
+    RootedPath pkgRootedPath = RootedPath.toRootedPath(pkgRoot, fooDir);
+    SkyValue fooDirValue = FileStateValue.create(pkgRootedPath,
+        getSkyframeExecutor().getTimestampGranularityMonitorForTesting());
+    differencer.inject(ImmutableMap.of(FileStateValue.key(pkgRootedPath), fooDirValue));
+    SkyKey skyKey = PackageValue.key(PackageIdentifier.parse("foo"));
+    String expectedMessage = "/workspace/foo/BUILD exists but its parent path /workspace/foo isn't "
+        + "an existing directory";
+    EvaluationResult<PackageValue> result = SkyframeExecutorTestUtils.evaluate(
+        getSkyframeExecutor(), skyKey, /*keepGoing=*/false, reporter);
+    assertTrue(result.hasError());
+    ErrorInfo errorInfo = result.getError(skyKey);
+    String errorMessage = errorInfo.getException().getMessage();
+    assertThat(errorMessage).contains("Inconsistent filesystem operations");
+    assertThat(errorMessage).contains(expectedMessage);
+  }
+
+  public void testPropagatesFilesystemInconsistencies_Globbing() throws Exception {
+    reporter.removeHandler(failFastHandler);
+    RecordingDifferencer differencer = getSkyframeExecutor().getDifferencerForTesting();
+    Path pkgRoot = getSkyframeExecutor().getPathEntries().get(0);
+    scratch.file("foo/BUILD",
+        "subinclude('//a:a')",
+        "sh_library(name = 'foo', srcs = glob(['bar/**/baz.sh']))");
+    scratch.file("a/BUILD");
+    scratch.file("a/a");
+    Path bazFile = scratch.file("foo/bar/baz/baz.sh");
+    Path bazDir = bazFile.getParentDirectory();
+    Path barDir = bazDir.getParentDirectory();
+
+    long bazFileNodeId = bazFile.stat().getNodeId();
+    // Our custom filesystem says "foo/bar/baz" does not exist but it also says that "foo/bar"
+    // has a child directory "baz".
+    fs.stubStat(bazDir, null);
+    RootedPath barDirRootedPath = RootedPath.toRootedPath(pkgRoot, barDir);
+    FileStateValue barDirFileStateValue = FileStateValue.create(barDirRootedPath,
+        getSkyframeExecutor().getTimestampGranularityMonitorForTesting());
+    FileValue barDirFileValue = FileValue.value(barDirRootedPath, barDirFileStateValue,
+        barDirRootedPath, barDirFileStateValue);
+    DirectoryListingValue barDirListing = DirectoryListingValue.value(barDirRootedPath,
+        barDirFileValue, DirectoryListingStateValue.create(ImmutableList.of(
+            new Dirent("baz", Dirent.Type.DIRECTORY))));
+    differencer.inject(ImmutableMap.of(DirectoryListingValue.key(barDirRootedPath), barDirListing));
+    SkyKey skyKey = PackageValue.key(PackageIdentifier.parse("foo"));
+    String expectedMessage = "Some filesystem operations implied /workspace/foo/bar/baz/baz.sh was "
+        + "a regular file with size of 0 and mtime of 0 and nodeId of " + bazFileNodeId + " and "
+        + "mtime of 0 but others made us think it was a nonexistent path";
+    EvaluationResult<PackageValue> result = SkyframeExecutorTestUtils.evaluate(
+        getSkyframeExecutor(), skyKey, /*keepGoing=*/false, reporter);
+    assertTrue(result.hasError());
+    ErrorInfo errorInfo = result.getError(skyKey);
+    String errorMessage = errorInfo.getException().getMessage();
+    assertThat(errorMessage).contains("Inconsistent filesystem operations");
+    assertThat(errorMessage).contains(expectedMessage);
+  }
+
+  /** Regression test for unexpected exception type from PackageValue. */
+  public void testDiscrepancyBetweenLegacyAndSkyframePackageLoadingErrors() throws Exception {
+    reporter.removeHandler(failFastHandler);
+    Path fooBuildFile = scratch.file("foo/BUILD",
+        "sh_library(name = 'foo', srcs = glob(['bar/*.sh']))");
+    Path fooDir = fooBuildFile.getParentDirectory();
+    Path barDir = fooDir.getRelative("bar");
+    scratch.file("foo/bar/baz.sh");
+    fs.scheduleMakeUnreadableAfterReaddir(barDir);
+
+    SkyKey skyKey = PackageValue.key(PackageIdentifier.parse("foo"));
+    String expectedMessage = "Encountered error 'Directory is not readable'";
+    EvaluationResult<PackageValue> result = SkyframeExecutorTestUtils.evaluate(
+        getSkyframeExecutor(), skyKey, /*keepGoing=*/false, reporter);
+    assertTrue(result.hasError());
+    ErrorInfo errorInfo = result.getError(skyKey);
+    String errorMessage = errorInfo.getException().getMessage();
+    assertThat(errorMessage).contains("Inconsistent filesystem operations");
+    assertThat(errorMessage).contains(expectedMessage);
+  }
+
+  public void testMultipleSubincludesFromSamePackage() throws Exception {
+    scratch.file("foo/BUILD",
+        "subinclude('//bar:a')",
+        "subinclude('//bar:b')");
+    scratch.file("bar/BUILD",
+        "exports_files(['a', 'b'])");
+    scratch.file("bar/a");
+    scratch.file("bar/b");
+
+    getSkyframeExecutor().preparePackageLoading(
+        new PathPackageLocator(outputBase, ImmutableList.of(rootDirectory)),
+        ConstantRuleVisibility.PUBLIC, true,
+        7, "", UUID.randomUUID());
+
+    SkyKey skyKey = PackageValue.key(PackageIdentifier.parse("foo"));
+    validPackage(skyKey);
+  }
+
+  public void testTransitiveSubincludesStoredInPackage() throws Exception {
+    scratch.file("foo/BUILD",
+        "subinclude('//bar:a')");
+    scratch.file("bar/BUILD",
+        "exports_files(['a'])");
+    scratch.file("bar/a",
+        "subinclude('//baz:b')");
+    scratch.file("baz/BUILD",
+        "exports_files(['b', 'c'])");
+    scratch.file("baz/b");
+    scratch.file("baz/c");
+
+    getSkyframeExecutor().preparePackageLoading(
+        new PathPackageLocator(outputBase, ImmutableList.of(rootDirectory)),
+        ConstantRuleVisibility.PUBLIC, true,
+        7, "", UUID.randomUUID());
+
+    SkyKey skyKey = PackageValue.key(PackageIdentifier.parse("foo"));
+    PackageValue value = validPackage(skyKey);
+    assertThat(value.getPackage().getSubincludeLabels()).containsExactly(
+        Label.parseAbsolute("//bar:a"), Label.parseAbsolute("//baz:b"));
+
+    scratch.overwriteFile("bar/a",
+        "subinclude('//baz:c')");
+    getSkyframeExecutor().invalidateFilesUnderPathForTesting(reporter,
+        ModifiedFileSet.builder().modify(new PathFragment("bar/a")).build(), rootDirectory);
+
+    value = validPackage(skyKey);
+    assertThat(value.getPackage().getSubincludeLabels()).containsExactly(
+        Label.parseAbsolute("//bar:a"), Label.parseAbsolute("//baz:c"));
+  }
+
+  public void testTransitiveSkylarkDepsStoredInPackage() throws Exception {
+    scratch.file("foo/BUILD",
+        "load('/bar/ext', 'a')");
+    scratch.file("bar/BUILD");
+    scratch.file("bar/ext.bzl",
+        "load('/baz/ext', 'b')",
+        "a = b");
+    scratch.file("baz/BUILD");
+    scratch.file("baz/ext.bzl",
+        "b = 1");
+    scratch.file("qux/BUILD");
+    scratch.file("qux/ext.bzl",
+        "c = 1");
+
+    getSkyframeExecutor().preparePackageLoading(
+        new PathPackageLocator(outputBase, ImmutableList.of(rootDirectory)),
+        ConstantRuleVisibility.PUBLIC, true,
+        7, "", UUID.randomUUID());
+
+    SkyKey skyKey = PackageValue.key(PackageIdentifier.parse("foo"));
+    PackageValue value = validPackage(skyKey);
+    assertThat(value.getPackage().getSkylarkFileDependencies()).containsExactly(
+        Label.parseAbsolute("//bar:ext.bzl"), Label.parseAbsolute("//baz:ext.bzl"));
+
+    scratch.overwriteFile("bar/ext.bzl",
+        "load('/qux/ext', 'c')",
+        "a = c");
+    getSkyframeExecutor().invalidateFilesUnderPathForTesting(reporter,
+        ModifiedFileSet.builder().modify(new PathFragment("bar/ext.bzl")).build(), rootDirectory);
+
+    value = validPackage(skyKey);
+    assertThat(value.getPackage().getSkylarkFileDependencies()).containsExactly(
+        Label.parseAbsolute("//bar:ext.bzl"), Label.parseAbsolute("//qux:ext.bzl"));
+  }
+
+  public void testNonExistingSkylarkExtension() throws Exception {
+    reporter.removeHandler(failFastHandler);
+    scratch.file("test/skylark/BUILD",
+        "load('/test/skylark/bad_extension', 'some_symbol')",
+        "genrule(name = gr,",
+        "    outs = ['out.txt'],",
+        "    cmd = 'echo hello >@')");
+    invalidatePackages();
+
+    SkyKey skyKey = PackageValue.key(PackageIdentifier.parse("test/skylark"));
+    EvaluationResult<PackageValue> result = SkyframeExecutorTestUtils.evaluate(
+        getSkyframeExecutor(), skyKey, /*keepGoing=*/false, reporter);
+    assertTrue(result.hasError());
+    ErrorInfo errorInfo = result.getError(skyKey);
+    assertThat(errorInfo.getException())
+        .hasMessage("error loading package 'test/skylark': Extension file not found. "
+            + "Unable to load file '//test/skylark:bad_extension.bzl': "
+            + "file doesn't exist or isn't a file");
+  }
+
+  public void testNonExistingSkylarkExtensionWithPythonPreprocessing() throws Exception {
+    reporter.removeHandler(failFastHandler);
+    scratch.file("foo/BUILD",
+        "exports_files(['a'])");
+    scratch.file("foo/a",
+        "load('/test/skylark/bad_extension', 'some_symbol')");
+    scratch.file("test/skylark/BUILD",
+        "subinclude('//foo:a')");
+    invalidatePackages();
+
+    SkyKey skyKey = PackageValue.key(PackageIdentifier.parse("test/skylark"));
+    EvaluationResult<PackageValue> result = SkyframeExecutorTestUtils.evaluate(
+        getSkyframeExecutor(), skyKey, /*keepGoing=*/false, reporter);
+    assertTrue(result.hasError());
+    assertContainsEvent("Extension file not found. "
+        + "Unable to load file '//test/skylark:bad_extension.bzl': "
+        + "file doesn't exist or isn't a file");
+  }
+
+  public void testNonExistingSkylarkExtensionFromExtension() throws Exception {
+    reporter.removeHandler(failFastHandler);
+    scratch.file("test/skylark/extension.bzl",
+        "load('/test/skylark/bad_extension', 'some_symbol')",
+        "a = 'a'");
+    scratch.file("test/skylark/BUILD",
+        "load('/test/skylark/extension', 'a')",
+        "genrule(name = gr,",
+        "    outs = ['out.txt'],",
+        "    cmd = 'echo hello >@')");
+    invalidatePackages();
+
+    SkyKey skyKey = PackageValue.key(PackageIdentifier.parse("test/skylark"));
+    EvaluationResult<PackageValue> result = SkyframeExecutorTestUtils.evaluate(
+        getSkyframeExecutor(), skyKey, /*keepGoing=*/false, reporter);
+    assertTrue(result.hasError());
+    ErrorInfo errorInfo = result.getError(skyKey);
+    assertThat(errorInfo.getException())
+        .hasMessage("error loading package 'test/skylark': Extension file not found. "
+            + "Unable to load file '//test/skylark:bad_extension.bzl': "
+            + "file doesn't exist or isn't a file");
+  }
+
+  public void testSymlinkCycleWithSkylarkExtension() throws Exception {
+    reporter.removeHandler(failFastHandler);
+    Path extensionFilePath = scratch.resolve("/workspace/test/skylark/extension.bzl");
+    FileSystemUtils.ensureSymbolicLink(extensionFilePath, new PathFragment("extension.bzl"));
+    scratch.file("test/skylark/BUILD",
+        "load('/test/skylark/extension', 'a')",
+        "genrule(name = gr,",
+        "    outs = ['out.txt'],",
+        "    cmd = 'echo hello >@')");
+    invalidatePackages();
+
+    SkyKey skyKey = PackageValue.key(PackageIdentifier.parse("test/skylark"));
+    EvaluationResult<PackageValue> result = SkyframeExecutorTestUtils.evaluate(
+        getSkyframeExecutor(), skyKey, /*keepGoing=*/false, reporter);
+    assertTrue(result.hasError());
+    ErrorInfo errorInfo = result.getError(skyKey);
+    assertEquals(skyKey, errorInfo.getRootCauseOfException());
+    assertThat(errorInfo.getException())
+        .hasMessage(
+            "error loading package 'test/skylark': Encountered error while reading extension "
+            + "file 'test/skylark/extension.bzl': Symlink cycle");
+  }
+
+  public void testIOErrorLookingForSubpackageForLabelIsHandled() throws Exception {
+    reporter.removeHandler(failFastHandler);
+    scratch.file("foo/BUILD",
+        "sh_library(name = 'foo', srcs = ['bar/baz.sh'])");
+    Path barBuildFile = scratch.file("foo/bar/BUILD");
+    fs.stubStatError(barBuildFile, new IOException("nope"));
+    SkyKey skyKey = PackageValue.key(PackageIdentifier.parse("foo"));
+    EvaluationResult<PackageValue> result = SkyframeExecutorTestUtils.evaluate(
+        getSkyframeExecutor(), skyKey, /*keepGoing=*/false, reporter);
+    assertTrue(result.hasError());
+    assertContainsEvent("nope");
+  }
+
+  public void testLoadRelativePath() throws Exception {
+    scratch.file("pkg/BUILD", "load('ext', 'a')");
+    scratch.file("pkg/ext.bzl", "a = 1");
+    validPackage(PackageValue.key(PackageIdentifier.parse("pkg")));
+  }
+
+  public void testLoadAbsolutePath() throws Exception {
+    scratch.file("pkg1/BUILD");
+    scratch.file("pkg2/BUILD",
+        "load('/pkg1/ext', 'a')");
+    scratch.file("pkg1/ext.bzl", "a = 1");
+    validPackage(PackageValue.key(PackageIdentifier.parse("pkg2")));
+  }
+
+  public void testBadWorkspaceFile() throws Exception {
+    Path workspacePath = scratch.overwriteFile("WORKSPACE", "junk");
+    SkyKey skyKey = PackageValue.key(PackageIdentifier.createInDefaultRepo("external"));
+    getSkyframeExecutor()
+        .invalidate(
+            Predicates.equalTo(
+                FileStateValue.key(
+                    RootedPath.toRootedPath(
+                        workspacePath.getParentDirectory(),
+                        new PathFragment(workspacePath.getBaseName())))));
+
+    reporter.removeHandler(failFastHandler);
+    EvaluationResult<PackageValue> result =
+        SkyframeExecutorTestUtils.evaluate(
+            getSkyframeExecutor(), skyKey, /*keepGoing=*/ false, reporter);
+    assertFalse(result.hasError());
+    assertTrue(result.get(skyKey).getPackage().containsErrors());
+  }
+
+  private static class CustomInMemoryFs extends InMemoryFileSystem {
+    private abstract static class FileStatusOrException {
+      abstract FileStatus get() throws IOException;
+
+      private static class ExceptionImpl extends FileStatusOrException {
+        private final IOException exn;
+
+        private ExceptionImpl(IOException exn) {
+          this.exn = exn;
+        }
+
+        @Override
+        FileStatus get() throws IOException {
+          throw exn;
+        }
+      }
+
+      private static class FileStatusImpl extends FileStatusOrException {
+
+        @Nullable
+        private final FileStatus fileStatus;
+
+        private  FileStatusImpl(@Nullable FileStatus fileStatus) {
+          this.fileStatus = fileStatus;
+        }
+
+        @Override
+        @Nullable
+        FileStatus get() {
+          return fileStatus;
+        }
+      }
+    }
+
+    private Map<Path, FileStatusOrException> stubbedStats = Maps.newHashMap();
+    private Set<Path> makeUnreadableAfterReaddir = Sets.newHashSet();
+
+    public CustomInMemoryFs(ManualClock manualClock) {
+      super(manualClock);
+    }
+
+    public void stubStat(Path path, @Nullable FileStatus stubbedResult) {
+      stubbedStats.put(path, new FileStatusOrException.FileStatusImpl(stubbedResult));
+    }
+
+    public void stubStatError(Path path, IOException stubbedResult) {
+      stubbedStats.put(path, new FileStatusOrException.ExceptionImpl(stubbedResult));
+    }
+
+    @Override
+    public FileStatus stat(Path path, boolean followSymlinks) throws IOException {
+      if (stubbedStats.containsKey(path)) {
+        return stubbedStats.get(path).get();
+      }
+      return super.stat(path, followSymlinks);
+    }
+
+    public void scheduleMakeUnreadableAfterReaddir(Path path) {
+      makeUnreadableAfterReaddir.add(path);
+    }
+
+    @Override
+    public Collection<Dirent> readdir(Path path, boolean followSymlinks) throws IOException {
+      Collection<Dirent> result = super.readdir(path, followSymlinks);
+      if (makeUnreadableAfterReaddir.contains(path)) {
+        path.setReadable(false);
+      }
+      return result;
+    }
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java
new file mode 100644
index 0000000..dfc1c44
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java
@@ -0,0 +1,231 @@
+// Copyright 2015 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.skyframe;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.testing.EqualsTester;
+import com.google.devtools.build.lib.analysis.BlazeDirectories;
+import com.google.devtools.build.lib.bazel.rules.BazelRulesModule;
+import com.google.devtools.build.lib.cmdline.PackageIdentifier;
+import com.google.devtools.build.lib.events.NullEventHandler;
+import com.google.devtools.build.lib.packages.PackageFactory;
+import com.google.devtools.build.lib.packages.RuleClassProvider;
+import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
+import com.google.devtools.build.lib.skyframe.PackageLookupValue.ErrorReason;
+import com.google.devtools.build.lib.testutil.FoundationTestCase;
+import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
+import com.google.devtools.build.lib.util.BlazeClock;
+import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor;
+import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.lib.vfs.PathFragment;
+import com.google.devtools.build.lib.vfs.RootedPath;
+import com.google.devtools.build.skyframe.InMemoryMemoizingEvaluator;
+import com.google.devtools.build.skyframe.MemoizingEvaluator;
+import com.google.devtools.build.skyframe.RecordingDifferencer;
+import com.google.devtools.build.skyframe.SequentialBuildDriver;
+import com.google.devtools.build.skyframe.SkyFunction;
+import com.google.devtools.build.skyframe.SkyFunctionName;
+import com.google.devtools.build.skyframe.SkyKey;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Tests for {@link PackageLookupFunction}.
+ */
+public class PackageLookupFunctionTest extends FoundationTestCase {
+  private AtomicReference<ImmutableSet<PackageIdentifier>> deletedPackages;
+  private MemoizingEvaluator evaluator;
+  private SequentialBuildDriver driver;
+  private RecordingDifferencer differencer;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+
+    Path emptyPackagePath = rootDirectory.getRelative("somewhere/else");
+    scratch.file("parentpackage/BUILD");
+
+    AtomicReference<PathPackageLocator> pkgLocator = new AtomicReference<>(
+        new PathPackageLocator(outputBase, ImmutableList.of(emptyPackagePath, rootDirectory)));
+    deletedPackages = new AtomicReference<>(ImmutableSet.<PackageIdentifier>of());
+    ExternalFilesHelper externalFilesHelper = new ExternalFilesHelper(pkgLocator);
+    TimestampGranularityMonitor tsgm = new TimestampGranularityMonitor(BlazeClock.instance());
+    BlazeDirectories directories = new BlazeDirectories(rootDirectory, outputBase, rootDirectory);
+
+    Map<SkyFunctionName, SkyFunction> skyFunctions = new HashMap<>();
+    skyFunctions.put(SkyFunctions.PACKAGE_LOOKUP,
+        new PackageLookupFunction(deletedPackages));
+    skyFunctions.put(
+        SkyFunctions.PACKAGE,
+        new PackageFunction(null, null, null, null, null, null, null));
+    skyFunctions.put(SkyFunctions.FILE_STATE, new FileStateFunction(tsgm, externalFilesHelper));
+    skyFunctions.put(SkyFunctions.FILE, new FileFunction(pkgLocator, tsgm, externalFilesHelper));
+    skyFunctions.put(SkyFunctions.BLACKLISTED_PACKAGE_PREFIXES,
+        new BlacklistedPackagePrefixesFunction());
+    RuleClassProvider ruleClassProvider = TestRuleClassProvider.getRuleClassProvider();
+    skyFunctions.put(
+        SkyFunctions.WORKSPACE_FILE,
+        new WorkspaceFileFunction(
+            ruleClassProvider,
+            new PackageFactory(
+                ruleClassProvider, new BazelRulesModule().getPackageEnvironmentExtension()),
+            directories));
+    differencer = new RecordingDifferencer();
+    evaluator = new InMemoryMemoizingEvaluator(skyFunctions, differencer);
+    driver = new SequentialBuildDriver(evaluator);
+    PrecomputedValue.BUILD_ID.set(differencer, UUID.randomUUID());
+    PrecomputedValue.PATH_PACKAGE_LOCATOR.set(differencer, pkgLocator.get());
+    PrecomputedValue.BLACKLISTED_PACKAGE_PREFIXES_FILE.set(
+        differencer, PathFragment.EMPTY_FRAGMENT);
+  }
+
+  private PackageLookupValue lookupPackage(String packageName) throws InterruptedException {
+    return lookupPackage(PackageIdentifier.createInDefaultRepo(packageName));
+  }
+
+  private PackageLookupValue lookupPackage(PackageIdentifier packageId)
+      throws InterruptedException {
+    SkyKey key = PackageLookupValue.key(packageId);
+    return driver.<PackageLookupValue>evaluate(
+        ImmutableList.of(key), false, SkyframeExecutor.DEFAULT_THREAD_COUNT,
+        NullEventHandler.INSTANCE).get(key);
+  }
+
+  public void testNoBuildFile() throws Exception {
+    scratch.file("parentpackage/nobuildfile/foo.txt");
+    PackageLookupValue packageLookupValue = lookupPackage("parentpackage/nobuildfile");
+    assertFalse(packageLookupValue.packageExists());
+    assertEquals(ErrorReason.NO_BUILD_FILE, packageLookupValue.getErrorReason());
+    assertNotNull(packageLookupValue.getErrorMsg());
+  }
+
+  public void testNoBuildFileAndNoParentPackage() throws Exception {
+    scratch.file("noparentpackage/foo.txt");
+    PackageLookupValue packageLookupValue = lookupPackage("noparentpackage");
+    assertFalse(packageLookupValue.packageExists());
+    assertEquals(ErrorReason.NO_BUILD_FILE, packageLookupValue.getErrorReason());
+    assertNotNull(packageLookupValue.getErrorMsg());
+  }
+
+  public void testDeletedPackage() throws Exception {
+    scratch.file("parentpackage/deletedpackage/BUILD");
+    deletedPackages.set(ImmutableSet.of(
+        PackageIdentifier.createInDefaultRepo("parentpackage/deletedpackage")));
+    PackageLookupValue packageLookupValue = lookupPackage("parentpackage/deletedpackage");
+    assertFalse(packageLookupValue.packageExists());
+    assertEquals(ErrorReason.DELETED_PACKAGE, packageLookupValue.getErrorReason());
+    assertNotNull(packageLookupValue.getErrorMsg());
+  }
+
+
+  public void testBlacklistedPackage() throws Exception {
+    scratch.file("blacklisted/subdir/BUILD");
+    scratch.file("blacklisted/BUILD");
+    PrecomputedValue.BLACKLISTED_PACKAGE_PREFIXES_FILE.set(differencer,
+        new PathFragment("config/blacklisted.txt"));
+    Path blacklist = scratch.file("config/blacklisted.txt", "blacklisted");
+
+    ImmutableSet<String> pkgs = ImmutableSet.of("blacklisted/subdir", "blacklisted");
+    for (String pkg : pkgs) {
+      PackageLookupValue packageLookupValue = lookupPackage(pkg);
+      assertFalse(packageLookupValue.packageExists());
+      assertEquals(ErrorReason.DELETED_PACKAGE, packageLookupValue.getErrorReason());
+      assertNotNull(packageLookupValue.getErrorMsg());
+    }
+
+    scratch.overwriteFile("config/blacklisted.txt", "not_blacklisted");
+    RootedPath rootedBlacklist = RootedPath.toRootedPath(
+        blacklist.getParentDirectory().getParentDirectory(),
+        new PathFragment("config/blacklisted.txt"));
+    differencer.invalidate(ImmutableSet.of(FileStateValue.key(rootedBlacklist)));
+    for (String pkg : pkgs) {
+      PackageLookupValue packageLookupValue = lookupPackage(pkg);
+      assertTrue(packageLookupValue.packageExists());
+    }
+  }
+
+  public void testInvalidPackageName() throws Exception {
+    scratch.file("parentpackage/invalidpackagename%42/BUILD");
+    PackageLookupValue packageLookupValue = lookupPackage("parentpackage/invalidpackagename%42");
+    assertFalse(packageLookupValue.packageExists());
+    assertEquals(ErrorReason.INVALID_PACKAGE_NAME,
+        packageLookupValue.getErrorReason());
+    assertNotNull(packageLookupValue.getErrorMsg());
+  }
+
+  public void testDirectoryNamedBuild() throws Exception {
+    scratch.dir("parentpackage/isdirectory/BUILD");
+    PackageLookupValue packageLookupValue = lookupPackage("parentpackage/isdirectory");
+    assertFalse(packageLookupValue.packageExists());
+    assertEquals(ErrorReason.NO_BUILD_FILE,
+        packageLookupValue.getErrorReason());
+    assertNotNull(packageLookupValue.getErrorMsg());
+  }
+
+  public void testEverythingIsGood() throws Exception {
+    scratch.file("parentpackage/everythinggood/BUILD");
+    PackageLookupValue packageLookupValue = lookupPackage("parentpackage/everythinggood");
+    assertTrue(packageLookupValue.packageExists());
+    assertEquals(rootDirectory, packageLookupValue.getRoot());
+  }
+
+  public void testEmptyPackageName() throws Exception {
+    scratch.file("BUILD");
+    PackageLookupValue packageLookupValue = lookupPackage("");
+    assertTrue(packageLookupValue.packageExists());
+    assertEquals(rootDirectory, packageLookupValue.getRoot());
+  }
+
+  public void testWorkspaceLookup() throws Exception {
+    scratch.overwriteFile("WORKSPACE");
+    PackageLookupValue packageLookupValue = lookupPackage("external");
+    assertTrue(packageLookupValue.packageExists());
+    assertEquals(rootDirectory, packageLookupValue.getRoot());
+  }
+
+  // TODO(kchodorow): Clean this up (see TODOs in PackageLookupValue).
+  public void testExternalPackageLookupSemantics() {
+    PackageLookupValue existing = PackageLookupValue.workspace(rootDirectory);
+    assertTrue(existing.isExternalPackage());
+    assertTrue(existing.packageExists());
+    PackageLookupValue nonExistent = PackageLookupValue.workspace(rootDirectory.getRelative("x/y"));
+    assertTrue(nonExistent.isExternalPackage());
+    assertFalse(nonExistent.packageExists());
+  }
+
+  public void testPackageLookupValueHashCodeAndEqualsContract() throws Exception {
+    Path root1 = rootDirectory.getRelative("root1");
+    Path root2 = rootDirectory.getRelative("root2");
+    // Our (seeming) duplication of parameters here is intentional. Some of the subclasses of
+    // PackageLookupValue are supposed to have reference equality semantics, and some are supposed
+    // to have logical equality semantics.
+    new EqualsTester()
+        .addEqualityGroup(PackageLookupValue.success(root1), PackageLookupValue.success(root1))
+        .addEqualityGroup(PackageLookupValue.success(root2), PackageLookupValue.success(root2))
+        .addEqualityGroup(
+            PackageLookupValue.NO_BUILD_FILE_VALUE, PackageLookupValue.NO_BUILD_FILE_VALUE)
+        .addEqualityGroup(
+            PackageLookupValue.DELETED_PACKAGE_VALUE, PackageLookupValue.DELETED_PACKAGE_VALUE)
+        .addEqualityGroup(PackageLookupValue.invalidPackageName("nope1"),
+            PackageLookupValue.invalidPackageName("nope1"))
+        .addEqualityGroup(PackageLookupValue.invalidPackageName("nope2"),
+             PackageLookupValue.invalidPackageName("nope2"))
+        .testEquals();
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ParallelBuilderMediumTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ParallelBuilderMediumTest.java
new file mode 100644
index 0000000..1d923d7
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/ParallelBuilderMediumTest.java
@@ -0,0 +1,44 @@
+// Copyright 2015 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.skyframe;
+
+import com.google.devtools.build.lib.testutil.Suite;
+import com.google.devtools.build.lib.testutil.TestSpec;
+
+/**
+ * Stress tests for the parallel builder.
+ */
+@TestSpec(size = Suite.MEDIUM_TESTS)
+public class ParallelBuilderMediumTest extends ParallelBuilderTest {
+
+  /**
+   * A larger set of tests using randomly-generated complex dependency graphs.
+   */
+  public void testRandomStressTest1() throws Exception {
+    final int numTrials = 2;
+    final int numArtifacts = 100;
+    final int randomSeed = 43;
+    StressTest test = new StressTest(numArtifacts, numTrials, randomSeed);
+    test.runStressTest();
+  }
+
+  public void testRandomStressTest2() throws Exception {
+    final int numTrials = 10;
+    final int numArtifacts = 10;
+    final int randomSeed = 44;
+    StressTest test = new StressTest(numArtifacts, numTrials, randomSeed);
+    test.runStressTest();
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ParallelBuilderTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ParallelBuilderTest.java
new file mode 100644
index 0000000..b1637b2
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/ParallelBuilderTest.java
@@ -0,0 +1,863 @@
+// Copyright 2015 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.skyframe;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.google.common.eventbus.EventBus;
+import com.google.common.eventbus.Subscribe;
+import com.google.common.util.concurrent.Runnables;
+import com.google.devtools.build.lib.actions.Action;
+import com.google.devtools.build.lib.actions.ActionExecutedEvent;
+import com.google.devtools.build.lib.actions.ActionExecutionContext;
+import com.google.devtools.build.lib.actions.ActionExecutionException;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.BuildFailedException;
+import com.google.devtools.build.lib.actions.Executor;
+import com.google.devtools.build.lib.actions.LocalHostCapacity;
+import com.google.devtools.build.lib.actions.ResourceManager;
+import com.google.devtools.build.lib.actions.ResourceSet;
+import com.google.devtools.build.lib.actions.TestExecException;
+import com.google.devtools.build.lib.actions.cache.ActionCache;
+import com.google.devtools.build.lib.actions.util.TestAction;
+import com.google.devtools.build.lib.events.Event;
+import com.google.devtools.build.lib.events.EventHandler;
+import com.google.devtools.build.lib.events.EventKind;
+import com.google.devtools.build.lib.events.PrintingEventHandler;
+import com.google.devtools.build.lib.testutil.BlazeTestUtils;
+import com.google.devtools.build.lib.testutil.Suite;
+import com.google.devtools.build.lib.testutil.TestSpec;
+import com.google.devtools.build.lib.testutil.TestUtils;
+import com.google.devtools.build.lib.util.AbruptExitException;
+import com.google.devtools.build.lib.vfs.FileStatus;
+import com.google.devtools.build.lib.vfs.FileSystem;
+import com.google.devtools.build.lib.vfs.FileSystemUtils;
+import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.logging.Logger;
+
+/**
+ * Test suite for ParallelBuilder.
+ *
+ */
+@TestSpec(size = Suite.MEDIUM_TESTS)
+public class ParallelBuilderTest extends TimestampBuilderTestCase {
+
+  private static final Logger LOG =
+    Logger.getLogger(ParallelBuilderTest.class.getName());
+
+  protected ActionCache cache;
+
+  protected static final int DEFAULT_NUM_JOBS = 100;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    this.cache = new InMemoryActionCache();
+    ResourceManager.instance().setAvailableResources(LocalHostCapacity.getLocalHostCapacity());
+    ResourceManager.instance().setRamUtilizationPercentage(
+        ResourceManager.DEFAULT_RAM_UTILIZATION_PERCENTAGE);
+    ResourceManager.instance().resetResourceUsage();
+  }
+
+  @SafeVarargs
+  protected static <T> Set<T> asSet(T... elements) {
+    return Sets.newHashSet(elements);
+  }
+
+  protected void buildArtifacts(Artifact... artifacts)
+      throws BuildFailedException, AbruptExitException,
+      InterruptedException, TestExecException {
+    buildArtifacts(createBuilder(DEFAULT_NUM_JOBS, false), artifacts);
+  }
+
+  private Builder createBuilder(int jobs, boolean keepGoing) {
+    return createBuilder(cache, jobs, keepGoing);
+  }
+
+  private volatile boolean runningFooAction;
+  private volatile boolean runningBarAction;
+
+  /**
+   * Test that independent actions are run in parallel threads
+   * that are scheduled concurrently.
+   */
+  public void runsInParallelWithBuilder(Builder builder) throws Exception {
+    // We create two actions, each of which waits (spinning) until the
+    // other action has started.  If the two actions are not run
+    // in parallel, the test will deadlock and time out.
+
+    // This specifies how many iterations to run before timing out.
+    // This should be large enough to ensure that that there is at
+    // least one context switch, otherwise the test may spuriously fail.
+    final long maxIterations = 100000000;
+
+    // This specifies how often to print out progress messages.
+    // Uncomment this for debugging.
+    //final long PRINT_FREQUENCY = maxIterations / 10;
+
+    runningFooAction = false;
+    runningBarAction = false;
+
+    // [action] -> foo
+    Artifact foo = createDerivedArtifact("foo");
+    Runnable makeFoo = new Runnable() {
+          @Override
+          public void run() {
+            runningFooAction = true;
+            for (long i = 0; i < maxIterations; i++) {
+              Thread.yield();
+              if (runningBarAction) {
+                return;
+              }
+              // Uncomment this for debugging.
+              //if (i % PRINT_FREQUENCY == 0) {
+              //  String msg = "ParallelBuilderTest: foo: waiting for bar";
+              //  System.out.println(bar);
+              //}
+            }
+            fail("ParallelBuilderTest: foo: waiting for bar: timed out");
+          }
+        };
+    registerAction(new TestAction(makeFoo, Artifact.NO_ARTIFACTS, ImmutableList.of(foo)));
+
+    // [action] -> bar
+    Artifact bar = createDerivedArtifact("bar");
+    Runnable makeBar = new Runnable() {
+          @Override
+          public void run() {
+            runningBarAction = true;
+            for (long i = 0; i < maxIterations; i++) {
+              Thread.yield();
+              if (runningFooAction) {
+                return;
+              }
+              // Uncomment this for debugging.
+              //if (i % PRINT_FREQUENCY == 0) {
+              //  String msg = "ParallelBuilderTest: bar: waiting for foo";
+              //  System.out.println(msg);
+              //}
+            }
+            fail("ParallelBuilderTest: bar: waiting for foo: timed out");
+          }
+        };
+    registerAction(new TestAction(makeBar, Artifact.NO_ARTIFACTS, ImmutableList.of(bar)));
+
+    buildArtifacts(builder, foo, bar);
+  }
+
+  /**
+   * Intercepts actionExecuted events, ordinarily written to the master log, for
+   * use locally within this test suite.
+   */
+  public static class ActionEventRecorder {
+    private final List<ActionExecutedEvent> actionExecutedEvents = new ArrayList<>();
+
+    @Subscribe
+    public void actionExecuted(ActionExecutedEvent event) {
+      actionExecutedEvents.add(event);
+    }
+  }
+
+  public void testReportsActionExecutedEvent() throws Exception {
+    Artifact pear = createDerivedArtifact("pear");
+    ActionEventRecorder recorder = new ActionEventRecorder();
+    EventBus eventBus = new EventBus();
+    eventBusRef.set(eventBus);
+    eventBus.register(recorder);
+
+    Action action = registerAction(new TestAction(Runnables.doNothing(), emptySet, asSet(pear)));
+
+    buildArtifacts(createBuilder(DEFAULT_NUM_JOBS, true), pear);
+    assertThat(recorder.actionExecutedEvents).hasSize(1);
+    assertEquals(action, recorder.actionExecutedEvents.get(0).getAction());
+  }
+
+  public void testRunsInParallel() throws Exception {
+    runsInParallelWithBuilder(createBuilder(DEFAULT_NUM_JOBS, false));
+  }
+
+  /**
+   * Test that we can recover properly after a failed build.
+   */
+  public void testFailureRecovery() throws Exception {
+
+    // [action] -> foo
+    Artifact foo = createDerivedArtifact("foo");
+    Callable<Void> makeFoo = new Callable<Void>() {
+          @Override
+          public Void call() throws IOException {
+            throw new IOException("building 'foo' is supposed to fail");
+          }
+        };
+    registerAction(new TestAction(makeFoo, Artifact.NO_ARTIFACTS, ImmutableList.of(foo)));
+
+    // [action] -> bar
+    Artifact bar = createDerivedArtifact("bar");
+    registerAction(new TestAction(TestAction.NO_EFFECT, emptySet, ImmutableList.of(bar)));
+
+    // Don't fail fast when we encounter the error
+    reporter.removeHandler(failFastHandler);
+
+    // test that building 'foo' fails
+    try {
+      buildArtifacts(foo);
+      fail("building 'foo' was supposed to fail!");
+    } catch (BuildFailedException e) {
+      if (!e.getMessage().contains("building 'foo' is supposed to fail")) {
+        throw e;
+      }
+      // Make sure the reporter reported the error message.
+      assertContainsEvent("building 'foo' is supposed to fail");
+    }
+    // test that a subsequent build of 'bar' succeeds
+    buildArtifacts(bar);
+  }
+
+  public void testUpdateCacheError() throws Exception {
+    FileSystem fs = new InMemoryFileSystem() {
+      @Override
+      public FileStatus stat(Path path, boolean followSymlinks) throws IOException {
+        final FileStatus stat = super.stat(path, followSymlinks);
+        if (path.toString().endsWith("/out/foo")) {
+          return new FileStatus() {
+            private final FileStatus original = stat;
+
+            @Override
+            public boolean isSymbolicLink() {
+              return original.isSymbolicLink();
+            }
+
+            @Override
+            public boolean isFile() {
+              return original.isFile();
+            }
+
+            @Override
+            public boolean isDirectory() {
+              return original.isDirectory();
+            }
+
+            @Override
+            public boolean isSpecialFile() {
+              return original.isSpecialFile();
+            }
+
+            @Override
+            public long getSize() throws IOException {
+              return original.getSize();
+            }
+
+            @Override
+            public long getNodeId() throws IOException {
+              return original.getNodeId();
+            }
+
+            @Override
+            public long getLastModifiedTime() throws IOException {
+              throw new IOException();
+            }
+
+            @Override
+            public long getLastChangeTime() throws IOException {
+              return original.getLastChangeTime();
+            }
+          };
+        }
+        return stat;
+      }
+    };
+    Artifact foo = createDerivedArtifact(fs, "foo");
+    registerAction(new TestAction(TestAction.NO_EFFECT, emptySet, ImmutableList.of(foo)));
+    reporter.removeHandler(failFastHandler);
+    try {
+      buildArtifacts(foo);
+      fail("Expected to fail");
+    } catch (BuildFailedException e) {
+      assertContainsEvent("not all outputs were created");
+    }
+  }
+
+  public void testNullBuild() throws Exception {
+    // BuildTool.setupLogging(Level.FINEST);
+    LOG.fine("Testing null build...");
+    buildArtifacts();
+  }
+
+  /**
+   * Test a randomly-generated complex dependency graph.
+   */
+  public void testSmallRandomStressTest() throws Exception {
+    final int numTrials = 1;
+    final int numArtifacts = 30;
+    final int randomSeed = 42;
+    StressTest test = new StressTest(numArtifacts, numTrials, randomSeed);
+    test.runStressTest();
+  }
+
+  private static enum BuildKind { Clean, Incremental, Nop }
+
+  /**
+   * Sets up and manages stress tests of arbitrary size.
+   */
+  protected class StressTest {
+
+    final int numArtifacts;
+    final int numTrials;
+
+    Random random;
+    Artifact artifacts[];
+
+    public StressTest(int numArtifacts, int numTrials, int randomSeed) {
+      this.numTrials = numTrials;
+      this.numArtifacts = numArtifacts;
+      this.random = new Random(randomSeed);
+    }
+
+    public void runStressTest() throws Exception {
+      for (int trial = 0; trial < numTrials; trial++) {
+        List<Counter> counters = buildRandomActionGraph(trial);
+
+        // do a clean build
+        LOG.fine("Testing clean build... (trial " + trial + ")");
+        Artifact[] buildTargets = chooseRandomBuild();
+        buildArtifacts(buildTargets);
+        doSanityChecks(buildTargets, counters, BuildKind.Clean);
+        resetCounters(counters);
+
+        // Do an incremental build.
+        //
+        // BuildTool creates new instances of the Builder for each build request. It may rely on
+        // that fact (that its state will be discarded after each build request) - thus
+        // test should use same approach and ensure that a new instance is used each time.
+        LOG.fine("Testing incremental build...");
+        buildTargets = chooseRandomBuild();
+        buildArtifacts(buildTargets);
+        doSanityChecks(buildTargets, counters, BuildKind.Incremental);
+        resetCounters(counters);
+
+        // do a do-nothing build
+        LOG.fine("Testing do-nothing rebuild...");
+        buildArtifacts(buildTargets);
+        doSanityChecks(buildTargets, counters, BuildKind.Nop);
+        //resetCounters(counters);
+      }
+    }
+
+    /**
+     * Construct a random action graph, and initialize the file system
+     * so that all of the input files exist and none of the output files
+     * exist.
+     */
+    public List<Counter> buildRandomActionGraph(int actionGraphNumber) throws IOException {
+      List<Counter> counters = new ArrayList<>(numArtifacts);
+
+      artifacts = new Artifact[numArtifacts];
+      for (int i = 0; i < numArtifacts; i++) {
+        artifacts[i] = createDerivedArtifact("file" + actionGraphNumber + "-" + i);
+      }
+
+      int numOutputs;
+      for (int i = 0; i < artifacts.length; i += numOutputs) {
+        int numInputs = random.nextInt(3);
+        numOutputs = 1 + random.nextInt(2);
+        if (i + numOutputs >= artifacts.length) {
+          numOutputs = artifacts.length - i;
+        }
+
+        Collection<Artifact> inputs = new ArrayList<>(numInputs);
+        for (int j = 0; j < numInputs; j++) {
+          if (i != 0) {
+            int inputNum = random.nextInt(i);
+            inputs.add(artifacts[inputNum]);
+          }
+        }
+        Collection<Artifact> outputs = new ArrayList<>(numOutputs);
+        for (int j = 0; j < numOutputs; j++) {
+          outputs.add(artifacts[i + j]);
+        }
+        counters.add(createActionCounter(inputs, outputs));
+        if (inputs.isEmpty()) {
+          // source files -- create them
+          for (Artifact output : outputs) {
+            BlazeTestUtils.makeEmptyFile(output.getPath());
+          }
+        } else {
+          // generated files -- delete them
+          for (Artifact output : outputs) {
+            try {
+              output.getPath().delete();
+            } catch (FileNotFoundException e) {
+              // ok
+            }
+          }
+        }
+      }
+      return counters;
+    }
+
+    /**
+     * Choose a random set of targets to build.
+     */
+    public Artifact[] chooseRandomBuild() {
+      Artifact[] buildTargets;
+      switch (random.nextInt(4)) {
+        case 0:
+          // build the final output target
+          LOG.fine("Building final output target.");
+          buildTargets = new Artifact[] { artifacts[numArtifacts - 1] };
+          break;
+
+        case 1: {
+          // build all the targets (in random order);
+          LOG.fine("Building all the targets.");
+          List<Artifact> targets = Lists.newArrayList(artifacts);
+          Collections.shuffle(targets, random);
+          buildTargets = targets.toArray(new Artifact[numArtifacts]);
+          break;
+        }
+
+        case 2:
+          // build a random target
+          LOG.fine("Building a random target.");
+          buildTargets = new Artifact[] {
+                artifacts[random.nextInt(numArtifacts)]
+              };
+          break;
+
+        case 3: {
+          // build a random subset of targets
+          LOG.fine("Building a random subset of targets.");
+          List<Artifact> targets = Lists.newArrayList(artifacts);
+          Collections.shuffle(targets, random);
+          List<Artifact> targetSubset = new ArrayList<>();
+          int numTargetsToTest = random.nextInt(numArtifacts);
+          LOG.fine("numTargetsToTest = " + numTargetsToTest);
+          Iterator<Artifact> iterator = targets.iterator();
+          for (int i = 0; i < numTargetsToTest; i++) {
+            targetSubset.add(iterator.next());
+          }
+          buildTargets = targetSubset.toArray(new Artifact[numTargetsToTest]);
+          break;
+        }
+
+        default:
+          throw new IllegalStateException();
+      }
+      return buildTargets;
+    }
+
+    public void doSanityChecks(Artifact[] targets, List<Counter> counters,
+        BuildKind kind) {
+      // Check that we really did build all the targets.
+      for (Artifact file : targets) {
+        assertTrue(file.getPath().exists());
+      }
+      // Check that each action was executed the right number of times
+      for (Counter counter : counters) {
+        switch (kind) {
+          case Clean:
+            //assert counter.count == 1;
+            //break;
+          case Incremental:
+            assert counter.count == 0 || counter.count == 1;
+            break;
+          case Nop:
+            assert counter.count == 0;
+            break;
+        }
+      }
+    }
+
+    private void resetCounters(List<Counter> counters) {
+      for (Counter counter : counters) {
+        counter.count = 0;
+      }
+    }
+
+  }
+
+  // Regression test for bug fixed in CL 3548332: builder was not waiting for
+  // all its subprocesses to terminate.
+  public void testWaitsForSubprocesses() throws Exception {
+    final Semaphore semaphore = new Semaphore(1);
+    final boolean[] finished = { false };
+
+    semaphore.acquireUninterruptibly(); // t=0: semaphore acquired
+
+    // This arrangement ensures that the "bar" action tries to run for about
+    // 100ms after the "foo" action has completed (failed).
+
+    // [action] -> foo
+    Artifact foo = createDerivedArtifact("foo");
+    Callable<Void> makeFoo = new Callable<Void>() {
+          @Override
+          public Void call() throws IOException {
+            semaphore.acquireUninterruptibly(); // t=2: semaphore re-acquired
+            throw new IOException("foo action failed");
+          }
+        };
+    registerAction(new TestAction(makeFoo, Artifact.NO_ARTIFACTS, ImmutableList.of(foo)));
+
+    // [action] -> bar
+    Artifact bar = createDerivedArtifact("bar");
+    Runnable makeBar = new Runnable() {
+          @Override
+          public void run() {
+            semaphore.release(); // t=1: semaphore released
+            try {
+              Thread.sleep(100); // 100ms
+            } catch (InterruptedException e) {
+              // This might happen (though not necessarily).  The
+              // ParallelBuilder interrupts all its workers at the first sign
+              // of trouble.
+            }
+            finished[0] = true;
+          }
+        };
+    registerAction(new TestAction(makeBar, emptySet, asSet(bar)));
+
+    // Don't fail fast when we encounter the error
+    reporter.removeHandler(failFastHandler);
+
+    try {
+      buildArtifacts(foo, bar);
+      fail();
+    } catch (BuildFailedException e) {
+      assertThat(e.getMessage()).contains("TestAction failed due to exception: foo action failed");
+      assertContainsEvent("TestAction failed due to exception: foo action failed");
+    }
+
+    assertTrue("bar action not finished, yet buildArtifacts has completed.",
+               finished[0]);
+  }
+
+  public void testSchedulingOfMemoryResources() throws Exception {
+    // The action graph consists of 100 independent actions, but execution is
+    // memory limited: only 6 TestActions can run concurrently:
+    ResourceManager.instance().setRamUtilizationPercentage(50);
+    ResourceManager.instance().setAvailableResources(
+        ResourceSet.createWithRamCpuIo(/*memoryMb=*/12.8, /*cpu=*/Integer.MAX_VALUE, /*io=*/0.0));
+    ResourceManager.instance().resetResourceUsage();
+
+    class Counter {
+      int currentlyRunning = 0;
+      int maxConcurrent = 0;
+      synchronized void increment() {
+        ++currentlyRunning;
+        if (currentlyRunning > maxConcurrent) {
+          maxConcurrent = currentlyRunning;
+        }
+      }
+      synchronized void decrement() {
+        currentlyRunning--;
+      }
+    }
+    final Counter counter = new Counter();
+
+    Artifact[] outputs = new Artifact[100];
+    for (int ii = 0; ii < outputs.length; ++ii) {
+      Artifact artifact = createDerivedArtifact("file" + ii);
+      Callable<Void> callable = new Callable<Void>() {
+          @Override
+          public Void call() throws Exception{
+            counter.increment();
+            Thread.sleep(100); // 100ms
+            counter.decrement();
+            return null;
+          }
+        };
+      registerAction(new TestAction(callable, Artifact.NO_ARTIFACTS, ImmutableList.of(artifact)));
+      outputs[ii] = artifact;
+    }
+
+    buildArtifacts(outputs);
+
+    assertEquals(0, counter.currentlyRunning);
+    assertEquals(6, counter.maxConcurrent);
+  }
+
+  public void testEstimateExceedsAvailableRam() throws Exception {
+    // Pretend that the machine has only 1MB of RAM available,
+    // then test running an action that we estimate requires 2MB of RAM.
+
+    ResourceManager.instance().setAvailableResources(
+        ResourceSet.createWithRamCpuIo(/*memoryMb=*/1.0, /*cpuUsage=*/4, /*ioUsage=*/0));
+    ResourceManager.instance().resetResourceUsage();
+
+    final boolean[] finished = { false };
+    Artifact foo = createDerivedArtifact("foo");
+    Runnable makeFoo = new Runnable() {
+        @Override
+        public void run() {
+          finished[0] = true;
+        }
+      };
+    registerAction(new TestAction(makeFoo, emptySet, asSet(foo)) {
+        @Override
+        public ResourceSet estimateResourceConsumption(Executor executor) {
+          return ResourceSet.createWithRamCpuIo(/*memoryMb=*/2.0, /*cpuUsage=*/1, /*ioUsage=*/0);
+        }
+      });
+    buildArtifacts(foo);
+    assertTrue(finished[0]);
+  }
+
+  public void testCyclicActionGraph() throws Exception {
+    // foo -> [action] -> bar
+    // bar -> [action] -> baz
+    // baz -> [action] -> foo
+    Artifact foo = createDerivedArtifact("foo");
+    Artifact bar = createDerivedArtifact("bar");
+    Artifact baz = createDerivedArtifact("baz");
+    try {
+      registerAction(new TestAction(TestAction.NO_EFFECT, asSet(foo), asSet(bar)));
+      registerAction(new TestAction(TestAction.NO_EFFECT, asSet(bar), asSet(baz)));
+      registerAction(new TestAction(TestAction.NO_EFFECT, asSet(baz), asSet(foo)));
+      buildArtifacts(foo);
+      fail("Builder failed to detect cyclic action graph");
+    } catch (BuildFailedException e) {
+      assertEquals(e.getMessage(), CYCLE_MSG);
+    }
+  }
+
+  public void testSelfCyclicActionGraph() throws Exception {
+    // foo -> [action] -> foo
+    Artifact foo = createDerivedArtifact("foo");
+    try {
+      registerAction(new TestAction(TestAction.NO_EFFECT, asSet(foo), asSet(foo)));
+      buildArtifacts(foo);
+      fail("Builder failed to detect cyclic action graph");
+    } catch (BuildFailedException e) {
+      assertEquals(e.getMessage(), CYCLE_MSG);
+    }
+  }
+
+  public void testCycleInActionGraphBelowTwoActions() throws Exception {
+    // bar -> [action] -> foo1
+    // bar -> [action] -> foo2
+    // baz -> [action] -> bar
+    // bar -> [action] -> baz
+    Artifact foo1 = createDerivedArtifact("foo1");
+    Artifact foo2 = createDerivedArtifact("foo2");
+    Artifact bar = createDerivedArtifact("bar");
+    Artifact baz = createDerivedArtifact("baz");
+    try {
+      registerAction(new TestAction(TestAction.NO_EFFECT, asSet(bar), asSet(foo1)));
+      registerAction(new TestAction(TestAction.NO_EFFECT, asSet(bar), asSet(foo2)));
+      registerAction(new TestAction(TestAction.NO_EFFECT, asSet(baz), asSet(bar)));
+      registerAction(new TestAction(TestAction.NO_EFFECT, asSet(bar), asSet(baz)));
+      buildArtifacts(foo1, foo2);
+      fail("Builder failed to detect cyclic action graph");
+    } catch (BuildFailedException e) {
+      assertEquals(e.getMessage(), CYCLE_MSG);
+    }
+  }
+
+
+  public void testCyclicActionGraphWithTail() throws Exception {
+    // bar -> [action] -> foo
+    // baz -> [action] -> bar
+    // bat, foo -> [action] -> baz
+    Artifact foo = createDerivedArtifact("foo");
+    Artifact bar = createDerivedArtifact("bar");
+    Artifact baz = createDerivedArtifact("baz");
+    Artifact bat = createDerivedArtifact("bat");
+    try {
+      registerAction(new TestAction(TestAction.NO_EFFECT, asSet(bar), asSet(foo)));
+      registerAction(new TestAction(TestAction.NO_EFFECT, asSet(baz), asSet(bar)));
+      registerAction(new TestAction(TestAction.NO_EFFECT, asSet(bat, foo), asSet(baz)));
+      registerAction(new TestAction(TestAction.NO_EFFECT, ImmutableSet.<Artifact>of(), asSet(bat)));
+      buildArtifacts(foo);
+      fail("Builder failed to detect cyclic action graph");
+    } catch (BuildFailedException e) {
+      assertEquals(e.getMessage(), CYCLE_MSG);
+    }
+  }
+
+  public void testDuplicatedInput() throws Exception {
+    // <null> -> [action] -> foo
+    // (foo, foo) -> [action] -> bar
+    Artifact foo = createDerivedArtifact("foo");
+    Artifact bar = createDerivedArtifact("bar");
+    registerAction(
+        new TestAction(TestAction.NO_EFFECT, ParallelBuilderTest.<Artifact>asSet(), asSet(foo)));
+    registerAction(
+        new TestAction(TestAction.NO_EFFECT, Lists.<Artifact>newArrayList(foo, foo), asSet(bar)));
+    buildArtifacts(bar);
+  }
+
+
+  // Regression test for bug #735765, "ParallelBuilder still issues new jobs
+  // after one has failed, without --keep-going."  The incorrect behaviour is
+  // that, when the first job fails, while no new jobs are added to the queue
+  // of runnable jobs, the queue may have lots of work in it, and the
+  // ParallelBuilder always completes these jobs before it returns.  The
+  // correct behaviour is to discard all the jobs in the queue after the first
+  // one fails.
+  public void assertNoNewJobsAreRunAfterFirstFailure(final boolean catastrophe, boolean keepGoing)
+      throws Exception {
+    // Strategy: Limit parallelism to 3.  Enqueue 10 runnable tasks that run
+    // for an appreciable period (say 100ms).  Ensure that at most 3 of those
+    // tasks completed.  This proves that all runnable tasks were dropped from
+    // the queue after the first batch (which included errors) was finished.
+    // It should be pretty robust even in the face of timing variations.
+
+    final AtomicInteger completedTasks = new AtomicInteger(0);
+
+    int numJobs = 50;
+    Artifact[] artifacts = new Artifact[numJobs];
+
+    for (int ii = 0; ii < numJobs; ++ii) {
+      Artifact out = createDerivedArtifact(ii + ".out");
+      List<Artifact> inputs = (catastrophe && ii > 10)
+          ? ImmutableList.of(artifacts[0])
+          : Artifact.NO_ARTIFACTS;
+      final int iCopy = ii;
+      registerAction(new TestAction(new Callable<Void>() {
+          @Override
+          public Void call() throws Exception {
+            Thread.sleep(100); // 100ms
+            completedTasks.getAndIncrement();
+            throw new IOException("task failed");
+          }
+        },
+          inputs, ImmutableList.of(out)) {
+        @Override
+        public void execute(ActionExecutionContext actionExecutionContext)
+        throws ActionExecutionException {
+          if (catastrophe && iCopy == 0) {
+            try {
+              Thread.sleep(300); // 300ms
+            } catch (InterruptedException e) {
+              throw new RuntimeException(e);
+            }
+            completedTasks.getAndIncrement();
+            throw new ActionExecutionException("This is a catastrophe", this, true);
+          }
+          super.execute(actionExecutionContext);
+        }
+      });
+      artifacts[ii] = out;
+    }
+
+    // Don't fail fast when we encounter the error
+    reporter.removeHandler(failFastHandler);
+
+    try {
+      buildArtifacts(createBuilder(3, keepGoing), artifacts);
+      fail();
+    } catch (BuildFailedException e) {
+      assertContainsEvent("task failed");
+    }
+    if (completedTasks.get() >= numJobs) {
+      fail("Expected early termination due to failed task, but all tasks ran to completion.");
+    }
+  }
+
+   public void testNoNewJobsAreRunAfterFirstFailure() throws Exception {
+     assertNoNewJobsAreRunAfterFirstFailure(false, false);
+   }
+
+   public void testNoNewJobsAreRunAfterCatastrophe() throws Exception {
+     assertNoNewJobsAreRunAfterFirstFailure(true, true);
+   }
+
+  private Artifact createInputFile(String name) throws IOException {
+    Artifact artifact = createSourceArtifact(name);
+    Path path = artifact.getPath();
+    FileSystemUtils.createDirectoryAndParents(path.getParentDirectory());
+    FileSystemUtils.createEmptyFile(path);
+    return artifact;
+  }
+
+  public void testProgressReporting() throws Exception {
+    // Build three artifacts in 3 separate actions (baz depends on bar and bar
+    // depends on foo.  Make sure progress is reported at the beginning of all
+    // three actions.
+    List<Artifact> sourceFiles = new ArrayList<>();
+    for (int i = 0; i < 10; i++) {
+      sourceFiles.add(createInputFile("file" + i));
+    }
+    Artifact foo = createDerivedArtifact("foo");
+    Artifact bar = createDerivedArtifact("bar");
+    Artifact baz = createDerivedArtifact("baz");
+    bar.getPath().delete();
+    baz.getPath().delete();
+
+    final List<String> messages = new ArrayList<>();
+    EventHandler handler = new EventHandler() {
+
+      @Override
+      public void handle(Event event) {
+        EventKind k = event.getKind();
+        if (k == EventKind.START || k == EventKind.FINISH) {
+          // Remove the tmpDir as this is user specific and the assert would
+          // fail below.
+          messages.add(
+              event.getMessage().replaceFirst(TestUtils.tmpDir(), "") + " " + event.getKind());
+        }
+      }
+    };
+    reporter.addHandler(handler);
+    reporter.addHandler(new PrintingEventHandler(EventKind.ALL_EVENTS));
+
+    registerAction(new TestAction(TestAction.NO_EFFECT, sourceFiles, asSet(foo)));
+    registerAction(new TestAction(TestAction.NO_EFFECT, asSet(foo), asSet(bar)));
+    registerAction(new TestAction(TestAction.NO_EFFECT, asSet(bar), asSet(baz)));
+    buildArtifacts(baz);
+    // Check that the percentages increase non-linearly, because foo has 10 input files
+    List<String> expectedMessages = Lists.newArrayList(
+        "Test foo START",
+        "Test foo FINISH",
+        "Test bar START",
+        "Test bar FINISH",
+        "Test baz START",
+        "Test baz FINISH");
+    assertThat(messages).containsAllIn(expectedMessages);
+
+    // Now do an incremental rebuild of bar and baz,
+    // and check the incremental progress percentages.
+    messages.clear();
+    bar.getPath().delete();
+    baz.getPath().delete();
+    // This uses a new builder instance so that we refetch timestamps from
+    // (in-memory) file system, rather than using cached entries.
+    buildArtifacts(baz);
+    expectedMessages = Lists.newArrayList(
+        "Test bar START",
+        "Test bar FINISH",
+        "Test baz START",
+        "Test baz FINISH");
+    assertThat(messages).containsAllIn(expectedMessages);
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfTargetsUnderDirectoryFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfTargetsUnderDirectoryFunctionTest.java
new file mode 100644
index 0000000..7574951
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfTargetsUnderDirectoryFunctionTest.java
@@ -0,0 +1,217 @@
+// Copyright 2015 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.skyframe;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.cmdline.PackageIdentifier;
+import com.google.devtools.build.lib.pkgcache.FilteringPolicies;
+import com.google.devtools.build.lib.pkgcache.FilteringPolicy;
+import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.lib.vfs.PathFragment;
+import com.google.devtools.build.lib.vfs.RootedPath;
+import com.google.devtools.build.skyframe.BuildDriver;
+import com.google.devtools.build.skyframe.EvaluationResult;
+import com.google.devtools.build.skyframe.SkyKey;
+import com.google.devtools.build.skyframe.WalkableGraph;
+
+import java.io.IOException;
+
+/**
+ * Tests for {@link PrepareDepsOfTargetsUnderDirectoryFunction}. Insert excuses here.
+ */
+public class PrepareDepsOfTargetsUnderDirectoryFunctionTest extends BuildViewTestCase {
+
+  private SkyframeExecutor skyframeExecutor;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    skyframeExecutor = getSkyframeExecutor();
+  }
+
+  private SkyKey createPrepDepsKey(Path root, PathFragment rootRelativePath) {
+    return createPrepDepsKey(root, rootRelativePath, ImmutableSet.<PathFragment>of());
+  }
+
+  private SkyKey createPrepDepsKey(Path root, PathFragment rootRelativePath,
+      ImmutableSet<PathFragment> excludedPaths) {
+    RootedPath rootedPath = RootedPath.toRootedPath(root, rootRelativePath);
+    return PrepareDepsOfTargetsUnderDirectoryValue.key(
+        PackageIdentifier.DEFAULT_REPOSITORY_NAME, rootedPath, excludedPaths);
+  }
+
+  private SkyKey createPrepDepsKey(Path root, PathFragment rootRelativePath,
+      ImmutableSet<PathFragment> excludedPaths, FilteringPolicy filteringPolicy) {
+    RootedPath rootedPath = RootedPath.toRootedPath(root, rootRelativePath);
+    return PrepareDepsOfTargetsUnderDirectoryValue.key(
+        PackageIdentifier.DEFAULT_REPOSITORY_NAME, rootedPath, excludedPaths, filteringPolicy);
+  }
+
+  private EvaluationResult<PrepareDepsOfTargetsUnderDirectoryValue> getEvaluationResult(SkyKey key)
+      throws InterruptedException {
+    BuildDriver driver = skyframeExecutor.getDriverForTesting();
+    EvaluationResult<PrepareDepsOfTargetsUnderDirectoryValue> evaluationResult =
+        driver.evaluate(ImmutableList.of(key), /*keepGoing=*/false,
+            SequencedSkyframeExecutor.DEFAULT_THREAD_COUNT, reporter);
+    Preconditions.checkState(!evaluationResult.hasError());
+    return evaluationResult;
+  }
+
+  public void testTransitiveLoading() throws Exception {
+    // Given a package "a" with a genrule "a" that depends on a target in package "b",
+    createPackages();
+
+    // When package "a" is evaluated,
+    SkyKey key = createPrepDepsKey(rootDirectory, new PathFragment("a"));
+    EvaluationResult<PrepareDepsOfTargetsUnderDirectoryValue> evaluationResult =
+        getEvaluationResult(key);
+    WalkableGraph graph = Preconditions.checkNotNull(evaluationResult.getWalkableGraph());
+
+    // Then the TransitiveTraversalValue for "a:a" is evaluated,
+    SkyKey aaKey = TransitiveTraversalValue.key(Label.create("a", "a"));
+    assertThat(graph.exists(aaKey)).isTrue();
+
+    // And that TransitiveTraversalValue depends on "b:b.txt".
+    Iterable<SkyKey> depsOfAa =
+        Iterables.getOnlyElement(graph.getDirectDeps(ImmutableList.of(aaKey)).values());
+    SkyKey bTxtKey = TransitiveTraversalValue.key(Label.create("b", "b.txt"));
+    assertThat(depsOfAa).contains(bTxtKey);
+
+    // And the TransitiveTraversalValue for "b:b.txt" is evaluated.
+    assertThat(graph.exists(bTxtKey)).isTrue();
+  }
+
+  public void testTargetFilterSensitivity() throws Exception {
+    // Given a package "a" with a genrule "a" that depends on a target in package "b", and a test
+    // rule "aTest",
+    createPackages();
+
+    // When package "a" is evaluated under a test-only filtering policy,
+    SkyKey key = createPrepDepsKey(rootDirectory, new PathFragment("a"),
+        ImmutableSet.<PathFragment>of(), FilteringPolicies.FILTER_TESTS);
+    EvaluationResult<PrepareDepsOfTargetsUnderDirectoryValue> evaluationResult =
+        getEvaluationResult(key);
+    WalkableGraph graph = Preconditions.checkNotNull(evaluationResult.getWalkableGraph());
+
+    // Then the TransitiveTraversalValue for "a:a" is not evaluated,
+    SkyKey aaKey = TransitiveTraversalValue.key(Label.create("a", "a"));
+    assertThat(graph.exists(aaKey)).isFalse();
+
+    // But the TransitiveTraversalValue for "a:aTest" is.
+    SkyKey aaTestKey = TransitiveTraversalValue.key(Label.create("a", "aTest"));
+    assertThat(graph.exists(aaTestKey)).isTrue();
+  }
+
+  /**
+   * Creates a package "a" with a genrule "a" that depends on a target in a created package "b",
+   * and a test rule "aTest".
+   */
+  private void createPackages() throws IOException {
+    scratch.file("a/BUILD",
+        "genrule(name='a', cmd='', srcs=['//b:b.txt'], outs=['a.out'])",
+        "sh_test(name='aTest', size='small', srcs=['aTest.sh'])");
+    scratch.file("b/BUILD",
+        "exports_files(['b.txt'])");
+  }
+
+  public void testSubdirectoryExclusion() throws Exception {
+    // Given a package "a" with two packages below it, "a/b" and "a/c",
+    scratch.file("a/BUILD");
+    scratch.file("a/b/BUILD");
+    scratch.file("a/c/BUILD");
+
+    // When the top package is evaluated via PrepareDepsOfTargetsUnderDirectoryValue with "a/b"
+    // excluded,
+    PathFragment excludedPathFragment = new PathFragment("a/b");
+    SkyKey key = createPrepDepsKey(rootDirectory, new PathFragment("a"),
+        ImmutableSet.of(excludedPathFragment));
+    EvaluationResult<PrepareDepsOfTargetsUnderDirectoryValue> evaluationResult =
+        getEvaluationResult(key);
+    PrepareDepsOfTargetsUnderDirectoryValue value = evaluationResult.get(key);
+
+    // Then the value reports that "a" is a package,
+    assertThat(value.isDirectoryPackage()).isTrue();
+
+    // And only the subdirectory corresponding to "a/c" is present in the result,
+    RootedPath onlySubdir =
+        Iterables.getOnlyElement(value.getSubdirectoryTransitivelyContainsPackages().keySet());
+    assertThat(onlySubdir.getRelativePath()).isEqualTo(new PathFragment("a/c"));
+
+    // And the "a/c" subdirectory reports a package under it.
+    assertThat(value.getSubdirectoryTransitivelyContainsPackages().get(onlySubdir)).isTrue();
+
+    // Also, the computation graph does not contain a cached value for "a/b".
+    WalkableGraph graph = Preconditions.checkNotNull(evaluationResult.getWalkableGraph());
+    assertFalse(graph.exists(createPrepDepsKey(rootDirectory, excludedPathFragment,
+        ImmutableSet.<PathFragment>of())));
+
+    // And the computation graph does contain a cached value for "a/c" with the empty set excluded,
+    // because that key was evaluated.
+    assertTrue(graph.exists(createPrepDepsKey(rootDirectory, new PathFragment("a/c"),
+        ImmutableSet.<PathFragment>of())));
+  }
+
+  public void testExcludedSubdirectoryGettingPassedDown() throws Exception {
+    // Given a package "a", and a package below it in "a/b/c", and a non-BUILD file below it in
+    // "a/b/d",
+    scratch.file("a/BUILD");
+    scratch.file("a/b/c/BUILD");
+    scratch.file("a/b/d/helloworld");
+
+    // When the top package is evaluated for recursive package values, and "a/b/c" is excluded,
+    ImmutableSet<PathFragment> excludedPaths = ImmutableSet.of(new PathFragment("a/b/c"));
+    SkyKey key = createPrepDepsKey(rootDirectory, new PathFragment("a"), excludedPaths);
+    EvaluationResult<PrepareDepsOfTargetsUnderDirectoryValue> evaluationResult =
+        getEvaluationResult(key);
+    PrepareDepsOfTargetsUnderDirectoryValue value = evaluationResult.get(key);
+
+    // Then the value reports that "a" is a package,
+    assertThat(value.isDirectoryPackage()).isTrue();
+
+    // And the subdirectory corresponding to "a/b" is present in the result,
+    RootedPath onlySubdir =
+        Iterables.getOnlyElement(value.getSubdirectoryTransitivelyContainsPackages().keySet());
+    assertThat(onlySubdir.getRelativePath()).isEqualTo(new PathFragment("a/b"));
+
+    // And the "a/b" subdirectory does not report a package under it (because it got excluded).
+    assertThat(value.getSubdirectoryTransitivelyContainsPackages().get(onlySubdir)).isFalse();
+
+    // Also, the computation graph contains a cached value for "a/b" with "a/b/c" excluded, because
+    // "a/b/c" does live underneath "a/b".
+    WalkableGraph graph = Preconditions.checkNotNull(evaluationResult.getWalkableGraph());
+    SkyKey abKey = createPrepDepsKey(rootDirectory, new PathFragment("a/b"), excludedPaths);
+    assertThat(graph.exists(abKey)).isTrue();
+    PrepareDepsOfTargetsUnderDirectoryValue abValue =
+        (PrepareDepsOfTargetsUnderDirectoryValue) Preconditions.checkNotNull(graph.getValue(abKey));
+
+    // And that value says that "a/b" is not a package,
+    assertThat(abValue.isDirectoryPackage()).isFalse();
+
+    // And only the subdirectory "a/b/d" is present in that value,
+    RootedPath abd =
+        Iterables.getOnlyElement(abValue.getSubdirectoryTransitivelyContainsPackages().keySet());
+    assertThat(abd.getRelativePath()).isEqualTo(new PathFragment("a/b/d"));
+
+    // And no package is under "a/b/d".
+    assertThat(abValue.getSubdirectoryTransitivelyContainsPackages().get(abd)).isFalse();
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTest.java
new file mode 100644
index 0000000..5359fe9
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTest.java
@@ -0,0 +1,317 @@
+// Copyright 2015 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.skyframe;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
+import com.google.common.collect.Sets;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.BuildFailedException;
+import com.google.devtools.build.lib.actions.util.TestAction;
+import com.google.devtools.build.lib.testutil.BlazeTestUtils;
+import com.google.devtools.build.lib.vfs.FileSystemUtils;
+
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * Test suite for TimestampBuilder.
+ *
+ */
+public class TimestampBuilderTest extends TimestampBuilderTestCase {
+
+  public void testAmnesiacBuilderAlwaysRebuilds() throws Exception {
+    // [action] -> hello
+    Artifact hello = createDerivedArtifact("hello");
+    Button button = createActionButton(emptySet, Sets.newHashSet(hello));
+
+    button.pressed = false;
+    buildArtifacts(amnesiacBuilder(), hello);
+    assertTrue(button.pressed); // built
+
+    button.pressed = false;
+    buildArtifacts(amnesiacBuilder(), hello);
+    assertTrue(button.pressed); // rebuilt
+  }
+
+  // If we re-use the same builder (even an "amnesiac" builder), it remembers
+  // which Actions it has already visited, and doesn't revisit them, even if
+  // they would otherwise be rebuilt.
+  //
+  // That is, Builders conflate traversal and dependency analysis, and don't
+  // revisit a node (traversal) even if it needs to be rebuilt (dependency
+  // analysis).  We might want to separate these aspects.
+  public void testBuilderDoesntRevisitActions() throws Exception {
+    // [action] -> hello
+    Artifact hello = createDerivedArtifact("hello");
+    Counter counter = createActionCounter(emptySet, Sets.newHashSet(hello));
+
+    Builder amnesiacBuilder = amnesiacBuilder();
+
+    counter.count = 0;
+    buildArtifacts(amnesiacBuilder, hello, hello);
+    assertEquals(counter.count, 1); // built only once
+  }
+
+  public void testBuildingExistingSourcefileSuceeds() throws Exception {
+    Artifact hello = createSourceArtifact("hello");
+    BlazeTestUtils.makeEmptyFile(hello.getPath());
+    buildArtifacts(cachingBuilder(), hello);
+  }
+
+  public void testBuildingNonexistentSourcefileFails() throws Exception {
+    reporter.removeHandler(failFastHandler);
+    Artifact hello = createSourceArtifact("hello");
+    try {
+      buildArtifacts(cachingBuilder(), hello);
+      fail("Expected input file to be missing");
+    } catch (BuildFailedException e) {
+      assertThat(e).hasMessage("missing input file '" + hello.getPath() + "'");
+    }
+  }
+
+  public void testCachingBuilderCachesUntilReset() throws Exception {
+    // [action] -> hello
+    Artifact hello = createDerivedArtifact("hello");
+    Button button = createActionButton(emptySet, Sets.newHashSet(hello));
+
+    button.pressed = false;
+    buildArtifacts(cachingBuilder(), hello);
+    assertTrue(button.pressed); // built
+
+    button.pressed = false;
+    buildArtifacts(cachingBuilder(), hello);
+    assertFalse(button.pressed); // not rebuilt
+
+    inMemoryCache.reset();
+
+    button.pressed = false;
+    buildArtifacts(cachingBuilder(), hello);
+    assertTrue(button.pressed); // rebuilt
+  }
+
+  public void testUnneededInputs() throws Exception {
+    Artifact hello = createSourceArtifact("hello");
+    BlazeTestUtils.makeEmptyFile(hello.getPath());
+    Artifact optional = createSourceArtifact("hello.optional");
+    Artifact goodbye = createDerivedArtifact("goodbye");
+    Button button = createActionButton(Sets.newHashSet(hello, optional), Sets.newHashSet(goodbye));
+
+    button.pressed = false;
+    buildArtifacts(cachingBuilder(), goodbye);
+    assertTrue(button.pressed); // built
+
+    button.pressed = false;
+    buildArtifacts(cachingBuilder(), goodbye);
+    assertFalse(button.pressed); // not rebuilt
+
+    BlazeTestUtils.makeEmptyFile(optional.getPath());
+
+    button.pressed = false;
+    buildArtifacts(cachingBuilder(), goodbye);
+    assertTrue(button.pressed); // built
+
+    button.pressed = false;
+    buildArtifacts(cachingBuilder(), goodbye);
+    assertFalse(button.pressed); // not rebuilt
+
+    optional.getPath().delete();
+
+    button.pressed = false;
+    buildArtifacts(cachingBuilder(), goodbye);
+    assertTrue(button.pressed); // built
+
+    button.pressed = false;
+    buildArtifacts(cachingBuilder(), goodbye);
+    assertFalse(button.pressed); // not rebuilt
+  }
+
+  public void testModifyingInputCausesActionReexecution() throws Exception {
+    // hello -> [action] -> goodbye
+    Artifact hello = createSourceArtifact("hello");
+    BlazeTestUtils.makeEmptyFile(hello.getPath());
+    Artifact goodbye = createDerivedArtifact("goodbye");
+    Button button = createActionButton(Sets.newHashSet(hello), Sets.newHashSet(goodbye));
+
+    button.pressed = false;
+    buildArtifacts(cachingBuilder(), goodbye);
+    assertTrue(button.pressed); // built
+
+    button.pressed = false;
+    buildArtifacts(cachingBuilder(), goodbye);
+    assertFalse(button.pressed); // not rebuilt
+
+    // inMemoryMetadataCache.useFileDigest is false, so new timestamp is enough to force a rebuild.
+    FileSystemUtils.touchFile(hello.getPath());
+
+    button.pressed = false;
+    buildArtifacts(cachingBuilder(), goodbye);
+    assertTrue(button.pressed); // rebuilt
+
+    button.pressed = false;
+    buildArtifacts(cachingBuilder(), goodbye);
+    assertFalse(button.pressed); // not rebuilt
+  }
+
+  public void testOnlyModifyingInputContentCausesReexecution() throws Exception {
+    // hello -> [action] -> goodbye
+    Artifact hello = createSourceArtifact("hello");
+    // touch file to create the directory structure
+    BlazeTestUtils.makeEmptyFile(hello.getPath());
+    FileSystemUtils.writeContentAsLatin1(hello.getPath(), "content1");
+
+    Artifact goodbye = createDerivedArtifact("goodbye");
+    Button button = createActionButton(Sets.newHashSet(hello), Sets.newHashSet(goodbye));
+
+    button.pressed = false;
+    buildArtifacts(cachingBuilder(), goodbye);
+    assertTrue(button.pressed); // built
+
+    button.pressed = false;
+    buildArtifacts(cachingBuilder(), goodbye);
+    assertFalse(button.pressed); // not rebuilt
+
+    FileSystemUtils.touchFile(hello.getPath());
+
+    button.pressed = false;
+    buildArtifacts(cachingBuilder(), goodbye);
+    assertFalse(button.pressed); // still not rebuilt
+
+    FileSystemUtils.writeContentAsLatin1(hello.getPath(), "content2");
+
+    button.pressed = false;
+    buildArtifacts(cachingBuilder(), goodbye);
+    assertTrue(button.pressed); // rebuilt
+
+    button.pressed = false;
+    buildArtifacts(cachingBuilder(), goodbye);
+    assertFalse(button.pressed); // not rebuilt
+  }
+
+  public void testModifyingOutputCausesActionReexecution() throws Exception {
+    // [action] -> hello
+    Artifact hello = createDerivedArtifact("hello");
+    Button button = createActionButton(emptySet, Sets.newHashSet(hello));
+
+    button.pressed = false;
+    buildArtifacts(cachingBuilder(), hello);
+    assertTrue(button.pressed); // built
+
+    button.pressed = false;
+    buildArtifacts(cachingBuilder(), hello);
+    assertFalse(button.pressed); // not rebuilt
+
+    // Touching the *output* file 'hello' causes 'action' to re-execute, to
+    // make things consistent again; this is not what Make would do, but it is
+    // correct according to this Builder.
+    BlazeTestUtils.changeModtime(hello.getPath());
+
+    button.pressed = false;
+    buildArtifacts(cachingBuilder(), hello);
+    assertTrue(button.pressed); // rebuilt
+
+    button.pressed = false;
+    buildArtifacts(cachingBuilder(), hello);
+    assertFalse(button.pressed); // not rebuilt
+  }
+
+  public void testBuildingTransitivePrerequisites() throws Exception {
+    // hello -> [action1] -> wazuup -> [action2] -> goodbye
+    Artifact hello = createSourceArtifact("hello");
+    BlazeTestUtils.makeEmptyFile(hello.getPath());
+    Artifact wazuup = createDerivedArtifact("wazuup");
+    Button button1 = createActionButton(Sets.newHashSet(hello), Sets.newHashSet(wazuup));
+    Artifact goodbye = createDerivedArtifact("goodbye");
+    Button button2 = createActionButton(Sets.newHashSet(wazuup), Sets.newHashSet(goodbye));
+
+    button1.pressed = button2.pressed = false;
+    buildArtifacts(cachingBuilder(), wazuup);
+    assertTrue(button1.pressed); // built wazuup
+    assertFalse(button2.pressed); // goodbye not built
+
+    button1.pressed = button2.pressed = false;
+    buildArtifacts(cachingBuilder(), wazuup);
+    assertFalse(button1.pressed); // wazuup not rebuilt
+    assertFalse(button2.pressed); // goodbye not built
+
+    button1.pressed = button2.pressed = false;
+    buildArtifacts(cachingBuilder(), goodbye);
+    assertFalse(button1.pressed); // wazuup not rebuilt
+    assertTrue(button2.pressed); // built goodbye
+
+    button1.pressed = button2.pressed = false;
+    buildArtifacts(cachingBuilder(), goodbye);
+    assertFalse(button1.pressed); // wazuup not rebuilt
+    assertFalse(button2.pressed); // goodbye not rebuilt
+
+    FileSystemUtils.touchFile(hello.getPath());
+
+    button1.pressed = button2.pressed = false;
+    buildArtifacts(cachingBuilder(), goodbye);
+    assertTrue(button1.pressed); // hello rebuilt
+    assertTrue(button2.pressed); // goodbye rebuilt
+  }
+
+  public void testWillNotRebuildActionsWithEmptyListOfInputsSpuriously()
+      throws Exception {
+
+    Artifact anOutputFile = createDerivedArtifact("anOutputFile");
+    Artifact anotherOutputFile = createDerivedArtifact("anotherOutputFile");
+    Collection<Artifact> noInputs = Collections.emptySet();
+
+    Button aButton = createActionButton(noInputs, Sets.newHashSet(anOutputFile));
+    Button anotherButton = createActionButton(noInputs,
+                                              Sets.newHashSet(anotherOutputFile));
+
+    buildArtifacts(cachingBuilder(), anOutputFile, anotherOutputFile);
+
+    assertTrue(aButton.pressed);
+    assertTrue(anotherButton.pressed);
+
+    aButton.pressed = anotherButton.pressed = false;
+
+    buildArtifacts(cachingBuilder(), anOutputFile, anotherOutputFile);
+
+    assertFalse(aButton.pressed);
+    assertFalse(anotherButton.pressed);
+  }
+
+  public void testMissingSourceFileIsAnError() throws Exception {
+    // A missing input to an action must be treated as an error because there's
+    // a risk that the action that consumes it will succeed, but with a
+    // different behavior (imagine that it globs over the directory, for
+    // example).  It's not ok to simply try the action and let the action
+    // report "input file not found".
+    //
+    // (However, there are exceptions to this principle: C++ compilation
+    // actions may depend on non-existent headers from stale .d files.  We need
+    // to allow the action to proceed to execution in this case.)
+
+    reporter.removeHandler(failFastHandler);
+    Artifact in = createSourceArtifact("in"); // doesn't exist
+    Artifact out = createDerivedArtifact("out");
+
+    registerAction(new TestAction(TestAction.NO_EFFECT, Collections.singleton(in),
+        Collections.singleton(out)));
+
+    try {
+      buildArtifacts(amnesiacBuilder(), out); // fails with ActionExecutionException
+      fail();
+    } catch (BuildFailedException e) {
+      assertThat(e.getMessage()).contains("1 input file(s) do not exist");
+    }
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunctionTest.java
new file mode 100644
index 0000000..da7eadc
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunctionTest.java
@@ -0,0 +1,195 @@
+// Copyright 2015 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.skyframe;
+
+import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
+import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
+import com.google.devtools.build.lib.bazel.rules.BazelRulesModule;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.packages.NoSuchTargetException;
+import com.google.devtools.build.lib.packages.Package;
+import com.google.devtools.build.lib.packages.PackageFactory;
+import com.google.devtools.build.lib.packages.Rule;
+import com.google.devtools.build.lib.testutil.MoreAsserts;
+import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
+import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.lib.vfs.PathFragment;
+import com.google.devtools.build.lib.vfs.RootedPath;
+import com.google.devtools.build.skyframe.SkyFunction;
+import com.google.devtools.build.skyframe.SkyKey;
+
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+
+import java.io.IOException;
+
+/**
+ * Test for {@link WorkspaceFileFunction}.
+ */
+public class WorkspaceFileFunctionTest extends BuildViewTestCase {
+
+  private WorkspaceFileFunction skyFunc;
+  private FakeFileValue fakeWorkspaceFileValue;
+
+  private static class FakeFileValue extends FileValue {
+    private boolean exists;
+    private long size;
+
+    FakeFileValue() {
+      super();
+      exists = true;
+      size = 0L;
+    }
+
+    @Override
+    public RootedPath realRootedPath() {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public FileStateValue realFileStateValue() {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean exists() {
+      return exists;
+    }
+
+    private void setExists(boolean exists) {
+      this.exists = exists;
+    }
+
+    @Override
+    public long getSize() {
+      return size;
+    }
+
+    private void setSize(long size) {
+      this.size = size;
+    }
+  }
+
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+    ConfiguredRuleClassProvider ruleClassProvider = TestRuleClassProvider.getRuleClassProvider();
+    skyFunc =
+        new WorkspaceFileFunction(
+            ruleClassProvider,
+            new PackageFactory(
+                TestRuleClassProvider.getRuleClassProvider(),
+                new BazelRulesModule().getPackageEnvironmentExtension()),
+            directories);
+    fakeWorkspaceFileValue = new FakeFileValue();
+  }
+
+  private Label getLabelMapping(Package pkg, String name) throws NoSuchTargetException {
+    return (Label) ((Rule) pkg.getTarget(name)).getAttributeContainer().getAttr("actual");
+  }
+
+  private RootedPath createWorkspaceFile(String... contents) throws IOException {
+    Path workspacePath = scratch.overwriteFile("WORKSPACE", contents);
+    fakeWorkspaceFileValue.setSize(workspacePath.getFileSize());
+    return RootedPath.toRootedPath(
+        workspacePath.getParentDirectory(), new PathFragment(workspacePath.getBaseName()));
+  }
+
+  private SkyFunction.Environment getEnv() {
+    SkyFunction.Environment env = Mockito.mock(SkyFunction.Environment.class);
+    Mockito.when(env.getValue(Matchers.<SkyKey>any())).thenReturn(fakeWorkspaceFileValue);
+    return env;
+  }
+
+  public void testInvalidRepo() throws Exception {
+    RootedPath workspacePath = createWorkspaceFile("workspace(name = 'foo$')");
+    PackageValue value =
+        (PackageValue) skyFunc.compute(PackageValue.workspaceKey(workspacePath), getEnv());
+    Package pkg = value.getPackage();
+    assertTrue(pkg.containsErrors());
+    MoreAsserts.assertContainsEvent(pkg.getEvents(), "target names may not contain '$'");
+  }
+
+  public void testBindFunction() throws Exception {
+    String lines[] = {"bind(name = 'foo/bar',", "actual = '//foo:bar')"};
+    RootedPath workspacePath = createWorkspaceFile(lines);
+
+    SkyKey key = PackageValue.workspaceKey(workspacePath);
+    PackageValue value = (PackageValue) skyFunc.compute(key, getEnv());
+    Package pkg = value.getPackage();
+    assertEquals(Label.parseAbsolute("//foo:bar"), getLabelMapping(pkg, "foo/bar"));
+    MoreAsserts.assertNoEvents(pkg.getEvents());
+  }
+
+  public void testBindArgsReversed() throws Exception {
+    String lines[] = {"bind(actual = '//foo:bar', name = 'foo/bar')"};
+    RootedPath workspacePath = createWorkspaceFile(lines);
+
+    SkyKey key = PackageValue.workspaceKey(workspacePath);
+    PackageValue value = (PackageValue) skyFunc.compute(key, getEnv());
+    Package pkg = value.getPackage();
+    assertEquals(Label.parseAbsolute("//foo:bar"), getLabelMapping(pkg, "foo/bar"));
+    MoreAsserts.assertNoEvents(pkg.getEvents());
+  }
+
+  public void testNonExternalBinding() throws Exception {
+    // name must be a valid label name.
+    String lines[] = {"bind(name = 'foo:bar', actual = '//bar/baz')"};
+    RootedPath workspacePath = createWorkspaceFile(lines);
+
+    PackageValue value =
+        (PackageValue) skyFunc.compute(PackageValue.workspaceKey(workspacePath), getEnv());
+    Package pkg = value.getPackage();
+    assertTrue(pkg.containsErrors());
+    MoreAsserts.assertContainsEvent(pkg.getEvents(), "target names may not contain ':'");
+  }
+
+  public void testWorkspaceFileParsingError() throws Exception {
+    // //external:bar:baz is not a legal package.
+    String lines[] = {"bind(name = 'foo/bar', actual = '//external:bar:baz')"};
+    RootedPath workspacePath = createWorkspaceFile(lines);
+
+    PackageValue value =
+        (PackageValue) skyFunc.compute(PackageValue.workspaceKey(workspacePath), getEnv());
+    Package pkg = value.getPackage();
+    assertTrue(pkg.containsErrors());
+    MoreAsserts.assertContainsEvent(pkg.getEvents(), "target names may not contain ':'");
+  }
+
+  public void testNoWorkspaceFile() throws Exception {
+    // Even though the WORKSPACE exists, Skyframe thinks it doesn't, so it doesn't.
+    String lines[] = {"bind(name = 'foo/bar', actual = '//foo:bar')"};
+    RootedPath workspacePath = createWorkspaceFile(lines);
+    fakeWorkspaceFileValue.setExists(false);
+
+    PackageValue value =
+        (PackageValue) skyFunc.compute(PackageValue.workspaceKey(workspacePath), getEnv());
+    Package pkg = value.getPackage();
+    assertFalse(pkg.containsErrors());
+    MoreAsserts.assertNoEvents(pkg.getEvents());
+  }
+
+  public void testListBindFunction() throws Exception {
+    String lines[] = {
+        "L = ['foo', 'bar']", "bind(name = '%s/%s' % (L[0], L[1]),", "actual = '//foo:bar')"};
+    RootedPath workspacePath = createWorkspaceFile(lines);
+
+    SkyKey key = PackageValue.workspaceKey(workspacePath);
+    PackageValue value = (PackageValue) skyFunc.compute(key, getEnv());
+    Package pkg = value.getPackage();
+    assertEquals(Label.parseAbsolute("//foo:bar"), getLabelMapping(pkg, "foo/bar"));
+    MoreAsserts.assertNoEvents(pkg.getEvents());
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/skyframe/BUILD b/src/test/java/com/google/devtools/build/skyframe/BUILD
new file mode 100644
index 0000000..7313ed0
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/skyframe/BUILD
@@ -0,0 +1,53 @@
+TESTUTIL_FILES = [
+    "DeterministicInMemoryGraph.java",
+    "NotifyingInMemoryGraph.java",
+    "TrackingAwaiter.java",
+    "GraphTester.java",
+    "GenericFunctionException.java",
+    "SomeErrorException.java",
+    "TrackingInvalidationReceiver.java",
+    "WalkableGraphUtils.java",
+]
+
+java_library(
+    name = "testutil",
+    srcs = TESTUTIL_FILES,
+    visibility = [
+        "//src/test/java/com/google/devtools/build/lib:__pkg__",
+    ],
+    deps = [
+        "//src/main/java/com/google/devtools/build/lib:collect",
+        "//src/main/java/com/google/devtools/build/lib:concurrent",
+        "//src/main/java/com/google/devtools/build/lib:events",
+        "//src/main/java/com/google/devtools/build/lib:util",
+        "//src/main/java/com/google/devtools/build/skyframe",
+        "//src/test/java/com/google/devtools/build/lib:testutil",
+        "//third_party:guava",
+        "//third_party:guava-testlib",
+        "//third_party:jsr305",
+        "//third_party:truth",
+    ],
+)
+
+java_test(
+    name = "skyframe_base_test",
+    srcs = glob(
+        ["*.java"],
+        exclude = TESTUTIL_FILES,
+    ),
+    args = ["com.google.devtools.build.skyframe.AllTests"],
+    deps = [
+        ":testutil",
+        "//src/main/java/com/google/devtools/build/lib:collect",
+        "//src/main/java/com/google/devtools/build/lib:concurrent",
+        "//src/main/java/com/google/devtools/build/lib:events",
+        "//src/main/java/com/google/devtools/build/lib:util",
+        "//src/main/java/com/google/devtools/build/skyframe",
+        "//src/test/java/com/google/devtools/build/lib:testutil",
+        "//third_party:guava",
+        "//third_party:guava-testlib",
+        "//third_party:jsr305",
+        "//third_party:junit4",
+        "//third_party:truth",
+    ],
+)
