diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BUILD b/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
index 28d35b08bc9969..9bcaa0efbac63c 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
@@ -1719,34 +1719,6 @@ java_library(
],
)
-java_library(
- name = "path_casing_lookup_function",
- srcs = ["PathCasingLookupFunction.java"],
- deps = [
- ":directory_listing_value",
- ":path_casing_lookup_value",
- "//src/main/java/com/google/devtools/build/lib/actions:file_metadata",
- "//src/main/java/com/google/devtools/build/lib/vfs",
- "//src/main/java/com/google/devtools/build/skyframe",
- "//src/main/java/com/google/devtools/build/skyframe:skyframe-objects",
- "//third_party:guava",
- ],
-)
-
-java_library(
- name = "path_casing_lookup_value",
- srcs = ["PathCasingLookupValue.java"],
- deps = [
- ":sky_functions",
- "//src/main/java/com/google/devtools/build/lib/concurrent",
- "//src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec",
- "//src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec:serialization-constant",
- "//src/main/java/com/google/devtools/build/lib/vfs",
- "//src/main/java/com/google/devtools/build/skyframe:skyframe-objects",
- "//third_party:guava",
- ],
-)
-
java_library(
name = "pattern_expanding_error",
srcs = ["PatternExpandingError.java"],
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PathCasingLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PathCasingLookupFunction.java
deleted file mode 100644
index 89424a96032bba..00000000000000
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PathCasingLookupFunction.java
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2019 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.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-import com.google.devtools.build.lib.actions.FileValue;
-import com.google.devtools.build.lib.vfs.Dirent;
-import com.google.devtools.build.lib.vfs.RootedPath;
-import com.google.devtools.build.lib.vfs.RootedPathAndCasing;
-import com.google.devtools.build.skyframe.SkyFunction;
-import com.google.devtools.build.skyframe.SkyFunctionException;
-import com.google.devtools.build.skyframe.SkyKey;
-import com.google.devtools.build.skyframe.SkyframeIterableResult;
-import java.io.IOException;
-
-/** SkyFunction for {@link PathCasingLookupValue}s. */
-public final class PathCasingLookupFunction implements SkyFunction {
-
- @Override
- public PathCasingLookupValue compute(SkyKey skyKey, Environment env)
- throws PathComponentIsNotDirectoryException, InterruptedException {
- RootedPathAndCasing arg = (RootedPathAndCasing) skyKey.argument();
- if (arg.getPath().getRootRelativePath().isEmpty()) {
- // This is a Root, e.g. "[/foo/bar]/[]".
- // As of 2019-12-04, PathCasingLookupValue is not used anywhere. But it's planned to be used
- // in PackageLookupFunction to validate the package part's casing, so the RootedPath's Root's
- // casing doesn't even matter, so if the relative part is empty then for our use case this is
- // a correctly cased RootedPath.
- return PathCasingLookupValue.GOOD;
- }
-
- RootedPath parent = arg.getPath().getParentDirectory();
- Preconditions.checkNotNull(parent, arg.getPath());
- Preconditions.checkNotNull(parent.getRootRelativePath(), arg.getPath());
-
- SkyKey parentCasingKey = PathCasingLookupValue.key(parent);
- SkyKey parentFileKey = FileValue.key(parent);
- SkyKey childFileKey = FileValue.key(arg.getPath());
- SkyframeIterableResult values =
- env.getOrderedValuesAndExceptions(
- ImmutableList.of(parentCasingKey, parentFileKey, childFileKey));
- if (env.valuesMissing()) {
- return null;
- }
- PathCasingLookupValue pathCasingLookupValue = (PathCasingLookupValue) values.next();
- if (pathCasingLookupValue == null) {
- return null;
- }
- if (!pathCasingLookupValue.isCorrect()) {
- // Parent's casing is bad, so this path's casing is also bad.
- return PathCasingLookupValue.BAD;
- }
-
- FileValue parentFile = (FileValue) values.next();
- if (parentFile == null) {
- return null;
- }
- if (!parentFile.exists()) {
- // Parent's casing is good, because it's missing.
- // That means this path is also missing, so by definition its casing is good.
- return PathCasingLookupValue.GOOD;
- }
- if (!parentFile.isDirectory()) {
- // Parent's casing is good, but it's not a directory.
- throw new PathComponentIsNotDirectoryException(
- new IOException(
- "Cannot check path casing of "
- + arg.getPath()
- + ": its parent exists but is not a directory"));
- }
-
- FileValue childFile = (FileValue) values.next();
- if (childFile == null) {
- return null;
- }
- if (!childFile.exists()) {
- // Parent's casing is good, but this file is missing.
- // That means this path is missing, so by definition its casing is good.
- return PathCasingLookupValue.GOOD;
- }
-
- // The parent file must exist, otherwise the DirectoryListingFunction will throw.
- SkyKey parentListingKey = DirectoryListingValue.key(parent);
- DirectoryListingValue parentList = (DirectoryListingValue) env.getValue(parentListingKey);
- if (parentList == null) {
- return null;
- }
-
- String expected = arg.getPath().getRootRelativePath().getBaseName();
- // We already handled RootedPaths with empty relative part.
- Preconditions.checkState(!Strings.isNullOrEmpty(expected), arg.getPath());
-
- Dirent child = parentList.getDirents().maybeGetDirent(expected);
- return (child != null && expected.equals(child.getName()))
- ? PathCasingLookupValue.GOOD
- : PathCasingLookupValue.BAD;
- }
-
- /** Thrown if a non-terminal path component exists, but it's not a directory. */
- public static final class PathComponentIsNotDirectoryException extends SkyFunctionException {
- public PathComponentIsNotDirectoryException(IOException e) {
- super(e, Transience.PERSISTENT);
- }
- }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PathCasingLookupValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/PathCasingLookupValue.java
deleted file mode 100644
index 8c77fa5fc28fa4..00000000000000
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PathCasingLookupValue.java
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2019 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.base.Preconditions;
-import com.google.common.collect.Interner;
-import com.google.devtools.build.lib.concurrent.BlazeInterners;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.SerializationConstant;
-import com.google.devtools.build.lib.vfs.RootedPath;
-import com.google.devtools.build.lib.vfs.RootedPathAndCasing;
-import com.google.devtools.build.skyframe.AbstractSkyKey;
-import com.google.devtools.build.skyframe.SkyFunctionName;
-import com.google.devtools.build.skyframe.SkyKey;
-import com.google.devtools.build.skyframe.SkyValue;
-
-/**
- * Value that represents whether a certain path is correctly cased.
- *
- *
Most filesystems preserve uppercase and lowercase letters when creating entries: {@code
- * mkdir("Abc1")} creates the directory "Abc1", and not "ABC1" nor "abc1".
- *
- *
Some filesystems differentiate casing when looking up entries, but some don't. Suppose we have
- * an empty directory and create the file "Abc1" underneath it. Then, calling {@code exists("Abc1")}
- * succeeds and {@code exists("ABC1")} fails on ext4 (Linux) but both calls succeed on APFS (macOS)
- * and NTFS (Windows). Reason for this difference is that ext4 is case-sensitive, so "Abc1" and
- * "ABC1" mean different files, but APFS and NTFS are case-ignoring (or case-insensitive), so both
- * paths mean the same file.
- *
- *
This object represents whether an existing path on a case-ignoring filesystem (APFS and NTFS)
- * is correctly or incorrectly cased, i.e. whether the exact use of upper and lower case letters
- * matches the entry on disk. In the previous example, "Abc1" is correctly cased while "ABC1" is
- * incorrectly cased.
- *
- *
Paths on case-sensitive filesystems (ext4) are always correctly cased, because the filesystem
- * requires exact case matching when accessing files.
- */
-public abstract class PathCasingLookupValue implements SkyValue {
-
- @SerializationConstant public static final BadPathCasing BAD = new BadPathCasing();
-
- @SerializationConstant public static final CorrectPathCasing GOOD = new CorrectPathCasing();
-
- /** Singleton {@link PathCasingLookupValue} instance for incorrectly cased paths. */
- public static class BadPathCasing extends PathCasingLookupValue {
- @Override
- public boolean isCorrect() {
- return false;
- }
- }
-
- /** Singleton {@link PathCasingLookupValue} instance for correctly cased paths. */
- public static class CorrectPathCasing extends PathCasingLookupValue {
- @Override
- public boolean isCorrect() {
- return true;
- }
- }
-
- /**
- * Creates a {@code SkyKey} to request this {@code PathCasingLookupValue} from Skyframe.
- *
- *
The argument is a {@link RootedPath} and not a {@link Path} for two reasons:
- *
- *
- * - as of 2019-12-04 the {@code PathCasingLookupFunction} depends on {@code
- * DirectoryListingValue} whose {@code SkyKey} requires a {@code RootedPath}
- *
- as of 2019-12-04 the {@code PathCasingLookupValue} is only used to validate that a
- * package label is correctly cased, and package labels are always relative to a package
- * root, so using a {@code RootedPath} is adequate and the Root part of it doesn't even have
- * to be correctly cased.
- *
- */
- public static SkyKey key(RootedPath path) {
- return Key.create(RootedPathAndCasing.create(path));
- }
-
- private PathCasingLookupValue() {}
-
- public abstract boolean isCorrect();
-
- /** {@link SkyKey} for {@link PathCasingLookupValue} computation. */
- @AutoCodec.VisibleForSerialization
- @AutoCodec
- public static class Key extends AbstractSkyKey {
- private static final Interner interner = BlazeInterners.newWeakInterner();
-
- private Key(RootedPathAndCasing arg) {
- super(arg);
- }
-
- @AutoCodec.VisibleForSerialization
- @AutoCodec.Instantiator
- static Key create(RootedPathAndCasing arg) {
- Preconditions.checkNotNull(arg);
- return interner.intern(new Key(arg));
- }
-
- @Override
- public SkyFunctionName functionName() {
- return SkyFunctions.PATH_CASING_LOOKUP;
- }
- }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
index 11c46c327681a8..169647327f563c 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
@@ -99,8 +99,6 @@ public final class SkyFunctions {
SkyFunctionName.createSemiHermetic("ACTION_EXECUTION");
public static final SkyFunctionName ARTIFACT_NESTED_SET =
SkyFunctionName.createHermetic("ARTIFACT_NESTED_SET");
- public static final SkyFunctionName PATH_CASING_LOOKUP =
- SkyFunctionName.createHermetic("PATH_CASING_LOOKUP");
static final SkyFunctionName RECURSIVE_FILESYSTEM_TRAVERSAL =
SkyFunctionName.createHermetic("RECURSIVE_DIRECTORY_TRAVERSAL");
public static final SkyFunctionName FILESET_ENTRY =
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/BUILD b/src/test/java/com/google/devtools/build/lib/skyframe/BUILD
index bae9bd652d0fb2..bf142bc60663b7 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/BUILD
@@ -12,12 +12,6 @@ filegroup(
visibility = ["//src/test/java/com/google/devtools/build/lib:__pkg__"],
)
-# Tests for Windows-specific functionality that can run cross-platform.
-# These don't need to run on Windows, they merely use Windows- and case-insensitive path semantics.
-CROSS_PLATFORM_WINDOWS_TESTS = [
- "PathCasingLookupFunctionTest.java",
-]
-
# Tests that are broken out from the SkyframeTests target into separate targets.
EXCLUDED_FROM_SKYFRAME_TESTS = [
"LocalDiffAwarenessTest.java",
@@ -25,7 +19,7 @@ EXCLUDED_FROM_SKYFRAME_TESTS = [
"PrepareDepsOfTargetsUnderDirectoryFunctionTest.java", # b/179148968
"SkyframeErrorProcessorTest.java",
"BuildDriverFunctionTest.java",
-] + CROSS_PLATFORM_WINDOWS_TESTS
+]
java_library(
name = "testutil",
@@ -322,56 +316,6 @@ java_test(
],
)
-# Tests that exercise Windows-specific (or case-insensitive-filesystem specific) functionality.
-# These don't need to run on Windows, they merely use Windows- and case-insensitive path semantics.
-java_test(
- name = "windows_test",
- srcs = CROSS_PLATFORM_WINDOWS_TESTS,
- jvm_flags = [
- "-Dblaze.os=Windows",
- "-Dbazel.windows_unix_root=C:/fake/msys",
- ],
- tags = ["skyframe"],
- test_class = "com.google.devtools.build.lib.AllTests",
- deps = [
- ":testutil",
- "//src/main/java/com/google/devtools/build/lib/actions",
- "//src/main/java/com/google/devtools/build/lib/actions:artifacts",
- "//src/main/java/com/google/devtools/build/lib/actions:file_metadata",
- "//src/main/java/com/google/devtools/build/lib/analysis:blaze_directories",
- "//src/main/java/com/google/devtools/build/lib/analysis:server_directories",
- "//src/main/java/com/google/devtools/build/lib/clock",
- "//src/main/java/com/google/devtools/build/lib/cmdline",
- "//src/main/java/com/google/devtools/build/lib/events",
- "//src/main/java/com/google/devtools/build/lib/packages",
- "//src/main/java/com/google/devtools/build/lib/pkgcache",
- "//src/main/java/com/google/devtools/build/lib/skyframe:directory_listing_function",
- "//src/main/java/com/google/devtools/build/lib/skyframe:directory_listing_state_value",
- "//src/main/java/com/google/devtools/build/lib/skyframe:file_function",
- "//src/main/java/com/google/devtools/build/lib/skyframe:path_casing_lookup_function",
- "//src/main/java/com/google/devtools/build/lib/skyframe:path_casing_lookup_value",
- "//src/main/java/com/google/devtools/build/lib/skyframe:sky_functions",
- "//src/main/java/com/google/devtools/build/lib/skyframe:skyframe_cluster",
- "//src/main/java/com/google/devtools/build/lib/skyframe/serialization",
- "//src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec",
- "//src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils",
- "//src/main/java/com/google/devtools/build/lib/util/io",
- "//src/main/java/com/google/devtools/build/lib/vfs",
- "//src/main/java/com/google/devtools/build/lib/vfs:pathfragment",
- "//src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs",
- "//src/main/java/com/google/devtools/build/skyframe",
- "//src/main/java/com/google/devtools/build/skyframe:skyframe-objects",
- "//src/test/java/com/google/devtools/build/lib:test_runner",
- "//src/test/java/com/google/devtools/build/lib/analysis/util",
- "//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",
- ],
-)
-
# TODO(b/179148968): This used to be part of SkyframeTests but was broken off because it has some
# non-hermetic interaction with another test, depending on how the tests get sharded.
java_test(
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/PathCasingLookupFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/PathCasingLookupFunctionTest.java
deleted file mode 100644
index ac0c33696ea5cf..00000000000000
--- a/src/test/java/com/google/devtools/build/lib/skyframe/PathCasingLookupFunctionTest.java
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright 2019 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.Suppliers;
-import com.google.common.collect.ImmutableList;
-import com.google.devtools.build.lib.actions.FileStateValue;
-import com.google.devtools.build.lib.actions.FileValue;
-import com.google.devtools.build.lib.analysis.BlazeDirectories;
-import com.google.devtools.build.lib.analysis.ServerDirectories;
-import com.google.devtools.build.lib.analysis.util.AnalysisMock;
-import com.google.devtools.build.lib.clock.BlazeClock;
-import com.google.devtools.build.lib.events.NullEventHandler;
-import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
-import com.google.devtools.build.lib.skyframe.ExternalFilesHelper.ExternalFileAction;
-import com.google.devtools.build.lib.testutil.FoundationTestCase;
-import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor;
-import com.google.devtools.build.lib.vfs.FileStateKey;
-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.RootedPathAndCasing;
-import com.google.devtools.build.lib.vfs.SyscallCache;
-import com.google.devtools.build.skyframe.EvaluationContext;
-import com.google.devtools.build.skyframe.EvaluationResult;
-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.SequencedRecordingDifferencer;
-import com.google.devtools.build.skyframe.SkyFunction;
-import com.google.devtools.build.skyframe.SkyFunctionName;
-import com.google.devtools.build.skyframe.SkyKey;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicReference;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for {@link PathCasingLookupFunction}. */
-@RunWith(JUnit4.class)
-public final class PathCasingLookupFunctionTest extends FoundationTestCase {
-
- private MemoizingEvaluator evaluator;
- private RecordingDifferencer differencer;
-
- @Before
- public void setUp() {
- AtomicReference pkgLocator =
- new AtomicReference<>(
- new PathPackageLocator(
- outputBase,
- ImmutableList.of(Root.fromPath(rootDirectory)),
- BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY));
- BlazeDirectories directories =
- new BlazeDirectories(
- new ServerDirectories(rootDirectory, outputBase, rootDirectory),
- rootDirectory,
- null,
- AnalysisMock.get().getProductName());
- ExternalFilesHelper externalFilesHelper =
- ExternalFilesHelper.createForTesting(
- pkgLocator,
- ExternalFileAction.DEPEND_ON_EXTERNAL_PKG_FOR_EXTERNAL_REPO_PATHS,
- directories);
-
- Map skyFunctions = new HashMap<>();
- skyFunctions.put(
- FileStateKey.FILE_STATE,
- new FileStateFunction(
- Suppliers.ofInstance(new TimestampGranularityMonitor(BlazeClock.instance())),
- SyscallCache.NO_CACHE,
- externalFilesHelper));
- skyFunctions.put(FileValue.FILE, new FileFunction(pkgLocator));
- skyFunctions.put(SkyFunctions.DIRECTORY_LISTING, new DirectoryListingFunction());
- skyFunctions.put(
- SkyFunctions.DIRECTORY_LISTING_STATE,
- new DirectoryListingStateFunction(externalFilesHelper, SyscallCache.NO_CACHE));
- skyFunctions.put(SkyFunctions.PATH_CASING_LOOKUP, new PathCasingLookupFunction());
-
- differencer = new SequencedRecordingDifferencer();
- evaluator = new InMemoryMemoizingEvaluator(skyFunctions, differencer, null);
- }
-
- private RootedPath rootedPath(String relative) {
- return RootedPath.toRootedPath(Root.fromPath(rootDirectory), PathFragment.create(relative));
- }
-
- @Test
- public void testSanityCheckFilesystemIsCaseInsensitive() {
- Path p1 = rootDirectory.getRelative("Foo/Bar");
- Path p2 = rootDirectory.getRelative("FOO/BAR");
- Path p3 = rootDirectory.getRelative("control");
- assertThat(p1).isNotSameInstanceAs(p2);
- assertThat(p1).isNotSameInstanceAs(p3);
- assertThat(p2).isNotSameInstanceAs(p3);
- assertThat(p1).isEqualTo(p2);
- assertThat(p1).isNotEqualTo(p3);
- }
-
- @Test
- public void testPathCasingLookup() throws Exception {
- RootedPath a = rootedPath("Foo/Bar/Baz");
- RootedPath b = rootedPath("fOO/baR/BAZ");
- createFile(a);
- assertThat(a).isEqualTo(b);
- assertThat(RootedPathAndCasing.create(a)).isNotEqualTo(RootedPathAndCasing.create(b));
- assertThat(expectEvalSuccess(a).isCorrect()).isTrue();
- assertThat(expectEvalSuccess(b).isCorrect()).isFalse();
- }
-
- @Test
- public void testNonExistentPath() throws Exception {
- RootedPath file = rootedPath("Foo/Bar/Baz.txt");
- createFile(file);
- RootedPath missing1 = rootedPath("Foo/Bar/x/y");
- RootedPath missing2 = rootedPath("Foo/BAR/x/y");
- // Non-existent paths are correct if their existing part is correct.
- assertThat(expectEvalSuccess(missing1).isCorrect()).isTrue();
- assertThat(expectEvalSuccess(missing2).isCorrect()).isFalse();
- // Non-existent paths are illegal if their parent exists but is not a directory.
- RootedPath bad = rootedPath("Foo/Bar/Baz.txt/x/y");
- Exception e = expectEvalFailure(bad);
- assertThat(e).hasMessageThat().contains("its parent exists but is not a directory");
- }
-
- @Test
- public void testNonExistentPathThatComesIntoExistence() throws Exception {
- RootedPath a = rootedPath("Foo/Bar/Baz");
- RootedPath b = rootedPath("fOO/baR/BAZ");
- assertThat(a).isEqualTo(b);
- // Expecting RootedPath.toRootedPath not to intern instances, otherwise 'a' would be the same
- // instance as 'b' which would nullify this test.
- assertThat(a).isNotSameInstanceAs(b);
- assertThat(a.toString()).isNotEqualTo(b.toString());
- assertThat(RootedPathAndCasing.create(a)).isNotEqualTo(RootedPathAndCasing.create(b));
- // Path does not exist, so both casings are correct!
- assertThat(expectEvalSuccess(a).isCorrect()).isTrue();
- assertThat(expectEvalSuccess(b).isCorrect()).isTrue();
- // Path comes into existence.
- createFile(a);
- // Now only one casing is correct.
- assertThat(expectEvalSuccess(a).isCorrect()).isTrue();
- assertThat(expectEvalSuccess(b).isCorrect()).isFalse();
- }
-
- @Test
- public void testExistingPathThatIsThenDeleted() throws Exception {
- RootedPath a = rootedPath("Foo/Bar/Baz");
- RootedPath b = rootedPath("Foo/Bar/BAZ");
- createFile(a);
- // Path exists, so only one casing is correct.
- assertThat(expectEvalSuccess(a).isCorrect()).isTrue();
- assertThat(expectEvalSuccess(b).isCorrect()).isFalse();
- // Path no longer exists, both casings are correct.
- deleteFile(a);
- assertThat(expectEvalSuccess(a).isCorrect()).isTrue();
- assertThat(expectEvalSuccess(b).isCorrect()).isTrue();
- }
-
- private void createFile(RootedPath p) throws IOException {
- Path path = p.asPath();
- if (!path.getParentDirectory().exists()) {
- scratch.dir(path.getParentDirectory().getPathString());
- }
- scratch.file(path.getPathString());
- invalidateFileAndParents(p);
- }
-
- private void deleteFile(RootedPath p) throws IOException {
- Path path = p.asPath();
- scratch.deleteFile(path.getPathString());
- invalidateFileAndParents(p);
- }
-
- private EvaluationResult evaluate(SkyKey key) throws Exception {
- EvaluationContext evaluationContext =
- EvaluationContext.newBuilder()
- .setKeepGoing(false)
- .setNumThreads(SkyframeExecutor.DEFAULT_THREAD_COUNT)
- .setEventHandler(NullEventHandler.INSTANCE)
- .build();
- return evaluator.evaluate(ImmutableList.of(key), evaluationContext);
- }
-
- private PathCasingLookupValue expectEvalSuccess(RootedPath path) throws Exception {
- SkyKey key = PathCasingLookupValue.key(path);
- EvaluationResult result = evaluate(key);
- assertThat(result.hasError()).isFalse();
- return result.get(key);
- }
-
- private Exception expectEvalFailure(RootedPath path) throws Exception {
- SkyKey key = PathCasingLookupValue.key(path);
- EvaluationResult result = evaluate(key);
- assertThat(result.hasError()).isTrue();
- return result.getError().getException();
- }
-
- private void invalidateFile(RootedPath path) {
- differencer.invalidate(ImmutableList.of(FileStateValue.key(path)));
- }
-
- private void invalidateDirectory(RootedPath path) {
- invalidateFile(path);
- differencer.invalidate(ImmutableList.of(DirectoryListingStateValue.key(path)));
- }
-
- private void invalidateFileAndParents(RootedPath p) {
- invalidateFile(p);
- do {
- p = p.getParentDirectory();
- invalidateDirectory(p);
- } while (!p.getRootRelativePath().isEmpty());
- }
-}