From 967c5c5a20f39ce232e415b371e7b3a038e453fa Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 17 Mar 2016 09:54:13 +0100 Subject: [PATCH] Add tests for restorable classes. Fix serialization issues --- .../gcloud/bigquery/SerializationTest.java | 17 +------ .../com/google/gcloud/AuthCredentials.java | 10 ++++ .../com/google/gcloud/ExceptionHandler.java | 22 +++++++++ .../google/gcloud/BaseSerializationTest.java | 19 +++++++- .../com/google/gcloud/SerializationTest.java | 46 ++++++++++++++++++- .../gcloud/datastore/SerializationTest.java | 2 - .../resourcemanager/SerializationTest.java | 4 +- .../gcloud/storage/SerializationTest.java | 29 ++---------- 8 files changed, 101 insertions(+), 48 deletions(-) diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java index f64946e062d7..087d263b0fa4 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java @@ -16,15 +16,10 @@ package com.google.gcloud.bigquery; -import static org.junit.Assert.assertEquals; - import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.gcloud.AuthCredentials; import com.google.gcloud.BaseSerializationTest; -import com.google.gcloud.RestorableState; -import com.google.gcloud.RetryParams; -import com.google.gcloud.WriteChannel; import com.google.gcloud.bigquery.StandardTableDefinition.StreamingBuffer; import org.junit.Test; @@ -235,7 +230,6 @@ public Serializable[] serializableObjects() { .build(); BigQueryOptions otherOptions = options.toBuilder() .projectId("p2") - .retryParams(RetryParams.defaultInstance()) .authCredentials(null) .build(); return new Serializable[]{DOMAIN_ACCESS, GROUP_ACCESS, USER_ACCESS, VIEW_ACCESS, DATASET_ID, @@ -254,18 +248,11 @@ public Serializable[] serializableObjects() { @Test public void testWriteChannelState() throws IOException, ClassNotFoundException { - BigQueryOptions options = BigQueryOptions.builder() - .projectId("p2") - .retryParams(RetryParams.defaultInstance()) - .build(); + BigQueryOptions options = BigQueryOptions.builder().projectId("p2").build(); // avoid closing when you don't want partial writes upon failure @SuppressWarnings("resource") TableDataWriteChannel writer = new TableDataWriteChannel(options, LOAD_CONFIGURATION, "upload-id"); - RestorableState state = writer.capture(); - RestorableState deserializedState = serializeAndDeserialize(state); - assertEquals(state, deserializedState); - assertEquals(state.hashCode(), deserializedState.hashCode()); - assertEquals(state.toString(), deserializedState.toString()); + assertRestorable(writer); } } diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java index 6f9e09ca04bc..38265a26be2e 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java @@ -276,6 +276,16 @@ private static class NoAuthCredentialsState public AuthCredentials restore() { return INSTANCE; } + + @Override + public int hashCode() { + return getClass().getName().hashCode(); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof NoAuthCredentialsState; + } } @Override diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ExceptionHandler.java b/gcloud-java-core/src/main/java/com/google/gcloud/ExceptionHandler.java index 39d4c4e75a1a..0dbcbeb65378 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/ExceptionHandler.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ExceptionHandler.java @@ -26,6 +26,7 @@ import java.io.Serializable; import java.lang.reflect.Method; +import java.util.Objects; import java.util.Set; import java.util.concurrent.Callable; @@ -259,6 +260,27 @@ boolean shouldRetry(Exception ex) { return retryResult == Interceptor.RetryResult.RETRY; } + @Override + public int hashCode() { + return Objects.hash(interceptors, retriableExceptions, nonRetriableExceptions, retryInfo); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ExceptionHandler)) { + return false; + } + ExceptionHandler other = (ExceptionHandler) obj; + return Objects.equals(interceptors, other.interceptors) + && Objects.equals(retriableExceptions, other.retriableExceptions) + && Objects.equals(nonRetriableExceptions, other.nonRetriableExceptions) + && Objects.equals(retryInfo, other.retryInfo); + + } + /** * Returns an instance which retry any checked exception and abort on any runtime exception. */ diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/BaseSerializationTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/BaseSerializationTest.java index 533dfcde6ad8..a8136bfbf0cc 100644 --- a/gcloud-java-core/src/test/java/com/google/gcloud/BaseSerializationTest.java +++ b/gcloud-java-core/src/test/java/com/google/gcloud/BaseSerializationTest.java @@ -34,6 +34,9 @@ */ public abstract class BaseSerializationTest { + /** + * Returns all objects for which correct serialization must be tested. + */ public abstract Serializable[] serializableObjects(); @Test @@ -50,8 +53,7 @@ public void testSerializableObjects() throws Exception { } @SuppressWarnings("unchecked") - public T serializeAndDeserialize(T obj) - throws IOException, ClassNotFoundException { + public T serializeAndDeserialize(T obj) throws IOException, ClassNotFoundException { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); try (ObjectOutputStream output = new ObjectOutputStream(bytes)) { output.writeObject(obj); @@ -61,4 +63,17 @@ public T serializeAndDeserialize(T obj) return (T) input.readObject(); } } + + /** + * Checks whether the state of a restorable object can correctly be captured, serialized and + * restored. + */ + public void assertRestorable(Restorable restorable) throws IOException, + ClassNotFoundException { + RestorableState state = restorable.capture(); + RestorableState deserializedState = serializeAndDeserialize(state); + assertEquals(state, deserializedState); + assertEquals(state.hashCode(), deserializedState.hashCode()); + assertEquals(state.toString(), deserializedState.toString()); + } } diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java index aec9158e1ee0..46f1f73563f7 100644 --- a/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java +++ b/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java @@ -18,16 +18,60 @@ import com.google.common.collect.ImmutableList; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.Serializable; public class SerializationTest extends BaseSerializationTest { + private static final ExceptionHandler EXCEPTION_HANDLER = ExceptionHandler.defaultInstance(); + private static final Identity IDENTITY = Identity.allAuthenticatedUsers(); private static final PageImpl PAGE = new PageImpl<>(null, "cursor", ImmutableList.of("string1", "string2")); private static final RetryParams RETRY_PARAMS = RetryParams.defaultInstance(); + private static final String JSON_KEY = "{\n" + + " \"private_key_id\": \"somekeyid\",\n" + + " \"private_key\": \"-----BEGIN PRIVATE KEY-----\\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggS" + + "kAgEAAoIBAQC+K2hSuFpAdrJI\\nnCgcDz2M7t7bjdlsadsasad+fvRSW6TjNQZ3p5LLQY1kSZRqBqylRkzteMOyHg" + + "aR\\n0Pmxh3ILCND5men43j3h4eDbrhQBuxfEMalkG92sL+PNQSETY2tnvXryOvmBRwa/\\nQP/9dJfIkIDJ9Fw9N4" + + "Bhhhp6mCcRpdQjV38H7JsyJ7lih/oNjECgYAt\\nknddadwkwewcVxHFhcZJO+XWf6ofLUXpRwiTZakGMn8EE1uVa2" + + "LgczOjwWHGi99MFjxSer5m9\\n1tCa3/KEGKiS/YL71JvjwX3mb+cewlkcmweBKZHM2JPTk0ZednFSpVZMtycjkbLa" + + "\\ndYOS8V85AgMBewECggEBAKksaldajfDZDV6nGqbFjMiizAKJolr/M3OQw16K6o3/\\n0S31xIe3sSlgW0+UbYlF" + + "4U8KifhManD1apVSC3csafaspP4RZUHFhtBywLO9pR5c\\nr6S5aLp+gPWFyIp1pfXbWGvc5VY/v9x7ya1VEa6rXvL" + + "sKupSeWAW4tMj3eo/64ge\\nsdaceaLYw52KeBYiT6+vpsnYrEkAHO1fF/LavbLLOFJmFTMxmsNaG0tuiJHgjshB\\" + + "n82DpMCbXG9YcCgI/DbzuIjsdj2JC1cascSP//3PmefWysucBQe7Jryb6NQtASmnv\\nCdDw/0jmZTEjpe4S1lxfHp" + + "lAhHFtdgYTvyYtaLZiVVkCgYEA8eVpof2rceecw/I6\\n5ng1q3Hl2usdWV/4mZMvR0fOemacLLfocX6IYxT1zA1FF" + + "JlbXSRsJMf/Qq39mOR2\\nSpW+hr4jCoHeRVYLgsbggtrevGmILAlNoqCMpGZ6vDmJpq6ECV9olliDvpPgWOP+\\nm" + + "YPDreFBGxWvQrADNbRt2dmGsrsCgYEAyUHqB2wvJHFqdmeBsaacewzV8x9WgmeX\\ngUIi9REwXlGDW0Mz50dxpxcK" + + "CAYn65+7TCnY5O/jmL0VRxU1J2mSWyWTo1C+17L0\\n3fUqjxL1pkefwecxwecvC+gFFYdJ4CQ/MHHXU81Lwl1iWdF" + + "Cd2UoGddYaOF+KNeM\\nHC7cmqra+JsCgYEAlUNywzq8nUg7282E+uICfCB0LfwejuymR93CtsFgb7cRd6ak\\nECR" + + "8FGfCpH8ruWJINllbQfcHVCX47ndLZwqv3oVFKh6pAS/vVI4dpOepP8++7y1u\\ncoOvtreXCX6XqfrWDtKIvv0vjl" + + "HBhhhp6mCcRpdQjV38H7JsyJ7lih/oNjECgYAt\\nkndj5uNl5SiuVxHFhcZJO+XWf6ofLUregtevZakGMn8EE1uVa" + + "2AY7eafmoU/nZPT\\n00YB0TBATdCbn/nBSuKDESkhSg9s2GEKQZG5hBmL5uCMfo09z3SfxZIhJdlerreP\\nJ7gSi" + + "dI12N+EZxYd4xIJh/HFDgp7RRO87f+WJkofMQKBgGTnClK1VMaCRbJZPriw\\nEfeFCoOX75MxKwXs6xgrw4W//AYG" + + "GUjDt83lD6AZP6tws7gJ2IwY/qP7+lyhjEqN\\nHtfPZRGFkGZsdaksdlaksd323423d+15/UvrlRSFPNj1tWQmNKk" + + "XyRDW4IG1Oa2p\\nrALStNBx5Y9t0/LQnFI4w3aG\\n-----END PRIVATE KEY-----\\n\",\n" + + " \"client_email\": \"someclientid@developer.gserviceaccount.com\",\n" + + " \"client_id\": \"someclientid.apps.googleusercontent.com\",\n" + + " \"type\": \"service_account\"\n" + + "}"; @Override public Serializable[] serializableObjects() { - return new Serializable[]{PAGE, RETRY_PARAMS}; + return new Serializable[]{EXCEPTION_HANDLER, IDENTITY, PAGE, RETRY_PARAMS}; + } + + @Test + public void testAuthCredentialState() throws IOException, ClassNotFoundException { + AuthCredentials credentials = AuthCredentials.createApplicationDefaults(); + assertRestorable(credentials); + credentials = AuthCredentials.createForAppEngine(); + assertRestorable(credentials); + credentials = AuthCredentials.noAuth(); + assertRestorable(credentials); + credentials = AuthCredentials.createForJson(new ByteArrayInputStream(JSON_KEY.getBytes())); + assertRestorable(credentials); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index 7a6f065d6ca6..5cbf63b9624d 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -21,7 +21,6 @@ import com.google.api.services.datastore.DatastoreV1; import com.google.gcloud.AuthCredentials; import com.google.gcloud.BaseSerializationTest; -import com.google.gcloud.RetryParams; import com.google.gcloud.datastore.StructuredQuery.CompositeFilter; import com.google.gcloud.datastore.StructuredQuery.OrderBy; import com.google.gcloud.datastore.StructuredQuery.Projection; @@ -112,7 +111,6 @@ public java.io.Serializable[] serializableObjects() { .build(); DatastoreOptions otherOptions = options.toBuilder() .namespace("ns1") - .retryParams(RetryParams.defaultInstance()) .authCredentials(null) .force(true) .build(); diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java index 2dcd3f9d3e7b..786865e0f872 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java @@ -18,10 +18,9 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -import com.google.gcloud.Identity; import com.google.gcloud.BaseSerializationTest; +import com.google.gcloud.Identity; import com.google.gcloud.PageImpl; -import com.google.gcloud.RetryParams; import java.io.Serializable; import java.util.Collections; @@ -55,7 +54,6 @@ public Serializable[] serializableObjects() { ResourceManagerOptions options = ResourceManagerOptions.builder().build(); ResourceManagerOptions otherOptions = options.toBuilder() .projectId("some-unnecessary-project-ID") - .retryParams(RetryParams.defaultInstance()) .build(); return new Serializable[]{PARTIAL_PROJECT_INFO, FULL_PROJECT_INFO, PROJECT, PAGE_RESULT, PROJECT_GET_OPTION, PROJECT_LIST_OPTION, POLICY, options, otherOptions}; diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java index ee3d7c946312..392636ccd100 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java @@ -16,16 +16,11 @@ package com.google.gcloud.storage; -import static org.junit.Assert.assertEquals; - import com.google.common.collect.ImmutableMap; import com.google.gcloud.AuthCredentials; import com.google.gcloud.BaseSerializationTest; import com.google.gcloud.PageImpl; import com.google.gcloud.ReadChannel; -import com.google.gcloud.RestorableState; -import com.google.gcloud.RetryParams; -import com.google.gcloud.WriteChannel; import com.google.gcloud.storage.Acl.Project.ProjectRole; import com.google.gcloud.storage.spi.StorageRpc; @@ -81,7 +76,6 @@ public Serializable[] serializableObjects() { .build(); StorageOptions otherOptions = options.toBuilder() .projectId("p2") - .retryParams(RetryParams.defaultInstance()) .authCredentials(null) .build(); return new Serializable[]{ACL_DOMAIN, ACL_GROUP, ACL_PROJECT_, ACL_USER, ACL_RAW, ACL, @@ -92,34 +86,19 @@ public Serializable[] serializableObjects() { @Test public void testReadChannelState() throws IOException, ClassNotFoundException { - StorageOptions options = StorageOptions.builder() - .projectId("p2") - .retryParams(RetryParams.defaultInstance()) - .build(); + StorageOptions options = StorageOptions.builder().projectId("p2").build(); ReadChannel reader = new BlobReadChannel(options, BlobId.of("b", "n"), EMPTY_RPC_OPTIONS); - RestorableState state = reader.capture(); - RestorableState deserializedState = serializeAndDeserialize(state); - assertEquals(state, deserializedState); - assertEquals(state.hashCode(), deserializedState.hashCode()); - assertEquals(state.toString(), deserializedState.toString()); - reader.close(); + assertRestorable(reader); } @Test public void testWriteChannelState() throws IOException, ClassNotFoundException { - StorageOptions options = StorageOptions.builder() - .projectId("p2") - .retryParams(RetryParams.defaultInstance()) - .build(); + StorageOptions options = StorageOptions.builder().projectId("p2").build(); // avoid closing when you don't want partial writes to GCS upon failure @SuppressWarnings("resource") BlobWriteChannel writer = new BlobWriteChannel(options, BlobInfo.builder(BlobId.of("b", "n")).build(), "upload-id"); - RestorableState state = writer.capture(); - RestorableState deserializedState = serializeAndDeserialize(state); - assertEquals(state, deserializedState); - assertEquals(state.hashCode(), deserializedState.hashCode()); - assertEquals(state.toString(), deserializedState.toString()); + assertRestorable(writer); } }