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 2021/06/29 21:46:34 UTC

[activemq-artemis] branch main updated: ARTEMIS-3371 Adding TestContainers support and adding QpidDispatchPeerTest

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

clebertsuconic pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git


The following commit(s) were added to refs/heads/main by this push:
     new 200e436  ARTEMIS-3371 Adding TestContainers support and adding QpidDispatchPeerTest
200e436 is described below

commit 200e436931bb5a15d23b71f6041ef8ad2ae2b8a0
Author: Clebert Suconic <cl...@apache.org>
AuthorDate: Tue Jun 29 13:58:48 2021 -0400

    ARTEMIS-3371 Adding TestContainers support and adding QpidDispatchPeerTest
    
    This is testing peer integration with qpid-dispatch by using TestContainer and a docker image for Artemis
    Also, as I added QpidDispatchTest, I reorganized the brokerConnect tests a bit into a brokerConnect folder.
---
 .../artemis/maven/ArtemisCreatePlugin.java         |   1 +
 tests/smoke-tests/pom.xml                          |  40 ++-
 .../src/main/resources/containerService/README     |  24 ++
 .../src/main/resources/containerService/artemis    | 136 ++++++++++
 .../resources/containerService/artemis.profile     |  38 +++
 .../main/resources/containerService/bootstrap.xml  |  37 +++
 .../bridgeSecurityA}/artemis-roles.properties      |   0
 .../bridgeSecurityA}/artemis-users.properties      |   0
 .../bridgeSecurityA}/broker.xml                    |   0
 .../bridgeSecurityB}/artemis-roles.properties      |   0
 .../bridgeSecurityB}/artemis-users.properties      |   0
 .../bridgeSecurityB}/broker.xml                    |   0
 .../mirrorSecurityA}/broker.xml                    |   0
 .../mirrorSecurityB}/broker.xml                    |   6 +-
 .../qdr}/broker.xml                                | 100 ++++----
 .../servers/brokerConnect/qdr/qdrouterd.conf       |  40 +++
 .../BrokerConnectionBridgeSecurityTest.java        |   4 +-
 .../BrokerConnectionMirrorSecurityTest.java        |   4 +-
 .../brokerConnection/QpidDispatchPeerTest.java     | 195 ++++++++++++++
 .../tests/smoke/common/ContainerService.java       | 283 +++++++++++++++++++++
 .../artemis/tests/smoke/common/SmokeTestBase.java  |  27 ++
 21 files changed, 875 insertions(+), 60 deletions(-)

diff --git a/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ArtemisCreatePlugin.java b/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ArtemisCreatePlugin.java
index 13707e7..3b6a8aa 100644
--- a/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ArtemisCreatePlugin.java
+++ b/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ArtemisCreatePlugin.java
@@ -246,6 +246,7 @@ public class ArtemisCreatePlugin extends ArtemisAbstractPlugin {
 
       getLog().debug("***** Server created at " + instance + " with home=" + home + " *****");
 
+      instance.mkdirs();
       File commandLine = new File(instance.getParentFile(), "create-" + instance.getName() + ".sh");
       FileOutputStream outputStream;
       try {
diff --git a/tests/smoke-tests/pom.xml b/tests/smoke-tests/pom.xml
index ed9c53b..7fb05df 100644
--- a/tests/smoke-tests/pom.xml
+++ b/tests/smoke-tests/pom.xml
@@ -149,8 +149,14 @@
       </dependency>
       <dependency>
          <groupId>org.testcontainers</groupId>
+         <artifactId>testcontainers</artifactId>
+         <version>1.15.3</version>
+         <scope>test</scope>
+      </dependency>
+      <dependency>
+         <groupId>org.testcontainers</groupId>
          <artifactId>selenium</artifactId>
-         <version>1.15.1</version>
+         <version>1.15.3</version>
          <scope>test</scope>
       </dependency>
       <!-- this dependency is needed for CFUtil and other tools from integration-tests -->
@@ -717,8 +723,8 @@
                      <user>A</user>
                      <password>A</password>
                      <noWeb>true</noWeb>
-                     <instance>${basedir}/target/brokerConnectBridgeSecurityA</instance>
-                     <configuration>${basedir}/target/classes/servers/brokerConnectBridgeSecurityA</configuration>
+                     <instance>${basedir}/target/brokerConnect/bridgeSecurityA</instance>
+                     <configuration>${basedir}/target/classes/servers/brokerConnect/bridgeSecurityA</configuration>
                   </configuration>
                </execution>
                <execution>
@@ -733,8 +739,8 @@
                      <password>B</password>
                      <noWeb>true</noWeb>
                      <portOffset>100</portOffset>
-                     <instance>${basedir}/target/brokerConnectBridgeSecurityB</instance>
-                     <configuration>${basedir}/target/classes/servers/brokerConnectBridgeSecurityB</configuration>
+                     <instance>${basedir}/target/brokerConnect/bridgeSecurityB</instance>
+                     <configuration>${basedir}/target/classes/servers/brokerConnect/bridgeSecurityB</configuration>
                   </configuration>
                </execution>
                <!-- used on BrokerConnectionBridgeSecurityTest  -->
@@ -749,8 +755,8 @@
                      <user>A</user>
                      <password>A</password>
                      <noWeb>true</noWeb>
-                     <instance>${basedir}/target/brokerConnectMirrorSecurityA</instance>
-                     <configuration>${basedir}/target/classes/servers/brokerConnectMirrorSecurityA</configuration>
+                     <instance>${basedir}/target/brokerConnect/mirrorSecurityA</instance>
+                     <configuration>${basedir}/target/classes/servers/brokerConnect/mirrorSecurityA</configuration>
                   </configuration>
                </execution>
                <execution>
@@ -765,8 +771,8 @@
                      <password>B</password>
                      <noWeb>true</noWeb>
                      <portOffset>1</portOffset>
-                     <instance>${basedir}/target/brokerConnectMirrorSecurityB</instance>
-                     <configuration>${basedir}/target/classes/servers/brokerConnectMirrorSecurityB</configuration>
+                     <instance>${basedir}/target/brokerConnect/mirrorSecurityB</instance>
+                     <configuration>${basedir}/target/classes/servers/brokerConnect/mirrorSecurityB</configuration>
                   </configuration>
                </execution>
 
@@ -826,6 +832,22 @@
                      </args>
                   </configuration>
                </execution>
+               <execution>
+                  <phase>test-compile</phase>
+                  <id>create-qdr</id>
+                  <goals>
+                     <goal>create</goal>
+                  </goals>
+                  <configuration>
+                     <role>amq</role>
+                     <user>artemis</user>
+                     <password>artemis</password>
+                     <allowAnonymous>false</allowAnonymous>
+                     <noWeb>false</noWeb>
+                     <instance>${basedir}/target/brokerConnect/qdr</instance>
+                     <configuration>${basedir}/target/classes/servers/brokerConnect/qdr</configuration>
+                  </configuration>
+               </execution>
             </executions>
             <dependencies>
                <dependency>
diff --git a/tests/smoke-tests/src/main/resources/containerService/README b/tests/smoke-tests/src/main/resources/containerService/README
new file mode 100644
index 0000000..31c0371
--- /dev/null
+++ b/tests/smoke-tests/src/main/resources/containerService/README
@@ -0,0 +1,24 @@
+# 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.
+
+
+*******************************************************************************************************************************
+This directory contains files supporting reusing a broker image inside a DockerImage.
+
+The method ContainerService::prepareInstance will copy files from this directory into a broker's home instance
+to allow it being used inside a docker image generated by ./artemis-docker.
+*******************************************************************************************************************************
diff --git a/tests/smoke-tests/src/main/resources/containerService/artemis b/tests/smoke-tests/src/main/resources/containerService/artemis
new file mode 100755
index 0000000..dfa6866
--- /dev/null
+++ b/tests/smoke-tests/src/main/resources/containerService/artemis
@@ -0,0 +1,136 @@
+#!/usr/bin/env sh
+# 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.
+
+if [ -z "$ARTEMIS_INSTANCE" ] ; then
+
+  ## resolve links - $0 may be a link to ActiveMQ's home
+  PRG="$0"
+  progname=`basename "$0"`
+  saveddir=`pwd`
+
+  # need this for relative symlinks
+  dirname_prg=`dirname "$PRG"`
+  cd "$dirname_prg"
+
+  while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '.*/.*' > /dev/null; then
+    PRG="$link"
+    else
+    PRG=`dirname "$PRG"`"/$link"
+    fi
+  done
+
+  ARTEMIS_INSTANCE=`dirname "$PRG"`
+  cd "$saveddir"
+
+  # make it fully qualified
+  ARTEMIS_INSTANCE=`cd "$ARTEMIS_INSTANCE/.." && pwd`
+fi
+
+# Load Profile Data
+ARTEMIS_INSTANCE_ETC='/var/lib/artemis-instance/etc'
+. "$ARTEMIS_INSTANCE_ETC/artemis.profile"
+
+# Set Defaults Properties
+ARTEMIS_LOGGING_CONF="$ARTEMIS_INSTANCE_ETC_URI/logging.properties"
+ARTEMIS_LOG_MANAGER=org.jboss.logmanager.LogManager
+
+
+CLASSPATH="$ARTEMIS_HOME/lib/artemis-boot.jar"
+
+# OS specific support.
+cygwin=false;
+darwin=false;
+case "`uname`" in
+  CYGWIN*) cygwin=true
+    OSTYPE=cygwin
+    export OSTYPE
+    ;;
+  Darwin*) darwin=true
+    if [ -z "$JAVA_HOME" ] ; then
+     JAVA_HOME=$(/usr/libexec/java_home)
+    fi
+    ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+  [ -n "$ARTEMIS_INSTANCE" ] &&
+    ARTEMIS_INSTANCE=`cygpath --unix "$ARTEMIS_INSTANCE"`
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+if [ -z "$JAVACMD" ] ; then
+  if [ -n "$JAVA_HOME"  ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+      # IBM's JDK on AIX uses strange locations for the executables
+      JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+      JAVACMD="$JAVA_HOME/bin/java"
+    fi
+  else
+    JAVACMD=java
+  fi
+fi
+
+if $cygwin ; then
+  JAVA_HOME=`cygpath --windows "$JAVA_HOME"`
+  ARTEMIS_HOME=`cygpath --windows "$ARTEMIS_HOME"`
+  CLASSPATH=`cygpath --windows "$CLASSPATH"`
+fi
+
+
+# finding the Log Manager
+LOG_MANAGER=`ls $ARTEMIS_HOME/lib/jboss-logmanager*jar 2>/dev/null`
+
+if [ -z "$LOG_MANAGER" ] ; then
+  # this is the one found when the server was created
+  LOG_MANAGER="$ARTEMIS_HOME/lib/jboss-logmanager-2.1.10.Final.jar"
+fi
+
+WILDFLY_COMMON=`ls $ARTEMIS_HOME/lib/wildfly-common*jar 2>/dev/null`
+if [ -z "$WILDFLY_COMMON" ] ; then
+  # this is the one found when the server was created
+  WILDFLY_COMMON="$ARTEMIS_HOME/lib/wildfly-common-1.5.2.Final.jar"
+fi
+
+if [ -f "$ARTEMIS_OOME_DUMP" ] ; then
+  # backup the last OOME heap dump
+  mv $ARTEMIS_OOME_DUMP $ARTEMIS_OOME_DUMP.bkp
+fi
+
+exec "$JAVACMD" \
+    $JAVA_ARGS \
+    -Dhawtio.role="$HAWTIO_ROLE" \
+    -Xbootclasspath/a:"$LOG_MANAGER:$WILDFLY_COMMON" \
+    -Djava.security.auth.login.config="$ARTEMIS_INSTANCE_ETC/login.config" \
+    $ARTEMIS_CLUSTER_PROPS \
+    -classpath "$CLASSPATH" \
+    -Dartemis.home="$ARTEMIS_HOME" \
+    -Dartemis.instance="$ARTEMIS_INSTANCE" \
+    -Djava.library.path="$ARTEMIS_HOME/bin/lib/linux-$(uname -m)" \
+    -Djava.io.tmpdir="$ARTEMIS_INSTANCE/tmp" \
+    -Ddata.dir="$ARTEMIS_DATA_DIR" \
+    -Dartemis.instance.etc="$ARTEMIS_INSTANCE_ETC" \
+    -Djava.util.logging.manager="$ARTEMIS_LOG_MANAGER" \
+    -Dlogging.configuration="$ARTEMIS_LOGGING_CONF" \
+    $DEBUG_ARGS \
+    org.apache.activemq.artemis.boot.Artemis "$@"
diff --git a/tests/smoke-tests/src/main/resources/containerService/artemis.profile b/tests/smoke-tests/src/main/resources/containerService/artemis.profile
new file mode 100644
index 0000000..93cffdc
--- /dev/null
+++ b/tests/smoke-tests/src/main/resources/containerService/artemis.profile
@@ -0,0 +1,38 @@
+# 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.
+
+# this is to replace the artemis.profile on an instance meant to be used as part of a docker image.
+
+ARTEMIS_HOME='/opt/activemq-artemis'
+ARTEMIS_INSTANCE='/var/lib/artemis-instance'
+ARTEMIS_DATA_DIR='/var/lib/artemis-instance/data'
+ARTEMIS_ETC_DIR='/var/lib/artemis-instance/etc'
+ARTEMIS_OOME_DUMP='/var/lib/artemis-instance/log/oom_dump.hprof'
+
+# The logging config will need an URI
+# this will be encoded in case you use spaces or special characters
+# on your directory structure
+ARTEMIS_INSTANCE_URI='file:/var/lib/artemis-instance/./'
+ARTEMIS_INSTANCE_ETC_URI='file:/var/lib/artemis-instance/./etc/'
+
+# Hawtio Properties
+HAWTIO_ROLE='amq'
+
+# Java Opts
+if [ -z "$JAVA_ARGS" ]; then
+    JAVA_ARGS="-XX:+PrintClassHistogram -XX:+UseG1GC -XX:+UseStringDeduplication -Xms128M -Xmx512M -Dhawtio.disableProxy=true -Dhawtio.realm=activemq -Dhawtio.offline=true -Dhawtio.rolePrincipalClasses=org.apache.activemq.artemis.spi.core.security.jaas.RolePrincipal -Djolokia.policyLocation=${ARTEMIS_INSTANCE_ETC_URI}jolokia-access.xml "
+fi
\ No newline at end of file
diff --git a/tests/smoke-tests/src/main/resources/containerService/bootstrap.xml b/tests/smoke-tests/src/main/resources/containerService/bootstrap.xml
new file mode 100644
index 0000000..ea4da15
--- /dev/null
+++ b/tests/smoke-tests/src/main/resources/containerService/bootstrap.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  ~ 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.
+  -->
+
+<broker xmlns="http://activemq.org/schema">
+
+   <jaas-security domain="activemq"/>
+
+
+   <!-- artemis.URI.instance is parsed from artemis.instance by the CLI startup.
+        This is to avoid situations where you could have spaces or special characters on this URI -->
+   <server configuration="file:/var/lib/artemis-instance/./etc//broker.xml"/>
+
+   <!-- The web server is only bound to localhost by default -->
+   <web bind="http://localhost:8161" path="web">
+       <app url="activemq-branding" war="activemq-branding.war"/>
+       <app url="artemis-plugin" war="artemis-plugin.war"/>
+       <app url="console" war="console.war"/>
+   </web>
+
+
+</broker>
+
diff --git a/tests/smoke-tests/src/main/resources/servers/brokerConnectBridgeSecurityA/artemis-roles.properties b/tests/smoke-tests/src/main/resources/servers/brokerConnect/bridgeSecurityA/artemis-roles.properties
similarity index 100%
rename from tests/smoke-tests/src/main/resources/servers/brokerConnectBridgeSecurityA/artemis-roles.properties
rename to tests/smoke-tests/src/main/resources/servers/brokerConnect/bridgeSecurityA/artemis-roles.properties
diff --git a/tests/smoke-tests/src/main/resources/servers/brokerConnectBridgeSecurityA/artemis-users.properties b/tests/smoke-tests/src/main/resources/servers/brokerConnect/bridgeSecurityA/artemis-users.properties
similarity index 100%
rename from tests/smoke-tests/src/main/resources/servers/brokerConnectBridgeSecurityA/artemis-users.properties
rename to tests/smoke-tests/src/main/resources/servers/brokerConnect/bridgeSecurityA/artemis-users.properties
diff --git a/tests/smoke-tests/src/main/resources/servers/brokerConnectBridgeSecurityA/broker.xml b/tests/smoke-tests/src/main/resources/servers/brokerConnect/bridgeSecurityA/broker.xml
similarity index 100%
rename from tests/smoke-tests/src/main/resources/servers/brokerConnectBridgeSecurityA/broker.xml
rename to tests/smoke-tests/src/main/resources/servers/brokerConnect/bridgeSecurityA/broker.xml
diff --git a/tests/smoke-tests/src/main/resources/servers/brokerConnectBridgeSecurityB/artemis-roles.properties b/tests/smoke-tests/src/main/resources/servers/brokerConnect/bridgeSecurityB/artemis-roles.properties
similarity index 100%
rename from tests/smoke-tests/src/main/resources/servers/brokerConnectBridgeSecurityB/artemis-roles.properties
rename to tests/smoke-tests/src/main/resources/servers/brokerConnect/bridgeSecurityB/artemis-roles.properties
diff --git a/tests/smoke-tests/src/main/resources/servers/brokerConnectBridgeSecurityB/artemis-users.properties b/tests/smoke-tests/src/main/resources/servers/brokerConnect/bridgeSecurityB/artemis-users.properties
similarity index 100%
rename from tests/smoke-tests/src/main/resources/servers/brokerConnectBridgeSecurityB/artemis-users.properties
rename to tests/smoke-tests/src/main/resources/servers/brokerConnect/bridgeSecurityB/artemis-users.properties
diff --git a/tests/smoke-tests/src/main/resources/servers/brokerConnectBridgeSecurityB/broker.xml b/tests/smoke-tests/src/main/resources/servers/brokerConnect/bridgeSecurityB/broker.xml
similarity index 100%
copy from tests/smoke-tests/src/main/resources/servers/brokerConnectBridgeSecurityB/broker.xml
copy to tests/smoke-tests/src/main/resources/servers/brokerConnect/bridgeSecurityB/broker.xml
diff --git a/tests/smoke-tests/src/main/resources/servers/brokerConnectMirrorSecurityA/broker.xml b/tests/smoke-tests/src/main/resources/servers/brokerConnect/mirrorSecurityA/broker.xml
similarity index 100%
rename from tests/smoke-tests/src/main/resources/servers/brokerConnectMirrorSecurityA/broker.xml
rename to tests/smoke-tests/src/main/resources/servers/brokerConnect/mirrorSecurityA/broker.xml
diff --git a/tests/smoke-tests/src/main/resources/servers/brokerConnectMirrorSecurityB/broker.xml b/tests/smoke-tests/src/main/resources/servers/brokerConnect/mirrorSecurityB/broker.xml
similarity index 97%
rename from tests/smoke-tests/src/main/resources/servers/brokerConnectMirrorSecurityB/broker.xml
rename to tests/smoke-tests/src/main/resources/servers/brokerConnect/mirrorSecurityB/broker.xml
index 21e0996..c9a4d06 100644
--- a/tests/smoke-tests/src/main/resources/servers/brokerConnectMirrorSecurityB/broker.xml
+++ b/tests/smoke-tests/src/main/resources/servers/brokerConnect/mirrorSecurityB/broker.xml
@@ -120,7 +120,11 @@ under the License.
       
       <page-sync-timeout>40000</page-sync-timeout>
 
-
+      <broker-connections>
+         <amqp-connection uri="tcp://localhost:61616" name="outgoing" reconnect-attempts="-1" retry-interval="100" user="A" password="A">
+            <mirror/>
+         </amqp-connection>
+      </broker-connections>
       <acceptors>
          <acceptor name="artemis">tcp://0.0.0.0:61617?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;amqpMinLargeMessageSize=102400;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpDuplicateDetection=true</acceptor>
       </acceptors>
diff --git a/tests/smoke-tests/src/main/resources/servers/brokerConnectBridgeSecurityB/broker.xml b/tests/smoke-tests/src/main/resources/servers/brokerConnect/qdr/broker.xml
similarity index 78%
rename from tests/smoke-tests/src/main/resources/servers/brokerConnectBridgeSecurityB/broker.xml
rename to tests/smoke-tests/src/main/resources/servers/brokerConnect/qdr/broker.xml
index 694d947..3a6e857 100644
--- a/tests/smoke-tests/src/main/resources/servers/brokerConnectBridgeSecurityB/broker.xml
+++ b/tests/smoke-tests/src/main/resources/servers/brokerConnect/qdr/broker.xml
@@ -26,10 +26,9 @@ under the License.
    <core xmlns="urn:activemq:core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="urn:activemq:core ">
 
-      <name>0.0.0.0</name>
+      <name>ServerA</name>
 
-
-      <persistence-enabled>false</persistence-enabled>
+      <persistence-enabled>true</persistence-enabled>
 
       <!-- this could be ASYNCIO, MAPPED, NIO
            ASYNCIO: Linux Libaio
@@ -100,7 +99,6 @@ under the License.
 
 
 
-
       <!-- how often we are looking for how many bytes are being used on the disk in ms -->
       <disk-scan-period>5000</disk-scan-period>
 
@@ -122,39 +120,25 @@ under the License.
 
 
       <acceptors>
-         <acceptor name="artemis">tcp://0.0.0.0:61617?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;amqpMinLargeMessageSize=102400;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpDuplicateDetection=true</acceptor>
+         <acceptor name="artemis">tcp://0.0.0.0:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;amqpMinLargeMessageSize=102400;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpDuplicateDetection=true</acceptor>
       </acceptors>
 
-      <security-settings>
 
-         <security-setting match="#">
-            <permission type="createNonDurableQueue" roles="amq"/>
-            <permission type="deleteNonDurableQueue" roles="amq"/>
-            <permission type="createDurableQueue" roles="amq"/>
-            <permission type="deleteDurableQueue" roles="amq"/>
-            <permission type="createAddress" roles="amq"/>
-            <permission type="deleteAddress" roles="amq"/>
-            <permission type="consume" roles="amq"/>
-            <permission type="browse" roles="amq"/>
-            <permission type="send" roles="amq"/>
-            <!-- we need this otherwise ./artemis data imp wouldn't work -->
-            <permission type="manage" roles="amq"/>
-         </security-setting>
-         <security-setting match="toB">
-            <permission type="createNonDurableQueue" roles="amq"/>
-            <permission type="deleteNonDurableQueue" roles="amq"/>
-            <permission type="createDurableQueue" roles="amq"/>
-            <permission type="deleteDurableQueue" roles="amq"/>
-            <permission type="createAddress" roles="amq"/>
-            <permission type="deleteAddress" roles="amq"/>
-            <permission type="consume" roles="amq"/>
-            <permission type="browse" roles="amq"/>
-            <permission type="send" roles="amq"/>
-            <!-- we need this otherwise ./artemis data imp wouldn't work -->
-            <permission type="manage" roles="amq"/>
-         </security-setting>
+      <broker-connections>
+         <amqp-connection uri="tcp://qdr:5672" name="another" retry-interval="100" reconnect-attempts="-1">
+            <peer address-match="queue.test0"/>
+            <peer address-match="queue.test1"/>
+            <peer address-match="queue.test2"/>
+            <peer address-match="queue.test3"/>
+            <peer address-match="queue.test4"/>
+            <peer address-match="queue.test5"/>
+            <peer queue-name="distinct.dist"/>
+         </amqp-connection>
+      </broker-connections>
+
 
-         <security-setting match="toA">
+      <security-settings>
+         <security-setting match="#">
             <permission type="createNonDurableQueue" roles="amq"/>
             <permission type="deleteNonDurableQueue" roles="amq"/>
             <permission type="createDurableQueue" roles="amq"/>
@@ -179,10 +163,10 @@ under the License.
             <max-size-bytes>-1</max-size-bytes>
             <message-counter-history-day-limit>10</message-counter-history-day-limit>
             <address-full-policy>PAGE</address-full-policy>
-            <auto-create-queues>true</auto-create-queues>
-            <auto-create-addresses>true</auto-create-addresses>
-            <auto-create-jms-queues>true</auto-create-jms-queues>
-            <auto-create-jms-topics>true</auto-create-jms-topics>
+            <auto-create-queues>false</auto-create-queues>
+            <auto-create-addresses>false</auto-create-addresses>
+            <auto-create-jms-queues>false</auto-create-jms-queues>
+            <auto-create-jms-topics>false</auto-create-jms-topics>
          </address-setting>
          <!--default for catch all-->
          <address-setting match="#">
@@ -193,10 +177,10 @@ under the License.
             <max-size-bytes>-1</max-size-bytes>
             <message-counter-history-day-limit>10</message-counter-history-day-limit>
             <address-full-policy>PAGE</address-full-policy>
-            <auto-create-queues>true</auto-create-queues>
-            <auto-create-addresses>true</auto-create-addresses>
-            <auto-create-jms-queues>true</auto-create-jms-queues>
-            <auto-create-jms-topics>true</auto-create-jms-topics>
+            <auto-create-queues>false</auto-create-queues>
+            <auto-create-addresses>false</auto-create-addresses>
+            <auto-create-jms-queues>false</auto-create-jms-queues>
+            <auto-create-jms-topics>false</auto-create-jms-topics>
          </address-setting>
       </address-settings>
 
@@ -211,17 +195,41 @@ under the License.
                <queue name="ExpiryQueue" />
             </anycast>
          </address>
-         <address name="toB">
+         <address name="queue.test0">
             <anycast>
-               <queue name="toB" />
+               <queue name="queue.test0" />
             </anycast>
          </address>
-         <address name="toA">
+         <address name="queue.test1">
             <anycast>
-               <queue name="toA" />
+               <queue name="queue.test1" />
+            </anycast>
+         </address>
+         <address name="queue.test2">
+            <anycast>
+               <queue name="queue.test2" />
+            </anycast>
+         </address>
+         <address name="queue.test3">
+            <anycast>
+               <queue name="queue.test3" />
+            </anycast>
+         </address>
+         <address name="queue.test4">
+            <anycast>
+               <queue name="queue.test4" />
+            </anycast>
+         </address>
+         <address name="queue.test5">
+            <anycast>
+               <queue name="queue.test5" />
+            </anycast>
+         </address>
+         <address name="queue.dist">
+            <anycast>
+               <queue name="distinct.dist" />
             </anycast>
          </address>
-
       </addresses>
 
 
diff --git a/tests/smoke-tests/src/main/resources/servers/brokerConnect/qdr/qdrouterd.conf b/tests/smoke-tests/src/main/resources/servers/brokerConnect/qdr/qdrouterd.conf
new file mode 100644
index 0000000..3acf22a
--- /dev/null
+++ b/tests/smoke-tests/src/main/resources/servers/brokerConnect/qdr/qdrouterd.conf
@@ -0,0 +1,40 @@
+ #
+ # 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.
+ #
+
+ router {
+     mode: standalone
+     id: INT.A
+ }
+log {
+    module: DEFAULT
+    enable: trace+
+    outputFile: /routerlog/qdrouterd.log
+}
+
+ # Clients connect to this port
+ listener {
+     saslMechanisms: ANONYMOUS
+     host: 0.0.0.0
+     role: normal
+     authenticatePeer: no
+     port: 5672
+  }
+
+ address {
+     prefix: queue
+     waypoint: yes
+ }
\ No newline at end of file
diff --git a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/brokerConnection/BrokerConnectionBridgeSecurityTest.java b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/brokerConnection/BrokerConnectionBridgeSecurityTest.java
index 1980d12..a97c2ce 100644
--- a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/brokerConnection/BrokerConnectionBridgeSecurityTest.java
+++ b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/brokerConnection/BrokerConnectionBridgeSecurityTest.java
@@ -34,8 +34,8 @@ import org.apache.activemq.artemis.tests.util.CFUtil;
 
 public class BrokerConnectionBridgeSecurityTest extends SmokeTestBase {
 
-   public static final String SERVER_NAME_A = "brokerConnectBridgeSecurityA";
-   public static final String SERVER_NAME_B = "brokerConnectBridgeSecurityB";
+   public static final String SERVER_NAME_A = "brokerConnect/bridgeSecurityA";
+   public static final String SERVER_NAME_B = "brokerConnect/bridgeSecurityB";
 
    @Before
    public void before() throws Exception {
diff --git a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/brokerConnection/BrokerConnectionMirrorSecurityTest.java b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/brokerConnection/BrokerConnectionMirrorSecurityTest.java
index d9da4fd..a3bafc8 100644
--- a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/brokerConnection/BrokerConnectionMirrorSecurityTest.java
+++ b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/brokerConnection/BrokerConnectionMirrorSecurityTest.java
@@ -34,8 +34,8 @@ import org.junit.Test;
 
 public class BrokerConnectionMirrorSecurityTest extends SmokeTestBase {
 
-   public static final String SERVER_NAME_A = "brokerConnectMirrorSecurityA";
-   public static final String SERVER_NAME_B = "brokerConnectMirrorSecurityB";
+   public static final String SERVER_NAME_A = "brokerConnect/mirrorSecurityA";
+   public static final String SERVER_NAME_B = "brokerConnect/mirrorSecurityB";
 
    @Before
    public void before() throws Exception {
diff --git a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/brokerConnection/QpidDispatchPeerTest.java b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/brokerConnection/QpidDispatchPeerTest.java
new file mode 100644
index 0000000..4893004
--- /dev/null
+++ b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/brokerConnection/QpidDispatchPeerTest.java
@@ -0,0 +1,195 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.tests.smoke.brokerConnection;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.DeliveryMode;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+
+import org.apache.activemq.artemis.tests.smoke.common.SmokeTestBase;
+import org.apache.activemq.artemis.tests.smoke.common.ContainerService;
+import org.jboss.logging.Logger;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * You need to build the Artemis Centos image before this test is executed.
+ * Follow the instructions under artemis-docker and build the Docker-centos image.
+ */
+public class QpidDispatchPeerTest extends SmokeTestBase {
+
+   private static final Logger logger = Logger.getLogger(QpidDispatchPeerTest.class);
+
+   static Object network;
+   static Object qpidServer;
+   static Object artemisServer;
+
+   static ContainerService service = ContainerService.getService();
+
+   @Before
+   public void disableThreadcheck() {
+      disableCheckThread();
+   }
+
+   private static final String QDR_HOME = basedir + "/target/brokerConnect/qdr";
+
+   @BeforeClass
+   public static void startServers() {
+      try {
+         Assert.assertNotNull(basedir);
+
+         network = service.newNetwork();
+
+         artemisServer = service.newBrokerImage();
+         service.setNetwork(artemisServer, network);
+         service.exposePorts(artemisServer, 61616);
+         service.prepareInstance(QDR_HOME);
+         service.exposeBrokerHome(artemisServer, QDR_HOME);
+         service.startLogging(artemisServer, "ArtemisServer:");
+
+         qpidServer = service.newInterconnectImage();
+         service.setNetwork(qpidServer, network);
+         service.exposePorts(qpidServer, 5672);
+         service.exposeHosts(qpidServer, "qdr");
+         service.exposeFile(qpidServer, basedir + "/src/main/resources/servers/brokerConnect/qdr/qdrouterd.conf", "/tmp/qdrouterd.conf");
+         service.exposeFolder(qpidServer, basedir + "/target/brokerConnect/qdr", "/routerlog");
+         service.startLogging(qpidServer, "qpid-dispatch:");
+         service.start(qpidServer);
+
+         recreateBrokerDirectory(QDR_HOME);
+
+         service.start(artemisServer);
+      } catch (Exception e) {
+         e.printStackTrace();
+         Assume.assumeNoException("Docker not available", e);
+      }
+   }
+
+   @AfterClass
+   public static void stopServer() {
+      service.stop(artemisServer);
+      service.stop(qpidServer);
+   }
+
+   @Test
+   public void testSendReceive() throws Exception {
+
+      int numberOfMessages = 100;
+
+      for (int dest = 0; dest < 5; dest++) {
+         {
+            ConnectionFactory factoryProducer = service.createCF(qpidServer, "amqp", 5672, "?amqpIdleTimeout=1000");
+            Connection connection = null;
+
+            connection = createConnectionDumbRetry(factoryProducer);
+
+            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+            Queue queue = session.createQueue("queue.test" + dest);
+            MessageProducer producer = session.createProducer(queue);
+            producer.setDeliveryMode(DeliveryMode.PERSISTENT);
+
+            for (int i = 0; i < numberOfMessages; i++) {
+               logger.debug("Sending " + i);
+               producer.send(session.createTextMessage("hello " + i));
+            }
+            connection.close();
+         }
+
+         {
+            ConnectionFactory factoryConsumer = service.createCF(artemisServer, "amqp", 61616, "?amqpIdleTimeout=1000");
+            Connection connectionConsumer = factoryConsumer.createConnection("artemis", "artemis");
+            Session sessionConsumer = connectionConsumer.createSession(false, Session.AUTO_ACKNOWLEDGE);
+            Queue queueConsumer = sessionConsumer.createQueue("queue.test" + dest);
+            MessageConsumer consumer = sessionConsumer.createConsumer(queueConsumer);
+            connectionConsumer.start();
+
+            for (int i = 0; i < numberOfMessages; i++) {
+               Message message = consumer.receive(5000);
+               Assert.assertNotNull(message);
+            }
+
+            connectionConsumer.close();
+         }
+
+      }
+
+   }
+
+   @Test
+   public void testSendReceiveDistinct() throws Exception {
+
+      int numberOfMessages = 100;
+
+      {
+         ConnectionFactory factoryProducer = service.createCF(qpidServer, "amqp", 5672, "?amqpIdleTimeout=1000");
+         Connection connection = null;
+
+         connection = createConnectionDumbRetry(factoryProducer);
+
+         Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         Queue queue = session.createQueue("queue.dist");
+         MessageProducer producer = session.createProducer(queue);
+         producer.setDeliveryMode(DeliveryMode.PERSISTENT);
+
+         for (int i = 0; i < numberOfMessages; i++) {
+            logger.debug("Sending " + i);
+            producer.send(session.createTextMessage("hello " + i));
+         }
+         connection.close();
+      }
+
+      {
+         ConnectionFactory factoryConsumer = service.createCF(artemisServer, "amqp", 61616, "?amqpIdleTimeout=1000");
+         Connection connectionConsumer = factoryConsumer.createConnection("artemis", "artemis");
+         Session sessionConsumer = connectionConsumer.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         Queue queueConsumer = sessionConsumer.createQueue("queue.dist::distinct.dist");
+         MessageConsumer consumer = sessionConsumer.createConsumer(queueConsumer);
+         connectionConsumer.start();
+
+         for (int i = 0; i < numberOfMessages; i++) {
+            Message message = consumer.receive(5000);
+            Assert.assertNotNull(message);
+         }
+
+         connectionConsumer.close();
+      }
+
+
+   }
+
+   private Connection createConnectionDumbRetry(ConnectionFactory factoryProducer) throws InterruptedException {
+      for (int i = 0; i < 100; i++) {
+         try {
+            // Some retry
+            return factoryProducer.createConnection();
+         } catch (Exception e) {
+            Thread.sleep(10);
+         }
+      }
+      return null;
+   }
+
+}
diff --git a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/common/ContainerService.java b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/common/ContainerService.java
new file mode 100644
index 0000000..3f75e6f
--- /dev/null
+++ b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/common/ContainerService.java
@@ -0,0 +1,283 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.tests.smoke.common;
+
+import javax.jms.ConnectionFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+import java.util.function.Consumer;
+
+import org.apache.activemq.artemis.tests.util.CFUtil;
+import org.junit.Assert;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.Network;
+import org.testcontainers.containers.output.OutputFrame;
+import org.testcontainers.containers.startupcheck.IsRunningStartupCheckStrategy;
+import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
+import org.testcontainers.utility.DockerImageName;
+import org.testcontainers.utility.MountableFile;
+
+/**
+ * I am intentionally not depending directly into TestContainer
+ * I intend in a near future to support kubernetes and podman and I would like to keep an interface between our tests and the Container provider.
+ */
+public abstract class ContainerService {
+
+   public static final ContainerService service;
+
+   static {
+      ContainerService loadingService;
+      try {
+         String providerName = System.getProperty(ContainerService.class.getName() + ".service");
+         if (providerName == null) {
+            loadingService = new TestContainerImpl();
+         } else {
+            loadingService = (ContainerService) Class.forName(providerName).newInstance();
+         }
+      } catch (Throwable e) {
+         e.printStackTrace();
+         loadingService = null;
+      }
+
+      service = loadingService;
+   }
+
+   public static ContainerService getService() {
+      return service;
+   }
+
+   public abstract Object newNetwork();
+
+   public abstract Object newBrokerImage();
+
+   public abstract Object newInterconnectImage();
+
+   public abstract void setNetwork(Object container, Object network);
+
+   public abstract void exposePorts(Object container, Integer... ports);
+
+   public abstract void exposeFile(Object container, String hostPath, String containerPath);
+
+   public abstract void exposeFolder(Object container, String hostPath, String containerPath);
+
+   public abstract void copyFileToContainer(Object container, String hostPath, String containerPath);
+
+   public abstract void exposeBrokerHome(Object container, String brokerHome);
+
+   public abstract void startLogging(Object container, String prefix);
+
+   public abstract void start(Object container);
+
+   public abstract void kill(Object container);
+
+   public abstract void stop(Object container);
+
+   public abstract void restart(Object container);
+
+   public abstract int getPort(Object container, int mappedPort);
+
+   public abstract void exposeHosts(Object container, String... hosts);
+
+   /** prepare the instance folder to run inside the docker image */
+   public abstract void prepareInstance(String home) throws Exception;
+
+   public String getHost(Object container) {
+      return "localhost";
+   }
+
+   public abstract ConnectionFactory createCF(Object container, String protocol);
+
+   public abstract String createURI(Object container, int port);
+
+   public abstract ConnectionFactory createCF(Object container, String protocol, int port);
+   public abstract ConnectionFactory createCF(Object container, String protocol, int port, String extraURL);
+
+   public boolean waitForServerToStart(Object container, String username, String password, long timeout) throws InterruptedException {
+      long realTimeout = System.currentTimeMillis() + timeout;
+      while (System.currentTimeMillis() < realTimeout) {
+         try {
+            ConnectionFactory cf = createCF(container, "core");
+            cf.createConnection(username, password).close();
+            if (cf instanceof AutoCloseable) {
+               ((AutoCloseable)cf).close();
+            }
+            System.out.println("server started");
+         } catch (Exception e) {
+            System.out.println("awaiting server start at ");
+            Thread.sleep(500);
+            continue;
+         }
+         return true;
+      }
+
+      return false;
+   }
+
+   public abstract void logWait(Object container, String log);
+
+   private static class TestContainerImpl extends ContainerService {
+
+      @Override
+      public ConnectionFactory createCF(Object container, String protocol) {
+         return createCF(container, protocol, 61616);
+      }
+
+      @Override
+      public void prepareInstance(String home) throws Exception {
+         File homeFile = new File(home);
+         Assert.assertTrue(homeFile.exists());
+         Assert.assertTrue(homeFile.isDirectory());
+
+         copyFile("artemis", home + "/bin/artemis");
+         copyFile("artemis.profile", home + "/etc/artemis.profile");
+         copyFile("bootstrap.xml", home + "/etc/bootstrap.xml");
+      }
+
+      private void copyFile(String from, String to) throws IOException {
+         File file = new File(SmokeTestBase.basedir + "/src/main/resources/containerService/" + from);
+         Files.copy(file.toPath(), new File(to).toPath(), StandardCopyOption.REPLACE_EXISTING);
+      }
+
+      @Override
+      public ConnectionFactory createCF(Object container, String protocol, int port) {
+         return CFUtil.createConnectionFactory("amqp", "tcp://" + getHost(container) + ":" + getPort(container, port));
+      }
+      @Override
+      public ConnectionFactory createCF(Object container, String protocol, int port, String extraURI) {
+         System.out.println("tcp://" + getHost(container) + ":" + getPort(container, port) + extraURI);
+         return CFUtil.createConnectionFactory("amqp", "tcp://" + getHost(container) + ":" + getPort(container, port) + extraURI);
+      }
+
+      @Override
+      public Object newNetwork() {
+         return Network.newNetwork();
+      }
+
+      @Override
+      public Object newBrokerImage() {
+         return new GenericContainer<>(DockerImageName.parse("artemis-centos"));
+      }
+
+      @Override
+      public Object newInterconnectImage() {
+         return new GenericContainer<>(DockerImageName.parse("quay.io/interconnectedcloud/qdrouterd:latest"));
+      }
+
+      @Override
+      public void setNetwork(Object container, Object network) {
+         ((GenericContainer)container).setNetwork((Network)network);
+      }
+
+      @Override
+      public void exposePorts(Object container, Integer... ports) {
+         ((GenericContainer)container).withExposedPorts(ports);
+      }
+
+      @Override
+      public void exposeFile(Object container, String hostPath, String containerPath) {
+         File file = new File(hostPath);
+         Assert.assertTrue(file.exists());
+         Assert.assertFalse(file.isDirectory());
+         ((GenericContainer)container).withFileSystemBind(hostPath, containerPath);
+      }
+
+      @Override
+      public void exposeFolder(Object container, String hostPath, String containerPath) {
+         File file = new File(hostPath);
+         Assert.assertTrue(file.exists());
+         Assert.assertTrue(file.isDirectory());
+         ((GenericContainer)container).withFileSystemBind(hostPath, containerPath);
+      }
+
+      @Override
+      public void copyFileToContainer(Object container, String hostPath, String containerPath) {
+         File file = new File(hostPath);
+         Assert.assertTrue(file.exists());
+         Assert.assertFalse(file.isDirectory());
+         ((GenericContainer)container).withCopyFileToContainer(MountableFile.forHostPath(hostPath), containerPath);
+      }
+
+      @Override
+      public void exposeBrokerHome(Object container, String brokerHome) {
+         exposeFolder(container, brokerHome, "/var/lib/artemis-instance");
+      }
+
+      @Override
+      public void start(Object container) {
+         ((GenericContainer)container).setStartupCheckStrategy(new IsRunningStartupCheckStrategy());
+         ((GenericContainer)container).start();
+      }
+
+      @Override
+      public void restart(Object containerObj) {
+         kill(containerObj);
+         start(containerObj);
+      }
+
+      @Override
+      public void kill(Object containerObj) {
+         GenericContainer container = (GenericContainer) containerObj;
+         container.getDockerClient().killContainerCmd(container.getContainerId()).exec();
+         container.stop();
+      }
+
+      @Override
+      public int getPort(Object container, int mappedPort) {
+         return ((GenericContainer)container).getMappedPort(mappedPort);
+      }
+
+      @Override
+      public void exposeHosts(Object container, String... hosts) {
+         ((GenericContainer)container).withNetworkAliases(hosts);
+      }
+
+      @Override
+      public void stop(Object container) {
+         if (container != null) {
+            ((GenericContainer) container).stop();
+         }
+      }
+
+      @Override
+      public void startLogging(Object container, String prefix) {
+         ((GenericContainer)container).withLogConsumer(new Consumer<OutputFrame>() {
+            @Override
+            public void accept(OutputFrame outputFrame) {
+               System.out.print(prefix + outputFrame.getUtf8String());
+            }
+         });
+      }
+
+      @Override
+      public void logWait(Object container, String log) {
+         LogMessageWaitStrategy logMessageWaitStrategy = new LogMessageWaitStrategy();
+         logMessageWaitStrategy.withRegEx(log);
+         ((GenericContainer)container).setWaitStrategy(logMessageWaitStrategy);
+      }
+
+      @Override
+      public String createURI(Object container, int port) {
+         GenericContainer genericContainer = (GenericContainer) container;
+         return "tcp://" + genericContainer.getHost() + ":" + genericContainer.getMappedPort(port);
+      }
+   }
+
+}
diff --git a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/common/SmokeTestBase.java b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/common/SmokeTestBase.java
index 313b15c..9a3231f 100644
--- a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/common/SmokeTestBase.java
+++ b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/common/SmokeTestBase.java
@@ -25,7 +25,9 @@ import java.io.IOException;
 import java.util.HashSet;
 import java.util.Set;
 
+import org.apache.activemq.artemis.api.jms.ActiveMQJMSClient;
 import org.apache.activemq.artemis.cli.commands.Stop;
+import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
 import org.apache.activemq.artemis.util.ServerUtil;
 import org.junit.After;
@@ -71,6 +73,7 @@ public class SmokeTestBase extends ActiveMQTestBase {
    public static void cleanupData(String serverName) {
       String location = getServerLocation(serverName);
       deleteDirectory(new File(location, "data"));
+      deleteDirectory(new File(location, "log"));
    }
 
    public void addProcess(Process process) {
@@ -109,4 +112,28 @@ public class SmokeTestBase extends ActiveMQTestBase {
       }
       return jmxConnector;
    }
+
+   protected static final void recreateBrokerDirectory(final String homeInstance) {
+      recreateDirectory(homeInstance + "/data");
+      recreateDirectory(homeInstance + "/logs");
+   }
+
+
+   public boolean waitForServerToStart(String uri, String username, String password, long timeout) throws InterruptedException {
+      long realTimeout = System.currentTimeMillis() + timeout;
+      while (System.currentTimeMillis() < realTimeout) {
+         try (ActiveMQConnectionFactory cf = ActiveMQJMSClient.createConnectionFactory(uri, null)) {
+            cf.createConnection(username, password).close();
+            System.out.println("server " + uri + " started");
+         } catch (Exception e) {
+            System.out.println("awaiting server " + uri + " start at ");
+            Thread.sleep(500);
+            continue;
+         }
+         return true;
+      }
+
+      return false;
+   }
+
 }