// Copyright 2021 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 com.google.common.truth.Truth.assertWithMessage;
import static com.google.common.truth.Truth8.assertThat;
import static com.google.devtools.build.lib.actions.FileStateValue.DIRECTORY_FILE_STATE_NODE;
import static com.google.devtools.build.lib.actions.FileStateValue.NONEXISTENT_FILE_STATE_NODE;
import static com.google.devtools.build.lib.testing.common.DirectoryListingHelper.file;
import static com.google.devtools.build.lib.testing.common.DirectoryListingHelper.symlink;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.fail;

import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Streams;
import com.google.devtools.build.lib.actions.FileStateValue;
import com.google.devtools.build.lib.server.FailureDetails.DiffAwareness.Code;
import com.google.devtools.build.lib.testutil.Scratch;
import com.google.devtools.build.lib.util.AbruptExitException;
import com.google.devtools.build.lib.vfs.DelegateFileSystem;
import com.google.devtools.build.lib.vfs.Dirent;
import com.google.devtools.build.lib.vfs.FileStateKey;
import com.google.devtools.build.lib.vfs.FileStatus;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.Root;
import com.google.devtools.build.lib.vfs.RootedPath;
import com.google.devtools.build.lib.vfs.SyscallCache;
import com.google.devtools.build.skyframe.ImmutableDiff;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import com.google.testing.junit.testparameterinjector.TestParameter;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

/** Unit tests for {@link FileSystemValueCheckerInferringAncestors}. */
@RunWith(TestParameterInjector.class)
public final class FileSystemValueCheckerInferringAncestorsTest {
  private final Scratch scratch = new Scratch();
  private final List<String> statedPaths = new ArrayList<>();
  private final DefaultSyscallCache syscallCache = DefaultSyscallCache.newBuilder().build();
  private Root root;
  private Root untrackedRoot;
  private Exception throwOnStat;

  @TestParameter({"1", "16"})
  private int fsvcThreads;

  @Before
  public void createRoot() throws IOException {
    Path srcRootPath = scratch.dir("/src");
    PathFragment srcRoot = srcRootPath.asFragment();
    FileSystem trackingFileSystem =
        new DelegateFileSystem(scratch.getFileSystem()) {
          @Nullable
          @Override
          public synchronized FileStatus statIfFound(PathFragment path, boolean followSymlinks)
              throws IOException {
            if (throwOnStat != null) {
              Exception toThrow = throwOnStat;
              throwOnStat = null;
              Throwables.propagateIfPossible(toThrow, IOException.class);
              fail("Unexpected exception type");
            }
            statedPaths.add(path.relativeTo(srcRoot).toString());
            return super.statIfFound(path, followSymlinks);
          }
        };
    root = Root.fromPath(trackingFileSystem.getPath(srcRoot));
    scratch.setWorkingDir("/src");
    untrackedRoot = Root.fromPath(srcRootPath);
  }

  @After
  public void checkExceptionThrown() {
    assertThat(throwOnStat).isNull();
    syscallCache.clear();
  }

  @Test
  public void getDiffWithInferredAncestors_unknownFileChanged_returnsFileAndDirs()
      throws Exception {
    ImmutableDiff diff =
        FileSystemValueCheckerInferringAncestors.getDiffWithInferredAncestors(
            /*tsgm=*/ null,
            /*graphValues=*/ ImmutableMap.of(),
            /*graphDoneValues=*/ ImmutableMap.of(),
            /*modifiedKeys=*/ ImmutableSet.of(fileStateValueKey("foo/file")),
            fsvcThreads,
            syscallCache);

    assertThat(diff.changedKeysWithoutNewValues())
        .containsExactly(
            fileStateValueKey(""),
            fileStateValueKey("foo"),
            fileStateValueKey("foo/file"),
            directoryListingStateValueKey(""),
            directoryListingStateValueKey("foo"));
    assertThat(diff.changedKeysWithNewValues()).isEmpty();
    assertThat(statedPaths).isEmpty();
  }

  @Test
  public void getDiffWithInferredAncestors_fileModified_returnsFileWithValues() throws Exception {
    scratch.file("file", "hello");
    FileStateKey key = fileStateValueKey("file");
    FileStateValue value = fileStateValue("file");
    scratch.overwriteFile("file", "there");

    ImmutableDiff diff =
        FileSystemValueCheckerInferringAncestors.getDiffWithInferredAncestors(
            /*tsgm=*/ null,
            /*graphValues=*/ ImmutableMap.of(fileStateValueKey("file"), value),
            /*graphDoneValues=*/ ImmutableMap.of(),
            /*modifiedKeys=*/ ImmutableSet.of(key),
            fsvcThreads,
            syscallCache);

    FileStateValue newValue = fileStateValue("file");
    assertThat(diff.changedKeysWithNewValues()).containsExactly(key, newValue);
    assertThat(diff.changedKeysWithoutNewValues()).isEmpty();
    assertThat(statedPaths).containsExactly("file");
  }

  @Test
  public void getDiffWithInferredAncestors_fileAdded_returnsFileAndDirListing() throws Exception {
    scratch.file("file");
    FileStateKey key = fileStateValueKey("file");

    ImmutableDiff diff =
        FileSystemValueCheckerInferringAncestors.getDiffWithInferredAncestors(
            /*tsgm=*/ null,
            /*graphValues=*/ ImmutableMap.of(
                key, NONEXISTENT_FILE_STATE_NODE, fileStateValueKey(""), fileStateValue("")),
            /*graphDoneValues=*/ ImmutableMap.of(),
            /*modifiedKeys=*/ ImmutableSet.of(key),
            fsvcThreads,
            syscallCache);

    FileStateValue value = fileStateValue("file");
    assertThat(diff.changedKeysWithNewValues()).containsExactly(key, value);
    assertThat(diff.changedKeysWithoutNewValues())
        .containsExactly(directoryListingStateValueKey(""));
    assertThat(statedPaths).containsExactly("file");
  }

  @Test
  public void getDiffWithInferredAncestors_fileWithDirsAdded_returnsFileAndInjectsDirs()
      throws Exception {
    scratch.file("a/b/file");
    FileStateKey fileKey = fileStateValueKey("a/b/file");

    ImmutableDiff diff =
        FileSystemValueCheckerInferringAncestors.getDiffWithInferredAncestors(
            /*tsgm=*/ null,
            /*graphValues=*/ ImmutableMap.of(
                fileStateValueKey(""),
                fileStateValue(""),
                fileStateValueKey("a"),
                NONEXISTENT_FILE_STATE_NODE,
                fileStateValueKey("a/b"),
                NONEXISTENT_FILE_STATE_NODE,
                fileKey,
                NONEXISTENT_FILE_STATE_NODE),
            /*graphDoneValues=*/ ImmutableMap.of(),
            /*modifiedKeys=*/ ImmutableSet.of(fileKey),
            fsvcThreads,
            syscallCache);

    FileStateValue value = fileStateValue("a/b/file");
    assertThat(diff.changedKeysWithNewValues())
        .containsExactly(
            fileKey,
            value,
            fileStateValueKey("a"),
            DIRECTORY_FILE_STATE_NODE,
            fileStateValueKey("a/b"),
            DIRECTORY_FILE_STATE_NODE);
    assertThat(diff.changedKeysWithoutNewValues())
        .containsExactly(
            directoryListingStateValueKey(""),
            directoryListingStateValueKey("a"),
            directoryListingStateValueKey("a/b"));
    assertThat(statedPaths).containsExactly("a/b/file");
  }

  @Test
  public void getDiffWithInferredAncestors_addedFileWithReportedDirs_returnsFileAndInjectsDirs()
      throws Exception {
    scratch.file("a/b/file");
    FileStateKey fileKey = fileStateValueKey("a/b/file");

    ImmutableDiff diff =
        FileSystemValueCheckerInferringAncestors.getDiffWithInferredAncestors(
            /*tsgm=*/ null,
            /*graphValues=*/ ImmutableMap.of(
                fileStateValueKey(""),
                fileStateValue(""),
                fileStateValueKey("a"),
                NONEXISTENT_FILE_STATE_NODE,
                fileStateValueKey("a/b"),
                NONEXISTENT_FILE_STATE_NODE,
                fileKey,
                NONEXISTENT_FILE_STATE_NODE),
            /*graphDoneValues=*/ ImmutableMap.of(),
            /*modifiedKeys=*/ ImmutableSet.of(fileKey, fileStateValueKey("a")),
            fsvcThreads,
            syscallCache);

    FileStateValue newState = fileStateValue("a/b/file");
    assertThat(diff.changedKeysWithNewValues())
        .containsExactly(
            fileKey,
            newState,
            fileStateValueKey("a"),
            DIRECTORY_FILE_STATE_NODE,
            fileStateValueKey("a/b"),
            DIRECTORY_FILE_STATE_NODE);
    assertThat(diff.changedKeysWithoutNewValues())
        .containsExactly(
            directoryListingStateValueKey(""),
            directoryListingStateValueKey("a"),
            directoryListingStateValueKey("a/b"));
    assertThat(statedPaths).containsExactly("a/b/file");
  }

  /**
   * This is a degenerate case since we normally only know about a file if we checked all parents,
   * but that is theoretically possible with this API.
   */
  @Test
  public void getDiffWithInferredAncestors_fileWithUnknownDirsAdded_returnsFileAndDirs()
      throws Exception {
    scratch.file("a/b/c/d");

    ImmutableDiff diff =
        FileSystemValueCheckerInferringAncestors.getDiffWithInferredAncestors(
            /*tsgm=*/ null,
            /*graphValues=*/ ImmutableMap.of(
                fileStateValueKey(""),
                fileStateValue(""),
                fileStateValueKey("a/b/c/d"),
                NONEXISTENT_FILE_STATE_NODE),
            /*graphDoneValues=*/ ImmutableMap.of(),
            /*modifiedKeys=*/ ImmutableSet.of(fileStateValueKey("a/b/c/d")),
            fsvcThreads,
            syscallCache);

    assertThat(diff.changedKeysWithoutNewValues())
        .containsExactly(
            fileStateValueKey("a"),
            fileStateValueKey("a/b"),
            fileStateValueKey("a/b/c"),
            directoryListingStateValueKey(""),
            directoryListingStateValueKey("a"),
            directoryListingStateValueKey("a/b"),
            directoryListingStateValueKey("a/b/c"));
    assertThat(diff.changedKeysWithNewValues())
        .containsExactly(fileStateValueKey("a/b/c/d"), fileStateValue("a/b/c/d"));
    assertThat(statedPaths).containsExactly("a/b/c/d");
  }

  @Test
  public void getDiffWithInferredAncestors_addEmptyDir_returnsDirAndParentListing()
      throws Exception {
    scratch.dir("dir");
    FileStateKey key = fileStateValueKey("dir");
    FileStateValue value = fileStateValue("dir");

    ImmutableDiff diff =
        FileSystemValueCheckerInferringAncestors.getDiffWithInferredAncestors(
            /*tsgm=*/ null,
            /*graphValues=*/ ImmutableMap.of(
                key, NONEXISTENT_FILE_STATE_NODE, fileStateValueKey(""), fileStateValue("")),
            /*graphDoneValues=*/ ImmutableMap.of(),
            /*modifiedKeys=*/ ImmutableSet.of(key),
            fsvcThreads,
            syscallCache);

    assertThat(diff.changedKeysWithNewValues()).containsExactly(key, value);
    assertThat(diff.changedKeysWithoutNewValues())
        .containsExactly(directoryListingStateValueKey(""));
    assertThat(statedPaths).containsExactly("dir");
  }

  @Test
  public void getDiffWithInferredAncestors_deleteFile_returnsFileParentListing() throws Exception {
    Path file = scratch.file("dir/file1");
    scratch.file("dir/file2");
    FileStateKey key = fileStateValueKey("dir/file1");
    FileStateValue oldValue = fileStateValue("dir/file1");
    file.delete();

    ImmutableDiff diff =
        FileSystemValueCheckerInferringAncestors.getDiffWithInferredAncestors(
            /*tsgm=*/ null,
            /*graphValues=*/ ImmutableMap.of(
                key, oldValue, fileStateValueKey("dir"), fileStateValue("dir")),
            /*graphDoneValues=*/ ImmutableMap.of(),
            /*modifiedKeys=*/ ImmutableSet.of(key),
            fsvcThreads,
            syscallCache);

    assertThat(diff.changedKeysWithNewValues()).containsExactly(key, NONEXISTENT_FILE_STATE_NODE);
    assertThat(diff.changedKeysWithoutNewValues())
        .containsExactly(directoryListingStateValueKey("dir"));
    assertThat(statedPaths).containsExactly("dir/file1", "dir");
  }

  @Test
  public void getDiffWithInferredAncestors_deleteFileFromDirWithListing_skipsDirStat()
      throws Exception {
    Path file1 = scratch.file("dir/file1");
    FileStateKey key = fileStateValueKey("dir/file1");
    FileStateValue oldValue = fileStateValue("dir/file1");
    file1.delete();

    ImmutableDiff diff =
        FileSystemValueCheckerInferringAncestors.getDiffWithInferredAncestors(
            /*tsgm=*/ null,
            /*graphValues=*/ ImmutableMap.of(
                key, oldValue, fileStateValueKey("dir"), fileStateValue("dir")),
            /*graphDoneValues=*/ ImmutableMap.of(
                directoryListingStateValueKey("dir"),
                directoryListingStateValue(file("file1"), file("file2"))),
            /*modifiedKeys=*/ ImmutableSet.of(key),
            fsvcThreads,
            syscallCache);

    assertThat(diff.changedKeysWithNewValues()).containsExactly(key, NONEXISTENT_FILE_STATE_NODE);
    assertThat(diff.changedKeysWithoutNewValues())
        .containsExactly(directoryListingStateValueKey("dir"));
    assertThat(statedPaths).containsExactly("dir/file1");
  }

  @Test
  public void getDiffWithInferredAncestors_deleteLastFileFromDir_ignoresInvalidatedListing()
      throws Exception {
    Path file1 = scratch.file("dir/file1");
    FileStateKey key = fileStateValueKey("dir/file1");
    FileStateValue oldValue = fileStateValue("dir/file1");
    file1.delete();

    ImmutableDiff diff =
        FileSystemValueCheckerInferringAncestors.getDiffWithInferredAncestors(
            /*tsgm=*/ null,
            /*graphValues=*/ ImmutableMap.of(
                key,
                oldValue,
                fileStateValueKey("dir"),
                fileStateValue("dir"),
                directoryListingStateValueKey("dir"),
                directoryListingStateValue(file("file1"), file("file2"))),
            /*graphDoneValues=*/ ImmutableMap.of(),
            /*modifiedKeys=*/ ImmutableSet.of(key),
            fsvcThreads,
            syscallCache);

    assertThat(diff.changedKeysWithNewValues()).containsExactly(key, NONEXISTENT_FILE_STATE_NODE);
    assertThat(diff.changedKeysWithoutNewValues())
        .containsExactly(directoryListingStateValueKey("dir"));
    assertThat(statedPaths).containsExactly("dir/file1", "dir");
  }

  @Test
  public void getDiffWithInferredAncestors_modifyAllUnknownEntriesInDirWithListing_skipsDir()
      throws Exception {
    Path file = scratch.file("dir/file");
    file.getParentDirectory()
        .getRelative("symlink")
        .createSymbolicLink(PathFragment.create("file"));
    FileStateKey fileKey = fileStateValueKey("dir/file");
    FileStateKey symlinkKey = fileStateValueKey("dir/symlink");

    ImmutableDiff diff =
        FileSystemValueCheckerInferringAncestors.getDiffWithInferredAncestors(
            /*tsgm=*/ null,
            /*graphValues=*/ ImmutableMap.of(fileStateValueKey("dir"), fileStateValue("dir")),
            /*graphDoneValues=*/ ImmutableMap.of(
                directoryListingStateValueKey("dir"),
                directoryListingStateValue(file("file"), symlink("symlink"))),
            /*modifiedKeys=*/ ImmutableSet.of(fileKey, symlinkKey),
            fsvcThreads,
            syscallCache);

    assertThat(diff.changedKeysWithNewValues())
        .containsExactly(
            fileKey, fileStateValue("dir/file"), symlinkKey, fileStateValue("dir/symlink"));
    assertThat(diff.changedKeysWithoutNewValues()).isEmpty();
    assertThat(statedPaths).containsExactly("dir/file", "dir/symlink");
  }

  @Test
  public void getDiffWithInferredAncestors_replaceUnknownEntriesInDirWithListing_skipsSiblingStat()
      throws Exception {
    scratch.dir("dir/file1");
    scratch.dir("dir/file2");
    FileStateKey file1Key = fileStateValueKey("dir/file1");
    FileStateKey file2Key = fileStateValueKey("dir/file2");
    DirectoryListingStateValue.Key dirKey = directoryListingStateValueKey("dir");

    ImmutableDiff diff =
        FileSystemValueCheckerInferringAncestors.getDiffWithInferredAncestors(
            /*tsgm=*/ null,
            /*graphValues=*/ ImmutableMap.of(fileStateValueKey("dir"), fileStateValue("dir")),
            /*graphDoneValues=*/ ImmutableMap.of(
                dirKey, directoryListingStateValue(file("file1"), file("file2"))),
            /*modifiedKeys=*/ ImmutableSet.of(file1Key, file2Key),
            fsvcThreads,
            syscallCache);

    assertIsSubsetOf(
        diff.changedKeysWithNewValues().entrySet(),
        Maps.immutableEntry(file1Key, fileStateValue("dir/file1")),
        Maps.immutableEntry(file2Key, fileStateValue("dir/file2")));
    assertThat(diff.changedKeysWithoutNewValues()).contains(dirKey);
    assertThat(
            Streams.concat(
                diff.changedKeysWithoutNewValues().stream(),
                diff.changedKeysWithNewValues().keySet().stream()))
        .containsExactly(file1Key, file2Key, dirKey);
    assertThat(statedPaths).isNotEmpty();
    assertIsSubsetOf(statedPaths, "dir/file1", "dir/file2");
    if (fsvcThreads == 1) {
      // In case of single-threaded execution, we know that once we check dir/file1 or dir/file2, we
      // will be able to skip stat on the other one.
      assertThat(diff.changedKeysWithNewValues()).hasSize(1);
      assertThat(diff.changedKeysWithoutNewValues()).hasSize(2);
      assertThat(statedPaths).hasSize(1);
    }
  }

  @Test
  public void getDiffWithInferredAncestors_deleteAllFilesFromDir_returnsFilesAndDirListing()
      throws Exception {
    Path file1 = scratch.file("dir/file1");
    Path file2 = scratch.file("dir/file2");
    Path file3 = scratch.file("dir/file3");
    FileStateKey key1 = fileStateValueKey("dir/file1");
    FileStateValue oldValue1 = fileStateValue("dir/file1");
    FileStateKey key2 = fileStateValueKey("dir/file2");
    FileStateValue oldValue2 = fileStateValue("dir/file2");
    FileStateKey key3 = fileStateValueKey("dir/file3");
    FileStateValue oldValue3 = fileStateValue("dir/file3");
    file1.delete();
    file2.delete();
    file3.delete();

    ImmutableDiff diff =
        FileSystemValueCheckerInferringAncestors.getDiffWithInferredAncestors(
            /*tsgm=*/ null,
            /*graphValues=*/ ImmutableMap.of(
                key1,
                oldValue1,
                key2,
                oldValue2,
                key3,
                oldValue3,
                fileStateValueKey("dir"),
                fileStateValue("dir")),
            /*graphDoneValues=*/ ImmutableMap.of(),
            /*modifiedKeys=*/ ImmutableSet.of(key1, key2, key3),
            fsvcThreads,
            syscallCache);

    assertThat(diff.changedKeysWithNewValues())
        .containsExactly(
            key1, NONEXISTENT_FILE_STATE_NODE,
            key2, NONEXISTENT_FILE_STATE_NODE,
            key3, NONEXISTENT_FILE_STATE_NODE);
    assertThat(diff.changedKeysWithoutNewValues())
        .containsExactly(directoryListingStateValueKey("dir"));
    assertThat(statedPaths).containsExactly("dir", "dir/file1", "dir/file2", "dir/file3");
  }

  @Test
  public void getDiffWithInferredAncestors_deleteFileWithDirs_returnsFileAndDirs()
      throws Exception {
    scratch.file("a/b/c/file");
    FileStateKey abKey = fileStateValueKey("a/b");
    FileStateValue abValue = fileStateValue("a/b");
    FileStateKey abcKey = fileStateValueKey("a/b/c");
    FileStateValue abcValue = fileStateValue("a/b/c");
    FileStateKey abcFileKey = fileStateValueKey("a/b/c/file");
    FileStateValue abcFileValue = fileStateValue("a/b/c/file");
    scratch.dir("a/b").deleteTree();

    ImmutableDiff diff =
        FileSystemValueCheckerInferringAncestors.getDiffWithInferredAncestors(
            /*tsgm=*/ null,
            /*graphValues=*/ ImmutableMap.of(
                fileStateValueKey("a"),
                fileStateValue("a"),
                abKey,
                abValue,
                abcKey,
                abcValue,
                abcFileKey,
                abcFileValue),
            /*graphDoneValues=*/ ImmutableMap.of(),
            /*modifiedKeys=*/ ImmutableSet.of(abcFileKey),
            fsvcThreads,
            syscallCache);

    assertThat(diff.changedKeysWithNewValues())
        .containsExactly(
            abKey, NONEXISTENT_FILE_STATE_NODE,
            abcKey, NONEXISTENT_FILE_STATE_NODE,
            abcFileKey, NONEXISTENT_FILE_STATE_NODE);
    assertThat(diff.changedKeysWithoutNewValues())
        .containsExactly(
            directoryListingStateValueKey("a"),
            directoryListingStateValueKey("a/b"),
            directoryListingStateValueKey("a/b/c"));
    assertThat(statedPaths).containsExactly("a", "a/b", "a/b/c", "a/b/c/file");
  }

  @Test
  public void getDiffWithInferredAncestors_deleteFileWithReportedDirs_returnsFileAndDirListings()
      throws Exception {
    scratch.file("a/b/c/file");
    FileStateKey abKey = fileStateValueKey("a/b");
    FileStateValue abValue = fileStateValue("a/b");
    FileStateKey abcKey = fileStateValueKey("a/b/c");
    FileStateValue abcValue = fileStateValue("a/b/c");
    FileStateKey abcFileKey = fileStateValueKey("a/b/c/file");
    FileStateValue abcFileValue = fileStateValue("a/b/c/file");
    scratch.dir("a/b").deleteTree();

    ImmutableDiff diff =
        FileSystemValueCheckerInferringAncestors.getDiffWithInferredAncestors(
            /*tsgm=*/ null,
            /*graphValues=*/ ImmutableMap.of(
                fileStateValueKey("a"),
                fileStateValue("a"),
                abKey,
                abValue,
                abcKey,
                abcValue,
                abcFileKey,
                abcFileValue),
            /*graphDoneValues=*/ ImmutableMap.of(),
            /*modifiedKeys=*/ ImmutableSet.of(abcFileKey, abKey),
            fsvcThreads,
            syscallCache);

    assertThat(diff.changedKeysWithNewValues())
        .containsExactly(
            abKey, NONEXISTENT_FILE_STATE_NODE,
            abcKey, NONEXISTENT_FILE_STATE_NODE,
            abcFileKey, NONEXISTENT_FILE_STATE_NODE);
    assertThat(diff.changedKeysWithoutNewValues())
        .containsExactly(
            directoryListingStateValueKey("a"),
            directoryListingStateValueKey("a/b"),
            directoryListingStateValueKey("a/b/c"));
    assertThat(statedPaths).containsExactly("a", "a/b", "a/b/c", "a/b/c/file");
  }

  @Test
  public void getDiffWithInferredAncestors_deleteFile_infersDirFromModifiedSibling()
      throws Exception {
    Path file1 = scratch.file("dir/file1");
    scratch.file("dir/file2", "1");
    FileStateKey file1Key = fileStateValueKey("dir/file1");
    FileStateValue file1Value = fileStateValue("dir/file1");
    FileStateKey file2Key = fileStateValueKey("dir/file2");
    FileStateValue file2Value = fileStateValue("dir/file2");
    file1.delete();
    scratch.overwriteFile("dir/file2", "12");

    ImmutableDiff diff =
        FileSystemValueCheckerInferringAncestors.getDiffWithInferredAncestors(
            /*tsgm=*/ null,
            /*graphValues=*/ ImmutableMap.of(
                fileStateValueKey("dir"),
                fileStateValue("dir"),
                file1Key,
                file1Value,
                file2Key,
                file2Value),
            /*graphDoneValues=*/ ImmutableMap.of(),
            /*modifiedKeys=*/ ImmutableSet.of(file1Key, file2Key, fileStateValueKey("dir")),
            fsvcThreads,
            syscallCache);

    FileStateValue file2NewValue = fileStateValue("dir/file2");
    assertThat(diff.changedKeysWithNewValues())
        .containsExactly(file1Key, NONEXISTENT_FILE_STATE_NODE, file2Key, file2NewValue);
    assertThat(diff.changedKeysWithoutNewValues())
        .containsExactly(directoryListingStateValueKey("dir"));
    assertThat(statedPaths).containsExactly("dir/file1", "dir/file2");
  }

  @Test
  public void getDiffWithInferredAncestors_deleteDirReportDirOnly_returnsDir() throws Exception {
    Path file1 = scratch.file("dir/file1");
    scratch.file("dir/file2");
    FileStateKey file1Key = fileStateValueKey("dir/file1");
    FileStateValue file1Value = fileStateValue("dir/file1");
    FileStateKey file2Key = fileStateValueKey("dir/file2");
    FileStateValue file2Value = fileStateValue("dir/file2");
    FileStateKey dirKey = fileStateValueKey("dir");
    FileStateValue dirValue = fileStateValue("dir");
    file1.getParentDirectory().deleteTree();

    ImmutableDiff diff =
        FileSystemValueCheckerInferringAncestors.getDiffWithInferredAncestors(
            /*tsgm=*/ null,
            /*graphValues=*/ ImmutableMap.of(
                file1Key,
                file1Value,
                file2Key,
                file2Value,
                dirKey,
                dirValue,
                fileStateValueKey(""),
                fileStateValue("")),
            /*graphDoneValues=*/ ImmutableMap.of(),
            /*modifiedKeys=*/ ImmutableSet.of(dirKey),
            fsvcThreads,
            syscallCache);

    assertThat(diff.changedKeysWithNewValues())
        .containsExactly(dirKey, NONEXISTENT_FILE_STATE_NODE);
    assertThat(diff.changedKeysWithoutNewValues())
        .containsExactly(directoryListingStateValueKey(""));
    assertThat(statedPaths).containsExactly("dir", "");
  }

  @Test
  public void getDiffWithInferredAncestors_phantomChangeForNonexistentEntry_returnsEmptyDiff()
      throws Exception {
    ImmutableDiff diff =
        FileSystemValueCheckerInferringAncestors.getDiffWithInferredAncestors(
            /*tsgm=*/ null,
            /*graphValues=*/ ImmutableMap.of(
                fileStateValueKey("file"), NONEXISTENT_FILE_STATE_NODE),
            /*graphDoneValues=*/ ImmutableMap.of(),
            /*modifiedKeys=*/ ImmutableSet.of(fileStateValueKey("file")),
            fsvcThreads,
            syscallCache);

    assertThat(diff.changedKeysWithoutNewValues()).isEmpty();
    assertThat(diff.changedKeysWithNewValues()).isEmpty();
    assertThat(statedPaths).containsExactly("file");
  }

  @Test
  public void getDiffWithInferredAncestors_statFails_fails() {
    throwOnStat = new IOException("oh no");
    ImmutableMap<SkyKey, SkyValue> graphValues =
        ImmutableMap.of(fileStateValueKey("file"), NONEXISTENT_FILE_STATE_NODE);
    ImmutableSet<FileStateKey> modifiedKeys = ImmutableSet.of(fileStateValueKey("file"));

    AbruptExitException e =
        assertThrows(
            AbruptExitException.class,
            () ->
                FileSystemValueCheckerInferringAncestors.getDiffWithInferredAncestors(
                    /*tsgm=*/ null,
                    graphValues,
                    /*graphDoneValues=*/ ImmutableMap.of(),
                    modifiedKeys,
                    fsvcThreads,
                    syscallCache));

    assertThat(e.getDetailedExitCode().getFailureDetail().hasDiffAwareness()).isTrue();
    assertThat(e.getDetailedExitCode().getFailureDetail().getDiffAwareness().getCode())
        .isEqualTo(Code.DIFF_STAT_FAILED);
    assertThat(e).hasMessageThat().isEqualTo("Failed to stat: '/src/file' while computing diff");
  }

  @Test
  public void getDiffWithInferredAncestors_statCrashes_fails() {
    throwOnStat = new RuntimeException("oh no");
    ImmutableMap<SkyKey, SkyValue> graphValues =
        ImmutableMap.of(fileStateValueKey("file"), NONEXISTENT_FILE_STATE_NODE);
    ImmutableSet<FileStateKey> modifiedKeys = ImmutableSet.of(fileStateValueKey("file"));

    assertThrows(
        IllegalStateException.class,
        () ->
            FileSystemValueCheckerInferringAncestors.getDiffWithInferredAncestors(
                /*tsgm=*/ null,
                graphValues,
                /*graphDoneValues=*/ ImmutableMap.of(),
                modifiedKeys,
                fsvcThreads,
                syscallCache));
  }

  private static <T> void assertIsSubsetOf(Iterable<T> list, T... elements) {
    ImmutableSet<T> set = ImmutableSet.copyOf(elements);
    assertWithMessage("%s has elements from outside of %s", list, set)
        .that(set)
        .containsAtLeastElementsIn(list);
  }

  private FileStateKey fileStateValueKey(String relativePath) {
    return FileStateValue.key(
        RootedPath.toRootedPath(root, root.asPath().getRelative(relativePath)));
  }

  private DirectoryListingStateValue.Key directoryListingStateValueKey(String relativePath) {
    return DirectoryListingStateValue.key(
        RootedPath.toRootedPath(root, root.asPath().getRelative(relativePath)));
  }

  private static DirectoryListingStateValue directoryListingStateValue(Dirent... dirents) {
    return DirectoryListingStateValue.create(ImmutableList.copyOf(dirents));
  }

  private FileStateValue fileStateValue(String relativePath) throws IOException {
    return FileStateValue.create(
        RootedPath.toRootedPath(
            untrackedRoot, untrackedRoot.asPath().asFragment().getRelative(relativePath)),
        SyscallCache.NO_CACHE,
        /*tsgm=*/ null);
  }
}
