aboutsummaryrefslogtreecommitdiff
path: root/jimfs/src
diff options
context:
space:
mode:
authorColin Decker <cgdecker@google.com>2014-03-14 18:10:11 -0400
committerColin Decker <cgdecker@google.com>2014-03-14 18:10:11 -0400
commit378dffb33f14d4a43692613215630967976909bd (patch)
tree599705bfb74e620d2468b1921bc2a6f68211f35b /jimfs/src
parent5e78b27e7565161faeed5df214c6448d99dece18 (diff)
downloadjimfs-378dffb33f14d4a43692613215630967976909bd.tar.gz
Add tests for moving and copying files from one JimfsFileSystem to another (moves/copies to FileSystems with different FileSystemProviders are handled by the Files class itself). Also fix an issue where attributes other than basic attributes were being copied from one file to a file on a different file system when COPY_ATTRIBUTES was specified--there's no guarantee that the other file system will support all the file attribute views the source file system does.
------------- Created by MOE: http://code.google.com/p/moe-java MOE_MIGRATED_REVID=63161492
Diffstat (limited to 'jimfs/src')
-rw-r--r--jimfs/src/main/java/com/google/jimfs/AttributeCopyOption.java32
-rw-r--r--jimfs/src/main/java/com/google/jimfs/AttributeService.java20
-rw-r--r--jimfs/src/main/java/com/google/jimfs/FileSystemView.java33
-rw-r--r--jimfs/src/main/java/com/google/jimfs/JimfsFileStore.java17
-rw-r--r--jimfs/src/test/java/com/google/jimfs/JimfsUnixLikeFileSystemTest.java82
5 files changed, 147 insertions, 37 deletions
diff --git a/jimfs/src/main/java/com/google/jimfs/AttributeCopyOption.java b/jimfs/src/main/java/com/google/jimfs/AttributeCopyOption.java
new file mode 100644
index 0000000..2ae5eaf
--- /dev/null
+++ b/jimfs/src/main/java/com/google/jimfs/AttributeCopyOption.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * 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.jimfs;
+
+/**
+ * Options for how to handle copying of file attributes when copying a file.
+ *
+ * @author Colin Decker
+ */
+enum AttributeCopyOption {
+ /** Copy all attributes on the file. */
+ ALL,
+ /** Copy only the basic attributes (file times) of the file. */
+ BASIC,
+ /** Do not copy any of the file's attributes. */
+ NONE
+}
+
diff --git a/jimfs/src/main/java/com/google/jimfs/AttributeService.java b/jimfs/src/main/java/com/google/jimfs/AttributeService.java
index 8787775..d28eb84 100644
--- a/jimfs/src/main/java/com/google/jimfs/AttributeService.java
+++ b/jimfs/src/main/java/com/google/jimfs/AttributeService.java
@@ -181,17 +181,19 @@ final class AttributeService {
}
/**
- * Copies the file times of the given file to the given copy file.
- */
- public void copyBasicAttributes(File file, File copy) {
- file.copyBasicAttributes(copy);
- }
-
- /**
* Copies the attributes of the given file to the given copy file.
*/
- public void copyAttributes(File file, File copy) {
- file.copyAttributes(copy);
+ public void copyAttributes(File file, File copy, AttributeCopyOption copyOption) {
+ switch (copyOption) {
+ case ALL:
+ file.copyAttributes(copy);
+ break;
+ case BASIC:
+ file.copyBasicAttributes(copy);
+ break;
+ default:
+ // don't copy
+ }
}
/**
diff --git a/jimfs/src/main/java/com/google/jimfs/FileSystemView.java b/jimfs/src/main/java/com/google/jimfs/FileSystemView.java
index 2418058..42cf8b2 100644
--- a/jimfs/src/main/java/com/google/jimfs/FileSystemView.java
+++ b/jimfs/src/main/java/com/google/jimfs/FileSystemView.java
@@ -572,20 +572,35 @@ final class FileSystemView {
}
}
- // can only do an actual move within one file system instance
- // otherwise we have to copy and delete
if (move && sameFileSystem) {
+ // Real move on the same file system.
sourceParent.unlink(source.name());
sourceParent.updateModifiedTime();
destParent.link(dest.name(), sourceFile);
destParent.updateModifiedTime();
} else {
- // copy
- boolean copyAttributes = options.contains(COPY_ATTRIBUTES) && !move;
+ // Doing a copy OR a move to a different file system, which must be implemented by copy and
+ // delete.
- // copy the file, but don't copy its content while we're holding the file store locks
- copyFile = destView.store.copyWithoutContent(sourceFile, copyAttributes);
+ // By default, don't copy attributes.
+ AttributeCopyOption attributeCopyOption = AttributeCopyOption.NONE;
+ if (move) {
+ // Copy only the basic attributes of the file to the other file system, as it may not
+ // support all the attribute views that this file system does. This also matches the
+ // behavior of moving a file to a foreign file system with a different
+ // FileSystemProvider.
+ attributeCopyOption = AttributeCopyOption.BASIC;
+ } else if (options.contains(COPY_ATTRIBUTES)) {
+ // As with move, if we're copying the file to a different file system, only copy its
+ // basic attributes.
+ attributeCopyOption = sameFileSystem
+ ? AttributeCopyOption.ALL
+ : AttributeCopyOption.BASIC;
+ }
+
+ // Copy the file, but don't copy its content while we're holding the file store locks.
+ copyFile = destView.store.copyWithoutContent(sourceFile, attributeCopyOption);
destParent.link(dest.name(), copyFile);
destParent.updateModifiedTime();
@@ -597,10 +612,8 @@ final class FileSystemView {
lockSourceAndCopy(sourceFile, copyFile);
if (move) {
- store.copyBasicAttributes(sourceFile, copyFile);
-
- // it should not be possible for delete to throw an exception here, because we already
- // checked that the file was deletable above
+ // It should not be possible for delete to throw an exception here, because we already
+ // checked that the file was deletable above.
delete(sourceEntry, DeleteMode.ANY, source);
}
}
diff --git a/jimfs/src/main/java/com/google/jimfs/JimfsFileStore.java b/jimfs/src/main/java/com/google/jimfs/JimfsFileStore.java
index 4819fe2..fe2dedc 100644
--- a/jimfs/src/main/java/com/google/jimfs/JimfsFileStore.java
+++ b/jimfs/src/main/java/com/google/jimfs/JimfsFileStore.java
@@ -148,15 +148,13 @@ final class JimfsFileStore extends FileStore {
}
/**
- * Creates a copy of the given file, copying its attributes as well if copy attributes is true.
- * Returns the copy.
+ * Creates a copy of the given file, copying its attributes as well according to the given
+ * {@code attributeCopyOption}.
*/
- File copyWithoutContent(File file, boolean copyAttributes) throws IOException {
+ File copyWithoutContent(File file, AttributeCopyOption attributeCopyOption) throws IOException {
File copy = factory.copyWithoutContent(file);
setInitialAttributes(copy);
- if (copyAttributes) {
- attributes.copyAttributes(file, copy);
- }
+ attributes.copyAttributes(file, copy, attributeCopyOption);
return copy;
}
@@ -169,13 +167,6 @@ final class JimfsFileStore extends FileStore {
}
/**
- * Copies the basic attributes (just file times) of the given file to the given copy file.
- */
- void copyBasicAttributes(File file, File copy) {
- attributes.copyBasicAttributes(file, copy);
- }
-
- /**
* Returns an attribute view of the given type for the given file lookup callback, or
* {@code null} if the view type is not supported.
*/
diff --git a/jimfs/src/test/java/com/google/jimfs/JimfsUnixLikeFileSystemTest.java b/jimfs/src/test/java/com/google/jimfs/JimfsUnixLikeFileSystemTest.java
index 48777e7..06552e8 100644
--- a/jimfs/src/test/java/com/google/jimfs/JimfsUnixLikeFileSystemTest.java
+++ b/jimfs/src/test/java/com/google/jimfs/JimfsUnixLikeFileSystemTest.java
@@ -110,13 +110,15 @@ import java.util.regex.PatternSyntaxException;
@RunWith(JUnit4.class)
public class JimfsUnixLikeFileSystemTest extends AbstractJimfsIntegrationTest {
+ private static final Configuration UNIX_CONFIGURATION = Configuration.unix().toBuilder()
+ .setAttributeViews("basic", "owner", "posix", "unix")
+ .setMaxSize(1024 * 1024 * 1024) // 1 GB
+ .setMaxCacheSize(256 * 1024 * 1024) // 256 MB
+ .build();
+
@Override
protected FileSystem createFileSystem() {
- return Jimfs.newFileSystem("unix", Configuration.unix().toBuilder()
- .setAttributeViews("basic", "owner", "posix", "unix")
- .setMaxSize(1024 * 1024 * 1024) // 1 GB
- .setMaxCacheSize(256 * 1024 * 1024) // 256 MB
- .build());
+ return Jimfs.newFileSystem("unix", UNIX_CONFIGURATION);
}
@Test
@@ -1681,6 +1683,55 @@ public class JimfsUnixLikeFileSystemTest extends AbstractJimfsIntegrationTest {
}
@Test
+ public void testCopy_toDifferentFileSystem() throws IOException {
+ try (FileSystem fs2 = Jimfs.newFileSystem(UNIX_CONFIGURATION)) {
+ Path foo = fs.getPath("/foo");
+ byte[] bytes = {0, 1, 2, 3, 4};
+ Files.write(foo, bytes);
+
+ Path foo2 = fs2.getPath("/foo");
+ Files.copy(foo, foo2);
+
+ assertThat(foo).exists();
+ assertThat(foo2).exists()
+ .and().containsBytes(bytes);
+ }
+ }
+
+ @Test
+ public void testCopy_toDifferentFileSystem_copyAttributes() throws IOException {
+ try (FileSystem fs2 = Jimfs.newFileSystem(UNIX_CONFIGURATION)) {
+ Path foo = fs.getPath("/foo");
+ byte[] bytes = {0, 1, 2, 3, 4};
+ Files.write(foo, bytes);
+ Files.getFileAttributeView(foo, BasicFileAttributeView.class)
+ .setTimes(FileTime.fromMillis(0), FileTime.fromMillis(1), FileTime.fromMillis(2));
+
+ UserPrincipal owner = fs.getUserPrincipalLookupService().lookupPrincipalByName("foobar");
+ Files.setOwner(foo, owner);
+
+ assertThat(foo)
+ .attribute("owner:owner").is(owner);
+
+ Path foo2 = fs2.getPath("/foo");
+ Files.copy(foo, foo2, COPY_ATTRIBUTES);
+
+ assertThat(foo).exists();
+
+ // when copying with COPY_ATTRIBUTES to a different FileSystem, only basic attributes (that
+ // is, file times) can actually be copied
+ assertThat(foo2).exists()
+ .and().attribute("lastModifiedTime").is(FileTime.fromMillis(0))
+ .and().attribute("lastAccessTime").is(FileTime.fromMillis(1))
+ .and().attribute("creationTime").is(FileTime.fromMillis(2))
+ .and().attribute("owner:owner").isNot(owner)
+ .and().attribute("owner:owner")
+ .isNot(fs2.getUserPrincipalLookupService().lookupPrincipalByName("foobar"))
+ .and().containsBytes(bytes); // do this last; it updates the access time
+ }
+ }
+
+ @Test
public void testMove() throws IOException {
byte[] bytes = preFilledBytes(100);
Files.write(path("/foo"), bytes);
@@ -1787,6 +1838,27 @@ public class JimfsUnixLikeFileSystemTest extends AbstractJimfsIntegrationTest {
}
@Test
+ public void testMove_toDifferentFileSystem() throws IOException {
+ try (FileSystem fs2 = Jimfs.newFileSystem(Configuration.unix())) {
+ Path foo = fs.getPath("/foo");
+ byte[] bytes = {0, 1, 2, 3, 4};
+ Files.write(foo, bytes);
+ Files.getFileAttributeView(foo, BasicFileAttributeView.class)
+ .setTimes(FileTime.fromMillis(0), FileTime.fromMillis(1), FileTime.fromMillis(2));
+
+ Path foo2 = fs2.getPath("/foo");
+ Files.move(foo, foo2);
+
+ assertThat(foo).doesNotExist();
+ assertThat(foo2).exists()
+ .and().attribute("lastModifiedTime").is(FileTime.fromMillis(0))
+ .and().attribute("lastAccessTime").is(FileTime.fromMillis(1))
+ .and().attribute("creationTime").is(FileTime.fromMillis(2))
+ .and().containsBytes(bytes); // do this last; it updates the access time
+ }
+ }
+
+ @Test
public void testIsSameFile() throws IOException {
Files.createDirectory(path("/foo"));
Files.createSymbolicLink(path("/bar"), path("/foo"));