From 200e436931bb5a15d23b71f6041ef8ad2ae2b8a0 Mon Sep 17 00:00:00 2001 From: Clebert Suconic Date: Tue, 29 Jun 2021 13:58:48 -0400 Subject: [PATCH] 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 ++- .../main/resources/containerService/README | 24 ++ .../main/resources/containerService/artemis | 136 +++++++++ .../containerService/artemis.profile | 38 +++ .../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 +- .../servers/brokerConnect/qdr/broker.xml | 251 ++++++++++++++++ .../servers/brokerConnect/qdr/qdrouterd.conf | 40 +++ .../BrokerConnectionBridgeSecurityTest.java | 4 +- .../BrokerConnectionMirrorSecurityTest.java | 4 +- .../QpidDispatchPeerTest.java | 195 ++++++++++++ .../tests/smoke/common/ContainerService.java | 283 ++++++++++++++++++ .../tests/smoke/common/SmokeTestBase.java | 27 ++ 21 files changed, 1072 insertions(+), 14 deletions(-) create mode 100644 tests/smoke-tests/src/main/resources/containerService/README create mode 100755 tests/smoke-tests/src/main/resources/containerService/artemis create mode 100644 tests/smoke-tests/src/main/resources/containerService/artemis.profile create mode 100644 tests/smoke-tests/src/main/resources/containerService/bootstrap.xml rename tests/smoke-tests/src/main/resources/servers/{brokerConnectBridgeSecurityA => brokerConnect/bridgeSecurityA}/artemis-roles.properties (100%) rename tests/smoke-tests/src/main/resources/servers/{brokerConnectBridgeSecurityA => brokerConnect/bridgeSecurityA}/artemis-users.properties (100%) rename tests/smoke-tests/src/main/resources/servers/{brokerConnectBridgeSecurityA => brokerConnect/bridgeSecurityA}/broker.xml (100%) rename tests/smoke-tests/src/main/resources/servers/{brokerConnectBridgeSecurityB => brokerConnect/bridgeSecurityB}/artemis-roles.properties (100%) rename tests/smoke-tests/src/main/resources/servers/{brokerConnectBridgeSecurityB => brokerConnect/bridgeSecurityB}/artemis-users.properties (100%) rename tests/smoke-tests/src/main/resources/servers/{brokerConnectBridgeSecurityB => brokerConnect/bridgeSecurityB}/broker.xml (100%) rename tests/smoke-tests/src/main/resources/servers/{brokerConnectMirrorSecurityA => brokerConnect/mirrorSecurityA}/broker.xml (100%) rename tests/smoke-tests/src/main/resources/servers/{brokerConnectMirrorSecurityB => brokerConnect/mirrorSecurityB}/broker.xml (97%) create mode 100644 tests/smoke-tests/src/main/resources/servers/brokerConnect/qdr/broker.xml create mode 100644 tests/smoke-tests/src/main/resources/servers/brokerConnect/qdr/qdrouterd.conf create mode 100644 tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/brokerConnection/QpidDispatchPeerTest.java create mode 100644 tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/common/ContainerService.java 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 13707e7f14..3b6a8aa4eb 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 ed9c53bcbf..7fb05df653 100644 --- a/tests/smoke-tests/pom.xml +++ b/tests/smoke-tests/pom.xml @@ -147,10 +147,16 @@ 3.14.0 test + + org.testcontainers + testcontainers + 1.15.3 + test + org.testcontainers selenium - 1.15.1 + 1.15.3 test @@ -717,8 +723,8 @@ A A true - ${basedir}/target/brokerConnectBridgeSecurityA - ${basedir}/target/classes/servers/brokerConnectBridgeSecurityA + ${basedir}/target/brokerConnect/bridgeSecurityA + ${basedir}/target/classes/servers/brokerConnect/bridgeSecurityA @@ -733,8 +739,8 @@ B true 100 - ${basedir}/target/brokerConnectBridgeSecurityB - ${basedir}/target/classes/servers/brokerConnectBridgeSecurityB + ${basedir}/target/brokerConnect/bridgeSecurityB + ${basedir}/target/classes/servers/brokerConnect/bridgeSecurityB @@ -749,8 +755,8 @@ A A true - ${basedir}/target/brokerConnectMirrorSecurityA - ${basedir}/target/classes/servers/brokerConnectMirrorSecurityA + ${basedir}/target/brokerConnect/mirrorSecurityA + ${basedir}/target/classes/servers/brokerConnect/mirrorSecurityA @@ -765,8 +771,8 @@ B true 1 - ${basedir}/target/brokerConnectMirrorSecurityB - ${basedir}/target/classes/servers/brokerConnectMirrorSecurityB + ${basedir}/target/brokerConnect/mirrorSecurityB + ${basedir}/target/classes/servers/brokerConnect/mirrorSecurityB @@ -826,6 +832,22 @@ + + test-compile + create-qdr + + create + + + amq + artemis + artemis + false + false + ${basedir}/target/brokerConnect/qdr + ${basedir}/target/classes/servers/brokerConnect/qdr + + 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 0000000000..31c0371b18 --- /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 0000000000..dfa686654d --- /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 0000000000..93cffdc862 --- /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 0000000000..ea4da157d3 --- /dev/null +++ b/tests/smoke-tests/src/main/resources/containerService/bootstrap.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + 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% rename from tests/smoke-tests/src/main/resources/servers/brokerConnectBridgeSecurityB/broker.xml rename 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 21e0996872..c9a4d061b4 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. 40000 - + + + + + 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 diff --git a/tests/smoke-tests/src/main/resources/servers/brokerConnect/qdr/broker.xml b/tests/smoke-tests/src/main/resources/servers/brokerConnect/qdr/broker.xml new file mode 100644 index 0000000000..3a6e857298 --- /dev/null +++ b/tests/smoke-tests/src/main/resources/servers/brokerConnect/qdr/broker.xml @@ -0,0 +1,251 @@ + + + + + + + + ServerA + + true + + + NIO + + data/paging + + data/bindings + + data/journal + + data/large-messages + + true + + 2 + + 10 + + 4096 + + 10M + + + 40000 + + + + 1 + + + + + + + + + + + + + + + + + + + + 5000 + + + 90 + + + true + + 120000 + + 60000 + + HALT + + + 40000 + + + + 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DLQ + ExpiryQueue + 0 + + -1 + 10 + PAGE + false + false + false + false + + + + DLQ + ExpiryQueue + 0 + + -1 + 10 + PAGE + false + false + false + false + + + + +
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + + +
+
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 0000000000..3acf22a171 --- /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 1980d12dc4..a97c2ce424 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 d9da4fde30..a3bafc891e 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 0000000000..48930043de --- /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 + *

+ * 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.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 0000000000..3f75e6f568 --- /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 + *

+ * 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.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() { + @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 313b15c862..9a3231f6ef 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; + } + }