You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2020/07/24 10:34:34 UTC
[james-project] 03/07: JAMES-3314 Mutualize
CassandraBlobStoreContract
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 <bt...@linagora.com>
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: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org