ARTEMIS-4583: remove the artemis-server test-jar, do related cleanup

- Move ActiveMQTestBase to artemis-test-support.
- Add reduced parent for current artemis-server tests.
- Add a simpler test case parent class unit tests can use.
- Convert some existing checks into a rule for reuse.
- Move various rules/utils to artemis[-unit]-test-support module from where they can be used instead of from artemis-server.
This commit is contained in:
Robbie Gemmell 2024-01-25 14:49:57 +00:00
parent e513e6d2dd
commit 83eb03c665
56 changed files with 1217 additions and 492 deletions

View File

@ -328,20 +328,4 @@
</build>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -75,7 +75,7 @@ import org.apache.activemq.artemis.core.settings.impl.DeletionPolicy;
import org.apache.activemq.artemis.core.settings.impl.ResourceLimitSettings;
import org.apache.activemq.artemis.logs.AssertionLoggerHandler;
import org.apache.activemq.artemis.core.settings.impl.SlowConsumerThresholdMeasurementUnit;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.apache.activemq.artemis.utils.RandomUtil;
import org.apache.activemq.artemis.utils.critical.CriticalAnalyzerPolicy;
import org.apache.commons.lang3.ClassUtils;
@ -88,7 +88,7 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class ConfigurationImplTest extends ActiveMQTestBase {
public class ConfigurationImplTest extends ServerTestBase {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.tests.unit.core.config.impl;
package org.apache.activemq.artemis.core.config.impl;
import org.apache.activemq.artemis.core.config.amqpBrokerConnectivity.AMQPBrokerConnectConfiguration;
@ -22,14 +22,13 @@ import org.apache.activemq.artemis.core.config.FileDeploymentManager;
import org.apache.activemq.artemis.core.config.amqpBrokerConnectivity.AMQPBrokerConnectionAddressType;
import org.apache.activemq.artemis.core.config.amqpBrokerConnectivity.AMQPFederatedBrokerConnectionElement;
import org.apache.activemq.artemis.core.config.amqpBrokerConnectivity.AMQPMirrorBrokerConnectionElement;
import org.apache.activemq.artemis.core.config.impl.FileConfiguration;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.apache.activemq.artemis.utils.XMLUtil;
import org.junit.Assert;
import org.junit.Test;
import org.w3c.dom.Element;
public class ConfigurationValidationTest extends ActiveMQTestBase {
public class ConfigurationValidationTest extends ServerTestBase {
static {
System.setProperty("a2Prop", "a2");

View File

@ -23,12 +23,12 @@ import org.apache.activemq.artemis.core.config.storage.DatabaseStorageConfigurat
import org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl;
import org.apache.activemq.artemis.jdbc.store.sql.PropertySQLProvider;
import org.apache.activemq.artemis.jdbc.store.sql.SQLProvider;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.junit.Test;
import static org.apache.activemq.artemis.jdbc.store.sql.PropertySQLProvider.Factory.SQLDialect.ORACLE;
public class DatabaseStoreConfigurationTest extends ActiveMQTestBase {
public class DatabaseStoreConfigurationTest extends ServerTestBase {
@Test
public void databaseStoreConfigTest() throws Exception {

View File

@ -37,7 +37,7 @@ import org.apache.activemq.artemis.core.config.ha.SharedStorePrimaryPolicyConfig
import org.apache.activemq.artemis.core.deployers.impl.FileConfigurationParser;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.apache.activemq.artemis.utils.ClassloadingUtil;
import org.apache.activemq.artemis.utils.DefaultSensitiveStringCodec;
import org.apache.activemq.artemis.utils.PasswordMaskingUtil;
@ -45,7 +45,7 @@ import org.apache.activemq.artemis.utils.StringPrintStream;
import org.junit.Assert;
import org.junit.Test;
public class FileConfigurationParserTest extends ActiveMQTestBase {
public class FileConfigurationParserTest extends ServerTestBase {
/**
* These "InvalidConfigurationTest*.xml" files are modified copies of {@value

View File

@ -50,11 +50,11 @@ import org.apache.activemq.artemis.quorum.DistributedLock;
import org.apache.activemq.artemis.quorum.DistributedPrimitiveManager;
import org.apache.activemq.artemis.quorum.MutableLong;
import org.apache.activemq.artemis.quorum.UnavailableStateException;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.junit.After;
import org.junit.Test;
public class HAPolicyConfigurationTest extends ActiveMQTestBase {
public class HAPolicyConfigurationTest extends ServerTestBase {
@Override
@After

View File

@ -21,14 +21,14 @@ import java.nio.charset.StandardCharsets;
import org.apache.activemq.artemis.core.deployers.impl.FileConfigurationParser;
import org.apache.activemq.artemis.logs.AssertionLoggerHandler;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.junit.Test;
/**
* When running this test from an IDE add this to the test command line so that the AssertionLoggerHandler works properly:
* -Dlog4j2.configurationFile=file:<path_to_source>/tests/config/log4j2-tests-config.properties
*/
public class WrongRoleFileConfigurationParserTest extends ActiveMQTestBase {
public class WrongRoleFileConfigurationParserTest extends ServerTestBase {
@Test
public void testParsingDefaultServerConfig() throws Exception {

View File

@ -32,13 +32,13 @@ import org.apache.activemq.artemis.core.paging.PagingStoreFactory;
import org.apache.activemq.artemis.core.paging.impl.PagingStoreImpl;
import org.apache.activemq.artemis.core.persistence.impl.nullpm.NullStorageManager;
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.apache.activemq.artemis.utils.actors.ArtemisExecutor;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;
public class ConcurrentAckTest extends ActiveMQTestBase {
public class ConcurrentAckTest extends ServerTestBase {
@Test
public void testConcurrentAddAckPaging() throws Throwable {

View File

@ -31,7 +31,7 @@ import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
import org.apache.activemq.artemis.core.postoffice.PostOffice;
import org.apache.activemq.artemis.core.server.JournalType;
import org.apache.activemq.artemis.core.server.impl.JournalLoader;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.apache.activemq.artemis.utils.ExecutorFactory;
import org.apache.activemq.artemis.utils.actors.OrderedExecutorFactory;
import org.junit.AfterClass;
@ -49,7 +49,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
@RunWith(Parameterized.class)
public class JournalStorageManagerTest extends ActiveMQTestBase {
public class JournalStorageManagerTest extends ServerTestBase {
@Parameterized.Parameter
public JournalType journalType;

View File

@ -21,11 +21,11 @@ import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
import org.apache.activemq.artemis.core.io.SequentialFile;
import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.core.persistence.impl.nullpm.NullStorageManager;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.junit.Assert;
import org.junit.Test;
public class LargeServerMessageImplTest extends ActiveMQTestBase {
public class LargeServerMessageImplTest extends ServerTestBase {
@Test
public void testDeleteNoRecreateFile() throws Exception {

View File

@ -25,14 +25,14 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
import org.apache.activemq.artemis.utils.Wait;
import org.apache.activemq.artemis.utils.actors.OrderedExecutor;
import org.junit.Assert;
import org.junit.Test;
public class OperationContextUnitTest extends ActiveMQTestBase {
public class OperationContextUnitTest extends ServerTestBase {
@Test
public void testCompleteTaskAfterPaging() throws Exception {

View File

@ -27,14 +27,14 @@ import java.util.concurrent.TimeUnit;
import org.apache.activemq.artemis.core.server.reload.ReloadCallback;
import org.apache.activemq.artemis.core.server.reload.ReloadManagerImpl;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.apache.activemq.artemis.utils.ReusableLatch;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class ReloadManagerTest extends ActiveMQTestBase {
public class ReloadManagerTest extends ServerTestBase {
private ScheduledExecutorService scheduledExecutorService;

View File

@ -24,7 +24,7 @@ import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl;
import org.apache.activemq.artemis.core.server.impl.ServerStatus;
import org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.apache.activemq.artemis.utils.Wait;
import org.junit.After;
import org.junit.Before;
@ -33,7 +33,7 @@ import org.junit.Test;
import static org.apache.activemq.artemis.core.server.impl.ServerStatus.JAAS_COMPONENT;
import static org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoader.LOGIN_CONFIG_SYS_PROP_NAME;
public class StatusTest extends ActiveMQTestBase {
public class StatusTest extends ServerTestBase {
private String existingPath = null;

View File

@ -22,13 +22,13 @@ import org.apache.activemq.artemis.api.core.BroadcastEndpoint;
import org.apache.activemq.artemis.api.core.BroadcastEndpointFactory;
import org.apache.activemq.artemis.api.core.TransportConfiguration;
import org.apache.activemq.artemis.core.server.impl.InVMNodeManager;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.junit.Test;
/**
* Test the {@link BroadcastGroupImpl}.<br>
*/
public class BroadcastGroupImplTest extends ActiveMQTestBase {
public class BroadcastGroupImplTest extends ServerTestBase {
static class BroadcastEndpointFactoryImpl implements BroadcastEndpointFactory {

View File

@ -22,7 +22,7 @@ import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
import org.apache.activemq.artemis.core.server.cluster.ClusterManager;
import org.apache.activemq.artemis.core.server.impl.Activation;
import org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
import org.apache.activemq.artemis.utils.ExecutorFactory;
import org.apache.activemq.artemis.utils.actors.ArtemisExecutor;
@ -31,7 +31,7 @@ import org.junit.Test;
import java.util.concurrent.Executors;
public class ClusterConnectionImplMockTest extends ActiveMQTestBase {
public class ClusterConnectionImplMockTest extends ServerTestBase {
/**
* Verification for the fix https://issues.apache.org/jira/browse/ARTEMIS-1946

View File

@ -27,7 +27,7 @@ import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.apache.activemq.artemis.utils.ReusableLatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -39,7 +39,7 @@ import org.junit.Test;
import static org.apache.activemq.artemis.core.server.files.FileStoreMonitor.FileStoreMonitorType.MaxDiskUsage;
public class FileStoreMonitorTest extends ActiveMQTestBase {
public class FileStoreMonitorTest extends ServerTestBase {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

View File

@ -58,7 +58,7 @@ import org.apache.activemq.artemis.core.settings.HierarchicalRepository;
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
import org.apache.activemq.artemis.core.transaction.ResourceManager;
import org.apache.activemq.artemis.spi.core.remoting.Acceptor;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.apache.activemq.artemis.utils.ReusableLatch;
import org.apache.activemq.artemis.utils.collections.ConcurrentHashSet;
import org.junit.Assert;
@ -69,7 +69,7 @@ import org.junit.Test;
* There is a small window where you could receive notifications wrongly
* this test will make sure the component would play well with that notification
*/
public class ClusteredResetMockTest extends ActiveMQTestBase {
public class ClusteredResetMockTest extends ServerTestBase {
public static final SimpleString ANYCLUSTER = SimpleString.toSimpleString("anycluster");

View File

@ -22,11 +22,11 @@ import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.junit.Assert;
import org.junit.Test;
public class ActiveMQServerImplTest extends ActiveMQTestBase {
public class ActiveMQServerImplTest extends ServerTestBase {
@Test
public void testAddingAndStartingExternalComponent() throws Exception {

View File

@ -19,14 +19,14 @@ package org.apache.activemq.artemis.core.server.impl;
import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.logs.AssertionLoggerHandler;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.apache.activemq.artemis.utils.critical.CriticalAnalyzerAccessor;
import org.apache.activemq.artemis.utils.critical.CriticalAnalyzerPolicy;
import org.apache.activemq.artemis.utils.critical.CriticalComponentImpl;
import org.junit.Assert;
import org.junit.Test;
public class ActiveMQServerStartupTest extends ActiveMQTestBase {
public class ActiveMQServerStartupTest extends ServerTestBase {
@Test
public void testTooLongToStartHalt() throws Exception {

View File

@ -36,7 +36,7 @@ import org.apache.activemq.artemis.core.server.NodeManager.LockListener;
import org.apache.activemq.artemis.jdbc.store.drivers.JDBCUtils;
import org.apache.activemq.artemis.jdbc.store.sql.SQLProvider;
import org.apache.activemq.artemis.logs.AssertionLoggerHandler;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.apache.activemq.artemis.utils.Wait;
import org.apache.activemq.artemis.utils.actors.ArtemisExecutor;
import org.apache.activemq.artemis.utils.actors.OrderedExecutorFactory;
@ -50,7 +50,7 @@ import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
@RunWith(Parameterized.class)
public class JdbcLeaseLockTest extends ActiveMQTestBase {
public class JdbcLeaseLockTest extends ServerTestBase {
private JdbcSharedStateManager jdbcSharedStateManager;
private DatabaseStorageConfiguration dbConf;

View File

@ -23,7 +23,7 @@ import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import org.apache.activemq.artemis.core.config.storage.DatabaseStorageConfiguration;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -32,7 +32,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@RunWith(Parameterized.class)
public class JdbcNodeManagerTest extends ActiveMQTestBase {
public class JdbcNodeManagerTest extends ServerTestBase {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

View File

@ -21,11 +21,11 @@ import java.util.UUID;
import org.apache.activemq.artemis.core.config.storage.DatabaseStorageConfiguration;
import org.apache.activemq.artemis.jdbc.store.drivers.JDBCUtils;
import org.apache.activemq.artemis.jdbc.store.sql.SQLProvider;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.junit.Before;
import org.junit.Test;
public class JdbcSharedStateManagerTest extends ActiveMQTestBase {
public class JdbcSharedStateManagerTest extends ServerTestBase {
private DatabaseStorageConfiguration dbConf;
private SQLProvider sqlProvider;

View File

@ -17,7 +17,7 @@
package org.apache.activemq.artemis.core.server.management;
import org.apache.activemq.artemis.core.config.JMXConnectorConfiguration;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.junit.Assert;
import org.junit.Test;
@ -25,7 +25,7 @@ import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
public class JMXRMIRegistryPortTest extends ActiveMQTestBase {
public class JMXRMIRegistryPortTest extends ServerTestBase {
@Test
public void explicitLocalhostRegistry() throws IOException {

View File

@ -23,13 +23,13 @@ import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy;
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
import org.apache.activemq.artemis.core.settings.impl.DeletionPolicy;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AddressSettingsTest extends ActiveMQTestBase {
public class AddressSettingsTest extends ServerTestBase {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

View File

@ -27,12 +27,12 @@ import org.apache.activemq.artemis.core.config.WildcardConfiguration;
import org.apache.activemq.artemis.core.security.Role;
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
import org.apache.activemq.artemis.core.settings.impl.HierarchicalObjectRepository;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class RepositoryTest extends ActiveMQTestBase {
public class RepositoryTest extends ServerTestBase {
HierarchicalRepository<HashSet<Role>> securityRepository;

View File

@ -68,15 +68,16 @@ import org.apache.activemq.artemis.core.server.impl.JournalLoader;
import org.apache.activemq.artemis.core.transaction.ResourceManager;
import org.apache.activemq.artemis.core.transaction.Transaction;
import org.apache.activemq.artemis.core.transaction.TransactionOperation;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ServerTestBase;
import org.apache.activemq.artemis.utils.ArtemisCloseable;
import org.apache.activemq.artemis.utils.UUIDGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.invoke.MethodHandles;
import org.junit.Assert;
import org.junit.Test;
public class TransactionImplTest extends ActiveMQTestBase {
public class TransactionImplTest extends ServerTestBase {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@Test
@ -937,4 +938,8 @@ public class TransactionImplTest extends ActiveMQTestBase {
}
}
protected XidImpl newXID() {
return new XidImpl("xa1".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());
}
}

View File

@ -19,6 +19,7 @@ package org.apache.activemq.artemis.tests.util;
import java.io.File;
import org.apache.activemq.artemis.utils.FileUtil;
import org.junit.rules.ExternalResource;
/**
@ -37,6 +38,6 @@ public class RemoveFolder extends ExternalResource {
*/
@Override
protected void after() {
ActiveMQTestBase.deleteDirectory(new File(folderName));
FileUtil.deleteDirectory(new File(folderName));
}
}

View File

@ -0,0 +1,706 @@
/*
* 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.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
import org.apache.activemq.artemis.api.core.TransportConfiguration;
import org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl;
import org.apache.activemq.artemis.core.client.impl.ServerLocatorImpl;
import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
import org.apache.activemq.artemis.core.config.storage.DatabaseStorageConfiguration;
import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
import org.apache.activemq.artemis.core.persistence.impl.journal.OperationContextImpl;
import org.apache.activemq.artemis.core.remoting.impl.invm.InVMAcceptorFactory;
import org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnector;
import org.apache.activemq.artemis.core.remoting.impl.invm.InVMRegistry;
import org.apache.activemq.artemis.core.remoting.impl.netty.NettyAcceptorFactory;
import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnector;
import org.apache.activemq.artemis.core.server.ActiveMQComponent;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.core.server.ActiveMQServers;
import org.apache.activemq.artemis.core.server.JournalType;
import org.apache.activemq.artemis.core.server.cluster.ClusterConnection;
import org.apache.activemq.artemis.core.server.cluster.ClusterManager;
import org.apache.activemq.artemis.core.server.impl.PrimaryOnlyActivation;
import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy;
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
import org.apache.activemq.artemis.core.settings.impl.PageFullMessagePolicy;
import org.apache.activemq.artemis.tests.rules.LibaioContextCheck;
import org.apache.activemq.artemis.utils.Env;
import org.apache.activemq.artemis.utils.FileUtil;
import org.apache.activemq.artemis.utils.PortCheckRule;
import org.apache.activemq.artemis.utils.ThreadDumpUtil;
import org.apache.activemq.artemis.utils.Wait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.invoke.MethodHandles;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.rules.TemporaryFolder;
/**
* Base class with basic utilities on starting up a basic server
*/
public abstract class ServerTestBase extends ArtemisTestCase {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
static {
Env.setTestEnv(true);
}
@ClassRule
public static PortCheckRule portCheckRule = new PortCheckRule(61616);
public static final String TARGET_TMP = "./target/tmp";
public static final String INVM_ACCEPTOR_FACTORY = InVMAcceptorFactory.class.getCanonicalName();
public static final String NETTY_ACCEPTOR_FACTORY = NettyAcceptorFactory.class.getCanonicalName();
public static final String CLUSTER_PASSWORD = "UnitTestsClusterPassword";
@ClassRule
public static LibaioContextCheck libaioContextRule = new LibaioContextCheck();
// There is a verification about thread leakages. We only fail a single thread when this happens
private static Set<Thread> alreadyFailedThread = new HashSet<>();
protected void clearServers() {
servers.clear();
}
private final Collection<ActiveMQServer> servers = new ArrayList<>();
private String testDir;
@Rule
public TemporaryFolder temporaryFolder;
@Rule
// This Custom rule will remove any files under ./target/tmp
// including anything created previously by TemporaryFolder
public RemoveFolder folder = new RemoveFolder(TARGET_TMP);
public ServerTestBase() {
File parent = new File(TARGET_TMP);
parent.mkdirs();
File subParent = new File(parent, this.getClass().getSimpleName());
subParent.mkdirs();
temporaryFolder = new TemporaryFolder(subParent);
}
protected <T> T serialClone(Object object) throws Exception {
logger.debug("object::{}", object);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream obOut = new ObjectOutputStream(bout);
obOut.writeObject(object);
ByteArrayInputStream binput = new ByteArrayInputStream(bout.toByteArray());
ObjectInputStream obinp = new ObjectInputStream(binput);
return (T) obinp.readObject();
}
@After
public void tearDown() throws Exception {
synchronized (servers) {
for (ActiveMQServer server : servers) {
if (server == null) {
continue;
}
// disable scaledown on tearDown, otherwise it takes a lot of time
try {
((PrimaryOnlyActivation) server.getActivation()).getPrimaryOnlyPolicy().getScaleDownPolicy().setEnabled(false);
} catch (Throwable ignored) {
// don't care about anything here
// if can't find activation, primaryPolicy or no PrimaryOnlyActivation... don't care!!!
// all I care is f you have scaleDownPolicy, it should be set to false at this point
}
try {
final ClusterManager clusterManager = server.getClusterManager();
if (clusterManager != null) {
for (ClusterConnection cc : clusterManager.getClusterConnections()) {
stopComponent(cc);
}
}
} catch (Exception e) {
// no-op
}
stopComponentOutputExceptions(server);
}
clearServers();
}
List<Exception> exceptions;
try {
exceptions = checkCsfStopped();
} finally {
cleanupPools();
}
InVMConnector.resetThreadPool();
//clean up pools before failing
if (!exceptions.isEmpty()) {
for (Exception exception : exceptions) {
exception.printStackTrace(System.out);
}
System.out.println(threadDump("Thread dump with reconnects happening"));
}
Map<Thread, StackTraceElement[]> threadMap = Thread.getAllStackTraces();
for (Map.Entry<Thread, StackTraceElement[]> entry : threadMap.entrySet()) {
Thread thread = entry.getKey();
StackTraceElement[] stack = entry.getValue();
for (StackTraceElement stackTraceElement : stack) {
if (stackTraceElement.getMethodName().contains("getConnectionWithRetry") && !alreadyFailedThread.contains(thread)) {
alreadyFailedThread.add(thread);
System.out.println(threadDump(this.getName() + " has left threads running. Look at thread " +
thread.getName() +
" id = " +
thread.getId() +
" has running locators on test " +
this.getName() +
" on this following dump"));
fail("test '" + getName() + "' left serverlocator running, this could effect other tests");
} else if (stackTraceElement.getMethodName().contains("BroadcastGroupImpl.run") && !alreadyFailedThread.contains(thread)) {
alreadyFailedThread.add(thread);
System.out.println(threadDump(this.getName() + " has left threads running. Look at thread " +
thread.getName() +
" id = " +
thread.getId() +
" is still broadcasting " +
this.getName() +
" on this following dump"));
fail("test left broadcastgroupimpl running, this could effect other tests");
}
}
}
if (Thread.currentThread().getContextClassLoader() == null) {
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
fail("Thread Context ClassLoader was set to null at some point before this test. We will set to this.getClass().getClassLoader(), but you are supposed to fix your tests");
}
checkFilesUsage();
if (InVMRegistry.instance.size() > 0) {
fail("InVMREgistry size > 0");
}
}
@Before
public void setupTestDir() {
testDir = temporaryFolder.getRoot().getAbsolutePath();
}
@Before
public void setUp() throws Exception {
clearDataRecreateServerDirs();
OperationContextImpl.clearContext();
InVMRegistry.instance.clear();
}
protected String getName() {
return name.getMethodName();
}
protected Configuration createDefaultInVMConfig() throws Exception {
return createDefaultConfig(0, false);
}
protected Configuration createDefaultConfig(final int serverID, final boolean netty) throws Exception {
ConfigurationImpl configuration = createBasicConfig(serverID).setJMXManagementEnabled(false).addAcceptorConfiguration(new TransportConfiguration(INVM_ACCEPTOR_FACTORY, generateInVMParams(serverID), "invm"));
if (netty) {
configuration.addAcceptorConfiguration(new TransportConfiguration(NETTY_ACCEPTOR_FACTORY, new HashMap<String, Object>(), "netty", new HashMap<String, Object>()));
} else {
// if we're in-vm it's a waste to resolve protocols since they'll never be used
configuration.setResolveProtocols(false);
}
return configuration;
}
/**
* @param serverID
* @return
* @throws Exception
*/
protected ConfigurationImpl createBasicConfig(final int serverID) {
ConfigurationImpl configuration = new ConfigurationImpl().setSecurityEnabled(false).setJournalMinFiles(2).setJournalFileSize(100 * 1024).setJournalType(getDefaultJournalType()).setJournalDirectory(getJournalDir(serverID, false)).setBindingsDirectory(getBindingsDir(serverID, false)).setPagingDirectory(getPageDir(serverID, false)).setLargeMessagesDirectory(getLargeMessagesDir(serverID, false)).setJournalCompactMinFiles(0).setJournalCompactPercentage(0).setClusterPassword(CLUSTER_PASSWORD).setJournalDatasync(false);
// When it comes to the testsuite, we don't need any batching, I will leave some minimal batching to exercise the codebase
configuration.setJournalBufferTimeout_AIO(100).setJournalBufferTimeout_NIO(100);
return configuration;
}
private boolean derbyDropped = false;
protected void dropDerby() throws Exception {
DBSupportUtil.dropDerbyDatabase(getJDBCUser(), getJDBCPassword(), getEmbeddedDataBaseName());
}
protected void shutdownDerby() throws SQLException {
DBSupportUtil.shutdownDerby(getJDBCUser(), getJDBCPassword());
}
protected DatabaseStorageConfiguration createDefaultDatabaseStorageConfiguration() {
DatabaseStorageConfiguration dbStorageConfiguration = new DatabaseStorageConfiguration();
String connectionURI = getTestJDBCConnectionUrl();
/** The connectionURI could be passed into the testsuite as a system property (say you are testing against Oracle).
* So, we only schedule the drop on Derby if we are using a derby memory database */
if (connectionURI.contains("derby") && connectionURI.contains("memory") && !derbyDropped) {
// some tests will reinitialize the server and call this method more than one time
// and we should only schedule one task
derbyDropped = true;
runAfterEx(this::dropDerby);
runAfterEx(this::shutdownDerby);
}
dbStorageConfiguration.setJdbcConnectionUrl(connectionURI);
dbStorageConfiguration.setBindingsTableName("BINDINGS");
dbStorageConfiguration.setMessageTableName("MESSAGE");
dbStorageConfiguration.setLargeMessageTableName("LARGE_MESSAGE");
dbStorageConfiguration.setPageStoreTableName("PAGE_STORE");
dbStorageConfiguration.setJdbcPassword(getJDBCPassword());
dbStorageConfiguration.setJdbcUser(getJDBCUser());
dbStorageConfiguration.setJdbcDriverClassName(getJDBCClassName());
dbStorageConfiguration.setJdbcLockAcquisitionTimeoutMillis(getJdbcLockAcquisitionTimeoutMillis());
dbStorageConfiguration.setJdbcLockExpirationMillis(getJdbcLockExpirationMillis());
dbStorageConfiguration.setJdbcLockRenewPeriodMillis(getJdbcLockRenewPeriodMillis());
dbStorageConfiguration.setJdbcNetworkTimeout(-1);
dbStorageConfiguration.setJdbcAllowedTimeDiff(250L);
return dbStorageConfiguration;
}
protected long getJdbcLockAcquisitionTimeoutMillis() {
return Long.getLong("jdbc.lock.acquisition", ActiveMQDefaultConfiguration.getDefaultJdbcLockAcquisitionTimeoutMillis());
}
protected long getJdbcLockExpirationMillis() {
return Long.getLong("jdbc.lock.expiration", 4_000);
}
protected long getJdbcLockRenewPeriodMillis() {
return Long.getLong("jdbc.lock.renew", 200);
}
protected Map<String, Object> generateInVMParams(final int node) {
Map<String, Object> params = new HashMap<>();
params.put(org.apache.activemq.artemis.core.remoting.impl.invm.TransportConstants.SERVER_ID_PROP_NAME, node);
return params;
}
public static JournalType getDefaultJournalType() {
if (AIOSequentialFileFactory.isSupported()) {
return JournalType.ASYNCIO;
} else {
return JournalType.NIO;
}
}
public static String threadDump(final String msg) {
return ThreadDumpUtil.threadDump(msg);
}
/**
* @return the testDir
*/
protected final String getTestDir() {
return testDir;
}
protected String getEmbeddedDataBaseName() {
return "memory:" + getTestDir();
}
protected String getTestJDBCConnectionUrl() {
return System.getProperty("jdbc.connection.url", "jdbc:derby:" + getEmbeddedDataBaseName() + ";create=true");
}
protected String getJDBCClassName() {
return System.getProperty("jdbc.driver.class", "org.apache.derby.jdbc.EmbeddedDriver");
}
protected String getJDBCUser() {
return System.getProperty("jdbc.user", null);
}
protected String getJDBCPassword() {
return System.getProperty("jdbc.password", null);
}
protected final File getTestDirfile() {
return new File(testDir);
}
protected final void clearDataRecreateServerDirs() {
clearDataRecreateServerDirs(0, false);
}
protected final void clearDataRecreateServerDirs(int index, boolean backup) {
clearDataRecreateServerDirs(getTestDir(), index, backup);
}
protected void clearDataRecreateServerDirs(final String testDir1, int index, boolean backup) {
// Need to delete the root
File file = new File(testDir1);
deleteDirectory(file);
file.mkdirs();
recreateDataDirectories(testDir1, index, backup);
}
protected void recreateDataDirectories(String testDir1, int index, boolean backup) {
recreateDirectory(getJournalDir(testDir1, index, backup));
recreateDirectory(getBindingsDir(testDir1, index, backup));
recreateDirectory(getPageDir(testDir1, index, backup));
recreateDirectory(getLargeMessagesDir(testDir1, index, backup));
recreateDirectory(getClientLargeMessagesDir(testDir1));
recreateDirectory(getTemporaryDir(testDir1));
}
/**
* @return the journalDir
*/
public String getJournalDir() {
return getJournalDir(0, false);
}
protected static String getJournalDir(final String testDir1) {
return testDir1 + "/journal";
}
public String getJournalDir(final int index, final boolean backup) {
return getJournalDir(getTestDir(), index, backup);
}
public static String getJournalDir(final String testDir, final int index, final boolean backup) {
return getJournalDir(testDir) + directoryNameSuffix(index, backup);
}
/**
* @return the bindingsDir
*/
protected String getBindingsDir() {
return getBindingsDir(0, false);
}
/**
* @return the bindingsDir
*/
protected static String getBindingsDir(final String testDir1) {
return testDir1 + "/bindings";
}
/**
* @return the bindingsDir
*/
protected String getBindingsDir(final int index, final boolean backup) {
return getBindingsDir(getTestDir(), index, backup);
}
public static String getBindingsDir(final String testDir, final int index, final boolean backup) {
return getBindingsDir(testDir) + directoryNameSuffix(index, backup);
}
/**
* @return the pageDir
*/
protected String getPageDir() {
return getPageDir(0, false);
}
protected File getPageDirFile() {
return new File(getPageDir());
}
/**
* @return the pageDir
*/
protected static String getPageDir(final String testDir1) {
return testDir1 + "/page";
}
protected String getPageDir(final int index, final boolean backup) {
return getPageDir(getTestDir(), index, backup);
}
public static String getPageDir(final String testDir, final int index, final boolean backup) {
return getPageDir(testDir) + directoryNameSuffix(index, backup);
}
/**
* @return the largeMessagesDir
*/
protected String getLargeMessagesDir() {
return getLargeMessagesDir(0, false);
}
/**
* @return the largeMessagesDir
*/
protected static String getLargeMessagesDir(final String testDir1) {
return testDir1 + "/large-msg";
}
protected String getLargeMessagesDir(final int index, final boolean backup) {
return getLargeMessagesDir(getTestDir(), index, backup);
}
public static String getLargeMessagesDir(final String testDir, final int index, final boolean backup) {
return getLargeMessagesDir(testDir) + directoryNameSuffix(index, backup);
}
private static String directoryNameSuffix(int index, boolean backup) {
if (index == -1)
return "";
return index + "-" + (backup ? "B" : "L");
}
/**
* @return the clientLargeMessagesDir
*/
protected String getClientLargeMessagesDir(final String testDir1) {
return testDir1 + "/client-large-msg";
}
/**
* @return the temporaryDir
*/
protected final String getTemporaryDir() {
return getTemporaryDir(getTestDir());
}
/**
* @return the temporaryDir
*/
protected String getTemporaryDir(final String testDir1) {
return testDir1 + "/temp";
}
protected final ActiveMQServer createServer(final boolean realFiles,
final Configuration configuration,
final int pageSize,
final long maxAddressSize,
final int maxReadMessages,
final int maxReadBytes) {
return createServer(realFiles, configuration, pageSize, maxAddressSize, maxReadMessages, maxReadBytes, (Map<String, AddressSettings>) null);
}
protected final ActiveMQServer createServer(final boolean realFiles,
final Configuration configuration,
final int pageSize,
final long maxAddressSize,
final Map<String, AddressSettings> settings) {
return createServer(realFiles, configuration, pageSize, maxAddressSize, null, null, settings);
}
protected final ActiveMQServer createServer(final boolean realFiles,
final Configuration configuration,
final int pageSize,
final long maxAddressSize,
final Integer maxReadPageMessages,
final Integer maxReadPageBytes,
final Map<String, AddressSettings> settings) {
return createServer(realFiles, configuration, pageSize, maxAddressSize, maxReadPageMessages, maxReadPageBytes, null, null, null, settings);
}
protected final ActiveMQServer createServer(final boolean realFiles,
final Configuration configuration,
final int pageSize,
final long maxAddressSize,
final Integer maxReadPageMessages,
final Integer maxReadPageBytes,
final Long pageLimitBytes,
final Long pageLimitMessages,
final String pageLimitPolicy,
final Map<String, AddressSettings> settings) {
ActiveMQServer server = addServer(ActiveMQServers.newActiveMQServer(configuration, realFiles));
if (settings != null) {
for (Map.Entry<String, AddressSettings> setting : settings.entrySet()) {
if (maxReadPageBytes != null) {
setting.getValue().setMaxReadPageBytes(maxReadPageBytes.intValue());
}
if (maxReadPageMessages != null) {
setting.getValue().setMaxReadPageMessages(maxReadPageMessages.intValue());
}
if (pageLimitBytes != null) {
setting.getValue().setPageLimitBytes(pageLimitBytes);
}
if (pageLimitMessages != null) {
setting.getValue().setPageLimitMessages(pageLimitMessages);
}
if (pageLimitPolicy != null) {
setting.getValue().setPageFullMessagePolicy(PageFullMessagePolicy.valueOf(pageLimitPolicy));
}
server.getAddressSettingsRepository().addMatch(setting.getKey(), setting.getValue());
}
}
AddressSettings defaultSetting = new AddressSettings().setPageSizeBytes(pageSize).setMaxSizeBytes(maxAddressSize).setAddressFullMessagePolicy(AddressFullMessagePolicy.PAGE);
if (maxReadPageBytes != null) {
defaultSetting.setMaxReadPageBytes(maxReadPageBytes.intValue());
}
if (maxReadPageMessages != null) {
defaultSetting.setMaxReadPageMessages(maxReadPageMessages.intValue());
}
if (pageLimitBytes != null) {
defaultSetting.setPageLimitBytes(pageLimitBytes);
}
if (pageLimitMessages != null) {
defaultSetting.setPageLimitMessages(pageLimitMessages);
}
if (pageLimitPolicy != null) {
defaultSetting.setPageFullMessagePolicy(PageFullMessagePolicy.valueOf(pageLimitPolicy));
}
server.getAddressSettingsRepository().addMatch("#", defaultSetting);
applySettings(server, configuration, pageSize, maxAddressSize, maxReadPageMessages, maxReadPageBytes, settings);
return server;
}
protected void applySettings(ActiveMQServer server,
final Configuration configuration,
final int pageSize,
final long maxAddressSize,
final Integer maxReadPageMessages,
final Integer maxReadPageBytes,
final Map<String, AddressSettings> settings) {
}
protected final ActiveMQServer createServer(final boolean realFiles) throws Exception {
return createServer(realFiles, createDefaultConfig(0, false), AddressSettings.DEFAULT_PAGE_SIZE, AddressSettings.DEFAULT_MAX_SIZE_BYTES, -1, -1);
}
private List<Exception> checkCsfStopped() throws Exception {
if (!Wait.waitFor(ClientSessionFactoryImpl.CLOSE_RUNNABLES::isEmpty, 5_000)) {
List<ClientSessionFactoryImpl.CloseRunnable> closeRunnables = new ArrayList<>(ClientSessionFactoryImpl.CLOSE_RUNNABLES);
ArrayList<Exception> exceptions = new ArrayList<>();
if (!closeRunnables.isEmpty()) {
for (ClientSessionFactoryImpl.CloseRunnable closeRunnable : closeRunnables) {
if (closeRunnable != null) {
exceptions.add(closeRunnable.stop().createTrace);
}
}
}
return exceptions;
}
return Collections.emptyList();
}
private void checkFilesUsage() throws Exception {
int invmSize = InVMRegistry.instance.size();
if (invmSize > 0) {
InVMRegistry.instance.clear();
logger.info(threadDump("Thread dump"));
fail("invm registry still had acceptors registered");
}
}
private void cleanupPools() {
OperationContextImpl.clearContext();
// We shutdown the global pools to give a better isolation between tests
try {
ServerLocatorImpl.clearThreadPools();
} catch (Throwable e) {
logger.info(threadDump(e.getMessage()));
System.err.println(threadDump(e.getMessage()));
}
try {
NettyConnector.clearThreadPools();
} catch (Exception e) {
logger.info(threadDump(e.getMessage()));
System.err.println(threadDump(e.getMessage()));
}
}
protected static final void recreateDirectory(final String directory) {
File file = new File(directory);
deleteDirectory(file);
file.mkdirs();
}
protected static final boolean deleteDirectory(final File directory) {
return FileUtil.deleteDirectory(directory);
}
protected static final void stopComponent(ActiveMQComponent component) {
if (component == null)
return;
try {
component.stop();
} catch (Exception e) {
// no-op
}
}
protected static final void stopComponentOutputExceptions(ActiveMQComponent component) {
if (component == null)
return;
try {
component.stop();
} catch (Exception e) {
System.err.println("Exception closing " + component);
e.printStackTrace();
}
}
protected final ActiveMQServer addServer(final ActiveMQServer server) {
if (server != null) {
synchronized (servers) {
servers.add(server);
}
}
return server;
}
}

View File

@ -17,6 +17,7 @@
package org.apache.activemq.artemis.tests.util;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
@ -383,7 +384,7 @@ public class SimpleStringTest extends Assert {
x[i].start();
}
ActiveMQTestBase.waitForLatch(latch);
assertTrue("Latch has got to return within a minute", latch.await(1, TimeUnit.MINUTES));
start.countDown();
for (T t : x) {

View File

@ -36,6 +36,12 @@
<artifactId>junit</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-artemis-native</artifactId>
<version>${activemq-artemis-native-version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>

View File

@ -0,0 +1,107 @@
/*
* 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.rules;
import static org.junit.Assert.fail;
import java.lang.invoke.MethodHandles;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.activemq.artemis.nativo.jlibaio.LibaioContext;
import org.apache.activemq.artemis.utils.Wait;
import org.junit.Assert;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This is useful to make sure you won't have LibaioContext between tests
*/
public class LibaioContextCheck extends TestWatcher {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private static final int INTERVAL = 100;
private static final int WAIT = 20_000;
private static String previouslyFailedTotalMaxIoMessage;
public LibaioContextCheck() {
}
@Override
protected void starting(Description description) {
checkLibaioBefore(description.getClassName());
}
@Override
protected void finished(Description description) {
checkLibaioAfter(description.getClassName());
}
public static void checkLibaioBefore(String testClassName) {
if (previouslyFailedTotalMaxIoMessage != null) {
// Fail immediately if this is already set.
fail(previouslyFailedTotalMaxIoMessage);
}
long totalMaxIO = LibaioContext.getTotalMaxIO();
if (totalMaxIO != 0) {
failDueToLibaioContextCheck("LibaioContext TotalMaxIO > 0 leak detected BEFORE class %s, TotalMaxIO=%s. Check prior test classes for issue (not possible to be sure of which here).", testClassName, totalMaxIO);
}
}
public static void checkLibaioAfter(String testClassName) {
if (previouslyFailedTotalMaxIoMessage != null) {
// Test class was already failed if this is set, nothing to do here.
return;
}
try {
if (!waitForLibaioContextTotalMaxIo(testClassName)) {
final long totalMaxIO = LibaioContext.getTotalMaxIO();
failDueToLibaioContextCheck("LibaioContext TotalMaxIO > 0 leak detected AFTER class %s, TotalMaxIO=%s.", testClassName, totalMaxIO);
}
} catch (Exception e) {
fail("Exception while checking Libaio after tests in class: " + testClassName);
}
}
private static boolean waitForLibaioContextTotalMaxIo(String testClassName) {
AtomicBoolean firstCheck = new AtomicBoolean();
return Wait.waitFor(() -> {
final boolean totalIsZero = LibaioContext.getTotalMaxIO() == 0;
if (!totalIsZero && firstCheck.compareAndSet(false, true)) {
logger.info("Waiting for LibaioContext TotalMaxIO to become 0 after class {}", testClassName);
}
return totalIsZero;
}, WAIT, INTERVAL);
}
private static void failDueToLibaioContextCheck(String currentFailureMessageFormat, String testClassName, long totalMaxIO) {
// Set message to immediately-fail subsequent tests with
previouslyFailedTotalMaxIoMessage = String.format("Aborting, LibaioContext TotalMaxIO > 0 issue previously detected by test class %s, see its output.", testClassName);
// Now fail this run
String message = String.format(currentFailureMessageFormat, testClassName, totalMaxIO);
logger.error(message);
Assert.fail(message);
}
}

View File

@ -14,17 +14,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.tests.util;
package org.apache.activemq.artemis.tests.rules;
import java.io.File;
import org.apache.activemq.artemis.utils.FileUtil;
import org.junit.Assert;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
/**
* This is useful to make sure you won't have leaking threads between tests
* This is useful to make sure you won't have leaking directories between tests
*/
public class NoFilesBehind extends TestWatcher {
@ -45,52 +44,19 @@ public class NoFilesBehind extends TestWatcher {
return null;
}
/**
* Override to set up your specific external resource.
*
* @throws if setup fails (which will disable {@code after}
*/
@Override
protected void starting(Description description) {
// do nothing
File leaked = checkFiles();
if (leaked != null) {
Assert.fail("A previous test left a folder around:: " + leaked.getAbsolutePath());
}
}
@Override
protected void failed(Throwable e, Description description) {
}
@Override
protected void succeeded(Description description) {
}
/**
* Override to tear down your specific external resource.
*/
@Override
protected void finished(Description description) {
File leaked = checkFiles();
if (leaked != null) {
try {
Assert.fail(leaked.getAbsolutePath() + " is being left behind");
} finally {
try {
FileUtil.deleteDirectory(leaked);
} catch (Throwable almostIgnored) {
// nothing we can do about it.. but we will log a stack trace for debugging
almostIgnored.printStackTrace();
}
}
Assert.fail(leaked.getAbsolutePath() + "A directory is being left behind: " + leaked.getAbsolutePath());
}
}
}

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.tests.util;
package org.apache.activemq.artemis.tests.rules;
import java.io.BufferedReader;
import java.io.InputStreamReader;
@ -26,38 +26,22 @@ import java.util.ArrayList;
import java.util.List;
import com.sun.management.UnixOperatingSystemMXBean;
import org.apache.activemq.artemis.nativo.jlibaio.LibaioContext;
import org.apache.activemq.artemis.utils.Wait;
import org.junit.Assert;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
/**
* This is useful to make sure you won't have leaking threads between tests
* This is useful to make sure you won't have leaking process files between tests
*/
public class NoProcessFilesBehind extends TestWatcher {
private long maxFiles;
public NoProcessFilesBehind(long maxFiles) {
this(-1, maxFiles);
}
/**
* -1 on maxVariance means no check
*/
public NoProcessFilesBehind(long variance, long maxFiles) {
this.maxFiles = maxFiles;
if (variance < 0) {
maxvariance = null;
} else {
this.maxvariance = variance;
}
}
long fdBefore;
long maxFiles;
Long maxvariance;
static OperatingSystemMXBean os = ManagementFactory.getOperatingSystemMXBean();
public static long getOpenFD() {
@ -68,14 +52,6 @@ public class NoProcessFilesBehind extends TestWatcher {
}
}
@Override
protected void starting(Description description) {
LibaioContext.isLoaded();
if (maxvariance != null) {
fdBefore = getOpenFD();
}
}
public static List<String> getOpenFiles(boolean filtered) {
ArrayList<String> openFiles = new ArrayList<>();
@ -97,6 +73,7 @@ public class NoProcessFilesBehind extends TestWatcher {
return openFiles;
}
private static int getProcessId() throws ReflectiveOperationException {
java.lang.management.RuntimeMXBean runtime = java.lang.management.ManagementFactory.getRuntimeMXBean();
java.lang.reflect.Field jvmField = runtime.getClass().getDeclaredField("jvm");
@ -107,37 +84,12 @@ public class NoProcessFilesBehind extends TestWatcher {
return (Integer) getProcessIdMethod.invoke(jvm);
}
@Override
protected void failed(Throwable e, Description description) {
}
@Override
protected void succeeded(Description description) {
}
/**
* Override to tear down your specific external resource.
*/
@Override
protected void finished(Description description) {
Wait.waitFor(() -> getOpenFD() < maxFiles, 5000, 0);
if (maxvariance != null) {
long currentVariance = getOpenFD() - fdBefore;
if (currentVariance > 0 && currentVariance > maxvariance) {
Assert.fail("too many files were opened files on this test::" + getOpenList());
}
}
if (!Wait.waitFor(() -> getOpenFD() < maxFiles, 5000, 0)) {
if (!Wait.waitFor(() -> getOpenFD() < maxFiles, 10000, 0)) {
String fileList = getOpenList();
Assert.fail("Too many files open (" + getOpenFD() + ">" + maxFiles + "). A possible list: " + fileList);
}
}
private String getOpenList() {
@ -152,5 +104,4 @@ public class NoProcessFilesBehind extends TestWatcher {
}
return stringWriter.toString();
}
}

View File

@ -0,0 +1,169 @@
/*
* 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.util;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.List;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import org.apache.activemq.artemis.tests.rules.NoFilesBehind;
import org.apache.activemq.artemis.tests.rules.NoProcessFilesBehind;
import org.apache.activemq.artemis.utils.CleanupSystemPropertiesRule;
import org.apache.activemq.artemis.utils.ThreadLeakCheckRule;
import org.junit.After;
import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.rules.TestName;
import org.junit.rules.TestRule;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Parent class with basic utilities around creating unit etc test classes.
*/
public abstract class ArtemisTestCase extends Assert {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private static String testClassName = "not-yet-set";
/** This will make sure threads are not leaking between tests */
@ClassRule
public static ThreadLeakCheckRule leakCheckRule = new ThreadLeakCheckRule();
@ClassRule
public static NoProcessFilesBehind noProcessFilesBehind = new NoProcessFilesBehind(1000);
@ClassRule
public static TestRule classWatcher = new TestWatcher() {
@Override
protected void starting(Description description) {
testClassName = description.getClassName();
}
};
/** We should not under any circumstance create data outside of ./target
* if you have a test failing because because of this rule for any reason,
* even if you use afterClass events, move the test to ./target and always cleanup after
* your data even under ./target.
* Do not try to disable this rule! Fix your test! */
@Rule
public NoFilesBehind noFilesBehind = new NoFilesBehind("data", "null");
/** This will cleanup any system property changed inside tests */
@Rule
public CleanupSystemPropertiesRule propertiesRule = new CleanupSystemPropertiesRule();
@Rule
public TestName name = new TestName();
@Rule
public TestRule watcher = new TestWatcher() {
@Override
protected void starting(Description description) {
logger.info("**** start #test {}() ***", description.getMethodName());
}
@Override
protected void finished(Description description) {
logger.info("**** end #test {}() ***", description.getMethodName());
}
};
public interface TestCompletionTask {
void run() throws Exception;
}
private List<TestCompletionTask> runAfter;
/**
* Use this method to cleanup your resources by passing a TestCleanupTask.
*
* Exceptions thrown from your tasks will just be logged and not passed as failures.
*
* @param completionTask A TestCleanupTask that will be passed, possibly from a lambda
*/
protected void runAfter(TestCompletionTask completionTask) {
Assert.assertNotNull(completionTask);
runAfterEx(() -> {
try {
completionTask.run();
} catch (Throwable e) {
logger.warn("Lambda {} is throwing an exception", completionTask.toString(), e);
}
});
}
/**
* Use this method to cleanup your resources and validating exceptional results by passing a TestCompletionTask.
*
* An exception thrown from a task will be thrown to JUnit. If more than one task is present, all tasks will be
* be executed, however only the exception of the first one will then be thrown the JUnit runner. All will be
* logged as they occur.
*
* @param completionTask A TestCompletionTask that will be passed, possibly from a lambda method
*/
protected synchronized void runAfterEx(TestCompletionTask completionTask) {
Assert.assertNotNull(completionTask);
if (runAfter == null) {
runAfter = new ArrayList<>();
}
runAfter.add(completionTask);
}
@After
public synchronized void runAfter() throws Throwable {
ArrayList<Throwable> throwables = new ArrayList<>();
List<TestCompletionTask> localRunAfter = runAfter;
runAfter = null;
if (localRunAfter != null) {
localRunAfter.forEach((r) -> {
try {
r.run();
} catch (Throwable e) {
logger.warn(e.getMessage(), e);
throwables.add(e);
}
});
}
if (!throwables.isEmpty()) {
throw throwables.get(0);
}
}
public static void forceGC() {
ThreadLeakCheckRule.forceGC();
}
public MBeanServer createMBeanServer() {
MBeanServer mBeanServer = MBeanServerFactory.createMBeanServer();
runAfter(() -> MBeanServerFactory.releaseMBeanServer(mBeanServer));
return mBeanServer;
}
public static String getTestClassName() {
return testClassName;
}
}

View File

@ -0,0 +1,64 @@
/*
* 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.util;
import java.lang.invoke.MethodHandles;
import java.sql.DriverManager;
import java.sql.SQLException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DBSupportUtil {
private static Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
public static final String EXPECTED_DERBY_DROP_STATE = "08006";
public static final String EXPECTED_DERBY_SHUTDOWN_STATE = "XJ015";
public static void dropDerbyDatabase(String user, String password, String databaseName) throws SQLException {
try {
if (user == null) {
DriverManager.getConnection("jdbc:derby:" + databaseName + ";drop=true");
} else {
DriverManager.getConnection("jdbc:derby:" + databaseName + ";drop=true", user, password);
}
} catch (SQLException sqlE) {
if (!sqlE.getSQLState().equals(EXPECTED_DERBY_DROP_STATE)) {
logger.warn("{} / {}", sqlE.getMessage(), sqlE.getSQLState());
throw sqlE;
} else {
logger.info("{} / {}", sqlE.getMessage(), sqlE.getSQLState());
}
}
}
public static void shutdownDerby(String user, String password) throws SQLException {
try {
if (user == null) {
DriverManager.getConnection("jdbc:derby:;shutdown=true;deregister=false");
} else {
DriverManager.getConnection("jdbc:derby:;shutdown=true;deregister=false", user, password);
}
} catch (SQLException sqlE) {
logger.debug("{} / {}", sqlE.getMessage(), sqlE.getSQLState());
if (!sqlE.getSQLState().equals(EXPECTED_DERBY_SHUTDOWN_STATE)) {
throw sqlE;
}
}
}
}

View File

@ -24,7 +24,7 @@
<artifactId>artemis-test-support</artifactId>
<packaging>jar</packaging>
<name>ActiveMQ Artemis Test Support</name>
<name>ActiveMQ Artemis System Test Support</name>
<properties>
<activemq.basedir>${project.basedir}/../..</activemq.basedir>
@ -120,7 +120,12 @@
<artifactId>junit</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-server</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-stomp-protocol</artifactId>
@ -128,12 +133,11 @@
<scope>provided</scope>
</dependency>
<!-- This should be the only dependency not at 'provided' scope, for now -->
<!-- This should be the only dependency not at 'provided' scope -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-server</artifactId>
<artifactId>artemis-unit-test-support</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
</dependency>
</dependencies>
</project>

View File

@ -19,7 +19,7 @@ package org.apache.activemq.artemis.core.paging.cursor.impl;
import org.apache.activemq.artemis.core.paging.cursor.PageCursorProvider;
public class PageCursorProviderAccessor {
public class PageCursorProviderTestAccessor {
public static void cleanup(PageCursorProvider provider) {
((PageCursorProviderImpl)provider).cleanup();

View File

@ -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.
*/
package org.apache.activemq.artemis.tests.rules;
import java.io.File;
import org.apache.activemq.artemis.utils.FileUtil;
import org.junit.rules.ExternalResource;
/**
* This will remove a folder on a tearDown *
*/
public class RemoveFolder extends ExternalResource {
private final String folderName;
public RemoveFolder(String folderName) {
this.folderName = folderName;
}
@Override
protected void after() {
FileUtil.deleteDirectory(new File(folderName));
}
}

View File

@ -16,8 +16,6 @@
*/
package org.apache.activemq.artemis.tests.util;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.naming.Context;
import javax.transaction.xa.XAException;
import javax.transaction.xa.Xid;
@ -38,7 +36,6 @@ import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.lang.management.ManagementFactory;
import java.lang.ref.WeakReference;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
@ -136,19 +133,17 @@ import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
import org.apache.activemq.artemis.core.settings.impl.PageFullMessagePolicy;
import org.apache.activemq.artemis.core.transaction.impl.XidImpl;
import org.apache.activemq.artemis.json.JsonObject;
import org.apache.activemq.artemis.nativo.jlibaio.LibaioContext;
import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
import org.apache.activemq.artemis.spi.core.security.jaas.InVMLoginModule;
import org.apache.activemq.artemis.tests.rules.LibaioContextCheck;
import org.apache.activemq.artemis.tests.rules.RemoveFolder;
import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
import org.apache.activemq.artemis.utils.CleanupSystemPropertiesRule;
import org.apache.activemq.artemis.utils.Env;
import org.apache.activemq.artemis.utils.FileUtil;
import org.apache.activemq.artemis.utils.PortCheckRule;
import org.apache.activemq.artemis.utils.RandomUtil;
import org.apache.activemq.artemis.utils.RunnableEx;
import org.apache.activemq.artemis.utils.ThreadDumpUtil;
import org.apache.activemq.artemis.utils.ThreadLeakCheckRule;
import org.apache.activemq.artemis.utils.UUIDGenerator;
import org.apache.activemq.artemis.utils.Wait;
import org.apache.activemq.artemis.utils.actors.OrderedExecutorFactory;
@ -157,22 +152,16 @@ import org.slf4j.LoggerFactory;
import java.lang.invoke.MethodHandles;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.rules.TemporaryFolder;
import org.junit.rules.TestName;
import org.junit.rules.TestRule;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
/**
* Base class with basic utilities on starting up a basic server
*/
public abstract class ActiveMQTestBase extends Assert {
public abstract class ActiveMQTestBase extends ArtemisTestCase {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@ -180,25 +169,6 @@ public abstract class ActiveMQTestBase extends Assert {
Env.setTestEnv(true);
}
/** This will make sure threads are not leaking between tests */
@ClassRule
public static ThreadLeakCheckRule leakCheckRule = new ThreadLeakCheckRule();
@ClassRule
public static NoProcessFilesBehind noProcessFilesBehind = new NoProcessFilesBehind(1000);
/** We should not under any circunstance create data outside of ./target
* if you have a test failing because because of this rule for any reason,
* even if you use afterClass events, move the test to ./target and always cleanup after
* your data even under ./target.
* Do not try to disable this rule! Fix your test! */
@Rule
public NoFilesBehind noFilesBehind = new NoFilesBehind("data", "null");
/** This will cleanup any system property changed inside tests */
@Rule
public CleanupSystemPropertiesRule propertiesRule = new CleanupSystemPropertiesRule();
@ClassRule
public static PortCheckRule portCheckRule = new PortCheckRule(61616);
@ -219,71 +189,12 @@ public abstract class ActiveMQTestBase extends Assert {
protected static final long WAIT_TIMEOUT = 30000;
private static String testClassName = "not-yet-set";
private static String previouslyFailedTotalMaxIoMessage;
@ClassRule
public static LibaioContextCheck libaioContextRule = new LibaioContextCheck();
// There is a verification about thread leakages. We only fail a single thread when this happens
private static Set<Thread> alreadyFailedThread = new HashSet<>();
private List<RunnableEx> runAfter;
/**
* Use this method to cleanup your resources by passing lambdas.
* Exceptions thrown from your lambdas will just be logged and not passed as failures.
* @param lambda A RunnableEX instance that will be passed possibly from a lambda method
*/
protected void runAfter(RunnableEx lambda) {
runAfterEx(() -> {
try {
lambda.run();
} catch (Throwable e) {
logger.warn("Lambda {} is throwing an exception", lambda.toString(), e);
}
});
}
/**
* Use this method to cleanup your resources and validating exceptional results by passing lambdas.
* Exceptions thrown from your lambdas will be sent straight to JUNIT.
* If more than one lambda threw an exception they will all be executed, however only the exception of the first one will
* sent to the junit runner.
* @param lambda A RunnableEX instance that will be passed possibly from a lambda method
*/
protected synchronized void runAfterEx(RunnableEx lambda) {
Assert.assertNotNull(lambda);
if (runAfter == null) {
runAfter = new ArrayList<>();
}
runAfter.add(lambda);
}
@After
public synchronized void runAfter() throws Throwable {
ArrayList<Throwable> throwables = new ArrayList<>();
List<RunnableEx> localRunAfter = runAfter;
runAfter = null;
if (localRunAfter != null) {
localRunAfter.forEach((r) -> {
try {
r.run();
} catch (Throwable e) {
logger.warn(e.getMessage(), e);
throwables.add(e);
}
});
}
if (!throwables.isEmpty()) {
throw throwables.get(0);
}
}
public MBeanServer createMBeanServer() {
MBeanServer mBeanServer = MBeanServerFactory.createMBeanServer();
runAfter(() -> MBeanServerFactory.releaseMBeanServer(mBeanServer));
return mBeanServer;
}
protected void clearServers() {
servers.clear();
}
@ -300,9 +211,6 @@ public abstract class ActiveMQTestBase extends Assert {
private String testDir;
private int sendMsgCount = 0;
@Rule
public TestName name = new TestName();
@Rule
public TemporaryFolder temporaryFolder;
@ -311,73 +219,6 @@ public abstract class ActiveMQTestBase extends Assert {
// including anything created previously by TemporaryFolder
public RemoveFolder folder = new RemoveFolder(TARGET_TMP);
@Rule
public TestRule watcher = new TestWatcher() {
@Override
protected void starting(Description description) {
logger.info("**** start #test {}() ***", description.getMethodName());
}
@Override
protected void finished(Description description) {
logger.info("**** end #test {}() ***", description.getMethodName());
}
};
@ClassRule
public static TestRule classWatcher = new TestWatcher() {
@Override
protected void starting(Description description) {
testClassName = description.getClassName();
}
};
// Static variable used by dropDerby
private static final String EXPECTED_DERBY_DROP_STATE = "08006";
// Static variable used by dropDerby
private static final String EXPECTED_DERBY_SHUTDOWN_STATE = "XJ015";
/** This method will be passed as a lambda into runAfter from createDefaultDatabaseStorageConfiguration */
protected void dropDerby() throws Exception {
String user = getJDBCUser();
String password = getJDBCPassword();
try {
if (user == null) {
DriverManager.getConnection("jdbc:derby:" + getEmbeddedDataBaseName() + ";drop=true");
} else {
DriverManager.getConnection("jdbc:derby:" + getEmbeddedDataBaseName() + ";drop=true", user, password);
}
} catch (SQLException sqlE) {
if (!sqlE.getSQLState().equals(EXPECTED_DERBY_DROP_STATE)) {
logger.warn("{} / {}", sqlE.getMessage(), sqlE.getSQLState());
throw sqlE;
} else {
logger.info("{} / {}", sqlE.getMessage(), sqlE.getSQLState());
}
}
}
/** Some tests may be using file database as they share the database with a process.
* these tests will call shutdown Derby only */
protected void shutdownDerby() throws SQLException {
String user = getJDBCUser();
String password = getJDBCPassword();
try {
if (user == null) {
DriverManager.getConnection("jdbc:derby:;shutdown=true;deregister=false");
} else {
DriverManager.getConnection("jdbc:derby:;shutdown=true;deregister=false", user, password);
}
} catch (SQLException sqlE) {
logger.debug("{} / {}", sqlE.getMessage(), sqlE.getSQLState());
if (!sqlE.getSQLState().equals(EXPECTED_DERBY_SHUTDOWN_STATE)) {
throw sqlE;
}
}
}
static {
Random random = new Random();
DEFAULT_UDP_PORT = 6000 + random.nextInt(1000);
@ -527,11 +368,6 @@ public abstract class ActiveMQTestBase extends Assert {
}
}
/**
* @param str
* @param sub
* @return
*/
public static int countOccurrencesOf(String str, String sub) {
if (str == null || sub == null || str.length() == 0 || sub.length() == 0) {
return 0;
@ -617,11 +453,6 @@ public abstract class ActiveMQTestBase extends Assert {
return createBasicConfig(-1);
}
/**
* @param serverID
* @return
* @throws Exception
*/
protected ConfigurationImpl createBasicConfig(final int serverID) {
ConfigurationImpl configuration = new ConfigurationImpl().setSecurityEnabled(false).setJournalMinFiles(2).setJournalFileSize(100 * 1024).setJournalType(getDefaultJournalType()).setJournalDirectory(getJournalDir(serverID, false)).setBindingsDirectory(getBindingsDir(serverID, false)).setPagingDirectory(getPageDir(serverID, false)).setLargeMessagesDirectory(getLargeMessagesDir(serverID, false)).setJournalCompactMinFiles(0).setJournalCompactPercentage(0).setClusterPassword(CLUSTER_PASSWORD).setJournalDatasync(false);
@ -637,6 +468,14 @@ public abstract class ActiveMQTestBase extends Assert {
private boolean derbyDropped = false;
protected void dropDerby() throws Exception {
DBSupportUtil.dropDerbyDatabase(getJDBCUser(), getJDBCPassword(), getEmbeddedDataBaseName());
}
protected void shutdownDerby() throws SQLException {
DBSupportUtil.shutdownDerby(getJDBCUser(), getJDBCPassword());
}
protected DatabaseStorageConfiguration createDefaultDatabaseStorageConfiguration() {
DatabaseStorageConfiguration dbStorageConfiguration = new DatabaseStorageConfiguration();
String connectionURI = getTestJDBCConnectionUrl();
@ -749,10 +588,6 @@ public abstract class ActiveMQTestBase extends Assert {
}
}
public static void forceGC() {
ThreadLeakCheckRule.forceGC();
}
/**
* Verifies whether weak references are released after a few GCs.
*
@ -1839,19 +1674,10 @@ public abstract class ActiveMQTestBase extends Assert {
return message;
}
/**
* @param i
* @param message
* @throws Exception
*/
protected void setBody(final int i, final ClientMessage message) {
message.getBodyBuffer().writeString("message" + i);
}
/**
* @param i
* @param message
*/
protected void assertMessageBody(final int i, final ClientMessage message) {
Assert.assertEquals(message.toString(), "message" + i, message.getBodyBuffer().readString());
}
@ -1902,12 +1728,8 @@ public abstract class ActiveMQTestBase extends Assert {
}
/**
* Reads a journal system and returns a Map<Integer,AtomicInteger> of recordTypes and the number of records per type,
* Reads a journal system and returns a Pair of List of RecordInfo,
* independent of being deleted or not
*
* @param config
* @return
* @throws Exception
*/
protected Pair<List<RecordInfo>, List<PreparedTransactionInfo>> loadMessageJournal(Configuration config) throws Exception {
JournalImpl messagesJournal = null;
@ -1935,7 +1757,7 @@ public abstract class ActiveMQTestBase extends Assert {
}
/**
* Reads a journal system and returns a Map<Integer,AtomicInteger> of recordTypes and the number of records per type,
* Reads a journal system and returns a {@literal Map<Integer,AtomicInteger>} of recordTypes and the number of records per type,
* independent of being deleted or not
*
* @param config
@ -1988,7 +1810,7 @@ public abstract class ActiveMQTestBase extends Assert {
* This method will load a journal and count the living records
*
* @param config
* @param messageJournal if true -> MessageJournal, false -> BindingsJournal
* @param messageJournal if true counts MessageJournal, if false counts BindingsJournal
* @return
* @throws Exception
*/
@ -2203,10 +2025,7 @@ public abstract class ActiveMQTestBase extends Assert {
return exceptions;
}
return Collections.EMPTY_LIST;
return Collections.emptyList();
}
private void assertAllClientProducersAreClosed() {
@ -2230,43 +2049,6 @@ public abstract class ActiveMQTestBase extends Assert {
}
}
@BeforeClass
public static void checkLibaioBeforeClass() throws Throwable {
if (previouslyFailedTotalMaxIoMessage != null) {
// Fail immediately if this is already set.
fail(previouslyFailedTotalMaxIoMessage);
}
long totalMaxIO = LibaioContext.getTotalMaxIO();
if (totalMaxIO != 0) {
failDueToLibaioContextCheck("LibaioContext TotalMaxIO > 0 leak detected BEFORE class %s, TotalMaxIO=%s. Check prior test classes for issue (not possible to be sure of which here).", totalMaxIO);
}
}
@AfterClass
public static void checkLibaioAfterClass() throws Throwable {
if (previouslyFailedTotalMaxIoMessage != null) {
// Test class was already failed if this is set, nothing to do here.
return;
}
if (!Wait.waitFor(() -> LibaioContext.getTotalMaxIO() == 0)) {
long totalMaxIO = LibaioContext.getTotalMaxIO();
failDueToLibaioContextCheck("LibaioContext TotalMaxIO > 0 leak detected AFTER class %s, TotalMaxIO=%s.", totalMaxIO);
}
}
private static void failDueToLibaioContextCheck(String currentFailureMessageFormat, long totalMaxIO) {
// Set message to immediately-fail subsequent tests with
previouslyFailedTotalMaxIoMessage = String.format("Aborting, LibaioContext TotalMaxIO > 0 issue previously detected by test class %s, see its output.", testClassName);
// Now fail this run
String message = String.format(currentFailureMessageFormat, testClassName, totalMaxIO);
logger.error(message);
Assert.fail(message);
}
private void checkFilesUsage() throws Exception {
int invmSize = InVMRegistry.instance.size();
if (invmSize > 0) {
@ -2482,7 +2264,7 @@ public abstract class ActiveMQTestBase extends Assert {
* This is because we don't want it closed in certain tests where we are issuing failures
*
* @param isNetty
* @return
* @return the locator
*/
public ServerLocator internalCreateNonHALocator(boolean isNetty) {
return isNetty ? ActiveMQClient.createServerLocatorWithoutHA(new TransportConfiguration(NETTY_CONNECTOR_FACTORY)) : ActiveMQClient.createServerLocatorWithoutHA(new TransportConfiguration(INVM_CONNECTOR_FACTORY));

View File

@ -83,8 +83,8 @@ import org.apache.activemq.artemis.core.paging.PagingStoreFactory;
import org.apache.activemq.artemis.core.paging.cursor.PageCursorProvider;
import org.apache.activemq.artemis.core.paging.cursor.PageIterator;
import org.apache.activemq.artemis.core.paging.cursor.PageSubscription;
import org.apache.activemq.artemis.core.paging.cursor.impl.PageCursorProviderAccessor;
import org.apache.activemq.artemis.core.paging.cursor.impl.PageCursorProviderImpl;
import org.apache.activemq.artemis.core.paging.cursor.impl.PageCursorProviderTestAccessor;
import org.apache.activemq.artemis.core.paging.cursor.impl.PagePositionImpl;
import org.apache.activemq.artemis.core.paging.impl.PagingStoreFactoryDatabase;
import org.apache.activemq.artemis.core.paging.impl.PagingStoreFactoryNIO;
@ -872,7 +872,7 @@ public class PagingTest extends ParameterDBTestBase {
Assert.assertEquals(10, queue.getPagingStore().getNumberOfPages());
PageCursorProviderAccessor.cleanup(queue.getPagingStore().getCursorProvider());
PageCursorProviderTestAccessor.cleanup(queue.getPagingStore().getCursorProvider());
Assert.assertEquals(9, queue.getPagingStore().getNumberOfPages());
@ -1000,7 +1000,7 @@ public class PagingTest extends ParameterDBTestBase {
session.commit();
consumer.close();
PageCursorProviderAccessor.cleanup(queue.getPagingStore().getCursorProvider());
PageCursorProviderTestAccessor.cleanup(queue.getPagingStore().getCursorProvider());
Wait.assertFalse(queue.getPagingStore()::isPaging, 5000, 100);
}
@ -1998,7 +1998,7 @@ public class PagingTest extends ParameterDBTestBase {
Wait.assertEquals(0, queue::getMessageCount);
PageCursorProviderAccessor.cleanup(queue.getPagingStore().getCursorProvider());
PageCursorProviderTestAccessor.cleanup(queue.getPagingStore().getCursorProvider());
waitForNotPaging(queue);
}
@ -2282,7 +2282,7 @@ public class PagingTest extends ParameterDBTestBase {
q2.getPageSubscription().cleanupEntries(false);
PageCursorProvider provider = q1.getPageSubscription().getPagingStore().getCursorProvider();
PageCursorProviderAccessor.cleanup(provider);
PageCursorProviderTestAccessor.cleanup(provider);
waitForNotPaging(q1);
@ -2480,7 +2480,7 @@ public class PagingTest extends ParameterDBTestBase {
session.commit();
PagingStore store = server.getPagingManager().getPageStore(ADDRESS);
PageCursorProviderAccessor.cleanup(store.getCursorProvider());
PageCursorProviderTestAccessor.cleanup(store.getCursorProvider());
Wait.assertFalse(server.getPagingManager().getPageStore(ADDRESS)::isPaging, 5000, 100);
}
@ -3623,7 +3623,7 @@ public class PagingTest extends ParameterDBTestBase {
queue.getPageSubscription().getPagingStore().disableCleanup();
PageCursorProviderAccessor.cleanup(queue.getPagingStore().getCursorProvider());
PageCursorProviderTestAccessor.cleanup(queue.getPagingStore().getCursorProvider());
consumerSession.start();
ClientConsumer consumer = consumerSession.createConsumer(ADDRESS, SimpleString.toSimpleString("id > 0"));
@ -3636,7 +3636,7 @@ public class PagingTest extends ParameterDBTestBase {
// The only reason I'm calling cleanup directly is that it would be easy to debug in case of bugs
// if you see an issue with cleanup here, enjoy debugging this method
PageCursorProviderAccessor.cleanup(queue.getPagingStore().getCursorProvider());
PageCursorProviderTestAccessor.cleanup(queue.getPagingStore().getCursorProvider());
}
queue.getPageSubscription().getPagingStore().enableCleanup();
@ -3780,7 +3780,7 @@ public class PagingTest extends ParameterDBTestBase {
queue = server.locateQueue(ADDRESS);
queue.getPageSubscription().cleanupEntries(false);
PageCursorProviderAccessor.cleanup(queue.getPageSubscription().getPagingStore().getCursorProvider());
PageCursorProviderTestAccessor.cleanup(queue.getPageSubscription().getPagingStore().getCursorProvider());
ClientConsumer consumer = session.createConsumer(ADDRESS);
session.start();
@ -4458,7 +4458,7 @@ public class PagingTest extends ParameterDBTestBase {
}
PagingStore store = server.getPagingManager().getPageStore(ADDRESS);
PageCursorProviderAccessor.cleanup(store.getCursorProvider());
PageCursorProviderTestAccessor.cleanup(store.getCursorProvider());
long timeout = System.currentTimeMillis() + 5000;
while (store.isPaging() && timeout > System.currentTimeMillis()) {
@ -4533,11 +4533,11 @@ public class PagingTest extends ParameterDBTestBase {
}
PagingStore store = server.getPagingManager().getPageStore(ADDRESS);
PageCursorProviderAccessor.cleanup(store.getCursorProvider());
PageCursorProviderTestAccessor.cleanup(store.getCursorProvider());
Wait.waitFor(() -> !store.isPaging(), 5000);
PageCursorProviderAccessor.cleanup(store.getCursorProvider());
PageCursorProviderTestAccessor.cleanup(store.getCursorProvider());
waitForNotPaging(server.locateQueue(PagingTest.ADDRESS.concat("=1")));
@ -4610,7 +4610,7 @@ public class PagingTest extends ParameterDBTestBase {
session.commit();
session.close();
PageCursorProviderAccessor.cleanup(store.getCursorProvider());
PageCursorProviderTestAccessor.cleanup(store.getCursorProvider());
waitForNotPaging(server.locateQueue(PagingTest.ADDRESS.concat("=1")));
@ -4909,7 +4909,7 @@ public class PagingTest extends ParameterDBTestBase {
pgStoreAddress.getCursorProvider().getSubscription(serverQueue.getID()).cleanupEntries(false);
PageCursorProviderAccessor.cleanup(pgStoreAddress.getCursorProvider());
PageCursorProviderTestAccessor.cleanup(pgStoreAddress.getCursorProvider());
Wait.assertFalse(pgStoreAddress::isPaging);
session.commit();
@ -6265,7 +6265,7 @@ public class PagingTest extends ParameterDBTestBase {
consumer.close();
session.close();
PageCursorProviderAccessor.cleanup(store.getCursorProvider());
PageCursorProviderTestAccessor.cleanup(store.getCursorProvider());
waitForNotPaging(server.locateQueue(PagingTest.ADDRESS.concat("=1")));
sf.close();
locator.close();

View File

@ -264,18 +264,6 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>

View File

@ -1,39 +0,0 @@
## ---------------------------------------------------------------------------
## Licensed to the Apache Software Foundation (ASF) under one or more
## contributor license agreements. See the NOTICE file distributed with
## this work for additional information regarding copyright ownership.
## The ASF licenses this file to You under the Apache License, Version 2.0
## (the "License"); you may not use this file except in compliance with
## the License. You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
## ---------------------------------------------------------------------------
dn: uid=first,ou=system
uid: first
userPassword: secret
objectClass: account
objectClass: simpleSecurityObject
objectClass: top
###################
## Define groups ##
###################
dn: cn=admins,ou=system
cn: admins
member: uid=first,ou=system
objectClass: groupOfNames
objectClass: top
dn: cn=users,ou=system
cn: users
member: cn=admins,ou=system
objectClass: groupOfNames
objectClass: top

View File

@ -35,17 +35,7 @@
</properties>
<dependencies>
<!-- this is needed for ActivemqTestBase.
TODO: We should eventually move ActiveMQTestBase into artemis-unit-test-support -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-server</artifactId>
<version>${project.version}</version>
<scope>test</scope>
<type>test-jar</type>
</dependency>
<!-- this is needed for Wait -->
<!-- Test support modules -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-unit-test-support</artifactId>
@ -53,11 +43,11 @@
<scope>test</scope>
</dependency>
<!-- this is needed for CFUtil -->
<dependency>
<groupId>org.apache.activemq.tests</groupId>
<artifactId>artemis-test-support</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<!-- Dependencies for the ActiveMQ Artemis Server and its protocols -->

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.core.message.impl;
package org.apache.activemq.artemis.tests.unit.core.message.impl;
import org.apache.activemq.artemis.api.core.QueueConfiguration;
import org.apache.activemq.artemis.api.core.SimpleString;

View File

@ -48,8 +48,8 @@ import org.apache.activemq.artemis.core.paging.cursor.PageIterator;
import org.apache.activemq.artemis.core.paging.cursor.PageSubscription;
import org.apache.activemq.artemis.core.paging.cursor.PagedReference;
import org.apache.activemq.artemis.core.paging.cursor.PagedReferenceImpl;
import org.apache.activemq.artemis.core.paging.cursor.impl.PageCursorProviderAccessor;
import org.apache.activemq.artemis.core.paging.cursor.impl.PageCursorProviderImpl;
import org.apache.activemq.artemis.core.paging.cursor.impl.PageCursorProviderTestAccessor;
import org.apache.activemq.artemis.core.paging.impl.Page;
import org.apache.activemq.artemis.core.paging.impl.PageReadWriter;
import org.apache.activemq.artemis.core.paging.impl.PageTransactionInfoImpl;
@ -323,7 +323,7 @@ public class PagingStoreImplTest extends ActiveMQTestBase {
debugPage(storeImpl, subscription, storeImpl.getFirstPage(), storeImpl.getCurrentWritingPage());
}
PageCursorProviderAccessor.cleanup(storeImpl.getCursorProvider());
PageCursorProviderTestAccessor.cleanup(storeImpl.getCursorProvider());
Assert.assertTrue(storeImpl.isPaging());
@ -350,7 +350,7 @@ public class PagingStoreImplTest extends ActiveMQTestBase {
Assert.assertEquals(3, storeImpl.getNumberOfPages());
PageCursorProviderAccessor.cleanup(storeImpl.getCursorProvider());
PageCursorProviderTestAccessor.cleanup(storeImpl.getCursorProvider());
Assert.assertFalse(storeImpl.isPaging());
@ -441,7 +441,7 @@ public class PagingStoreImplTest extends ActiveMQTestBase {
Assert.assertEquals(7, messagesRead);
PageCursorProviderAccessor.cleanup(storeImpl.getCursorProvider());
PageCursorProviderTestAccessor.cleanup(storeImpl.getCursorProvider());
Assert.assertEquals(10, factory.listFiles("page").size());
@ -451,7 +451,7 @@ public class PagingStoreImplTest extends ActiveMQTestBase {
Assert.assertEquals(11, factory.listFiles("page").size());
PageCursorProviderAccessor.cleanup(storeImpl.getCursorProvider());
PageCursorProviderTestAccessor.cleanup(storeImpl.getCursorProvider());
Assert.assertEquals(10, factory.listFiles("page").size());
@ -476,7 +476,7 @@ public class PagingStoreImplTest extends ActiveMQTestBase {
Assert.assertEquals(90, messagesRead);
PageCursorProviderAccessor.cleanup(storeImpl.getCursorProvider());
PageCursorProviderTestAccessor.cleanup(storeImpl.getCursorProvider());
Assert.assertFalse(storeImpl.isPaging());
}

View File

@ -43,6 +43,7 @@ import org.apache.activemq.artemis.tests.unit.util.deserialization.pkg1.Enclosin
import org.apache.activemq.artemis.tests.unit.util.deserialization.pkg1.TestClass1;
import org.apache.activemq.artemis.tests.unit.util.deserialization.pkg1.TestClass2;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.ArtemisTestCase;
import org.apache.activemq.artemis.utils.ObjectInputStreamWithClassLoader;
import org.junit.Assert;
import org.junit.Test;
@ -92,8 +93,8 @@ public class ObjectInputStreamWithClassLoaderTest extends ActiveMQTestBase {
//Class.isAnonymousClass() call used in ObjectInputStreamWithClassLoader
//need to access the enclosing class and its parent class of the obj
//i.e. ActiveMQTestBase and Assert.
ClassLoader testClassLoader = ObjectInputStreamWithClassLoaderTest.newClassLoader(obj.getClass(), ActiveMQTestBase.class, Assert.class);
//i.e. ActiveMQTestBase, ArtemisTestCase, and Assert.
ClassLoader testClassLoader = ObjectInputStreamWithClassLoaderTest.newClassLoader(obj.getClass(), ActiveMQTestBase.class, ArtemisTestCase.class, Assert.class);
Thread.currentThread().setContextClassLoader(testClassLoader);
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
@ -120,7 +121,7 @@ public class ObjectInputStreamWithClassLoaderTest extends ActiveMQTestBase {
originalProxy.setMyInt(100);
byte[] bytes = ObjectInputStreamWithClassLoaderTest.toBytes(originalProxy);
ClassLoader testClassLoader = ObjectInputStreamWithClassLoaderTest.newClassLoader(this.getClass(), ActiveMQTestBase.class, Assert.class);
ClassLoader testClassLoader = ObjectInputStreamWithClassLoaderTest.newClassLoader(this.getClass(), ActiveMQTestBase.class, ArtemisTestCase.class, Assert.class);
Thread.currentThread().setContextClassLoader(testClassLoader);
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStreamWithClassLoader ois = new ObjectInputStreamWithClassLoader(bais);