aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/java/com/google/devtools/build/lib/vfs/ScopeEscapableFileSystemTest.java818
-rw-r--r--src/test/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileSystemTest.java12
2 files changed, 5 insertions, 825 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/ScopeEscapableFileSystemTest.java b/src/test/java/com/google/devtools/build/lib/vfs/ScopeEscapableFileSystemTest.java
deleted file mode 100644
index 9fd98b0f6d..0000000000
--- a/src/test/java/com/google/devtools/build/lib/vfs/ScopeEscapableFileSystemTest.java
+++ /dev/null
@@ -1,818 +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 java.nio.charset.StandardCharsets.UTF_8;
-import static org.junit.Assert.fail;
-
-import com.google.common.collect.ImmutableList;
-import com.google.devtools.build.lib.util.Preconditions;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Collection;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Generic tests for any file system that implements {@link ScopeEscapableFileSystem},
- * i.e. any file system that supports symlinks that escape its scope.
- *
- * Each suitable file system test should inherit from this class, thereby obtaining
- * all the tests.
- */
-public abstract class ScopeEscapableFileSystemTest extends SymlinkAwareFileSystemTest {
-
- /**
- * Trivial FileSystem implementation that can record the last path passed to each method
- * and read/write to a unified "state" variable (which can then be checked by tests) for
- * each data type this class manipulates.
- *
- * The default implementation of each method throws an exception. Each test case should
- * selectively override the methods it expects to be invoked.
- */
- private static class TestDelegator extends FileSystem {
- protected Path lastPath;
- protected boolean booleanState;
- protected long longState;
- protected Object objectState;
-
- public void setState(boolean state) { booleanState = state; }
- public void setState(long state) { longState = state; }
- public void setState(Object state) { objectState = state; }
-
- public boolean booleanState() { return booleanState; }
- public long longState() { return longState; }
- public Object objectState() { return objectState; }
-
- public PathFragment lastPath() {
- Path ans = lastPath;
- // Clear this out to protect against accidental matches when testing the same path multiple
- // consecutive times.
- lastPath = null;
- return ans != null ? ans.asFragment() : null;
- }
-
- @Override
- public boolean supportsModifications(Path path) {
- return true;
- }
-
- @Override
- public boolean supportsSymbolicLinksNatively(Path path) {
- return true;
- }
-
- @Override
- public boolean supportsHardLinksNatively(Path path) {
- return true;
- }
-
- @Override
- public boolean isFilePathCaseSensitive() {
- return true;
- }
-
- private static RuntimeException re() {
- return new RuntimeException("This method should not be called in this context");
- }
-
- @Override protected boolean isReadable(Path path) { throw re(); }
- @Override protected boolean isWritable(Path path) { throw re(); }
- @Override protected boolean isDirectory(Path path, boolean followSymlinks) { throw re(); }
- @Override protected boolean isFile(Path path, boolean followSymlinks) { throw re(); }
- @Override protected boolean isSpecialFile(Path path, boolean followSymlinks) { throw re(); }
- @Override protected boolean isExecutable(Path path) { throw re(); }
- @Override protected boolean exists(Path path, boolean followSymlinks) {throw re(); }
- @Override protected boolean isSymbolicLink(Path path) { throw re(); }
- @Override protected boolean createDirectory(Path path) { throw re(); }
- @Override protected boolean delete(Path path) { throw re(); }
-
- @Override protected long getFileSize(Path path, boolean followSymlinks) { throw re(); }
- @Override protected long getLastModifiedTime(Path path, boolean followSymlinks) { throw re(); }
-
- @Override protected void setWritable(Path path, boolean writable) { throw re(); }
- @Override protected void setExecutable(Path path, boolean executable) { throw re(); }
- @Override protected void setReadable(Path path, boolean readable) { throw re(); }
- @Override protected void setLastModifiedTime(Path path, long newTime) { throw re(); }
- @Override protected void renameTo(Path sourcePath, Path targetPath) { throw re(); }
- @Override protected void createSymbolicLink(Path linkPath, PathFragment targetFragment) {
- throw re();
- }
- @Override protected void createFSDependentHardLink(Path linkPath, Path originalPath) {
- throw re();
- }
- @Override protected PathFragment readSymbolicLink(Path path) { throw re(); }
- @Override protected InputStream getInputStream(Path path) { throw re(); }
- @Override protected Collection<Path> getDirectoryEntries(Path path) { throw re(); }
- @Override protected OutputStream getOutputStream(Path path, boolean append) { throw re(); }
- @Override
- protected FileStatus statIfFound(Path path, boolean followSymlinks) throws IOException {
- throw re();
- }
- }
-
- protected static final PathFragment SCOPE_ROOT = PathFragment.create("/fs/root");
-
- private Path fileLink;
- private PathFragment fileLinkTarget;
- private Path dirLink;
- private PathFragment dirLinkTarget;
-
- @Before
- public final void createLinks() throws Exception {
- Preconditions.checkState(
- testFS instanceof ScopeEscapableFileSystem, "Not ScopeEscapable: %s", testFS);
- ((ScopeEscapableFileSystem) testFS).enableScopeChecking(false);
- for (int i = 1; i <= SCOPE_ROOT.segmentCount(); i++) {
- testFS.getPath(SCOPE_ROOT.subFragment(0, i)).createDirectory();
- }
-
- fileLink = testFS.getPath(SCOPE_ROOT.getRelative("link"));
- fileLinkTarget = PathFragment.create("/should/be/delegated/fileLinkTarget");
- testFS.createSymbolicLink(fileLink, fileLinkTarget);
-
- dirLink = testFS.getPath(SCOPE_ROOT.getRelative("dirlink"));
- dirLinkTarget = PathFragment.create("/should/be/delegated/dirLinkTarget");
- testFS.createSymbolicLink(dirLink, dirLinkTarget);
- }
-
- /**
- * Returns the file system supplied by {@link #getFreshFileSystem}, cast to
- * a {@link ScopeEscapableFileSystem}. Also enables scope checking within
- * the file system (which we keep disabled for inherited tests that aren't
- * intended to test scope boundaries).
- */
- private ScopeEscapableFileSystem scopedFS() {
- ScopeEscapableFileSystem fs = (ScopeEscapableFileSystem) testFS;
- fs.enableScopeChecking(true);
- return fs;
- }
-
- // Checks that the semi-resolved path passed to the delegator matches the expected value.
- private void checkPath(TestDelegator delegator, PathFragment expectedDelegatedPath) {
- assertThat(delegator.lastPath()).isEqualTo(expectedDelegatedPath);
- }
-
- // Asserts that the condition is false and checks that the expected path was delegated.
- private void assertFalseWithPathCheck(boolean result, TestDelegator delegator,
- PathFragment expectedDelegatedPath) {
- assertThat(result).isFalse();
- checkPath(delegator, expectedDelegatedPath);
- }
-
- // Asserts that the condition is true and checks that the expected path was delegated.
- private void assertTrueWithPathCheck(boolean result, TestDelegator delegator,
- PathFragment expectedDelegatedPath) {
- assertThat(result).isTrue();
- checkPath(delegator, expectedDelegatedPath);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Tests:
- /////////////////////////////////////////////////////////////////////////////
-
- @Test
- public void testIsReadableCallOnEscapingSymlink() throws Exception {
- TestDelegator delegator = new TestDelegator() {
- @Override protected boolean isReadable(Path path) {
- lastPath = path;
- return booleanState();
- }
- };
- scopedFS().setDelegator(delegator);
-
- delegator.setState(false);
- assertFalseWithPathCheck(fileLink.isReadable(), delegator, fileLinkTarget);
- assertFalseWithPathCheck(dirLink.getRelative("a").isReadable(), delegator,
- dirLinkTarget.getRelative("a"));
-
- delegator.setState(true);
- assertTrueWithPathCheck(fileLink.isReadable(), delegator, fileLinkTarget);
- assertTrueWithPathCheck(dirLink.getRelative("a").isReadable(), delegator,
- dirLinkTarget.getRelative("a"));
- }
-
- @Test
- public void testIsWritableCallOnEscapingSymlink() throws Exception {
- TestDelegator delegator = new TestDelegator() {
- @Override protected boolean isWritable(Path path) {
- lastPath = path;
- return booleanState();
- }
- };
- scopedFS().setDelegator(delegator);
-
- delegator.setState(false);
- assertFalseWithPathCheck(fileLink.isWritable(), delegator, fileLinkTarget);
- assertFalseWithPathCheck(dirLink.getRelative("a").isWritable(), delegator,
- dirLinkTarget.getRelative("a"));
-
- delegator.setState(true);
- assertTrueWithPathCheck(fileLink.isWritable(), delegator, fileLinkTarget);
- assertTrueWithPathCheck(dirLink.getRelative("a").isWritable(), delegator,
- dirLinkTarget.getRelative("a"));
- }
-
- @Test
- public void testisExecutableCallOnEscapingSymlink() throws Exception {
- TestDelegator delegator = new TestDelegator() {
- @Override protected boolean isExecutable(Path path) {
- lastPath = path;
- return booleanState();
- }
- };
- scopedFS().setDelegator(delegator);
-
- delegator.setState(false);
- assertFalseWithPathCheck(fileLink.isExecutable(), delegator, fileLinkTarget);
- assertFalseWithPathCheck(dirLink.getRelative("a").isExecutable(), delegator,
- dirLinkTarget.getRelative("a"));
-
- delegator.setState(true);
- assertTrueWithPathCheck(fileLink.isExecutable(), delegator, fileLinkTarget);
- assertTrueWithPathCheck(dirLink.getRelative("a").isExecutable(), delegator,
- dirLinkTarget.getRelative("a"));
- }
-
- @Test
- public void testIsDirectoryCallOnEscapingSymlink() throws Exception {
- TestDelegator delegator = new TestDelegator() {
- @Override protected boolean isDirectory(Path path, boolean followSymlinks) {
- lastPath = path;
- return booleanState();
- }
- @Override protected boolean exists(Path path, boolean followSymlinks) { return true; }
- @Override protected long getLastModifiedTime(Path path, boolean followSymlinks) { return 0; }
- };
- scopedFS().setDelegator(delegator);
-
- delegator.setState(false);
- assertFalseWithPathCheck(fileLink.isDirectory(), delegator, fileLinkTarget);
- assertFalseWithPathCheck(dirLink.getRelative("a").isDirectory(), delegator,
- dirLinkTarget.getRelative("a"));
-
- delegator.setState(true);
- assertTrueWithPathCheck(fileLink.isDirectory(), delegator, fileLinkTarget);
- assertTrueWithPathCheck(dirLink.getRelative("a").isDirectory(), delegator,
- dirLinkTarget.getRelative("a"));
- }
-
- @Test
- public void testIsFileCallOnEscapingSymlink() throws Exception {
- TestDelegator delegator = new TestDelegator() {
- @Override protected boolean isFile(Path path, boolean followSymlinks) {
- lastPath = path;
- return booleanState();
- }
- @Override protected boolean exists(Path path, boolean followSymlinks) { return true; }
- @Override protected long getLastModifiedTime(Path path, boolean followSymlinks) { return 0; }
- };
- scopedFS().setDelegator(delegator);
-
- delegator.setState(false);
- assertFalseWithPathCheck(fileLink.isFile(), delegator, fileLinkTarget);
- assertFalseWithPathCheck(dirLink.getRelative("a").isFile(), delegator,
- dirLinkTarget.getRelative("a"));
-
- delegator.setState(true);
- assertTrueWithPathCheck(fileLink.isFile(), delegator, fileLinkTarget);
- assertTrueWithPathCheck(dirLink.getRelative("a").isFile(), delegator,
- dirLinkTarget.getRelative("a"));
- }
-
- @Test
- public void testIsSymbolicLinkCallOnEscapingSymlink() throws Exception {
- TestDelegator delegator = new TestDelegator() {
- @Override protected boolean isSymbolicLink(Path path) {
- lastPath = path;
- return booleanState();
- }
- @Override protected boolean exists(Path path, boolean followSymlinks) { return true; }
- @Override protected long getLastModifiedTime(Path path, boolean followSymlinks) { return 0; }
- @Override protected boolean isDirectory(Path path, boolean followSymlinks) { return true; }
- };
- scopedFS().setDelegator(delegator);
-
- // We shouldn't follow final-segment links, so they should never invoke the delegator.
- delegator.setState(false);
- assertThat(fileLink.isSymbolicLink()).isTrue();
- assertThat(delegator.lastPath()).isNull();
-
- assertFalseWithPathCheck(dirLink.getRelative("a").isSymbolicLink(), delegator,
- dirLinkTarget.getRelative("a"));
-
- delegator.setState(true);
- assertTrueWithPathCheck(dirLink.getRelative("a").isSymbolicLink(), delegator,
- dirLinkTarget.getRelative("a"));
- }
-
- /**
- * Returns a test delegator that reflects info passed to Path.exists() calls.
- */
- private TestDelegator newExistsDelegator() {
- return new TestDelegator() {
- @Override protected boolean exists(Path path, boolean followSymlinks) {
- lastPath = path;
- return booleanState();
- }
- @Override protected FileStatus stat(Path path, boolean followSymlinks) throws IOException {
- if (!exists(path, followSymlinks)) {
- throw new IOException("Expected exception on stat of non-existent file");
- }
- return super.stat(path, followSymlinks);
- }
- @Override protected long getLastModifiedTime(Path path, boolean followSymlinks) { return 0; }
- };
- }
-
- @Test
- public void testExistsCallOnEscapingSymlink() throws Exception {
- TestDelegator delegator = newExistsDelegator();
- scopedFS().setDelegator(delegator);
-
- delegator.setState(false);
- assertFalseWithPathCheck(fileLink.exists(), delegator, fileLinkTarget);
- assertFalseWithPathCheck(dirLink.getRelative("a").exists(), delegator,
- dirLinkTarget.getRelative("a"));
-
- delegator.setState(true);
- assertTrueWithPathCheck(fileLink.exists(), delegator, fileLinkTarget);
- assertTrueWithPathCheck(dirLink.getRelative("a").exists(), delegator,
- dirLinkTarget.getRelative("a"));
- }
-
- @Test
- public void testCreateDirectoryCallOnEscapingSymlink() throws Exception {
- TestDelegator delegator = new TestDelegator() {
- @Override protected boolean createDirectory(Path path) {
- lastPath = path;
- return booleanState();
- }
- @Override protected boolean isDirectory(Path path, boolean followSymlinks) { return true; }
- };
- scopedFS().setDelegator(delegator);
-
- delegator.setState(false);
- assertFalseWithPathCheck(dirLink.getRelative("a").createDirectory(), delegator,
- dirLinkTarget.getRelative("a"));
-
- delegator.setState(true);
- assertTrueWithPathCheck(dirLink.getRelative("a").createDirectory(), delegator,
- dirLinkTarget.getRelative("a"));
- }
-
- @Test
- public void testDeleteCallOnEscapingSymlink() throws Exception {
- TestDelegator delegator = new TestDelegator() {
- @Override protected boolean delete(Path path) {
- lastPath = path;
- return booleanState();
- }
- @Override protected boolean isDirectory(Path path, boolean followSymlinks) { return true; }
- @Override protected long getLastModifiedTime(Path path, boolean followSymlinks) { return 0; }
- };
- scopedFS().setDelegator(delegator);
-
- delegator.setState(false);
- assertThat(fileLink.delete()).isTrue();
- assertThat(delegator.lastPath()).isNull(); // Deleting a link shouldn't require delegation.
- assertFalseWithPathCheck(dirLink.getRelative("a").delete(), delegator,
- dirLinkTarget.getRelative("a"));
-
- delegator.setState(true);
- assertTrueWithPathCheck(dirLink.getRelative("a").delete(), delegator,
- dirLinkTarget.getRelative("a"));
- }
-
- @Test
- public void testCallGetFileSizeOnEscapingSymlink() throws Exception {
- TestDelegator delegator = new TestDelegator() {
- @Override protected long getFileSize(Path path, boolean followSymlinks) {
- lastPath = path;
- return longState();
- }
- @Override protected long getLastModifiedTime(Path path, boolean followSymlinks) { return 0; }
- };
- scopedFS().setDelegator(delegator);
-
- final int state1 = 10;
- delegator.setState(state1);
- assertThat(fileLink.getFileSize()).isEqualTo(state1);
- checkPath(delegator, fileLinkTarget);
- assertThat(dirLink.getRelative("a").getFileSize()).isEqualTo(state1);
- checkPath(delegator, dirLinkTarget.getRelative("a"));
-
- final int state2 = 10;
- delegator.setState(state2);
- assertThat(fileLink.getFileSize()).isEqualTo(state2);
- checkPath(delegator, fileLinkTarget);
- assertThat(dirLink.getRelative("a").getFileSize()).isEqualTo(state2);
- checkPath(delegator, dirLinkTarget.getRelative("a"));
- }
-
- @Test
- public void testCallGetLastModifiedTimeOnEscapingSymlink() throws Exception {
- TestDelegator delegator = new TestDelegator() {
- @Override protected long getLastModifiedTime(Path path, boolean followSymlinks) {
- lastPath = path;
- return longState();
- }
- };
- scopedFS().setDelegator(delegator);
-
- final int state1 = 10;
- delegator.setState(state1);
- assertThat(fileLink.getLastModifiedTime()).isEqualTo(state1);
- checkPath(delegator, fileLinkTarget);
- assertThat(dirLink.getRelative("a").getLastModifiedTime()).isEqualTo(state1);
- checkPath(delegator, dirLinkTarget.getRelative("a"));
-
- final int state2 = 10;
- delegator.setState(state2);
- assertThat(fileLink.getLastModifiedTime()).isEqualTo(state2);
- checkPath(delegator, fileLinkTarget);
- assertThat(dirLink.getRelative("a").getLastModifiedTime()).isEqualTo(state2);
- checkPath(delegator, dirLinkTarget.getRelative("a"));
- }
-
- @Test
- public void testCallSetReadableOnEscapingSymlink() throws Exception {
- TestDelegator delegator = new TestDelegator() {
- @Override protected void setReadable(Path path, boolean readable) {
- lastPath = path;
- setState(readable);
- }
- };
- scopedFS().setDelegator(delegator);
-
- delegator.setState(false);
- fileLink.setReadable(true);
- assertThat(delegator.booleanState()).isTrue();
- checkPath(delegator, fileLinkTarget);
- fileLink.setReadable(false);
- assertThat(delegator.booleanState()).isFalse();
- checkPath(delegator, fileLinkTarget);
-
- delegator.setState(false);
- dirLink.getRelative("a").setReadable(true);
- assertThat(delegator.booleanState()).isTrue();
- checkPath(delegator, dirLinkTarget.getRelative("a"));
- dirLink.getRelative("a").setReadable(false);
- assertThat(delegator.booleanState()).isFalse();
- checkPath(delegator, dirLinkTarget.getRelative("a"));
- }
-
- @Test
- public void testCallSetWritableOnEscapingSymlink() throws Exception {
- TestDelegator delegator = new TestDelegator() {
- @Override protected void setWritable(Path path, boolean writable) {
- lastPath = path;
- setState(writable);
- }
- };
- scopedFS().setDelegator(delegator);
-
- delegator.setState(false);
- fileLink.setWritable(true);
- assertThat(delegator.booleanState()).isTrue();
- checkPath(delegator, fileLinkTarget);
- fileLink.setWritable(false);
- assertThat(delegator.booleanState()).isFalse();
- checkPath(delegator, fileLinkTarget);
-
- delegator.setState(false);
- dirLink.getRelative("a").setWritable(true);
- assertThat(delegator.booleanState()).isTrue();
- checkPath(delegator, dirLinkTarget.getRelative("a"));
- dirLink.getRelative("a").setWritable(false);
- assertThat(delegator.booleanState()).isFalse();
- checkPath(delegator, dirLinkTarget.getRelative("a"));
- }
-
- @Test
- public void testCallSetExecutableOnEscapingSymlink() throws Exception {
- TestDelegator delegator = new TestDelegator() {
- @Override protected void setReadable(Path path, boolean readable) {
- lastPath = path;
- setState(readable);
- }
- };
- scopedFS().setDelegator(delegator);
-
- delegator.setState(false);
- fileLink.setReadable(true);
- assertThat(delegator.booleanState()).isTrue();
- checkPath(delegator, fileLinkTarget);
- fileLink.setReadable(false);
- assertThat(delegator.booleanState()).isFalse();
- checkPath(delegator, fileLinkTarget);
-
- delegator.setState(false);
- dirLink.getRelative("a").setReadable(true);
- assertThat(delegator.booleanState()).isTrue();
- checkPath(delegator, dirLinkTarget.getRelative("a"));
- dirLink.getRelative("a").setReadable(false);
- assertThat(delegator.booleanState()).isFalse();
- checkPath(delegator, dirLinkTarget.getRelative("a"));
- }
-
- @Test
- public void testCallSetLastModifiedTimeOnEscapingSymlink() throws Exception {
- TestDelegator delegator = new TestDelegator() {
- @Override protected void setLastModifiedTime(Path path, long newTime) {
- lastPath = path;
- setState(newTime);
- }
- };
- scopedFS().setDelegator(delegator);
-
- delegator.setState(0);
- fileLink.setLastModifiedTime(10);
- assertThat(delegator.longState()).isEqualTo(10);
- checkPath(delegator, fileLinkTarget);
- fileLink.setLastModifiedTime(15);
- assertThat(delegator.longState()).isEqualTo(15);
- checkPath(delegator, fileLinkTarget);
-
- dirLink.getRelative("a").setLastModifiedTime(20);
- assertThat(delegator.longState()).isEqualTo(20);
- checkPath(delegator, dirLinkTarget.getRelative("a"));
- dirLink.getRelative("a").setLastModifiedTime(25);
- assertThat(delegator.longState()).isEqualTo(25);
- checkPath(delegator, dirLinkTarget.getRelative("a"));
- }
-
- @Test
- public void testCallRenameToOnEscapingSymlink() throws Exception {
- TestDelegator delegator = new TestDelegator() {
- @Override protected void renameTo(Path sourcePath, Path targetPath) {
- lastPath = sourcePath;
- setState(targetPath);
- }
- @Override protected boolean isDirectory(Path path, boolean followSymlinks) { return true; }
- };
- scopedFS().setDelegator(delegator);
-
- // Renaming a link should work fine.
- delegator.setState(null);
- fileLink.renameTo(testFS.getPath(SCOPE_ROOT).getRelative("newname"));
- assertThat(delegator.lastPath()).isNull(); // Renaming a link shouldn't require delegation.
- assertThat(delegator.objectState()).isNull();
-
- // Renaming an out-of-scope path to an in-scope path should fail due to filesystem mismatch
- // errors.
- Path newPath = testFS.getPath(SCOPE_ROOT.getRelative("blah"));
- try {
- dirLink.getRelative("a").renameTo(newPath);
- fail("This is an attempt at a cross-filesystem renaming, which should fail");
- } catch (IOException e) {
- // Expected.
- }
-
- // Renaming an out-of-scope path to another out-of-scope path can be valid.
- newPath = dirLink.getRelative("b");
- dirLink.getRelative("a").renameTo(newPath);
- assertThat(delegator.lastPath()).isEqualTo(dirLinkTarget.getRelative("a"));
- assertThat(((Path) delegator.objectState()).asFragment())
- .isEqualTo(dirLinkTarget.getRelative("b"));
- }
-
- @Test
- public void testCallCreateSymbolicLinkOnEscapingSymlink() throws Exception {
- TestDelegator delegator = new TestDelegator() {
- @Override protected void createSymbolicLink(Path linkPath, PathFragment targetFragment) {
- lastPath = linkPath;
- setState(targetFragment);
- }
- @Override protected boolean isDirectory(Path path, boolean followSymlinks) { return true; }
- };
- scopedFS().setDelegator(delegator);
-
- PathFragment newLinkTarget = PathFragment.create("/something/else");
- dirLink.getRelative("a").createSymbolicLink(newLinkTarget);
- assertThat(delegator.lastPath()).isEqualTo(dirLinkTarget.getRelative("a"));
- assertThat(delegator.objectState()).isSameAs(newLinkTarget);
- }
-
- @Test
- public void testCallReadSymbolicLinkOnEscapingSymlink() throws Exception {
- TestDelegator delegator = new TestDelegator() {
- @Override protected PathFragment readSymbolicLink(Path path) {
- lastPath = path;
- return (PathFragment) objectState;
- }
- @Override protected boolean isDirectory(Path path, boolean followSymlinks) { return true; }
- };
- scopedFS().setDelegator(delegator);
-
- // Since we're not following the link, this shouldn't invoke delegation.
- delegator.setState(PathFragment.create("whatever"));
- PathFragment p = fileLink.readSymbolicLink();
- assertThat(delegator.lastPath()).isNull();
- assertThat(p).isNotSameAs(delegator.objectState());
-
- // This should.
- p = dirLink.getRelative("a").readSymbolicLink();
- assertThat(delegator.lastPath()).isEqualTo(dirLinkTarget.getRelative("a"));
- assertThat(p).isSameAs(delegator.objectState());
- }
-
- @Test
- public void testCallGetInputStreamOnEscapingSymlink() throws Exception {
- TestDelegator delegator = new TestDelegator() {
- @Override protected InputStream getInputStream(Path path) {
- lastPath = path;
- return (InputStream) objectState;
- }
- };
- scopedFS().setDelegator(delegator);
-
- delegator.setState(new ByteArrayInputStream("blah".getBytes(UTF_8)));
- InputStream is = fileLink.getInputStream();
- assertThat(delegator.lastPath()).isEqualTo(fileLinkTarget);
- assertThat(is).isSameAs(delegator.objectState());
-
- delegator.setState(new ByteArrayInputStream("blah2".getBytes(UTF_8)));
- is = dirLink.getInputStream();
- assertThat(delegator.lastPath()).isEqualTo(dirLinkTarget);
- assertThat(is).isSameAs(delegator.objectState());
- }
-
- @Test
- public void testCallGetOutputStreamOnEscapingSymlink() throws Exception {
- TestDelegator delegator = new TestDelegator() {
- @Override protected OutputStream getOutputStream(Path path, boolean append) {
- lastPath = path;
- return (OutputStream) objectState;
- }
- @Override protected boolean isDirectory(Path path, boolean followSymlinks) { return true; }
- };
- scopedFS().setDelegator(delegator);
-
- delegator.setState(new ByteArrayOutputStream());
- OutputStream os = fileLink.getOutputStream();
- assertThat(delegator.lastPath()).isEqualTo(fileLinkTarget);
- assertThat(os).isSameAs(delegator.objectState());
-
- delegator.setState(new ByteArrayOutputStream());
- os = dirLink.getOutputStream();
- assertThat(delegator.lastPath()).isEqualTo(dirLinkTarget);
- assertThat(os).isSameAs(delegator.objectState());
- }
-
- @Test
- public void testCallGetDirectoryEntriesOnEscapingSymlink() throws Exception {
- TestDelegator delegator = new TestDelegator() {
- @Override protected Collection<Path> getDirectoryEntries(Path path) {
- lastPath = path;
- return ImmutableList.of((Path) objectState);
- }
- @Override protected boolean isDirectory(Path path, boolean followSymlinks) { return true; }
- };
- scopedFS().setDelegator(delegator);
-
- delegator.setState(testFS.getPath("/anything"));
- Collection<Path> entries = dirLink.getDirectoryEntries();
- assertThat(delegator.lastPath()).isEqualTo(dirLinkTarget);
- assertThat(entries).hasSize(1);
- assertThat(entries.iterator().next()).isSameAs(delegator.objectState());
- }
-
- /**
- * Asserts that "link" is an in-scope link that doesn't result in an out-of-FS
- * delegation. If link is relative, its path is relative to SCOPE_ROOT.
- *
- * Note that we don't actually check that the canonicalized target path matches
- * the link's target value. Such testing should be covered by
- * SymlinkAwareFileSystemTest.
- */
- private void assertInScopeLink(String link, String target, TestDelegator d) throws IOException {
- Path l = testFS.getPath(SCOPE_ROOT.getRelative(link));
- testFS.createSymbolicLink(l, PathFragment.create(target));
- l.exists();
- assertThat(d.lastPath()).isNull();
- }
-
- /**
- * Asserts that "link" is an out-of-scope link and that the re-delegated path
- * matches expectedPath. If link is relative, its path is relative to SCOPE_ROOT.
- */
- private void assertOutOfScopeLink(String link, String target, String expectedPath,
- TestDelegator d) throws IOException {
- Path l = testFS.getPath(SCOPE_ROOT.getRelative(link));
- testFS.createSymbolicLink(l, PathFragment.create(target));
- l.exists();
- assertThat(d.lastPath().getPathString()).isEqualTo(expectedPath);
- }
-
- /**
- * Returns the scope root with the final n segments chopped off (or a 0-segment path
- * if n > SCOPE_ROOT.segmentCount()).
- */
- private String chopScopeRoot(int n) {
- return SCOPE_ROOT
- .subFragment(0, n > SCOPE_ROOT.segmentCount() ? 0 : SCOPE_ROOT.segmentCount() - n)
- .getPathString();
- }
-
- /**
- * Tests that absolute symlinks with ".." and "." segments are delegated to
- * the expected paths.
- */
- @Test
- public void testAbsoluteSymlinksWithParentReferences() throws Exception {
- TestDelegator d = newExistsDelegator();
- scopedFS().setDelegator(d);
- testFS.createDirectory(testFS.getPath(SCOPE_ROOT.getRelative("dir")));
- String scopeRoot = SCOPE_ROOT.getPathString();
- String scopeBase = SCOPE_ROOT.getBaseName();
-
- // Symlinks that should never escape our scope.
- assertInScopeLink("ilink1", scopeRoot, d);
- assertInScopeLink("ilink2", scopeRoot + "/target", d);
- assertInScopeLink("ilink3", scopeRoot + "/dir/../target", d);
- assertInScopeLink("ilink4", scopeRoot + "/dir/../dir/dir2/../target", d);
- assertInScopeLink("ilink5", scopeRoot + "/./dir/.././target", d);
- assertInScopeLink("ilink6", scopeRoot + "/../" + scopeBase + "/target", d);
- assertInScopeLink("ilink7", "/some/path/../.." + scopeRoot + "/target", d);
-
- // Symlinks that should escape our scope.
- assertOutOfScopeLink("olink1", scopeRoot + "/../target", chopScopeRoot(1) + "/target", d);
- assertOutOfScopeLink("olink2", "/some/other/path", "/some/other/path", d);
- assertOutOfScopeLink("olink3", scopeRoot + "/../target", chopScopeRoot(1) + "/target", d);
- assertOutOfScopeLink("olink4", chopScopeRoot(1) + "/target", chopScopeRoot(1) + "/target", d);
- assertOutOfScopeLink("olink5", scopeRoot + "/../../../../target", "/target", d);
-
- // In-scope symlink that's not the final segment in a query.
- Path iDirLink = testFS.getPath(SCOPE_ROOT.getRelative("ilinkdir"));
- testFS.createSymbolicLink(iDirLink, SCOPE_ROOT.getRelative("dir"));
- iDirLink.getRelative("file").exists();
- assertThat(d.lastPath()).isNull();
-
- // Out-of-scope symlink that's not the final segment in a query.
- Path oDirLink = testFS.getPath(SCOPE_ROOT.getRelative("olinkdir"));
- testFS.createSymbolicLink(oDirLink, PathFragment.create("/some/other/dir"));
- oDirLink.getRelative("file").exists();
- assertThat(d.lastPath().getPathString()).isEqualTo("/some/other/dir/file");
- }
-
- /**
- * Tests that relative symlinks with ".." and "." segments are delegated to
- * the expected paths.
- */
- @Test
- public void testRelativeSymlinksWithParentReferences() throws Exception {
- TestDelegator d = newExistsDelegator();
- scopedFS().setDelegator(d);
- testFS.createDirectory(testFS.getPath(SCOPE_ROOT.getRelative("dir")));
- testFS.createDirectory(testFS.getPath(SCOPE_ROOT.getRelative("dir/dir2")));
- testFS.createDirectory(testFS.getPath(SCOPE_ROOT.getRelative("dir/dir2/dir3")));
- String scopeRoot = SCOPE_ROOT.getPathString();
- String scopeBase = SCOPE_ROOT.getBaseName();
-
- // Symlinks that should never escape our scope.
- assertInScopeLink("ilink1", "target", d);
- assertInScopeLink("ilink2", "dir/../otherdir/target", d);
- assertInScopeLink("dir/ilink3", "../target", d);
- assertInScopeLink("dir/dir2/ilink4", "../../target", d);
- assertInScopeLink("dir/dir2/ilink5", ".././../dir/./target", d);
- assertInScopeLink("dir/dir2/ilink6", "../dir2/../../dir/dir2/dir3/../../../target", d);
-
- // Symlinks that should escape our scope.
- assertOutOfScopeLink("olink1", "../target", chopScopeRoot(1) + "/target", d);
- assertOutOfScopeLink("dir/olink2", "../../target", chopScopeRoot(1) + "/target", d);
- assertOutOfScopeLink("olink3", "../" + scopeBase + "/target", scopeRoot + "/target", d);
- assertOutOfScopeLink("dir/dir2/olink5", "../../../target", chopScopeRoot(1) + "/target", d);
- assertOutOfScopeLink("dir/dir2/olink6", "../dir2/../../dir/dir2/../../../target",
- chopScopeRoot(1) + "/target", d);
- assertOutOfScopeLink("dir/olink7", "../../../target", chopScopeRoot(2) + "target", d);
- assertOutOfScopeLink("olink8", "../../../../../target", "/target", d);
-
- // In-scope symlink that's not the final segment in a query.
- Path iDirLink = testFS.getPath(SCOPE_ROOT.getRelative("dir/dir2/ilinkdir"));
- testFS.createSymbolicLink(iDirLink, PathFragment.create("../../dir"));
- iDirLink.getRelative("file").exists();
- assertThat(d.lastPath()).isNull();
-
- // Out-of-scope symlink that's not the final segment in a query.
- Path oDirLink = testFS.getPath(SCOPE_ROOT.getRelative("dir/dir2/olinkdir"));
- testFS.createSymbolicLink(oDirLink, PathFragment.create("../../../other/dir"));
- oDirLink.getRelative("file").exists();
- assertThat(d.lastPath().getPathString()).isEqualTo(chopScopeRoot(1) + "/other/dir/file");
- }
-}
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileSystemTest.java b/src/test/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileSystemTest.java
index 355d96d089..2ebe0a5dd3 100644
--- a/src/test/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileSystemTest.java
+++ b/src/test/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileSystemTest.java
@@ -21,7 +21,7 @@ import com.google.devtools.build.lib.testutil.TestThread;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
-import com.google.devtools.build.lib.vfs.ScopeEscapableFileSystemTest;
+import com.google.devtools.build.lib.vfs.SymlinkAwareFileSystemTest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
@@ -34,17 +34,15 @@ import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/**
- * Tests for {@link InMemoryFileSystem}. Note that most tests are inherited
- * from {@link ScopeEscapableFileSystemTest} and ancestors. This specific
- * file focuses only on concurrency tests.
- *
+ * Tests for {@link InMemoryFileSystem}. Note that most tests are inherited from {@link
+ * SymlinkAwareFileSystemTest} and ancestors. This specific file focuses only on concurrency tests.
*/
@RunWith(JUnit4.class)
-public class InMemoryFileSystemTest extends ScopeEscapableFileSystemTest {
+public class InMemoryFileSystemTest extends SymlinkAwareFileSystemTest {
@Override
public FileSystem getFreshFileSystem() {
- return new InMemoryFileSystem(BlazeClock.instance(), SCOPE_ROOT);
+ return new InMemoryFileSystem(BlazeClock.instance());
}
@Override