aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar tomlu <tomlu@google.com>2017-10-06 00:47:27 +0200
committerGravatar Klaus Aehlig <aehlig@google.com>2017-10-06 19:48:31 +0200
commitb021cf4b0871247bb0ad2efb76b3fd91c98c94c8 (patch)
treea15651ff48760a18255e557b957a457e6e8706f5 /src
parent2fc22de577f181a8490b13213efbe20cd3a2ae7b (diff)
Make Fdo use straight zip files, delete ZipFileSystem.
PiperOrigin-RevId: 171221156
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java153
-rw-r--r--src/main/java/com/google/devtools/build/lib/vfs/ZipFileSystem.java325
-rw-r--r--src/test/java/com/google/devtools/build/lib/vfs/ZipFileSystemTest.java229
-rw-r--r--src/test/java/com/google/devtools/build/lib/vfs/sample_with_dirs.zipbin1247 -> 0 bytes
-rw-r--r--src/test/java/com/google/devtools/build/lib/vfs/sample_without_dirs.zipbin737 -> 0 bytes
-rw-r--r--src/test/java/com/google/devtools/build/lib/vfs/util/FileSystems.java11
6 files changed, 101 insertions, 617 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java
index 31cfca5d79..24bcd7c10d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java
@@ -14,6 +14,8 @@
package com.google.devtools.build.lib.rules.cpp;
+import static java.nio.charset.StandardCharsets.ISO_8859_1;
+
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
@@ -21,6 +23,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
+import com.google.common.io.ByteSource;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.Root;
import com.google.devtools.build.lib.analysis.AnalysisEnvironment;
@@ -36,12 +39,19 @@ import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.RootedPath;
-import com.google.devtools.build.lib.vfs.ZipFileSystem;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.LipoMode;
import com.google.devtools.build.skyframe.SkyFunction;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.util.Collection;
+import java.util.Enumeration;
+import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
/**
* Support class for FDO (feedback directed optimization) and LIPO (lightweight inter-procedural
@@ -142,12 +152,6 @@ public class FdoSupport {
}
/**
- * Path within profile data .zip files that is considered the root of the
- * profile information directory tree.
- */
- private static final PathFragment ZIP_ROOT = PathFragment.create("/");
-
- /**
* Returns true if the given fdoFile represents an AutoFdo profile.
*/
public static final boolean isAutoFdo(String fdoFile) {
@@ -359,21 +363,36 @@ public class FdoSupport {
} else {
// Path objects referring to inside the zip file are only valid within this try block.
// FdoZipContents doesn't reference any of them, so we are fine.
- try (ZipFileSystem zipFileSystem = new ZipFileSystem(fdoProfile)) {
- Path zipFilePath = zipFileSystem.getRootDirectory();
- String outputSymlinkName = productName + "-out";
- if (!zipFilePath.getRelative(outputSymlinkName).isDirectory()) {
- throw new ZipException(
- "FDO zip files must be zipped directly above '"
- + outputSymlinkName
- + "' for the compiler to find the profile");
+ if (!fdoProfile.exists()) {
+ throw new FileNotFoundException(String.format("File '%s' does not exist", fdoProfile));
+ }
+ File zipIoFile = fdoProfile.getPathFile();
+ File tempFile = null;
+ try {
+ // If it doesn't exist, we're dealing with an in-memory fs for testing
+ // Copy the file and delete later
+ if (!zipIoFile.exists()) {
+ tempFile = File.createTempFile("bazel.test.", ".tmp");
+ zipIoFile = tempFile;
+ byte[] contents = FileSystemUtils.readContent(fdoProfile);
+ try (OutputStream os = new FileOutputStream(tempFile)) {
+ os.write(contents);
+ }
+ }
+ try (ZipFile zipFile = new ZipFile(zipIoFile)) {
+ String outputSymlinkName = productName + "-out";
+ ImmutableSet.Builder<PathFragment> gcdaFilesBuilder = ImmutableSet.builder();
+ ImmutableMultimap.Builder<PathFragment, PathFragment> importsBuilder =
+ ImmutableMultimap.builder();
+ extractFdoZipDirectory(
+ zipFile, fdoDirPath, outputSymlinkName, gcdaFilesBuilder, importsBuilder);
+ gcdaFiles = gcdaFilesBuilder.build();
+ imports = importsBuilder.build();
+ }
+ } finally {
+ if (tempFile != null) {
+ tempFile.delete();
}
- ImmutableSet.Builder<PathFragment> gcdaFilesBuilder = ImmutableSet.builder();
- ImmutableMultimap.Builder<PathFragment, PathFragment> importsBuilder =
- ImmutableMultimap.builder();
- extractFdoZipDirectory(zipFilePath, fdoDirPath, gcdaFilesBuilder, importsBuilder);
- gcdaFiles = gcdaFilesBuilder.build();
- imports = importsBuilder.build();
}
}
}
@@ -382,65 +401,95 @@ public class FdoSupport {
}
/**
- * Recursively extracts a directory from the GCDA ZIP file into a target
- * directory.
+ * Recursively extracts a directory from the GCDA ZIP file into a target directory.
*
- * <p>Imports files are not written to disk. Their content is directly added
- * to an internal data structure.
+ * <p>Imports files are not written to disk. Their content is directly added to an internal data
+ * structure.
*
- * <p>The files are written at $EXECROOT/blaze-fdo/_fdo/(base name of profile zip), and the
- * {@code _fdo} directory there is symlinked to from the exec root, so that the file are also
- * available at $EXECROOT/_fdo/..., which is their exec path. We need to jump through these
- * hoops because the FDO root 1. needs to be a source root, thus the exec path of its root is
- * ".", 2. it must not be equal to the exec root so that the artifact factory does not get
- * confused, 3. the files under it must be reachable by their exec path from the exec root.
+ * <p>The files are written at $EXECROOT/blaze-fdo/_fdo/(base name of profile zip), and the {@code
+ * _fdo} directory there is symlinked to from the exec root, so that the file are also available
+ * at $EXECROOT/_fdo/..., which is their exec path. We need to jump through these hoops because
+ * the FDO root 1. needs to be a source root, thus the exec path of its root is ".", 2. it must
+ * not be equal to the exec root so that the artifact factory does not get confused, 3. the files
+ * under it must be reachable by their exec path from the exec root.
*
* @throws IOException if any of the I/O operations failed
* @throws FdoException if the FDO ZIP contains a file of unknown type
*/
- private static void extractFdoZipDirectory(Path sourceDir, Path targetDir,
+ private static void extractFdoZipDirectory(
+ ZipFile zipFile,
+ Path targetDir,
+ String outputSymlinkName,
ImmutableSet.Builder<PathFragment> gcdaFilesBuilder,
ImmutableMultimap.Builder<PathFragment, PathFragment> importsBuilder)
- throws IOException, FdoException {
- for (Path sourceFile : sourceDir.getDirectoryEntries()) {
- Path targetFile = targetDir.getRelative(sourceFile.getBaseName());
- if (sourceFile.isDirectory()) {
- targetFile.createDirectory();
- extractFdoZipDirectory(sourceFile, targetFile, gcdaFilesBuilder, importsBuilder);
- } else {
- if (CppFileTypes.COVERAGE_DATA.matches(sourceFile)) {
- FileSystemUtils.copyFile(sourceFile, targetFile);
- gcdaFilesBuilder.add(
- sourceFile.relativeTo(sourceFile.getFileSystem().getRootDirectory()));
- } else if (CppFileTypes.COVERAGE_DATA_IMPORTS.matches(sourceFile)) {
- readCoverageImports(sourceFile, importsBuilder);
+ throws IOException, FdoException {
+ Enumeration<? extends ZipEntry> zipEntries = zipFile.entries();
+ while (zipEntries.hasMoreElements()) {
+ ZipEntry zipEntry = zipEntries.nextElement();
+ if (zipEntry.isDirectory()) {
+ continue;
+ }
+ String name = zipEntry.getName();
+ if (!name.startsWith(outputSymlinkName)) {
+ throw new ZipException(
+ "FDO zip files must be zipped directly above '"
+ + outputSymlinkName
+ + "' for the compiler to find the profile");
+ }
+ Path targetFile = targetDir.getRelative(name);
+ FileSystemUtils.createDirectoryAndParents(targetFile.getParentDirectory());
+ if (CppFileTypes.COVERAGE_DATA.matches(name)) {
+ try (OutputStream out = targetFile.getOutputStream()) {
+ new ZipByteSource(zipFile, zipEntry).copyTo(out);
}
+ targetFile.setLastModifiedTime(zipEntry.getTime());
+ targetFile.setWritable(false);
+ targetFile.setExecutable(false);
+ gcdaFilesBuilder.add(PathFragment.create(name));
+ } else if (CppFileTypes.COVERAGE_DATA_IMPORTS.matches(name)) {
+ readCoverageImports(zipFile, zipEntry, importsBuilder);
}
}
}
+ private static class ZipByteSource extends ByteSource {
+ final ZipFile zipFile;
+ final ZipEntry zipEntry;
+
+ ZipByteSource(ZipFile zipFile, ZipEntry zipEntry) {
+ this.zipFile = zipFile;
+ this.zipEntry = zipEntry;
+ }
+
+ @Override
+ public InputStream openStream() throws IOException {
+ return zipFile.getInputStream(zipEntry);
+ }
+ }
/**
* Reads a .gcda.imports file and stores the imports information.
*
* @throws FdoException if an auxiliary LIPO input was not found
*/
- private static void readCoverageImports(Path importsFile,
+ private static void readCoverageImports(
+ ZipFile zipFile,
+ ZipEntry importsFile,
ImmutableMultimap.Builder<PathFragment, PathFragment> importsBuilder)
- throws IOException, FdoException {
- PathFragment key = importsFile.asFragment().relativeTo(ZIP_ROOT);
+ throws IOException, FdoException {
+ PathFragment key = PathFragment.create(importsFile.getName());
String baseName = key.getBaseName();
String ext = Iterables.getOnlyElement(CppFileTypes.COVERAGE_DATA_IMPORTS.getExtensions());
key = key.replaceName(baseName.substring(0, baseName.length() - ext.length()));
-
- for (String line : FileSystemUtils.iterateLinesAsLatin1(importsFile)) {
+ for (String line :
+ new ZipByteSource(zipFile, importsFile).asCharSource(ISO_8859_1).readLines()) {
if (!line.isEmpty()) {
// We can't yet fully check the validity of a line. this is done later
// when we actually parse the contained paths.
PathFragment execPath = PathFragment.create(line);
if (execPath.isAbsolute()) {
- throw new FdoException("Absolute paths not allowed in gcda imports file " + importsFile
- + ": " + execPath);
+ throw new FdoException(
+ "Absolute paths not allowed in gcda imports file " + importsFile + ": " + execPath);
}
importsBuilder.put(key, PathFragment.create(line));
}
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/ZipFileSystem.java b/src/main/java/com/google/devtools/build/lib/vfs/ZipFileSystem.java
deleted file mode 100644
index 92117434b2..0000000000
--- a/src/main/java/com/google/devtools/build/lib/vfs/ZipFileSystem.java
+++ /dev/null
@@ -1,325 +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 com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible;
-import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
-import com.google.devtools.build.lib.util.Preconditions;
-import com.google.devtools.build.lib.vfs.Path.PathFactory;
-import java.io.Closeable;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.logging.Logger;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-/**
- * A FileSystem that provides a read-only filesystem view on a zip file.
- * Inherits the constraints imposed by ReadonlyFileSystem.
- */
-@ThreadCompatible // Can only be accessed from one thread at a time (including its Path objects)
-public class ZipFileSystem extends ReadonlyFileSystem implements Closeable {
- private static final Logger logger = Logger.getLogger(ZipFileSystem.class.getName());
-
- private final File tempFile; // In case this needs to be written to the file system
- private final ZipFile zipFile;
- private boolean open;
-
- /**
- * The sole purpose of this field is to hold a strong reference to all leaf
- * {@link Path}s which have a non-null "entry" field, preventing them from
- * being garbage-collected. (The leaf paths hold string references to their
- * parents, so we don't need to include them here.)
- *
- * <p>This is necessary because {@link Path}s may be recycled when they
- * become unreachable, but the ZipFileSystem uses them to hold the {@link
- * ZipEntry} for that path, if any. Without this additional strong
- * reference, ZipEntries would seem to "disappear" during garbage collection.
- */
- @SuppressWarnings("unused")
- private final Object paths;
-
- /**
- * Constructs a ZipFileSystem from a zip file identified with a given path.
- */
- public ZipFileSystem(Path zipPath) throws IOException {
- if (!zipPath.exists()) {
- throw new FileNotFoundException(String.format("File '%s' does not exist", zipPath));
- }
-
- File file = zipPath.getPathFile();
- if (!file.exists()) {
- // If the File says that it does not exist but the Path says that it does, we are probably
- // dealing with a FileSystem that does not represent the actual file system we are running
- // under. Then we copy the Path into a temporary File.
- tempFile = File.createTempFile("bazel.test.", ".tmp");
- file = tempFile;
- byte[] contents = FileSystemUtils.readContent(zipPath);
- try (OutputStream os = new FileOutputStream(tempFile)) {
- os.write(contents);
- }
- } else {
- tempFile = null;
- }
-
- if (!file.isFile()) {
- throw new IOException(String.format("'%s' is not a file", zipPath));
- }
- if (!file.canRead()) {
- throw new IOException(String.format("File '%s' is not readable", zipPath));
- }
-
- this.zipFile = new ZipFile(file);
- this.paths = populatePathTree();
- this.open = true;
- }
-
- // ZipPath extends Path with a set-once ZipEntry field.
- // TODO(bazel-team): (2009) Delete class ZipPath, and perform the
- // Path-to-ZipEntry lookup in {@link #zipEntry} and {@link
- // #getDirectoryEntries}. Then this field becomes redundant.
- @ThreadSafe
- private static class ZipPath extends Path {
-
- private enum Factory implements PathFactory {
- INSTANCE {
- @Override
- public Path createRootPath(FileSystem filesystem) {
- Preconditions.checkArgument(filesystem instanceof ZipFileSystem);
- return new ZipPath((ZipFileSystem) filesystem);
- }
-
- @Override
- public Path createChildPath(Path parent, String childName) {
- Preconditions.checkState(parent instanceof ZipPath);
- return new ZipPath((ZipFileSystem) parent.getFileSystem(), childName, (ZipPath) parent);
- }
-
- @Override
- public Path getCachedChildPathInternal(Path path, String childName) {
- return Path.getCachedChildPathInternal(path, childName, /*cacheable=*/ true);
- }
- };
- }
-
- /**
- * Non-null iff this file/directory exists. Set by setZipEntry for files
- * explicitly mentioned in the zipfile's table of contents, or implicitly
- * an ancestor of them.
- */
- ZipEntry entry = null;
-
- // Root path.
- private ZipPath(ZipFileSystem fileSystem) {
- super(fileSystem);
- }
-
- // Non-root paths.
- private ZipPath(ZipFileSystem fileSystem, String name, ZipPath parent) {
- super(fileSystem, name, parent);
- }
-
- void setZipEntry(ZipEntry entry) {
- if (this.entry != null) {
- throw new IllegalStateException("setZipEntry(" + entry
- + ") called twice!");
- }
- this.entry = entry;
-
- // Ensure all parents of this path have a directory ZipEntry:
- for (ZipPath path = (ZipPath) getParentDirectory();
- path != null && path.entry == null;
- path = (ZipPath) path.getParentDirectory()) {
- // Note, the ZipEntry for the root path is called "//", but that's ok.
- path.setZipEntry(new ZipEntry(path + "/")); // trailing "/" => isDir
- }
- }
- }
-
- /**
- * Scans the Zip file and associates a ZipEntry with each filename
- * (ZipPath) that is mentioned in the table of contents. Returns a
- * collection of all corresponding Paths.
- */
- private Collection<Path> populatePathTree() {
- Collection<Path> paths = new ArrayList<>();
- for (ZipEntry entry : Collections.list(zipFile.entries())) {
- PathFragment frag = PathFragment.create(entry.getName());
- Path path = rootPath.getRelative(frag);
- paths.add(path);
- ((ZipPath) path).setZipEntry(entry);
- }
- return paths;
- }
-
- @Override
- public String getFileSystemType(Path path) {
- return "zipfs";
- }
-
- @Override
- protected PathFactory getPathFactory() {
- return ZipPath.Factory.INSTANCE;
- }
-
- /** Returns the ZipEntry associated with a given path name, if any. */
- private static ZipEntry zipEntry(Path path) {
- return ((ZipPath) path).entry;
- }
-
- /** Like zipEntry, but throws FileNotFoundException unless path exists. */
- private static ZipEntry zipEntryNonNull(Path path)
- throws FileNotFoundException {
- ZipEntry zipEntry = zipEntry(path);
- if (zipEntry == null) {
- throw new FileNotFoundException(path + " (No such file or directory)");
- }
- return zipEntry;
- }
-
- @Override
- protected InputStream getInputStream(Path path) throws IOException {
- Preconditions.checkState(open);
- return zipFile.getInputStream(zipEntryNonNull(path));
- }
-
- @Override
- protected Collection<Path> getDirectoryEntries(Path path)
- throws IOException {
- Preconditions.checkState(open);
- zipEntryNonNull(path);
- final Collection<Path> result = new ArrayList<>();
- ((ZipPath) path)
- .applyToChildren(
- child -> {
- if (zipEntry(child) != null) {
- result.add(child);
- }
- return true;
- });
- return result;
- }
-
- @Override
- protected boolean exists(Path path, boolean followSymlinks) {
- Preconditions.checkState(open);
- return zipEntry(path) != null;
- }
-
- @Override
- protected boolean isDirectory(Path path, boolean followSymlinks) {
- Preconditions.checkState(open);
- ZipEntry entry = zipEntry(path);
- return entry != null && entry.isDirectory();
- }
-
- @Override
- protected boolean isFile(Path path, boolean followSymlinks) {
- Preconditions.checkState(open);
- ZipEntry entry = zipEntry(path);
- return entry != null && !entry.isDirectory();
- }
-
- @Override
- protected boolean isSpecialFile(Path path, boolean followSymlinks) {
- Preconditions.checkState(open);
- return false;
- }
-
- @Override
- protected boolean isReadable(Path path) throws IOException {
- Preconditions.checkState(open);
- zipEntryNonNull(path);
- return true;
- }
-
- @Override
- protected boolean isWritable(Path path) throws IOException {
- Preconditions.checkState(open);
- zipEntryNonNull(path);
- return false;
- }
-
- @Override
- protected boolean isExecutable(Path path) throws IOException {
- Preconditions.checkState(open);
- zipEntryNonNull(path);
- return false;
- }
-
- @Override
- protected PathFragment readSymbolicLink(Path path) throws IOException {
- Preconditions.checkState(open);
- zipEntryNonNull(path);
- throw new NotASymlinkException(path);
- }
-
- @Override
- protected long getFileSize(Path path, boolean followSymlinks)
- throws IOException {
- Preconditions.checkState(open);
- return zipEntryNonNull(path).getSize();
- }
-
- @Override
- protected long getLastModifiedTime(Path path, boolean followSymlinks)
- throws FileNotFoundException {
- Preconditions.checkState(open);
- return zipEntryNonNull(path).getTime();
- }
-
- @Override
- protected boolean isSymbolicLink(Path path) {
- Preconditions.checkState(open);
- return false;
- }
-
- @Override
- protected FileStatus statIfFound(Path path, boolean followSymlinks) {
- Preconditions.checkState(open);
- try {
- return stat(path, followSymlinks);
- } catch (FileNotFoundException e) {
- return null;
- } catch (IOException e) {
- // getLastModifiedTime can only throw FileNotFoundException, which is what stat uses.
- throw new IllegalStateException (e);
- }
- }
-
- @Override
- public void close() {
- if (open) {
- try {
- zipFile.close();
- } catch (IOException e) {
- // Not a lot can be done about this. Log an error and move on.
- logger.warning(
- String.format(
- "Error while closing zip file '%s': %s", zipFile.getName(), e.getMessage()));
- }
- if (tempFile != null) {
- tempFile.delete();
- }
- open = false;
- }
- }
-}
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/ZipFileSystemTest.java b/src/test/java/com/google/devtools/build/lib/vfs/ZipFileSystemTest.java
deleted file mode 100644
index c097fc4928..0000000000
--- a/src/test/java/com/google/devtools/build/lib/vfs/ZipFileSystemTest.java
+++ /dev/null
@@ -1,229 +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.Lists;
-import com.google.common.io.CharStreams;
-import com.google.devtools.build.lib.testutil.BlazeTestUtils;
-import com.google.devtools.build.lib.testutil.TestConstants;
-import com.google.devtools.build.lib.vfs.util.FileSystems;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-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;
-
-@RunWith(JUnit4.class)
-public class ZipFileSystemTest {
-
- /**
- * Expected listing of sample zip files, in alpha sorted order
- */
- private static final String[] LISTING = {
- "/dir1",
- "/dir1/file1a",
- "/dir1/file1b",
- "/dir2",
- "/dir2/dir3",
- "/dir2/dir3/dir4",
- "/dir2/dir3/dir4/file4",
- "/dir2/file2",
- "/file0",
- };
-
- private FileSystem zipFS1;
- private FileSystem zipFS2;
-
- @Before
- public final void initializeFileSystems() throws Exception {
- FileSystem unixFs = FileSystems.getNativeFileSystem();
- Path testdataDir = unixFs.getPath(BlazeTestUtils.runfilesDir()).getRelative(
- TestConstants.JAVATESTS_ROOT + "/com/google/devtools/build/lib/vfs");
- Path zPath1 = testdataDir.getChild("sample_with_dirs.zip");
- Path zPath2 = testdataDir.getChild("sample_without_dirs.zip");
- zipFS1 = new ZipFileSystem(zPath1);
- zipFS2 = new ZipFileSystem(zPath2);
- }
-
- private void checkExists(FileSystem fs) {
- assertThat(fs.getPath("/dir2/dir3/dir4").exists()).isTrue();
- assertThat(fs.getPath("/dir2/dir3/dir4/file4").exists()).isTrue();
- assertThat(fs.getPath("/dir2/dir3/dir4/bogus").exists()).isFalse();
- }
-
- @Test
- public void testExists() {
- checkExists(zipFS1);
- checkExists(zipFS2);
- }
-
- private void checkIsFile(FileSystem fs) {
- assertThat(fs.getPath("/dir2/dir3/dir4").isFile()).isFalse();
- assertThat(fs.getPath("/dir2/dir3/dir4/file4").isFile()).isTrue();
- assertThat(fs.getPath("/dir2/dir3/dir4/bogus").isFile()).isFalse();
- }
-
- @Test
- public void testIsFile() {
- checkIsFile(zipFS1);
- checkIsFile(zipFS2);
- }
-
- private void checkIsDir(FileSystem fs) {
- assertThat(fs.getPath("/dir2/dir3/dir4").isDirectory()).isTrue();
- assertThat(fs.getPath("/dir2/dir3/dir4/file4").isDirectory()).isFalse();
- assertThat(fs.getPath("/bogus/mobogus").isDirectory()).isFalse();
- assertThat(fs.getPath("/bogus").isDirectory()).isFalse();
- }
-
- @Test
- public void testIsDir() {
- checkIsDir(zipFS1);
- checkIsDir(zipFS2);
- }
-
- /**
- * Recursively add the contents of a given path, rendered as strings, into a
- * given list.
- */
- private static void listChildren(Path p, List<String> list)
- throws IOException {
- for (Path c : p.getDirectoryEntries()) {
- list.add(c.getPathString());
- if (c.isDirectory()) {
- listChildren(c, list);
- }
- }
- }
-
- private void checkListing(FileSystem fs) throws Exception {
- List<String> list = new ArrayList<>();
- listChildren(fs.getRootDirectory(), list);
- Collections.sort(list);
- assertThat(list).isEqualTo(Lists.newArrayList(LISTING));
- }
-
- @Test
- public void testListing() throws Exception {
- checkListing(zipFS1);
- checkListing(zipFS2);
-
- // Regression test for: creation of a path (i.e. a file *name*)
- // must not affect the result of getDirectoryEntries().
- zipFS1.getPath("/dir1/notthere");
- checkListing(zipFS1);
- }
-
- private void checkFileSize(FileSystem fs, String name, long expectedSize)
- throws IOException {
- assertThat(fs.getPath(name).getFileSize()).isEqualTo(expectedSize);
- }
-
- @Test
- public void testCanReadRoot() {
- Path rootDirectory = zipFS1.getRootDirectory();
- assertThat(rootDirectory.isDirectory()).isTrue();
- }
-
- @Test
- public void testFileSize() throws IOException {
- checkFileSize(zipFS1, "/dir1/file1a", 5);
- checkFileSize(zipFS2, "/dir1/file1a", 5);
- checkFileSize(zipFS1, "/dir2/dir3/dir4/file4", 5000);
- checkFileSize(zipFS2, "/dir2/dir3/dir4/file4", 5000);
- }
-
- private void checkCantGetFileSize(FileSystem fs, String name) {
- try {
- fs.getPath(name).getFileSize();
- fail();
- } catch (IOException expected) {
- // expected
- }
- }
-
- @Test
- public void testCantGetFileSize() {
- checkCantGetFileSize(zipFS1, "/dir2/dir3/dir4/bogus");
- checkCantGetFileSize(zipFS2, "/dir2/dir3/dir4/bogus");
- }
-
- private void checkOpenFile(FileSystem fs, String name, int expectedSize)
- throws Exception {
- InputStream is = fs.getPath(name).getInputStream();
- List<String> lines = CharStreams.readLines(new InputStreamReader(is, "ISO-8859-1"));
- assertThat(lines).hasSize(expectedSize);
- for (int i = 0; i < expectedSize; i++) {
- assertThat(lines.get(i)).isEqualTo("body");
- }
- }
-
- @Test
- public void testOpenSmallFile() throws Exception {
- checkOpenFile(zipFS1, "/dir1/file1a", 1);
- checkOpenFile(zipFS2, "/dir1/file1a", 1);
- }
-
- @Test
- public void testOpenBigFile() throws Exception {
- checkOpenFile(zipFS1, "/dir2/dir3/dir4/file4", 1000);
- checkOpenFile(zipFS2, "/dir2/dir3/dir4/file4", 1000);
- }
-
- private void checkCantOpenFile(FileSystem fs, String name) {
- try {
- fs.getPath(name).getInputStream();
- fail();
- } catch (IOException expected) {
- // expected
- }
- }
-
- @Test
- public void testCantOpenFile() throws Exception {
- checkCantOpenFile(zipFS1, "/dir2/dir3/dir4/bogus");
- checkCantOpenFile(zipFS2, "/dir2/dir3/dir4/bogus");
- }
-
- private void checkCantCreateAnything(FileSystem fs, String name) {
- Path p = fs.getPath(name);
- try {
- p.createDirectory();
- fail();
- } catch (Exception expected) {}
- try {
- FileSystemUtils.createEmptyFile(p);
- fail();
- } catch (Exception expected) {}
- try {
- p.createSymbolicLink(p);
- fail();
- } catch (Exception expected) {}
- }
-
- @Test
- public void testCantCreateAnything() throws Exception {
- checkCantCreateAnything(zipFS1, "/dir2/dir3/dir4/new");
- checkCantCreateAnything(zipFS2, "/dir2/dir3/dir4/new");
- }
-
-}
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/sample_with_dirs.zip b/src/test/java/com/google/devtools/build/lib/vfs/sample_with_dirs.zip
deleted file mode 100644
index 22ff63cd32..0000000000
--- a/src/test/java/com/google/devtools/build/lib/vfs/sample_with_dirs.zip
+++ /dev/null
Binary files differ
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/sample_without_dirs.zip b/src/test/java/com/google/devtools/build/lib/vfs/sample_without_dirs.zip
deleted file mode 100644
index f3ec5ab792..0000000000
--- a/src/test/java/com/google/devtools/build/lib/vfs/sample_without_dirs.zip
+++ /dev/null
Binary files differ
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/util/FileSystems.java b/src/test/java/com/google/devtools/build/lib/vfs/util/FileSystems.java
index f7e6d6cb6e..17beb85bbc 100644
--- a/src/test/java/com/google/devtools/build/lib/vfs/util/FileSystems.java
+++ b/src/test/java/com/google/devtools/build/lib/vfs/util/FileSystems.java
@@ -20,12 +20,9 @@ import com.google.devtools.build.lib.unix.UnixFileSystem;
import com.google.devtools.build.lib.util.OS;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.JavaIoFileSystem;
-import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.UnionFileSystem;
-import com.google.devtools.build.lib.vfs.ZipFileSystem;
import com.google.devtools.build.lib.windows.WindowsFileSystem;
-import java.io.IOException;
import java.util.Map;
/**
@@ -100,12 +97,4 @@ public final class FileSystems {
}
return defaultUnionFileSystem;
}
-
- /**
- * Returns a new instance of a simple {@link FileSystem} implementation that
- * presents the contents of a zip file as a read-only file system view.
- */
- public static FileSystem getZipFileSystem(Path zipFile) throws IOException {
- return new ZipFileSystem(zipFile);
- }
}