From 7428c07b1a91373d13d6d4eab59539cfe7039fd8 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 21 Mar 2016 16:22:40 -0400 Subject: [PATCH] Make some final changes to the GCS NIO API This change prepares GCS NIO to be merged into master, by making some last minute API changes. - Documentation has been added to many methods to clarify the preferred method for instantiating the library, which is the non-SPI version. - Unit tests have been updated to not rely on the SPI, because there's no way to guarantee clean isolation of SPI usage across tests. We'll be relying on integration testing to test the SPI interface. - The unit testing methodology has changed somewhat. FakeStorageRpc should be a private final field on the test class so, if desired, we'll be able to have the tests dip directly into fake memory. - IOException has been added back to the throws of file system close, in case we decide to implement the "close all owned channels" thing into that method in the future. - The getters on the configuration class have been made package-private, since there's no foreseeable reason they would be needed by the user. In a future change, a README.md file will be added to replace the documentation in the package-info.java file. --- gcloud-java-contrib/gcloud-java-nio/pom.xml | 6 + .../nio/CloudStorageConfiguration.java | 60 +- .../contrib/nio/CloudStorageFileSystem.java | 77 +- .../nio/CloudStorageFileSystemProvider.java | 75 +- .../nio/CloudStorageConfigurationTest.java | 4 +- .../CloudStorageFileAttributeViewTest.java | 97 +-- .../nio/CloudStorageFileAttributesTest.java | 208 +++--- .../CloudStorageFileSystemProviderTest.java | 669 ++++++++++-------- .../nio/CloudStorageFileSystemTest.java | 43 +- .../contrib/nio/CloudStorageOptionsTest.java | 106 +-- .../contrib/nio/CloudStoragePathTest.java | 220 +++--- .../nio/CloudStorageReadChannelTest.java | 2 - .../storage/contrib/nio/NioTestHelper.java | 63 ++ .../storage/testing/FakeStorageRpc.java | 40 +- .../storage/testing/LocalGcsHelper.java | 68 -- 15 files changed, 931 insertions(+), 807 deletions(-) create mode 100644 gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/NioTestHelper.java delete mode 100644 gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/LocalGcsHelper.java diff --git a/gcloud-java-contrib/gcloud-java-nio/pom.xml b/gcloud-java-contrib/gcloud-java-nio/pom.xml index ed1b631ef931..4a2aafa8e8b7 100644 --- a/gcloud-java-contrib/gcloud-java-nio/pom.xml +++ b/gcloud-java-contrib/gcloud-java-nio/pom.xml @@ -49,6 +49,12 @@ 1.1 provided + + com.google.auto.factory + auto-factory + 1.0-beta3 + provided + junit junit diff --git a/gcloud-java-contrib/gcloud-java-nio/src/main/java/com/google/gcloud/storage/contrib/nio/CloudStorageConfiguration.java b/gcloud-java-contrib/gcloud-java-nio/src/main/java/com/google/gcloud/storage/contrib/nio/CloudStorageConfiguration.java index 0371965e20ec..0b56fe4c2acf 100644 --- a/gcloud-java-contrib/gcloud-java-nio/src/main/java/com/google/gcloud/storage/contrib/nio/CloudStorageConfiguration.java +++ b/gcloud-java-contrib/gcloud-java-nio/src/main/java/com/google/gcloud/storage/contrib/nio/CloudStorageConfiguration.java @@ -3,43 +3,26 @@ import static com.google.common.base.Preconditions.checkArgument; import com.google.auto.value.AutoValue; +import com.google.common.base.Strings; import java.util.Map; +import javax.annotation.Nullable; + /** * Configuration for {@link CloudStorageFileSystem} instances. */ @AutoValue public abstract class CloudStorageConfiguration { - /** - * Returns path of current working directory. This defaults to the root directory. - */ - public abstract String workingDirectory(); - - /** - * Returns {@code true} if we shouldn't throw an exception when encountering object names - * containing superfluous slashes, e.g. {@code a//b}. - */ - public abstract boolean permitEmptyPathComponents(); - - /** - * Returns {@code true} if '/' prefix on absolute object names should be removed before I/O. - * - *

If you disable this feature, please take into consideration that all paths created from a - * URI will have the leading slash. - */ - public abstract boolean stripPrefixSlash(); - - /** - * Returns {@code true} if paths with a trailing slash should be treated as fake directories. - */ - public abstract boolean usePseudoDirectories(); + private static final CloudStorageConfiguration DEFAULT = builder().build(); /** - * Returns block size (in bytes) used when talking to the GCS HTTP server. + * Returns default GCS NIO configuration. */ - public abstract int blockSize(); + public static CloudStorageConfiguration getDefault() { + return DEFAULT; + } /** * Creates a new builder, initialized with the following settings: @@ -54,22 +37,29 @@ public static Builder builder() { return new Builder(); } + abstract String workingDirectory(); + abstract boolean permitEmptyPathComponents(); + abstract boolean stripPrefixSlash(); + abstract boolean usePseudoDirectories(); + abstract int blockSize(); + /** * Builder for {@link CloudStorageConfiguration}. */ public static final class Builder { private String workingDirectory = UnixPath.ROOT; - private boolean permitEmptyPathComponents = false; + private boolean permitEmptyPathComponents; private boolean stripPrefixSlash = true; private boolean usePseudoDirectories = true; private int blockSize = CloudStorageFileSystem.BLOCK_SIZE_DEFAULT; /** - * Changes current working directory for new filesystem. This cannot be changed once it's - * been set. You'll need to create another {@link CloudStorageFileSystem} object. + * Changes current working directory for new filesystem. This defaults to the root directory. + * The working directory cannot be changed once it's been set. You'll need to create another + * {@link CloudStorageFileSystem} object. * - * @throws IllegalArgumentException if {@code path} is not absolute. + * @throws IllegalArgumentException if {@code path} is not absolute */ public Builder workingDirectory(String path) { checkArgument(UnixPath.getPath(false, path).isAbsolute(), "not absolute: %s", path); @@ -79,7 +69,7 @@ public Builder workingDirectory(String path) { /** * Configures whether or not we should throw an exception when encountering object names - * containing superfluous slashes, e.g. {@code a//b} + * containing superfluous slashes, e.g. {@code a//b}. */ public Builder permitEmptyPathComponents(boolean value) { permitEmptyPathComponents = value; @@ -130,15 +120,13 @@ public CloudStorageConfiguration build() { Builder() {} } - static final CloudStorageConfiguration DEFAULT = builder().build(); - - static CloudStorageConfiguration fromMap(Map env) { + static CloudStorageConfiguration fromMap(@Nullable String workingDirectory, Map env) { Builder builder = builder(); + if (!Strings.isNullOrEmpty(workingDirectory)) { + builder.workingDirectory(workingDirectory); + } for (Map.Entry entry : env.entrySet()) { switch (entry.getKey()) { - case "workingDirectory": - builder.workingDirectory((String) entry.getValue()); - break; case "permitEmptyPathComponents": builder.permitEmptyPathComponents((Boolean) entry.getValue()); break; diff --git a/gcloud-java-contrib/gcloud-java-nio/src/main/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileSystem.java b/gcloud-java-contrib/gcloud-java-nio/src/main/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileSystem.java index 88f66150e123..00de91128b9b 100644 --- a/gcloud-java-contrib/gcloud-java-nio/src/main/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileSystem.java +++ b/gcloud-java-contrib/gcloud-java-nio/src/main/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileSystem.java @@ -3,7 +3,11 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import com.google.auto.factory.AutoFactory; +import com.google.auto.factory.Provided; +import com.google.common.base.Predicates; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; import java.io.IOException; import java.net.URI; @@ -15,10 +19,12 @@ import java.nio.file.WatchService; import java.nio.file.attribute.FileTime; import java.nio.file.attribute.UserPrincipalLookupService; +import java.nio.file.spi.FileSystemProvider; import java.util.Objects; import java.util.Set; -import javax.annotation.concurrent.Immutable; +import javax.annotation.CheckReturnValue; +import javax.annotation.concurrent.ThreadSafe; /** * Google Cloud Storage {@link FileSystem} implementation. @@ -28,38 +34,48 @@ * @see * Bucket and Object Naming Guidelines */ -@Immutable +@ThreadSafe public final class CloudStorageFileSystem extends FileSystem { /** - * Returns Google Cloud Storage {@link FileSystem} object for {@code bucket}. - * - *

NOTE: You may prefer to use Java's standard API instead:

   {@code
-   *
-   *   FileSystem fs = FileSystems.getFileSystem(URI.create("gs://bucket"));}
- * - *

However some systems and build environments might be flaky when it comes to Java SPI. This - * is because services are generally runtime dependencies and depend on a META-INF file being - * present in your jar (generated by Google Auto at compile-time). In such cases, this method - * provides a simpler alternative. - * - * @see #forBucket(String, CloudStorageConfiguration) - * @see java.nio.file.FileSystems#getFileSystem(java.net.URI) + * Invokes {@link #forBucket(String, CloudStorageConfiguration)} with + * {@link CloudStorageConfiguration#getDefault()}. */ + @CheckReturnValue public static CloudStorageFileSystem forBucket(String bucket) { - return forBucket(bucket, CloudStorageConfiguration.DEFAULT); + return forBucket(bucket, CloudStorageConfiguration.getDefault()); } /** - * Creates new file system instance for {@code bucket}, with customizable settings. + * Returns Google Cloud Storage {@link FileSystem} object for {@code bucket}. + * + *

GCS file system objects are basically free. You can create as many as you want, even if you + * have multiple instances for the same bucket. There's no actual system resources associated + * with this object. Therefore calling {@link #close()} on the returned value is optional. * - * @see #forBucket(String) + *

Note: It is also possible to instantiate this class via Java's Service Provider + * Interface (SPI), e.g. {@code FileSystems.getFileSystem(URI.create("gs://bucket"))}. We + * discourage you from using the SPI if possible, for the reasons documented in + * {@link CloudStorageFileSystemProvider#newFileSystem(URI, java.util.Map)} + * + * @see #forBucket(String, CloudStorageConfiguration) + * @see java.nio.file.FileSystems#getFileSystem(java.net.URI) */ + @CheckReturnValue public static CloudStorageFileSystem forBucket(String bucket, CloudStorageConfiguration config) { + checkNotNull(config); checkArgument( !bucket.startsWith(URI_SCHEME + ":"), "Bucket name must not have schema: %s", bucket); return new CloudStorageFileSystem( - new CloudStorageFileSystemProvider(), bucket, checkNotNull(config)); + // XXX: This is a kludge to get the provider instance from the SPI. This is necessary since + // the behavior of NIO changes quite a bit if the provider instances aren't the same. + (CloudStorageFileSystemProvider) + Iterables.getOnlyElement( + Iterables.filter( + FileSystemProvider.installedProviders(), + Predicates.instanceOf(CloudStorageFileSystemProvider.class))), + config, + bucket); } public static final String URI_SCHEME = "gs"; @@ -69,12 +85,15 @@ public static CloudStorageFileSystem forBucket(String bucket, CloudStorageConfig public static final FileTime FILE_TIME_UNKNOWN = FileTime.fromMillis(0); public static final ImmutableSet SUPPORTED_VIEWS = ImmutableSet.of(BASIC_VIEW, GCS_VIEW); - private final CloudStorageFileSystemProvider provider; private final String bucket; + private final CloudStorageFileSystemProvider provider; private final CloudStorageConfiguration config; + @AutoFactory CloudStorageFileSystem( - CloudStorageFileSystemProvider provider, String bucket, CloudStorageConfiguration config) { + @Provided CloudStorageFileSystemProvider provider, + @Provided CloudStorageConfiguration config, + String bucket) { checkArgument(!bucket.isEmpty(), "bucket"); this.provider = provider; this.bucket = bucket; @@ -113,13 +132,20 @@ public CloudStoragePath getPath(String first, String... more) { } /** - * Does nothing. + * Does nothing currently. This method might be updated in the future to close all channels + * associated with this file system object. However it's unlikely that even then, calling this + * method will become mandatory. */ @Override - public void close() {} + public void close() throws IOException { + // TODO(jean-philippe-martin,jart): Synchronously close all active channels associated with this + // FileSystem instance on close, per NIO documentation. But we + // probably shouldn't bother unless a legitimate reason can be + // found to implement this behavior. + } /** - * Returns {@code true}. + * Returns {@code true}, even if you previously called the {@link #close()} method. */ @Override public boolean isOpen() { @@ -147,6 +173,9 @@ public Iterable getRootDirectories() { return ImmutableSet.of(CloudStoragePath.getPath(this, UnixPath.ROOT)); } + /** + * Returns nothing because GCS doesn't have disk partitions of limited size, or anything similar. + */ @Override public Iterable getFileStores() { return ImmutableSet.of(); diff --git a/gcloud-java-contrib/gcloud-java-nio/src/main/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileSystemProvider.java b/gcloud-java-contrib/gcloud-java-nio/src/main/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileSystemProvider.java index 4c7acba98a96..5eb56138f473 100644 --- a/gcloud-java-contrib/gcloud-java-nio/src/main/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileSystemProvider.java +++ b/gcloud-java-contrib/gcloud-java-nio/src/main/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileSystemProvider.java @@ -10,9 +10,7 @@ import static com.google.gcloud.storage.contrib.nio.CloudStorageUtil.stripPathFromUri; import com.google.auto.service.AutoService; -import com.google.common.annotations.VisibleForTesting; import com.google.common.base.MoreObjects; -import com.google.common.base.Throwables; import com.google.common.primitives.Ints; import com.google.gcloud.storage.Acl; import com.google.gcloud.storage.BlobId; @@ -53,45 +51,33 @@ import java.util.Objects; import java.util.Set; -import javax.annotation.Nullable; import javax.annotation.concurrent.ThreadSafe; +import javax.inject.Inject; +import javax.inject.Singleton; /** * Google Cloud Storage {@link FileSystemProvider} implementation. */ +@Singleton @ThreadSafe @AutoService(FileSystemProvider.class) public final class CloudStorageFileSystemProvider extends FileSystemProvider { private final Storage storage; - // used only when we create a new instance of CloudStorageFileSystemProvider. - private static StorageOptions storageOptions; - - /** - * Sets options that are only used by the constructor. - */ - @VisibleForTesting - public static void setGCloudOptions(StorageOptions newStorageOptions) { - storageOptions = newStorageOptions; + @Inject + CloudStorageFileSystemProvider(Storage storage) { + this.storage = storage; } /** - * Default constructor which should only be called by Java SPI. + * Constructs a new instance with the default options. * - * @see java.nio.file.FileSystems#getFileSystem(URI) - * @see CloudStorageFileSystem#forBucket(String) + *

Note: This should only be called by the Java SPI. Please use + * {@link CloudStorageFileSystem#forBucket(String, CloudStorageConfiguration)} instead. */ public CloudStorageFileSystemProvider() { - this(storageOptions); - } - - private CloudStorageFileSystemProvider(@Nullable StorageOptions gcsStorageOptions) { - if (gcsStorageOptions == null) { - this.storage = StorageOptions.defaultInstance().service(); - } else { - this.storage = gcsStorageOptions.service(); - } + this(StorageOptions.defaultInstance().service()); } @Override @@ -100,7 +86,7 @@ public String getScheme() { } /** - * Returns Cloud Storage file system, provided a URI with no path, e.g. {@code gs://bucket}. + * Calls {@link #newFileSystem(URI, Map)} with an empty configuration map. */ @Override public CloudStorageFileSystem getFileSystem(URI uri) { @@ -108,7 +94,21 @@ public CloudStorageFileSystem getFileSystem(URI uri) { } /** - * Returns Cloud Storage file system, provided a URI with no path, e.g. {@code gs://bucket}. + * Returns Cloud Storage file system, provided a URI with no path. + * + *

Note: This method should be invoked indirectly via the SPI by calling + * {@link java.nio.file.FileSystems#newFileSystem(URI, Map) FileSystems.newFileSystem()}. However + * we recommend that you don't use the SPI if possible; the recommended approach is to write a + * dependency injection module that calls the statically-linked type-safe version of this method, + * which is: {@link CloudStorageFileSystem#forBucket(String, CloudStorageConfiguration)}. Please + * see that method for further documentation on creating GCS file systems. + * + * @param uri bucket and current working directory, e.g. {@code gs://bucket} + * @param env map of configuration options, whose keys correspond to the method names of + * {@link CloudStorageConfiguration.Builder}. However you are not allowed to set the working + * directory, as that should be provided in the {@code uri} + * @throws IllegalArgumentException if {@code uri} specifies a user, query, fragment, or scheme is + * not {@value CloudStorageFileSystem#URI_SCHEME} */ @Override public CloudStorageFileSystem newFileSystem(URI uri, Map env) { @@ -121,14 +121,14 @@ public CloudStorageFileSystem newFileSystem(URI uri, Map env) { !isNullOrEmpty(uri.getHost()), "%s:// URIs must have a host: %s", URI_SCHEME, uri); checkArgument( uri.getPort() == -1 - && isNullOrEmpty(uri.getPath()) && isNullOrEmpty(uri.getQuery()) && isNullOrEmpty(uri.getFragment()) && isNullOrEmpty(uri.getUserInfo()), "GCS FileSystem URIs mustn't have: port, userinfo, path, query, or fragment: %s", uri); checkBucket(uri.getHost()); - return new CloudStorageFileSystem(this, uri.getHost(), CloudStorageConfiguration.fromMap(env)); + return new CloudStorageFileSystem( + this, CloudStorageConfiguration.fromMap(uri.getPath(), env), uri.getHost()); } @Override @@ -554,23 +554,16 @@ public String toString() { } private IOException asIOException(StorageException oops) { + // RPC API can only throw StorageException, but CloudStorageFileSystemProvider + // can only throw IOException. Square peg, round hole. + // TODO: research if other codes should be translated similarly. if (oops.code() == 404) { return new NoSuchFileException(oops.reason()); } - // TODO: research if other codes should be translated to IOException. - - // RPC API can only throw StorageException, but CloudStorageFileSystemProvider - // can only throw IOException. Square peg, round hole. Throwable cause = oops.getCause(); - try { - if (cause instanceof FileAlreadyExistsException) { - throw new FileAlreadyExistsException(((FileAlreadyExistsException) cause).getReason()); - } - // fallback - Throwables.propagateIfInstanceOf(oops.getCause(), IOException.class); - } catch (IOException okEx) { - return okEx; + if (cause instanceof FileAlreadyExistsException) { + return (FileAlreadyExistsException) cause; } - return new IOException(oops.getMessage(), oops); + return new IOException("Storage operation failed", oops); } } diff --git a/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageConfigurationTest.java b/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageConfigurationTest.java index 66963b18ddb9..771d08fb3837 100644 --- a/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageConfigurationTest.java +++ b/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageConfigurationTest.java @@ -39,8 +39,8 @@ public void testBuilder() { public void testFromMap() { CloudStorageConfiguration config = CloudStorageConfiguration.fromMap( + "/omg", new ImmutableMap.Builder() - .put("workingDirectory", "/omg") .put("permitEmptyPathComponents", true) .put("stripPrefixSlash", false) .put("usePseudoDirectories", false) @@ -56,6 +56,6 @@ public void testFromMap() { @Test public void testFromMap_badKey_throwsIae() { thrown.expect(IllegalArgumentException.class); - CloudStorageConfiguration.fromMap(ImmutableMap.of("lol", "/omg")); + CloudStorageConfiguration.fromMap(null, ImmutableMap.of("lol", "/omg")); } } diff --git a/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileAttributeViewTest.java b/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileAttributeViewTest.java index 71e35ab1745f..68f500e8e41d 100644 --- a/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileAttributeViewTest.java +++ b/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileAttributeViewTest.java @@ -6,9 +6,8 @@ import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; -import com.google.gcloud.storage.testing.LocalGcsHelper; +import com.google.gcloud.storage.testing.FakeStorageRpc; -import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -16,11 +15,10 @@ import org.junit.runners.JUnit4; import java.io.IOException; -import java.net.URI; +import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.NoSuchFileException; import java.nio.file.Path; -import java.nio.file.Paths; import java.nio.file.attribute.FileTime; /** @@ -33,67 +31,76 @@ public class CloudStorageFileAttributeViewTest { @Rule public final ExpectedException thrown = ExpectedException.none(); - private Path path; - - @Before - public void before() { - CloudStorageFileSystemProvider.setGCloudOptions(LocalGcsHelper.options()); - path = Paths.get(URI.create("gs://red/water")); - } + private final FakeStorageRpc storage = new FakeStorageRpc(true); + private final NioTestHelper helper = new NioTestHelper(storage); @Test public void testReadAttributes() throws IOException { - Files.write(path, HAPPY, withCacheControl("potato")); - CloudStorageFileAttributeView lazyAttributes = - Files.getFileAttributeView(path, CloudStorageFileAttributeView.class); - assertThat(lazyAttributes.readAttributes().cacheControl().get()).isEqualTo("potato"); + try (FileSystem fs = helper.forBucket("red")) { + Path path = fs.getPath("/water"); + Files.write(path, HAPPY, withCacheControl("potato")); + CloudStorageFileAttributeView lazyAttributes = + Files.getFileAttributeView(path, CloudStorageFileAttributeView.class); + assertThat(lazyAttributes.readAttributes().cacheControl().get()).isEqualTo("potato"); + } } @Test public void testReadAttributes_notFound_throwsNoSuchFileException() throws IOException { - CloudStorageFileAttributeView lazyAttributes = - Files.getFileAttributeView(path, CloudStorageFileAttributeView.class); - thrown.expect(NoSuchFileException.class); - lazyAttributes.readAttributes(); + try (FileSystem fs = helper.forBucket("red")) { + Path path = fs.getPath("/water"); + CloudStorageFileAttributeView lazyAttributes = + Files.getFileAttributeView(path, CloudStorageFileAttributeView.class); + thrown.expect(NoSuchFileException.class); + lazyAttributes.readAttributes(); + } } @Test public void testReadAttributes_pseudoDirectory() throws IOException { - Path dir = Paths.get(URI.create("gs://red/rum/")); - CloudStorageFileAttributeView lazyAttributes = - Files.getFileAttributeView(dir, CloudStorageFileAttributeView.class); - assertThat(lazyAttributes.readAttributes()) - .isInstanceOf(CloudStoragePseudoDirectoryAttributes.class); + try (FileSystem fs = helper.forBucket("red")) { + Path dir = fs.getPath("/rum/"); + CloudStorageFileAttributeView lazyAttributes = + Files.getFileAttributeView(dir, CloudStorageFileAttributeView.class); + assertThat(lazyAttributes.readAttributes()) + .isInstanceOf(CloudStoragePseudoDirectoryAttributes.class); + } } @Test public void testName() throws IOException { - Files.write(path, HAPPY, withCacheControl("potato")); - CloudStorageFileAttributeView lazyAttributes = - Files.getFileAttributeView(path, CloudStorageFileAttributeView.class); - assertThat(lazyAttributes.name()).isEqualTo("gcs"); + try (FileSystem fs = helper.forBucket("red")) { + Path path = fs.getPath("/water"); + Files.write(path, HAPPY, withCacheControl("potato")); + CloudStorageFileAttributeView lazyAttributes = + Files.getFileAttributeView(path, CloudStorageFileAttributeView.class); + assertThat(lazyAttributes.name()).isEqualTo("gcs"); + } } @Test - public void testEquals_equalsTester() { - new EqualsTester() - .addEqualityGroup( - Files.getFileAttributeView( - Paths.get(URI.create("gs://red/rum")), CloudStorageFileAttributeView.class), - Files.getFileAttributeView( - Paths.get(URI.create("gs://red/rum")), CloudStorageFileAttributeView.class)) - .addEqualityGroup( - Files.getFileAttributeView( - Paths.get(URI.create("gs://red/lol/dog")), CloudStorageFileAttributeView.class)) - .testEquals(); + public void testEquals_equalsTester() throws IOException { + try (FileSystem fs = helper.forBucket("red")) { + new EqualsTester() + .addEqualityGroup( + Files.getFileAttributeView(fs.getPath("/rum"), CloudStorageFileAttributeView.class), + Files.getFileAttributeView(fs.getPath("/rum"), CloudStorageFileAttributeView.class)) + .addEqualityGroup( + Files.getFileAttributeView( + fs.getPath("/lol/dog"), CloudStorageFileAttributeView.class)) + .testEquals(); + } } @Test - public void testNullness() throws NoSuchMethodException, SecurityException { - new NullPointerTester() - .ignore(CloudStorageFileAttributeView.class.getMethod("equals", Object.class)) - .setDefault(FileTime.class, FileTime.fromMillis(0)) - .testAllPublicInstanceMethods( - Files.getFileAttributeView(path, CloudStorageFileAttributeView.class)); + public void testNullness() throws NoSuchMethodException, SecurityException, IOException { + try (FileSystem fs = helper.forBucket("red")) { + Path path = fs.getPath("/water"); + new NullPointerTester() + .ignore(CloudStorageFileAttributeView.class.getMethod("equals", Object.class)) + .setDefault(FileTime.class, FileTime.fromMillis(0)) + .testAllPublicInstanceMethods( + Files.getFileAttributeView(path, CloudStorageFileAttributeView.class)); + } } } diff --git a/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileAttributesTest.java b/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileAttributesTest.java index 92f9acd1407b..d2e9fb91109e 100644 --- a/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileAttributesTest.java +++ b/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileAttributesTest.java @@ -12,18 +12,16 @@ import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; import com.google.gcloud.storage.Acl; -import com.google.gcloud.storage.testing.LocalGcsHelper; +import com.google.gcloud.storage.testing.FakeStorageRpc; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import java.io.IOException; -import java.net.URI; +import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; /** * Unit tests for {@link CloudStorageFileAttributes}. @@ -33,137 +31,177 @@ public class CloudStorageFileAttributesTest { private static final byte[] HAPPY = "(✿◕ ‿◕ )ノ".getBytes(UTF_8); - private Path path; - private Path dir; - - @Before - public void before() { - CloudStorageFileSystemProvider.setGCloudOptions(LocalGcsHelper.options()); - path = Paths.get(URI.create("gs://bucket/randompath")); - dir = Paths.get(URI.create("gs://bucket/randompath/")); - } + private final FakeStorageRpc storage = new FakeStorageRpc(true); + private final NioTestHelper helper = new NioTestHelper(storage); @Test public void testCacheControl() throws IOException { - Files.write(path, HAPPY, withCacheControl("potato")); - assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).cacheControl().get()) - .isEqualTo("potato"); + try (FileSystem fs = helper.forBucket("red")) { + Path path = fs.getPath("/water"); + Files.write(path, HAPPY, withCacheControl("potato")); + assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).cacheControl().get()) + .isEqualTo("potato"); + } } @Test public void testMimeType() throws IOException { - Files.write(path, HAPPY, withMimeType("text/potato")); - assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).mimeType().get()) - .isEqualTo("text/potato"); + try (FileSystem fs = helper.forBucket("red")) { + Path path = fs.getPath("/water"); + Files.write(path, HAPPY, withMimeType("text/potato")); + assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).mimeType().get()) + .isEqualTo("text/potato"); + } } @Test public void testAcl() throws IOException { - Acl acl = Acl.of(new Acl.User("serf@example.com"), Acl.Role.READER); - Files.write(path, HAPPY, withAcl(acl)); - assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).acl().get()) - .contains(acl); + try (FileSystem fs = helper.forBucket("red")) { + Path path = fs.getPath("/water"); + Acl acl = Acl.of(new Acl.User("serf@example.com"), Acl.Role.READER); + Files.write(path, HAPPY, withAcl(acl)); + assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).acl().get()) + .contains(acl); + } } @Test public void testContentDisposition() throws IOException { - Files.write(path, HAPPY, withContentDisposition("crash call")); - assertThat( - Files.readAttributes(path, CloudStorageFileAttributes.class).contentDisposition().get()) - .isEqualTo("crash call"); + try (FileSystem fs = helper.forBucket("red")) { + Path path = fs.getPath("/water"); + Files.write(path, HAPPY, withContentDisposition("crash call")); + assertThat( + Files.readAttributes( + path, CloudStorageFileAttributes.class).contentDisposition().get()) + .isEqualTo("crash call"); + } } @Test public void testContentEncoding() throws IOException { - Files.write(path, HAPPY, withContentEncoding("my content encoding")); - assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).contentEncoding().get()) - .isEqualTo("my content encoding"); + try (FileSystem fs = helper.forBucket("red")) { + Path path = fs.getPath("/water"); + Files.write(path, HAPPY, withContentEncoding("my content encoding")); + assertThat( + Files.readAttributes(path, CloudStorageFileAttributes.class).contentEncoding().get()) + .isEqualTo("my content encoding"); + } } @Test public void testUserMetadata() throws IOException { - Files.write(path, HAPPY, withUserMetadata("green", "bean")); - assertThat( - Files.readAttributes(path, CloudStorageFileAttributes.class) - .userMetadata() - .get("green")) - .isEqualTo("bean"); + try (FileSystem fs = helper.forBucket("red")) { + Path path = fs.getPath("/water"); + Files.write(path, HAPPY, withUserMetadata("green", "bean")); + assertThat( + Files.readAttributes(path, CloudStorageFileAttributes.class) + .userMetadata() + .get("green")) + .isEqualTo("bean"); + } } @Test public void testIsDirectory() throws IOException { - Files.write(path, HAPPY); - assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).isDirectory()) - .isFalse(); - assertThat(Files.readAttributes(dir, CloudStorageFileAttributes.class).isDirectory()).isTrue(); + try (FileSystem fs = helper.forBucket("red")) { + Path path = fs.getPath("/water"); + Path dir = fs.getPath("/rum/"); + Files.write(path, HAPPY); + assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).isDirectory()) + .isFalse(); + assertThat(Files.readAttributes(dir, CloudStorageFileAttributes.class).isDirectory()) + .isTrue(); + } } @Test public void testIsRegularFile() throws IOException { - Files.write(path, HAPPY); - assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).isRegularFile()) - .isTrue(); - assertThat(Files.readAttributes(dir, CloudStorageFileAttributes.class).isRegularFile()) - .isFalse(); + try (FileSystem fs = helper.forBucket("red")) { + Path path = fs.getPath("/water"); + Path dir = fs.getPath("/rum/"); + Files.write(path, HAPPY); + assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).isRegularFile()) + .isTrue(); + assertThat(Files.readAttributes(dir, CloudStorageFileAttributes.class).isRegularFile()) + .isFalse(); + } } @Test public void testIsOther() throws IOException { - Files.write(path, HAPPY); - assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).isOther()).isFalse(); - assertThat(Files.readAttributes(dir, CloudStorageFileAttributes.class).isOther()).isFalse(); + try (FileSystem fs = helper.forBucket("red")) { + Path path = fs.getPath("/water"); + Path dir = fs.getPath("/rum/"); + Files.write(path, HAPPY); + assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).isOther()).isFalse(); + assertThat(Files.readAttributes(dir, CloudStorageFileAttributes.class).isOther()).isFalse(); + } } @Test public void testIsSymbolicLink() throws IOException { - Files.write(path, HAPPY); - assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).isSymbolicLink()) - .isFalse(); - assertThat(Files.readAttributes(dir, CloudStorageFileAttributes.class).isSymbolicLink()) - .isFalse(); + try (FileSystem fs = helper.forBucket("red")) { + Path path = fs.getPath("/water"); + Path dir = fs.getPath("/rum/"); + Files.write(path, HAPPY); + assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).isSymbolicLink()) + .isFalse(); + assertThat(Files.readAttributes(dir, CloudStorageFileAttributes.class).isSymbolicLink()) + .isFalse(); + } } @Test public void testEquals_equalsTester() throws IOException { - Files.write(path, HAPPY, withMimeType("text/plain")); - CloudStorageFileAttributes a1 = Files.readAttributes(path, CloudStorageFileAttributes.class); - CloudStorageFileAttributes a2 = Files.readAttributes(path, CloudStorageFileAttributes.class); - Files.write(path, HAPPY, withMimeType("text/potato")); - CloudStorageFileAttributes b1 = Files.readAttributes(path, CloudStorageFileAttributes.class); - CloudStorageFileAttributes b2 = Files.readAttributes(path, CloudStorageFileAttributes.class); - new EqualsTester().addEqualityGroup(a1, a2).addEqualityGroup(b1, b2).testEquals(); + try (FileSystem fs = helper.forBucket("red")) { + Path path = fs.getPath("/water"); + Files.write(path, HAPPY, withMimeType("text/plain")); + CloudStorageFileAttributes a1 = Files.readAttributes(path, CloudStorageFileAttributes.class); + CloudStorageFileAttributes a2 = Files.readAttributes(path, CloudStorageFileAttributes.class); + Files.write(path, HAPPY, withMimeType("text/potato")); + CloudStorageFileAttributes b1 = Files.readAttributes(path, CloudStorageFileAttributes.class); + CloudStorageFileAttributes b2 = Files.readAttributes(path, CloudStorageFileAttributes.class); + new EqualsTester().addEqualityGroup(a1, a2).addEqualityGroup(b1, b2).testEquals(); + } } @Test public void testFilekey() throws IOException { - Files.write(path, HAPPY, withMimeType("text/plain")); - Path path2 = Paths.get(URI.create("gs://bucket/anotherrandompath")); - Files.write(path2, HAPPY, withMimeType("text/plain")); - - // diff files cannot have same filekey - CloudStorageFileAttributes a1 = Files.readAttributes(path, CloudStorageFileAttributes.class); - CloudStorageFileAttributes a2 = Files.readAttributes(path2, CloudStorageFileAttributes.class); - assertThat(a1.fileKey()).isNotEqualTo(a2.fileKey()); - - // same for directories - CloudStorageFileAttributes b1 = Files.readAttributes(dir, CloudStorageFileAttributes.class); - CloudStorageFileAttributes b2 = - Files.readAttributes( - Paths.get(URI.create("gs://bucket/jacket/")), CloudStorageFileAttributes.class); - assertThat(a1.fileKey()).isNotEqualTo(b1.fileKey()); - assertThat(b1.fileKey()).isNotEqualTo(b2.fileKey()); + try (FileSystem fs = helper.forBucket("red")) { + Path dir = fs.getPath("/rum/"); + Path path = fs.getPath("/water"); + Files.write(path, HAPPY, withMimeType("text/plain")); + Path path2 = fs.getPath("/anotherrandompath"); + Files.write(path2, HAPPY, withMimeType("text/plain")); + + // diff files cannot have same filekey + CloudStorageFileAttributes a1 = Files.readAttributes(path, CloudStorageFileAttributes.class); + CloudStorageFileAttributes a2 = Files.readAttributes(path2, CloudStorageFileAttributes.class); + assertThat(a1.fileKey()).isNotEqualTo(a2.fileKey()); + + // same for directories + CloudStorageFileAttributes b1 = Files.readAttributes(dir, CloudStorageFileAttributes.class); + CloudStorageFileAttributes b2 = + Files.readAttributes(fs.getPath("/jacket/"), CloudStorageFileAttributes.class); + assertThat(a1.fileKey()).isNotEqualTo(b1.fileKey()); + assertThat(b1.fileKey()).isNotEqualTo(b2.fileKey()); + } } @Test public void testNullness() throws IOException, NoSuchMethodException, SecurityException { - Files.write(path, HAPPY); - CloudStorageFileAttributes pathAttributes = - Files.readAttributes(path, CloudStorageFileAttributes.class); - CloudStorageFileAttributes dirAttributes = - Files.readAttributes(dir, CloudStorageFileAttributes.class); - NullPointerTester tester = new NullPointerTester(); - tester.ignore(CloudStorageObjectAttributes.class.getMethod("equals", Object.class)); - tester.testAllPublicInstanceMethods(pathAttributes); - tester.testAllPublicInstanceMethods(dirAttributes); + try (FileSystem fs = helper.forBucket("red")) { + Path path = fs.getPath("/water"); + Path dir = fs.getPath("/rum/"); + Files.write(path, HAPPY); + CloudStorageFileAttributes pathAttributes = + Files.readAttributes(path, CloudStorageFileAttributes.class); + CloudStorageFileAttributes dirAttributes = + Files.readAttributes(dir, CloudStorageFileAttributes.class); + NullPointerTester tester = new NullPointerTester(); + tester.ignore(CloudStorageObjectAttributes.class.getMethod("equals", Object.class)); + tester.testAllPublicInstanceMethods(pathAttributes); + tester.testAllPublicInstanceMethods(dirAttributes); + } } } diff --git a/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileSystemProviderTest.java b/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileSystemProviderTest.java index f38860aef1e6..337fb3f1f56e 100644 --- a/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileSystemProviderTest.java +++ b/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileSystemProviderTest.java @@ -1,12 +1,13 @@ package com.google.gcloud.storage.contrib.nio; import static com.google.common.truth.Truth.assertThat; -import static com.google.gcloud.storage.contrib.nio.CloudStorageFileSystem.forBucket; import static com.google.gcloud.storage.contrib.nio.CloudStorageOptions.withCacheControl; import static com.google.gcloud.storage.contrib.nio.CloudStorageOptions.withContentDisposition; import static com.google.gcloud.storage.contrib.nio.CloudStorageOptions.withContentEncoding; import static com.google.gcloud.storage.contrib.nio.CloudStorageOptions.withMimeType; import static com.google.gcloud.storage.contrib.nio.CloudStorageOptions.withUserMetadata; +import static com.google.gcloud.storage.contrib.nio.NioTestHelper.permitEmptyPathComponents; +import static com.google.gcloud.storage.contrib.nio.NioTestHelper.usePseudoDirectories; import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.file.StandardCopyOption.ATOMIC_MOVE; import static java.nio.file.StandardCopyOption.COPY_ATTRIBUTES; @@ -17,9 +18,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.testing.NullPointerTester; -import com.google.gcloud.storage.testing.LocalGcsHelper; +import com.google.gcloud.storage.testing.FakeStorageRpc; -import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -42,7 +42,6 @@ import java.nio.file.NoSuchFileException; import java.nio.file.OpenOption; import java.nio.file.Path; -import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.nio.file.StandardOpenOption; import java.util.List; @@ -78,26 +77,28 @@ public class CloudStorageFileSystemProviderTest { @Rule public final ExpectedException thrown = ExpectedException.none(); - @Before - public void before() { - CloudStorageFileSystemProvider.setGCloudOptions(LocalGcsHelper.options()); - } + private final FakeStorageRpc storage = new FakeStorageRpc(true); + private final NioTestHelper helper = new NioTestHelper(storage); @Test public void testSize() throws IOException { - Path path = Paths.get(URI.create("gs://bucket/wat")); - Files.write(path, SINGULARITY.getBytes(UTF_8)); - assertThat(Files.size(path)).isEqualTo(SINGULARITY.getBytes(UTF_8).length); + try (FileSystem fs = helper.forBucket("bucket")) { + Path path = fs.getPath("/wat"); + Files.write(path, SINGULARITY.getBytes(UTF_8)); + assertThat(Files.size(path)).isEqualTo(SINGULARITY.getBytes(UTF_8).length); + } } @Test public void testSize_trailingSlash_returnsFakePseudoDirectorySize() throws IOException { - assertThat(Files.size(Paths.get(URI.create("gs://bucket/wat/")))).isEqualTo(1); + try (FileSystem fs = helper.forBucket("bucket")) { + assertThat(Files.size(fs.getPath("/wat/"))).isEqualTo(1); + } } @Test public void testSize_trailingSlash_disablePseudoDirectories() throws IOException { - try (CloudStorageFileSystem fs = forBucket("doodle", usePseudoDirectories(false))) { + try (CloudStorageFileSystem fs = helper.forBucket("doodle", usePseudoDirectories(false))) { Path path = fs.getPath("wat/"); byte[] rapture = SINGULARITY.getBytes(UTF_8); Files.write(path, rapture); @@ -107,190 +108,227 @@ public void testSize_trailingSlash_disablePseudoDirectories() throws IOException @Test public void testReadAllBytes() throws IOException { - Path path = Paths.get(URI.create("gs://bucket/wat")); - Files.write(path, SINGULARITY.getBytes(UTF_8)); - assertThat(new String(Files.readAllBytes(path), UTF_8)).isEqualTo(SINGULARITY); + try (FileSystem fs = helper.forBucket("bucket")) { + Path path = fs.getPath("/wat"); + Files.write(path, SINGULARITY.getBytes(UTF_8)); + assertThat(new String(Files.readAllBytes(path), UTF_8)).isEqualTo(SINGULARITY); + } } @Test public void testReadAllBytes_trailingSlash() throws IOException { - thrown.expect(CloudStoragePseudoDirectoryException.class); - Files.readAllBytes(Paths.get(URI.create("gs://bucket/wat/"))); + try (FileSystem fs = helper.forBucket("bucket")) { + thrown.expect(CloudStoragePseudoDirectoryException.class); + Files.readAllBytes(fs.getPath("/wat/")); + } } @Test public void testNewByteChannelRead() throws IOException { - Path path = Paths.get(URI.create("gs://bucket/wat")); - byte[] data = SINGULARITY.getBytes(UTF_8); - Files.write(path, data); - try (ReadableByteChannel input = Files.newByteChannel(path)) { - ByteBuffer buffer = ByteBuffer.allocate(data.length); - assertThat(input.read(buffer)).isEqualTo(data.length); - assertThat(new String(buffer.array(), UTF_8)).isEqualTo(SINGULARITY); - buffer.rewind(); - assertThat(input.read(buffer)).isEqualTo(-1); + try (FileSystem fs = helper.forBucket("bucket")) { + Path path = fs.getPath("/wat"); + byte[] data = SINGULARITY.getBytes(UTF_8); + Files.write(path, data); + try (ReadableByteChannel input = Files.newByteChannel(path)) { + ByteBuffer buffer = ByteBuffer.allocate(data.length); + assertThat(input.read(buffer)).isEqualTo(data.length); + assertThat(new String(buffer.array(), UTF_8)).isEqualTo(SINGULARITY); + buffer.rewind(); + assertThat(input.read(buffer)).isEqualTo(-1); + } } } @Test public void testNewByteChannelRead_seeking() throws IOException { - Path path = Paths.get(URI.create("gs://lol/cat")); - Files.write(path, "helloworld".getBytes(UTF_8)); - try (SeekableByteChannel input = Files.newByteChannel(path)) { - ByteBuffer buffer = ByteBuffer.allocate(5); - input.position(5); - assertThat(input.position()).isEqualTo(5); - assertThat(input.read(buffer)).isEqualTo(5); - assertThat(input.position()).isEqualTo(10); - assertThat(new String(buffer.array(), UTF_8)).isEqualTo("world"); - buffer.rewind(); - assertThat(input.read(buffer)).isEqualTo(-1); - input.position(0); - assertThat(input.position()).isEqualTo(0); - assertThat(input.read(buffer)).isEqualTo(5); - assertThat(input.position()).isEqualTo(5); - assertThat(new String(buffer.array(), UTF_8)).isEqualTo("hello"); + try (FileSystem fs = helper.forBucket("lol")) { + Path path = fs.getPath("/cat"); + Files.write(path, "helloworld".getBytes(UTF_8)); + try (SeekableByteChannel input = Files.newByteChannel(path)) { + ByteBuffer buffer = ByteBuffer.allocate(5); + input.position(5); + assertThat(input.position()).isEqualTo(5); + assertThat(input.read(buffer)).isEqualTo(5); + assertThat(input.position()).isEqualTo(10); + assertThat(new String(buffer.array(), UTF_8)).isEqualTo("world"); + buffer.rewind(); + assertThat(input.read(buffer)).isEqualTo(-1); + input.position(0); + assertThat(input.position()).isEqualTo(0); + assertThat(input.read(buffer)).isEqualTo(5); + assertThat(input.position()).isEqualTo(5); + assertThat(new String(buffer.array(), UTF_8)).isEqualTo("hello"); + } } } @Test public void testNewByteChannelRead_seekBeyondSize_reportsEofOnNextRead() throws IOException { - Path path = Paths.get(URI.create("gs://lol/cat")); - Files.write(path, "hellocat".getBytes(UTF_8)); - try (SeekableByteChannel input = Files.newByteChannel(path)) { - ByteBuffer buffer = ByteBuffer.allocate(5); - input.position(10); - assertThat(input.read(buffer)).isEqualTo(-1); - input.position(11); - assertThat(input.read(buffer)).isEqualTo(-1); - assertThat(input.size()).isEqualTo(8); + try (FileSystem fs = helper.forBucket("lol")) { + Path path = fs.getPath("/cat"); + Files.write(path, "hellocat".getBytes(UTF_8)); + try (SeekableByteChannel input = Files.newByteChannel(path)) { + ByteBuffer buffer = ByteBuffer.allocate(5); + input.position(10); + assertThat(input.read(buffer)).isEqualTo(-1); + input.position(11); + assertThat(input.read(buffer)).isEqualTo(-1); + assertThat(input.size()).isEqualTo(8); + } } } @Test public void testNewByteChannelRead_trailingSlash() throws IOException { - Path path = Paths.get(URI.create("gs://bucket/wat/")); - thrown.expect(CloudStoragePseudoDirectoryException.class); - Files.newByteChannel(path); + try (FileSystem fs = helper.forBucket("bucket")) { + Path path = fs.getPath("/wat/"); + thrown.expect(CloudStoragePseudoDirectoryException.class); + Files.newByteChannel(path); + } } @Test public void testNewByteChannelRead_notFound() throws IOException { - Path path = Paths.get(URI.create("gs://bucket/wednesday")); - thrown.expect(NoSuchFileException.class); - Files.newByteChannel(path); + try (FileSystem fs = helper.forBucket("bucket")) { + Path path = fs.getPath("/wednesday"); + thrown.expect(NoSuchFileException.class); + Files.newByteChannel(path); + } } @Test public void testNewByteChannelWrite() throws IOException { - Path path = Paths.get(URI.create("gs://bucket/tests")); - try (SeekableByteChannel output = Files.newByteChannel(path, WRITE)) { - assertThat(output.position()).isEqualTo(0); - assertThat(output.size()).isEqualTo(0); - ByteBuffer buffer = ByteBuffer.wrap("filec".getBytes(UTF_8)); - assertThat(output.write(buffer)).isEqualTo(5); - assertThat(output.position()).isEqualTo(5); - assertThat(output.size()).isEqualTo(5); - buffer = ByteBuffer.wrap("onten".getBytes(UTF_8)); - assertThat(output.write(buffer)).isEqualTo(5); - assertThat(output.position()).isEqualTo(10); - assertThat(output.size()).isEqualTo(10); + try (FileSystem fs = helper.forBucket("bucket")) { + Path path = fs.getPath("/tests"); + try (SeekableByteChannel output = Files.newByteChannel(path, WRITE)) { + assertThat(output.position()).isEqualTo(0); + assertThat(output.size()).isEqualTo(0); + ByteBuffer buffer = ByteBuffer.wrap("filec".getBytes(UTF_8)); + assertThat(output.write(buffer)).isEqualTo(5); + assertThat(output.position()).isEqualTo(5); + assertThat(output.size()).isEqualTo(5); + buffer = ByteBuffer.wrap("onten".getBytes(UTF_8)); + assertThat(output.write(buffer)).isEqualTo(5); + assertThat(output.position()).isEqualTo(10); + assertThat(output.size()).isEqualTo(10); + } + assertThat(new String(Files.readAllBytes(path), UTF_8)).isEqualTo("fileconten"); } - assertThat(new String(Files.readAllBytes(path), UTF_8)).isEqualTo("fileconten"); } @Test public void testNewInputStream() throws IOException { - Path path = Paths.get(URI.create("gs://bucket/wat")); - Files.write(path, SINGULARITY.getBytes(UTF_8)); - try (InputStream input = Files.newInputStream(path)) { - byte[] data = new byte[SINGULARITY.getBytes(UTF_8).length]; - input.read(data); - assertThat(new String(data, UTF_8)).isEqualTo(SINGULARITY); + try (FileSystem fs = helper.forBucket("bucket")) { + Path path = fs.getPath("/wat"); + Files.write(path, SINGULARITY.getBytes(UTF_8)); + try (InputStream input = Files.newInputStream(path)) { + byte[] data = new byte[SINGULARITY.getBytes(UTF_8).length]; + input.read(data); + assertThat(new String(data, UTF_8)).isEqualTo(SINGULARITY); + } } } @Test public void testNewInputStream_trailingSlash() throws IOException { - Path path = Paths.get(URI.create("gs://bucket/wat/")); - thrown.expect(CloudStoragePseudoDirectoryException.class); - try (InputStream input = Files.newInputStream(path)) { - input.read(); + try (FileSystem fs = helper.forBucket("bucket")) { + Path path = fs.getPath("/wat/"); + thrown.expect(CloudStoragePseudoDirectoryException.class); + try (InputStream input = Files.newInputStream(path)) { + input.read(); + } } } @Test public void testNewInputStream_notFound() throws IOException { - Path path = Paths.get(URI.create("gs://cry/wednesday")); - thrown.expect(NoSuchFileException.class); - try (InputStream input = Files.newInputStream(path)) { - input.read(); + try (FileSystem fs = helper.forBucket("cry")) { + Path path = fs.getPath("/wednesday"); + thrown.expect(NoSuchFileException.class); + try (InputStream input = Files.newInputStream(path)) { + input.read(); + } } } @Test public void testNewOutputStream() throws IOException { - Path path = Paths.get(URI.create("gs://bucket/wat")); - Files.write(path, SINGULARITY.getBytes(UTF_8)); - try (OutputStream output = Files.newOutputStream(path)) { - output.write(SINGULARITY.getBytes(UTF_8)); + try (FileSystem fs = helper.forBucket("bucket")) { + Path path = fs.getPath("/wat"); + Files.write(path, SINGULARITY.getBytes(UTF_8)); + try (OutputStream output = Files.newOutputStream(path)) { + output.write(SINGULARITY.getBytes(UTF_8)); + } + assertThat(new String(Files.readAllBytes(path), UTF_8)).isEqualTo(SINGULARITY); } - assertThat(new String(Files.readAllBytes(path), UTF_8)).isEqualTo(SINGULARITY); } @Test public void testNewOutputStream_truncateByDefault() throws IOException { - Path path = Paths.get(URI.create("gs://bucket/wat")); - Files.write(path, SINGULARITY.getBytes(UTF_8)); - Files.write(path, "hello".getBytes(UTF_8)); - try (OutputStream output = Files.newOutputStream(path)) { - output.write(SINGULARITY.getBytes(UTF_8)); + try (FileSystem fs = helper.forBucket("bucket")) { + Path path = fs.getPath("/wat"); + Files.write(path, SINGULARITY.getBytes(UTF_8)); + Files.write(path, "hello".getBytes(UTF_8)); + try (OutputStream output = Files.newOutputStream(path)) { + output.write(SINGULARITY.getBytes(UTF_8)); + } + assertThat(new String(Files.readAllBytes(path), UTF_8)).isEqualTo(SINGULARITY); } - assertThat(new String(Files.readAllBytes(path), UTF_8)).isEqualTo(SINGULARITY); } @Test public void testNewOutputStream_truncateExplicitly() throws IOException { - Path path = Paths.get(URI.create("gs://bucket/wat")); - Files.write(path, SINGULARITY.getBytes(UTF_8)); - Files.write(path, "hello".getBytes(UTF_8)); - try (OutputStream output = Files.newOutputStream(path, TRUNCATE_EXISTING)) { - output.write(SINGULARITY.getBytes(UTF_8)); + try (FileSystem fs = helper.forBucket("bucket")) { + Path path = fs.getPath("/wat"); + Files.write(path, SINGULARITY.getBytes(UTF_8)); + Files.write(path, "hello".getBytes(UTF_8)); + try (OutputStream output = Files.newOutputStream(path, TRUNCATE_EXISTING)) { + output.write(SINGULARITY.getBytes(UTF_8)); + } + assertThat(new String(Files.readAllBytes(path), UTF_8)).isEqualTo(SINGULARITY); } - assertThat(new String(Files.readAllBytes(path), UTF_8)).isEqualTo(SINGULARITY); } @Test public void testNewOutputStream_trailingSlash() throws IOException { - Path path = Paths.get(URI.create("gs://bucket/wat/")); - thrown.expect(CloudStoragePseudoDirectoryException.class); - Files.newOutputStream(path); + try (FileSystem fs = helper.forBucket("bucket")) { + Path path = fs.getPath("/wat/"); + thrown.expect(CloudStoragePseudoDirectoryException.class); + Files.newOutputStream(path); + } } @Test public void testNewOutputStream_createNew() throws IOException { - Path path = Paths.get(URI.create("gs://cry/wednesday")); - Files.newOutputStream(path, CREATE_NEW); + try (FileSystem fs = helper.forBucket("cry")) { + Path path = fs.getPath("/wednesday"); + Files.newOutputStream(path, CREATE_NEW); + } } @Test public void testNewOutputStream_createNew_alreadyExists() throws IOException { - Path path = Paths.get(URI.create("gs://cry/wednesday")); - Files.write(path, SINGULARITY.getBytes(UTF_8)); - thrown.expect(FileAlreadyExistsException.class); - Files.newOutputStream(path, CREATE_NEW); + try (FileSystem fs = helper.forBucket("cry")) { + Path path = fs.getPath("/wednesday"); + Files.write(path, SINGULARITY.getBytes(UTF_8)); + thrown.expect(FileAlreadyExistsException.class); + Files.newOutputStream(path, CREATE_NEW); + } } @Test public void testWrite_objectNameWithExtraSlashes_throwsIae() throws IOException { - Path path = Paths.get(URI.create("gs://double/slash//yep")); - thrown.expect(IllegalArgumentException.class); - Files.write(path, FILE_CONTENTS, UTF_8); + try (FileSystem fs = helper.forBucket("double")) { + Path path = fs.getPath("/slash//yep"); + thrown.expect(IllegalArgumentException.class); + Files.write(path, FILE_CONTENTS, UTF_8); + } } @Test public void testWrite_objectNameWithExtraSlashes_canBeNormalized() throws IOException { - try (CloudStorageFileSystem fs = forBucket("greenbean", permitEmptyPathComponents(false))) { + try (CloudStorageFileSystem fs = + helper.forBucket("greenbean", permitEmptyPathComponents(false))) { Path path = fs.getPath("adipose//yep").normalize(); Files.write(path, FILE_CONTENTS, UTF_8); assertThat(Files.readAllLines(path, UTF_8)).isEqualTo(FILE_CONTENTS); @@ -300,7 +338,8 @@ public void testWrite_objectNameWithExtraSlashes_canBeNormalized() throws IOExce @Test public void testWrite_objectNameWithExtraSlashes_permitEmptyPathComponents() throws IOException { - try (CloudStorageFileSystem fs = forBucket("greenbean", permitEmptyPathComponents(true))) { + try (CloudStorageFileSystem fs = + helper.forBucket("greenbean", permitEmptyPathComponents(true))) { Path path = fs.getPath("adipose//yep"); Files.write(path, FILE_CONTENTS, UTF_8); assertThat(Files.readAllLines(path, UTF_8)).isEqualTo(FILE_CONTENTS); @@ -310,16 +349,18 @@ public void testWrite_objectNameWithExtraSlashes_permitEmptyPathComponents() thr @Test public void testWrite_absoluteObjectName_prefixSlashGetsRemoved() throws IOException { - Path path = Paths.get(URI.create("gs://greenbean/adipose/yep")); - Files.write(path, FILE_CONTENTS, UTF_8); - assertThat(Files.readAllLines(path, UTF_8)).isEqualTo(FILE_CONTENTS); - assertThat(Files.exists(path)).isTrue(); + try (CloudStorageFileSystem fs = helper.forBucket("greenbean")) { + Path path = fs.getPath("/adipose/yep"); + Files.write(path, FILE_CONTENTS, UTF_8); + assertThat(Files.readAllLines(path, UTF_8)).isEqualTo(FILE_CONTENTS); + assertThat(Files.exists(path)).isTrue(); + } } @Test public void testWrite_absoluteObjectName_disableStrip_slashGetsPreserved() throws IOException { try (CloudStorageFileSystem fs = - forBucket( + helper.forBucket( "greenbean", CloudStorageConfiguration.builder().stripPrefixSlash(false).build())) { Path path = fs.getPath("/adipose/yep"); Files.write(path, FILE_CONTENTS, UTF_8); @@ -330,85 +371,101 @@ public void testWrite_absoluteObjectName_disableStrip_slashGetsPreserved() throw @Test public void testWrite() throws IOException { - Path path = Paths.get(URI.create("gs://greenbean/adipose")); - Files.write(path, FILE_CONTENTS, UTF_8); - assertThat(Files.readAllLines(path, UTF_8)).isEqualTo(FILE_CONTENTS); + try (FileSystem fs = helper.forBucket("greenbean")) { + Path path = fs.getPath("/adipose"); + Files.write(path, FILE_CONTENTS, UTF_8); + assertThat(Files.readAllLines(path, UTF_8)).isEqualTo(FILE_CONTENTS); + } } @Test public void testWriteOnClose() throws IOException { - Path path = Paths.get(URI.create("gs://greenbean/adipose")); - try (SeekableByteChannel chan = Files.newByteChannel(path, StandardOpenOption.WRITE)) { - // writing lots of contents to defeat channel-internal buffering. - for (int i = 0; i < 9999; i++) { - for (String s : FILE_CONTENTS) { - chan.write(ByteBuffer.wrap(s.getBytes(UTF_8))); + try (FileSystem fs = helper.forBucket("greenbean")) { + Path path = fs.getPath("/adipose"); + try (SeekableByteChannel chan = Files.newByteChannel(path, StandardOpenOption.WRITE)) { + // writing lots of contents to defeat channel-internal buffering. + for (int i = 0; i < 9999; i++) { + for (String s : FILE_CONTENTS) { + chan.write(ByteBuffer.wrap(s.getBytes(UTF_8))); + } + } + try { + Files.size(path); + // we shouldn't make it to this line. Not using thrown.expect because + // I still want to run a few lines after the exception. + assertThat(false).isTrue(); + } catch (NoSuchFileException nsf) { + // that's what we wanted, we're good. } } - try { - Files.size(path); - // we shouldn't make it to this line. Not using thrown.expect because - // I still want to run a few lines after the exception. - assertThat(false).isTrue(); - } catch (NoSuchFileException nsf) { - // that's what we wanted, we're good. - } + // channel now closed, the file should be there and with the new contents. + assertThat(Files.exists(path)).isTrue(); + assertThat(Files.size(path)).isGreaterThan(100L); } - // channel now closed, the file should be there and with the new contents. - assertThat(Files.exists(path)).isTrue(); - assertThat(Files.size(path)).isGreaterThan(100L); } @Test public void testWrite_trailingSlash() throws IOException { - thrown.expect(CloudStoragePseudoDirectoryException.class); - Files.write(Paths.get(URI.create("gs://greenbean/adipose/")), FILE_CONTENTS, UTF_8); + try (FileSystem fs = helper.forBucket("greenbean")) { + thrown.expect(CloudStoragePseudoDirectoryException.class); + Files.write(fs.getPath("/adipose/"), FILE_CONTENTS, UTF_8); + } } @Test public void testExists() throws IOException { - assertThat(Files.exists(Paths.get(URI.create("gs://military/fashion")))).isFalse(); - Files.write(Paths.get(URI.create("gs://military/fashion")), "(✿◕ ‿◕ )ノ".getBytes(UTF_8)); - assertThat(Files.exists(Paths.get(URI.create("gs://military/fashion")))).isTrue(); + try (FileSystem fs = helper.forBucket("military")) { + assertThat(Files.exists(fs.getPath("/fashion"))).isFalse(); + Files.write(fs.getPath("/fashion"), "(✿◕ ‿◕ )ノ".getBytes(UTF_8)); + assertThat(Files.exists(fs.getPath("/fashion"))).isTrue(); + } } @Test - public void testExists_trailingSlash() { - assertThat(Files.exists(Paths.get(URI.create("gs://military/fashion/")))).isTrue(); - assertThat(Files.exists(Paths.get(URI.create("gs://military/fashion/.")))).isTrue(); - assertThat(Files.exists(Paths.get(URI.create("gs://military/fashion/..")))).isTrue(); + public void testExists_trailingSlash() throws IOException { + try (FileSystem fs = helper.forBucket("military")) { + assertThat(Files.exists(fs.getPath("/fashion/"))).isTrue(); + assertThat(Files.exists(fs.getPath("/fashion/."))).isTrue(); + assertThat(Files.exists(fs.getPath("/fashion/.."))).isTrue(); + } } @Test - public void testExists_trailingSlash_disablePseudoDirectories() { - try (CloudStorageFileSystem fs = forBucket("military", usePseudoDirectories(false))) { + public void testExists_trailingSlash_disablePseudoDirectories() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("military", usePseudoDirectories(false))) { assertThat(Files.exists(fs.getPath("fashion/"))).isFalse(); } } @Test public void testDelete() throws IOException { - Files.write(Paths.get(URI.create("gs://love/fashion")), "(✿◕ ‿◕ )ノ".getBytes(UTF_8)); - assertThat(Files.exists(Paths.get(URI.create("gs://love/fashion")))).isTrue(); - Files.delete(Paths.get(URI.create("gs://love/fashion"))); - assertThat(Files.exists(Paths.get(URI.create("gs://love/fashion")))).isFalse(); + try (FileSystem fs = helper.forBucket("love")) { + Files.write(fs.getPath("/fashion"), "(✿◕ ‿◕ )ノ".getBytes(UTF_8)); + assertThat(Files.exists(fs.getPath("/fashion"))).isTrue(); + Files.delete(fs.getPath("/fashion")); + assertThat(Files.exists(fs.getPath("/fashion"))).isFalse(); + } } @Test public void testDelete_dotDirNotNormalized_throwsIae() throws IOException { - thrown.expect(IllegalArgumentException.class); - Files.delete(Paths.get(URI.create("gs://love/fly/../passion"))); + try (FileSystem fs = helper.forBucket("love")) { + thrown.expect(IllegalArgumentException.class); + Files.delete(fs.getPath("/fly/../passion")); + } } @Test public void testDelete_trailingSlash() throws IOException { - thrown.expect(CloudStoragePseudoDirectoryException.class); - Files.delete(Paths.get(URI.create("gs://love/passion/"))); + try (FileSystem fs = helper.forBucket("love")) { + thrown.expect(CloudStoragePseudoDirectoryException.class); + Files.delete(fs.getPath("/passion/")); + } } @Test public void testDelete_trailingSlash_disablePseudoDirectories() throws IOException { - try (CloudStorageFileSystem fs = forBucket("pumpkin", usePseudoDirectories(false))) { + try (CloudStorageFileSystem fs = helper.forBucket("pumpkin", usePseudoDirectories(false))) { Path path = fs.getPath("wat/"); Files.write(path, FILE_CONTENTS, UTF_8); assertThat(Files.exists(path)); @@ -419,106 +476,134 @@ public void testDelete_trailingSlash_disablePseudoDirectories() throws IOExcepti @Test public void testDelete_notFound() throws IOException { - thrown.expect(NoSuchFileException.class); - Files.delete(Paths.get(URI.create("gs://loveh/passionehu"))); + try (FileSystem fs = helper.forBucket("loveh")) { + thrown.expect(NoSuchFileException.class); + Files.delete(fs.getPath("/passionehu")); + } } @Test public void testDeleteIfExists() throws IOException { - Files.write(Paths.get(URI.create("gs://love/passionz")), "(✿◕ ‿◕ )ノ".getBytes(UTF_8)); - assertThat(Files.deleteIfExists(Paths.get(URI.create("gs://love/passionz")))).isTrue(); + try (FileSystem fs = helper.forBucket("love")) { + Files.write(fs.getPath("/passionz"), "(✿◕ ‿◕ )ノ".getBytes(UTF_8)); + assertThat(Files.deleteIfExists(fs.getPath("/passionz"))).isTrue(); + } } @Test public void testDeleteIfExists_trailingSlash() throws IOException { - thrown.expect(CloudStoragePseudoDirectoryException.class); - Files.deleteIfExists(Paths.get(URI.create("gs://love/passion/"))); + try (FileSystem fs = helper.forBucket("love")) { + thrown.expect(CloudStoragePseudoDirectoryException.class); + Files.deleteIfExists(fs.getPath("/passion/")); + } } @Test - public void testCopy() throws IOException { - Path source = Paths.get(URI.create("gs://military/fashion.show")); - Path target = Paths.get(URI.create("gs://greenbean/adipose")); - Files.write(source, "(✿◕ ‿◕ )ノ".getBytes(UTF_8)); - Files.copy(source, target); - assertThat(new String(Files.readAllBytes(target), UTF_8)).isEqualTo("(✿◕ ‿◕ )ノ"); - assertThat(Files.exists(source)).isTrue(); - assertThat(Files.exists(target)).isTrue(); + public void testCopyAcrossBuckets() throws IOException { + try (FileSystem fsMilitary = helper.forBucket("military"); + FileSystem fsGreenbean = helper.forBucket("greenbean")) { + Path source = fsMilitary.getPath("/fashion.show"); + Path target = fsGreenbean.getPath("/adipose"); + Files.write(source, "(✿◕ ‿◕ )ノ".getBytes(UTF_8)); + Files.copy(source, target); + assertThat(new String(Files.readAllBytes(target), UTF_8)).isEqualTo("(✿◕ ‿◕ )ノ"); + assertThat(Files.exists(source)).isTrue(); + assertThat(Files.exists(target)).isTrue(); + } } @Test public void testCopy_sourceMissing_throwsNoSuchFileException() throws IOException { - thrown.expect(NoSuchFileException.class); - Files.copy( - Paths.get(URI.create("gs://military/fashion.show")), - Paths.get(URI.create("gs://greenbean/adipose"))); + try (FileSystem fsMilitary = helper.forBucket("military"); + FileSystem fsGreenbean = helper.forBucket("greenbean")) { + thrown.expect(NoSuchFileException.class); + Files.copy(fsMilitary.getPath("/fashion.show"), fsGreenbean.getPath("/adipose")); + } } @Test public void testCopy_targetExists_throwsFileAlreadyExistsException() throws IOException { - Path source = Paths.get(URI.create("gs://military/fashion.show")); - Path target = Paths.get(URI.create("gs://greenbean/adipose")); - Files.write(source, "(✿◕ ‿◕ )ノ".getBytes(UTF_8)); - Files.write(target, "(✿◕ ‿◕ )ノ".getBytes(UTF_8)); - thrown.expect(FileAlreadyExistsException.class); - Files.copy(source, target); + try (FileSystem fsMilitary = helper.forBucket("military"); + FileSystem fsGreenbean = helper.forBucket("greenbean")) { + Path source = fsMilitary.getPath("/fashion.show"); + Path target = fsGreenbean.getPath("/adipose"); + Files.write(source, "(✿◕ ‿◕ )ノ".getBytes(UTF_8)); + Files.write(target, "(✿◕ ‿◕ )ノ".getBytes(UTF_8)); + thrown.expect(FileAlreadyExistsException.class); + Files.copy(source, target); + } } @Test public void testCopyReplace_targetExists_works() throws IOException { - Path source = Paths.get(URI.create("gs://military/fashion.show")); - Path target = Paths.get(URI.create("gs://greenbean/adipose")); - Files.write(source, "(✿◕ ‿◕ )ノ".getBytes(UTF_8)); - Files.write(target, "(✿◕ ‿◕ )ノ".getBytes(UTF_8)); - Files.copy(source, target, REPLACE_EXISTING); + try (FileSystem fsMilitary = helper.forBucket("military"); + FileSystem fsGreenbean = helper.forBucket("greenbean")) { + Path source = fsMilitary.getPath("/fashion.show"); + Path target = fsGreenbean.getPath("/adipose"); + Files.write(source, "(✿◕ ‿◕ )ノ".getBytes(UTF_8)); + Files.write(target, "(✿◕ ‿◕ )ノ".getBytes(UTF_8)); + Files.copy(source, target, REPLACE_EXISTING); + } } @Test public void testCopy_directory_doesNothing() throws IOException { - Path source = Paths.get(URI.create("gs://military/fundir/")); - Path target = Paths.get(URI.create("gs://greenbean/loldir/")); - Files.copy(source, target); + try (FileSystem fs = helper.forBucket("greenbean", usePseudoDirectories(true))) { + Path source = fs.getPath("/fundir/"); + Path target = fs.getPath("/loldir/"); + Files.copy(source, target); + } } @Test public void testCopy_atomic_throwsUnsupported() throws IOException { - Path source = Paths.get(URI.create("gs://military/fashion.show")); - Path target = Paths.get(URI.create("gs://greenbean/adipose")); - Files.write(source, "(✿◕ ‿◕ )ノ".getBytes(UTF_8)); - thrown.expect(UnsupportedOperationException.class); - Files.copy(source, target, ATOMIC_MOVE); + try (FileSystem fsMilitary = helper.forBucket("military"); + FileSystem fsGreenbean = helper.forBucket("greenbean")) { + Path source = fsMilitary.getPath("/fashion.show"); + Path target = fsGreenbean.getPath("/adipose"); + Files.write(source, "(✿◕ ‿◕ )ノ".getBytes(UTF_8)); + thrown.expect(UnsupportedOperationException.class); + Files.copy(source, target, ATOMIC_MOVE); + } } @Test public void testMove() throws IOException { - Path source = Paths.get(URI.create("gs://military/fashion.show")); - Path target = Paths.get(URI.create("gs://greenbean/adipose")); - Files.write(source, "(✿◕ ‿◕ )ノ".getBytes(UTF_8)); - Files.move(source, target); - assertThat(new String(Files.readAllBytes(target), UTF_8)).isEqualTo("(✿◕ ‿◕ )ノ"); - assertThat(Files.exists(source)).isFalse(); - assertThat(Files.exists(target)).isTrue(); + try (FileSystem fs = helper.forBucket("greenbean")) { + Path source = fs.getPath("/fashion.show"); + Path target = fs.getPath("/adipose"); + Files.write(source, "(✿◕ ‿◕ )ノ".getBytes(UTF_8)); + Files.move(source, target); + assertThat(new String(Files.readAllBytes(target), UTF_8)).isEqualTo("(✿◕ ‿◕ )ノ"); + assertThat(Files.exists(source)).isFalse(); + assertThat(Files.exists(target)).isTrue(); + } } @Test public void testCreateDirectory() throws IOException { - Path path = Paths.get(URI.create("gs://greenbean/dir/")); - Files.createDirectory(path); - assertThat(Files.exists(path)).isTrue(); + try (FileSystem fsGreenbean = helper.forBucket("greenbean")) { + Path path = fsGreenbean.getPath("/dir/"); + Files.createDirectory(path); + assertThat(Files.exists(path)).isTrue(); + } } @Test public void testMove_atomicMove_notSupported() throws IOException { - Path source = Paths.get(URI.create("gs://military/fashion.show")); - Path target = Paths.get(URI.create("gs://greenbean/adipose")); - Files.write(source, "(✿◕ ‿◕ )ノ".getBytes(UTF_8)); - thrown.expect(AtomicMoveNotSupportedException.class); - Files.move(source, target, ATOMIC_MOVE); + try (FileSystem fsMilitary = helper.forBucket("military"); + FileSystem fsGreenbean = helper.forBucket("greenbean")) { + Path source = fsMilitary.getPath("/fashion.show"); + Path target = fsGreenbean.getPath("/adipose"); + Files.write(source, "(✿◕ ‿◕ )ノ".getBytes(UTF_8)); + thrown.expect(AtomicMoveNotSupportedException.class); + Files.move(source, target, ATOMIC_MOVE); + } } @Test public void testIsDirectory() throws IOException { - try (FileSystem fs = FileSystems.getFileSystem(URI.create("gs://doodle"))) { + try (FileSystem fs = helper.forBucket("doodle")) { assertThat(Files.isDirectory(fs.getPath(""))).isTrue(); assertThat(Files.isDirectory(fs.getPath("/"))).isTrue(); assertThat(Files.isDirectory(fs.getPath("."))).isTrue(); @@ -531,88 +616,99 @@ public void testIsDirectory() throws IOException { } @Test - public void testIsDirectory_trailingSlash_alwaysTrue() { - assertThat(Files.isDirectory(Paths.get(URI.create("gs://military/fundir/")))).isTrue(); + public void testIsDirectory_trailingSlash_alwaysTrue() throws IOException { + try (FileSystem fs = helper.forBucket("military")) { + assertThat(Files.isDirectory(fs.getPath("/fundir/"))).isTrue(); + } } @Test - public void testIsDirectory_trailingSlash_pseudoDirectoriesDisabled_false() { - try (CloudStorageFileSystem fs = forBucket("doodle", usePseudoDirectories(false))) { + public void testIsDirectory_trailingSlash_pseudoDirectoriesDisabled_false() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle", usePseudoDirectories(false))) { assertThat(Files.isDirectory(fs.getPath("fundir/"))).isFalse(); } } @Test public void testCopy_withCopyAttributes_preservesAttributes() throws IOException { - Path source = Paths.get(URI.create("gs://military/fashion.show")); - Path target = Paths.get(URI.create("gs://greenbean/adipose")); - Files.write( - source, - "(✿◕ ‿◕ )ノ".getBytes(UTF_8), - withMimeType("text/lolcat"), - withCacheControl("public; max-age=666"), - withContentEncoding("foobar"), - withContentDisposition("my-content-disposition"), - withUserMetadata("answer", "42")); - Files.copy(source, target, COPY_ATTRIBUTES); - - CloudStorageFileAttributes attributes = - Files.readAttributes(target, CloudStorageFileAttributes.class); - assertThat(attributes.mimeType()).hasValue("text/lolcat"); - assertThat(attributes.cacheControl()).hasValue("public; max-age=666"); - assertThat(attributes.contentEncoding()).hasValue("foobar"); - assertThat(attributes.contentDisposition()).hasValue("my-content-disposition"); - assertThat(attributes.userMetadata().containsKey("answer")).isTrue(); - assertThat(attributes.userMetadata().get("answer")).isEqualTo("42"); + try (FileSystem fsMilitary = helper.forBucket("military"); + FileSystem fsGreenbean = helper.forBucket("greenbean")) { + Path source = fsMilitary.getPath("/fashion.show"); + Path target = fsGreenbean.getPath("/adipose"); + Files.write( + source, + "(✿◕ ‿◕ )ノ".getBytes(UTF_8), + withMimeType("text/lolcat"), + withCacheControl("public; max-age=666"), + withContentEncoding("foobar"), + withContentDisposition("my-content-disposition"), + withUserMetadata("answer", "42")); + Files.copy(source, target, COPY_ATTRIBUTES); + + CloudStorageFileAttributes attributes = + Files.readAttributes(target, CloudStorageFileAttributes.class); + assertThat(attributes.mimeType()).hasValue("text/lolcat"); + assertThat(attributes.cacheControl()).hasValue("public; max-age=666"); + assertThat(attributes.contentEncoding()).hasValue("foobar"); + assertThat(attributes.contentDisposition()).hasValue("my-content-disposition"); + assertThat(attributes.userMetadata().containsKey("answer")).isTrue(); + assertThat(attributes.userMetadata().get("answer")).isEqualTo("42"); + } } @Test public void testCopy_withoutOptions_doesntPreservesAttributes() throws IOException { - Path source = Paths.get(URI.create("gs://military/fashion.show")); - Path target = Paths.get(URI.create("gs://greenbean/adipose")); - Files.write( - source, - "(✿◕ ‿◕ )ノ".getBytes(UTF_8), - withMimeType("text/lolcat"), - withCacheControl("public; max-age=666"), - withUserMetadata("answer", "42")); - Files.copy(source, target); - - CloudStorageFileAttributes attributes = - Files.readAttributes(target, CloudStorageFileAttributes.class); - String mimeType = attributes.mimeType().orNull(); - String cacheControl = attributes.cacheControl().orNull(); - assertThat(mimeType).isNotEqualTo("text/lolcat"); - assertThat(cacheControl).isNull(); - assertThat(attributes.userMetadata().containsKey("answer")).isFalse(); + try (FileSystem fsMilitary = helper.forBucket("military"); + FileSystem fsGreenbean = helper.forBucket("greenbean")) { + Path source = fsMilitary.getPath("/fashion.show"); + Path target = fsGreenbean.getPath("/adipose"); + Files.write( + source, + "(✿◕ ‿◕ )ノ".getBytes(UTF_8), + withMimeType("text/lolcat"), + withCacheControl("public; max-age=666"), + withUserMetadata("answer", "42")); + Files.copy(source, target); + + CloudStorageFileAttributes attributes = + Files.readAttributes(target, CloudStorageFileAttributes.class); + String mimeType = attributes.mimeType().orNull(); + String cacheControl = attributes.cacheControl().orNull(); + assertThat(mimeType).isNotEqualTo("text/lolcat"); + assertThat(cacheControl).isNull(); + assertThat(attributes.userMetadata().containsKey("answer")).isFalse(); + } } @Test public void testCopy_overwriteAttributes() throws IOException { - Path source = Paths.get(URI.create("gs://military/fashion.show")); - Path target1 = Paths.get(URI.create("gs://greenbean/adipose")); - Path target2 = Paths.get(URI.create("gs://greenbean/round")); - Files.write( - source, - "(✿◕ ‿◕ )ノ".getBytes(UTF_8), - withMimeType("text/lolcat"), - withCacheControl("public; max-age=666")); - Files.copy(source, target1, COPY_ATTRIBUTES); - Files.copy(source, target2, COPY_ATTRIBUTES, withMimeType("text/palfun")); - - CloudStorageFileAttributes attributes = - Files.readAttributes(target1, CloudStorageFileAttributes.class); - assertThat(attributes.mimeType()).hasValue("text/lolcat"); - assertThat(attributes.cacheControl()).hasValue("public; max-age=666"); - - attributes = Files.readAttributes(target2, CloudStorageFileAttributes.class); - assertThat(attributes.mimeType()).hasValue("text/palfun"); - assertThat(attributes.cacheControl()).hasValue("public; max-age=666"); + try (FileSystem fsMilitary = helper.forBucket("military"); + FileSystem fsGreenbean = helper.forBucket("greenbean")) { + Path source = fsMilitary.getPath("/fashion.show"); + Path target1 = fsGreenbean.getPath("/adipose"); + Path target2 = fsGreenbean.getPath("/round"); + Files.write( + source, + "(✿◕ ‿◕ )ノ".getBytes(UTF_8), + withMimeType("text/lolcat"), + withCacheControl("public; max-age=666")); + Files.copy(source, target1, COPY_ATTRIBUTES); + Files.copy(source, target2, COPY_ATTRIBUTES, withMimeType("text/palfun")); + + CloudStorageFileAttributes attributes = + Files.readAttributes(target1, CloudStorageFileAttributes.class); + assertThat(attributes.mimeType()).hasValue("text/lolcat"); + assertThat(attributes.cacheControl()).hasValue("public; max-age=666"); + + attributes = Files.readAttributes(target2, CloudStorageFileAttributes.class); + assertThat(attributes.mimeType()).hasValue("text/palfun"); + assertThat(attributes.cacheControl()).hasValue("public; max-age=666"); + } } @Test public void testNullness() throws IOException, NoSuchMethodException, SecurityException { - try (FileSystem fs = FileSystems.getFileSystem(URI.create("gs://blood"))) { + try (FileSystem fs = helper.forBucket("blood")) { NullPointerTester tester = new NullPointerTester(); tester.ignore(CloudStorageFileSystemProvider.class.getMethod("equals", Object.class)); tester.setDefault(URI.class, URI.create("gs://blood")); @@ -627,19 +723,14 @@ public void testNullness() throws IOException, NoSuchMethodException, SecurityEx } @Test - public void testProviderEquals() { - Path path1 = Paths.get(URI.create("gs://bucket/tuesday")); - Path path2 = Paths.get(URI.create("gs://blood/wednesday")); - Path path3 = Paths.get("tmp"); - assertThat(path1.getFileSystem().provider()).isEqualTo(path2.getFileSystem().provider()); - assertThat(path1.getFileSystem().provider()).isNotEqualTo(path3.getFileSystem().provider()); - } - - private static CloudStorageConfiguration permitEmptyPathComponents(boolean value) { - return CloudStorageConfiguration.builder().permitEmptyPathComponents(value).build(); - } - - private static CloudStorageConfiguration usePseudoDirectories(boolean value) { - return CloudStorageConfiguration.builder().usePseudoDirectories(value).build(); + public void testProviderEquals() throws IOException { + try (FileSystem fs1 = helper.forBucket("bucket"); + FileSystem fs2 = helper.forBucket("blood")) { + Path path1 = fs1.getPath("/tuesday"); + Path path2 = fs2.getPath("/wednesday"); + Path path3 = FileSystems.getDefault().getPath("tmp"); + assertThat(path1.getFileSystem().provider()).isEqualTo(path2.getFileSystem().provider()); + assertThat(path1.getFileSystem().provider()).isNotEqualTo(path3.getFileSystem().provider()); + } } } diff --git a/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileSystemTest.java b/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileSystemTest.java index 3ef113e14744..96c242e39369 100644 --- a/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileSystemTest.java +++ b/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageFileSystemTest.java @@ -5,19 +5,15 @@ import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; -import com.google.gcloud.storage.testing.LocalGcsHelper; +import com.google.gcloud.storage.testing.FakeStorageRpc; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import java.io.IOException; -import java.net.URI; import java.nio.file.FileSystem; -import java.nio.file.FileSystems; import java.nio.file.Files; -import java.nio.file.Paths; /** * Unit tests for {@link CloudStorageFileSystem}. @@ -35,14 +31,12 @@ public class CloudStorageFileSystemTest { + "The Heart-ache, and the thousand Natural shocks\n" + "That Flesh is heir to? 'Tis a consummation\n"; - @Before - public void before() { - CloudStorageFileSystemProvider.setGCloudOptions(LocalGcsHelper.options()); - } + private final FakeStorageRpc storage = new FakeStorageRpc(true); + private final NioTestHelper helper = new NioTestHelper(storage); @Test public void testGetPath() throws IOException { - try (FileSystem fs = CloudStorageFileSystem.forBucket("bucket")) { + try (FileSystem fs = helper.forBucket("bucket")) { assertThat(fs.getPath("/angel").toString()).isEqualTo("/angel"); assertThat(fs.getPath("/angel").toUri().toString()).isEqualTo("gs://bucket/angel"); } @@ -50,39 +44,38 @@ public void testGetPath() throws IOException { @Test public void testWrite() throws IOException { - try (FileSystem fs = CloudStorageFileSystem.forBucket("bucket")) { + try (FileSystem fs = helper.forBucket("bucket")) { Files.write(fs.getPath("/angel"), ALONE.getBytes(UTF_8)); + assertThat(new String(Files.readAllBytes(fs.getPath("/angel")), UTF_8)).isEqualTo(ALONE); } - assertThat(new String(Files.readAllBytes(Paths.get(URI.create("gs://bucket/angel"))), UTF_8)) - .isEqualTo(ALONE); } @Test public void testRead() throws IOException { - Files.write(Paths.get(URI.create("gs://bucket/angel")), ALONE.getBytes(UTF_8)); - try (FileSystem fs = CloudStorageFileSystem.forBucket("bucket")) { + try (FileSystem fs = helper.forBucket("bucket")) { + Files.write(fs.getPath("/angel"), ALONE.getBytes(UTF_8)); assertThat(new String(Files.readAllBytes(fs.getPath("/angel")), UTF_8)).isEqualTo(ALONE); } } @Test public void testExists_false() throws IOException { - try (FileSystem fs = FileSystems.getFileSystem(URI.create("gs://bucket"))) { + try (FileSystem fs = helper.forBucket("bucket")) { assertThat(Files.exists(fs.getPath("/angel"))).isFalse(); } } @Test public void testExists_true() throws IOException { - Files.write(Paths.get(URI.create("gs://bucket/angel")), ALONE.getBytes(UTF_8)); - try (FileSystem fs = CloudStorageFileSystem.forBucket("bucket")) { + try (FileSystem fs = helper.forBucket("bucket")) { + Files.write(fs.getPath("/angel"), ALONE.getBytes(UTF_8)); assertThat(Files.exists(fs.getPath("/angel"))).isTrue(); } } @Test public void testGetters() throws IOException { - try (FileSystem fs = CloudStorageFileSystem.forBucket("bucket")) { + try (FileSystem fs = helper.forBucket("bucket")) { assertThat(fs.isOpen()).isTrue(); assertThat(fs.isReadOnly()).isFalse(); assertThat(fs.getRootDirectories()).containsExactly(fs.getPath("/")); @@ -94,10 +87,10 @@ public void testGetters() throws IOException { @Test public void testEquals() throws IOException { - try (FileSystem bucket1 = CloudStorageFileSystem.forBucket("bucket"); - FileSystem bucket2 = FileSystems.getFileSystem(URI.create("gs://bucket")); - FileSystem doge1 = CloudStorageFileSystem.forBucket("doge"); - FileSystem doge2 = FileSystems.getFileSystem(URI.create("gs://doge"))) { + try (FileSystem bucket1 = helper.forBucket("bucket"); + FileSystem bucket2 = helper.forBucket("bucket"); + FileSystem doge1 = helper.forBucket("doge"); + FileSystem doge2 = helper.forBucket("doge")) { new EqualsTester() .addEqualityGroup(bucket1, bucket2) .addEqualityGroup(doge1, doge2) @@ -107,11 +100,11 @@ public void testEquals() throws IOException { @Test public void testNullness() throws IOException, NoSuchMethodException, SecurityException { - try (FileSystem fs = FileSystems.getFileSystem(URI.create("gs://bucket"))) { + try (FileSystem fs = helper.forBucket("bucket")) { NullPointerTester tester = new NullPointerTester() .ignore(CloudStorageFileSystem.class.getMethod("equals", Object.class)) - .setDefault(CloudStorageConfiguration.class, CloudStorageConfiguration.DEFAULT); + .setDefault(CloudStorageConfiguration.class, CloudStorageConfiguration.getDefault()); tester.testAllPublicStaticMethods(CloudStorageFileSystem.class); tester.testAllPublicInstanceMethods(fs); } diff --git a/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageOptionsTest.java b/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageOptionsTest.java index e852d4035a1a..6b7daca98c3e 100644 --- a/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageOptionsTest.java +++ b/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageOptionsTest.java @@ -12,18 +12,16 @@ import com.google.common.testing.NullPointerTester; import com.google.gcloud.storage.Acl; -import com.google.gcloud.storage.testing.LocalGcsHelper; +import com.google.gcloud.storage.testing.FakeStorageRpc; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import java.io.IOException; -import java.net.URI; +import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; /** * Unit tests for {@link CloudStorageOptions}. @@ -31,77 +29,89 @@ @RunWith(JUnit4.class) public class CloudStorageOptionsTest { - @Before - public void before() { - CloudStorageFileSystemProvider.setGCloudOptions(LocalGcsHelper.options()); - } + private final FakeStorageRpc storage = new FakeStorageRpc(true); + private final NioTestHelper helper = new NioTestHelper(storage); @Test public void testWithoutCaching() throws IOException { - Path path = Paths.get(URI.create("gs://bucket/path")); - Files.write(path, "(✿◕ ‿◕ )ノ".getBytes(UTF_8), withoutCaching()); - assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).cacheControl().get()) - .isEqualTo("no-cache"); + try (FileSystem fs = helper.forBucket("bucket")) { + Path path = fs.getPath("/path"); + Files.write(path, "(✿◕ ‿◕ )ノ".getBytes(UTF_8), withoutCaching()); + assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).cacheControl().get()) + .isEqualTo("no-cache"); + } } @Test public void testCacheControl() throws IOException { - Path path = Paths.get(URI.create("gs://bucket/path")); - Files.write(path, "(✿◕ ‿◕ )ノ".getBytes(UTF_8), withCacheControl("potato")); - assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).cacheControl().get()) - .isEqualTo("potato"); + try (FileSystem fs = helper.forBucket("bucket")) { + Path path = fs.getPath("/path"); + Files.write(path, "(✿◕ ‿◕ )ノ".getBytes(UTF_8), withCacheControl("potato")); + assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).cacheControl().get()) + .isEqualTo("potato"); + } } @Test public void testWithAcl() throws IOException { - Path path = Paths.get(URI.create("gs://bucket/path")); - Acl acl = Acl.of(new Acl.User("king@example.com"), Acl.Role.OWNER); - Files.write(path, "(✿◕ ‿◕ )ノ".getBytes(UTF_8), withAcl(acl)); - assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).acl().get()) - .contains(acl); + try (FileSystem fs = helper.forBucket("bucket")) { + Path path = fs.getPath("/path"); + Acl acl = Acl.of(new Acl.User("king@example.com"), Acl.Role.OWNER); + Files.write(path, "(✿◕ ‿◕ )ノ".getBytes(UTF_8), withAcl(acl)); + assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).acl().get()) + .contains(acl); + } } @Test public void testWithContentDisposition() throws IOException { - Path path = Paths.get(URI.create("gs://bucket/path")); - Files.write(path, "(✿◕ ‿◕ )ノ".getBytes(UTF_8), withContentDisposition("bubbly fun")); - assertThat( - Files.readAttributes(path, CloudStorageFileAttributes.class).contentDisposition().get()) - .isEqualTo("bubbly fun"); + try (FileSystem fs = helper.forBucket("bucket")) { + Path path = fs.getPath("/path"); + Files.write(path, "(✿◕ ‿◕ )ノ".getBytes(UTF_8), withContentDisposition("bubbly fun")); + assertThat( + Files.readAttributes(path, CloudStorageFileAttributes.class).contentDisposition().get()) + .isEqualTo("bubbly fun"); + } } @Test public void testWithContentEncoding() throws IOException { - Path path = Paths.get(URI.create("gs://bucket/path")); - Files.write(path, "(✿◕ ‿◕ )ノ".getBytes(UTF_8), withContentEncoding("gzip")); - assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).contentEncoding().get()) - .isEqualTo("gzip"); + try (FileSystem fs = helper.forBucket("bucket")) { + Path path = fs.getPath("/path"); + Files.write(path, "(✿◕ ‿◕ )ノ".getBytes(UTF_8), withContentEncoding("gzip")); + assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).contentEncoding().get()) + .isEqualTo("gzip"); + } } @Test public void testWithUserMetadata() throws IOException { - Path path = Paths.get(URI.create("gs://bucket/path")); - Files.write( - path, - "(✿◕ ‿◕ )ノ".getBytes(UTF_8), - withUserMetadata("nolo", "contendere"), - withUserMetadata("eternal", "sadness")); - assertThat( - Files.readAttributes(path, CloudStorageFileAttributes.class).userMetadata().get("nolo")) - .isEqualTo("contendere"); - assertThat( - Files.readAttributes(path, CloudStorageFileAttributes.class) - .userMetadata() - .get("eternal")) - .isEqualTo("sadness"); + try (FileSystem fs = helper.forBucket("bucket")) { + Path path = fs.getPath("/path"); + Files.write( + path, + "(✿◕ ‿◕ )ノ".getBytes(UTF_8), + withUserMetadata("nolo", "contendere"), + withUserMetadata("eternal", "sadness")); + assertThat( + Files.readAttributes(path, CloudStorageFileAttributes.class).userMetadata().get("nolo")) + .isEqualTo("contendere"); + assertThat( + Files.readAttributes(path, CloudStorageFileAttributes.class) + .userMetadata() + .get("eternal")) + .isEqualTo("sadness"); + } } @Test public void testWithMimeType_string() throws IOException { - Path path = Paths.get(URI.create("gs://bucket/path")); - Files.write(path, "(✿◕ ‿◕ )ノ".getBytes(UTF_8), withMimeType("text/plain")); - assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).mimeType().get()) - .isEqualTo("text/plain"); + try (FileSystem fs = helper.forBucket("bucket")) { + Path path = fs.getPath("/path"); + Files.write(path, "(✿◕ ‿◕ )ノ".getBytes(UTF_8), withMimeType("text/plain")); + assertThat(Files.readAttributes(path, CloudStorageFileAttributes.class).mimeType().get()) + .isEqualTo("text/plain"); + } } @Test diff --git a/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStoragePathTest.java b/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStoragePathTest.java index 24393f175b2b..6ec4a740f848 100644 --- a/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStoragePathTest.java +++ b/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStoragePathTest.java @@ -1,14 +1,15 @@ package com.google.gcloud.storage.contrib.nio; import static com.google.common.truth.Truth.assertThat; -import static com.google.gcloud.storage.contrib.nio.CloudStorageFileSystem.forBucket; +import static com.google.gcloud.storage.contrib.nio.NioTestHelper.permitEmptyPathComponents; +import static com.google.gcloud.storage.contrib.nio.NioTestHelper.stripPrefixSlash; +import static com.google.gcloud.storage.contrib.nio.NioTestHelper.workingDirectory; import com.google.common.collect.Iterables; import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; -import com.google.gcloud.storage.testing.LocalGcsHelper; +import com.google.gcloud.storage.testing.FakeStorageRpc; -import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -16,7 +17,6 @@ import org.junit.runners.JUnit4; import java.io.IOException; -import java.net.URI; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Path; @@ -30,75 +30,74 @@ public class CloudStoragePathTest { @Rule public final ExpectedException thrown = ExpectedException.none(); - @Before - public void before() { - CloudStorageFileSystemProvider.setGCloudOptions(LocalGcsHelper.options()); - } + private final FakeStorageRpc storage = new FakeStorageRpc(true); + private final NioTestHelper helper = new NioTestHelper(storage); @Test - public void testCreate_neverRemoveExtraSlashes() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testCreate_neverRemoveExtraSlashes() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat(fs.getPath("lol//cat").toString()).isEqualTo("lol//cat"); assertThat((Object) fs.getPath("lol//cat")).isEqualTo(fs.getPath("lol//cat")); } } @Test - public void testCreate_preservesTrailingSlash() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testCreate_preservesTrailingSlash() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat(fs.getPath("lol/cat/").toString()).isEqualTo("lol/cat/"); assertThat((Object) fs.getPath("lol/cat/")).isEqualTo(fs.getPath("lol/cat/")); } } @Test - public void testGetGcsFilename_empty_notAllowed() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testGetGcsFilename_empty_notAllowed() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { thrown.expect(IllegalArgumentException.class); fs.getPath("").getBlobId(); } } @Test - public void testGetGcsFilename_stripsPrefixSlash() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testGetGcsFilename_stripsPrefixSlash() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat(fs.getPath("/hi").getBlobId().name()).isEqualTo("hi"); } } @Test - public void testGetGcsFilename_overrideStripPrefixSlash_doesntStripPrefixSlash() { - try (CloudStorageFileSystem fs = forBucket("doodle", stripPrefixSlash(false))) { + public void testGetGcsFilename_overrideStripPrefixSlash_doesntStripPrefixSlash() + throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle", stripPrefixSlash(false))) { assertThat(fs.getPath("/hi").getBlobId().name()).isEqualTo("/hi"); } } @Test - public void testGetGcsFilename_extraSlashes_throwsIae() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testGetGcsFilename_extraSlashes_throwsIae() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { thrown.expect(IllegalArgumentException.class); fs.getPath("a//b").getBlobId().name(); } } @Test - public void testGetGcsFilename_overridepermitEmptyPathComponents() { - try (CloudStorageFileSystem fs = forBucket("doodle", permitEmptyPathComponents(true))) { + public void testGetGcsFilename_overridepermitEmptyPathComponents() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle", permitEmptyPathComponents(true))) { assertThat(fs.getPath("a//b").getBlobId().name()).isEqualTo("a//b"); } } @Test - public void testGetGcsFilename_freaksOutOnExtraSlashesAndDotDirs() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testGetGcsFilename_freaksOutOnExtraSlashesAndDotDirs() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { thrown.expect(IllegalArgumentException.class); fs.getPath("a//b/..").getBlobId().name(); } } @Test - public void testNameCount() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testNameCount() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat(fs.getPath("").getNameCount()).isEqualTo(1); assertThat(fs.getPath("/").getNameCount()).isEqualTo(0); assertThat(fs.getPath("/hi/").getNameCount()).isEqualTo(1); @@ -108,8 +107,8 @@ public void testNameCount() { } @Test - public void testGetName() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testGetName() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat(fs.getPath("").getName(0).toString()).isEqualTo(""); assertThat(fs.getPath("/hi").getName(0).toString()).isEqualTo("hi"); assertThat(fs.getPath("hi/there").getName(1).toString()).isEqualTo("there"); @@ -117,24 +116,24 @@ public void testGetName() { } @Test - public void testGetName_negative_throwsIae() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testGetName_negative_throwsIae() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { thrown.expect(IllegalArgumentException.class); fs.getPath("angel").getName(-1); } } @Test - public void testGetName_overflow_throwsIae() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testGetName_overflow_throwsIae() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { thrown.expect(IllegalArgumentException.class); fs.getPath("angel").getName(1); } } @Test - public void testIterator() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testIterator() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat(Iterables.get(fs.getPath("/dog/mog"), 0).toString()).isEqualTo("dog"); assertThat(Iterables.get(fs.getPath("/dog/mog"), 1).toString()).isEqualTo("mog"); assertThat(Iterables.size(fs.getPath("/"))).isEqualTo(0); @@ -144,8 +143,8 @@ public void testIterator() { } @Test - public void testNormalize() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testNormalize() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat(fs.getPath("/").normalize().toString()).isEqualTo("/"); assertThat(fs.getPath("a/x/../b/x/..").normalize().toString()).isEqualTo("a/b/"); assertThat(fs.getPath("/x/x/../../♡").normalize().toString()).isEqualTo("/♡"); @@ -154,38 +153,38 @@ public void testNormalize() { } @Test - public void testNormalize_dot_becomesBlank() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testNormalize_dot_becomesBlank() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat(fs.getPath("").normalize().toString()).isEqualTo(""); assertThat(fs.getPath(".").normalize().toString()).isEqualTo(""); } } @Test - public void testNormalize_trailingSlash_isPreserved() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testNormalize_trailingSlash_isPreserved() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat(fs.getPath("o/").normalize().toString()).isEqualTo("o/"); } } @Test - public void testNormalize_doubleDot_becomesBlank() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testNormalize_doubleDot_becomesBlank() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat(fs.getPath("..").normalize().toString()).isEqualTo(""); assertThat(fs.getPath("../..").normalize().toString()).isEqualTo(""); } } @Test - public void testNormalize_extraSlashes_getRemoved() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testNormalize_extraSlashes_getRemoved() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat(fs.getPath("//life///b/good//").normalize().toString()).isEqualTo("/life/b/good/"); } } @Test - public void testToRealPath_hasDotDir_throwsIae() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testToRealPath_hasDotDir_throwsIae() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { fs.getPath("a/hi./b").toRealPath(); fs.getPath("a/.hi/b").toRealPath(); thrown.expect(IllegalArgumentException.class); @@ -195,8 +194,8 @@ public void testToRealPath_hasDotDir_throwsIae() { } @Test - public void testToRealPath_hasDotDotDir_throwsIae() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testToRealPath_hasDotDotDir_throwsIae() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { fs.getPath("a/hi../b").toRealPath(); fs.getPath("a/..hi/b").toRealPath(); thrown.expect(IllegalArgumentException.class); @@ -206,8 +205,8 @@ public void testToRealPath_hasDotDotDir_throwsIae() { } @Test - public void testToRealPath_extraSlashes_throwsIae() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testToRealPath_extraSlashes_throwsIae() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("extra slashes"); fs.getPath("a//b").toRealPath(); @@ -215,16 +214,17 @@ public void testToRealPath_extraSlashes_throwsIae() { } @Test - public void testToRealPath_overridePermitEmptyPathComponents_extraSlashes_slashesRemain() { - try (CloudStorageFileSystem fs = forBucket("doodle", permitEmptyPathComponents(true))) { + public void testToRealPath_overridePermitEmptyPathComponents_extraSlashes_slashesRemain() + throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle", permitEmptyPathComponents(true))) { assertThat(fs.getPath("/life///b/./good/").toRealPath().toString()) .isEqualTo("life///b/./good/"); } } @Test - public void testToRealPath_permitEmptyPathComponents_doesNotNormalize() { - try (CloudStorageFileSystem fs = forBucket("doodle", permitEmptyPathComponents(true))) { + public void testToRealPath_permitEmptyPathComponents_doesNotNormalize() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle", permitEmptyPathComponents(true))) { assertThat(fs.getPath("a").toRealPath().toString()).isEqualTo("a"); assertThat(fs.getPath("a//b").toRealPath().toString()).isEqualTo("a//b"); assertThat(fs.getPath("a//./b//..").toRealPath().toString()).isEqualTo("a//./b//.."); @@ -232,45 +232,45 @@ public void testToRealPath_permitEmptyPathComponents_doesNotNormalize() { } @Test - public void testToRealPath_withWorkingDirectory_makesAbsolute() { - try (CloudStorageFileSystem fs = forBucket("doodle", workingDirectory("/lol"))) { + public void testToRealPath_withWorkingDirectory_makesAbsolute() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle", workingDirectory("/lol"))) { assertThat(fs.getPath("a").toRealPath().toString()).isEqualTo("lol/a"); } } @Test - public void testToRealPath_disableStripPrefixSlash_makesPathAbsolute() { - try (CloudStorageFileSystem fs = forBucket("doodle", stripPrefixSlash(false))) { + public void testToRealPath_disableStripPrefixSlash_makesPathAbsolute() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle", stripPrefixSlash(false))) { assertThat(fs.getPath("a").toRealPath().toString()).isEqualTo("/a"); assertThat(fs.getPath("/a").toRealPath().toString()).isEqualTo("/a"); } } @Test - public void testToRealPath_trailingSlash_getsPreserved() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testToRealPath_trailingSlash_getsPreserved() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat(fs.getPath("a/b/").toRealPath().toString()).isEqualTo("a/b/"); } } @Test - public void testNormalize_empty_returnsEmpty() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testNormalize_empty_returnsEmpty() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat(fs.getPath("").normalize().toString()).isEqualTo(""); } } @Test - public void testNormalize_preserveTrailingSlash() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testNormalize_preserveTrailingSlash() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat(fs.getPath("a/b/../c/").normalize().toString()).isEqualTo("a/c/"); assertThat(fs.getPath("a/b/./c/").normalize().toString()).isEqualTo("a/b/c/"); } } @Test - public void testGetParent_preserveTrailingSlash() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testGetParent_preserveTrailingSlash() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat(fs.getPath("a/b/c").getParent().toString()).isEqualTo("a/b/"); assertThat(fs.getPath("a/b/c/").getParent().toString()).isEqualTo("a/b/"); assertThat((Object) fs.getPath("").getParent()).isNull(); @@ -281,16 +281,16 @@ public void testGetParent_preserveTrailingSlash() { } @Test - public void testGetRoot() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testGetRoot() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat(fs.getPath("/hello").getRoot().toString()).isEqualTo("/"); assertThat((Object) fs.getPath("hello").getRoot()).isNull(); } } @Test - public void testRelativize() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testRelativize() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat( fs.getPath("/foo/bar/lol/cat").relativize(fs.getPath("/foo/a/b/../../c")).toString()) .isEqualTo("../../../a/b/../../c"); @@ -298,8 +298,8 @@ public void testRelativize() { } @Test - public void testRelativize_providerMismatch() { - try (CloudStorageFileSystem gcs = forBucket("doodle")) { + public void testRelativize_providerMismatch() throws IOException { + try (CloudStorageFileSystem gcs = helper.forBucket("doodle")) { thrown.expect(ProviderMismatchException.class); gcs.getPath("/etc").relativize(FileSystems.getDefault().getPath("/dog")); } @@ -307,63 +307,63 @@ public void testRelativize_providerMismatch() { @Test @SuppressWarnings("ReturnValueIgnored") // testing that an Exception is thrown - public void testRelativize_providerMismatch2() { - try (CloudStorageFileSystem gcs = forBucket("doodle")) { + public void testRelativize_providerMismatch2() throws IOException { + try (CloudStorageFileSystem gcs = helper.forBucket("doodle")) { thrown.expect(ProviderMismatchException.class); gcs.getPath("/dog").relativize(FileSystems.getDefault().getPath("/etc")); } } @Test - public void testResolve() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testResolve() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat(fs.getPath("/hi").resolve("there").toString()).isEqualTo("/hi/there"); assertThat(fs.getPath("hi").resolve("there").toString()).isEqualTo("hi/there"); } } @Test - public void testResolve_providerMismatch() { - try (CloudStorageFileSystem gcs = forBucket("doodle")) { + public void testResolve_providerMismatch() throws IOException { + try (CloudStorageFileSystem gcs = helper.forBucket("doodle")) { thrown.expect(ProviderMismatchException.class); gcs.getPath("etc").resolve(FileSystems.getDefault().getPath("/dog")); } } @Test - public void testIsAbsolute() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testIsAbsolute() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat(fs.getPath("/hi").isAbsolute()).isTrue(); assertThat(fs.getPath("hi").isAbsolute()).isFalse(); } } @Test - public void testToAbsolutePath() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testToAbsolutePath() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat((Object) fs.getPath("/hi").toAbsolutePath()).isEqualTo(fs.getPath("/hi")); assertThat((Object) fs.getPath("hi").toAbsolutePath()).isEqualTo(fs.getPath("/hi")); } } @Test - public void testToAbsolutePath_withWorkingDirectory() { - try (CloudStorageFileSystem fs = forBucket("doodle", workingDirectory("/lol"))) { + public void testToAbsolutePath_withWorkingDirectory() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle", workingDirectory("/lol"))) { assertThat(fs.getPath("a").toAbsolutePath().toString()).isEqualTo("/lol/a"); } } @Test - public void testGetFileName() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testGetFileName() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat(fs.getPath("/hi/there").getFileName().toString()).isEqualTo("there"); assertThat(fs.getPath("military/fashion/show").getFileName().toString()).isEqualTo("show"); } } @Test - public void testCompareTo() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testCompareTo() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat(fs.getPath("/hi/there").compareTo(fs.getPath("/hi/there"))).isEqualTo(0); assertThat(fs.getPath("/hi/there").compareTo(fs.getPath("/hi/therf"))).isEqualTo(-1); assertThat(fs.getPath("/hi/there").compareTo(fs.getPath("/hi/therd"))).isEqualTo(1); @@ -371,8 +371,8 @@ public void testCompareTo() { } @Test - public void testStartsWith() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testStartsWith() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat(fs.getPath("/hi/there").startsWith(fs.getPath("/hi/there"))).isTrue(); assertThat(fs.getPath("/hi/there").startsWith(fs.getPath("/hi/therf"))).isFalse(); assertThat(fs.getPath("/hi/there").startsWith(fs.getPath("/hi"))).isTrue(); @@ -384,8 +384,8 @@ public void testStartsWith() { } @Test - public void testEndsWith() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testEndsWith() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { assertThat(fs.getPath("/hi/there").endsWith(fs.getPath("there"))).isTrue(); assertThat(fs.getPath("/hi/there").endsWith(fs.getPath("therf"))).isFalse(); assertThat(fs.getPath("/hi/there").endsWith(fs.getPath("/blag/therf"))).isFalse(); @@ -402,8 +402,8 @@ public void testEndsWith() { @Test public void testResolve_willWorkWithRecursiveCopy() throws IOException { // See: http://stackoverflow.com/a/10068306 - try (FileSystem fsSource = FileSystems.getFileSystem(URI.create("gs://hello")); - FileSystem fsTarget = FileSystems.getFileSystem(URI.create("gs://cat"))) { + try (FileSystem fsSource = helper.forBucket("hello"); + FileSystem fsTarget = helper.forBucket("cat")) { Path targetPath = fsTarget.getPath("/some/folder/"); Path relSrcPath = fsSource.getPath("file.txt"); assertThat((Object) targetPath.resolve(relSrcPath)) @@ -414,8 +414,8 @@ public void testResolve_willWorkWithRecursiveCopy() throws IOException { @Test public void testRelativize_willWorkWithRecursiveCopy() throws IOException { // See: http://stackoverflow.com/a/10068306 - try (FileSystem fsSource = FileSystems.getFileSystem(URI.create("gs://hello")); - FileSystem fsTarget = FileSystems.getFileSystem(URI.create("gs://cat"))) { + try (FileSystem fsSource = helper.forBucket("hello"); + FileSystem fsTarget = helper.forBucket("cat")) { Path targetPath = fsTarget.getPath("/some/folder/"); Path sourcePath = fsSource.getPath("/sloth/"); Path file = fsSource.getPath("/sloth/file.txt"); @@ -425,8 +425,8 @@ public void testRelativize_willWorkWithRecursiveCopy() throws IOException { } @Test - public void testToFile_unsupported() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testToFile_unsupported() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { Path path = fs.getPath("/lol"); thrown.expect(UnsupportedOperationException.class); path.toFile(); @@ -434,8 +434,8 @@ public void testToFile_unsupported() { } @Test - public void testEquals() { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testEquals() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { new EqualsTester() // These are obviously equal. .addEqualityGroup(fs.getPath("/hello/cat"), fs.getPath("/hello/cat")) @@ -450,8 +450,8 @@ public void testEquals() { } @Test - public void testEquals_currentDirectoryIsTakenIntoConsideration() { - try (CloudStorageFileSystem fs = forBucket("doodle", workingDirectory("/hello"))) { + public void testEquals_currentDirectoryIsTakenIntoConsideration() throws IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle", workingDirectory("/hello"))) { new EqualsTester() .addEqualityGroup(fs.getPath("cat"), fs.getPath("/hello/cat")) .addEqualityGroup(fs.getPath(""), fs.getPath("/hello")) @@ -460,8 +460,8 @@ public void testEquals_currentDirectoryIsTakenIntoConsideration() { } @Test - public void testNullness() throws NoSuchMethodException, SecurityException { - try (CloudStorageFileSystem fs = forBucket("doodle")) { + public void testNullness() throws NoSuchMethodException, SecurityException, IOException { + try (CloudStorageFileSystem fs = helper.forBucket("doodle")) { NullPointerTester tester = new NullPointerTester(); tester.ignore(CloudStoragePath.class.getMethod("equals", Object.class)); tester.setDefault(Path.class, fs.getPath("sup")); @@ -469,16 +469,4 @@ public void testNullness() throws NoSuchMethodException, SecurityException { tester.testAllPublicInstanceMethods(fs.getPath("sup")); } } - - private static CloudStorageConfiguration stripPrefixSlash(boolean value) { - return CloudStorageConfiguration.builder().stripPrefixSlash(value).build(); - } - - private static CloudStorageConfiguration permitEmptyPathComponents(boolean value) { - return CloudStorageConfiguration.builder().permitEmptyPathComponents(value).build(); - } - - private static CloudStorageConfiguration workingDirectory(String value) { - return CloudStorageConfiguration.builder().workingDirectory(value).build(); - } } diff --git a/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageReadChannelTest.java b/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageReadChannelTest.java index 810e619b6277..c783794da4d6 100644 --- a/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageReadChannelTest.java +++ b/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/CloudStorageReadChannelTest.java @@ -6,14 +6,12 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import com.google.gcloud.ReadChannel; import com.google.gcloud.storage.Blob; import com.google.gcloud.storage.BlobId; -import com.google.gcloud.storage.BlobInfo; import com.google.gcloud.storage.Storage; import org.junit.Before; diff --git a/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/NioTestHelper.java b/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/NioTestHelper.java new file mode 100644 index 000000000000..703038f6a9ba --- /dev/null +++ b/gcloud-java-contrib/gcloud-java-nio/src/test/java/com/google/gcloud/storage/contrib/nio/NioTestHelper.java @@ -0,0 +1,63 @@ +package com.google.gcloud.storage.contrib.nio; + +import com.google.gcloud.spi.ServiceRpcFactory; +import com.google.gcloud.storage.Storage; +import com.google.gcloud.storage.StorageOptions; +import com.google.gcloud.storage.spi.StorageRpc; + +/** + * Helper for creating NIO file system instances without using the SPI. + * + *

There's no way to create perfect isolation between unit tests when using the Java SPI, because + * it stores a list of loaded provider instances. We instead rely on integration tests to test our + * usage of the SPI. + */ +final class NioTestHelper { + + // Within a unit test we use the same provider for multiple file systems. Having a different + // provider instance causes the behavior of many operations, such as Files.copy, to change + // dramatically. + private final CloudStorageFileSystemProvider provider; + + NioTestHelper(StorageRpc storage) { + this.provider = new CloudStorageFileSystemProvider(makeStorage(storage)); + } + + CloudStorageFileSystem forBucket(String bucket) { + return forBucket(bucket, CloudStorageConfiguration.getDefault()); + } + + CloudStorageFileSystem forBucket(String bucket, CloudStorageConfiguration config) { + return new CloudStorageFileSystem(provider, config, bucket); + } + + private static Storage makeStorage(final StorageRpc storageRpc) { + return StorageOptions.builder() + .projectId("dummy-project-for-testing") + .serviceRpcFactory( + new ServiceRpcFactory() { + @Override + public StorageRpc create(StorageOptions options) { + return storageRpc; + } + }) + .build() + .service(); + } + + static CloudStorageConfiguration stripPrefixSlash(boolean value) { + return CloudStorageConfiguration.builder().stripPrefixSlash(value).build(); + } + + static CloudStorageConfiguration permitEmptyPathComponents(boolean value) { + return CloudStorageConfiguration.builder().permitEmptyPathComponents(value).build(); + } + + static CloudStorageConfiguration workingDirectory(String value) { + return CloudStorageConfiguration.builder().workingDirectory(value).build(); + } + + static CloudStorageConfiguration usePseudoDirectories(boolean value) { + return CloudStorageConfiguration.builder().usePseudoDirectories(value).build(); + } +} diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/FakeStorageRpc.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/FakeStorageRpc.java index 3c5911b9f617..6afd73b3904b 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/FakeStorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/FakeStorageRpc.java @@ -17,20 +17,19 @@ import javax.annotation.concurrent.NotThreadSafe; /** - * A bare-bones in-memory implementation of Storage, meant for testing. - * See LocalGcsHelper. - * - * This class is NOT thread-safe. + * Bare-bones in-memory implementation of {@link Storage} for testing. */ @NotThreadSafe -public class FakeStorageRpc implements StorageRpc { +public final class FakeStorageRpc implements StorageRpc { // fullname -> metadata - Map stuff = new HashMap<>(); + private final Map stuff = new HashMap<>(); + // fullname -> contents - Map contents = new HashMap<>(); + private final Map contents = new HashMap<>(); + // fullname -> future contents that will be visible on close. - Map futureContents = new HashMap<>(); + private final Map futureContents = new HashMap<>(); private final boolean throwIfOption; @@ -41,12 +40,6 @@ public FakeStorageRpc(boolean throwIfOption) { this.throwIfOption = throwIfOption; } - // remove all files - void reset() { - stuff = new HashMap<>(); - contents = new HashMap<>(); - } - @Override public Bucket create(Bucket bucket, Map options) throws StorageException { throw new UnsupportedOperationException(); @@ -189,12 +182,9 @@ public String open(StorageObject object, Map options) throws StorageE String key = fullname(object); boolean mustNotExist = false; for (Option option : options.keySet()) { - if (option instanceof StorageRpc.Option) { - // this is a bit of a hack, since we don't implement generations. - if ((StorageRpc.Option) option == Option.IF_GENERATION_MATCH - && ((Long) options.get(option)).longValue() == 0L) { - mustNotExist = true; - } + // this is a bit of a hack, since we don't implement generations. + if (option == Option.IF_GENERATION_MATCH && ((Long) options.get(option)).longValue() == 0L) { + mustNotExist = true; } } if (mustNotExist && stuff.containsKey(key)) { @@ -238,12 +228,10 @@ public RewriteResponse openRewrite(RewriteRequest rewriteRequest) throws Storage boolean mustNotExist = false; for (Option option : rewriteRequest.targetOptions.keySet()) { - if (option instanceof StorageRpc.Option) { - // this is a bit of a hack, since we don't implement generations. - if ((StorageRpc.Option) option == Option.IF_GENERATION_MATCH - && ((Long) rewriteRequest.targetOptions.get(option)).longValue() == 0L) { - mustNotExist = true; - } + // this is a bit of a hack, since we don't implement generations. + if (option == Option.IF_GENERATION_MATCH + && ((Long) rewriteRequest.targetOptions.get(option)).longValue() == 0L) { + mustNotExist = true; } } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/LocalGcsHelper.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/LocalGcsHelper.java deleted file mode 100644 index 7749ad160096..000000000000 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/LocalGcsHelper.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2015 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.gcloud.storage.testing; - -import com.google.gcloud.spi.ServiceRpcFactory; -import com.google.gcloud.storage.spi.StorageRpc; -import com.google.gcloud.storage.StorageOptions; - -/** - * Utility to create an in-memory storage configuration for testing. Storage options can be - * obtained via the {@link #options()} method. Returned options will point to FakeStorageRpc. - */ -public class LocalGcsHelper { - - // used for testing. Will throw if you pass it an option. - private static final FakeStorageRpc instance = new FakeStorageRpc(true); - - /** - * Returns a {@link StorageOptions} that use the static FakeStorageRpc instance, - * and resets it first so you start from a clean slate. - * That instance will throw if you pass it any option. * - */ - public static StorageOptions options() { - instance.reset(); - return StorageOptions.builder() - .projectId("dummy-project-for-testing") - .serviceRpcFactory( - new ServiceRpcFactory() { - @Override - public StorageRpc create(StorageOptions options) { - return instance; - } - }) - .build(); - } - - /** - * Returns a {@link StorageOptions} that creates a new FakeStorageRpc instance - * with the given option. - */ - public static StorageOptions customOptions(final boolean throwIfOptions) { - return StorageOptions.builder() - .projectId("dummy-project-for-testing") - .serviceRpcFactory( - new ServiceRpcFactory() { - @Override - public StorageRpc create(StorageOptions options) { - return new FakeStorageRpc(throwIfOptions); - } - }) - .build(); - } - -}