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 rc...@apache.org on 2019/12/02 03:01:05 UTC

[james-project] 02/05: JAMES-2990 MessagePreviewStore concurrent storing test

This is an automated email from the ASF dual-hosted git repository.

rcordier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit ee155c2d09663dc11401ec073937dcc56f837245
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Thu Nov 21 18:32:22 2019 +0700

    JAMES-2990 MessagePreviewStore concurrent storing test
---
 .../org/apache/james/jmap/api/preview/Preview.java |  8 ++++
 .../api/preview/MessagePreviewStoreContract.java   | 47 ++++++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/preview/Preview.java b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/preview/Preview.java
index 42c3db3..90c2fe2 100644
--- a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/preview/Preview.java
+++ b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/preview/Preview.java
@@ -24,6 +24,7 @@ import java.util.Objects;
 import org.apache.commons.lang3.StringUtils;
 
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.MoreObjects;
 import com.google.common.base.Preconditions;
 
 public class Preview {
@@ -73,4 +74,11 @@ public class Preview {
     public final int hashCode() {
         return Objects.hash(value);
     }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+            .add("value", value)
+            .toString();
+    }
 }
diff --git a/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/preview/MessagePreviewStoreContract.java b/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/preview/MessagePreviewStoreContract.java
index 3320684..335c0e2 100644
--- a/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/preview/MessagePreviewStoreContract.java
+++ b/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/preview/MessagePreviewStoreContract.java
@@ -23,9 +23,15 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
+import java.time.Duration;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.IntStream;
+
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.TestMessageId;
+import org.apache.james.util.concurrency.ConcurrentTestRunner;
 import org.assertj.core.api.SoftAssertions;
+import org.junit.jupiter.api.RepeatedTest;
 import org.junit.jupiter.api.Test;
 
 import reactor.core.publisher.Mono;
@@ -115,6 +121,47 @@ public interface MessagePreviewStoreContract {
     }
 
     @Test
+    default void concurrentStoreShouldOverrideOldValueWhenSameMessageId() throws Exception {
+        int threadCount = 10;
+        int stepCount = 100;
+
+        ConcurrentTestRunner.builder()
+            .operation((thread, step) -> Mono.from(testee()
+                .store(TestMessageId.of(thread), Preview.from(String.valueOf(step))))
+                .block())
+            .threadCount(threadCount)
+            .operationCount(stepCount)
+            .runSuccessfullyWithin(Duration.ofMinutes(1));
+
+        IntStream.range(0, threadCount)
+            .forEach(index -> assertThat(Mono.from(testee()
+                    .retrieve(TestMessageId.of(index)))
+                    .block())
+                .isEqualTo(Preview.from(String.valueOf(stepCount - 1))));
+    }
+
+    @Test
+    default void storeShouldBeConsistentUponSingleKeyOperation() throws Exception {
+        int threadCount = 10;
+        int operationCount = 100;
+
+        ConcurrentTestRunner.builder()
+            .operation((thread, step) -> Mono.from(testee()
+                .store(MESSAGE_ID_1, Preview.from(String.valueOf(step * threadCount + thread))))
+                .block())
+            .threadCount(threadCount)
+            .operationCount(operationCount)
+            .runSuccessfullyWithin(Duration.ofMinutes(1));
+
+        Preview preview = Mono.from(testee().retrieve(MESSAGE_ID_1)).block();
+        Integer previewAsInt = Integer.valueOf(preview.getValue());
+
+        assertThat(previewAsInt)
+            .describedAs("Ensure the stored result was generated by the last operation of one of the threads")
+            .isBetween(threadCount * (operationCount - 1), threadCount * operationCount);
+    }
+
+    @Test
     default void deleteShouldThrowWhenNullMessageId() {
         assertThatThrownBy(() -> Mono.from(testee().delete(null)).block())
             .isInstanceOf(NullPointerException.class);


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org