Skip to content

Commit

Permalink
test: converting a portion of tests from easymock to mockito (#330)
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitry-fa committed May 21, 2020
1 parent 6c18c88 commit ae0aa99
Show file tree
Hide file tree
Showing 2 changed files with 228 additions and 142 deletions.
Expand Up @@ -16,21 +16,30 @@

package com.google.cloud.storage;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.mockito.Mockito.any;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import com.google.api.core.ApiClock;
import com.google.cloud.Identity;
import com.google.cloud.Policy;
import com.google.cloud.ReadChannel;
import com.google.cloud.ServiceOptions;
import com.google.cloud.Tuple;
import com.google.cloud.WriteChannel;
import com.google.cloud.storage.spi.StorageRpcFactory;
import com.google.cloud.storage.spi.v1.StorageRpc;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.BaseEncoding;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.security.Key;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
Expand All @@ -40,11 +49,15 @@
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.Map;
import javax.crypto.spec.SecretKeySpec;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

public class StorageImplMockitoTest {

Expand Down Expand Up @@ -358,11 +371,28 @@ public static void beforeClass() throws NoSuchAlgorithmException, InvalidKeySpec
publicKey = keyFactory.generatePublic(publicKeySpec);
}

private static final RuntimeException STORAGE_FAILURE =
new RuntimeException("Something went wrong");

private static final RuntimeException UNEXPECTED_CALL_EXCEPTION =
new RuntimeException("Unexpected call");
private static final Answer UNEXPECTED_CALL_ANSWER =
new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) {
throw new IllegalArgumentException(
"Unexpected call of "
+ invocation.getMethod()
+ " with "
+ Arrays.toString(invocation.getArguments()));
};
};

@Before
public void setUp() {
rpcFactoryMock = mock(StorageRpcFactory.class);
storageRpcMock = mock(StorageRpc.class);
when(rpcFactoryMock.create(any(StorageOptions.class))).thenReturn(storageRpcMock);
rpcFactoryMock = mock(StorageRpcFactory.class, UNEXPECTED_CALL_ANSWER);
storageRpcMock = mock(StorageRpc.class, UNEXPECTED_CALL_ANSWER);
doReturn(storageRpcMock).when(rpcFactoryMock).create(Mockito.any(StorageOptions.class));
options =
StorageOptions.newBuilder()
.setProjectId("projectId")
Expand Down Expand Up @@ -395,22 +425,209 @@ public void testGetOptions() {

@Test
public void testCreateBucket() {
when(storageRpcMock.create(BUCKET_INFO1.toPb(), EMPTY_RPC_OPTIONS))
.thenReturn(BUCKET_INFO1.toPb())
.thenThrow(new RuntimeException("Fail"));
doReturn(BUCKET_INFO1.toPb())
.doThrow(UNEXPECTED_CALL_EXCEPTION)
.when(storageRpcMock)
.create(BUCKET_INFO1.toPb(), EMPTY_RPC_OPTIONS);
initializeService();
Bucket bucket = storage.create(BUCKET_INFO1);
assertEquals(expectedBucket1, bucket);
}

@Test
public void testCreateBucketWithOptions() {
when(storageRpcMock.create(BUCKET_INFO1.toPb(), BUCKET_TARGET_OPTIONS))
.thenReturn(BUCKET_INFO1.toPb())
.thenThrow(new RuntimeException("Fail"));
doReturn(BUCKET_INFO1.toPb())
.doThrow(UNEXPECTED_CALL_EXCEPTION)
.when(storageRpcMock)
.create(BUCKET_INFO1.toPb(), BUCKET_TARGET_OPTIONS);
initializeService();
Bucket bucket =
storage.create(BUCKET_INFO1, BUCKET_TARGET_METAGENERATION, BUCKET_TARGET_PREDEFINED_ACL);
assertEquals(expectedBucket1, bucket);
}

@Test
public void testCreateBucketFailure() {
doThrow(STORAGE_FAILURE).when(storageRpcMock).create(BUCKET_INFO1.toPb(), EMPTY_RPC_OPTIONS);
initializeService();
try {
storage.create(BUCKET_INFO1);
fail();
} catch (StorageException e) {
assertEquals(STORAGE_FAILURE, e.getCause());
}
}

private void verifyChannelRead(ReadChannel channel, byte[] bytes) throws IOException {
assertNotNull(channel);
assertTrue(channel.isOpen());

ByteBuffer buffer = ByteBuffer.allocate(42);
byte[] expectedBytes = new byte[buffer.capacity()];
System.arraycopy(bytes, 0, expectedBytes, 0, bytes.length);

int size = channel.read(buffer);
assertEquals(bytes.length, size);
assertEquals(bytes.length, buffer.position());
assertArrayEquals(expectedBytes, buffer.array());
}

@Test
public void testReader() {
initializeService();
ReadChannel channel = storage.reader(BUCKET_NAME1, BLOB_NAME1);
assertNotNull(channel);
assertTrue(channel.isOpen());
// Storage.reader() does not issue any RPC, channel.read() does
try {
channel.read(ByteBuffer.allocate(100));
fail();
} catch (IOException e) {
assertTrue(e.getMessage().contains("java.lang.IllegalArgumentException: Unexpected call"));
}
}

@Test
public void testReaderWithOptions() throws IOException {
doReturn(Tuple.of("etag", BLOB_CONTENT))
.doThrow(UNEXPECTED_CALL_EXCEPTION)
.when(storageRpcMock)
.read(BLOB_INFO2.toPb(), BLOB_SOURCE_OPTIONS, 0, DEFAULT_CHUNK_SIZE);
initializeService();
ReadChannel channel =
storage.reader(
BUCKET_NAME1, BLOB_NAME2, BLOB_SOURCE_GENERATION, BLOB_SOURCE_METAGENERATION);
verifyChannelRead(channel, BLOB_CONTENT);
}

@Test
public void testReaderWithDecryptionKey() throws IOException {
doReturn(Tuple.of("a", BLOB_CONTENT), Tuple.of("b", BLOB_SUB_CONTENT))
.doThrow(UNEXPECTED_CALL_EXCEPTION)
.when(storageRpcMock)
.read(BLOB_INFO2.toPb(), ENCRYPTION_KEY_OPTIONS, 0, DEFAULT_CHUNK_SIZE);
initializeService();
ReadChannel channel =
storage.reader(BUCKET_NAME1, BLOB_NAME2, Storage.BlobSourceOption.decryptionKey(KEY));

verifyChannelRead(channel, BLOB_CONTENT);
channel =
storage.reader(
BUCKET_NAME1, BLOB_NAME2, Storage.BlobSourceOption.decryptionKey(BASE64_KEY));
verifyChannelRead(channel, BLOB_SUB_CONTENT);
}

@Test
public void testReaderWithOptionsFromBlobId() throws IOException {
doReturn(Tuple.of("etag", BLOB_CONTENT))
.doThrow(UNEXPECTED_CALL_EXCEPTION)
.when(storageRpcMock)
.read(BLOB_INFO1.getBlobId().toPb(), BLOB_SOURCE_OPTIONS, 0, DEFAULT_CHUNK_SIZE);
initializeService();
ReadChannel channel =
storage.reader(
BLOB_INFO1.getBlobId(),
BLOB_SOURCE_GENERATION_FROM_BLOB_ID,
BLOB_SOURCE_METAGENERATION);
verifyChannelRead(channel, BLOB_CONTENT);
}

@Test
public void testReaderFailure() throws IOException {
doThrow(STORAGE_FAILURE)
.when(storageRpcMock)
.read(BLOB_INFO2.getBlobId().toPb(), EMPTY_RPC_OPTIONS, 0, DEFAULT_CHUNK_SIZE);
initializeService();
ReadChannel channel = storage.reader(BUCKET_NAME1, BLOB_NAME2);
assertNotNull(channel);
assertTrue(channel.isOpen());
try {
channel.read(ByteBuffer.allocate(42));
fail();
} catch (IOException e) {
assertTrue(e.getMessage().contains(STORAGE_FAILURE.toString()));
}
}

@Test
public void testWriter() {
BlobInfo.Builder infoBuilder = BLOB_INFO1.toBuilder();
BlobInfo infoWithHashes = infoBuilder.setMd5(CONTENT_MD5).setCrc32c(CONTENT_CRC32C).build();
BlobInfo infoWithoutHashes = infoBuilder.setMd5(null).setCrc32c(null).build();
doReturn("upload-id")
.doThrow(UNEXPECTED_CALL_EXCEPTION)
.when(storageRpcMock)
.open(infoWithoutHashes.toPb(), EMPTY_RPC_OPTIONS);
initializeService();
WriteChannel channel = storage.writer(infoWithHashes);
assertNotNull(channel);
assertTrue(channel.isOpen());
}

@Test
public void testWriterWithOptions() {
BlobInfo info = BLOB_INFO1.toBuilder().setMd5(CONTENT_MD5).setCrc32c(CONTENT_CRC32C).build();
doReturn("upload-id")
.doThrow(UNEXPECTED_CALL_EXCEPTION)
.when(storageRpcMock)
.open(info.toPb(), BLOB_TARGET_OPTIONS_CREATE);
initializeService();
WriteChannel channel =
storage.writer(
info,
BLOB_WRITE_METAGENERATION,
BLOB_WRITE_NOT_EXIST,
BLOB_WRITE_PREDEFINED_ACL,
BLOB_WRITE_CRC2C,
BLOB_WRITE_MD5_HASH);
assertNotNull(channel);
assertTrue(channel.isOpen());
}

@Test
public void testWriterWithEncryptionKey() {
BlobInfo info = BLOB_INFO1.toBuilder().setMd5(null).setCrc32c(null).build();
doReturn("upload-id-1", "upload-id-2")
.doThrow(UNEXPECTED_CALL_EXCEPTION)
.when(storageRpcMock)
.open(info.toPb(), ENCRYPTION_KEY_OPTIONS);
initializeService();
WriteChannel channel = storage.writer(info, Storage.BlobWriteOption.encryptionKey(KEY));
assertNotNull(channel);
assertTrue(channel.isOpen());
channel = storage.writer(info, Storage.BlobWriteOption.encryptionKey(BASE64_KEY));
assertNotNull(channel);
assertTrue(channel.isOpen());
}

@Test
public void testWriterWithKmsKeyName() {
BlobInfo info = BLOB_INFO1.toBuilder().setMd5(null).setCrc32c(null).build();
doReturn("upload-id-1", "upload-id-2")
.doThrow(UNEXPECTED_CALL_EXCEPTION)
.when(storageRpcMock)
.open(info.toPb(), KMS_KEY_NAME_OPTIONS);
initializeService();
WriteChannel channel = storage.writer(info, Storage.BlobWriteOption.kmsKeyName(KMS_KEY_NAME));
assertNotNull(channel);
assertTrue(channel.isOpen());
channel = storage.writer(info, Storage.BlobWriteOption.kmsKeyName(KMS_KEY_NAME));
assertNotNull(channel);
assertTrue(channel.isOpen());
}

@Test
public void testWriterFailure() {
BlobInfo.Builder infoBuilder = BLOB_INFO1.toBuilder();
BlobInfo infoWithHashes = infoBuilder.setMd5(CONTENT_MD5).setCrc32c(CONTENT_CRC32C).build();
BlobInfo infoWithoutHashes = infoBuilder.setMd5(null).setCrc32c(null).build();
doThrow(STORAGE_FAILURE).when(storageRpcMock).open(infoWithoutHashes.toPb(), EMPTY_RPC_OPTIONS);
initializeService();
try {
storage.writer(infoWithHashes);
fail();
} catch (StorageException e) {
assertSame(STORAGE_FAILURE, e.getCause());
}
}
}

0 comments on commit ae0aa99

Please sign in to comment.