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 2018/01/19 12:07:26 UTC

[12/14] james-project git commit: JAMES-2290 try to make MemoryMailRepository to break with parallelism (fail)

JAMES-2290 try to make MemoryMailRepository to break with parallelism (fail)


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/a0d734f9
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/a0d734f9
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/a0d734f9

Branch: refs/heads/master
Commit: a0d734f95a12050c627bd6f1f3ad9f068c958f6e
Parents: cba5a2f
Author: Matthieu Baechler <ma...@apache.org>
Authored: Wed Jan 17 17:09:45 2018 +0100
Committer: benwa <bt...@linagora.com>
Committed: Fri Jan 19 18:57:58 2018 +0700

----------------------------------------------------------------------
 .../mailrepository/mailrepository-api/pom.xml   |  5 ++
 .../mailrepository/MailRepositoryContract.java  | 63 ++++++++++++++++++++
 .../mailrepository-memory/pom.xml               |  5 ++
 3 files changed, 73 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/a0d734f9/server/mailrepository/mailrepository-api/pom.xml
----------------------------------------------------------------------
diff --git a/server/mailrepository/mailrepository-api/pom.xml b/server/mailrepository/mailrepository-api/pom.xml
index b2fc1e7..26e97ec 100644
--- a/server/mailrepository/mailrepository-api/pom.xml
+++ b/server/mailrepository/mailrepository-api/pom.xml
@@ -43,6 +43,11 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>james-server-testing</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.assertj</groupId>
             <artifactId>assertj-core</artifactId>
             <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/james-project/blob/a0d734f9/server/mailrepository/mailrepository-api/src/test/java/org/apache/james/mailrepository/MailRepositoryContract.java
----------------------------------------------------------------------
diff --git a/server/mailrepository/mailrepository-api/src/test/java/org/apache/james/mailrepository/MailRepositoryContract.java b/server/mailrepository/mailrepository-api/src/test/java/org/apache/james/mailrepository/MailRepositoryContract.java
index 2afdf76..f89eb14 100644
--- a/server/mailrepository/mailrepository-api/src/test/java/org/apache/james/mailrepository/MailRepositoryContract.java
+++ b/server/mailrepository/mailrepository-api/src/test/java/org/apache/james/mailrepository/MailRepositoryContract.java
@@ -24,7 +24,13 @@ import static org.junit.jupiter.api.Assertions.assertAll;
 
 import java.nio.charset.StandardCharsets;
 import java.util.Date;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Random;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
 import javax.mail.MessagingException;
 import javax.mail.internet.MimeMessage;
@@ -33,10 +39,16 @@ import org.apache.james.core.MailAddress;
 import org.apache.james.core.builder.MimeMessageBuilder;
 import org.apache.james.mailrepository.api.MailRepository;
 import org.apache.james.server.core.MailImpl;
+import org.apache.james.util.concurrency.ConcurrentTestRunner;
+import org.apache.james.utils.DiscreteDistribution;
+import org.apache.james.utils.DiscreteDistribution.DistributionEntry;
 import org.apache.mailet.Mail;
 import org.apache.mailet.PerRecipientHeaders;
+import org.junit.jupiter.api.RepeatedTest;
 import org.junit.jupiter.api.Test;
 
+import com.github.fge.lambdas.runnable.ThrowingRunnable;
+import com.github.steveash.guavate.Guavate;
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableList;
 import com.google.common.hash.Hashing;
@@ -304,4 +316,55 @@ public interface MailRepositoryContract {
         assertThat(testee.retrieve(key)).satisfies(actual -> checkMailEquality(actual, mail));
     }
 
+    @RepeatedTest(100)
+    default void storingAndRemovingMessagesConcurrentlyShouldLeadToConsistentResult() throws Exception {
+        MailRepository testee = retrieveRepository();
+        int nbKeys = 20;
+        int nbIterations = 10;
+        int threadCount = 10;
+        ConcurrentHashMap.KeySetView<String, Boolean> expectedResult = ConcurrentHashMap.newKeySet();
+        List<Object> locks = IntStream.range(0, 10)
+            .boxed()
+            .collect(Guavate.toImmutableList());
+
+        Random random = new Random();
+        ThrowingRunnable add = () -> {
+            int keyIndex = computeKeyIndex(nbKeys, random.nextInt());
+            String key =  computeKey(keyIndex);
+            synchronized (locks.get(keyIndex)) {
+                testee.store(createMail(key));
+                expectedResult.add(key);
+            }
+        };
+
+        ThrowingRunnable remove = () -> {
+            int keyIndex = computeKeyIndex(nbKeys, random.nextInt());
+            String key =  computeKey(keyIndex);
+            synchronized (locks.get(keyIndex)) {
+                testee.remove(key);
+                expectedResult.remove(key);
+            }
+        };
+
+        DiscreteDistribution<ThrowingRunnable> distribution = DiscreteDistribution.create(
+            ImmutableList.of(
+                new DistributionEntry<>(add, 0.25),
+                new DistributionEntry<>(remove, 0.75)));
+
+        new ConcurrentTestRunner(threadCount, nbIterations,
+            (a, b) -> distribution.sample().run())
+            .run()
+            .awaitTermination(1, TimeUnit.MINUTES);
+
+        assertThat(testee.list()).containsOnlyElementsOf(expectedResult);
+    }
+
+    default String computeKey(int keyIndex) {
+        return "mail" + keyIndex;
+    }
+
+    default int computeKeyIndex(int nbKeys, Integer i) {
+        return i % nbKeys;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/a0d734f9/server/mailrepository/mailrepository-memory/pom.xml
----------------------------------------------------------------------
diff --git a/server/mailrepository/mailrepository-memory/pom.xml b/server/mailrepository/mailrepository-memory/pom.xml
index 4870dc5..0fec615 100644
--- a/server/mailrepository/mailrepository-memory/pom.xml
+++ b/server/mailrepository/mailrepository-memory/pom.xml
@@ -38,6 +38,11 @@
             <artifactId>james-server-core</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>james-server-testing</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>james-server-mailrepository-api</artifactId>
         </dependency>


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