Skip to content

Commit

Permalink
Add tests for restorable classes. Fix serialization issues
Browse files Browse the repository at this point in the history
  • Loading branch information
mziccard committed Mar 17, 2016
1 parent 8ae8a1b commit 967c5c5
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand All @@ -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<WriteChannel> state = writer.capture();
RestorableState<WriteChannel> deserializedState = serializeAndDeserialize(state);
assertEquals(state, deserializedState);
assertEquals(state.hashCode(), deserializedState.hashCode());
assertEquals(state.toString(), deserializedState.toString());
assertRestorable(writer);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
*/
public abstract class BaseSerializationTest {

/**
* Returns all objects for which correct serialization must be tested.
*/
public abstract Serializable[] serializableObjects();

@Test
Expand All @@ -50,8 +53,7 @@ public void testSerializableObjects() throws Exception {
}

@SuppressWarnings("unchecked")
public <T> T serializeAndDeserialize(T obj)
throws IOException, ClassNotFoundException {
public <T> T serializeAndDeserialize(T obj) throws IOException, ClassNotFoundException {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
try (ObjectOutputStream output = new ObjectOutputStream(bytes)) {
output.writeObject(obj);
Expand All @@ -61,4 +63,17 @@ public <T> 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());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> 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\": \"[email protected]\",\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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -112,7 +111,6 @@ public java.io.Serializable[] serializableObjects() {
.build();
DatastoreOptions otherOptions = options.toBuilder()
.namespace("ns1")
.retryParams(RetryParams.defaultInstance())
.authCredentials(null)
.force(true)
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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,
Expand All @@ -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<ReadChannel> state = reader.capture();
RestorableState<ReadChannel> 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<WriteChannel> state = writer.capture();
RestorableState<WriteChannel> deserializedState = serializeAndDeserialize(state);
assertEquals(state, deserializedState);
assertEquals(state.hashCode(), deserializedState.hashCode());
assertEquals(state.toString(), deserializedState.toString());
assertRestorable(writer);
}
}

0 comments on commit 967c5c5

Please sign in to comment.