You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by cl...@apache.org on 2016/09/26 21:58:50 UTC
[5/6] activemq-artemis git commit: ARTEMIS-737 Improving Tests by
checking thread leaks and Waiting condition, also adding docs
ARTEMIS-737 Improving Tests by checking thread leaks and Waiting condition, also adding docs
Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/03b3b9fa
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/03b3b9fa
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/03b3b9fa
Branch: refs/heads/master
Commit: 03b3b9fa80028dcb736c33f6f8e41f22584aa3b9
Parents: 32b7c03
Author: Clebert Suconic <cl...@apache.org>
Authored: Mon Sep 26 15:33:39 2016 -0400
Committer: Clebert Suconic <cl...@apache.org>
Committed: Mon Sep 26 17:58:05 2016 -0400
----------------------------------------------------------------------
.../artemis/junit/ActiveMQConsumerResource.java | 2 +-
.../artemis/junit/ThreadLeakCheckRule.java | 223 +++++++++++++++++++
.../org/apache/activemq/artemis/junit/Wait.java | 55 +++++
.../junit/ActiveMQConsumerResourceTest.java | 10 +-
.../ActiveMQDynamicProducerResourceTest.java | 8 +-
...ucerResourceWithoutAddressExceptionTest.java | 2 +-
...namicProducerResourceWithoutAddressTest.java | 8 +-
.../junit/ActiveMQProducerResourceTest.java | 2 +-
...ActiveMQResourceCustomConfigurationTest.java | 5 +-
...edActiveMQResourceFileConfigurationTest.java | 6 +-
.../junit/EmbeddedActiveMQResourceTest.java | 11 +-
...MSResourceMultipleFileConfigurationTest.java | 5 +-
.../junit/EmbeddedJMSResourceQueueTest.java | 11 +-
...dJMSResourceSingleFileConfigurationTest.java | 5 +-
.../junit/EmbeddedJMSResourceTopicTest.java | 11 +-
.../MultipleEmbeddedActiveMQResourcesTest.java | 6 +-
.../junit/MultipleEmbeddedJMSResourcesTest.java | 6 +-
docs/user-manual/en/SUMMARY.md | 1 +
docs/user-manual/en/unit-testing.md | 77 +++++++
19 files changed, 437 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/03b3b9fa/artemis-junit/src/main/java/org/apache/activemq/artemis/junit/ActiveMQConsumerResource.java
----------------------------------------------------------------------
diff --git a/artemis-junit/src/main/java/org/apache/activemq/artemis/junit/ActiveMQConsumerResource.java b/artemis-junit/src/main/java/org/apache/activemq/artemis/junit/ActiveMQConsumerResource.java
index d48ef1d..200ce92 100644
--- a/artemis-junit/src/main/java/org/apache/activemq/artemis/junit/ActiveMQConsumerResource.java
+++ b/artemis-junit/src/main/java/org/apache/activemq/artemis/junit/ActiveMQConsumerResource.java
@@ -31,7 +31,7 @@ import org.apache.activemq.artemis.api.core.client.ServerLocator;
* <pre><code>
* public class SimpleTest {
* {@code @Rule}
- * public ActiveMQConsumerResource producer = new ActiveMQProducerResource( "vm://0", "test.queue" );
+ * public ActiveMQConsumerResource client = new ActiveMQProducerResource( "vm://0", "test.queue" );
*
* {@code @Test}
* public void testSomething() throws Exception {
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/03b3b9fa/artemis-junit/src/main/java/org/apache/activemq/artemis/junit/ThreadLeakCheckRule.java
----------------------------------------------------------------------
diff --git a/artemis-junit/src/main/java/org/apache/activemq/artemis/junit/ThreadLeakCheckRule.java b/artemis-junit/src/main/java/org/apache/activemq/artemis/junit/ThreadLeakCheckRule.java
new file mode 100644
index 0000000..43da4f5
--- /dev/null
+++ b/artemis-junit/src/main/java/org/apache/activemq/artemis/junit/ThreadLeakCheckRule.java
@@ -0,0 +1,223 @@
+/**
+ * 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.activemq.artemis.junit;
+
+import java.lang.ref.WeakReference;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
+import org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnector;
+import org.jboss.logging.Logger;
+import org.junit.Assert;
+import org.junit.rules.ExternalResource;
+
+/**
+ * Messaging tests are usually Thread intensive and a thread leak or a server leakage may affect future tests.
+ * This Rule will prevent Threads leaking from one test into another by checking left over threads.
+ * This will also clear Client Thread Pools from ActiveMQClient.
+ */
+public class ThreadLeakCheckRule extends ExternalResource {
+ private static Logger log = Logger.getLogger(ThreadLeakCheckRule.class);
+
+ private static Set<String> knownThreads = new HashSet<>();
+
+ boolean enabled = true;
+
+ private Map<Thread, StackTraceElement[]> previousThreads;
+
+ public void disable() {
+ enabled = false;
+ }
+
+ /**
+ * Override to set up your specific external resource.
+ *
+ * @throws if setup fails (which will disable {@code after}
+ */
+ @Override
+ protected void before() throws Throwable {
+ // do nothing
+
+ previousThreads = Thread.getAllStackTraces();
+
+ }
+
+ /**
+ * Override to tear down your specific external resource.
+ */
+ @Override
+ protected void after() {
+ ActiveMQClient.clearThreadPools();
+ InVMConnector.resetThreadPool();
+
+ try {
+ if (enabled) {
+ boolean failed = true;
+
+ boolean failedOnce = false;
+
+ long timeout = System.currentTimeMillis() + 60000;
+ while (failed && timeout > System.currentTimeMillis()) {
+ failed = checkThread();
+
+ if (failed) {
+ failedOnce = true;
+ forceGC();
+ try {
+ Thread.sleep(500);
+ }
+ catch (Throwable e) {
+ }
+ }
+ }
+
+ if (failed) {
+ Assert.fail("Thread leaked");
+ }
+ else if (failedOnce) {
+ System.out.println("******************** Threads cleared after retries ********************");
+ System.out.println();
+ }
+
+ }
+ else {
+ enabled = true;
+ }
+ }
+ finally {
+ // clearing just to help GC
+ previousThreads = null;
+ }
+
+ }
+
+ private static int failedGCCalls = 0;
+
+ public static void forceGC() {
+
+ if (failedGCCalls >= 10) {
+ log.info("ignoring forceGC call since it seems System.gc is not working anyways");
+ return;
+ }
+ log.info("#test forceGC");
+ CountDownLatch finalized = new CountDownLatch(1);
+ WeakReference<DumbReference> dumbReference = new WeakReference<>(new DumbReference(finalized));
+
+ long timeout = System.currentTimeMillis() + 1000;
+
+ // A loop that will wait GC, using the minimal time as possible
+ while (!(dumbReference.get() == null && finalized.getCount() == 0) && System.currentTimeMillis() < timeout) {
+ System.gc();
+ System.runFinalization();
+ try {
+ finalized.await(100, TimeUnit.MILLISECONDS);
+ }
+ catch (InterruptedException e) {
+ }
+ }
+
+ if (dumbReference.get() != null) {
+ failedGCCalls++;
+ log.info("It seems that GC is disabled at your VM");
+ }
+ else {
+ // a success would reset the count
+ failedGCCalls = 0;
+ }
+ log.info("#test forceGC Done ");
+ }
+ public static void removeKownThread(String name) {
+ knownThreads.remove(name);
+ }
+
+ public static void addKownThread(String name) {
+ knownThreads.add(name);
+ }
+
+ private boolean checkThread() {
+ boolean failedThread = false;
+
+ Map<Thread, StackTraceElement[]> postThreads = Thread.getAllStackTraces();
+
+ if (postThreads != null && previousThreads != null && postThreads.size() > previousThreads.size()) {
+
+
+ for (Thread aliveThread : postThreads.keySet()) {
+ if (aliveThread.isAlive() && !isExpectedThread(aliveThread) && !previousThreads.containsKey(aliveThread)) {
+ if (!failedThread) {
+ System.out.println("*********************************************************************************");
+ System.out.println("LEAKING THREADS");
+ }
+ failedThread = true;
+ System.out.println("=============================================================================");
+ System.out.println("Thread " + aliveThread + " is still alive with the following stackTrace:");
+ StackTraceElement[] elements = postThreads.get(aliveThread);
+ for (StackTraceElement el : elements) {
+ System.out.println(el);
+ }
+ }
+
+ }
+ if (failedThread) {
+ System.out.println("*********************************************************************************");
+ }
+ }
+
+
+ return failedThread;
+ }
+
+
+ /**
+ * if it's an expected thread... we will just move along ignoring it
+ *
+ * @param thread
+ * @return
+ */
+ private boolean isExpectedThread(Thread thread) {
+
+ for (String known: knownThreads) {
+ if (thread.getName().contains(known)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+ protected static class DumbReference {
+
+ private CountDownLatch finalized;
+
+ public DumbReference(CountDownLatch finalized) {
+ this.finalized = finalized;
+ }
+
+ @Override
+ public void finalize() throws Throwable {
+ finalized.countDown();
+ super.finalize();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/03b3b9fa/artemis-junit/src/main/java/org/apache/activemq/artemis/junit/Wait.java
----------------------------------------------------------------------
diff --git a/artemis-junit/src/main/java/org/apache/activemq/artemis/junit/Wait.java b/artemis-junit/src/main/java/org/apache/activemq/artemis/junit/Wait.java
new file mode 100644
index 0000000..fe8fba0
--- /dev/null
+++ b/artemis-junit/src/main/java/org/apache/activemq/artemis/junit/Wait.java
@@ -0,0 +1,55 @@
+/*
+ * 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.activemq.artemis.junit;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Utility adapted from: org.apache.activemq.util.Wait
+ */
+public class Wait {
+
+ public static final long MAX_WAIT_MILLIS = 30 * 1000;
+ public static final int SLEEP_MILLIS = 1000;
+
+ public interface Condition {
+
+ boolean isSatisfied() throws Exception;
+ }
+
+ public static boolean waitFor(Condition condition) throws Exception {
+ return waitFor(condition, MAX_WAIT_MILLIS);
+ }
+
+ public static boolean waitFor(final Condition condition, final long duration) throws Exception {
+ return waitFor(condition, duration, SLEEP_MILLIS);
+ }
+
+ public static boolean waitFor(final Condition condition,
+ final long duration,
+ final long sleepMillis) throws Exception {
+
+ final long expiry = System.currentTimeMillis() + duration;
+ boolean conditionSatisified = condition.isSatisfied();
+ while (!conditionSatisified && System.currentTimeMillis() < expiry) {
+ TimeUnit.MILLISECONDS.sleep(sleepMillis);
+ conditionSatisified = condition.isSatisfied();
+ }
+ return conditionSatisified;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/03b3b9fa/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQConsumerResourceTest.java
----------------------------------------------------------------------
diff --git a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQConsumerResourceTest.java b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQConsumerResourceTest.java
index b8a637a..08a2d80 100644
--- a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQConsumerResourceTest.java
+++ b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQConsumerResourceTest.java
@@ -50,14 +50,22 @@ public class ActiveMQConsumerResourceTest {
ActiveMQConsumerResource consumer = new ActiveMQConsumerResource(server.getVmURL(), TEST_QUEUE);
+
@Rule
- public RuleChain ruleChain = RuleChain.outerRule(server).around(consumer);
+ public RuleChain ruleChain = RuleChain.outerRule(new ThreadLeakCheckRule()).outerRule(server).around(consumer);
+
ClientMessage sent = null;
@After
public void tearDown() throws Exception {
assertNotNull(String.format(ASSERT_SENT_FORMAT, TEST_ADDRESS), sent);
+ Wait.waitFor(new Wait.Condition() {
+ @Override
+ public boolean isSatisfied() throws Exception {
+ return server.getMessageCount("TEST_QUEUE") == 1;
+ }
+ }, 5000, 100);
assertEquals(String.format(ASSERT_COUNT_FORMAT, TEST_QUEUE), 1, server.getMessageCount(TEST_QUEUE));
ClientMessage received = consumer.receiveMessage();
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/03b3b9fa/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQDynamicProducerResourceTest.java
----------------------------------------------------------------------
diff --git a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQDynamicProducerResourceTest.java b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQDynamicProducerResourceTest.java
index 7d09848..da3990c 100644
--- a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQDynamicProducerResourceTest.java
+++ b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQDynamicProducerResourceTest.java
@@ -51,7 +51,7 @@ public class ActiveMQDynamicProducerResourceTest {
ActiveMQDynamicProducerResource producer = new ActiveMQDynamicProducerResource(server.getVmURL(), TEST_QUEUE_ONE);
@Rule
- public RuleChain ruleChain = RuleChain.outerRule(server).around(producer);
+ public RuleChain ruleChain = RuleChain.outerRule(new ThreadLeakCheckRule()).around(server).around(producer);
ClientMessage sentOne = null;
ClientMessage sentTwo = null;
@@ -60,6 +60,12 @@ public class ActiveMQDynamicProducerResourceTest {
public void tearDown() throws Exception {
assertNotNull(String.format(ASSERT_SENT_FORMAT, TEST_QUEUE_ONE), sentOne);
assertNotNull(String.format(ASSERT_SENT_FORMAT, TEST_QUEUE_TWO), sentTwo);
+ Wait.waitFor(new Wait.Condition() {
+ @Override
+ public boolean isSatisfied() throws Exception {
+ return server.getMessageCount(TEST_QUEUE_ONE) == 1 && server.getMessageCount(TEST_QUEUE_TWO) == 1;
+ }
+ }, 5000, 100);
assertEquals(String.format(ASSERT_COUNT_FORMAT, TEST_QUEUE_ONE), 1, server.getMessageCount(TEST_QUEUE_ONE));
assertEquals(String.format(ASSERT_COUNT_FORMAT, TEST_QUEUE_TWO), 1, server.getMessageCount(TEST_QUEUE_TWO));
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/03b3b9fa/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQDynamicProducerResourceWithoutAddressExceptionTest.java
----------------------------------------------------------------------
diff --git a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQDynamicProducerResourceWithoutAddressExceptionTest.java b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQDynamicProducerResourceWithoutAddressExceptionTest.java
index 5367009..7f6cbb4 100644
--- a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQDynamicProducerResourceWithoutAddressExceptionTest.java
+++ b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQDynamicProducerResourceWithoutAddressExceptionTest.java
@@ -43,7 +43,7 @@ public class ActiveMQDynamicProducerResourceWithoutAddressExceptionTest {
ActiveMQDynamicProducerResource producer = new ActiveMQDynamicProducerResource(server.getVmURL());
@Rule
- public RuleChain ruleChain = RuleChain.outerRule(server).around(producer);
+ public RuleChain ruleChain = RuleChain.outerRule(new ThreadLeakCheckRule()).around(server).around(producer);
ClientMessage sentOne = null;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/03b3b9fa/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQDynamicProducerResourceWithoutAddressTest.java
----------------------------------------------------------------------
diff --git a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQDynamicProducerResourceWithoutAddressTest.java b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQDynamicProducerResourceWithoutAddressTest.java
index 6e61a3a..e57e175 100644
--- a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQDynamicProducerResourceWithoutAddressTest.java
+++ b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQDynamicProducerResourceWithoutAddressTest.java
@@ -52,7 +52,7 @@ public class ActiveMQDynamicProducerResourceWithoutAddressTest {
ActiveMQDynamicProducerResource producer = new ActiveMQDynamicProducerResource(server.getVmURL());
@Rule
- public RuleChain ruleChain = RuleChain.outerRule(server).around(producer);
+ public RuleChain ruleChain = RuleChain.outerRule(new ThreadLeakCheckRule()).around(server).around(producer);
ClientMessage sentOne = null;
ClientMessage sentTwo = null;
@@ -68,6 +68,12 @@ public class ActiveMQDynamicProducerResourceWithoutAddressTest {
public void tearDown() throws Exception {
assertNotNull(String.format(ASSERT_SENT_FORMAT, TEST_QUEUE_ONE), sentOne);
assertNotNull(String.format(ASSERT_SENT_FORMAT, TEST_QUEUE_TWO), sentTwo);
+ Wait.waitFor(new Wait.Condition() {
+ @Override
+ public boolean isSatisfied() throws Exception {
+ return server.getMessageCount(TEST_QUEUE_ONE) == 1 && server.getMessageCount(TEST_QUEUE_TWO) == 1;
+ }
+ }, 5000, 100);
assertEquals(String.format(ASSERT_COUNT_FORMAT, TEST_QUEUE_ONE), 1, server.getMessageCount(TEST_QUEUE_ONE));
assertEquals(String.format(ASSERT_COUNT_FORMAT, TEST_QUEUE_TWO), 1, server.getMessageCount(TEST_QUEUE_TWO));
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/03b3b9fa/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQProducerResourceTest.java
----------------------------------------------------------------------
diff --git a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQProducerResourceTest.java b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQProducerResourceTest.java
index b0fd086..df9977d 100644
--- a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQProducerResourceTest.java
+++ b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/ActiveMQProducerResourceTest.java
@@ -50,7 +50,7 @@ public class ActiveMQProducerResourceTest {
ActiveMQProducerResource producer = new ActiveMQProducerResource(server.getVmURL(), TEST_ADDRESS);
@Rule
- public RuleChain ruleChain = RuleChain.outerRule(server).around(producer);
+ public RuleChain ruleChain = RuleChain.outerRule(new ThreadLeakCheckRule()).around(server).around(producer);
ClientMessage sent = null;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/03b3b9fa/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedActiveMQResourceCustomConfigurationTest.java
----------------------------------------------------------------------
diff --git a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedActiveMQResourceCustomConfigurationTest.java b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedActiveMQResourceCustomConfigurationTest.java
index 13a6f52..fae54cc 100644
--- a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedActiveMQResourceCustomConfigurationTest.java
+++ b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedActiveMQResourceCustomConfigurationTest.java
@@ -24,6 +24,7 @@ import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
import org.apache.activemq.artemis.core.server.Queue;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.RuleChain;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -37,8 +38,10 @@ public class EmbeddedActiveMQResourceCustomConfigurationTest {
CoreQueueConfiguration queueConfiguration = new CoreQueueConfiguration().setAddress(TEST_ADDRESS).setName(TEST_QUEUE);
Configuration customConfiguration = new ConfigurationImpl().setPersistenceEnabled(false).setSecurityEnabled(true).addQueueConfiguration(queueConfiguration);
+ private EmbeddedActiveMQResource server = new EmbeddedActiveMQResource(customConfiguration);
+
@Rule
- public EmbeddedActiveMQResource server = new EmbeddedActiveMQResource(customConfiguration);
+ public RuleChain rulechain = RuleChain.outerRule(new ThreadLeakCheckRule()).around(server);
@Test
public void testCustomConfiguration() throws Exception {
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/03b3b9fa/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedActiveMQResourceFileConfigurationTest.java
----------------------------------------------------------------------
diff --git a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedActiveMQResourceFileConfigurationTest.java b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedActiveMQResourceFileConfigurationTest.java
index 80ed251..ef10173 100644
--- a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedActiveMQResourceFileConfigurationTest.java
+++ b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedActiveMQResourceFileConfigurationTest.java
@@ -21,6 +21,7 @@ import java.util.List;
import org.apache.activemq.artemis.core.server.Queue;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.RuleChain;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -31,8 +32,11 @@ public class EmbeddedActiveMQResourceFileConfigurationTest {
static final String TEST_QUEUE = "test.queue";
static final String TEST_ADDRESS = "test.address";
+ private EmbeddedActiveMQResource server = new EmbeddedActiveMQResource("embedded-artemis-server.xml");
+
@Rule
- public EmbeddedActiveMQResource server = new EmbeddedActiveMQResource("embedded-artemis-server.xml");
+ public RuleChain rulechain = RuleChain.outerRule(new ThreadLeakCheckRule()).around(server);
+
@Test
public void testConfiguredQueue() throws Exception {
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/03b3b9fa/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedActiveMQResourceTest.java
----------------------------------------------------------------------
diff --git a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedActiveMQResourceTest.java b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedActiveMQResourceTest.java
index 876695d..36f8ad9 100644
--- a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedActiveMQResourceTest.java
+++ b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedActiveMQResourceTest.java
@@ -25,6 +25,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.RuleChain;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -46,9 +47,11 @@ public class EmbeddedActiveMQResourceTest {
TEST_PROPERTIES.put("PropertyTwo", "Property Value 2");
}
- @Rule
public EmbeddedActiveMQResource server = new EmbeddedActiveMQResource();
+ @Rule
+ public RuleChain rulechain = RuleChain.outerRule(new ThreadLeakCheckRule()).around(server);
+
ClientMessage sent = null;
@Before
@@ -59,6 +62,12 @@ public class EmbeddedActiveMQResourceTest {
@After
public void tearDown() throws Exception {
assertNotNull(String.format(ASSERT_SENT_FORMAT, TEST_ADDRESS), sent);
+ Wait.waitFor(new Wait.Condition() {
+ @Override
+ public boolean isSatisfied() throws Exception {
+ return server.getMessageCount(TEST_QUEUE) == 1;
+ }
+ }, 5000, 100);
assertEquals(String.format(ASSERT_COUNT_FORMAT, TEST_QUEUE), 1, server.getMessageCount(TEST_QUEUE));
ClientMessage received = server.receiveMessage(TEST_QUEUE);
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/03b3b9fa/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedJMSResourceMultipleFileConfigurationTest.java
----------------------------------------------------------------------
diff --git a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedJMSResourceMultipleFileConfigurationTest.java b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedJMSResourceMultipleFileConfigurationTest.java
index aa96ab7..ceb06e8 100644
--- a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedJMSResourceMultipleFileConfigurationTest.java
+++ b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedJMSResourceMultipleFileConfigurationTest.java
@@ -29,6 +29,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.RuleChain;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -42,9 +43,11 @@ public class EmbeddedJMSResourceMultipleFileConfigurationTest {
static final String ASSERT_PUSHED_FORMAT = "Message should have been pushed a message to %s";
static final String ASSERT_COUNT_FORMAT = "Unexpected message count in destination %s";
- @Rule
public EmbeddedJMSResource jmsServer = new EmbeddedJMSResource("embedded-artemis-minimal-server.xml", "embedded-artemis-jms-only.xml");
+ @Rule
+ public RuleChain rulechain = RuleChain.outerRule(new ThreadLeakCheckRule()).around(jmsServer);
+
ConnectionFactory connectionFactory;
Connection connection;
Session session;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/03b3b9fa/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedJMSResourceQueueTest.java
----------------------------------------------------------------------
diff --git a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedJMSResourceQueueTest.java b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedJMSResourceQueueTest.java
index 19b04aa..bb2bf6b 100644
--- a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedJMSResourceQueueTest.java
+++ b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedJMSResourceQueueTest.java
@@ -24,6 +24,7 @@ import java.util.Map;
import org.junit.After;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.RuleChain;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -48,14 +49,22 @@ public class EmbeddedJMSResourceQueueTest {
TEST_PROPERTIES.put("PropertyTwo", "Property Value 2");
}
- @Rule
public EmbeddedJMSResource jmsServer = new EmbeddedJMSResource();
+ @Rule
+ public RuleChain rulechain = RuleChain.outerRule(new ThreadLeakCheckRule()).around(jmsServer);
+
Message pushed = null;
@After
public void tearDown() throws Exception {
assertNotNull(String.format(ASSERT_PUSHED_FORMAT, TEST_DESTINATION_NAME), pushed);
+ Wait.waitFor(new Wait.Condition() {
+ @Override
+ public boolean isSatisfied() throws Exception {
+ return jmsServer.getMessageCount(TEST_DESTINATION_NAME) == 1;
+ }
+ }, 5000, 100);
assertEquals(String.format(ASSERT_COUNT_FORMAT, TEST_DESTINATION_NAME), 1, jmsServer.getMessageCount(TEST_DESTINATION_NAME));
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/03b3b9fa/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedJMSResourceSingleFileConfigurationTest.java
----------------------------------------------------------------------
diff --git a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedJMSResourceSingleFileConfigurationTest.java b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedJMSResourceSingleFileConfigurationTest.java
index cdcbcaa..5ca3560 100644
--- a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedJMSResourceSingleFileConfigurationTest.java
+++ b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedJMSResourceSingleFileConfigurationTest.java
@@ -29,6 +29,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.RuleChain;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -42,9 +43,11 @@ public class EmbeddedJMSResourceSingleFileConfigurationTest {
static final String ASSERT_PUSHED_FORMAT = "Message should have been pushed a message to %s";
static final String ASSERT_COUNT_FORMAT = "Unexpected message count in destination %s";
- @Rule
public EmbeddedJMSResource jmsServer = new EmbeddedJMSResource("embedded-artemis-jms-server.xml");
+ @Rule
+ public RuleChain rulechain = RuleChain.outerRule(new ThreadLeakCheckRule()).around(jmsServer);
+
ConnectionFactory connectionFactory;
Connection connection;
Session session;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/03b3b9fa/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedJMSResourceTopicTest.java
----------------------------------------------------------------------
diff --git a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedJMSResourceTopicTest.java b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedJMSResourceTopicTest.java
index d4dd738..0bccba1 100644
--- a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedJMSResourceTopicTest.java
+++ b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/EmbeddedJMSResourceTopicTest.java
@@ -31,6 +31,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.RuleChain;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -55,9 +56,11 @@ public class EmbeddedJMSResourceTopicTest {
TEST_PROPERTIES.put("PropertyTwo", "Property Value 2");
}
- @Rule
public EmbeddedJMSResource jmsServer = new EmbeddedJMSResource();
+ @Rule
+ public RuleChain rulechain = RuleChain.outerRule(new ThreadLeakCheckRule()).around(jmsServer);
+
Message pushed = null;
ConnectionFactory connectionFactory;
@@ -77,6 +80,12 @@ public class EmbeddedJMSResourceTopicTest {
@After
public void tearDown() throws Exception {
assertNotNull(String.format(ASSERT_PUSHED_FORMAT, TEST_DESTINATION_NAME), pushed);
+ Wait.waitFor(new Wait.Condition() {
+ @Override
+ public boolean isSatisfied() throws Exception {
+ return jmsServer.getMessageCount(TEST_DESTINATION_NAME) == 1;
+ }
+ }, 5000, 100);
assertEquals(String.format(ASSERT_COUNT_FORMAT, TEST_DESTINATION_NAME), 1, jmsServer.getMessageCount(TEST_DESTINATION_NAME));
consumer.close();
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/03b3b9fa/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/MultipleEmbeddedActiveMQResourcesTest.java
----------------------------------------------------------------------
diff --git a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/MultipleEmbeddedActiveMQResourcesTest.java b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/MultipleEmbeddedActiveMQResourcesTest.java
index 97f1f5b..2fa1057 100644
--- a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/MultipleEmbeddedActiveMQResourcesTest.java
+++ b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/MultipleEmbeddedActiveMQResourcesTest.java
@@ -21,6 +21,7 @@ import org.apache.activemq.artemis.api.core.client.ClientMessage;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.RuleChain;
import static org.junit.Assert.assertNotNull;
@@ -37,12 +38,13 @@ public class MultipleEmbeddedActiveMQResourcesTest {
static final String ASSERT_RECEIVED_FORMAT = "Message should have been received from %s";
static final String ASSERT_COUNT_FORMAT = "Unexpected message count in queue %s";
- @Rule
public EmbeddedActiveMQResource serverOne = new EmbeddedActiveMQResource(0);
- @Rule
public EmbeddedActiveMQResource serverTwo = new EmbeddedActiveMQResource(1);
+ @Rule
+ public RuleChain rulechain = RuleChain.outerRule(new ThreadLeakCheckRule()).around(serverOne).around(serverTwo);
+
@Before
public void setUp() throws Exception {
serverOne.createQueue(TEST_ADDRESS_ONE, TEST_QUEUE_ONE);
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/03b3b9fa/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/MultipleEmbeddedJMSResourcesTest.java
----------------------------------------------------------------------
diff --git a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/MultipleEmbeddedJMSResourcesTest.java b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/MultipleEmbeddedJMSResourcesTest.java
index 1a5381c..e2b8416 100644
--- a/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/MultipleEmbeddedJMSResourcesTest.java
+++ b/artemis-junit/src/test/java/org/apache/activemq/artemis/junit/MultipleEmbeddedJMSResourcesTest.java
@@ -20,6 +20,7 @@ import javax.jms.Message;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.RuleChain;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -33,12 +34,13 @@ public class MultipleEmbeddedJMSResourcesTest {
static final String ASSERT_PUSHED_FORMAT = "Message should have been pushed a message to %s";
static final String ASSERT_COUNT_FORMAT = "Unexpected message count in destination %s";
- @Rule
public EmbeddedJMSResource jmsServerOne = new EmbeddedJMSResource(0);
- @Rule
public EmbeddedJMSResource jmsServerTwo = new EmbeddedJMSResource(1);
+ @Rule
+ public RuleChain rulechain = RuleChain.outerRule(new ThreadLeakCheckRule()).around(jmsServerOne).around(jmsServerTwo);
+
@Test
public void testMultipleServers() throws Exception {
Message pushedOne = jmsServerOne.pushMessage(TEST_QUEUE_ONE, TEST_BODY);
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/03b3b9fa/docs/user-manual/en/SUMMARY.md
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/SUMMARY.md b/docs/user-manual/en/SUMMARY.md
index 57d83ab..166fee1 100644
--- a/docs/user-manual/en/SUMMARY.md
+++ b/docs/user-manual/en/SUMMARY.md
@@ -56,6 +56,7 @@
* [Protocols and Interoperability](protocols-interoperability.md)
* [Tools](tools.md)
* [Maven Plugin](maven-plugin.md)
+* [Unit Testing](unit-testing.md)
* [Troubleshooting and Performance Tuning](perf-tuning.md)
* [Configuration Reference](configuration-index.md)
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/03b3b9fa/docs/user-manual/en/unit-testing.md
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/unit-testing.md b/docs/user-manual/en/unit-testing.md
new file mode 100644
index 0000000..7beb311
--- /dev/null
+++ b/docs/user-manual/en/unit-testing.md
@@ -0,0 +1,77 @@
+# Unit Testing
+
+The package ```artemis-junit``` provides tools to facilitate how to run Artemis resources inside Junit Tests.
+
+These are provided as junit rules and can make it easier to embed Messaging functionality on your tests.
+
+
+## Example
+
+
+### Import this on your pom.xml
+
+```xml
+<dependency>
+ <groupId>org.apache.activemq</groupId>
+ <artifactId>artemis-junit</artifactId>
+ <!-- replace this for the version you are using -->
+ <version>1.5.0</version>
+ <scope>test</scope>
+</dependency>
+```
+
+
+### Declare a rule on your JUnit Test
+
+
+```java
+import org.apache.activemq.artemis.junit.EmbeddedJMSResource;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class MyTest {
+
+ @Rule
+ public EmbeddedJMSResource resource = new EmbeddedJMSResource();
+
+ @Test
+ public void myTest() {
+
+ }
+}
+```
+
+This will start a server that will be available for your test:
+
+```
+ain] 17:00:16,644 INFO [org.apache.activemq.artemis.core.server] AMQ221000: live Message Broker is starting with configuration Broker Configuration (clustered=false,journalDirectory=data/journal,bindingsDirectory=data/bindings,largeMessagesDirectory=data/largemessages,pagingDirectory=data/paging)
+[main] 17:00:16,666 INFO [org.apache.activemq.artemis.core.server] AMQ221045: libaio is not available, switching the configuration into NIO
+[main] 17:00:16,688 INFO [org.apache.activemq.artemis.core.server] AMQ221043: Protocol module found: [artemis-server]. Adding protocol support for: CORE
+[main] 17:00:16,801 INFO [org.apache.activemq.artemis.core.server] AMQ221007: Server is now live
+[main] 17:00:16,801 INFO [org.apache.activemq.artemis.core.server] AMQ221001: Apache ActiveMQ Artemis Message Broker version 1.5.0-SNAPSHOT [embedded-jms-server, nodeID=39e78380-842c-11e6-9e43-f45c8992f3c7]
+[main] 17:00:16,891 INFO [org.apache.activemq.artemis.core.server] AMQ221002: Apache ActiveMQ Artemis Message Broker version 1.5.0-SNAPSHOT [39e78380-842c-11e6-9e43-f45c8992f3c7] stopped, uptime 0.272 seconds
+
+```
+
+
+### Ordering rules
+
+This is actually a Junit feature, but this could be helpful on pre-determining the order on which rules are executed.
+
+```java
+ ActiveMQDynamicProducerResource producer = new ActiveMQDynamicProducerResource(server.getVmURL());
+
+ @Rule
+ public RuleChain ruleChain = RuleChain.outerRule(new ThreadLeakCheckRule()).around(server).around(producer);
+
+```
+
+### Available Rules
+
+Name | Description
+:--- | :---
+EmbeddedActiveMQResource | It will run a Server, without the JMS manager
+EmbeddedJMSResource | It will run a Server, including the JMS Manager
+ActiveMQConsumerResource | It will automate the creation of a consumer
+ActiveMQProducerResource | It will automate the creation of a producer
+ThreadLeakCheckRule | It will check that all threads have been finished after the test is finished