com.talis.storage.s3.DirectChunkHandlerTest.java Source code

Java tutorial

Introduction

Here is the source code for com.talis.storage.s3.DirectChunkHandlerTest.java

Source

/*
 * Copyright 2010 Talis Information Ltd
 * 
 *    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.talis.storage.s3;

import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.classextension.EasyMock.createStrictMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.easymock.classextension.EasyMock.verify;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.UUID;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.jets3t.service.S3Service;
import org.jets3t.service.S3ServiceException;
import org.jets3t.service.model.S3Bucket;
import org.jets3t.service.model.S3Object;
import org.junit.Before;
import org.junit.Test;

public class DirectChunkHandlerTest {

    private String key;
    private String bucketName;
    private S3Bucket bucket;

    @Before
    public void setup() {
        key = UUID.randomUUID().toString();
        bucketName = UUID.randomUUID().toString();
        bucket = new S3Bucket(bucketName);
    }

    @Test
    public void writeChunkUsesSuppliedServiceToStoreObject() throws Exception {
        S3Object chunk = new S3Object(key);
        chunk.setMd5Hash(DigestUtils.md5("Mickey Mouse is dead"));
        S3Service mockService = createStrictMock(S3Service.class);
        mockService.putObject(bucket, chunk);
        expectLastCall().andReturn(chunk);
        replay(mockService);

        new DirectChunkHandler(bucket, mockService).writeChunk(chunk);
        verify(mockService);
    }

    @Test(expected = IOException.class)
    public void exceptionThrownByServiceAreCaughtAndRethrown() throws Exception {
        S3Object chunk = new S3Object(key);
        chunk.setMd5Hash(DigestUtils.md5("Mickey Mouse is dead"));
        S3Service mockService = createStrictMock(S3Service.class);
        mockService.putObject(bucket, chunk);
        expectLastCall().andThrow(new S3ServiceException("TEST"));
        replay(mockService);

        try {
            new DirectChunkHandler(bucket, mockService).writeChunk(chunk);
        } finally {
            verify(mockService);
        }
    }

    @Test
    public void writeChunkReturnsObjectReturnedByService() throws Exception {
        S3Object chunk = new S3Object(key);
        S3Object written = new S3Object(key);
        written.setMd5Hash(DigestUtils.md5("Mickey Mouse is dead"));
        S3Service mockService = createStrictMock(S3Service.class);
        mockService.putObject(bucket, chunk);
        expectLastCall().andReturn(written);
        replay(mockService);

        assertSame(written, new DirectChunkHandler(bucket, mockService).writeChunk(chunk));
        verify(mockService);
    }

    @Test
    public void listChunksForResourceWithSinglePart() throws Exception {
        S3Object chunk = new S3Object(key);
        S3Object[] chunks = new S3Object[] { chunk };
        S3Service mockService = createStrictMock(S3Service.class);
        mockService.listObjects(bucket, key, null);
        expectLastCall().andReturn(chunks);
        replay(mockService);

        assertSame(chunks, new DirectChunkHandler(bucket, mockService).listChunks(key));
        verify(mockService);
    }

    @Test
    public void listChunksForResourceWithMultipleParts() throws Exception {
        S3Object chunk0 = new S3Object(key + "/0");
        S3Object chunk1 = new S3Object(key + "/1");
        S3Object[] chunks = new S3Object[] { chunk0, chunk1 };
        S3Service mockService = createStrictMock(S3Service.class);
        mockService.listObjects(bucket, key, null);
        expectLastCall().andReturn(chunks);
        replay(mockService);

        assertSame(chunks, new DirectChunkHandler(bucket, mockService).listChunks(key));
        verify(mockService);
    }

    @Test
    public void listChunksForResourceWithNoParts() throws Exception {
        S3Object[] chunks = new S3Object[] {};
        S3Service mockService = createStrictMock(S3Service.class);
        mockService.listObjects(bucket, key, null);
        expectLastCall().andReturn(chunks);
        replay(mockService);

        assertSame(chunks, new DirectChunkHandler(bucket, mockService).listChunks(key));
        verify(mockService);
    }

    @Test(expected = IOException.class)
    public void remoteServiceThrowsErrorWhenListingChunks() throws Exception {
        S3Service mockService = createStrictMock(S3Service.class);
        mockService.listObjects(bucket, key, null);
        expectLastCall().andThrow(new S3ServiceException("TEST"));
        replay(mockService);

        try {
            new DirectChunkHandler(bucket, mockService).listChunks(key);
        } finally {
            verify(mockService);
        }
    }

    @Test
    public void deleteChunkDeletesUsingRemoteService() throws Exception {
        S3Object chunk0 = new S3Object(key + "/0");
        S3Service mockService = createStrictMock(S3Service.class);
        mockService.deleteObject(bucket, chunk0.getKey());
        replay(mockService);

        new DirectChunkHandler(bucket, mockService).deleteChunk(chunk0.getKey());
        verify(mockService);
    }

    @Test(expected = IOException.class)
    public void remoteServiceThrowsErrorWhenDeletingChunk() throws Exception {
        S3Object chunk0 = new S3Object(key + "/0");
        S3Service mockService = createStrictMock(S3Service.class);
        mockService.deleteObject(bucket, chunk0.getKey());
        expectLastCall().andThrow(new S3ServiceException("TEST"));
        replay(mockService);

        new DirectChunkHandler(bucket, mockService).deleteChunk(chunk0.getKey());
        verify(mockService);
    }

    @Test
    public void getChunkReturnsObjectFromRemoteService() throws Exception {
        S3Object chunk0 = new S3Object(key + "/0");
        S3Service mockService = createStrictMock(S3Service.class);
        mockService.getObject(bucket, chunk0.getKey());
        expectLastCall().andReturn(chunk0);
        replay(mockService);

        assertSame(chunk0, new DirectChunkHandler(bucket, mockService).getChunk(chunk0.getKey()));
        verify(mockService);
    }

    @Test
    public void reconstructItemFromMultipleChunks() throws Exception {
        S3Object chunk0 = new S3Object(key + "/0");
        byte[] bytes0 = "There's a band on stage\n".getBytes();
        chunk0.setDataInputStream(new ByteArrayInputStream(bytes0));

        S3Object chunk1 = new S3Object(key + "/1");
        byte[] bytes1 = "That used to be huge\n".getBytes();
        chunk1.setDataInputStream(new ByteArrayInputStream(bytes1));

        S3Object chunk2 = new S3Object(key + "/2");
        byte[] bytes2 = "They're on but noone's listening".getBytes();
        chunk2.setDataInputStream(new ByteArrayInputStream(bytes2));

        S3Service mockService = createStrictMock(S3Service.class);
        replay(mockService);
        S3Object[] chunks = new S3Object[] { chunk0, chunk1, chunk2 };

        InputStream in = new DirectChunkHandler(bucket, mockService).reconstructChunks(chunks);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        IOUtils.copy(in, out);

        byte[] expected = new byte[bytes0.length + bytes1.length + bytes2.length];
        System.arraycopy(bytes0, 0, expected, 0, bytes0.length);
        System.arraycopy(bytes1, 0, expected, bytes0.length, bytes1.length);
        System.arraycopy(bytes2, 0, expected, (bytes0.length + bytes1.length), bytes2.length);

        assertTrue(Arrays.equals(expected, out.toByteArray()));
        verify(mockService);
    }

    @Test
    public void reconstructItemFromSingleChunk() throws Exception {
        S3Object chunk0 = new S3Object(key + "/0");
        byte[] bytes0 = "There's a band on stage\n".getBytes();
        chunk0.setDataInputStream(new ByteArrayInputStream(bytes0));

        S3Service mockService = createStrictMock(S3Service.class);
        replay(mockService);
        S3Object[] chunks = new S3Object[] { chunk0 };

        InputStream in = new DirectChunkHandler(bucket, mockService).reconstructChunks(chunks);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        IOUtils.copy(in, out);

        assertTrue(Arrays.equals(bytes0, out.toByteArray()));
        verify(mockService);
    }

    @Test
    public void checkDataInputStreamInitialisedForChunkBeforeReading() throws Exception {
        S3Object unreadChunk = new S3Object(key + "/0");

        S3Object readChunk = new S3Object(key + "/0");
        byte[] bytes = "There's a band on stage\n".getBytes();
        readChunk.setDataInputStream(new ByteArrayInputStream(bytes));

        S3Service mockService = createStrictMock(S3Service.class);
        mockService.getObject(bucket, unreadChunk.getKey());
        expectLastCall().andReturn(readChunk);
        replay(mockService);

        S3Object[] chunks = new S3Object[] { unreadChunk };
        InputStream in = new DirectChunkHandler(bucket, mockService).reconstructChunks(chunks);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        IOUtils.copy(in, out);

        verify(mockService);
    }

    @Test
    public void ensureChunksSortedByKeyBeforeStreaming() throws Exception {
        // TODO : check s3 docs and/or implement comparator to sort array by key
    }

    @Test(expected = IOException.class)
    public void ensureContinuousSequenceOfKeysBeforeRead() throws Exception {
        S3Object chunk0 = new S3Object(key + "/0");
        S3Object chunk1 = new S3Object(key + "/1");
        S3Object chunk3 = new S3Object(key + "/3");
        S3Object[] incorrectlyOrderedChunks = new S3Object[] { chunk0, chunk1, chunk3 };

        S3Service mockService = createStrictMock(S3Service.class);
        replay(mockService);

        try {
            new DirectChunkHandler(bucket, mockService).reconstructChunks(incorrectlyOrderedChunks);
        } finally {
            verify(mockService);
        }
    }
}