PROTOCOL-115 Move ConcurrentTestRunner to james-util
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/4eb5e7df Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/4eb5e7df Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/4eb5e7df Branch: refs/heads/master Commit: 4eb5e7dfd86a17e0e936c1a2e68e7b477acb8a34 Parents: d4f18a9 Author: Raphael Ouazana <[email protected]> Authored: Thu Feb 2 10:12:19 2017 +0100 Committer: Raphael Ouazana <[email protected]> Committed: Thu Feb 2 15:23:43 2017 +0100 ---------------------------------------------------------------------- mailbox/pom.xml | 5 + mailbox/store/pom.xml | 5 + .../store/mail/model/MessageIdMapperTest.java | 2 +- .../store/mail/model/MessageMapperTest.java | 2 +- .../model/concurrency/ConcurrentTestRunner.java | 90 ------------- .../concurrency/ConcurrentTestRunnerTest.java | 135 ------------------- .../util/concurrency/ConcurrentTestRunner.java | 90 +++++++++++++ .../concurrency/ConcurrentTestRunnerTest.java | 135 +++++++++++++++++++ 8 files changed, 237 insertions(+), 227 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/4eb5e7df/mailbox/pom.xml ---------------------------------------------------------------------- diff --git a/mailbox/pom.xml b/mailbox/pom.xml index c4699f6..e838610 100644 --- a/mailbox/pom.xml +++ b/mailbox/pom.xml @@ -215,6 +215,11 @@ <artifactId>apache-james-mailbox-tool</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>james-server-util</artifactId> + <version>${project.version}</version> + </dependency> <!-- END Modules --> http://git-wip-us.apache.org/repos/asf/james-project/blob/4eb5e7df/mailbox/store/pom.xml ---------------------------------------------------------------------- diff --git a/mailbox/store/pom.xml b/mailbox/store/pom.xml index f6f10b0..52d16de 100644 --- a/mailbox/store/pom.xml +++ b/mailbox/store/pom.xml @@ -38,6 +38,11 @@ </dependency> <dependency> <groupId>org.apache.james</groupId> + <artifactId>james-server-util</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.james</groupId> <artifactId>apache-mime4j-core</artifactId> </dependency> <dependency> http://git-wip-us.apache.org/repos/asf/james-project/blob/4eb5e7df/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageIdMapperTest.java ---------------------------------------------------------------------- diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageIdMapperTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageIdMapperTest.java index 5ede73c..0770ec1 100644 --- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageIdMapperTest.java +++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageIdMapperTest.java @@ -43,10 +43,10 @@ import org.apache.james.mailbox.store.mail.MailboxMapper; import org.apache.james.mailbox.store.mail.MessageIdMapper; import org.apache.james.mailbox.store.mail.MessageMapper; import org.apache.james.mailbox.store.mail.MessageMapper.FetchType; -import org.apache.james.mailbox.store.mail.model.concurrency.ConcurrentTestRunner; import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder; import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox; import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage; +import org.apache.james.util.concurrency.ConcurrentTestRunner; import org.assertj.core.data.MapEntry; import org.junit.After; import org.junit.Assume; http://git-wip-us.apache.org/repos/asf/james-project/blob/4eb5e7df/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageMapperTest.java ---------------------------------------------------------------------- diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageMapperTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageMapperTest.java index ccbb0f2..6fdb35a 100644 --- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageMapperTest.java +++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageMapperTest.java @@ -46,10 +46,10 @@ import org.apache.james.mailbox.store.FlagsUpdateCalculator; import org.apache.james.mailbox.store.mail.MailboxMapper; import org.apache.james.mailbox.store.mail.MessageMapper; import org.apache.james.mailbox.store.mail.MessageMapper.FetchType; -import org.apache.james.mailbox.store.mail.model.concurrency.ConcurrentTestRunner; import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder; import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox; import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage; +import org.apache.james.util.concurrency.ConcurrentTestRunner; import org.junit.After; import org.junit.Assume; import org.junit.Rule; http://git-wip-us.apache.org/repos/asf/james-project/blob/4eb5e7df/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/concurrency/ConcurrentTestRunner.java ---------------------------------------------------------------------- diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/concurrency/ConcurrentTestRunner.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/concurrency/ConcurrentTestRunner.java deleted file mode 100644 index 35be61e..0000000 --- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/concurrency/ConcurrentTestRunner.java +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one * - * or more contributor license agreements. See the NOTICE file * - * distributed with this work for additional information * - * regarding copyright ownership. The ASF licenses this file * - * to you under the Apache License, Version 2.0 (the * - * "License"); you may not use this file except in compliance * - * with the License. You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, * - * software distributed under the License is distributed on an * - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * - * KIND, either express or implied. See the License for the * - * specific language governing permissions and limitations * - * under the License. * - ****************************************************************/ - -package org.apache.james.mailbox.store.mail.model.concurrency; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.Preconditions; - -public class ConcurrentTestRunner { - - private static final Logger LOGGER = LoggerFactory.getLogger(ConcurrentTestRunner.class); - - public interface BiConsumer { - void consume(int threadNumber, int step) throws Exception; - } - - private class ConcurrentRunnableTask implements Runnable { - private final int threadNumber; - private final BiConsumer biConsumer; - - public ConcurrentRunnableTask(int threadNumber, BiConsumer biConsumer) { - this.threadNumber = threadNumber; - this.biConsumer = biConsumer; - } - - @Override - public void run() { - countDownLatch.countDown(); - for (int i = 0; i < operationCount; i++) { - try { - biConsumer.consume(threadNumber, i); - } catch (Exception e) { - LOGGER.error("Error caught during concurrent testing", e); - } - } - } - } - - private final int threadCount; - private final int operationCount; - private final CountDownLatch countDownLatch; - private final BiConsumer biConsumer; - private final ExecutorService executorService; - - public ConcurrentTestRunner(int threadCount, int operationCount, BiConsumer biConsumer) { - Preconditions.checkArgument(threadCount > 0, "Thread count should be strictly positive"); - Preconditions.checkArgument(operationCount > 0, "Operation count should be strictly positive"); - Preconditions.checkNotNull(biConsumer); - this.threadCount = threadCount; - this.operationCount = operationCount; - this.countDownLatch = new CountDownLatch(threadCount); - this.biConsumer = biConsumer; - this.executorService = Executors.newFixedThreadPool(threadCount); - } - - public ConcurrentTestRunner run() { - for (int i = 0; i < threadCount; i++) { - executorService.submit(new ConcurrentRunnableTask(i, biConsumer)); - } - return this; - } - - public boolean awaitTermination(long time, TimeUnit unit) throws InterruptedException { - executorService.shutdown(); - return executorService.awaitTermination(time, unit); - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/4eb5e7df/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/concurrency/ConcurrentTestRunnerTest.java ---------------------------------------------------------------------- diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/concurrency/ConcurrentTestRunnerTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/concurrency/ConcurrentTestRunnerTest.java deleted file mode 100644 index 302ed9e..0000000 --- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/concurrency/ConcurrentTestRunnerTest.java +++ /dev/null @@ -1,135 +0,0 @@ -/**************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one * - * or more contributor license agreements. See the NOTICE file * - * distributed with this work for additional information * - * regarding copyright ownership. The ASF licenses this file * - * to you under the Apache License, Version 2.0 (the * - * "License"); you may not use this file except in compliance * - * with the License. You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, * - * software distributed under the License is distributed on an * - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * - * KIND, either express or implied. See the License for the * - * specific language governing permissions and limitations * - * under the License. * - ****************************************************************/ - -package org.apache.james.mailbox.store.mail.model.concurrency; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.TimeUnit; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -public class ConcurrentTestRunnerTest { - - public static final ConcurrentTestRunner.BiConsumer EMPTY_BI_CONSUMER = new ConcurrentTestRunner.BiConsumer() { - @Override - public void consume(int threadNumber, int step) throws Exception { - - } - }; - public static final int DEFAULT_AWAIT_TIME = 100; - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void constructorShouldThrowOnNegativeThreadCount() { - expectedException.expect(IllegalArgumentException.class); - - int operationCount = 1; - int threadCount = -1; - new ConcurrentTestRunner(threadCount, operationCount, EMPTY_BI_CONSUMER); - } - - @Test - public void constructorShouldThrowOnNegativeOperationCount() { - expectedException.expect(IllegalArgumentException.class); - - int operationCount = -1; - int threadCount = 1; - new ConcurrentTestRunner(threadCount, operationCount, EMPTY_BI_CONSUMER); - } - - @Test - public void constructorShouldThrowOnZeroThreadCount() { - expectedException.expect(IllegalArgumentException.class); - - int operationCount = 1; - int threadCount = 0; - new ConcurrentTestRunner(threadCount, operationCount, EMPTY_BI_CONSUMER); - } - - @Test - public void constructorShouldThrowOnZeroOperationCount() { - expectedException.expect(IllegalArgumentException.class); - - int operationCount = 0; - int threadCount = 1; - new ConcurrentTestRunner(threadCount, operationCount, EMPTY_BI_CONSUMER); - } - - @Test - public void constructorShouldThrowOnNullBiConsumer() { - expectedException.expect(NullPointerException.class); - - int operationCount = 1; - int threadCount = 1; - new ConcurrentTestRunner(threadCount, operationCount, null); - } - - @Test - public void awaitTerminationShouldReturnTrueWhenFinished() throws Exception { - int operationCount = 1; - int threadCount = 1; - - ConcurrentTestRunner concurrentTestRunner = new ConcurrentTestRunner(threadCount, operationCount, EMPTY_BI_CONSUMER) - .run(); - - assertThat(concurrentTestRunner.awaitTermination(DEFAULT_AWAIT_TIME, TimeUnit.MILLISECONDS)).isTrue(); - } - - @Test - public void awaitTerminationShouldReturnFalseWhenNotFinished() throws Exception { - int operationCount = 1; - int threadCount = 1; - final int sleepDelay = 50; - - ConcurrentTestRunner concurrentTestRunner = new ConcurrentTestRunner(threadCount, operationCount, - new ConcurrentTestRunner.BiConsumer() { - @Override - public void consume(int threadNumber, int step) throws Exception { - Thread.sleep(sleepDelay); - } - }) - .run(); - - assertThat(concurrentTestRunner.awaitTermination(sleepDelay / 2, TimeUnit.MILLISECONDS)).isFalse(); - } - - @Test - public void runShouldPerformAllOperations() throws Exception { - int operationCount = 2; - int threadCount = 2; - final ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<String>(); - - ConcurrentTestRunner concurrentTestRunner = new ConcurrentTestRunner(threadCount, operationCount, - new ConcurrentTestRunner.BiConsumer() { - @Override - public void consume(int threadNumber, int step) throws Exception { - queue.add(threadNumber + ":" + step); - } - }) - .run(); - - assertThat(concurrentTestRunner.awaitTermination(DEFAULT_AWAIT_TIME, TimeUnit.MILLISECONDS)).isTrue(); - assertThat(queue).containsOnly("0:0", "0:1", "1:0", "1:1"); - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/4eb5e7df/server/container/util/src/main/java/org/apache/james/util/concurrency/ConcurrentTestRunner.java ---------------------------------------------------------------------- diff --git a/server/container/util/src/main/java/org/apache/james/util/concurrency/ConcurrentTestRunner.java b/server/container/util/src/main/java/org/apache/james/util/concurrency/ConcurrentTestRunner.java new file mode 100644 index 0000000..0a4fa40 --- /dev/null +++ b/server/container/util/src/main/java/org/apache/james/util/concurrency/ConcurrentTestRunner.java @@ -0,0 +1,90 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.util.concurrency; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Preconditions; + +public class ConcurrentTestRunner { + + private static final Logger LOGGER = LoggerFactory.getLogger(ConcurrentTestRunner.class); + + public interface BiConsumer { + void consume(int threadNumber, int step) throws Exception; + } + + private class ConcurrentRunnableTask implements Runnable { + private final int threadNumber; + private final BiConsumer biConsumer; + + public ConcurrentRunnableTask(int threadNumber, BiConsumer biConsumer) { + this.threadNumber = threadNumber; + this.biConsumer = biConsumer; + } + + @Override + public void run() { + countDownLatch.countDown(); + for (int i = 0; i < operationCount; i++) { + try { + biConsumer.consume(threadNumber, i); + } catch (Exception e) { + LOGGER.error("Error caught during concurrent testing", e); + } + } + } + } + + private final int threadCount; + private final int operationCount; + private final CountDownLatch countDownLatch; + private final BiConsumer biConsumer; + private final ExecutorService executorService; + + public ConcurrentTestRunner(int threadCount, int operationCount, BiConsumer biConsumer) { + Preconditions.checkArgument(threadCount > 0, "Thread count should be strictly positive"); + Preconditions.checkArgument(operationCount > 0, "Operation count should be strictly positive"); + Preconditions.checkNotNull(biConsumer); + this.threadCount = threadCount; + this.operationCount = operationCount; + this.countDownLatch = new CountDownLatch(threadCount); + this.biConsumer = biConsumer; + this.executorService = Executors.newFixedThreadPool(threadCount); + } + + public ConcurrentTestRunner run() { + for (int i = 0; i < threadCount; i++) { + executorService.submit(new ConcurrentRunnableTask(i, biConsumer)); + } + return this; + } + + public boolean awaitTermination(long time, TimeUnit unit) throws InterruptedException { + executorService.shutdown(); + return executorService.awaitTermination(time, unit); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/4eb5e7df/server/container/util/src/test/java/org/apache/james/util/concurrency/ConcurrentTestRunnerTest.java ---------------------------------------------------------------------- diff --git a/server/container/util/src/test/java/org/apache/james/util/concurrency/ConcurrentTestRunnerTest.java b/server/container/util/src/test/java/org/apache/james/util/concurrency/ConcurrentTestRunnerTest.java new file mode 100644 index 0000000..98bde34 --- /dev/null +++ b/server/container/util/src/test/java/org/apache/james/util/concurrency/ConcurrentTestRunnerTest.java @@ -0,0 +1,135 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.util.concurrency; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.TimeUnit; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class ConcurrentTestRunnerTest { + + public static final ConcurrentTestRunner.BiConsumer EMPTY_BI_CONSUMER = new ConcurrentTestRunner.BiConsumer() { + @Override + public void consume(int threadNumber, int step) throws Exception { + + } + }; + public static final int DEFAULT_AWAIT_TIME = 100; + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void constructorShouldThrowOnNegativeThreadCount() { + expectedException.expect(IllegalArgumentException.class); + + int operationCount = 1; + int threadCount = -1; + new ConcurrentTestRunner(threadCount, operationCount, EMPTY_BI_CONSUMER); + } + + @Test + public void constructorShouldThrowOnNegativeOperationCount() { + expectedException.expect(IllegalArgumentException.class); + + int operationCount = -1; + int threadCount = 1; + new ConcurrentTestRunner(threadCount, operationCount, EMPTY_BI_CONSUMER); + } + + @Test + public void constructorShouldThrowOnZeroThreadCount() { + expectedException.expect(IllegalArgumentException.class); + + int operationCount = 1; + int threadCount = 0; + new ConcurrentTestRunner(threadCount, operationCount, EMPTY_BI_CONSUMER); + } + + @Test + public void constructorShouldThrowOnZeroOperationCount() { + expectedException.expect(IllegalArgumentException.class); + + int operationCount = 0; + int threadCount = 1; + new ConcurrentTestRunner(threadCount, operationCount, EMPTY_BI_CONSUMER); + } + + @Test + public void constructorShouldThrowOnNullBiConsumer() { + expectedException.expect(NullPointerException.class); + + int operationCount = 1; + int threadCount = 1; + new ConcurrentTestRunner(threadCount, operationCount, null); + } + + @Test + public void awaitTerminationShouldReturnTrueWhenFinished() throws Exception { + int operationCount = 1; + int threadCount = 1; + + ConcurrentTestRunner concurrentTestRunner = new ConcurrentTestRunner(threadCount, operationCount, EMPTY_BI_CONSUMER) + .run(); + + assertThat(concurrentTestRunner.awaitTermination(DEFAULT_AWAIT_TIME, TimeUnit.MILLISECONDS)).isTrue(); + } + + @Test + public void awaitTerminationShouldReturnFalseWhenNotFinished() throws Exception { + int operationCount = 1; + int threadCount = 1; + final int sleepDelay = 50; + + ConcurrentTestRunner concurrentTestRunner = new ConcurrentTestRunner(threadCount, operationCount, + new ConcurrentTestRunner.BiConsumer() { + @Override + public void consume(int threadNumber, int step) throws Exception { + Thread.sleep(sleepDelay); + } + }) + .run(); + + assertThat(concurrentTestRunner.awaitTermination(sleepDelay / 2, TimeUnit.MILLISECONDS)).isFalse(); + } + + @Test + public void runShouldPerformAllOperations() throws Exception { + int operationCount = 2; + int threadCount = 2; + final ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<String>(); + + ConcurrentTestRunner concurrentTestRunner = new ConcurrentTestRunner(threadCount, operationCount, + new ConcurrentTestRunner.BiConsumer() { + @Override + public void consume(int threadNumber, int step) throws Exception { + queue.add(threadNumber + ":" + step); + } + }) + .run(); + + assertThat(concurrentTestRunner.awaitTermination(DEFAULT_AWAIT_TIME, TimeUnit.MILLISECONDS)).isTrue(); + assertThat(queue).containsOnly("0:0", "0:1", "1:0", "1:1"); + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
