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 305c9212bd829ddb07501c8aa314e486a4a58a8b Author: Benoit Tellier <[email protected]> AuthorDate: Fri Feb 22 14:50:45 2019 +0700 MAILBOX-381 Add concurrent tests for Message Vault --- .../vault/memory/MemoryDeletedMessagesVault.java | 6 ++-- .../apache/james/vault/DeletedMessageFixture.java | 21 ++++++------ .../james/vault/DeletedMessageVaultContract.java | 37 ++++++++++++++++++++++ 3 files changed, 51 insertions(+), 13 deletions(-) diff --git a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/memory/MemoryDeletedMessagesVault.java b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/memory/MemoryDeletedMessagesVault.java index d35f43b..172692e 100644 --- a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/memory/MemoryDeletedMessagesVault.java +++ b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/memory/MemoryDeletedMessagesVault.java @@ -40,7 +40,7 @@ public class MemoryDeletedMessagesVault implements DeletedMessageVault { } @Override - public Mono<Void> append(User user, DeletedMessage deletedMessage) { + public synchronized Mono<Void> append(User user, DeletedMessage deletedMessage) { Preconditions.checkNotNull(user); Preconditions.checkNotNull(deletedMessage); @@ -49,7 +49,7 @@ public class MemoryDeletedMessagesVault implements DeletedMessageVault { } @Override - public Mono<Void> delete(User user, MessageId messageId) { + public synchronized Mono<Void> delete(User user, MessageId messageId) { Preconditions.checkNotNull(user); Preconditions.checkNotNull(messageId); @@ -58,7 +58,7 @@ public class MemoryDeletedMessagesVault implements DeletedMessageVault { } @Override - public Flux<DeletedMessage> search(User user, Query query) { + public synchronized Flux<DeletedMessage> search(User user, Query query) { Preconditions.checkNotNull(user); Preconditions.checkNotNull(query); Preconditions.checkArgument(query.getCriteria().isEmpty(), "Search is not supported yet..."); diff --git a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageFixture.java b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageFixture.java index 69f58e0..f74d7c1 100644 --- a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageFixture.java +++ b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageFixture.java @@ -26,6 +26,7 @@ import static org.apache.mailet.base.MailAddressFixture.SENDER; import java.io.ByteArrayInputStream; import java.nio.charset.StandardCharsets; import java.time.ZonedDateTime; +import java.util.function.Function; import java.util.function.Supplier; import org.apache.james.core.MaybeSender; @@ -45,9 +46,8 @@ public interface DeletedMessageFixture { byte[] CONTENT = "header: value\r\n\r\ncontent".getBytes(StandardCharsets.UTF_8); String SUBJECT = "subject"; - - Supplier<DeletedMessage.Builder.FinalStage> FINAL_STAGE = () -> DeletedMessage.builder() - .messageId(MESSAGE_ID) + Function<Long, DeletedMessage> DELETED_MESSAGE_GENERATOR = i -> DeletedMessage.builder() + .messageId(InMemoryMessageId.of(i)) .originMailboxes(MAILBOX_ID_1, MAILBOX_ID_2) .user(USER) .deliveryDate(DELIVERY_DATE) @@ -55,13 +55,10 @@ public interface DeletedMessageFixture { .content(() -> new ByteArrayInputStream(CONTENT)) .sender(MaybeSender.of(SENDER)) .recipients(RECIPIENT1, RECIPIENT2) - .hasAttachment(false); - DeletedMessage DELETED_MESSAGE_WITH_SUBJECT = FINAL_STAGE.get() - .subject(SUBJECT) + .hasAttachment(false) .build(); - DeletedMessage DELETED_MESSAGE = FINAL_STAGE.get().build(); - DeletedMessage DELETED_MESSAGE_2 = DeletedMessage.builder() - .messageId(MESSAGE_ID_2) + Supplier<DeletedMessage.Builder.FinalStage> FINAL_STAGE = () -> DeletedMessage.builder() + .messageId(MESSAGE_ID) .originMailboxes(MAILBOX_ID_1, MAILBOX_ID_2) .user(USER) .deliveryDate(DELIVERY_DATE) @@ -69,6 +66,10 @@ public interface DeletedMessageFixture { .content(() -> new ByteArrayInputStream(CONTENT)) .sender(MaybeSender.of(SENDER)) .recipients(RECIPIENT1, RECIPIENT2) - .hasAttachment(false) + .hasAttachment(false); + DeletedMessage DELETED_MESSAGE_WITH_SUBJECT = FINAL_STAGE.get() + .subject(SUBJECT) .build(); + DeletedMessage DELETED_MESSAGE = FINAL_STAGE.get().build(); + DeletedMessage DELETED_MESSAGE_2 = DELETED_MESSAGE_GENERATOR.apply(MESSAGE_ID_2.getRawId()); } diff --git a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultContract.java b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultContract.java index 1474763..5012475 100644 --- a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultContract.java +++ b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultContract.java @@ -21,12 +21,17 @@ package org.apache.james.vault; import static org.apache.james.vault.DeletedMessageFixture.DELETED_MESSAGE; import static org.apache.james.vault.DeletedMessageFixture.DELETED_MESSAGE_2; +import static org.apache.james.vault.DeletedMessageFixture.DELETED_MESSAGE_GENERATOR; import static org.apache.james.vault.DeletedMessageFixture.MESSAGE_ID; import static org.apache.james.vault.DeletedMessageFixture.USER; import static org.apache.james.vault.DeletedMessageFixture.USER_2; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import java.time.Duration; + +import org.apache.james.mailbox.inmemory.InMemoryMessageId; +import org.apache.james.util.concurrency.ConcurrentTestRunner; import org.junit.jupiter.api.Test; import reactor.core.publisher.Flux; @@ -111,4 +116,36 @@ public interface DeletedMessageVaultContract { assertThat(Flux.from(getVault().search(USER, Query.all())).collectList().block()) .isEmpty(); } + + @Test + default void appendShouldRunSuccessfullyInAConcurrentContext() throws Exception { + int operationCount = 10; + int threadCount = 10; + ConcurrentTestRunner.builder() + .operation((a, b) -> Mono.from(getVault().append(USER, DELETED_MESSAGE_GENERATOR.apply(Long.valueOf(a * threadCount + b)))).block()) + .threadCount(threadCount) + .operationCount(operationCount) + .runSuccessfullyWithin(Duration.ofMinutes(1)); + + assertThat(Flux.from(getVault().search(USER, Query.all())).collectList().block()) + .hasSize(threadCount * operationCount); + } + + @Test + default void deleteShouldRunSuccessfullyInAConcurrentContext() throws Exception { + int operationCount = 10; + int threadCount = 10; + Flux.range(0, operationCount * threadCount) + .flatMap(i -> Mono.from(getVault().append(USER, DELETED_MESSAGE_GENERATOR.apply(Long.valueOf(i))))) + .blockLast(); + + ConcurrentTestRunner.builder() + .operation((a, b) -> Mono.from(getVault().delete(USER, InMemoryMessageId.of(a * threadCount + b))).block()) + .threadCount(threadCount) + .operationCount(operationCount) + .runSuccessfullyWithin(Duration.ofMinutes(1)); + + assertThat(Flux.from(getVault().search(USER, Query.all())).collectList().block()) + .isEmpty(); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
