diff options
author | tomlu <tomlu@google.com> | 2018-02-08 15:32:00 -0800 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-02-08 15:34:11 -0800 |
commit | a729b9b4c3d7844a7d44934bf3365f92633c0a60 (patch) | |
tree | 6329f4baf5b0b83ea6e3bd577b78b8d49afea9f1 /src/test/java/com/google/devtools/build/lib/vfs/PathTest.java | |
parent | 0ab46f0dd95f735056add4dd8a90a76944b81d00 (diff) |
Replace path implementation.
Path and PathFragment have been replaced with String-based implementations. They are pretty similar, but each method is dissimilar enough that I did not feel sharing code was appropriate.
A summary of changes:
PATH
====
* Subsumes LocalPath (deleted, its tests repurposed)
* Use a simple string to back Path
* Path instances are no longer interned; Reference equality will no longer work
* Always normalized (same as before)
* Some operations will now be slower, like instance compares (which were previously just a reference check)
* Multiple identical paths will now consume more memory since they are not interned
PATH FRAGMENT
=============
* Use a simple string to back PathFragment
* No more segment arrays with interned strings
* Always normalized
* Remove isNormalized
* Replace some isNormalizied uses with containsUpLevelReferences() to check if path fragments try to escape their scope
* To check if user input is normalized, supply static methods on PathFragment to validate the string before constructing a PathFragment
* Because PathFragments are always normalized, we have to replace checks for literal "." from PathFragment#getPathString to PathFragment#getSafePathString. The latter returns "." for the empty string.
* The previous implementation supported efficient segment semantics (segment count, iterating over segments). This is now expensive since we do longer have a segment array.
ARTIFACT
========
* Remove Path instance. It is instead dynamically constructed on request. This is necessary to avoid this CL becoming a memory regression.
RELNOTES: None
PiperOrigin-RevId: 185062932
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 | 341 |
1 files changed, 0 insertions, 341 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 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)); - } -} |