This is an automated email from the ASF dual-hosted git repository. btellier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 700116f79c8cc5f71279210142161719c0302152 Author: Benoit Tellier <[email protected]> AuthorDate: Wed Jul 22 11:48:49 2020 +0700 JAMES-3314 Mutualize CassandraBlobStoreContract --- ...reTest.java => CassandraBlobStoreContract.java} | 84 ++++++--------------- .../blob/cassandra/CassandraBlobStoreTest.java | 88 +--------------------- .../CassandraPassTroughBlobStoreTest.java | 87 +-------------------- 3 files changed, 29 insertions(+), 230 deletions(-) diff --git a/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraBlobStoreTest.java b/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraBlobStoreContract.java similarity index 50% copy from server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraBlobStoreTest.java copy to server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraBlobStoreContract.java index ae9136b..b6a6434 100644 --- a/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraBlobStoreTest.java +++ b/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraBlobStoreContract.java @@ -22,7 +22,6 @@ package org.apache.james.blob.cassandra; import static org.apache.james.blob.api.BlobStore.StoragePolicy.LOW_COST; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import java.io.IOException; @@ -30,21 +29,11 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; import org.apache.commons.io.IOUtils; -import org.apache.james.backends.cassandra.CassandraCluster; -import org.apache.james.backends.cassandra.CassandraClusterExtension; -import org.apache.james.backends.cassandra.init.configuration.CassandraConfiguration; import org.apache.james.blob.api.BlobId; -import org.apache.james.blob.api.BlobStore; -import org.apache.james.blob.api.BucketName; -import org.apache.james.blob.api.HashBlobId; -import org.apache.james.blob.api.MetricableBlobStore; import org.apache.james.blob.api.MetricableBlobStoreContract; import org.apache.james.blob.api.ObjectStoreException; -import org.apache.james.server.blob.deduplication.BlobStoreFactory; import org.apache.james.util.io.ZeroedInputStream; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; import com.google.common.base.Strings; import com.google.common.hash.Hashing; @@ -52,93 +41,62 @@ import com.google.common.hash.HashingInputStream; import reactor.core.publisher.Mono; -public class CassandraBlobStoreTest implements MetricableBlobStoreContract { - private static final int CHUNK_SIZE = 10240; - private static final int MULTIPLE_CHUNK_SIZE = 3; - - @RegisterExtension - static CassandraClusterExtension cassandraCluster = new CassandraClusterExtension(CassandraBlobModule.MODULE); - - private BlobStore testee; - private CassandraDefaultBucketDAO defaultBucketDAO; - - @BeforeEach - void setUp(CassandraCluster cassandra) { - HashBlobId.Factory blobIdFactory = new HashBlobId.Factory(); - CassandraBucketDAO bucketDAO = new CassandraBucketDAO(blobIdFactory, cassandra.getConf()); - defaultBucketDAO = spy(new CassandraDefaultBucketDAO(cassandra.getConf())); - CassandraConfiguration cassandraConfiguration = CassandraConfiguration.builder() - .blobPartSize(CHUNK_SIZE) - .build(); - testee = new MetricableBlobStore( - metricsTestExtension.getMetricFactory(), - BlobStoreFactory.builder() - .dumbBlobStore(new CassandraDumbBlobStore(defaultBucketDAO, bucketDAO, cassandraConfiguration, BucketName.DEFAULT)) - .blobIdFactory(blobIdFactory) - .defaultBucketName() - .deduplication()); - } - - @Override - public BlobStore testee() { - return testee; - } +public interface CassandraBlobStoreContract extends MetricableBlobStoreContract { + int MULTIPLE_CHUNK_SIZE = 3; + int CHUNK_SIZE = 10240; - @Override - public BlobId.Factory blobIdFactory() { - return new HashBlobId.Factory(); - } + CassandraDefaultBucketDAO defaultBucketDAO(); @Test - void readBytesShouldReturnSplitSavedDataByChunk() { + default void readBytesShouldReturnSplitSavedDataByChunk() { String longString = Strings.repeat("0123456789\n", MULTIPLE_CHUNK_SIZE); - BlobId blobId = Mono.from(testee.save(testee.getDefaultBucketName(), longString, LOW_COST)).block(); + BlobId blobId = Mono.from(testee().save(testee().getDefaultBucketName(), longString, LOW_COST)).block(); - byte[] bytes = Mono.from(testee.readBytes(testee.getDefaultBucketName(), blobId)).block(); + byte[] bytes = Mono.from(testee().readBytes(testee().getDefaultBucketName(), blobId)).block(); assertThat(new String(bytes, StandardCharsets.UTF_8)).isEqualTo(longString); } @Test - void readBytesShouldNotReturnInvalidResultsWhenPartialDataPresent() { + default void readBytesShouldNotReturnInvalidResultsWhenPartialDataPresent() { int repeatCount = MULTIPLE_CHUNK_SIZE * CHUNK_SIZE; String longString = Strings.repeat("0123456789\n", repeatCount); - BlobId blobId = Mono.from(testee.save(testee.getDefaultBucketName(), longString, LOW_COST)).block(); + BlobId blobId = Mono.from(testee().save(testee().getDefaultBucketName(), longString, LOW_COST)).block(); - when(defaultBucketDAO.readPart(blobId, 1)).thenReturn(Mono.empty()); + when(defaultBucketDAO().readPart(blobId, 1)).thenReturn(Mono.empty()); - assertThatThrownBy(() -> Mono.from(testee.readBytes(testee.getDefaultBucketName(), blobId)).block()) + assertThatThrownBy(() -> Mono.from(testee().readBytes(testee().getDefaultBucketName(), blobId)).block()) .isInstanceOf(ObjectStoreException.class) .hasMessageContaining("Missing blob part for blobId"); } @Test - void readShouldNotReturnInvalidResultsWhenPartialDataPresent() { + default void readShouldNotReturnInvalidResultsWhenPartialDataPresent() { int repeatCount = MULTIPLE_CHUNK_SIZE * CHUNK_SIZE; String longString = Strings.repeat("0123456789\n", repeatCount); - BlobId blobId = Mono.from(testee.save(testee.getDefaultBucketName(), longString, LOW_COST)).block(); + BlobId blobId = Mono.from(testee().save(testee().getDefaultBucketName(), longString, LOW_COST)).block(); - when(defaultBucketDAO.readPart(blobId, 1)).thenReturn(Mono.empty()); + when(defaultBucketDAO().readPart(blobId, 1)).thenReturn(Mono.empty()); - assertThatThrownBy(() -> IOUtils.toString(testee.read(testee.getDefaultBucketName(), blobId), StandardCharsets.UTF_8)) + assertThatThrownBy(() -> IOUtils.toString(testee().read(testee().getDefaultBucketName(), blobId), StandardCharsets.UTF_8)) .isInstanceOf(ObjectStoreException.class) .hasMessageContaining("Missing blob part for blobId"); } @Test - void deleteBucketShouldThrowWhenDeletingDefaultBucket() { - assertThatThrownBy(() -> testee.deleteBucket(testee.getDefaultBucketName())) + default void deleteBucketShouldThrowWhenDeletingDefaultBucket() { + assertThatThrownBy(() -> testee().deleteBucket(testee().getDefaultBucketName())) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Deleting the default bucket is forbidden"); } @Test - void blobStoreShouldSupport100MBBlob() throws IOException { + default void blobStoreShouldSupport100MBBlob() throws IOException { ZeroedInputStream data = new ZeroedInputStream(100_000_000); HashingInputStream writeHash = new HashingInputStream(Hashing.sha256(), data); - BlobId blobId = Mono.from(testee.save(testee.getDefaultBucketName(), writeHash, LOW_COST)).block(); + BlobId blobId = Mono.from(testee().save(testee().getDefaultBucketName(), writeHash, LOW_COST)).block(); - InputStream bytes = testee.read(testee.getDefaultBucketName(), blobId); + InputStream bytes = testee().read(testee().getDefaultBucketName(), blobId); HashingInputStream readHash = new HashingInputStream(Hashing.sha256(), bytes); consumeStream(readHash); @@ -151,4 +109,4 @@ public class CassandraBlobStoreTest implements MetricableBlobStoreContract { // consume the rest of the stream } } -} \ No newline at end of file +} diff --git a/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraBlobStoreTest.java b/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraBlobStoreTest.java index ae9136b..73b031a 100644 --- a/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraBlobStoreTest.java +++ b/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraBlobStoreTest.java @@ -19,17 +19,8 @@ package org.apache.james.blob.cassandra; -import static org.apache.james.blob.api.BlobStore.StoragePolicy.LOW_COST; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; import org.apache.james.backends.cassandra.CassandraCluster; import org.apache.james.backends.cassandra.CassandraClusterExtension; import org.apache.james.backends.cassandra.init.configuration.CassandraConfiguration; @@ -38,24 +29,11 @@ import org.apache.james.blob.api.BlobStore; import org.apache.james.blob.api.BucketName; import org.apache.james.blob.api.HashBlobId; import org.apache.james.blob.api.MetricableBlobStore; -import org.apache.james.blob.api.MetricableBlobStoreContract; -import org.apache.james.blob.api.ObjectStoreException; import org.apache.james.server.blob.deduplication.BlobStoreFactory; -import org.apache.james.util.io.ZeroedInputStream; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import com.google.common.base.Strings; -import com.google.common.hash.Hashing; -import com.google.common.hash.HashingInputStream; - -import reactor.core.publisher.Mono; - -public class CassandraBlobStoreTest implements MetricableBlobStoreContract { - private static final int CHUNK_SIZE = 10240; - private static final int MULTIPLE_CHUNK_SIZE = 3; - +public class CassandraBlobStoreTest implements CassandraBlobStoreContract { @RegisterExtension static CassandraClusterExtension cassandraCluster = new CassandraClusterExtension(CassandraBlobModule.MODULE); @@ -89,66 +67,8 @@ public class CassandraBlobStoreTest implements MetricableBlobStoreContract { return new HashBlobId.Factory(); } - @Test - void readBytesShouldReturnSplitSavedDataByChunk() { - String longString = Strings.repeat("0123456789\n", MULTIPLE_CHUNK_SIZE); - BlobId blobId = Mono.from(testee.save(testee.getDefaultBucketName(), longString, LOW_COST)).block(); - - byte[] bytes = Mono.from(testee.readBytes(testee.getDefaultBucketName(), blobId)).block(); - - assertThat(new String(bytes, StandardCharsets.UTF_8)).isEqualTo(longString); - } - - @Test - void readBytesShouldNotReturnInvalidResultsWhenPartialDataPresent() { - int repeatCount = MULTIPLE_CHUNK_SIZE * CHUNK_SIZE; - String longString = Strings.repeat("0123456789\n", repeatCount); - BlobId blobId = Mono.from(testee.save(testee.getDefaultBucketName(), longString, LOW_COST)).block(); - - when(defaultBucketDAO.readPart(blobId, 1)).thenReturn(Mono.empty()); - - assertThatThrownBy(() -> Mono.from(testee.readBytes(testee.getDefaultBucketName(), blobId)).block()) - .isInstanceOf(ObjectStoreException.class) - .hasMessageContaining("Missing blob part for blobId"); - } - - @Test - void readShouldNotReturnInvalidResultsWhenPartialDataPresent() { - int repeatCount = MULTIPLE_CHUNK_SIZE * CHUNK_SIZE; - String longString = Strings.repeat("0123456789\n", repeatCount); - BlobId blobId = Mono.from(testee.save(testee.getDefaultBucketName(), longString, LOW_COST)).block(); - - when(defaultBucketDAO.readPart(blobId, 1)).thenReturn(Mono.empty()); - - assertThatThrownBy(() -> IOUtils.toString(testee.read(testee.getDefaultBucketName(), blobId), StandardCharsets.UTF_8)) - .isInstanceOf(ObjectStoreException.class) - .hasMessageContaining("Missing blob part for blobId"); - } - - @Test - void deleteBucketShouldThrowWhenDeletingDefaultBucket() { - assertThatThrownBy(() -> testee.deleteBucket(testee.getDefaultBucketName())) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Deleting the default bucket is forbidden"); - } - - @Test - void blobStoreShouldSupport100MBBlob() throws IOException { - ZeroedInputStream data = new ZeroedInputStream(100_000_000); - HashingInputStream writeHash = new HashingInputStream(Hashing.sha256(), data); - BlobId blobId = Mono.from(testee.save(testee.getDefaultBucketName(), writeHash, LOW_COST)).block(); - - InputStream bytes = testee.read(testee.getDefaultBucketName(), blobId); - HashingInputStream readHash = new HashingInputStream(Hashing.sha256(), bytes); - consumeStream(readHash); - - assertThat(readHash.hash().toString()).isEqualTo(writeHash.hash().toString()); - } - - private void consumeStream(InputStream tmpMsgIn) throws IOException { - byte[] discard = new byte[4096]; - while (tmpMsgIn.read(discard) != -1) { - // consume the rest of the stream - } + @Override + public CassandraDefaultBucketDAO defaultBucketDAO() { + return defaultBucketDAO; } } \ No newline at end of file diff --git a/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraPassTroughBlobStoreTest.java b/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraPassTroughBlobStoreTest.java index 9ea1731..755dc28 100644 --- a/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraPassTroughBlobStoreTest.java +++ b/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraPassTroughBlobStoreTest.java @@ -19,17 +19,8 @@ package org.apache.james.blob.cassandra; -import static org.apache.james.blob.api.BlobStore.StoragePolicy.LOW_COST; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; import org.apache.james.backends.cassandra.CassandraCluster; import org.apache.james.backends.cassandra.CassandraClusterExtension; import org.apache.james.backends.cassandra.init.configuration.CassandraConfiguration; @@ -38,23 +29,11 @@ import org.apache.james.blob.api.BlobStore; import org.apache.james.blob.api.BucketName; import org.apache.james.blob.api.HashBlobId; import org.apache.james.blob.api.MetricableBlobStore; -import org.apache.james.blob.api.MetricableBlobStoreContract; -import org.apache.james.blob.api.ObjectStoreException; import org.apache.james.server.blob.deduplication.BlobStoreFactory; -import org.apache.james.util.io.ZeroedInputStream; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import com.google.common.base.Strings; -import com.google.common.hash.Hashing; -import com.google.common.hash.HashingInputStream; -import reactor.core.publisher.Mono; - -public class CassandraPassTroughBlobStoreTest implements MetricableBlobStoreContract { - private static final int CHUNK_SIZE = 10240; - private static final int MULTIPLE_CHUNK_SIZE = 3; - +public class CassandraPassTroughBlobStoreTest implements CassandraBlobStoreContract { @RegisterExtension static CassandraClusterExtension cassandraCluster = new CassandraClusterExtension(CassandraBlobModule.MODULE); @@ -88,66 +67,8 @@ public class CassandraPassTroughBlobStoreTest implements MetricableBlobStoreCont return new HashBlobId.Factory(); } - @Test - void readBytesShouldReturnSplitSavedDataByChunk() { - String longString = Strings.repeat("0123456789\n", MULTIPLE_CHUNK_SIZE); - BlobId blobId = Mono.from(testee.save(testee.getDefaultBucketName(), longString, LOW_COST)).block(); - - byte[] bytes = Mono.from(testee.readBytes(testee.getDefaultBucketName(), blobId)).block(); - - assertThat(new String(bytes, StandardCharsets.UTF_8)).isEqualTo(longString); - } - - @Test - void readBytesShouldNotReturnInvalidResultsWhenPartialDataPresent() { - int repeatCount = MULTIPLE_CHUNK_SIZE * CHUNK_SIZE; - String longString = Strings.repeat("0123456789\n", repeatCount); - BlobId blobId = Mono.from(testee.save(testee.getDefaultBucketName(), longString, LOW_COST)).block(); - - when(defaultBucketDAO.readPart(blobId, 1)).thenReturn(Mono.empty()); - - assertThatThrownBy(() -> Mono.from(testee.readBytes(testee.getDefaultBucketName(), blobId)).block()) - .isInstanceOf(ObjectStoreException.class) - .hasMessageContaining("Missing blob part for blobId"); - } - - @Test - void readShouldNotReturnInvalidResultsWhenPartialDataPresent() { - int repeatCount = MULTIPLE_CHUNK_SIZE * CHUNK_SIZE; - String longString = Strings.repeat("0123456789\n", repeatCount); - BlobId blobId = Mono.from(testee.save(testee.getDefaultBucketName(), longString, LOW_COST)).block(); - - when(defaultBucketDAO.readPart(blobId, 1)).thenReturn(Mono.empty()); - - assertThatThrownBy(() -> IOUtils.toString(testee.read(testee.getDefaultBucketName(), blobId), StandardCharsets.UTF_8)) - .isInstanceOf(ObjectStoreException.class) - .hasMessageContaining("Missing blob part for blobId"); - } - - @Test - void deleteBucketShouldThrowWhenDeletingDefaultBucket() { - assertThatThrownBy(() -> testee.deleteBucket(testee.getDefaultBucketName())) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Deleting the default bucket is forbidden"); - } - - @Test - void blobStoreShouldSupport100MBBlob() throws IOException { - ZeroedInputStream data = new ZeroedInputStream(100_000_000); - HashingInputStream writeHash = new HashingInputStream(Hashing.sha256(), data); - BlobId blobId = Mono.from(testee.save(testee.getDefaultBucketName(), writeHash, LOW_COST)).block(); - - InputStream bytes = testee.read(testee.getDefaultBucketName(), blobId); - HashingInputStream readHash = new HashingInputStream(Hashing.sha256(), bytes); - consumeStream(readHash); - - assertThat(readHash.hash().toString()).isEqualTo(writeHash.hash().toString()); - } - - private void consumeStream(InputStream tmpMsgIn) throws IOException { - byte[] discard = new byte[4096]; - while (tmpMsgIn.read(discard) != -1) { - // consume the rest of the stream - } + @Override + public CassandraDefaultBucketDAO defaultBucketDAO() { + return defaultBucketDAO; } } \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
