diff options
Diffstat (limited to 'src/test/java/com/google/devtools/build/lib')
38 files changed, 698 insertions, 1705 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/BUILD b/src/test/java/com/google/devtools/build/lib/BUILD index 7cbf304f16..538cb8fd2c 100644 --- a/src/test/java/com/google/devtools/build/lib/BUILD +++ b/src/test/java/com/google/devtools/build/lib/BUILD @@ -9,8 +9,7 @@ package( CROSS_PLATFORM_WINDOWS_TESTS = [ "util/DependencySetWindowsTest.java", "vfs/PathFragmentWindowsTest.java", - "vfs/WindowsLocalPathTest.java", - "windows/PathWindowsTest.java", + "vfs/WindowsPathTest.java", ] # Tests for Windows-specific functionality that run on Windows. @@ -18,7 +17,6 @@ WINDOWS_ON_WINDOWS_TESTS = glob( ["windows/*.java"], exclude = [ "windows/MockSubprocess.java", - "windows/PathWindowsTest.java", ], ) @@ -374,6 +372,7 @@ java_library( deps = [ ":guava_junit_truth", ":vfs_filesystem_test", + "//src/main/java/com/google/devtools/build/lib:os_util", "//src/main/java/com/google/devtools/build/lib/vfs", ], ) @@ -401,7 +400,7 @@ java_test( # systems java_test( name = "windows_test", - srcs = CROSS_PLATFORM_WINDOWS_TESTS + ["vfs/LocalPathAbstractTest.java"], + srcs = CROSS_PLATFORM_WINDOWS_TESTS + ["vfs/PathAbstractTest.java"], jvm_flags = [ "-Dblaze.os=Windows", "-Dbazel.windows_unix_root=C:/fake/msys", diff --git a/src/test/java/com/google/devtools/build/lib/actions/ArtifactTest.java b/src/test/java/com/google/devtools/build/lib/actions/ArtifactTest.java index 363bae9df3..f26d00eaa5 100644 --- a/src/test/java/com/google/devtools/build/lib/actions/ArtifactTest.java +++ b/src/test/java/com/google/devtools/build/lib/actions/ArtifactTest.java @@ -27,6 +27,7 @@ import com.google.devtools.build.lib.rules.cpp.CppFileTypes; import com.google.devtools.build.lib.rules.java.JavaSemantics; import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodecAdapter; import com.google.devtools.build.lib.skyframe.serialization.testutils.ObjectCodecTester; +import com.google.devtools.build.lib.testutil.MoreAsserts; import com.google.devtools.build.lib.testutil.Scratch; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; @@ -58,7 +59,7 @@ public class ArtifactTest { Path f1 = scratch.file("/exec/dir/file.ext"); Path bogusDir = scratch.file("/exec/dir/bogus"); try { - new Artifact(f1, ArtifactRoot.asDerivedRoot(execDir, bogusDir), f1.relativeTo(execDir)); + new Artifact(ArtifactRoot.asDerivedRoot(execDir, bogusDir), f1.relativeTo(execDir)); fail("Expected IllegalArgumentException constructing artifact with a bad root dir"); } catch (IllegalArgumentException expected) {} } @@ -93,7 +94,7 @@ public class ArtifactTest { @Test public void testRootPrefixedExecPath_normal() throws IOException { Path f1 = scratch.file("/exec/root/dir/file.ext"); - Artifact a1 = new Artifact(f1, rootDir, f1.relativeTo(execDir)); + Artifact a1 = new Artifact(rootDir, f1.relativeTo(execDir)); assertThat(Artifact.asRootPrefixedExecPath(a1)).isEqualTo("root:dir/file.ext"); } @@ -109,9 +110,10 @@ public class ArtifactTest { public void testRootPrefixedExecPath_nullRootDir() throws IOException { Path f1 = scratch.file("/exec/dir/file.ext"); try { - new Artifact(f1, null, f1.relativeTo(execDir)); - fail("Expected IllegalArgumentException creating artifact with null root"); - } catch (IllegalArgumentException expected) {} + new Artifact(null, f1.relativeTo(execDir)); + fail("Expected NullPointerException creating artifact with null root"); + } catch (NullPointerException expected) { + } } @Test @@ -119,9 +121,9 @@ public class ArtifactTest { Path f1 = scratch.file("/exec/root/dir/file1.ext"); Path f2 = scratch.file("/exec/root/dir/dir/file2.ext"); Path f3 = scratch.file("/exec/root/dir/dir/dir/file3.ext"); - Artifact a1 = new Artifact(f1, rootDir, f1.relativeTo(execDir)); - Artifact a2 = new Artifact(f2, rootDir, f2.relativeTo(execDir)); - Artifact a3 = new Artifact(f3, rootDir, f3.relativeTo(execDir)); + Artifact a1 = new Artifact(rootDir, f1.relativeTo(execDir)); + Artifact a2 = new Artifact(rootDir, f2.relativeTo(execDir)); + Artifact a3 = new Artifact(rootDir, f3.relativeTo(execDir)); List<String> strings = new ArrayList<>(); Artifact.addRootPrefixedExecPaths(Lists.newArrayList(a1, a2, a3), strings); assertThat(strings).containsExactly( @@ -283,10 +285,9 @@ public class ArtifactTest { @Test public void testToDetailString() throws Exception { - Path execRoot = scratch.getFileSystem().getPath("/"); + Path execRoot = scratch.getFileSystem().getPath("/a"); Artifact a = new Artifact( - scratch.file("/a/b/c"), ArtifactRoot.asDerivedRoot(execRoot, scratch.dir("/a/b")), PathFragment.create("b/c")); assertThat(a.toDetailString()).isEqualTo("[[/a]b]c"); @@ -294,17 +295,12 @@ public class ArtifactTest { @Test public void testWeirdArtifact() throws Exception { - try { - Path execRoot = scratch.getFileSystem().getPath("/"); - new Artifact( - scratch.file("/a/b/c"), - ArtifactRoot.asDerivedRoot(execRoot, scratch.dir("/a")), - PathFragment.create("c")); - fail(); - } catch (IllegalArgumentException e) { - assertThat(e).hasMessage( - "c: illegal execPath doesn't end with b/c at /a/b/c with root /a[derived]"); - } + Path execRoot = scratch.getFileSystem().getPath("/"); + MoreAsserts.expectThrows( + IllegalArgumentException.class, + () -> + new Artifact( + ArtifactRoot.asDerivedRoot(execRoot, scratch.dir("/a")), PathFragment.create("c"))); } @Test @@ -319,25 +315,23 @@ public class ArtifactTest { @Test public void testSerializeToStringWithExecPath() throws Exception { - Path execRoot = scratch.getFileSystem().getPath("/"); - Path path = scratch.file("/aaa/bbb/ccc"); + Path execRoot = scratch.getFileSystem().getPath("/aaa"); ArtifactRoot root = ArtifactRoot.asDerivedRoot(execRoot, scratch.dir("/aaa/bbb")); PathFragment execPath = PathFragment.create("bbb/ccc"); - assertThat(new Artifact(path, root, execPath).serializeToString()).isEqualTo("bbb/ccc /3"); + assertThat(new Artifact(root, execPath).serializeToString()).isEqualTo("bbb/ccc /3"); } @Test public void testSerializeToStringWithOwner() throws Exception { - Path execRoot = scratch.getFileSystem().getPath("/"); + Path execRoot = scratch.getFileSystem().getPath("/aa"); assertThat( new Artifact( - scratch.file("/aa/b/c"), - ArtifactRoot.asDerivedRoot(execRoot, scratch.dir("/aa")), + ArtifactRoot.asDerivedRoot(execRoot, scratch.dir("/aa/b")), PathFragment.create("b/c"), new LabelArtifactOwner(Label.parseAbsoluteUnchecked("//foo:bar"))) .serializeToString()) - .isEqualTo("b/c /3 //foo:bar"); + .isEqualTo("b/c /1 //foo:bar"); } @Test @@ -349,10 +343,9 @@ public class ArtifactTest { new Artifact( PathFragment.create("src/b"), ArtifactRoot.asSourceRoot(Root.fromPath(execDir))), new Artifact( - scratch.file("/src/c"), ArtifactRoot.asDerivedRoot( scratch.getFileSystem().getPath("/"), scratch.dir("/src")), - PathFragment.create("c"), + PathFragment.create("src/c"), new LabelArtifactOwner(Label.parseAbsoluteUnchecked("//foo:bar")))) .buildAndRunTests(); } @@ -387,7 +380,6 @@ public class ArtifactTest { public void testIsSourceArtifact() throws Exception { assertThat( new Artifact( - scratch.file("/src/foo.cc"), ArtifactRoot.asSourceRoot(Root.fromPath(scratch.dir("/"))), PathFragment.create("src/foo.cc")) .isSourceArtifact()) diff --git a/src/test/java/com/google/devtools/build/lib/actions/CustomCommandLineTest.java b/src/test/java/com/google/devtools/build/lib/actions/CustomCommandLineTest.java index 085415cf34..b9f341a588 100644 --- a/src/test/java/com/google/devtools/build/lib/actions/CustomCommandLineTest.java +++ b/src/test/java/com/google/devtools/build/lib/actions/CustomCommandLineTest.java @@ -984,7 +984,6 @@ public class CustomCommandLineTest { private SpecialArtifact createTreeArtifact(String rootRelativePath) { PathFragment relpath = PathFragment.create(rootRelativePath); return new SpecialArtifact( - rootDir.getRoot().getRelative(relpath), rootDir, rootDir.getExecPath().getRelative(relpath), ArtifactOwner.NullArtifactOwner.INSTANCE, diff --git a/src/test/java/com/google/devtools/build/lib/analysis/actions/ParamFileWriteActionTest.java b/src/test/java/com/google/devtools/build/lib/analysis/actions/ParamFileWriteActionTest.java index 4c9d2dda5c..8678d50a30 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/actions/ParamFileWriteActionTest.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/actions/ParamFileWriteActionTest.java @@ -111,7 +111,6 @@ public class ParamFileWriteActionTest extends BuildViewTestCase { private SpecialArtifact createTreeArtifact(String rootRelativePath) { PathFragment relpath = PathFragment.create(rootRelativePath); return new SpecialArtifact( - rootDir.getRoot().getRelative(relpath), rootDir, rootDir.getExecPath().getRelative(relpath), ArtifactOwner.NullArtifactOwner.INSTANCE, diff --git a/src/test/java/com/google/devtools/build/lib/analysis/actions/PopulateTreeArtifactActionTest.java b/src/test/java/com/google/devtools/build/lib/analysis/actions/PopulateTreeArtifactActionTest.java index 345aa97ab8..1ce4fd5b43 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/actions/PopulateTreeArtifactActionTest.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/actions/PopulateTreeArtifactActionTest.java @@ -346,7 +346,6 @@ public class PopulateTreeArtifactActionTest extends BuildViewTestCase { private SpecialArtifact createTreeArtifact(String rootRelativePath) { PathFragment relpath = PathFragment.create(rootRelativePath); return new SpecialArtifact( - root.getRoot().getRelative(relpath), root, root.getExecPath().getRelative(relpath), ArtifactOwner.NullArtifactOwner.INSTANCE, diff --git a/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTemplateTest.java b/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTemplateTest.java index ad03fe7ef9..17588a6504 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTemplateTest.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTemplateTest.java @@ -325,7 +325,6 @@ public class SpawnActionTemplateTest { private SpecialArtifact createTreeArtifact(String rootRelativePath) { PathFragment relpath = PathFragment.create(rootRelativePath); return new SpecialArtifact( - root.getRoot().getRelative(relpath), root, root.getExecPath().getRelative(relpath), ArtifactOwner.NullArtifactOwner.INSTANCE, diff --git a/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventTransportFactoryTest.java b/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventTransportFactoryTest.java index ca8bef91a2..5e22269292 100644 --- a/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventTransportFactoryTest.java +++ b/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventTransportFactoryTest.java @@ -133,6 +133,13 @@ public class BuildEventTransportFactoryTest { assertThat(transports).isEmpty(); } + @Test + public void testPathToUriString() { + // See https://blogs.msdn.microsoft.com/ie/2006/12/06/file-uris-in-windows/ + assertThat(BuildEventTransportFactory.pathToUriString("C:/Temp/Foo Bar.txt")) + .isEqualTo("file:///C:/Temp/Foo%20Bar.txt"); + } + private void sendEventsAndClose(BuildEvent event, Iterable<BuildEventTransport> transports) throws IOException{ for (BuildEventTransport transport : transports) { diff --git a/src/test/java/com/google/devtools/build/lib/pkgcache/PathPackageLocatorTest.java b/src/test/java/com/google/devtools/build/lib/pkgcache/PathPackageLocatorTest.java index 1cac35349c..a9b224f026 100644 --- a/src/test/java/com/google/devtools/build/lib/pkgcache/PathPackageLocatorTest.java +++ b/src/test/java/com/google/devtools/build/lib/pkgcache/PathPackageLocatorTest.java @@ -338,7 +338,7 @@ public class PathPackageLocatorTest extends FoundationTestCase { workspace.getRelative("foo"), BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY); assertThat(eventCollector.count()).isSameAs(1); - assertContainsEvent("The package path element './foo' will be taken relative"); + assertContainsEvent("The package path element 'foo' will be taken relative"); } /** Regression test for bug: "IllegalArgumentException in PathPackageLocator.create()" */ diff --git a/src/test/java/com/google/devtools/build/lib/rules/android/ResourceTestBase.java b/src/test/java/com/google/devtools/build/lib/rules/android/ResourceTestBase.java index 1bd5bed2d3..9ea174a8ad 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/android/ResourceTestBase.java +++ b/src/test/java/com/google/devtools/build/lib/rules/android/ResourceTestBase.java @@ -183,6 +183,6 @@ public abstract class ResourceTestBase { public Artifact getResource(String pathString) { Path path = fileSystem.getPath("/" + RESOURCE_ROOT + "/" + pathString); return new Artifact( - path, root, root.getExecPath().getRelative(root.getRoot().relativize(path)), OWNER); + root, root.getExecPath().getRelative(root.getRoot().relativize(path)), OWNER); } } diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcLibraryConfiguredTargetTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcLibraryConfiguredTargetTest.java index 4d7c3fc697..36fcadf028 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcLibraryConfiguredTargetTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcLibraryConfiguredTargetTest.java @@ -1066,7 +1066,7 @@ public class CcLibraryConfiguredTargetTest extends BuildViewTestCase { checkError( "root", "a", - "The include path 'd/../../somewhere' references a path outside of the execution root.", + "The include path '../somewhere' references a path outside of the execution root.", "cc_library(name='a', srcs=['a.cc'], copts=['-Id/../../somewhere'])"); } diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionTest.java index db56bd53d6..f7bf8ebfbd 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionTest.java @@ -524,10 +524,6 @@ public class CppLinkActionTest extends BuildViewTestCase { public Artifact getOutputArtifact(String relpath) { return new Artifact( - getTargetConfiguration() - .getBinDirectory(RepositoryName.MAIN) - .getRoot() - .getRelative(relpath), getTargetConfiguration().getBinDirectory(RepositoryName.MAIN), getTargetConfiguration().getBinFragment().getRelative(relpath)); } @@ -672,9 +668,7 @@ public class CppLinkActionTest extends BuildViewTestCase { FileSystem fs = scratch.getFileSystem(); Path execRoot = fs.getPath(TestUtils.tmpDir()); PathFragment execPath = PathFragment.create("out").getRelative(name); - Path path = execRoot.getRelative(execPath); return new SpecialArtifact( - path, ArtifactRoot.asDerivedRoot(execRoot, execRoot.getRelative("out")), execPath, ArtifactOwner.NullArtifactOwner.INSTANCE, diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationLoaderTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationLoaderTest.java index 4a3714b890..e45e32fe56 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationLoaderTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationLoaderTest.java @@ -186,7 +186,7 @@ public class CrosstoolConfigurationLoaderTest extends AnalysisTestCase { assertThat(ccProvider.getTargetCpu()).isEqualTo("piii"); assertThat(ccProvider.getTargetGnuSystemName()).isEqualTo("target-system-name"); - assertThat(toolchain.getToolPathFragment(Tool.AR)).isEqualTo(getToolPath("/path-to-ar")); + assertThat(toolchain.getToolPathFragment(Tool.AR)).isEqualTo(getToolPath("path-to-ar")); assertThat(ccProvider.getAbi()).isEqualTo("abi-version"); assertThat(ccProvider.getAbiGlibcVersion()).isEqualTo("abi-libc-version"); @@ -199,7 +199,7 @@ public class CrosstoolConfigurationLoaderTest extends AnalysisTestCase { assertThat(ccProvider.supportsFission()).isTrue(); assertThat(ccProvider.getBuiltInIncludeDirectories()) - .containsExactly(getToolPath("/system-include-dir")); + .containsExactly(getToolPath("system-include-dir")); assertThat(ccProvider.getSysroot()).isNull(); assertThat(CppHelper.getCompilerOptions(toolchain, ccProvider, NO_FEATURES)) @@ -238,8 +238,8 @@ public class CrosstoolConfigurationLoaderTest extends AnalysisTestCase { "CC_FLAGS", "") .entrySet()); - assertThat(toolchain.getToolPathFragment(Tool.LD)).isEqualTo(getToolPath("/path-to-ld")); - assertThat(toolchain.getToolPathFragment(Tool.DWP)).isEqualTo(getToolPath("/path-to-dwp")); + assertThat(toolchain.getToolPathFragment(Tool.LD)).isEqualTo(getToolPath("path-to-ld")); + assertThat(toolchain.getToolPathFragment(Tool.DWP)).isEqualTo(getToolPath("path-to-dwp")); } /** @@ -605,7 +605,7 @@ public class CrosstoolConfigurationLoaderTest extends AnalysisTestCase { .entrySet()); assertThat(ccProviderA.getBuiltInIncludeDirectories()) .containsExactly( - getToolPath("/system-include-dir-A-1"), getToolPath("/system-include-dir-A-2")) + getToolPath("system-include-dir-A-1"), getToolPath("system-include-dir-A-2")) .inOrder(); assertThat(ccProviderA.getSysroot()).isEqualTo(PathFragment.create("some")); @@ -682,9 +682,7 @@ public class CrosstoolConfigurationLoaderTest extends AnalysisTestCase { PackageIdentifier packageIdentifier = PackageIdentifier.create( TestConstants.TOOLS_REPOSITORY, - PathFragment.create( - PathFragment.create(TestConstants.MOCK_CC_CROSSTOOL_PATH), - PathFragment.create(path))); + PathFragment.create(TestConstants.MOCK_CC_CROSSTOOL_PATH).getRelative(path)); return packageIdentifier.getPathUnderExecRoot(); } diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/HeaderThinningTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/HeaderThinningTest.java index cdd9d72764..ee9b9fb6d8 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/HeaderThinningTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/HeaderThinningTest.java @@ -189,7 +189,6 @@ public class HeaderThinningTest extends ObjcRuleTestCase { private Artifact getTreeArtifact(String name) { Artifact treeArtifactBase = getSourceArtifact(name); return new SpecialArtifact( - treeArtifactBase.getPath(), treeArtifactBase.getRoot(), treeArtifactBase.getExecPath(), treeArtifactBase.getArtifactOwner(), diff --git a/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoCompileActionBuilderTest.java b/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoCompileActionBuilderTest.java index d21acf1839..bc0ebaabe7 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoCompileActionBuilderTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoCompileActionBuilderTest.java @@ -347,7 +347,6 @@ public class ProtoCompileActionBuilderTest { private Artifact artifact(String ownerLabel, String path) { return new Artifact( - root.getRoot().getRelative(path), root, root.getExecPath().getRelative(path), new LabelArtifactOwner(Label.parseAbsoluteUnchecked(ownerLabel))); @@ -356,7 +355,6 @@ public class ProtoCompileActionBuilderTest { /** Creates a dummy artifact with the given path, that actually resides in /out/<path>. */ private Artifact derivedArtifact(String ownerLabel, String path) { return new Artifact( - derivedRoot.getRoot().getRelative(path), derivedRoot, derivedRoot.getExecPath().getRelative(path), new LabelArtifactOwner(Label.parseAbsoluteUnchecked(ownerLabel))); diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ActionTemplateExpansionFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ActionTemplateExpansionFunctionTest.java index 7c864789ec..f8b6a9db3d 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/ActionTemplateExpansionFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/ActionTemplateExpansionFunctionTest.java @@ -39,7 +39,6 @@ import com.google.devtools.build.lib.analysis.actions.SpawnActionTemplate.Output import com.google.devtools.build.lib.events.NullEventHandler; import com.google.devtools.build.lib.pkgcache.PathPackageLocator; import com.google.devtools.build.lib.testutil.FoundationTestCase; -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.skyframe.EvaluationResult; @@ -205,9 +204,7 @@ public final class ActionTemplateExpansionFunctionTest extends FoundationTestCas private SpecialArtifact createTreeArtifact(String path) { PathFragment execPath = PathFragment.create("out").getRelative(path); - Path fullPath = rootDirectory.getRelative(execPath); return new SpecialArtifact( - fullPath, ArtifactRoot.asDerivedRoot(rootDirectory, rootDirectory.getRelative("out")), execPath, ArtifactOwner.NullArtifactOwner.INSTANCE, diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTest.java index 1699fc25fc..21b0a10274 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTest.java @@ -250,10 +250,8 @@ public class ArtifactFunctionTest extends ArtifactFunctionTestCase { private Artifact createDerivedArtifact(String path) { PathFragment execPath = PathFragment.create("out").getRelative(path); - Path fullPath = root.getRelative(execPath); Artifact output = new Artifact( - fullPath, ArtifactRoot.asDerivedRoot(root, root.getRelative("out")), execPath, ALL_OWNER); @@ -264,9 +262,7 @@ public class ArtifactFunctionTest extends ArtifactFunctionTestCase { private Artifact createMiddlemanArtifact(String path) { ArtifactRoot middlemanRoot = ArtifactRoot.middlemanRoot(middlemanPath, middlemanPath.getRelative("out")); - Path fullPath = middlemanRoot.getRoot().getRelative(path); - return new Artifact( - fullPath, middlemanRoot, middlemanRoot.getExecPath().getRelative(path), ALL_OWNER); + return new Artifact(middlemanRoot, middlemanRoot.getExecPath().getRelative(path), ALL_OWNER); } private SpecialArtifact createDerivedTreeArtifactWithAction(String path) { @@ -277,9 +273,7 @@ public class ArtifactFunctionTest extends ArtifactFunctionTestCase { private SpecialArtifact createDerivedTreeArtifactOnly(String path) { PathFragment execPath = PathFragment.create("out").getRelative(path); - Path fullPath = root.getRelative(execPath); return new SpecialArtifact( - fullPath, ArtifactRoot.asDerivedRoot(root, root.getRelative("out")), execPath, ALL_OWNER, diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/FilesystemValueCheckerTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/FilesystemValueCheckerTest.java index f7a989a4ae..48ccd7e341 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/FilesystemValueCheckerTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/FilesystemValueCheckerTest.java @@ -620,7 +620,6 @@ public class FilesystemValueCheckerTest { outputDir.createDirectory(); ArtifactRoot derivedRoot = ArtifactRoot.asDerivedRoot(fs.getPath("/"), outputDir); return new SpecialArtifact( - outputPath, derivedRoot, derivedRoot.getExecPath().getRelative(derivedRoot.getRoot().relativize(outputPath)), ArtifactOwner.NullArtifactOwner.INSTANCE, diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunctionTest.java index 872de47ad0..25b510e18e 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunctionTest.java @@ -171,10 +171,8 @@ public final class RecursiveFilesystemTraversalFunctionTest extends FoundationTe private Artifact derivedArtifact(String path) { PathFragment execPath = PathFragment.create("out").getRelative(path); - Path fullPath = rootDirectory.getRelative(execPath); Artifact output = new Artifact( - fullPath, ArtifactRoot.asDerivedRoot(rootDirectory, rootDirectory.getRelative("out")), execPath); return output; diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java b/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java index 3b39d03441..e63d1ea06e 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java @@ -336,9 +336,7 @@ public abstract class TimestampBuilderTestCase extends FoundationTestCase { Artifact createDerivedArtifact(FileSystem fs, String name) { Path execRoot = fs.getPath(TestUtils.tmpDir()); PathFragment execPath = PathFragment.create("out").getRelative(name); - Path path = execRoot.getRelative(execPath); return new Artifact( - path, ArtifactRoot.asDerivedRoot(execRoot, execRoot.getRelative("out")), execPath, ACTION_LOOKUP_KEY); diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java index 30b6c4caf8..5d24b9ef28 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java @@ -1192,9 +1192,7 @@ public class TreeArtifactBuildTest extends TimestampBuilderTestCase { FileSystem fs = scratch.getFileSystem(); Path execRoot = fs.getPath(TestUtils.tmpDir()); PathFragment execPath = PathFragment.create("out").getRelative(name); - Path path = execRoot.getRelative(execPath); return new SpecialArtifact( - path, ArtifactRoot.asDerivedRoot(execRoot, execRoot.getRelative("out")), execPath, ACTION_LOOKUP_KEY, diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactMetadataTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactMetadataTest.java index 96bc4bed65..9e3fd39ddd 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactMetadataTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactMetadataTest.java @@ -204,7 +204,6 @@ public class TreeArtifactMetadataTest extends ArtifactFunctionTestCase { Path fullPath = root.getRelative(execPath); SpecialArtifact output = new SpecialArtifact( - fullPath, ArtifactRoot.asDerivedRoot(root, root.getRelative("out")), execPath, ALL_OWNER, diff --git a/src/test/java/com/google/devtools/build/lib/unix/UnixPathEqualityTest.java b/src/test/java/com/google/devtools/build/lib/unix/UnixPathEqualityTest.java index d77b10fd86..2d81e13965 100644 --- a/src/test/java/com/google/devtools/build/lib/unix/UnixPathEqualityTest.java +++ b/src/test/java/com/google/devtools/build/lib/unix/UnixPathEqualityTest.java @@ -14,9 +14,9 @@ package com.google.devtools.build.lib.unix; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; import com.google.common.testing.EqualsTester; +import com.google.devtools.build.lib.testutil.MoreAsserts; import com.google.devtools.build.lib.vfs.FileSystem; import com.google.devtools.build.lib.vfs.Path; import org.junit.Before; @@ -93,25 +93,8 @@ public class UnixPathEqualityTest { Path a = unixFs.getPath("/a"); Path b = otherUnixFs.getPath("/b"); - try { - a.renameTo(b); - fail(); - } catch (IllegalArgumentException e) { - assertThat(e).hasMessageThat().contains("different filesystems"); - } - - try { - a.relativeTo(b); - fail(); - } catch (IllegalArgumentException e) { - assertThat(e).hasMessageThat().contains("different filesystems"); - } - - try { - a.createSymbolicLink(b); - fail(); - } catch (IllegalArgumentException e) { - assertThat(e).hasMessageThat().contains("different filesystems"); - } + MoreAsserts.expectThrows(IllegalArgumentException.class, () -> a.renameTo(b)); + MoreAsserts.expectThrows(IllegalArgumentException.class, () -> a.relativeTo(b)); + MoreAsserts.expectThrows(IllegalArgumentException.class, () -> a.createSymbolicLink(b)); } } diff --git a/src/test/java/com/google/devtools/build/lib/vfs/FileSystemTest.java b/src/test/java/com/google/devtools/build/lib/vfs/FileSystemTest.java index e8896bbc0d..47ae76aa8b 100644 --- a/src/test/java/com/google/devtools/build/lib/vfs/FileSystemTest.java +++ b/src/test/java/com/google/devtools/build/lib/vfs/FileSystemTest.java @@ -14,7 +14,6 @@ package com.google.devtools.build.lib.vfs; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.fail; @@ -789,23 +788,6 @@ public abstract class FileSystemTest { assertThat(xNonEmptyDirectoryFoo.isFile()).isTrue(); } - @Test - public void testCannotRemoveRoot() { - Path rootDirectory = testFS.getRootDirectory(); - try { - rootDirectory.delete(); - fail(); - } catch (IOException e) { - String msg = e.getMessage(); - assertWithMessage(String.format("got %s want EBUSY or ENOTEMPTY", msg)) - .that( - msg.endsWith(" (Directory not empty)") - || msg.endsWith(" (Device or resource busy)") - || msg.endsWith(" (Is a directory)")) - .isTrue(); // Happens on OS X. - } - } - // Test the date functions @Test public void testCreateFileChangesTimeOfDirectory() throws Exception { @@ -1105,22 +1087,13 @@ public abstract class FileSystemTest { // Test the Paths @Test public void testGetPathOnlyAcceptsAbsolutePath() { - try { - testFS.getPath("not-absolute"); - fail("The expected Exception was not thrown."); - } catch (IllegalArgumentException ex) { - assertThat(ex).hasMessage("not-absolute (not an absolute path)"); - } + MoreAsserts.expectThrows(IllegalArgumentException.class, () -> testFS.getPath("not-absolute")); } @Test public void testGetPathOnlyAcceptsAbsolutePathFragment() { - try { - testFS.getPath(PathFragment.create("not-absolute")); - fail("The expected Exception was not thrown."); - } catch (IllegalArgumentException ex) { - assertThat(ex).hasMessage("not-absolute (not an absolute path)"); - } + MoreAsserts.expectThrows( + IllegalArgumentException.class, () -> testFS.getPath(PathFragment.create("not-absolute"))); } // Test the access permissions diff --git a/src/test/java/com/google/devtools/build/lib/vfs/FileSystemUtilsTest.java b/src/test/java/com/google/devtools/build/lib/vfs/FileSystemUtilsTest.java index 656363333e..f9cc1a9031 100644 --- a/src/test/java/com/google/devtools/build/lib/vfs/FileSystemUtilsTest.java +++ b/src/test/java/com/google/devtools/build/lib/vfs/FileSystemUtilsTest.java @@ -175,11 +175,29 @@ public class FileSystemUtilsTest { @Test public void testRelativePath() throws IOException { createTestDirectoryTree(); - assertThat(relativePath(topDir, file1).getPathString()).isEqualTo("file-1"); - assertThat(relativePath(topDir, topDir).getPathString()).isEqualTo("."); - assertThat(relativePath(topDir, dirLink).getPathString()).isEqualTo("a-dir/inner-dir/dir-link"); - assertThat(relativePath(topDir, file4).getPathString()).isEqualTo("../file-4"); - assertThat(relativePath(innerDir, file4).getPathString()).isEqualTo("../../../file-4"); + assertThat( + relativePath(PathFragment.create("/top-dir"), PathFragment.create("/top-dir/file-1")) + .getPathString()) + .isEqualTo("file-1"); + assertThat( + relativePath(PathFragment.create("/top-dir"), PathFragment.create("/top-dir")) + .getPathString()) + .isEqualTo(""); + assertThat( + relativePath( + PathFragment.create("/top-dir"), + PathFragment.create("/top-dir/a-dir/inner-dir/dir-link")) + .getPathString()) + .isEqualTo("a-dir/inner-dir/dir-link"); + assertThat( + relativePath(PathFragment.create("/top-dir"), PathFragment.create("/file-4")) + .getPathString()) + .isEqualTo("../file-4"); + assertThat( + relativePath( + PathFragment.create("/top-dir/a-dir/inner-dir"), PathFragment.create("/file-4")) + .getPathString()) + .isEqualTo("../../../file-4"); } @Test diff --git a/src/test/java/com/google/devtools/build/lib/vfs/LocalPathAbstractTest.java b/src/test/java/com/google/devtools/build/lib/vfs/LocalPathAbstractTest.java deleted file mode 100644 index 93869521ad..0000000000 --- a/src/test/java/com/google/devtools/build/lib/vfs/LocalPathAbstractTest.java +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright 2017 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.vfs; - -import static com.google.common.truth.Truth.assertThat; -import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows; -import static java.util.stream.Collectors.toList; - -import com.google.common.collect.Lists; -import com.google.common.testing.EqualsTester; -import com.google.devtools.build.lib.vfs.LocalPath.OsPathPolicy; -import java.util.Collections; -import java.util.List; -import org.junit.Before; -import org.junit.Test; - -/** Tests for {@link LocalPath}. */ -public abstract class LocalPathAbstractTest { - - private OsPathPolicy os; - - @Before - public void setup() { - os = getFilePathOs(); - } - - @Test - public void testEqualsAndHashCode() { - new EqualsTester() - .addEqualityGroup( - create("../relative/path"), create("..").getRelative("relative").getRelative("path")) - .addEqualityGroup(create("something/else")) - .addEqualityGroup(create(""), LocalPath.EMPTY) - .testEquals(); - } - - @Test - public void testRelativeTo() { - assertThat(create("").relativeTo(create("")).getPathString()).isEmpty(); - assertThat(create("foo").relativeTo(create("foo")).getPathString()).isEmpty(); - assertThat(create("foo/bar/baz").relativeTo(create("foo")).getPathString()) - .isEqualTo("bar/baz"); - assertThat(create("foo/bar/baz").relativeTo(create("foo/bar")).getPathString()) - .isEqualTo("baz"); - assertThat(create("foo").relativeTo(create("")).getPathString()).isEqualTo("foo"); - - // Cannot relativize non-ancestors - assertThrows(IllegalArgumentException.class, () -> create("foo/bar").relativeTo(create("fo"))); - - // Make sure partial directory matches aren't reported - assertThrows( - IllegalArgumentException.class, () -> create("foo/bar").relativeTo(create("foo/ba"))); - } - - @Test - public void testGetRelative() { - assertThat(create("a").getRelative("b").getPathString()).isEqualTo("a/b"); - assertThat(create("a/b").getRelative("c/d").getPathString()).isEqualTo("a/b/c/d"); - assertThat(create("a").getRelative("").getPathString()).isEqualTo("a"); - assertThat(create("a/b").getRelative("../c").getPathString()).isEqualTo("a/c"); - assertThat(create("a/b").getRelative("..").getPathString()).isEqualTo("a"); - } - - @Test - public void testEmptyPathToEmptyPath() { - // compare string forms - assertThat(create("").getPathString()).isEmpty(); - // compare fragment forms - assertThat(create("")).isEqualTo(create("")); - } - - @Test - public void testSimpleNameToSimpleName() { - // compare string forms - assertThat(create("foo").getPathString()).isEqualTo("foo"); - // compare fragment forms - assertThat(create("foo")).isEqualTo(create("foo")); - } - - @Test - public void testSimplePathToSimplePath() { - // compare string forms - assertThat(create("foo/bar").getPathString()).isEqualTo("foo/bar"); - // compare fragment forms - assertThat(create("foo/bar")).isEqualTo(create("foo/bar")); - } - - @Test - public void testStripsTrailingSlash() { - // compare string forms - assertThat(create("foo/bar/").getPathString()).isEqualTo("foo/bar"); - // compare fragment forms - assertThat(create("foo/bar/")).isEqualTo(create("foo/bar")); - } - - @Test - public void testGetParentDirectory() { - LocalPath fooBarWiz = create("foo/bar/wiz"); - LocalPath fooBar = create("foo/bar"); - LocalPath foo = create("foo"); - LocalPath empty = create(""); - assertThat(fooBarWiz.getParentDirectory()).isEqualTo(fooBar); - assertThat(fooBar.getParentDirectory()).isEqualTo(foo); - assertThat(foo.getParentDirectory()).isEqualTo(empty); - assertThat(empty.getParentDirectory()).isNull(); - } - - @Test - public void testBasename() throws Exception { - assertThat(create("foo/bar").getBaseName()).isEqualTo("bar"); - assertThat(create("foo/").getBaseName()).isEqualTo("foo"); - assertThat(create("foo").getBaseName()).isEqualTo("foo"); - assertThat(create("").getBaseName()).isEmpty(); - } - - @Test - public void testStartsWith() { - // (relative path, relative prefix) => true - assertThat(create("foo/bar").startsWith(create("foo/bar"))).isTrue(); - assertThat(create("foo/bar").startsWith(create("foo"))).isTrue(); - assertThat(create("foot/bar").startsWith(create("foo"))).isFalse(); - } - - @Test - public void testNormalize() { - assertThat(create("a/b")).isEqualTo(create("a/b")); - assertThat(create("a/../../b")).isEqualTo(create("../b")); - assertThat(create("a/../..")).isEqualTo(create("..")); - assertThat(create("a/../b")).isEqualTo(create("b")); - assertThat(create("a/b/../b")).isEqualTo(create("a/b")); - } - - @Test - public void testNormalStringsDoNotAllocate() { - String normal1 = "a/b/hello.txt"; - assertThat(create(normal1).getPathString()).isSameAs(normal1); - - // Sanity check our testing strategy - String notNormal = "a/../b"; - assertThat(create(notNormal).getPathString()).isNotSameAs(notNormal); - } - - @Test - public void testComparableSortOrder() { - List<LocalPath> list = - Lists.newArrayList( - create("zzz"), - create("ZZZ"), - create("ABC"), - create("aBc"), - create("AbC"), - create("abc")); - Collections.sort(list); - List<String> result = list.stream().map(LocalPath::getPathString).collect(toList()); - - if (os.isCaseSensitive()) { - assertThat(result).containsExactly("ABC", "AbC", "ZZZ", "aBc", "abc", "zzz").inOrder(); - } else { - // Partial ordering among case-insensitive items guaranteed by Collections.sort stability - assertThat(result).containsExactly("ABC", "aBc", "AbC", "abc", "zzz", "ZZZ").inOrder(); - } - } - - protected abstract OsPathPolicy getFilePathOs(); - - protected LocalPath create(String path) { - return LocalPath.createWithOs(path, os); - } -} diff --git a/src/test/java/com/google/devtools/build/lib/vfs/MacOsLocalPathTest.java b/src/test/java/com/google/devtools/build/lib/vfs/MacOsLocalPathTest.java deleted file mode 100644 index c99ad487ee..0000000000 --- a/src/test/java/com/google/devtools/build/lib/vfs/MacOsLocalPathTest.java +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2017 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.vfs; - -import static com.google.common.truth.Truth.assertThat; - -import com.google.common.testing.EqualsTester; -import com.google.devtools.build.lib.vfs.LocalPath.MacOsPathPolicy; -import com.google.devtools.build.lib.vfs.LocalPath.OsPathPolicy; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Tests Mac-specific parts of {@link LocalPath}. */ -@RunWith(JUnit4.class) -public class MacOsLocalPathTest extends UnixLocalPathTest { - - @Override - protected OsPathPolicy getFilePathOs() { - return new MacOsPathPolicy(); - } - - @Test - public void testMacEqualsAndHashCode() { - new EqualsTester() - .addEqualityGroup(create("a/b"), create("A/B")) - .addEqualityGroup(create("/a/b"), create("/A/B")) - .addEqualityGroup(create("something/else")) - .addEqualityGroup(create("/something/else")) - .testEquals(); - } - - @Test - public void testCaseIsPreserved() { - assertThat(create("a/B").getPathString()).isEqualTo("a/B"); - } -} diff --git a/src/test/java/com/google/devtools/build/lib/vfs/NativePathTest.java b/src/test/java/com/google/devtools/build/lib/vfs/NativePathTest.java index 6d112853fd..5dc43a2567 100644 --- a/src/test/java/com/google/devtools/build/lib/vfs/NativePathTest.java +++ b/src/test/java/com/google/devtools/build/lib/vfs/NativePathTest.java @@ -106,13 +106,6 @@ public class NativePathTest { } @Test - public void testParentOfRootIsRoot() { - assertThat(fs.getPath("/..")).isEqualTo(fs.getPath("/")); - assertThat(fs.getPath("/../../../../../..")).isEqualTo(fs.getPath("/")); - assertThat(fs.getPath("/../../../foo")).isEqualTo(fs.getPath("/foo")); - } - - @Test public void testIsDirectory() { assertThat(fs.getPath(aDirectory.getPath()).isDirectory()).isTrue(); assertThat(fs.getPath(aFile.getPath()).isDirectory()).isFalse(); @@ -241,14 +234,4 @@ public class NativePathTest { assertThat(in.read()).isEqualTo(-1); in.close(); } - - @Test - public void testDerivedSegmentEquality() { - Path absoluteSegment = fs.getRootDirectory(); - - Path derivedNode = absoluteSegment.getChild("derivedSegment"); - Path otherDerivedNode = absoluteSegment.getChild("derivedSegment"); - - assertThat(otherDerivedNode).isSameAs(derivedNode); - } } diff --git a/src/test/java/com/google/devtools/build/lib/vfs/PathAbstractTest.java b/src/test/java/com/google/devtools/build/lib/vfs/PathAbstractTest.java new file mode 100644 index 0000000000..7494683391 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/vfs/PathAbstractTest.java @@ -0,0 +1,141 @@ +// Copyright 2017 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.vfs; + +import static com.google.common.truth.Truth.assertThat; +import static java.util.stream.Collectors.toList; + +import com.google.common.collect.Lists; +import com.google.common.testing.EqualsTester; +import com.google.devtools.build.lib.clock.BlazeClock; +import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.Collections; +import java.util.List; +import org.junit.Before; +import org.junit.Test; + +/** Tests for {@link Path}. */ +public abstract class PathAbstractTest { + + private FileSystem fileSystem; + private boolean isCaseSensitive; + + @Before + public void setup() { + fileSystem = new InMemoryFileSystem(BlazeClock.instance()); + isCaseSensitive = OsPathPolicy.getFilePathOs().isCaseSensitive(); + } + + @Test + public void testStripsTrailingSlash() { + // compare string forms + assertThat(create("/foo/bar/").getPathString()).isEqualTo("/foo/bar"); + // compare fragment forms + assertThat(create("/foo/bar/")).isEqualTo(create("/foo/bar")); + } + + @Test + public void testBasename() throws Exception { + assertThat(create("/foo/bar").getBaseName()).isEqualTo("bar"); + assertThat(create("/foo/").getBaseName()).isEqualTo("foo"); + assertThat(create("/foo").getBaseName()).isEqualTo("foo"); + assertThat(create("/").getBaseName()).isEmpty(); + } + + @Test + public void testNormalStringsDoNotAllocate() { + String normal1 = "/a/b/hello.txt"; + assertThat(create(normal1).getPathString()).isSameAs(normal1); + + // Sanity check our testing strategy + String notNormal = "/a/../b"; + assertThat(create(notNormal).getPathString()).isNotSameAs(notNormal); + } + + @Test + public void testComparableSortOrder() { + List<Path> list = + Lists.newArrayList( + create("/zzz"), + create("/ZZZ"), + create("/ABC"), + create("/aBc"), + create("/AbC"), + create("/abc")); + Collections.sort(list); + List<String> result = list.stream().map(Path::getPathString).collect(toList()); + + if (isCaseSensitive) { + assertThat(result).containsExactly("/ABC", "/AbC", "/ZZZ", "/aBc", "/abc", "/zzz").inOrder(); + } else { + // Partial ordering among case-insensitive items guaranteed by Collections.sort stability + assertThat(result).containsExactly("/ABC", "/aBc", "/AbC", "/abc", "/zzz", "/ZZZ").inOrder(); + } + } + + @Test + public void testSerialization() throws Exception { + FileSystem oldFileSystem = Path.getFileSystemForSerialization(); + try { + Path.setFileSystemForSerialization(fileSystem); + Path root = fileSystem.getPath("/"); + Path p1 = fileSystem.getPath("/foo"); + Path p2 = fileSystem.getPath("/foo/bar"); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + + oos.writeObject(root); + oos.writeObject(p1); + oos.writeObject(p2); + + ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(bis); + + Path dsRoot = (Path) ois.readObject(); + Path dsP1 = (Path) ois.readObject(); + Path dsP2 = (Path) ois.readObject(); + + new EqualsTester() + .addEqualityGroup(root, dsRoot) + .addEqualityGroup(p1, dsP1) + .addEqualityGroup(p2, dsP2) + .testEquals(); + + assertThat(p2.startsWith(p1)).isTrue(); + assertThat(p2.startsWith(dsP1)).isTrue(); + assertThat(dsP2.startsWith(p1)).isTrue(); + assertThat(dsP2.startsWith(dsP1)).isTrue(); + + // Regression test for a very specific bug in compareTo involving our incorrect usage of + // reference equality rather than logical equality. + String relativePathStringA = "child/grandchildA"; + String relativePathStringB = "child/grandchildB"; + assertThat( + p1.getRelative(relativePathStringA).compareTo(dsP1.getRelative(relativePathStringB))) + .isEqualTo( + p1.getRelative(relativePathStringA).compareTo(p1.getRelative(relativePathStringB))); + } finally { + Path.setFileSystemForSerialization(oldFileSystem); + } + } + + protected Path create(String path) { + return Path.create(path, fileSystem); + } +} diff --git a/src/test/java/com/google/devtools/build/lib/vfs/PathFragmentTest.java b/src/test/java/com/google/devtools/build/lib/vfs/PathFragmentTest.java index 7fa3c73d89..02446c0337 100644 --- a/src/test/java/com/google/devtools/build/lib/vfs/PathFragmentTest.java +++ b/src/test/java/com/google/devtools/build/lib/vfs/PathFragmentTest.java @@ -15,13 +15,14 @@ package com.google.devtools.build.lib.vfs; import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; +import static com.google.devtools.build.lib.vfs.PathFragment.create; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import com.google.common.testing.EqualsTester; import com.google.devtools.build.lib.skyframe.serialization.testutils.ObjectCodecTester; +import com.google.devtools.build.lib.testutil.MoreAsserts; import com.google.devtools.build.lib.testutil.TestUtils; import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem; import java.io.File; @@ -36,32 +37,6 @@ import org.junit.runners.JUnit4; */ @RunWith(JUnit4.class) public class PathFragmentTest { - @Test - public void testMergeFourPathsWithAbsolute() { - assertThat( - PathFragment.create( - PathFragment.create("x/y"), - PathFragment.create("z/a"), - PathFragment.create("/b/c"), - PathFragment.create("d/e"))) - .isEqualTo(PathFragment.create("x/y/z/a/b/c/d/e")); - } - - @Test - public void testCreateInternsPathFragments() { - String[] firstSegments = new String[] {"hello", "world"}; - PathFragment first = PathFragment.create( - /*driveLetter=*/ '\0', /*isAbsolute=*/ false, firstSegments); - - String[] secondSegments = new String[] {new String("hello"), new String("world")}; - PathFragment second = PathFragment.create( - /*driveLetter=*/ '\0', /*isAbsolute=*/ false, secondSegments); - - assertThat(first.segmentCount()).isEqualTo(second.segmentCount()); - for (int i = 0; i < first.segmentCount(); i++) { - assertThat(first.getSegment(i)).isSameAs(second.getSegment(i)); - } - } @Test public void testEqualsAndHashCode() { @@ -69,23 +44,21 @@ public class PathFragmentTest { new EqualsTester() .addEqualityGroup( - PathFragment.create("../relative/path"), - PathFragment.create("..").getRelative("relative").getRelative("path"), - PathFragment.createAlreadyInterned( - '\0', false, new String[] {"..", "relative", "path"}), - PathFragment.create(new File("../relative/path"))) - .addEqualityGroup(PathFragment.create("something/else")) - .addEqualityGroup(PathFragment.create("/something/else")) - .addEqualityGroup(PathFragment.create("/"), PathFragment.create("//////")) - .addEqualityGroup(PathFragment.create(""), PathFragment.EMPTY_FRAGMENT) + create("../relative/path"), + create("..").getRelative("relative").getRelative("path"), + create(new File("../relative/path").getPath())) + .addEqualityGroup(create("something/else")) + .addEqualityGroup(create("/something/else")) + .addEqualityGroup(create("/"), create("//////")) + .addEqualityGroup(create(""), PathFragment.EMPTY_FRAGMENT) .addEqualityGroup(filesystem.getPath("/")) // A Path object. .testEquals(); } @Test public void testHashCodeCache() { - PathFragment relativePath = PathFragment.create("../relative/path"); - PathFragment rootPath = PathFragment.create("/"); + PathFragment relativePath = create("../relative/path"); + PathFragment rootPath = create("/"); int oldResult = relativePath.hashCode(); int rootResult = rootPath.hashCode(); @@ -93,279 +66,272 @@ public class PathFragmentTest { assertThat(rootPath.hashCode()).isEqualTo(rootResult); } - private void checkRelativeTo(String path, String base) { - PathFragment relative = PathFragment.create(path).relativeTo(base); - assertThat(PathFragment.create(base).getRelative(relative).normalize()) - .isEqualTo(PathFragment.create(path)); - } - @Test public void testRelativeTo() { - assertPath("bar/baz", PathFragment.create("foo/bar/baz").relativeTo("foo")); - assertPath("bar/baz", PathFragment.create("/foo/bar/baz").relativeTo("/foo")); - assertPath("baz", PathFragment.create("foo/bar/baz").relativeTo("foo/bar")); - assertPath("baz", PathFragment.create("/foo/bar/baz").relativeTo("/foo/bar")); - assertPath("foo", PathFragment.create("/foo").relativeTo("/")); - assertPath("foo", PathFragment.create("foo").relativeTo("")); - assertPath("foo/bar", PathFragment.create("foo/bar").relativeTo("")); - - checkRelativeTo("foo/bar/baz", "foo"); - checkRelativeTo("/foo/bar/baz", "/foo"); - checkRelativeTo("foo/bar/baz", "foo/bar"); - checkRelativeTo("/foo/bar/baz", "/foo/bar"); - checkRelativeTo("/foo", "/"); - checkRelativeTo("foo", ""); - checkRelativeTo("foo/bar", ""); + assertThat(create("foo/bar/baz").relativeTo("foo").getPathString()).isEqualTo("bar/baz"); + assertThat(create("/foo/bar/baz").relativeTo("/foo").getPathString()).isEqualTo("bar/baz"); + assertThat(create("foo/bar/baz").relativeTo("foo/bar").getPathString()).isEqualTo("baz"); + assertThat(create("/foo/bar/baz").relativeTo("/foo/bar").getPathString()).isEqualTo("baz"); + assertThat(create("/foo").relativeTo("/").getPathString()).isEqualTo("foo"); + assertThat(create("foo").relativeTo("").getPathString()).isEqualTo("foo"); + assertThat(create("foo/bar").relativeTo("").getPathString()).isEqualTo("foo/bar"); } @Test public void testIsAbsolute() { - assertThat(PathFragment.create("/absolute/test").isAbsolute()).isTrue(); - assertThat(PathFragment.create("relative/test").isAbsolute()).isFalse(); - assertThat(PathFragment.create(new File("/absolute/test")).isAbsolute()).isTrue(); - assertThat(PathFragment.create(new File("relative/test")).isAbsolute()).isFalse(); + assertThat(create("/absolute/test").isAbsolute()).isTrue(); + assertThat(create("relative/test").isAbsolute()).isFalse(); + assertThat(create(new File("/absolute/test").getPath()).isAbsolute()).isTrue(); + assertThat(create(new File("relative/test").getPath()).isAbsolute()).isFalse(); } @Test public void testIsNormalized() { - assertThat(PathFragment.create("/absolute/path").isNormalized()).isTrue(); - assertThat(PathFragment.create("some//path").isNormalized()).isTrue(); - assertThat(PathFragment.create("some/./path").isNormalized()).isFalse(); - assertThat(PathFragment.create("../some/path").isNormalized()).isFalse(); - assertThat(PathFragment.create("some/other/../path").isNormalized()).isFalse(); - assertThat(PathFragment.create("some/other//tricky..path..").isNormalized()).isTrue(); - assertThat(PathFragment.create("/some/other//tricky..path..").isNormalized()).isTrue(); + assertThat(PathFragment.isNormalized("/absolute/path")).isTrue(); + assertThat(PathFragment.isNormalized("some//path")).isTrue(); + assertThat(PathFragment.isNormalized("some/./path")).isFalse(); + assertThat(PathFragment.isNormalized("../some/path")).isFalse(); + assertThat(PathFragment.isNormalized("./some/path")).isFalse(); + assertThat(PathFragment.isNormalized("some/path/..")).isFalse(); + assertThat(PathFragment.isNormalized("some/path/.")).isFalse(); + assertThat(PathFragment.isNormalized("some/other/../path")).isFalse(); + assertThat(PathFragment.isNormalized("some/other//tricky..path..")).isTrue(); + assertThat(PathFragment.isNormalized("/some/other//tricky..path..")).isTrue(); + } + + @Test + public void testContainsUpLevelReferences() { + assertThat(PathFragment.containsUplevelReferences("/absolute/path")).isFalse(); + assertThat(PathFragment.containsUplevelReferences("some//path")).isFalse(); + assertThat(PathFragment.containsUplevelReferences("some/./path")).isFalse(); + assertThat(PathFragment.containsUplevelReferences("../some/path")).isTrue(); + assertThat(PathFragment.containsUplevelReferences("./some/path")).isFalse(); + assertThat(PathFragment.containsUplevelReferences("some/path/..")).isTrue(); + assertThat(PathFragment.containsUplevelReferences("some/path/.")).isFalse(); + assertThat(PathFragment.containsUplevelReferences("some/other/../path")).isTrue(); + assertThat(PathFragment.containsUplevelReferences("some/other//tricky..path..")).isFalse(); + assertThat(PathFragment.containsUplevelReferences("/some/other//tricky..path..")).isFalse(); + + // Normalization cannot remove leading uplevel references, so this will be true + assertThat(create("../some/path").containsUplevelReferences()).isTrue(); + // Normalization will remove these, so no uplevel references left + assertThat(create("some/path/..").containsUplevelReferences()).isFalse(); } @Test public void testRootNodeReturnsRootString() { - PathFragment rootFragment = PathFragment.create("/"); + PathFragment rootFragment = create("/"); assertThat(rootFragment.getPathString()).isEqualTo("/"); } @Test - public void testGetPathFragmentDoesNotNormalize() { - String nonCanonicalPath = "/a/weird/noncanonical/../path/."; - assertThat(PathFragment.create(nonCanonicalPath).getPathString()).isEqualTo(nonCanonicalPath); - } - - @Test public void testGetRelative() { - assertThat(PathFragment.create("a").getRelative("b").getPathString()).isEqualTo("a/b"); - assertThat(PathFragment.create("a/b").getRelative("c/d").getPathString()).isEqualTo("a/b/c/d"); - assertThat(PathFragment.create("c/d").getRelative("/a/b").getPathString()).isEqualTo("/a/b"); - assertThat(PathFragment.create("a").getRelative("").getPathString()).isEqualTo("a"); - assertThat(PathFragment.create("/").getRelative("").getPathString()).isEqualTo("/"); + assertThat(create("a").getRelative("b").getPathString()).isEqualTo("a/b"); + assertThat(create("a/b").getRelative("c/d").getPathString()).isEqualTo("a/b/c/d"); + assertThat(create("c/d").getRelative("/a/b").getPathString()).isEqualTo("/a/b"); + assertThat(create("a").getRelative("").getPathString()).isEqualTo("a"); + assertThat(create("/").getRelative("").getPathString()).isEqualTo("/"); + assertThat(create("a/b").getRelative("../foo").getPathString()).isEqualTo("a/foo"); + assertThat(create("/a/b").getRelative("../foo").getPathString()).isEqualTo("/a/foo"); + + // Make sure any fast path of PathFragment#getRelative(PathFragment) works + assertThat(create("a/b").getRelative(create("../foo")).getPathString()).isEqualTo("a/foo"); + assertThat(create("/a/b").getRelative(create("../foo")).getPathString()).isEqualTo("/a/foo"); + + // Make sure any fast path of PathFragment#getRelative(PathFragment) works + assertThat(create("c/d").getRelative(create("/a/b")).getPathString()).isEqualTo("/a/b"); + + // Test normalization + assertThat(create("a").getRelative(".").getPathString()).isEqualTo("a"); } @Test public void testGetChildWorks() { - PathFragment pf = PathFragment.create("../some/path"); - assertThat(pf.getChild("hi")).isEqualTo(PathFragment.create("../some/path/hi")); + PathFragment pf = create("../some/path"); + assertThat(pf.getChild("hi")).isEqualTo(create("../some/path/hi")); } @Test public void testGetChildRejectsInvalidBaseNames() { - PathFragment pf = PathFragment.create("../some/path"); - assertGetChildFails(pf, "."); - assertGetChildFails(pf, ".."); - assertGetChildFails(pf, "x/y"); - assertGetChildFails(pf, "/y"); - assertGetChildFails(pf, "y/"); - assertGetChildFails(pf, ""); - } - - private void assertGetChildFails(PathFragment pf, String baseName) { - try { - pf.getChild(baseName); - fail(); - } catch (Exception e) { /* Expected. */ } - } - - // Tests after here test the canonicalization - private void assertRegular(String expected, String actual) { - // compare string forms - assertThat(PathFragment.create(actual).getPathString()).isEqualTo(expected); - // compare fragment forms - assertThat(PathFragment.create(actual)).isEqualTo(PathFragment.create(expected)); + PathFragment pf = create("../some/path"); + MoreAsserts.expectThrows(IllegalArgumentException.class, () -> pf.getChild(".")); + MoreAsserts.expectThrows(IllegalArgumentException.class, () -> pf.getChild("..")); + MoreAsserts.expectThrows(IllegalArgumentException.class, () -> pf.getChild("x/y")); + MoreAsserts.expectThrows(IllegalArgumentException.class, () -> pf.getChild("/y")); + MoreAsserts.expectThrows(IllegalArgumentException.class, () -> pf.getChild("y/")); + MoreAsserts.expectThrows(IllegalArgumentException.class, () -> pf.getChild("")); } @Test public void testEmptyPathToEmptyPath() { - assertRegular("/", "/"); - assertRegular("", ""); + assertThat(create("/").getPathString()).isEqualTo("/"); + assertThat(create("").getPathString()).isEqualTo(""); } @Test public void testRedundantSlashes() { - assertRegular("/", "///"); - assertRegular("/foo/bar", "/foo///bar"); - assertRegular("/foo/bar", "////foo//bar"); + assertThat(create("///").getPathString()).isEqualTo("/"); + assertThat(create("/foo///bar").getPathString()).isEqualTo("/foo/bar"); + assertThat(create("////foo//bar").getPathString()).isEqualTo("/foo/bar"); } @Test public void testSimpleNameToSimpleName() { - assertRegular("/foo", "/foo"); - assertRegular("foo", "foo"); + assertThat(create("/foo").getPathString()).isEqualTo("/foo"); + assertThat(create("foo").getPathString()).isEqualTo("foo"); } @Test public void testSimplePathToSimplePath() { - assertRegular("/foo/bar", "/foo/bar"); - assertRegular("foo/bar", "foo/bar"); + assertThat(create("/foo/bar").getPathString()).isEqualTo("/foo/bar"); + assertThat(create("foo/bar").getPathString()).isEqualTo("foo/bar"); } @Test public void testStripsTrailingSlash() { - assertRegular("/foo/bar", "/foo/bar/"); + assertThat(create("/foo/bar/").getPathString()).isEqualTo("/foo/bar"); } @Test public void testGetParentDirectory() { - PathFragment fooBarWiz = PathFragment.create("foo/bar/wiz"); - PathFragment fooBar = PathFragment.create("foo/bar"); - PathFragment foo = PathFragment.create("foo"); - PathFragment empty = PathFragment.create(""); + PathFragment fooBarWiz = create("foo/bar/wiz"); + PathFragment fooBar = create("foo/bar"); + PathFragment foo = create("foo"); + PathFragment empty = create(""); assertThat(fooBarWiz.getParentDirectory()).isEqualTo(fooBar); assertThat(fooBar.getParentDirectory()).isEqualTo(foo); assertThat(foo.getParentDirectory()).isEqualTo(empty); assertThat(empty.getParentDirectory()).isNull(); - PathFragment fooBarWizAbs = PathFragment.create("/foo/bar/wiz"); - PathFragment fooBarAbs = PathFragment.create("/foo/bar"); - PathFragment fooAbs = PathFragment.create("/foo"); - PathFragment rootAbs = PathFragment.create("/"); + PathFragment fooBarWizAbs = create("/foo/bar/wiz"); + PathFragment fooBarAbs = create("/foo/bar"); + PathFragment fooAbs = create("/foo"); + PathFragment rootAbs = create("/"); assertThat(fooBarWizAbs.getParentDirectory()).isEqualTo(fooBarAbs); assertThat(fooBarAbs.getParentDirectory()).isEqualTo(fooAbs); assertThat(fooAbs.getParentDirectory()).isEqualTo(rootAbs); assertThat(rootAbs.getParentDirectory()).isNull(); - - // Note, this is surprising but correct behavior: - assertThat(PathFragment.create("/foo/bar/..").getParentDirectory()).isEqualTo(fooBarAbs); } @Test public void testSegmentsCount() { - assertThat(PathFragment.create("foo/bar").segmentCount()).isEqualTo(2); - assertThat(PathFragment.create("/foo/bar").segmentCount()).isEqualTo(2); - assertThat(PathFragment.create("foo//bar").segmentCount()).isEqualTo(2); - assertThat(PathFragment.create("/foo//bar").segmentCount()).isEqualTo(2); - assertThat(PathFragment.create("foo/").segmentCount()).isEqualTo(1); - assertThat(PathFragment.create("/foo/").segmentCount()).isEqualTo(1); - assertThat(PathFragment.create("foo").segmentCount()).isEqualTo(1); - assertThat(PathFragment.create("/foo").segmentCount()).isEqualTo(1); - assertThat(PathFragment.create("/").segmentCount()).isEqualTo(0); - assertThat(PathFragment.create("").segmentCount()).isEqualTo(0); + assertThat(create("foo/bar").segmentCount()).isEqualTo(2); + assertThat(create("/foo/bar").segmentCount()).isEqualTo(2); + assertThat(create("foo//bar").segmentCount()).isEqualTo(2); + assertThat(create("/foo//bar").segmentCount()).isEqualTo(2); + assertThat(create("foo/").segmentCount()).isEqualTo(1); + assertThat(create("/foo/").segmentCount()).isEqualTo(1); + assertThat(create("foo").segmentCount()).isEqualTo(1); + assertThat(create("/foo").segmentCount()).isEqualTo(1); + assertThat(create("/").segmentCount()).isEqualTo(0); + assertThat(create("").segmentCount()).isEqualTo(0); } @Test public void testGetSegment() { - assertThat(PathFragment.create("foo/bar").getSegment(0)).isEqualTo("foo"); - assertThat(PathFragment.create("foo/bar").getSegment(1)).isEqualTo("bar"); - assertThat(PathFragment.create("/foo/bar").getSegment(0)).isEqualTo("foo"); - assertThat(PathFragment.create("/foo/bar").getSegment(1)).isEqualTo("bar"); - assertThat(PathFragment.create("foo/").getSegment(0)).isEqualTo("foo"); - assertThat(PathFragment.create("/foo/").getSegment(0)).isEqualTo("foo"); - assertThat(PathFragment.create("foo").getSegment(0)).isEqualTo("foo"); - assertThat(PathFragment.create("/foo").getSegment(0)).isEqualTo("foo"); + assertThat(create("foo/bar").getSegment(0)).isEqualTo("foo"); + assertThat(create("foo/bar").getSegment(1)).isEqualTo("bar"); + assertThat(create("/foo/bar").getSegment(0)).isEqualTo("foo"); + assertThat(create("/foo/bar").getSegment(1)).isEqualTo("bar"); + assertThat(create("foo/").getSegment(0)).isEqualTo("foo"); + assertThat(create("/foo/").getSegment(0)).isEqualTo("foo"); + assertThat(create("foo").getSegment(0)).isEqualTo("foo"); + assertThat(create("/foo").getSegment(0)).isEqualTo("foo"); } @Test public void testBasename() throws Exception { - assertThat(PathFragment.create("foo/bar").getBaseName()).isEqualTo("bar"); - assertThat(PathFragment.create("/foo/bar").getBaseName()).isEqualTo("bar"); - assertThat(PathFragment.create("foo/").getBaseName()).isEqualTo("foo"); - assertThat(PathFragment.create("/foo/").getBaseName()).isEqualTo("foo"); - assertThat(PathFragment.create("foo").getBaseName()).isEqualTo("foo"); - assertThat(PathFragment.create("/foo").getBaseName()).isEqualTo("foo"); - assertThat(PathFragment.create("/").getBaseName()).isEmpty(); - assertThat(PathFragment.create("").getBaseName()).isEmpty(); + assertThat(create("foo/bar").getBaseName()).isEqualTo("bar"); + assertThat(create("/foo/bar").getBaseName()).isEqualTo("bar"); + assertThat(create("foo/").getBaseName()).isEqualTo("foo"); + assertThat(create("/foo/").getBaseName()).isEqualTo("foo"); + assertThat(create("foo").getBaseName()).isEqualTo("foo"); + assertThat(create("/foo").getBaseName()).isEqualTo("foo"); + assertThat(create("/").getBaseName()).isEmpty(); + assertThat(create("").getBaseName()).isEmpty(); } @Test public void testFileExtension() throws Exception { - assertThat(PathFragment.create("foo.bar").getFileExtension()).isEqualTo("bar"); - assertThat(PathFragment.create("foo.barr").getFileExtension()).isEqualTo("barr"); - assertThat(PathFragment.create("foo.b").getFileExtension()).isEqualTo("b"); - assertThat(PathFragment.create("foo.").getFileExtension()).isEmpty(); - assertThat(PathFragment.create("foo").getFileExtension()).isEmpty(); - assertThat(PathFragment.create(".").getFileExtension()).isEmpty(); - assertThat(PathFragment.create("").getFileExtension()).isEmpty(); - assertThat(PathFragment.create("foo/bar.baz").getFileExtension()).isEqualTo("baz"); - assertThat(PathFragment.create("foo.bar.baz").getFileExtension()).isEqualTo("baz"); - assertThat(PathFragment.create("foo.bar/baz").getFileExtension()).isEmpty(); - } - - private static void assertPath(String expected, PathFragment actual) { - assertThat(actual.getPathString()).isEqualTo(expected); + assertThat(create("foo.bar").getFileExtension()).isEqualTo("bar"); + assertThat(create("foo.barr").getFileExtension()).isEqualTo("barr"); + assertThat(create("foo.b").getFileExtension()).isEqualTo("b"); + assertThat(create("foo.").getFileExtension()).isEmpty(); + assertThat(create("foo").getFileExtension()).isEmpty(); + assertThat(create(".").getFileExtension()).isEmpty(); + assertThat(create("").getFileExtension()).isEmpty(); + assertThat(create("foo/bar.baz").getFileExtension()).isEqualTo("baz"); + assertThat(create("foo.bar.baz").getFileExtension()).isEqualTo("baz"); + assertThat(create("foo.bar/baz").getFileExtension()).isEmpty(); } @Test public void testReplaceName() throws Exception { - assertPath("foo/baz", PathFragment.create("foo/bar").replaceName("baz")); - assertPath("/foo/baz", PathFragment.create("/foo/bar").replaceName("baz")); - assertPath("foo", PathFragment.create("foo/bar").replaceName("")); - assertPath("baz", PathFragment.create("foo/").replaceName("baz")); - assertPath("/baz", PathFragment.create("/foo/").replaceName("baz")); - assertPath("baz", PathFragment.create("foo").replaceName("baz")); - assertPath("/baz", PathFragment.create("/foo").replaceName("baz")); - assertThat(PathFragment.create("/").replaceName("baz")).isNull(); - assertThat(PathFragment.create("/").replaceName("")).isNull(); - assertThat(PathFragment.create("").replaceName("baz")).isNull(); - assertThat(PathFragment.create("").replaceName("")).isNull(); - - assertPath("foo/bar/baz", PathFragment.create("foo/bar").replaceName("bar/baz")); - assertPath("foo/bar/baz", PathFragment.create("foo/bar").replaceName("bar/baz/")); + assertThat(create("foo/bar").replaceName("baz").getPathString()).isEqualTo("foo/baz"); + assertThat(create("/foo/bar").replaceName("baz").getPathString()).isEqualTo("/foo/baz"); + assertThat(create("foo/bar").replaceName("").getPathString()).isEqualTo("foo"); + assertThat(create("foo/").replaceName("baz").getPathString()).isEqualTo("baz"); + assertThat(create("/foo/").replaceName("baz").getPathString()).isEqualTo("/baz"); + assertThat(create("foo").replaceName("baz").getPathString()).isEqualTo("baz"); + assertThat(create("/foo").replaceName("baz").getPathString()).isEqualTo("/baz"); + assertThat(create("/").replaceName("baz")).isNull(); + assertThat(create("/").replaceName("")).isNull(); + assertThat(create("").replaceName("baz")).isNull(); + assertThat(create("").replaceName("")).isNull(); + + assertThat(create("foo/bar").replaceName("bar/baz").getPathString()).isEqualTo("foo/bar/baz"); + assertThat(create("foo/bar").replaceName("bar/baz/").getPathString()).isEqualTo("foo/bar/baz"); // Absolute path arguments will clobber the original path. - assertPath("/absolute", PathFragment.create("foo/bar").replaceName("/absolute")); - assertPath("/", PathFragment.create("foo/bar").replaceName("/")); + assertThat(create("foo/bar").replaceName("/absolute").getPathString()).isEqualTo("/absolute"); + assertThat(create("foo/bar").replaceName("/").getPathString()).isEqualTo("/"); } @Test public void testSubFragment() throws Exception { - assertPath("/foo/bar/baz", - PathFragment.create("/foo/bar/baz").subFragment(0, 3)); - assertPath("foo/bar/baz", - PathFragment.create("foo/bar/baz").subFragment(0, 3)); - assertPath("/foo/bar", - PathFragment.create("/foo/bar/baz").subFragment(0, 2)); - assertPath("bar/baz", - PathFragment.create("/foo/bar/baz").subFragment(1, 3)); - assertPath("/foo", - PathFragment.create("/foo/bar/baz").subFragment(0, 1)); - assertPath("bar", - PathFragment.create("/foo/bar/baz").subFragment(1, 2)); - assertPath("baz", PathFragment.create("/foo/bar/baz").subFragment(2, 3)); - assertPath("/", PathFragment.create("/foo/bar/baz").subFragment(0, 0)); - assertPath("", PathFragment.create("foo/bar/baz").subFragment(0, 0)); - assertPath("", PathFragment.create("foo/bar/baz").subFragment(1, 1)); - assertPath("/foo/bar/baz", PathFragment.create("/foo/bar/baz").subFragment(0)); - assertPath("bar/baz", PathFragment.create("/foo/bar/baz").subFragment(1)); - try { - fail("unexpectedly succeeded: " + PathFragment.create("foo/bar/baz").subFragment(3, 2)); - } catch (IndexOutOfBoundsException e) { /* Expected. */ } - try { - fail("unexpectedly succeeded: " + PathFragment.create("foo/bar/baz").subFragment(4, 4)); - } catch (IndexOutOfBoundsException e) { /* Expected. */ } + assertThat(create("/foo/bar/baz").subFragment(0, 3).getPathString()).isEqualTo("/foo/bar/baz"); + assertThat(create("foo/bar/baz").subFragment(0, 3).getPathString()).isEqualTo("foo/bar/baz"); + assertThat(create("/foo/bar/baz").subFragment(0, 2).getPathString()).isEqualTo("/foo/bar"); + assertThat(create("/foo/bar/baz").subFragment(1, 3).getPathString()).isEqualTo("bar/baz"); + assertThat(create("/foo/bar/baz").subFragment(0, 1).getPathString()).isEqualTo("/foo"); + assertThat(create("/foo/bar/baz").subFragment(1, 2).getPathString()).isEqualTo("bar"); + assertThat(create("/foo/bar/baz").subFragment(2, 3).getPathString()).isEqualTo("baz"); + assertThat(create("/foo/bar/baz").subFragment(0, 0).getPathString()).isEqualTo("/"); + assertThat(create("foo/bar/baz").subFragment(0, 0).getPathString()).isEqualTo(""); + assertThat(create("foo/bar/baz").subFragment(1, 1).getPathString()).isEqualTo(""); + + assertThat(create("/foo/bar/baz").subFragment(0).getPathString()).isEqualTo("/foo/bar/baz"); + assertThat(create("foo/bar/baz").subFragment(0).getPathString()).isEqualTo("foo/bar/baz"); + assertThat(create("/foo/bar/baz").subFragment(1).getPathString()).isEqualTo("bar/baz"); + assertThat(create("foo/bar/baz").subFragment(1).getPathString()).isEqualTo("bar/baz"); + assertThat(create("foo/bar/baz").subFragment(2).getPathString()).isEqualTo("baz"); + assertThat(create("foo/bar/baz").subFragment(3).getPathString()).isEqualTo(""); + + MoreAsserts.expectThrows( + IndexOutOfBoundsException.class, () -> create("foo/bar/baz").subFragment(3, 2)); + MoreAsserts.expectThrows( + IndexOutOfBoundsException.class, () -> create("foo/bar/baz").subFragment(4, 4)); + MoreAsserts.expectThrows( + IndexOutOfBoundsException.class, () -> create("foo/bar/baz").subFragment(3, 2)); + MoreAsserts.expectThrows( + IndexOutOfBoundsException.class, () -> create("foo/bar/baz").subFragment(4)); } @Test public void testStartsWith() { - PathFragment foobar = PathFragment.create("/foo/bar"); - PathFragment foobarRelative = PathFragment.create("foo/bar"); + PathFragment foobar = create("/foo/bar"); + PathFragment foobarRelative = create("foo/bar"); // (path, prefix) => true assertThat(foobar.startsWith(foobar)).isTrue(); - assertThat(foobar.startsWith(PathFragment.create("/"))).isTrue(); - assertThat(foobar.startsWith(PathFragment.create("/foo"))).isTrue(); - assertThat(foobar.startsWith(PathFragment.create("/foo/"))).isTrue(); - assertThat(foobar.startsWith(PathFragment.create("/foo/bar/"))) - .isTrue(); // Includes trailing slash. + assertThat(foobar.startsWith(create("/"))).isTrue(); + assertThat(foobar.startsWith(create("/foo"))).isTrue(); + assertThat(foobar.startsWith(create("/foo/"))).isTrue(); + assertThat(foobar.startsWith(create("/foo/bar/"))).isTrue(); // Includes trailing slash. // (prefix, path) => false - assertThat(PathFragment.create("/foo").startsWith(foobar)).isFalse(); - assertThat(PathFragment.create("/").startsWith(foobar)).isFalse(); + assertThat(create("/foo").startsWith(foobar)).isFalse(); + assertThat(create("/").startsWith(foobar)).isFalse(); // (absolute, relative) => false assertThat(foobar.startsWith(foobarRelative)).isFalse(); @@ -373,69 +339,53 @@ public class PathFragmentTest { // (relative path, relative prefix) => true assertThat(foobarRelative.startsWith(foobarRelative)).isTrue(); - assertThat(foobarRelative.startsWith(PathFragment.create("foo"))).isTrue(); - assertThat(foobarRelative.startsWith(PathFragment.create(""))).isTrue(); + assertThat(foobarRelative.startsWith(create("foo"))).isTrue(); + assertThat(foobarRelative.startsWith(create(""))).isTrue(); // (path, sibling) => false - assertThat(PathFragment.create("/foo/wiz").startsWith(foobar)).isFalse(); - assertThat(foobar.startsWith(PathFragment.create("/foo/wiz"))).isFalse(); - - // Does not normalize. - PathFragment foodotbar = PathFragment.create("foo/./bar"); - assertThat(foodotbar.startsWith(foodotbar)).isTrue(); - assertThat(foodotbar.startsWith(PathFragment.create("foo/."))).isTrue(); - assertThat(foodotbar.startsWith(PathFragment.create("foo/./"))).isTrue(); - assertThat(foodotbar.startsWith(PathFragment.create("foo/./bar"))).isTrue(); - assertThat(foodotbar.startsWith(PathFragment.create("foo/bar"))).isFalse(); + assertThat(create("/foo/wiz").startsWith(foobar)).isFalse(); + assertThat(foobar.startsWith(create("/foo/wiz"))).isFalse(); } @Test public void testCheckAllPathsStartWithButAreNotEqualTo() { // Check passes: - PathFragment.checkAllPathsAreUnder(toPathsSet("a/b", "a/c"), - PathFragment.create("a")); + PathFragment.checkAllPathsAreUnder(toPathsSet("a/b", "a/c"), create("a")); // Check trivially passes: - PathFragment.checkAllPathsAreUnder(ImmutableList.<PathFragment>of(), - PathFragment.create("a")); + PathFragment.checkAllPathsAreUnder(ImmutableList.<PathFragment>of(), create("a")); // Check fails when some path does not start with startingWithPath: - try { - PathFragment.checkAllPathsAreUnder(toPathsSet("a/b", "b/c"), - PathFragment.create("a")); - fail(); - } catch (IllegalArgumentException expected) { - } + MoreAsserts.expectThrows( + IllegalArgumentException.class, + () -> PathFragment.checkAllPathsAreUnder(toPathsSet("a/b", "b/c"), create("a"))); // Check fails when some path is equal to startingWithPath: - try { - PathFragment.checkAllPathsAreUnder(toPathsSet("a/b", "a"), - PathFragment.create("a")); - fail(); - } catch (IllegalArgumentException expected) { - } + MoreAsserts.expectThrows( + IllegalArgumentException.class, + () -> PathFragment.checkAllPathsAreUnder(toPathsSet("a/b", "a"), create("a"))); } @Test public void testEndsWith() { - PathFragment foobar = PathFragment.create("/foo/bar"); - PathFragment foobarRelative = PathFragment.create("foo/bar"); + PathFragment foobar = create("/foo/bar"); + PathFragment foobarRelative = create("foo/bar"); // (path, suffix) => true assertThat(foobar.endsWith(foobar)).isTrue(); - assertThat(foobar.endsWith(PathFragment.create("bar"))).isTrue(); - assertThat(foobar.endsWith(PathFragment.create("foo/bar"))).isTrue(); - assertThat(foobar.endsWith(PathFragment.create("/foo/bar"))).isTrue(); - assertThat(foobar.endsWith(PathFragment.create("/bar"))).isFalse(); + assertThat(foobar.endsWith(create("bar"))).isTrue(); + assertThat(foobar.endsWith(create("foo/bar"))).isTrue(); + assertThat(foobar.endsWith(create("/foo/bar"))).isTrue(); + assertThat(foobar.endsWith(create("/bar"))).isFalse(); // (prefix, path) => false - assertThat(PathFragment.create("/foo").endsWith(foobar)).isFalse(); - assertThat(PathFragment.create("/").endsWith(foobar)).isFalse(); + assertThat(create("/foo").endsWith(foobar)).isFalse(); + assertThat(create("/").endsWith(foobar)).isFalse(); // (suffix, path) => false - assertThat(PathFragment.create("/bar").endsWith(foobar)).isFalse(); - assertThat(PathFragment.create("bar").endsWith(foobar)).isFalse(); - assertThat(PathFragment.create("").endsWith(foobar)).isFalse(); + assertThat(create("/bar").endsWith(foobar)).isFalse(); + assertThat(create("bar").endsWith(foobar)).isFalse(); + assertThat(create("").endsWith(foobar)).isFalse(); // (absolute, relative) => true assertThat(foobar.endsWith(foobarRelative)).isTrue(); @@ -445,18 +395,32 @@ public class PathFragmentTest { // (relative path, relative prefix) => true assertThat(foobarRelative.endsWith(foobarRelative)).isTrue(); - assertThat(foobarRelative.endsWith(PathFragment.create("bar"))).isTrue(); - assertThat(foobarRelative.endsWith(PathFragment.create(""))).isTrue(); + assertThat(foobarRelative.endsWith(create("bar"))).isTrue(); + assertThat(foobarRelative.endsWith(create(""))).isTrue(); // (path, sibling) => false - assertThat(PathFragment.create("/foo/wiz").endsWith(foobar)).isFalse(); - assertThat(foobar.endsWith(PathFragment.create("/foo/wiz"))).isFalse(); + assertThat(create("/foo/wiz").endsWith(foobar)).isFalse(); + assertThat(foobar.endsWith(create("/foo/wiz"))).isFalse(); + } + + @Test + public void testToRelative() { + assertThat(create("/foo/bar").toRelative()).isEqualTo(create("foo/bar")); + assertThat(create("/").toRelative()).isEqualTo(create("")); + MoreAsserts.expectThrows(IllegalArgumentException.class, () -> create("foo").toRelative()); + } + + @Test + public void testGetDriveStr() { + assertThat(create("/foo/bar").getDriveStr()).isEqualTo("/"); + assertThat(create("/").getDriveStr()).isEqualTo("/"); + MoreAsserts.expectThrows(IllegalArgumentException.class, () -> create("foo").getDriveStr()); } static List<PathFragment> toPaths(List<String> strs) { List<PathFragment> paths = Lists.newArrayList(); for (String s : strs) { - paths.add(PathFragment.create(s)); + paths.add(create(s)); } return paths; } @@ -464,15 +428,26 @@ public class PathFragmentTest { static ImmutableSet<PathFragment> toPathsSet(String... strs) { ImmutableSet.Builder<PathFragment> builder = ImmutableSet.builder(); for (String str : strs) { - builder.add(PathFragment.create(str)); + builder.add(create(str)); } return builder.build(); } @Test public void testCompareTo() throws Exception { - List<String> pathStrs = ImmutableList.of( - "", "/", "//", ".", "/./", "foo/.//bar", "foo", "/foo", "foo/bar", "foo/Bar", "Foo/bar"); + List<String> pathStrs = + ImmutableList.of( + "", + "/", + "foo", + "/foo", + "foo/bar", + "foo.bar", + "foo/bar.baz", + "foo/bar/baz", + "foo/barfile", + "foo/Bar", + "Foo/bar"); List<PathFragment> paths = toPaths(pathStrs); // First test that compareTo is self-consistent. for (PathFragment x : paths) { @@ -493,36 +468,80 @@ public class PathFragmentTest { } } } - // Now test that compareTo does what we expect. The exact ordering here doesn't matter much, - // but there are three things to notice: 1. absolute < relative, 2. comparison is lexicographic - // 3. repeated slashes are ignored. (PathFragment("//") prints as "/"). + // Now test that compareTo does what we expect. The exact ordering here doesn't matter much. Collections.shuffle(paths); Collections.sort(paths); - List<PathFragment> expectedOrder = toPaths(ImmutableList.of( - "/", "//", "/./", "/foo", "", ".", "Foo/bar", "foo", "foo/.//bar", "foo/Bar", "foo/bar")); + List<PathFragment> expectedOrder = + toPaths( + ImmutableList.of( + "", + "/", + "/foo", + "Foo/bar", + "foo", + "foo.bar", + "foo/Bar", + "foo/bar", + "foo/bar.baz", + "foo/bar/baz", + "foo/barfile")); assertThat(paths).isEqualTo(expectedOrder); } @Test public void testGetSafePathString() { - assertThat(PathFragment.create("/").getSafePathString()).isEqualTo("/"); - assertThat(PathFragment.create("/abc").getSafePathString()).isEqualTo("/abc"); - assertThat(PathFragment.create("").getSafePathString()).isEqualTo("."); + assertThat(create("/").getSafePathString()).isEqualTo("/"); + assertThat(create("/abc").getSafePathString()).isEqualTo("/abc"); + assertThat(create("").getSafePathString()).isEqualTo("."); assertThat(PathFragment.EMPTY_FRAGMENT.getSafePathString()).isEqualTo("."); - assertThat(PathFragment.create("abc/def").getSafePathString()).isEqualTo("abc/def"); + assertThat(create("abc/def").getSafePathString()).isEqualTo("abc/def"); } @Test public void testNormalize() { - assertThat(PathFragment.create("/a/b").normalize()).isEqualTo(PathFragment.create("/a/b")); - assertThat(PathFragment.create("/a/./b").normalize()).isEqualTo(PathFragment.create("/a/b")); - assertThat(PathFragment.create("/a/../b").normalize()).isEqualTo(PathFragment.create("/b")); - assertThat(PathFragment.create("a/b").normalize()).isEqualTo(PathFragment.create("a/b")); - assertThat(PathFragment.create("a/../../b").normalize()).isEqualTo(PathFragment.create("../b")); - assertThat(PathFragment.create("a/../..").normalize()).isEqualTo(PathFragment.create("..")); - assertThat(PathFragment.create("a/../b").normalize()).isEqualTo(PathFragment.create("b")); - assertThat(PathFragment.create("a/b/../b").normalize()).isEqualTo(PathFragment.create("a/b")); - assertThat(PathFragment.create("/..").normalize()).isEqualTo(PathFragment.create("/..")); + assertThat(create("/a/b")).isEqualTo(create("/a/b")); + assertThat(create("/a/./b")).isEqualTo(create("/a/b")); + assertThat(create("/a/../b")).isEqualTo(create("/b")); + assertThat(create("a/b")).isEqualTo(create("a/b")); + assertThat(create("a/../../b")).isEqualTo(create("../b")); + assertThat(create("a/../..")).isEqualTo(create("..")); + assertThat(create("a/../b")).isEqualTo(create("b")); + assertThat(create("a/b/../b")).isEqualTo(create("a/b")); + assertThat(create("/..")).isEqualTo(create("/..")); + assertThat(create("..")).isEqualTo(create("..")); + } + + @Test + public void testSegments() { + assertThat(create("").segmentCount()).isEqualTo(0); + assertThat(create("a").segmentCount()).isEqualTo(1); + assertThat(create("a/b").segmentCount()).isEqualTo(2); + assertThat(create("a/b/c").segmentCount()).isEqualTo(3); + assertThat(create("/").segmentCount()).isEqualTo(0); + assertThat(create("/a").segmentCount()).isEqualTo(1); + assertThat(create("/a/b").segmentCount()).isEqualTo(2); + assertThat(create("/a/b/c").segmentCount()).isEqualTo(3); + + assertThat(create("").getSegments()).isEmpty(); + assertThat(create("a").getSegments()).containsExactly("a").inOrder(); + assertThat(create("a/b").getSegments()).containsExactly("a", "b").inOrder(); + assertThat(create("a/b/c").getSegments()).containsExactly("a", "b", "c").inOrder(); + assertThat(create("/").getSegments()).isEmpty(); + assertThat(create("/a").getSegments()).containsExactly("a").inOrder(); + assertThat(create("/a/b").getSegments()).containsExactly("a", "b").inOrder(); + assertThat(create("/a/b/c").getSegments()).containsExactly("a", "b", "c").inOrder(); + + assertThat(create("a").getSegment(0)).isEqualTo("a"); + assertThat(create("a/b").getSegment(0)).isEqualTo("a"); + assertThat(create("a/b").getSegment(1)).isEqualTo("b"); + assertThat(create("a/b/c").getSegment(2)).isEqualTo("c"); + assertThat(create("/a").getSegment(0)).isEqualTo("a"); + assertThat(create("/a/b").getSegment(0)).isEqualTo("a"); + assertThat(create("/a/b").getSegment(1)).isEqualTo("b"); + assertThat(create("/a/b/c").getSegment(2)).isEqualTo("c"); + + MoreAsserts.expectThrows(IllegalArgumentException.class, () -> create("").getSegment(0)); + MoreAsserts.expectThrows(IllegalArgumentException.class, () -> create("a/b").getSegment(2)); } @Test @@ -552,7 +571,7 @@ public class PathFragmentTest { } private void checkSerialization(String pathFragmentString, int expectedSize) throws Exception { - PathFragment a = PathFragment.create(pathFragmentString); + PathFragment a = create(pathFragmentString); byte[] sa = TestUtils.serializeObject(a); assertThat(sa).hasLength(expectedSize); diff --git a/src/test/java/com/google/devtools/build/lib/vfs/PathFragmentWindowsTest.java b/src/test/java/com/google/devtools/build/lib/vfs/PathFragmentWindowsTest.java index 1f18d07475..b2a8a52977 100644 --- a/src/test/java/com/google/devtools/build/lib/vfs/PathFragmentWindowsTest.java +++ b/src/test/java/com/google/devtools/build/lib/vfs/PathFragmentWindowsTest.java @@ -14,9 +14,9 @@ package com.google.devtools.build.lib.vfs; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; -import static org.junit.Assert.fail; +import static com.google.devtools.build.lib.vfs.PathFragment.create; +import com.google.devtools.build.lib.testutil.MoreAsserts; import java.io.File; import org.junit.Test; import org.junit.runner.RunWith; @@ -30,303 +30,199 @@ public class PathFragmentWindowsTest { @Test public void testWindowsSeparator() { - assertThat(PathFragment.create("bar\\baz").toString()).isEqualTo("bar/baz"); - assertThat(PathFragment.create("c:\\bar\\baz").toString()).isEqualTo("C:/bar/baz"); + assertThat(create("bar\\baz").toString()).isEqualTo("bar/baz"); + assertThat(create("c:\\bar\\baz").toString()).isEqualTo("C:/bar/baz"); } @Test public void testIsAbsoluteWindows() { - assertThat(PathFragment.create("C:/").isAbsolute()).isTrue(); - assertThat(PathFragment.create("C:/").isAbsolute()).isTrue(); - assertThat(PathFragment.create("C:/foo").isAbsolute()).isTrue(); - assertThat(PathFragment.create("d:/foo/bar").isAbsolute()).isTrue(); + assertThat(create("C:/").isAbsolute()).isTrue(); + assertThat(create("C:/").isAbsolute()).isTrue(); + assertThat(create("C:/foo").isAbsolute()).isTrue(); + assertThat(create("d:/foo/bar").isAbsolute()).isTrue(); - assertThat(PathFragment.create("*:/").isAbsolute()).isFalse(); + assertThat(create("*:/").isAbsolute()).isFalse(); } @Test public void testAbsoluteAndAbsoluteLookingPaths() { - PathFragment p1 = PathFragment.create("/c"); - assertThat(p1.isAbsolute()).isTrue(); - assertThat(p1.getDriveLetter()).isEqualTo('\0'); - assertThat(p1.getSegments()).containsExactly("c"); - - PathFragment p2 = PathFragment.create("/c/"); - assertThat(p2.isAbsolute()).isTrue(); - assertThat(p2.getDriveLetter()).isEqualTo('\0'); - assertThat(p2.getSegments()).containsExactly("c"); - - PathFragment p3 = PathFragment.create("C:/"); - assertThat(p3.isAbsolute()).isTrue(); - assertThat(p3.getDriveLetter()).isEqualTo('C'); - assertThat(p3.getSegments()).isEmpty(); - - PathFragment p5 = PathFragment.create("/c:"); + assertThat(create("/c").isAbsolute()).isTrue(); + assertThat(create("/c").getSegments()).containsExactly("c"); + + assertThat(create("/c/").isAbsolute()).isTrue(); + assertThat(create("/c/").getSegments()).containsExactly("c"); + + assertThat(create("C:/").isAbsolute()).isTrue(); + assertThat(create("C:/").getSegments()).isEmpty(); + + PathFragment p5 = create("/c:"); assertThat(p5.isAbsolute()).isTrue(); - assertThat(p5.getDriveLetter()).isEqualTo('\0'); assertThat(p5.getSegments()).containsExactly("c:"); + assertThat(create("C:").isAbsolute()).isFalse(); - assertThat(p1).isEqualTo(p2); - assertThat(p1).isNotEqualTo(p3); - assertThat(p1).isNotEqualTo(p5); - assertThat(p3).isNotEqualTo(p5); - } + assertThat(create("/c:").isAbsolute()).isTrue(); + assertThat(create("/c:").getSegments()).containsExactly("c:"); - @Test - public void testIsAbsoluteWindowsBackslash() { - assertThat(PathFragment.create(new File("C:\\blah")).isAbsolute()).isTrue(); - assertThat(PathFragment.create(new File("C:\\")).isAbsolute()).isTrue(); - assertThat(PathFragment.create(new File("\\blah")).isAbsolute()).isTrue(); - assertThat(PathFragment.create(new File("\\")).isAbsolute()).isTrue(); + assertThat(create("/c")).isEqualTo(create("/c/")); + assertThat(create("/c")).isNotEqualTo(create("C:/")); + assertThat(create("/c")).isNotEqualTo(create("C:")); + assertThat(create("/c")).isNotEqualTo(create("/c:")); + assertThat(create("C:/")).isNotEqualTo(create("C:")); + assertThat(create("C:/")).isNotEqualTo(create("/c:")); } @Test - public void testIsNormalizedWindows() { - assertThat(PathFragment.create("C:/").isNormalized()).isTrue(); - assertThat(PathFragment.create("C:/absolute/path").isNormalized()).isTrue(); - assertThat(PathFragment.create("C:/absolute/./path").isNormalized()).isFalse(); - assertThat(PathFragment.create("C:/absolute/../path").isNormalized()).isFalse(); + public void testIsAbsoluteWindowsBackslash() { + assertThat(create(new File("C:\\blah").getPath()).isAbsolute()).isTrue(); + assertThat(create(new File("C:\\").getPath()).isAbsolute()).isTrue(); + assertThat(create(new File("\\blah").getPath()).isAbsolute()).isTrue(); + assertThat(create(new File("\\").getPath()).isAbsolute()).isTrue(); } @Test public void testRootNodeReturnsRootStringWindows() { - PathFragment rootFragment = PathFragment.create("C:/"); - assertThat(rootFragment.getPathString()).isEqualTo("C:/"); + assertThat(create("C:/").getPathString()).isEqualTo("C:/"); } @Test public void testGetRelativeWindows() { - assertThat(PathFragment.create("C:/a").getRelative("b").getPathString()).isEqualTo("C:/a/b"); - assertThat(PathFragment.create("C:/a/b").getRelative("c/d").getPathString()) - .isEqualTo("C:/a/b/c/d"); - assertThat(PathFragment.create("C:/a").getRelative("C:/b").getPathString()).isEqualTo("C:/b"); - assertThat(PathFragment.create("C:/a/b").getRelative("C:/c/d").getPathString()) - .isEqualTo("C:/c/d"); - assertThat(PathFragment.create("a").getRelative("C:/b").getPathString()).isEqualTo("C:/b"); - assertThat(PathFragment.create("a/b").getRelative("C:/c/d").getPathString()) - .isEqualTo("C:/c/d"); - } - - private void assertGetRelative(String path, String relative, PathFragment expected) - throws Exception { - PathFragment actual = PathFragment.create(path).getRelative(relative); - assertThat(actual.getPathString()).isEqualTo(expected.getPathString()); - assertThat(actual).isEqualTo(expected); - assertThat(actual.getDriveLetter()).isEqualTo(expected.getDriveLetter()); - assertThat(actual.hashCode()).isEqualTo(expected.hashCode()); - } - - private void assertRelativeTo(String path, String relativeTo, String... expectedPathSegments) - throws Exception { - PathFragment expected = PathFragment.createAlreadyInterned('\0', false, expectedPathSegments); - PathFragment actual = PathFragment.create(path).relativeTo(relativeTo); - assertThat(actual.getPathString()).isEqualTo(expected.getPathString()); - assertThat(actual).isEqualTo(expected); - assertThat(actual.getDriveLetter()).isEqualTo(expected.getDriveLetter()); - assertThat(actual.hashCode()).isEqualTo(expected.hashCode()); - } - - private void assertCantComputeRelativeTo(String path, String relativeTo) throws Exception { - try { - PathFragment.create(path).relativeTo(relativeTo); - fail("expected failure"); - } catch (Exception e) { - assertThat(e).hasMessageThat().contains("is not beneath"); - } - } - - private static PathFragment makePath(char drive, boolean absolute, String... segments) { - return PathFragment.createAlreadyInterned(drive, absolute, segments); + assertThat(create("C:/a").getRelative("b").getPathString()).isEqualTo("C:/a/b"); + assertThat(create("C:/a/b").getRelative("c/d").getPathString()).isEqualTo("C:/a/b/c/d"); + assertThat(create("C:/a").getRelative("C:/b").getPathString()).isEqualTo("C:/b"); + assertThat(create("C:/a/b").getRelative("C:/c/d").getPathString()).isEqualTo("C:/c/d"); + assertThat(create("a").getRelative("C:/b").getPathString()).isEqualTo("C:/b"); + assertThat(create("a/b").getRelative("C:/c/d").getPathString()).isEqualTo("C:/c/d"); } @Test public void testGetRelativeMixed() throws Exception { - assertGetRelative("a", "b", makePath('\0', false, "a", "b")); - assertGetRelative("a", "/b", makePath('\0', true, "b")); - assertGetRelative("a", "E:/b", makePath('E', true, "b")); + assertThat(create("a").getRelative("b")).isEqualTo(create("a/b")); + assertThat(create("a").getRelative("/b")).isEqualTo(create("/b")); + assertThat(create("a").getRelative("E:/b")).isEqualTo(create("E:/b")); - assertGetRelative("/a", "b", makePath('\0', true, "a", "b")); - assertGetRelative("/a", "/b", makePath('\0', true, "b")); - assertGetRelative("/a", "E:/b", makePath('E', true, "b")); + assertThat(create("/a").getRelative("b")).isEqualTo(create("/a/b")); + assertThat(create("/a").getRelative("/b")).isEqualTo(create("/b")); + assertThat(create("/a").getRelative("E:/b")).isEqualTo(create("E:/b")); - assertGetRelative("D:/a", "b", makePath('D', true, "a", "b")); - assertGetRelative("D:/a", "/b", makePath('D', true, "b")); - assertGetRelative("D:/a", "E:/b", makePath('E', true, "b")); + assertThat(create("D:/a").getRelative("b")).isEqualTo(create("D:/a/b")); + assertThat(create("D:/a").getRelative("/b")).isEqualTo(create("/b")); + assertThat(create("D:/a").getRelative("E:/b")).isEqualTo(create("E:/b")); } @Test public void testRelativeTo() throws Exception { - assertRelativeTo("", ""); - assertCantComputeRelativeTo("", "a"); + assertThat(create("").relativeTo("").getPathString()).isEqualTo(""); + MoreAsserts.expectThrows(IllegalArgumentException.class, () -> create("").relativeTo("a")); - assertRelativeTo("a", "", "a"); - assertRelativeTo("a", "a"); - assertCantComputeRelativeTo("a", "b"); - assertRelativeTo("a/b", "a", "b"); + assertThat(create("a").relativeTo("")).isEqualTo(create("a")); + assertThat(create("a").relativeTo("a").getPathString()).isEqualTo(""); + MoreAsserts.expectThrows(IllegalArgumentException.class, () -> create("a").relativeTo("b")); + assertThat(create("a/b").relativeTo("a")).isEqualTo(create("b")); - assertCantComputeRelativeTo("C:/", ""); - assertRelativeTo("C:/", "C:/"); + MoreAsserts.expectThrows(IllegalArgumentException.class, () -> create("C:/").relativeTo("")); + assertThat(create("C:/").relativeTo("C:/").getPathString()).isEqualTo(""); } @Test public void testGetChildWorks() { - PathFragment pf = PathFragment.create("../some/path"); - assertThat(pf.getChild("hi")).isEqualTo(PathFragment.create("../some/path/hi")); - } - - // Tests after here test the canonicalization - private void assertRegular(String expected, String actual) { - PathFragment exp = PathFragment.create(expected); - PathFragment act = PathFragment.create(actual); - assertThat(exp.getPathString()).isEqualTo(expected); - assertThat(act.getPathString()).isEqualTo(expected); - assertThat(act).isEqualTo(exp); - assertThat(act.hashCode()).isEqualTo(exp.hashCode()); + assertThat(create("../some/path").getChild("hi")).isEqualTo(create("../some/path/hi")); } @Test public void testEmptyPathToEmptyPathWindows() { - assertRegular("C:/", "C:/"); - } - - private void assertAllEqual(PathFragment... ps) { - assertThat(ps.length).isGreaterThan(1); - for (int i = 1; i < ps.length; i++) { - String msg = "comparing items 0 and " + i; - assertWithMessage(msg + " for getPathString") - .that(ps[i].getPathString()) - .isEqualTo(ps[0].getPathString()); - assertWithMessage(msg + " for equals").that(ps[0]).isEqualTo(ps[i]); - assertWithMessage(msg + " for hashCode").that(ps[0].hashCode()).isEqualTo(ps[i].hashCode()); - } - } - - @Test - public void testEmptyRelativePathToEmptyPathWindows() { - // Surprising but correct behavior: a PathFragment made of just a drive identifier (and not the - // absolute path "C:/") is equal not only to the empty fragment, but (therefore) also to other - // drive identifiers. - // This makes sense if you consider that these are still empty paths, the drive letter adds no - // information to the path itself. - assertAllEqual( - PathFragment.EMPTY_FRAGMENT, - PathFragment.createAlreadyInterned('\0', false, new String[0]), - PathFragment.createAlreadyInterned('C', false, new String[0]), - PathFragment.createAlreadyInterned('D', false, new String[0])); - assertAllEqual(PathFragment.create("/c"), PathFragment.create("/c/")); - assertThat(PathFragment.create("C:/")).isNotEqualTo(PathFragment.create("/c")); - assertThat(PathFragment.create("C:/foo")).isNotEqualTo(PathFragment.create("/c/foo")); - - assertThat(PathFragment.create("C:/")).isNotEqualTo(PathFragment.create("C:")); - assertThat(PathFragment.create("C:/").getPathString()) - .isNotEqualTo(PathFragment.create("C:").getPathString()); + assertThat(create("C:/")).isEqualTo(create("C:/")); } @Test public void testWindowsVolumeUppercase() { - assertRegular("C:/", "c:/"); + assertThat(create("C:/")).isEqualTo(create("c:/")); } @Test public void testRedundantSlashesWindows() { - assertRegular("C:/", "C:///"); - assertRegular("C:/foo/bar", "C:/foo///bar"); - assertRegular("C:/foo/bar", "C:////foo//bar"); + assertThat(create("C:/")).isEqualTo(create("C:///")); + assertThat(create("C:/foo/bar")).isEqualTo(create("C:/foo///bar")); + assertThat(create("C:/foo/bar")).isEqualTo(create("C:////foo//bar")); } @Test public void testSimpleNameToSimpleNameWindows() { - assertRegular("C:/foo", "C:/foo"); + assertThat(create("C:/foo")).isEqualTo(create("C:/foo")); } @Test public void testStripsTrailingSlashWindows() { - assertRegular("C:/foo/bar", "C:/foo/bar/"); + assertThat(create("C:/foo/bar")).isEqualTo(create("C:/foo/bar/")); } @Test public void testGetParentDirectoryWindows() { - PathFragment fooBarWizAbs = PathFragment.create("C:/foo/bar/wiz"); - PathFragment fooBarAbs = PathFragment.create("C:/foo/bar"); - PathFragment fooAbs = PathFragment.create("C:/foo"); - PathFragment rootAbs = PathFragment.create("C:/"); - assertThat(fooBarWizAbs.getParentDirectory()).isEqualTo(fooBarAbs); - assertThat(fooBarAbs.getParentDirectory()).isEqualTo(fooAbs); - assertThat(fooAbs.getParentDirectory()).isEqualTo(rootAbs); - assertThat(rootAbs.getParentDirectory()).isNull(); - - // Note, this is suprising but correct behaviour: - assertThat(PathFragment.create("C:/foo/bar/..").getParentDirectory()).isEqualTo(fooBarAbs); + assertThat(create("C:/foo/bar/wiz").getParentDirectory()).isEqualTo(create("C:/foo/bar")); + assertThat(create("C:/foo/bar").getParentDirectory()).isEqualTo(create("C:/foo")); + assertThat(create("C:/foo").getParentDirectory()).isEqualTo(create("C:/")); + assertThat(create("C:/").getParentDirectory()).isNull(); } @Test public void testSegmentsCountWindows() { - assertThat(PathFragment.create("C:/foo").segmentCount()).isEqualTo(1); - assertThat(PathFragment.create("C:/").segmentCount()).isEqualTo(0); + assertThat(create("C:/foo").segmentCount()).isEqualTo(1); + assertThat(create("C:/").segmentCount()).isEqualTo(0); } @Test public void testGetSegmentWindows() { - assertThat(PathFragment.create("C:/foo/bar").getSegment(0)).isEqualTo("foo"); - assertThat(PathFragment.create("C:/foo/bar").getSegment(1)).isEqualTo("bar"); - assertThat(PathFragment.create("C:/foo/").getSegment(0)).isEqualTo("foo"); - assertThat(PathFragment.create("C:/foo").getSegment(0)).isEqualTo("foo"); + assertThat(create("C:/foo/bar").getSegment(0)).isEqualTo("foo"); + assertThat(create("C:/foo/bar").getSegment(1)).isEqualTo("bar"); + assertThat(create("C:/foo/").getSegment(0)).isEqualTo("foo"); + assertThat(create("C:/foo").getSegment(0)).isEqualTo("foo"); } @Test public void testBasenameWindows() throws Exception { - assertThat(PathFragment.create("C:/foo/bar").getBaseName()).isEqualTo("bar"); - assertThat(PathFragment.create("C:/foo").getBaseName()).isEqualTo("foo"); + assertThat(create("C:/foo/bar").getBaseName()).isEqualTo("bar"); + assertThat(create("C:/foo").getBaseName()).isEqualTo("foo"); // Never return the drive name as a basename. - assertThat(PathFragment.create("C:/").getBaseName()).isEmpty(); - } - - private static void assertPath(String expected, PathFragment actual) { - assertThat(actual.getPathString()).isEqualTo(expected); + assertThat(create("C:/").getBaseName()).isEmpty(); } @Test public void testReplaceNameWindows() throws Exception { - assertPath("C:/foo/baz", PathFragment.create("C:/foo/bar").replaceName("baz")); - assertThat(PathFragment.create("C:/").replaceName("baz")).isNull(); + assertThat(create("C:/foo/bar").replaceName("baz").getPathString()).isEqualTo("C:/foo/baz"); + assertThat(create("C:/").replaceName("baz")).isNull(); } @Test public void testStartsWithWindows() { - assertThat(PathFragment.create("C:/foo/bar").startsWith(PathFragment.create("C:/foo"))) - .isTrue(); - assertThat(PathFragment.create("C:/foo/bar").startsWith(PathFragment.create("C:/"))).isTrue(); - assertThat(PathFragment.create("C:/").startsWith(PathFragment.create("C:/"))).isTrue(); + assertThat(create("C:/foo/bar").startsWith(create("C:/foo"))).isTrue(); + assertThat(create("C:/foo/bar").startsWith(create("C:/"))).isTrue(); + assertThat(create("C:/").startsWith(create("C:/"))).isTrue(); // The first path is absolute, the second is not. - assertThat(PathFragment.create("C:/foo/bar").startsWith(PathFragment.create("C:"))).isFalse(); - assertThat(PathFragment.create("C:/").startsWith(PathFragment.create("C:"))).isFalse(); + assertThat(create("C:/foo/bar").startsWith(create("C:"))).isFalse(); + assertThat(create("C:/").startsWith(create("C:"))).isFalse(); } @Test public void testEndsWithWindows() { - assertThat(PathFragment.create("C:/foo/bar").endsWith(PathFragment.create("bar"))).isTrue(); - assertThat(PathFragment.create("C:/foo/bar").endsWith(PathFragment.create("foo/bar"))).isTrue(); - assertThat(PathFragment.create("C:/foo/bar").endsWith(PathFragment.create("C:/foo/bar"))) - .isTrue(); - assertThat(PathFragment.create("C:/").endsWith(PathFragment.create("C:/"))).isTrue(); + assertThat(create("C:/foo/bar").endsWith(create("bar"))).isTrue(); + assertThat(create("C:/foo/bar").endsWith(create("foo/bar"))).isTrue(); + assertThat(create("C:/foo/bar").endsWith(create("C:/foo/bar"))).isTrue(); + assertThat(create("C:/").endsWith(create("C:/"))).isTrue(); } @Test public void testGetSafePathStringWindows() { - assertThat(PathFragment.create("C:/").getSafePathString()).isEqualTo("C:/"); - assertThat(PathFragment.create("C:/abc").getSafePathString()).isEqualTo("C:/abc"); - assertThat(PathFragment.create("C:/abc/def").getSafePathString()).isEqualTo("C:/abc/def"); + assertThat(create("C:/").getSafePathString()).isEqualTo("C:/"); + assertThat(create("C:/abc").getSafePathString()).isEqualTo("C:/abc"); + assertThat(create("C:/abc/def").getSafePathString()).isEqualTo("C:/abc/def"); } @Test public void testNormalizeWindows() { - assertThat(PathFragment.create("C:/a/b").normalize()).isEqualTo(PathFragment.create("C:/a/b")); - assertThat(PathFragment.create("C:/a/./b").normalize()) - .isEqualTo(PathFragment.create("C:/a/b")); - assertThat(PathFragment.create("C:/a/../b").normalize()).isEqualTo(PathFragment.create("C:/b")); - assertThat(PathFragment.create("C:/../b").normalize()) - .isEqualTo(PathFragment.create("C:/../b")); + assertThat(create("C:/a/b")).isEqualTo(create("C:/a/b")); + assertThat(create("C:/a/./b")).isEqualTo(create("C:/a/b")); + assertThat(create("C:/a/../b")).isEqualTo(create("C:/b")); + assertThat(create("C:/../b")).isEqualTo(create("C:/../b")); } @Test @@ -335,8 +231,21 @@ public class PathFragmentWindowsTest { // of drive C:\". // Bazel doesn't resolve such paths, and just takes them literally like normal path segments. // If the user attempts to open files under such paths, the file system API will give an error. - assertThat(PathFragment.create("C:").isAbsolute()).isFalse(); - assertThat(PathFragment.create("C:").getDriveLetter()).isEqualTo('\0'); - assertThat(PathFragment.create("C:").getSegments()).containsExactly("C:"); + assertThat(create("C:").isAbsolute()).isFalse(); + assertThat(create("C:").getSegments()).containsExactly("C:"); + } + + @Test + public void testToRelative() { + assertThat(create("C:/foo/bar").toRelative()).isEqualTo(create("foo/bar")); + assertThat(create("C:/").toRelative()).isEqualTo(create("")); + MoreAsserts.expectThrows(IllegalArgumentException.class, () -> create("foo").toRelative()); + } + + @Test + public void testGetDriveStr() { + assertThat(create("C:/foo/bar").getDriveStr()).isEqualTo("C:/"); + assertThat(create("C:/").getDriveStr()).isEqualTo("C:/"); + MoreAsserts.expectThrows(IllegalArgumentException.class, () -> create("foo").getDriveStr()); } } diff --git a/src/test/java/com/google/devtools/build/lib/vfs/PathTest.java b/src/test/java/com/google/devtools/build/lib/vfs/PathTest.java deleted file mode 100644 index eaad458438..0000000000 --- a/src/test/java/com/google/devtools/build/lib/vfs/PathTest.java +++ /dev/null @@ -1,341 +0,0 @@ -// Copyright 2014 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.vfs; - -import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.common.testing.EqualsTester; -import com.google.common.testing.GcFinalization; -import com.google.devtools.build.lib.clock.BlazeClock; -import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodecAdapter; -import com.google.devtools.build.lib.skyframe.serialization.testutils.FsUtils; -import com.google.devtools.build.lib.skyframe.serialization.testutils.ObjectCodecTester; -import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.lang.ref.WeakReference; -import java.net.URI; -import java.util.Collections; -import java.util.List; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * A test for {@link Path}. - */ -@RunWith(JUnit4.class) -public class PathTest { - private FileSystem filesystem; - private Path root; - - @Before - public final void initializeFileSystem() throws Exception { - filesystem = new InMemoryFileSystem(BlazeClock.instance()); - root = filesystem.getRootDirectory(); - Path first = root.getChild("first"); - first.createDirectory(); - } - - @Test - public void testStartsWithWorksForSelf() { - assertStartsWithReturns(true, "/first/child", "/first/child"); - } - - @Test - public void testStartsWithWorksForChild() { - assertStartsWithReturns(true, - "/first/child", "/first/child/grandchild"); - } - - @Test - public void testStartsWithWorksForDeepDescendant() { - assertStartsWithReturns(true, - "/first/child", "/first/child/grandchild/x/y/z"); - } - - @Test - public void testStartsWithFailsForParent() { - assertStartsWithReturns(false, "/first/child", "/first"); - } - - @Test - public void testStartsWithFailsForSibling() { - assertStartsWithReturns(false, "/first/child", "/first/child2"); - } - - @Test - public void testStartsWithFailsForLinkToDescendant() - throws Exception { - Path linkTarget = filesystem.getPath("/first/linked_to"); - FileSystemUtils.createEmptyFile(linkTarget); - Path second = filesystem.getPath("/second/"); - second.createDirectory(); - second.getChild("child_link").createSymbolicLink(linkTarget); - assertStartsWithReturns(false, "/first", "/second/child_link"); - } - - @Test - public void testStartsWithFailsForNullPrefix() { - try { - filesystem.getPath("/first").startsWith(null); - fail(); - } catch (Exception e) { - } - } - - private void assertStartsWithReturns(boolean expected, - String ancestor, - String descendant) { - Path parent = filesystem.getPath(ancestor); - Path child = filesystem.getPath(descendant); - assertThat(child.startsWith(parent)).isEqualTo(expected); - } - - @Test - public void testGetChildWorks() { - assertGetChildWorks("second"); - assertGetChildWorks("..."); - assertGetChildWorks("...."); - } - - private void assertGetChildWorks(String childName) { - assertThat(filesystem.getPath("/first").getChild(childName)) - .isEqualTo(filesystem.getPath("/first/" + childName)); - } - - @Test - public void testGetChildFailsForChildWithSlashes() { - assertGetChildFails("second/third"); - assertGetChildFails("./third"); - assertGetChildFails("../third"); - assertGetChildFails("second/.."); - assertGetChildFails("second/."); - assertGetChildFails("/third"); - assertGetChildFails("third/"); - } - - private void assertGetChildFails(String childName) { - try { - filesystem.getPath("/first").getChild(childName); - fail(); - } catch (IllegalArgumentException e) { - // Expected. - } - } - - @Test - public void testGetChildFailsForDotAndDotDot() { - assertGetChildFails("."); - assertGetChildFails(".."); - } - - @Test - public void testGetChildFailsForEmptyString() { - assertGetChildFails(""); - } - - @Test - public void testRelativeToWorks() { - assertRelativeToWorks("apple", "/fruit/apple", "/fruit"); - assertRelativeToWorks("apple/jonagold", "/fruit/apple/jonagold", "/fruit"); - } - - @Test - public void testGetRelativeWithStringWorks() { - assertGetRelativeWorks("/first/x/y", "y"); - assertGetRelativeWorks("/y", "/y"); - assertGetRelativeWorks("/first/x/x", "./x"); - assertGetRelativeWorks("/first/y", "../y"); - assertGetRelativeWorks("/", "../../../../.."); - } - - @Test - public void testAsFragmentWorks() { - assertAsFragmentWorks("/"); - assertAsFragmentWorks("//"); - assertAsFragmentWorks("/first"); - assertAsFragmentWorks("/first/x/y"); - assertAsFragmentWorks("/first/x/y.foo"); - } - - @Test - public void testGetRelativeWithFragmentWorks() { - Path dir = filesystem.getPath("/first/x"); - assertThat(dir.getRelative(PathFragment.create("y")).toString()).isEqualTo("/first/x/y"); - assertThat(dir.getRelative(PathFragment.create("./x")).toString()).isEqualTo("/first/x/x"); - assertThat(dir.getRelative(PathFragment.create("../y")).toString()).isEqualTo("/first/y"); - } - - @Test - public void testGetRelativeWithAbsoluteFragmentWorks() { - Path root = filesystem.getPath("/first/x"); - assertThat(root.getRelative(PathFragment.create("/x/y")).toString()).isEqualTo("/x/y"); - } - - @Test - public void testGetRelativeWithAbsoluteStringWorks() { - Path root = filesystem.getPath("/first/x"); - assertThat(root.getRelative("/x/y").toString()).isEqualTo("/x/y"); - } - - @Test - public void testComparableSortOrder() { - Path zzz = filesystem.getPath("/zzz"); - Path ZZZ = filesystem.getPath("/ZZZ"); - Path abc = filesystem.getPath("/abc"); - Path aBc = filesystem.getPath("/aBc"); - Path AbC = filesystem.getPath("/AbC"); - Path ABC = filesystem.getPath("/ABC"); - List<Path> list = Lists.newArrayList(zzz, ZZZ, ABC, aBc, AbC, abc); - Collections.sort(list); - assertThat(list).containsExactly(ABC, AbC, ZZZ, aBc, abc, zzz).inOrder(); - } - - @Test - public void testParentOfRootIsRoot() { - assertThat(root.getRelative("..")).isSameAs(root); - - assertThat(root.getRelative("broken/../../dots")).isSameAs(root.getRelative("dots")); - } - - @Test - public void testSingleSegmentEquivalence() { - assertThat(root.getRelative("aSingleSegment")).isSameAs(root.getRelative("aSingleSegment")); - } - - @Test - public void testSiblingNonEquivalenceString() { - assertThat(root.getRelative("aDifferentSegment")) - .isNotSameAs(root.getRelative("aSingleSegment")); - } - - @Test - public void testSiblingNonEquivalenceFragment() { - assertThat(root.getRelative(PathFragment.create("aDifferentSegment"))) - .isNotSameAs(root.getRelative(PathFragment.create("aSingleSegment"))); - } - - @Test - public void testHashCodeStableAcrossGarbageCollections() { - Path parent = filesystem.getPath("/a"); - PathFragment childFragment = PathFragment.create("b"); - Path child = parent.getRelative(childFragment); - WeakReference<Path> childRef = new WeakReference<>(child); - int childHashCode1 = childRef.get().hashCode(); - assertThat(parent.getRelative(childFragment).hashCode()).isEqualTo(childHashCode1); - child = null; - GcFinalization.awaitClear(childRef); - int childHashCode2 = parent.getRelative(childFragment).hashCode(); - assertThat(childHashCode2).isEqualTo(childHashCode1); - } - - @Test - public void testSerialization() throws Exception { - FileSystem oldFileSystem = Path.getFileSystemForSerialization(); - try { - Path.setFileSystemForSerialization(filesystem); - Path root = filesystem.getPath("/"); - Path p1 = filesystem.getPath("/foo"); - Path p2 = filesystem.getPath("/foo/bar"); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(bos); - - oos.writeObject(root); - oos.writeObject(p1); - oos.writeObject(p2); - - ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); - ObjectInputStream ois = new ObjectInputStream(bis); - - Path dsRoot = (Path) ois.readObject(); - Path dsP1 = (Path) ois.readObject(); - Path dsP2 = (Path) ois.readObject(); - - new EqualsTester() - .addEqualityGroup(root, dsRoot) - .addEqualityGroup(p1, dsP1) - .addEqualityGroup(p2, dsP2) - .testEquals(); - - assertThat(p2.startsWith(p1)).isTrue(); - assertThat(p2.startsWith(dsP1)).isTrue(); - assertThat(dsP2.startsWith(p1)).isTrue(); - assertThat(dsP2.startsWith(dsP1)).isTrue(); - - // Regression test for a very specific bug in compareTo involving our incorrect usage of - // reference equality rather than logical equality. - String relativePathStringA = "child/grandchildA"; - String relativePathStringB = "child/grandchildB"; - assertThat( - p1.getRelative(relativePathStringA).compareTo(dsP1.getRelative(relativePathStringB))) - .isEqualTo( - p1.getRelative(relativePathStringA).compareTo(p1.getRelative(relativePathStringB))); - } finally { - Path.setFileSystemForSerialization(oldFileSystem); - } - } - - @Test - public void testAbsolutePathRoot() { - assertThat(new Path(null).toString()).isEqualTo("/"); - } - - @Test - public void testAbsolutePath() { - Path segment = new Path(null, "bar.txt", - new Path(null, "foo", new Path(null))); - assertThat(segment.toString()).isEqualTo("/foo/bar.txt"); - } - - @Test - public void testToURI() throws Exception { - Path p = root.getRelative("/tmp/foo bar.txt"); - URI uri = p.toURI(); - assertThat(uri.toString()).isEqualTo("file:///tmp/foo%20bar.txt"); - } - - @Test - public void testCodec() throws Exception { - ObjectCodecTester.newBuilder( - new InjectingObjectCodecAdapter<>(Path.CODEC, FsUtils.TEST_FILESYSTEM_PROVIDER)) - .addSubjects( - ImmutableList.of( - FsUtils.TEST_FILESYSTEM.getPath("/"), - FsUtils.TEST_FILESYSTEM.getPath("/some/path"), - FsUtils.TEST_FILESYSTEM.getPath("/some/other/path/with/empty/last/fragment/"))) - .buildAndRunTests(); - } - - private void assertAsFragmentWorks(String expected) { - assertThat(filesystem.getPath(expected).asFragment()).isEqualTo(PathFragment.create(expected)); - } - - private void assertGetRelativeWorks(String expected, String relative) { - assertThat(filesystem.getPath("/first/x").getRelative(relative)) - .isEqualTo(filesystem.getPath(expected)); - } - - private void assertRelativeToWorks(String expected, String relative, String original) { - assertThat(filesystem.getPath(relative).relativeTo(filesystem.getPath(original))) - .isEqualTo(PathFragment.create(expected)); - } -} diff --git a/src/test/java/com/google/devtools/build/lib/vfs/PathTrieTest.java b/src/test/java/com/google/devtools/build/lib/vfs/PathTrieTest.java deleted file mode 100644 index 0807b4aa5d..0000000000 --- a/src/test/java/com/google/devtools/build/lib/vfs/PathTrieTest.java +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2014 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.vfs; - -import static com.google.common.truth.Truth.assertThat; -import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Unit tests for {@link PathTrie}. */ -@RunWith(JUnit4.class) -public class PathTrieTest { - @Test - public void empty() { - PathTrie<Integer> pathTrie = new PathTrie<>(); - assertThat(pathTrie.get(PathFragment.EMPTY_FRAGMENT)).isNull(); - assertThat(pathTrie.get(PathFragment.create("/x"))).isNull(); - assertThat(pathTrie.get(PathFragment.create("/x/y"))).isNull(); - } - - @Test - public void simpleBranches() { - PathTrie<Integer> pathTrie = new PathTrie<>(); - pathTrie.put(PathFragment.create("/a"), 1); - pathTrie.put(PathFragment.create("/b"), 2); - - assertThat(pathTrie.get(PathFragment.EMPTY_FRAGMENT)).isNull(); - assertThat(pathTrie.get(PathFragment.create("/a"))).isEqualTo(1); - assertThat(pathTrie.get(PathFragment.create("/a/b"))).isEqualTo(1); - assertThat(pathTrie.get(PathFragment.create("/a/b/c"))).isEqualTo(1); - assertThat(pathTrie.get(PathFragment.create("/b"))).isEqualTo(2); - assertThat(pathTrie.get(PathFragment.create("/b/c"))).isEqualTo(2); - } - - @Test - public void nestedDirectories() { - PathTrie<Integer> pathTrie = new PathTrie<>(); - pathTrie.put(PathFragment.create("/a/b/c"), 3); - assertThat(pathTrie.get(PathFragment.EMPTY_FRAGMENT)).isNull(); - assertThat(pathTrie.get(PathFragment.create("/a"))).isNull(); - assertThat(pathTrie.get(PathFragment.create("/a/b"))).isNull(); - assertThat(pathTrie.get(PathFragment.create("/a/b/c"))).isEqualTo(3); - assertThat(pathTrie.get(PathFragment.create("/a/b/c/d"))).isEqualTo(3); - - pathTrie.put(PathFragment.create("/a"), 1); - assertThat(pathTrie.get(PathFragment.EMPTY_FRAGMENT)).isNull(); - assertThat(pathTrie.get(PathFragment.create("/b"))).isNull(); - assertThat(pathTrie.get(PathFragment.create("/a"))).isEqualTo(1); - assertThat(pathTrie.get(PathFragment.create("/a/b"))).isEqualTo(1); - assertThat(pathTrie.get(PathFragment.create("/a/b/c"))).isEqualTo(3); - assertThat(pathTrie.get(PathFragment.create("/a/b/c/d"))).isEqualTo(3); - - pathTrie.put(PathFragment.ROOT_FRAGMENT, 0); - assertThat(pathTrie.get(PathFragment.EMPTY_FRAGMENT)).isEqualTo(0); - assertThat(pathTrie.get(PathFragment.create("/b"))).isEqualTo(0); - assertThat(pathTrie.get(PathFragment.create("/a"))).isEqualTo(1); - assertThat(pathTrie.get(PathFragment.create("/a/b"))).isEqualTo(1); - } - - @Test - public void unrootedDirectoriesError() { - PathTrie<Integer> pathTrie = new PathTrie<>(); - assertThrows(IllegalArgumentException.class, () -> pathTrie.put(PathFragment.create("a"), 1)); - } -} diff --git a/src/test/java/com/google/devtools/build/lib/vfs/SymlinkAwareFileSystemTest.java b/src/test/java/com/google/devtools/build/lib/vfs/SymlinkAwareFileSystemTest.java index 4720a6e773..ba7029daf2 100644 --- a/src/test/java/com/google/devtools/build/lib/vfs/SymlinkAwareFileSystemTest.java +++ b/src/test/java/com/google/devtools/build/lib/vfs/SymlinkAwareFileSystemTest.java @@ -16,6 +16,7 @@ package com.google.devtools.build.lib.vfs; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; +import com.google.devtools.build.lib.util.OS; import com.google.devtools.build.lib.vfs.FileSystem.NotASymlinkException; import java.io.FileNotFoundException; import java.io.IOException; @@ -197,7 +198,8 @@ public abstract class SymlinkAwareFileSystemTest extends FileSystemTest { linkPath.delete(); createSymbolicLink(linkPath, relative); if (testFS.supportsSymbolicLinksNatively(linkPath)) { - assertThat(linkPath.getFileSize(Symlinks.NOFOLLOW)).isEqualTo(linkTarget.length()); + assertThat(linkPath.getFileSize(Symlinks.NOFOLLOW)) + .isEqualTo(relative.getSafePathString().length()); assertThat(linkPath.readSymbolicLink()).isEqualTo(relative); } } @@ -205,6 +207,10 @@ public abstract class SymlinkAwareFileSystemTest extends FileSystemTest { @Test public void testLinkToRootResolvesCorrectly() throws IOException { + if (OS.getCurrent() == OS.WINDOWS) { + // This test cannot be run on Windows, it mixes "/" paths with "C:/" paths + return; + } Path rootPath = testFS.getPath("/"); try { diff --git a/src/test/java/com/google/devtools/build/lib/vfs/UnionFileSystemTest.java b/src/test/java/com/google/devtools/build/lib/vfs/UnionFileSystemTest.java index 1e877a5255..3799cfdd46 100644 --- a/src/test/java/com/google/devtools/build/lib/vfs/UnionFileSystemTest.java +++ b/src/test/java/com/google/devtools/build/lib/vfs/UnionFileSystemTest.java @@ -163,7 +163,7 @@ public class UnionFileSystemTest extends SymlinkAwareFileSystemTest { // FileSystemTest.setUp() silently creates the test root on the filesystem... Path testDirUnderRoot = unionfs.getPath(workingDir.asFragment().subFragment(0, 1)); - assertThat(unionfs.getDirectoryEntries(unionfs.getRootDirectory())) + assertThat(unionfs.getDirectoryEntries(unionfs.getPath("/"))) .containsExactly( foo.getBaseName(), bar.getBaseName(), diff --git a/src/test/java/com/google/devtools/build/lib/vfs/UnixLocalPathTest.java b/src/test/java/com/google/devtools/build/lib/vfs/UnixPathTest.java index 2cdb4014ae..306ca9bc08 100644 --- a/src/test/java/com/google/devtools/build/lib/vfs/UnixLocalPathTest.java +++ b/src/test/java/com/google/devtools/build/lib/vfs/UnixPathTest.java @@ -17,15 +17,13 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows; import com.google.common.testing.EqualsTester; -import com.google.devtools.build.lib.vfs.LocalPath.OsPathPolicy; -import com.google.devtools.build.lib.vfs.LocalPath.UnixOsPathPolicy; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Tests the unix implementation of {@link LocalPath}. */ +/** Tests the unix implementation of {@link Path}. */ @RunWith(JUnit4.class) -public class UnixLocalPathTest extends LocalPathAbstractTest { +public class UnixPathTest extends PathAbstractTest { @Test public void testEqualsAndHashCodeUnix() { @@ -37,8 +35,6 @@ public class UnixLocalPathTest extends LocalPathAbstractTest { @Test public void testRelativeToUnix() { - // Cannot relativize absolute and non-absolute - assertThat(create("c/d").getRelative("/a/b").getPathString()).isEqualTo("/a/b"); assertThat(create("/").relativeTo(create("/")).getPathString()).isEmpty(); assertThat(create("/foo").relativeTo(create("/foo")).getPathString()).isEmpty(); assertThat(create("/foo/bar/baz").relativeTo(create("/foo")).getPathString()) @@ -53,16 +49,24 @@ public class UnixLocalPathTest extends LocalPathAbstractTest { } @Test - public void testIsAbsoluteUnix() { - assertThat(create("/absolute/test").isAbsolute()).isTrue(); - assertThat(create("relative/test").isAbsolute()).isFalse(); - } - - @Test public void testGetRelativeUnix() { assertThat(create("/a").getRelative("b").getPathString()).isEqualTo("/a/b"); + assertThat(create("/a/b").getRelative("c/d").getPathString()).isEqualTo("/a/b/c/d"); + assertThat(create("/c/d").getRelative("/a/b").getPathString()).isEqualTo("/a/b"); + assertThat(create("/a").getRelative("").getPathString()).isEqualTo("/a"); assertThat(create("/").getRelative("").getPathString()).isEqualTo("/"); - assertThat(create("c/d").getRelative("/a/b").getPathString()).isEqualTo("/a/b"); + assertThat(create("/a/b").getRelative("../foo").getPathString()).isEqualTo("/a/foo"); + + // Make sure any fast path of Path#getRelative(PathFragment) works + assertThat(create("/a/b").getRelative(PathFragment.create("../foo")).getPathString()) + .isEqualTo("/a/foo"); + + // Make sure any fast path of Path#getRelative(PathFragment) works + assertThat(create("/c/d").getRelative(PathFragment.create("/a/b")).getPathString()) + .isEqualTo("/a/b"); + + // Test normalization + assertThat(create("/a").getRelative(".").getPathString()).isEqualTo("/a"); } @Test @@ -107,14 +111,10 @@ public class UnixLocalPathTest extends LocalPathAbstractTest { @Test public void testGetParentDirectoryUnix() { - LocalPath fooBarWizAbs = create("/foo/bar/wiz"); - LocalPath fooBarAbs = create("/foo/bar"); - LocalPath fooAbs = create("/foo"); - LocalPath rootAbs = create("/"); - assertThat(fooBarWizAbs.getParentDirectory()).isEqualTo(fooBarAbs); - assertThat(fooBarAbs.getParentDirectory()).isEqualTo(fooAbs); - assertThat(fooAbs.getParentDirectory()).isEqualTo(rootAbs); - assertThat(rootAbs.getParentDirectory()).isNull(); + assertThat(create("/foo/bar/wiz").getParentDirectory()).isEqualTo(create("/foo/bar")); + assertThat(create("/foo/bar").getParentDirectory()).isEqualTo(create("/foo")); + assertThat(create("/foo").getParentDirectory()).isEqualTo(create("/")); + assertThat(create("/").getParentDirectory()).isNull(); } @Test @@ -127,8 +127,7 @@ public class UnixLocalPathTest extends LocalPathAbstractTest { @Test public void testStartsWithUnix() { - LocalPath foobar = create("/foo/bar"); - LocalPath foobarRelative = create("foo/bar"); + Path foobar = create("/foo/bar"); // (path, prefix) => true assertThat(foobar.startsWith(foobar)).isTrue(); @@ -141,13 +140,6 @@ public class UnixLocalPathTest extends LocalPathAbstractTest { assertThat(create("/foo").startsWith(foobar)).isFalse(); assertThat(create("/").startsWith(foobar)).isFalse(); - // (absolute, relative) => false - assertThat(foobar.startsWith(foobarRelative)).isFalse(); - assertThat(foobarRelative.startsWith(foobar)).isFalse(); - - // relative paths start with nothing, absolute paths do not - assertThat(foobar.startsWith(create(""))).isFalse(); - // (path, sibling) => false assertThat(create("/foo/wiz").startsWith(foobar)).isFalse(); assertThat(foobar.startsWith(create("/foo/wiz"))).isFalse(); @@ -162,8 +154,10 @@ public class UnixLocalPathTest extends LocalPathAbstractTest { assertThat(create("/..")).isEqualTo(create("/..")); } - @Override - protected OsPathPolicy getFilePathOs() { - return new UnixOsPathPolicy(); + @Test + public void testParentOfRootIsRootUnix() { + assertThat(create("/..")).isEqualTo(create("/")); + assertThat(create("/../../../../../..")).isEqualTo(create("/")); + assertThat(create("/../../../foo")).isEqualTo(create("/foo")); } } diff --git a/src/test/java/com/google/devtools/build/lib/vfs/WindowsLocalPathTest.java b/src/test/java/com/google/devtools/build/lib/vfs/WindowsPathTest.java index ac5acef1f4..c7592197e1 100644 --- a/src/test/java/com/google/devtools/build/lib/vfs/WindowsLocalPathTest.java +++ b/src/test/java/com/google/devtools/build/lib/vfs/WindowsPathTest.java @@ -17,18 +17,16 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; import com.google.devtools.build.lib.testutil.MoreAsserts; -import com.google.devtools.build.lib.vfs.LocalPath.OsPathPolicy; -import com.google.devtools.build.lib.vfs.LocalPath.WindowsOsPathPolicy; -import com.google.devtools.build.lib.vfs.LocalPath.WindowsOsPathPolicy.ShortPathResolver; +import com.google.devtools.build.lib.vfs.WindowsOsPathPolicy.ShortPathResolver; import java.util.HashMap; import java.util.Map; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Tests windows-specific parts of {@link LocalPath} */ +/** Tests windows-specific parts of {@link Path} */ @RunWith(JUnit4.class) -public class WindowsLocalPathTest extends LocalPathAbstractTest { +public class WindowsPathTest extends PathAbstractTest { private static final class MockShortPathResolver implements ShortPathResolver { // Full path to resolved child mapping. @@ -52,26 +50,18 @@ public class WindowsLocalPathTest extends LocalPathAbstractTest { } } - private final MockShortPathResolver shortPathResolver = new MockShortPathResolver(); - - @Override - protected OsPathPolicy getFilePathOs() { - return new WindowsOsPathPolicy(shortPathResolver); - } - @Test public void testEqualsAndHashcodeWindows() { new EqualsTester() - .addEqualityGroup(create("a/b"), create("A/B")) .addEqualityGroup(create("/a/b"), create("/A/B")) .addEqualityGroup(create("c:/a/b"), create("C:\\A\\B")) - .addEqualityGroup(create("something/else")) + .addEqualityGroup(create("C:/something/else")) .testEquals(); } @Test public void testCaseIsPreserved() { - assertThat(create("a/B").getPathString()).isEqualTo("a/B"); + assertThat(create("C:/a/B").getPathString()).isEqualTo("C:/a/B"); } @Test @@ -96,69 +86,62 @@ public class WindowsLocalPathTest extends LocalPathAbstractTest { public void testGetParentDirectoryWindows() { assertThat(create("C:/foo").getParentDirectory()).isEqualTo(create("C:/")); assertThat(create("C:/").getParentDirectory()).isNull(); + assertThat(create("/").getParentDirectory()).isNull(); } @Test - public void testisAbsoluteWindows() { - assertThat(create("C:/").isAbsolute()).isTrue(); - // test that msys paths turn into absolute paths - assertThat(create("/").isAbsolute()).isTrue(); + public void testParentOfRootIsRootWindows() { + assertThat(create("C:/..")).isEqualTo(create("C:/")); + assertThat(create("C:/../../../../../..")).isEqualTo(create("C:/")); + assertThat(create("C:/../../../foo")).isEqualTo(create("C:/foo")); } @Test public void testRelativeToWindows() { - assertThat(create("C:/foo").relativeTo(create("C:/"))).isEqualTo(create("foo")); + assertThat(create("C:/foo").relativeTo(create("C:/")).getPathString()).isEqualTo("foo"); // Case insensitivity test - assertThat(create("C:/foo/bar").relativeTo(create("C:/FOO"))).isEqualTo(create("bar")); + assertThat(create("C:/foo/bar").relativeTo(create("C:/FOO")).getPathString()).isEqualTo("bar"); MoreAsserts.assertThrows( IllegalArgumentException.class, () -> create("D:/foo").relativeTo(create("C:/"))); } @Test - public void testAbsoluteUnixPathIsRelativeToWindowsUnixRoot() { - assertThat(create("/").getPathString()).isEqualTo("C:/fake/msys"); - assertThat(create("/foo/bar").getPathString()).isEqualTo("C:/fake/msys/foo/bar"); - assertThat(create("/foo/bar").getPathString()).isEqualTo("C:/fake/msys/foo/bar"); - } - - @Test - public void testAbsoluteUnixPathReferringToDriveIsRecognized() { - assertThat(create("/c/foo").getPathString()).isEqualTo("C:/foo"); - assertThat(create("/c/foo").getPathString()).isEqualTo("C:/foo"); - assertThat(create("/c:").getPathString()).isNotEqualTo("C:/foo"); - } - - @Test public void testResolvesShortenedPaths() { + MockShortPathResolver shortPathResolver = new MockShortPathResolver(); + WindowsOsPathPolicy osPathPolicy = new WindowsOsPathPolicy(shortPathResolver); shortPathResolver.resolutions.put("d:/progra~1", "program files"); shortPathResolver.resolutions.put("d:/program files/micros~1", "microsoft something"); shortPathResolver.resolutions.put( "d:/program files/microsoft something/foo/~bar~1", "~bar_hello"); // Assert normal shortpath resolution. - LocalPath normal = create("d:/progra~1/micros~1/foo/~bar~1/baz"); - // The path string has an upper-case drive letter because that's how path printing works. - assertThat(normal.getPathString()) + assertThat(normalize(osPathPolicy, "d:/progra~1/micros~1/foo/~bar~1/baz")) .isEqualTo("D:/program files/microsoft something/foo/~bar_hello/baz"); - LocalPath notYetExistent = create("d:/progra~1/micros~1/foo/will~1.exi/bar"); - // The path string has an upper-case drive letter because that's how path printing works. - assertThat(notYetExistent.getPathString()) + assertThat(normalize(osPathPolicy, "d:/progra~1/micros~1/foo/will~1.exi/bar")) .isEqualTo("D:/program files/microsoft something/foo/will~1.exi/bar"); - LocalPath msRoot = create("d:/progra~1/micros~1"); - assertThat(msRoot.getPathString()).isEqualTo("D:/program files/microsoft something"); + assertThat(normalize(osPathPolicy, "d:/progra~1/micros~1")) + .isEqualTo("D:/program files/microsoft something"); // Pretend that a path we already failed to resolve once came into existence. shortPathResolver.resolutions.put( "d:/program files/microsoft something/foo/will~1.exi", "will.exist"); // Assert that this time we can resolve the previously non-existent path. - LocalPath nowExists = create("d:/progra~1/micros~1/foo/will~1.exi/bar"); // The path string has an upper-case drive letter because that's how path printing works. - assertThat(nowExists.getPathString()) + assertThat(normalize(osPathPolicy, "d:/progra~1/micros~1/foo/will~1.exi/bar")) .isEqualTo("D:/program files/microsoft something/foo/will.exist/bar"); - // Assert relative paths that look like short paths are untouched - assertThat(create("progra~1").getPathString()).isEqualTo("progra~1"); + // Check needsToNormalized + assertThat(osPathPolicy.needsToNormalize("d:/progra~1/micros~1/foo/will~1.exi/bar")) + .isEqualTo(WindowsOsPathPolicy.NEEDS_SHORT_PATH_NORMALIZATION); + assertThat(osPathPolicy.needsToNormalize("will~1.exi")) + .isEqualTo(WindowsOsPathPolicy.NEEDS_SHORT_PATH_NORMALIZATION); + assertThat(osPathPolicy.needsToNormalize("d:/no-normalization")) + .isEqualTo(WindowsOsPathPolicy.NORMALIZED); // Sanity check + } + + private static String normalize(OsPathPolicy osPathPolicy, String str) { + return osPathPolicy.normalize(str, osPathPolicy.needsToNormalize(str)); } } diff --git a/src/test/java/com/google/devtools/build/lib/windows/PathWindowsTest.java b/src/test/java/com/google/devtools/build/lib/windows/PathWindowsTest.java deleted file mode 100644 index e77de52d83..0000000000 --- a/src/test/java/com/google/devtools/build/lib/windows/PathWindowsTest.java +++ /dev/null @@ -1,298 +0,0 @@ -// Copyright 2014 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.windows; - -import static com.google.common.truth.Truth.assertThat; - -import com.google.common.base.Function; -import com.google.common.base.Predicate; -import com.google.devtools.build.lib.clock.BlazeClock; -import com.google.devtools.build.lib.vfs.FileSystem; -import com.google.devtools.build.lib.vfs.Path; -import com.google.devtools.build.lib.vfs.Path.PathFactory; -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.inmemoryfs.InMemoryFileSystem; -import com.google.devtools.build.lib.windows.WindowsFileSystem.WindowsPath; -import java.net.URI; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** A test for windows aspects of {@link Path}. */ -@RunWith(JUnit4.class) -public class PathWindowsTest { - - private static final class MockShortPathResolver implements Function<String, String> { - public List<String> resolutionQueries = new ArrayList<>(); - - // Full path to resolved child mapping. - public Map<String, String> resolutions = new HashMap<>(); - - @Override - public String apply(String path) { - path = path.toLowerCase(); - resolutionQueries.add(path); - return resolutions.get(path); - } - } - - private FileSystem filesystem; - private WindowsPath root; - private final MockShortPathResolver shortPathResolver = new MockShortPathResolver(); - - @Before - public final void initializeFileSystem() throws Exception { - filesystem = - new InMemoryFileSystem(BlazeClock.instance()) { - @Override - protected PathFactory getPathFactory() { - return WindowsFileSystem.getPathFactoryForTesting(shortPathResolver); - } - - @Override - public boolean isFilePathCaseSensitive() { - return false; - } - }; - root = (WindowsPath) filesystem.getRootDirectory().getRelative("C:/"); - root.createDirectory(); - } - - private void assertAsFragmentWorks(String expected) { - assertThat(filesystem.getPath(expected).asFragment()).isEqualTo(PathFragment.create(expected)); - } - - @Test - public void testWindowsPath() { - Path p = filesystem.getPath("C:/foo/bar"); - assertThat(p.getPathString()).isEqualTo("C:/foo/bar"); - assertThat(p.toString()).isEqualTo("C:/foo/bar"); - } - - @Test - public void testAsFragmentWindows() { - assertAsFragmentWorks("C:/"); - assertAsFragmentWorks("C://"); - assertAsFragmentWorks("C:/first"); - assertAsFragmentWorks("C:/first/x/y"); - assertAsFragmentWorks("C:/first/x/y.foo"); - } - - @Test - public void testGetRelativeWithFragmentWindows() { - Path dir = filesystem.getPath("C:/first/x"); - assertThat(dir.getRelative(PathFragment.create("y")).toString()).isEqualTo("C:/first/x/y"); - assertThat(dir.getRelative(PathFragment.create("./x")).toString()).isEqualTo("C:/first/x/x"); - assertThat(dir.getRelative(PathFragment.create("../y")).toString()).isEqualTo("C:/first/y"); - assertThat(dir.getRelative(PathFragment.create("../y")).toString()).isEqualTo("C:/first/y"); - assertThat(dir.getRelative(PathFragment.create("../../../y")).toString()).isEqualTo("C:/y"); - } - - @Test - public void testGetRelativeWithAbsoluteFragmentWindows() { - Path x = filesystem.getPath("C:/first/x"); - assertThat(x.getRelative(PathFragment.create("C:/x/y")).toString()).isEqualTo("C:/x/y"); - } - - @Test - public void testGetRelativeWithAbsoluteStringWorksWindows() { - Path x = filesystem.getPath("C:/first/x"); - assertThat(x.getRelative("C:/x/y").toString()).isEqualTo("C:/x/y"); - } - - @Test - public void testParentOfRootIsRootWindows() { - assertThat(root).isSameAs(root.getRelative("..")); - assertThat(root.getRelative("dots")).isSameAs(root.getRelative("broken/../../dots")); - } - - @Test - public void testStartsWithWorksOnWindows() { - assertStartsWithReturnsOnWindows(true, "C:/first/x", "C:/first/x/y"); - assertStartsWithReturnsOnWindows(true, "c:/first/x", "C:/FIRST/X/Y"); - assertStartsWithReturnsOnWindows(true, "C:/FIRST/X", "c:/first/x/y"); - assertStartsWithReturnsOnWindows(false, "C:/", "/"); - assertStartsWithReturnsOnWindows(false, "C:/", "D:/"); - assertStartsWithReturnsOnWindows(false, "C:/", "D:/foo"); - } - - @Test - public void testGetRelative() { - Path x = filesystem.getPath("C:\\first\\x"); - Path other = x.getRelative("a\\b\\c"); - assertThat(other.asFragment().getPathString()).isEqualTo("C:/first/x/a/b/c"); - } - - private static void assertStartsWithReturnsOnWindows( - boolean expected, String ancestor, String descendant) { - FileSystem windowsFileSystem = new WindowsFileSystem(); - Path parent = windowsFileSystem.getPath(ancestor); - Path child = windowsFileSystem.getPath(descendant); - assertThat(child.startsWith(parent)).isEqualTo(expected); - } - - @Test - public void testResolvesShortenedPaths() { - shortPathResolver.resolutions.put("d:/progra~1", "program files"); - shortPathResolver.resolutions.put("d:/program files/micros~1", "microsoft something"); - shortPathResolver.resolutions.put( - "d:/program files/microsoft something/foo/~bar~1", "~bar_hello"); - - // Assert normal shortpath resolution. - Path normal = root.getRelative("d:/progra~1/micros~1/foo/~bar~1/baz"); - // The path string has an upper-case drive letter because that's how path printing works. - assertThat(normal.getPathString()) - .isEqualTo("D:/program files/microsoft something/foo/~bar_hello/baz"); - // Assert that we only try to resolve the path segments that look like they may be shortened. - assertThat(shortPathResolver.resolutionQueries) - .containsExactly( - "d:/progra~1", - "d:/program files/micros~1", - "d:/program files/microsoft something/foo/~bar~1"); - - // Assert resolving a path that has a segment which doesn't exist but later will. - shortPathResolver.resolutionQueries.clear(); - Path notYetExistent = root.getRelative("d:/progra~1/micros~1/foo/will~1.exi/bar"); - // The path string has an upper-case drive letter because that's how path printing works. - assertThat(notYetExistent.getPathString()) - .isEqualTo("D:/program files/microsoft something/foo/will~1.exi/bar"); - // Assert that we only try to resolve the path segments that look like they may be shortened. - assertThat(shortPathResolver.resolutionQueries) - .containsExactly( - "d:/progra~1", - "d:/program files/micros~1", - "d:/program files/microsoft something/foo/will~1.exi"); - - // Assert that the paths we failed to resolve don't get cached. - final List<String> children = new ArrayList<>(2); - Predicate<Path> collector = - new Predicate<Path>() { - @Override - public boolean apply(Path child) { - children.add(child.getPathString()); - return true; - } - }; - - WindowsPath msRoot = (WindowsPath) root.getRelative("d:/progra~1/micros~1"); - assertThat(msRoot.getPathString()).isEqualTo("D:/program files/microsoft something"); - msRoot.applyToChildren(collector); - // The path string has an upper-case drive letter because that's how path printing works. - assertThat(children).containsExactly("D:/program files/microsoft something/foo"); - - // Assert that the non-resolvable path was not cached. - children.clear(); - WindowsPath foo = (WindowsPath) msRoot.getRelative("foo"); - foo.applyToChildren(collector); - assertThat(children).containsExactly("D:/program files/microsoft something/foo/~bar_hello"); - - // Pretend that a path we already failed to resolve once came into existence. - shortPathResolver.resolutions.put( - "d:/program files/microsoft something/foo/will~1.exi", "will.exist"); - - // Assert that this time we can resolve the previously non-existent path. - shortPathResolver.resolutionQueries.clear(); - Path nowExists = root.getRelative("d:/progra~1/micros~1/foo/will~1.exi/bar"); - // The path string has an upper-case drive letter because that's how path printing works. - assertThat(nowExists.getPathString()) - .isEqualTo("D:/program files/microsoft something/foo/will.exist/bar"); - // Assert that we only try to resolve the path segments that look like they may be shortened. - assertThat(shortPathResolver.resolutionQueries) - .containsExactly( - "d:/progra~1", - "d:/program files/micros~1", - "d:/program files/microsoft something/foo/will~1.exi"); - - // Assert that this time we cached the previously non-existent path. - children.clear(); - foo.applyToChildren(collector); - // The path strings have upper-case drive letters because that's how path printing works. - children.clear(); - foo.applyToChildren(collector); - assertThat(children) - .containsExactly( - "D:/program files/microsoft something/foo/~bar_hello", - "D:/program files/microsoft something/foo/will.exist"); - } - - @Test - public void testCaseInsensitivePathFragment() { - // equals - assertThat(PathFragment.create("c:/FOO/BAR")).isEqualTo(PathFragment.create("c:\\foo\\bar")); - assertThat(PathFragment.create("c:/FOO/BAR")).isNotEqualTo(PathFragment.create("d:\\foo\\bar")); - assertThat(PathFragment.create("c:/FOO/BAR")).isNotEqualTo(PathFragment.create("/foo/bar")); - // equals for the string representation - assertThat(PathFragment.create("c:/FOO/BAR").toString()) - .isNotEqualTo(PathFragment.create("c:/foo/bar").toString()); - // hashCode - assertThat(PathFragment.create("c:/FOO/BAR").hashCode()) - .isEqualTo(PathFragment.create("c:\\foo\\bar").hashCode()); - assertThat(PathFragment.create("c:/FOO/BAR").hashCode()) - .isNotEqualTo(PathFragment.create("d:\\foo\\bar").hashCode()); - assertThat(PathFragment.create("c:/FOO/BAR").hashCode()) - .isNotEqualTo(PathFragment.create("/foo/bar").hashCode()); - // compareTo - assertThat(PathFragment.create("c:/FOO/BAR").compareTo(PathFragment.create("c:\\foo\\bar"))) - .isEqualTo(0); - assertThat(PathFragment.create("c:/FOO/BAR").compareTo(PathFragment.create("d:\\foo\\bar"))) - .isLessThan(0); - assertThat(PathFragment.create("c:/FOO/BAR").compareTo(PathFragment.create("/foo/bar"))) - .isGreaterThan(0); - // startsWith - assertThat(PathFragment.create("c:/FOO/BAR").startsWith(PathFragment.create("c:\\foo"))) - .isTrue(); - assertThat(PathFragment.create("c:/FOO/BAR").startsWith(PathFragment.create("d:\\foo"))) - .isFalse(); - // endsWith - assertThat(PathFragment.create("c:/FOO/BAR/BAZ").endsWith(PathFragment.create("bar\\baz"))) - .isTrue(); - assertThat(PathFragment.create("c:/FOO/BAR/BAZ").endsWith(PathFragment.create("/bar/baz"))) - .isFalse(); - assertThat(PathFragment.create("c:/FOO/BAR/BAZ").endsWith(PathFragment.create("d:\\bar\\baz"))) - .isFalse(); - // relativeTo - assertThat( - PathFragment.create("c:/FOO/BAR/BAZ/QUX") - .relativeTo(PathFragment.create("c:\\foo\\bar"))) - .isEqualTo(PathFragment.create("Baz/Qux")); - } - - @Test - public void testCaseInsensitiveRootedPath() { - Path ancestor = filesystem.getPath("C:\\foo\\bar"); - assertThat(ancestor).isInstanceOf(WindowsPath.class); - Path child = filesystem.getPath("C:\\FOO\\Bar\\baz"); - assertThat(child).isInstanceOf(WindowsPath.class); - assertThat(child.startsWith(ancestor)).isTrue(); - assertThat(child.relativeTo(ancestor)).isEqualTo(PathFragment.create("baz")); - RootedPath actual = RootedPath.toRootedPath(Root.fromPath(ancestor), child); - assertThat(actual.getRoot()).isEqualTo(Root.fromPath(ancestor)); - assertThat(actual.getRootRelativePath()).isEqualTo(PathFragment.create("baz")); - } - - @Test - public void testToURI() { - // See https://blogs.msdn.microsoft.com/ie/2006/12/06/file-uris-in-windows/ - Path p = root.getRelative("Temp\\Foo Bar.txt"); - URI uri = p.toURI(); - assertThat(uri.toString()).isEqualTo("file:///C:/Temp/Foo%20Bar.txt"); - } -} diff --git a/src/test/java/com/google/devtools/build/lib/windows/WindowsFileSystemTest.java b/src/test/java/com/google/devtools/build/lib/windows/WindowsFileSystemTest.java index 8937c453a7..3e9cd27c93 100644 --- a/src/test/java/com/google/devtools/build/lib/windows/WindowsFileSystemTest.java +++ b/src/test/java/com/google/devtools/build/lib/windows/WindowsFileSystemTest.java @@ -18,7 +18,6 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import com.google.common.base.Function; -import com.google.common.base.Predicate; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; @@ -27,16 +26,13 @@ import com.google.devtools.build.lib.util.OS; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.build.lib.vfs.Symlinks; -import com.google.devtools.build.lib.windows.WindowsFileSystem.WindowsPath; import com.google.devtools.build.lib.windows.jni.WindowsFileOperations; import com.google.devtools.build.lib.windows.util.WindowsTestUtil; import java.io.File; import java.io.IOException; import java.nio.file.Files; -import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.List; import java.util.Map; import org.junit.After; import org.junit.Before; @@ -246,42 +242,22 @@ public class WindowsFileSystemTest { assertThat(p.getPathString()).endsWith(longPath); assertThat(p).isEqualTo(fs.getPath(scratchRoot).getRelative(shortPath)); assertThat(p).isEqualTo(fs.getPath(scratchRoot).getRelative(longPath)); - assertThat(fs.getPath(scratchRoot).getRelative(shortPath)).isSameAs(p); - assertThat(fs.getPath(scratchRoot).getRelative(longPath)).isSameAs(p); + assertThat(fs.getPath(scratchRoot).getRelative(shortPath)).isEqualTo(p); + assertThat(fs.getPath(scratchRoot).getRelative(longPath)).isEqualTo(p); } @Test public void testUnresolvableShortPathWhichIsThenCreated() throws Exception { String shortPath = "unreso~1.sho/foo/will~1.exi/bar/hello.txt"; - String longPrefix = "unresolvable.shortpath/foo/"; - String longPath = longPrefix + "will.exist/bar/hello.txt"; - testUtil.scratchDir(longPrefix); - final WindowsPath foo = (WindowsPath) fs.getPath(scratchRoot).getRelative(longPrefix); - + String longPath = "unresolvable.shortpath/foo/will.exist/bar/hello.txt"; // Assert that we can create an unresolvable path. Path p = fs.getPath(scratchRoot).getRelative(shortPath); - assertThat(p.getPathString()).endsWith(longPrefix + "will~1.exi/bar/hello.txt"); - // Assert that said path is not cached in its parent's `children` cache. - final List<String> children = new ArrayList<>(); - Predicate<Path> collector = - new Predicate<Path>() { - @Override - public boolean apply(Path child) { - children.add(child.relativeTo(foo).getPathString()); - return true; - } - }; - foo.applyToChildren(collector); - assertThat(children).isEmpty(); + assertThat(p.getPathString()).endsWith(shortPath); // Assert that we can then create the whole path, and can now resolve the short form. testUtil.scratchFile(longPath, "hello"); Path q = fs.getPath(scratchRoot).getRelative(shortPath); assertThat(q.getPathString()).endsWith(longPath); - // Assert however that the unresolved and resolved Path objects are different, and only the - // resolved one is cached. assertThat(p).isNotEqualTo(q); - foo.applyToChildren(collector); - assertThat(children).containsExactly("will.exist"); } /** @@ -297,18 +273,11 @@ public class WindowsFileSystemTest { Path p2 = fs.getPath(scratchRoot).getRelative("longpa~1"); assertThat(p1.exists()).isFalse(); assertThat(p1).isEqualTo(p2); - assertThat(p1).isNotSameAs(p2); testUtil.scratchDir("longpathnow"); Path q1 = fs.getPath(scratchRoot).getRelative("longpa~1"); - Path q2 = fs.getPath(scratchRoot).getRelative("longpa~1"); assertThat(q1.exists()).isTrue(); - assertThat(q1).isEqualTo(q2); - // Assert q1 == q2, because we could successfully resolve the short path to a long name and we - // cache them by the long name, so it's irrelevant they were created from a 8dot3 name, or what - // that name resolves to later in time. - assertThat(q1).isSameAs(q2); - assertThat(q1).isSameAs(fs.getPath(scratchRoot).getRelative("longpathnow")); + assertThat(q1).isEqualTo(fs.getPath(scratchRoot).getRelative("longpathnow")); // Delete the original resolution of "longpa~1" ("longpathnow"). assertThat(q1.delete()).isTrue(); @@ -317,14 +286,8 @@ public class WindowsFileSystemTest { // Create a directory whose 8dot3 name is also "longpa~1" but its long name is different. testUtil.scratchDir("longpaththen"); Path r1 = fs.getPath(scratchRoot).getRelative("longpa~1"); - Path r2 = fs.getPath(scratchRoot).getRelative("longpa~1"); assertThat(r1.exists()).isTrue(); - assertThat(r1).isEqualTo(r2); - assertThat(r1).isSameAs(r2); - assertThat(r1).isSameAs(fs.getPath(scratchRoot).getRelative("longpaththen")); - // r1 == r2 and q1 == q2, but r1 != q1, because the resolution of "longpa~1" changed over time. - assertThat(r1).isNotEqualTo(q1); - assertThat(r1).isNotSameAs(q1); + assertThat(r1).isEqualTo(fs.getPath(scratchRoot).getRelative("longpaththen")); } @Test |