diff options
Diffstat (limited to 'src/test/java/com/google/devtools/build/lib/vfs/PathTest.java')
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/vfs/PathTest.java | 312 |
1 files changed, 312 insertions, 0 deletions
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 new file mode 100644 index 0000000000..738e454e43 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/vfs/PathTest.java @@ -0,0 +1,312 @@ +// Copyright 2014 Google Inc. 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.assertEquals; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.google.common.collect.Lists; +import com.google.common.testing.EqualsTester; +import com.google.common.testing.GcFinalization; +import com.google.devtools.build.lib.util.BlazeClock; +import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.lang.ref.WeakReference; +import java.util.Collections; +import java.util.List; + +/** + * A test for {@link Path}. + */ +@RunWith(JUnit4.class) +public class PathTest { + private FileSystem filesystem; + private Path root; + + @Before + public void setUp() 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); + assertEquals(expected, child.startsWith(parent)); + } + + @Test + public void testGetChildWorks() { + assertGetChildWorks("second"); + assertGetChildWorks("..."); + assertGetChildWorks("...."); + } + + private void assertGetChildWorks(String childName) { + assertEquals(filesystem.getPath("/first/" + childName), + filesystem.getPath("/first").getChild(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"); + assertEquals("/first/x/y", + dir.getRelative(new PathFragment("y")).toString()); + assertEquals("/first/x/x", + dir.getRelative(new PathFragment("./x")).toString()); + assertEquals("/first/y", + dir.getRelative(new PathFragment("../y")).toString()); + + } + + @Test + public void testGetRelativeWithAbsoluteFragmentWorks() { + Path root = filesystem.getPath("/first/x"); + assertEquals("/x/y", + root.getRelative(new PathFragment("/x/y")).toString()); + } + + @Test + public void testGetRelativeWithAbsoluteStringWorks() { + Path root = filesystem.getPath("/first/x"); + assertEquals("/x/y", root.getRelative("/x/y").toString()); + } + + @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() { + assertSame(root, root.getRelative("..")); + + assertSame(root.getRelative("dots"), + root.getRelative("broken/../../dots")); + } + + @Test + public void testSingleSegmentEquivalence() { + assertSame( + root.getRelative("aSingleSegment"), + root.getRelative("aSingleSegment")); + } + + @Test + public void testSiblingNonEquivalenceString() { + assertNotSame( + root.getRelative("aSingleSegment"), + root.getRelative("aDifferentSegment")); + } + + @Test + public void testSiblingNonEquivalenceFragment() { + assertNotSame( + root.getRelative(new PathFragment("aSingleSegment")), + root.getRelative(new PathFragment("aDifferentSegment"))); + } + + @Test + public void testHashCodeStableAcrossGarbageCollections() { + Path parent = filesystem.getPath("/a"); + PathFragment childFragment = new PathFragment("b"); + Path child = parent.getRelative(childFragment); + WeakReference<Path> childRef = new WeakReference<>(child); + int childHashCode1 = childRef.get().hashCode(); + assertEquals(childHashCode1, parent.getRelative(childFragment).hashCode()); + child = null; + GcFinalization.awaitClear(childRef); + int childHashCode2 = parent.getRelative(childFragment).hashCode(); + assertEquals(childHashCode1, childHashCode2); + } + + @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(); + + assertTrue(p2.startsWith(p1)); + assertTrue(p2.startsWith(dsP1)); + assertTrue(dsP2.startsWith(p1)); + assertTrue(dsP2.startsWith(dsP1)); + } finally { + Path.setFileSystemForSerialization(oldFileSystem); + } + } + + private void assertAsFragmentWorks(String expected) { + assertEquals(new PathFragment(expected), filesystem.getPath(expected).asFragment()); + } + + private void assertGetRelativeWorks(String expected, String relative) { + assertEquals(filesystem.getPath(expected), + filesystem.getPath("/first/x").getRelative(relative)); + } + + private void assertRelativeToWorks(String expected, String relative, String original) { + assertEquals(new PathFragment(expected), + filesystem.getPath(relative).relativeTo(filesystem.getPath(original))); + } +} |