diff --git a/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/ExpiryHogTest.java b/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/ExpiryHogTest.java index ce98133ca9c..ef876315070 100644 --- a/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/ExpiryHogTest.java +++ b/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/ExpiryHogTest.java @@ -35,8 +35,6 @@ @RunWith(BlockJUnit4ClassRunner.class) public class ExpiryHogTest extends JmsMultipleClientsTestSupport { - boolean sleep = false; - int numMessages = 4; @Test(timeout = 2 * 60 * 1000) @@ -44,7 +42,6 @@ public void testImmediateDispatchWhenCacheDisabled() throws Exception { ConnectionFactory f = createConnectionFactory(); destination = createDestination(); startConsumers(f, destination); - sleep = true; this.startProducers(f, destination, numMessages); allMessagesList.assertMessagesReceived(numMessages); } @@ -55,7 +52,7 @@ protected BrokerService createBroker() throws Exception { bs.setDeleteAllMessagesOnStartup(true); PolicyMap policyMap = new PolicyMap(); PolicyEntry defaultEntry = new PolicyEntry(); - defaultEntry.setExpireMessagesPeriod(5000); + defaultEntry.setExpireMessagesPeriod(500); defaultEntry.setUseCache(false); policyMap.setDefaultEntry(defaultEntry); bs.setDestinationPolicy(policyMap); @@ -65,11 +62,8 @@ protected BrokerService createBroker() throws Exception { @Override protected TextMessage createTextMessage(Session session, String initText) throws Exception { - if (sleep) { - TimeUnit.SECONDS.sleep(10); - } TextMessage msg = super.createTextMessage(session, initText); - msg.setJMSExpiration(4000); + msg.setJMSExpiration(500); return msg; } diff --git a/tests/artemis-test-support/src/main/java/org/apache/activemq/artemis/tests/integration/largemessage/LargeMessageTestBase.java b/tests/artemis-test-support/src/main/java/org/apache/activemq/artemis/tests/integration/largemessage/LargeMessageTestBase.java index cc5a4bc869a..642b024e893 100644 --- a/tests/artemis-test-support/src/main/java/org/apache/activemq/artemis/tests/integration/largemessage/LargeMessageTestBase.java +++ b/tests/artemis-test-support/src/main/java/org/apache/activemq/artemis/tests/integration/largemessage/LargeMessageTestBase.java @@ -50,13 +50,18 @@ import org.apache.activemq.artemis.core.config.Configuration; import org.apache.activemq.artemis.core.config.StoreConfiguration; import org.apache.activemq.artemis.core.server.ActiveMQServer; +import org.apache.activemq.artemis.core.server.LargeServerMessage; +import org.apache.activemq.artemis.core.server.MessageReference; import org.apache.activemq.artemis.core.server.Queue; import org.apache.activemq.artemis.tests.extensions.parameterized.ParameterizedTestExtension; import org.apache.activemq.artemis.tests.extensions.parameterized.Parameters; import org.apache.activemq.artemis.tests.util.ActiveMQTestBase; import org.apache.activemq.artemis.utils.DataConstants; import org.apache.activemq.artemis.utils.DeflaterReader; +import org.apache.activemq.artemis.utils.Wait; +import org.apache.activemq.artemis.utils.collections.LinkedListIterator; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -65,20 +70,46 @@ @ExtendWith(ParameterizedTestExtension.class) public abstract class LargeMessageTestBase extends ActiveMQTestBase { - private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); protected final SimpleString ADDRESS = SimpleString.of("SimpleAddress"); + protected ServerLocator locator; + protected StoreConfiguration.StoreType storeType; + protected boolean isCompressedTest = false; + public LargeMessageTestBase(StoreConfiguration.StoreType storeType) { + this.storeType = storeType; + } + protected void validateLargeMessageComplete(ActiveMQServer server) throws Exception { + Queue queue = server.locateQueue(ADDRESS); - protected StoreConfiguration.StoreType storeType; + Wait.assertEquals(1, queue::getMessageCount); - public LargeMessageTestBase(StoreConfiguration.StoreType storeType) { - this.storeType = storeType; + LinkedListIterator browserIterator = queue.browserIterator(); + + while (browserIterator.hasNext()) { + MessageReference ref = browserIterator.next(); + Message message = ref.getMessage(); + + assertNotNull(message); + assertTrue(message instanceof LargeServerMessage); + } + browserIterator.close(); + } + + protected boolean isNetty() { + return false; + } + + @Override + @BeforeEach + public void setUp() throws Exception { + super.setUp(); + locator = createFactory(isNetty()); } @AfterEach diff --git a/tests/artemis-test-support/src/main/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/SequentialFileFactoryTestBase.java b/tests/artemis-test-support/src/main/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/SequentialFileFactoryTestBase.java index 954308c4ec3..0a9e158edeb 100644 --- a/tests/artemis-test-support/src/main/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/SequentialFileFactoryTestBase.java +++ b/tests/artemis-test-support/src/main/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/SequentialFileFactoryTestBase.java @@ -56,8 +56,6 @@ public void tearDown() throws Exception { factory = null; - ActiveMQTestBase.forceGC(); - assertEquals(0, LibaioContext.getTotalMaxIO()); super.tearDown(); diff --git a/tests/artemis-test-support/src/main/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java b/tests/artemis-test-support/src/main/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java index 33786dcce6a..8917209c896 100644 --- a/tests/artemis-test-support/src/main/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java +++ b/tests/artemis-test-support/src/main/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java @@ -545,7 +545,7 @@ protected static final ClusterConnectionConfiguration basicClusterConnectionConf setName("cluster1").setAddress("jms").setConnectorName(connectorName). setRetryInterval(100).setDuplicateDetection(false).setMaxHops(1). setConfirmationWindowSize(1).setMessageLoadBalancingType(MessageLoadBalancingType.STRICT). - setStaticConnectors(connectors0); + setStaticConnectors(connectors0).setCallTimeout(1000).setCallFailoverTimeout(1000); return clusterConnectionConfiguration; } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/InterruptedLargeMessageTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/InterruptedLargeMessageTest.java index 767d408a852..d01c1d37145 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/InterruptedLargeMessageTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/InterruptedLargeMessageTest.java @@ -44,7 +44,6 @@ import org.apache.activemq.artemis.api.core.client.ClientProducer; import org.apache.activemq.artemis.api.core.client.ClientSession; import org.apache.activemq.artemis.api.core.client.ClientSessionFactory; -import org.apache.activemq.artemis.api.core.client.ServerLocator; import org.apache.activemq.artemis.core.config.StoreConfiguration; import org.apache.activemq.artemis.core.filter.Filter; import org.apache.activemq.artemis.core.paging.PagingManager; @@ -87,8 +86,6 @@ public class InterruptedLargeMessageTest extends LargeMessageTestBase { private final int LARGE_MESSAGE_SIZE = ActiveMQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE * 3; - protected ServerLocator locator; - public InterruptedLargeMessageTest(StoreConfiguration.StoreType storeType) { super(storeType); } @@ -98,9 +95,9 @@ public InterruptedLargeMessageTest(StoreConfiguration.StoreType storeType) { public void setUp() throws Exception { super.setUp(); LargeMessageTestInterceptorIgnoreLastPacket.clearInterrupt(); - locator = createFactory(isNetty()); } + @Override protected boolean isNetty() { return false; } @@ -141,8 +138,6 @@ public void testInterruptLargeMessageSend() throws Exception { server.fail(false); - ActiveMQTestBase.forceGC(); - server.start(); server.stop(); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LargeMessageAvoidLargeMessagesTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LargeMessageAvoidLargeMessagesTest.java index 5b2b7edc0d5..235abbd0006 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LargeMessageAvoidLargeMessagesTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LargeMessageAvoidLargeMessagesTest.java @@ -33,19 +33,13 @@ import org.apache.activemq.artemis.core.server.ActiveMQServer; import org.apache.activemq.artemis.core.settings.impl.AddressSettings; import org.apache.activemq.artemis.tests.extensions.parameterized.ParameterizedTestExtension; +import org.apache.activemq.artemis.tests.integration.largemessage.LargeMessageTestBase; import org.apache.activemq.artemis.tests.util.ActiveMQTestBase; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.TestTemplate; import org.junit.jupiter.api.extension.ExtendWith; -/** - * The test extends the LargeMessageTest and tests - * the functionality of option avoid-large-messages - * - * Parameters set in superclass - */ @ExtendWith(ParameterizedTestExtension.class) -public class LargeMessageAvoidLargeMessagesTest extends LargeMessageTest { +public class LargeMessageAvoidLargeMessagesTest extends LargeMessageTestBase { public LargeMessageAvoidLargeMessagesTest(StoreConfiguration.StoreType storeType) { super(storeType); @@ -66,12 +60,6 @@ protected ServerLocator createFactory(final boolean isNetty) throws Exception { return super.createFactory(isNetty).setMinLargeMessageSize(10240).setCompressLargeMessage(true); } - @Disabled - @Override - @TestTemplate - public void testDeleteUnreferencedMessage() { - // this test makes no sense as it needs to delete a large message and its record - } @TestTemplate public void testSimpleSendOnAvoid() throws Exception { @@ -286,7 +274,6 @@ public void testMixedCompressionSendReceive() throws Exception { //this test won't leave any large messages in the large-messages dir //because after compression, the messages are regulars at server. - @Override @TestTemplate public void testDLALargeMessage() throws Exception { final int messageSize = (int) (3.5 * ActiveMQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE); @@ -388,11 +375,4 @@ public void testDLALargeMessage() throws Exception { validateNoFilesOnLargeDir(); } - @Disabled - @Override - @TestTemplate - public void testSendServerMessage() throws Exception { - // doesn't make sense as compressed - } - } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LargeMessageCompressTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LargeMessageCompressTest.java index 0c708f509d7..50f902b4a97 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LargeMessageCompressTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LargeMessageCompressTest.java @@ -54,8 +54,8 @@ import org.apache.activemq.artemis.core.server.ActiveMQServer; import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory; import org.apache.activemq.artemis.tests.extensions.parameterized.ParameterizedTestExtension; +import org.apache.activemq.artemis.tests.integration.largemessage.LargeMessageTestBase; import org.apache.activemq.artemis.utils.RandomUtil; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.TestTemplate; import org.junit.jupiter.api.extension.ExtendWith; @@ -70,7 +70,7 @@ //Parameters set in superclass @ExtendWith(ParameterizedTestExtension.class) -public class LargeMessageCompressTest extends LargeMessageTest { +public class LargeMessageCompressTest extends LargeMessageTestBase { public LargeMessageCompressTest(StoreConfiguration.StoreType storeType) { @@ -92,13 +92,6 @@ protected ServerLocator createFactory(final boolean isNetty) throws Exception { return super.createFactory(isNetty).setCompressLargeMessage(true); } - @Override - @TestTemplate - @Disabled - public void testDeleteUnreferencedMessage() { - // this test makes no sense as it needs to delete a large message and its record - } - @TestTemplate public void testLargeMessageCompressionNotCompressedAndBrowsed() throws Exception { final int messageSize = (int) (3.5 * ActiveMQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE); @@ -642,14 +635,6 @@ public void testLargeMessageCompressionLevel() throws Exception { } - @Disabled - @Override - @TestTemplate - public void testSendServerMessage() throws Exception { - // doesn't make sense as compressed - } - - // https://issues.apache.org/jira/projects/ARTEMIS/issues/ARTEMIS-3751 @TestTemplate public void testOverrideSize() throws Exception { diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LargeMessageTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LargeMessageTest.java index af19833f66a..bc2d5793deb 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LargeMessageTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LargeMessageTest.java @@ -69,8 +69,6 @@ import org.apache.activemq.artemis.core.paging.PagingStore; import org.apache.activemq.artemis.core.persistence.impl.journal.LargeServerMessageImpl; import org.apache.activemq.artemis.core.server.ActiveMQServer; -import org.apache.activemq.artemis.core.server.LargeServerMessage; -import org.apache.activemq.artemis.core.server.MessageReference; import org.apache.activemq.artemis.core.server.Queue; import org.apache.activemq.artemis.core.server.RoutingContext; import org.apache.activemq.artemis.core.server.ServerProducer; @@ -84,7 +82,6 @@ import org.apache.activemq.artemis.tests.util.CFUtil; import org.apache.activemq.artemis.tests.util.RandomUtil; import org.apache.activemq.artemis.tests.util.Wait; -import org.apache.activemq.artemis.utils.collections.LinkedListIterator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.TestTemplate; import org.junit.jupiter.api.extension.ExtendWith; @@ -101,14 +98,8 @@ public class LargeMessageTest extends LargeMessageTestBase { protected ServerLocator locator; - protected boolean isCompressedTest = false; - private int largeMessageSize; - protected boolean isNetty() { - return false; - } - public LargeMessageTest(StoreConfiguration.StoreType storeType) { super(storeType); // The JDBC Large Message store is pretty slow, to speed tests up we only test 5MB large messages @@ -482,23 +473,6 @@ public void testPendingRecord() throws Exception { validateNoFilesOnLargeDir(); } - protected void validateLargeMessageComplete(ActiveMQServer server) throws Exception { - Queue queue = server.locateQueue(ADDRESS); - - Wait.assertEquals(1, queue::getMessageCount); - - LinkedListIterator browserIterator = queue.browserIterator(); - - while (browserIterator.hasNext()) { - MessageReference ref = browserIterator.next(); - Message message = ref.getMessage(); - - assertNotNull(message); - assertTrue(message instanceof LargeServerMessage); - } - browserIterator.close(); - } - @TestTemplate public void testDeleteOnDrop() throws Exception { fillAddress(); @@ -2114,13 +2088,13 @@ public void testPageOnLargeMessageMultipleQueues() throws Exception { final int numberOfBytes = 1024; - final int numberOfBytesBigMessage = 400000; + final int numberOfBytesBigMessage = 4000; - locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true); + locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setMinLargeMessageSize(1000); ClientSessionFactory sf = addSessionFactory(createSessionFactory(locator)); - ClientSession session = sf.createSession(null, null, false, true, true, false, 0); + ClientSession session = sf.createSession(null, null, false, false, true, false, 0); session.createQueue(QueueConfiguration.of(ADDRESS.concat("-0")).setAddress(ADDRESS)); session.createQueue(QueueConfiguration.of(ADDRESS.concat("-1")).setAddress(ADDRESS)); @@ -2143,17 +2117,20 @@ public void testPageOnLargeMessageMultipleQueues() throws Exception { producer.send(message); } + session.commit(); + ClientMessage clientFile = createLargeClientMessageStreaming(session, numberOfBytesBigMessage); clientFile.putBooleanProperty("TestLarge", true); producer.send(clientFile); - for (int i = 0; i < 100; i++) { + for (int i = 0; i < 10; i++) { message = session.createMessage(true); message.getBodyBuffer().writeBytes(new byte[numberOfBytes]); producer.send(message); } + session.commit(); session.close(); @@ -2205,7 +2182,7 @@ public void testPageOnLargeMessageMultipleQueues() throws Exception { session.commit(); } - for (int i = 0; i < 100; i++) { + for (int i = 0; i < 5; i++) { ClientMessage message2 = consumer.receive(LargeMessageTest.RECEIVE_WAIT_TIME); assertNotNull(message2); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/ClusterTestBase.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/ClusterTestBase.java index d34c512b3ab..f1077b76a0e 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/ClusterTestBase.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/ClusterTestBase.java @@ -35,8 +35,6 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; @@ -123,9 +121,9 @@ protected boolean isLargeMessage() { return false; } - private static final long TIMEOUT_START_SERVER = 1000; + private static final long TIMEOUT_START_SERVER = 10; - private static final SimpleString COUNT_PROP = SimpleString.of("count_prop"); + protected static final SimpleString COUNT_PROP = SimpleString.of("count_prop"); protected static final SimpleString FILTER_PROP = SimpleString.of("animal"); @@ -169,8 +167,6 @@ private DistributedLockManagerConfiguration getOrCreatePluggableQuorumConfigurat public void setUp() throws Exception { super.setUp(); - forceGC(); - consumers = new ConsumerHolder[ClusterTestBase.MAX_CONSUMERS]; servers = new ActiveMQServer[ClusterTestBase.MAX_SERVERS]; @@ -1254,91 +1250,10 @@ protected void verifyReceiveRoundRobinInSomeOrder(final boolean ack, } } - protected void verifyReceiveRoundRobinInSomeOrderWithCounts(final boolean ack, - final int[] messageCounts, - final int... consumerIDs) throws Exception { - List> receivedCounts = new ArrayList<>(); - - Set counts = new HashSet<>(); - - for (int consumerID : consumerIDs) { - ConsumerHolder holder = consumers[consumerID]; - - if (holder == null) { - throw new IllegalArgumentException("No consumer at " + consumerID); - } - - LinkedList list = new LinkedList<>(); - - receivedCounts.add(list); - - ClientMessage message; - do { - message = holder.consumer.receive(1000); - - if (message != null) { - int count = (Integer) message.getObjectProperty(ClusterTestBase.COUNT_PROP); - - checkMessageBody(message); - - // logger.debug("consumer {} received message {}", consumerIDs[i], count); - - assertFalse(counts.contains(count)); - - counts.add(count); - - list.add(count); - - if (ack) { - message.acknowledge(); - } - } - } - while (message != null); - } - - for (int messageCount : messageCounts) { - assertTrue(counts.contains(messageCount)); - } - - @SuppressWarnings("unchecked") - LinkedList[] lists = new LinkedList[consumerIDs.length]; - - for (int i = 0; i < messageCounts.length; i++) { - for (LinkedList list : receivedCounts) { - int elem = list.get(0); - - if (elem == messageCounts[i]) { - lists[i] = list; - - break; - } - } - } - int index = 0; - - for (int messageCount : messageCounts) { - LinkedList list = lists[index]; - - assertNotNull(list); - - int elem = list.poll(); - - assertEquals(messageCount, elem); - - index++; - - if (index == consumerIDs.length) { - index = 0; - } - } - - } - /** * @param message */ - private void checkMessageBody(ClientMessage message) { + protected void checkMessageBody(ClientMessage message) { if (isLargeMessage()) { for (int posMsg = 0; posMsg < getLargeMessageSize(); posMsg++) { assertEquals(getSamplebyte(posMsg), message.getBodyBuffer().readByte()); @@ -1790,7 +1705,7 @@ protected void setupClusterConnection(final String name, } Configuration config = serverFrom.getConfiguration(); - ClusterConnectionConfiguration clusterConf = new ClusterConnectionConfiguration().setName(name).setAddress(address).setConnectorName(name).setRetryInterval(100).setMessageLoadBalancingType(messageLoadBalancingType).setMaxHops(maxHops).setConfirmationWindowSize(1024).setStaticConnectors(pairs).setAllowDirectConnectionsOnly(allowDirectConnectionsOnly); + ClusterConnectionConfiguration clusterConf = new ClusterConnectionConfiguration().setName(name).setAddress(address).setConnectorName(name).setRetryInterval(100).setMessageLoadBalancingType(messageLoadBalancingType).setMaxHops(maxHops).setConfirmationWindowSize(1024).setStaticConnectors(pairs).setAllowDirectConnectionsOnly(allowDirectConnectionsOnly).setCallTimeout(100); config.getClusterConfigurations().add(clusterConf); } @@ -1956,7 +1871,7 @@ private ClusterConnectionConfiguration createClusterConfig(final String name, .setName(name) .setAddress(address) .setConnectorName(connectorFrom.getName()) - .setRetryInterval(250) + .setRetryInterval(250).setCallFailoverTimeout(100).setCallTimeout(100) .setMessageLoadBalancingType(messageLoadBalancingType) .setMaxHops(maxHops) .setConfirmationWindowSize(1024) diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/ClusteredGroupingTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/ClusteredGroupingTest.java index 83d2ab5d9b4..261508c7e04 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/ClusteredGroupingTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/ClusteredGroupingTest.java @@ -35,6 +35,7 @@ import org.apache.activemq.artemis.core.server.group.impl.Response; import org.apache.activemq.artemis.core.server.impl.QueueImpl; import org.apache.activemq.artemis.core.server.management.Notification; +import org.apache.activemq.artemis.tests.util.Wait; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -116,12 +117,7 @@ public void testGroupingGroupTimeoutWithUnproposal() throws Exception { assertTrue(latch.await(5, TimeUnit.SECONDS)); - long timeLimit = System.currentTimeMillis() + 5000; - while (timeLimit > System.currentTimeMillis() && queue0Server2.getGroupCount() != 0) { - Thread.sleep(10); - } - - assertEquals(0, queue0Server2.getGroupCount(), "Unproposal should cleanup the queue group as well"); + Wait.assertEquals(0, queue0Server2::getGroupCount, 5000, 100); removeConsumer(0); @@ -331,7 +327,7 @@ public void testGroupingSimpleFail2nd() throws Exception { setupClusterConnection("cluster2", "queues", MessageLoadBalancingType.ON_DEMAND, 1, isNetty(), 2, 0, 1); - final int TIMEOUT_GROUPS = 5000; + final int TIMEOUT_GROUPS = 1000; setUpGroupHandler(GroupingHandlerConfiguration.TYPE.LOCAL, 0, TIMEOUT_GROUPS, -1, -1); setUpGroupHandler(GroupingHandlerConfiguration.TYPE.REMOTE, 1, TIMEOUT_GROUPS, -1, -1); setUpGroupHandler(GroupingHandlerConfiguration.TYPE.REMOTE, 2, TIMEOUT_GROUPS, -1, -1); @@ -440,7 +436,7 @@ public void testGroupTimeout() throws Exception { setupClusterConnection("cluster2", "queues", MessageLoadBalancingType.ON_DEMAND, 1, isNetty(), 2, 0, 1); - setUpGroupHandler(GroupingHandlerConfiguration.TYPE.LOCAL, 0, 1000, 1000, 100); + setUpGroupHandler(GroupingHandlerConfiguration.TYPE.LOCAL, 0, 1000, 500, 100); setUpGroupHandler(GroupingHandlerConfiguration.TYPE.REMOTE, 1, 1000, 100, 100); setUpGroupHandler(GroupingHandlerConfiguration.TYPE.REMOTE, 2, 1000, 100, 100); @@ -472,52 +468,14 @@ public void testGroupTimeout() throws Exception { assertNotNull(servers[0].getGroupingHandler().getProposal(SimpleString.of("id1.queue0"), false)); - // Group timeout - Thread.sleep(1000); - - long timeLimit = System.currentTimeMillis() + 5000; - while (timeLimit > System.currentTimeMillis() && servers[0].getGroupingHandler().getProposal(SimpleString.of("id1.queue0"), false) != null) { - Thread.sleep(10); - } - Thread.sleep(1000); - - assertNull(servers[0].getGroupingHandler().getProposal(SimpleString.of("id1.queue0"), false), "Group should have timed out"); - - sendWithProperty(0, "queues.testaddress", 1, false, Message.HDR_GROUP_ID, SimpleString.of("id1")); - sendWithProperty(1, "queues.testaddress", 1, false, Message.HDR_GROUP_ID, SimpleString.of("id1")); - - // Verify why this is failing... whyt it's creating a new one here???? - assertNotNull(servers[0].getGroupingHandler().getProposal(SimpleString.of("id1.queue0"), false)); - assertNotNull(servers[1].getGroupingHandler().getProposal(SimpleString.of("id1.queue0"), false)); - - timeLimit = System.currentTimeMillis() + 1500; - - // We will keep bothering server1 as it will ping server0 eventually - while (timeLimit > System.currentTimeMillis() && servers[1].getGroupingHandler().getProposal(SimpleString.of("id1.queue0"), true) != null) { - assertNotNull(servers[0].getGroupingHandler().getProposal(SimpleString.of("id1.queue0"), false)); - Thread.sleep(10); - } - - // Group timeout - Thread.sleep(1000); - - timeLimit = System.currentTimeMillis() + 5000; - while (timeLimit > System.currentTimeMillis() && servers[0].getGroupingHandler().getProposal(SimpleString.of("id1.queue0"), false) != null) { - Thread.sleep(10); + { + SimpleString idString = SimpleString.of("id1.queue0"); + Wait.assertTrue(() -> servers[0].getGroupingHandler().getProposal(SimpleString.of("id1.queue0"), false) == null); } assertNull(servers[0].getGroupingHandler().getProposal(SimpleString.of("id1.queue0"), false), "Group should have timed out"); } - private void cycleServer(int node) { - try { - stopServers(node); - startServers(node); - } catch (Exception e) { - e.printStackTrace(); - } - } - @Test public void testGroupingBindingNotPresentAtStart() throws Exception { setupServer(0, isFileStorage(), isNetty()); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/LargeMessageRedistributionTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/LargeMessageRedistributionTest.java index 724b731ae2c..f7b5c633946 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/LargeMessageRedistributionTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/LargeMessageRedistributionTest.java @@ -30,7 +30,7 @@ public boolean isLargeMessage() { @Test public void testRedistributionLargeMessageDirCleanup() throws Exception { - final long delay = 1000; + final long delay = 100; final int numMessages = 5; setRedistributionDelay(delay); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/MessageRedistributionTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/MessageRedistributionTest.java index ccb238d29d9..9ef9553a048 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/MessageRedistributionTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/MessageRedistributionTest.java @@ -20,6 +20,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import javax.jms.Connection; import javax.jms.ConnectionFactory; @@ -31,6 +32,10 @@ import javax.transaction.xa.Xid; import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import org.apache.activemq.artemis.api.core.Message; @@ -283,7 +288,7 @@ public void testRedistributionStopsWhenConsumerAdded() throws Exception { waitForBindings(1, "queues.testaddress", 2, 1, false); waitForBindings(2, "queues.testaddress", 2, 1, false); - send(0, "queues.testaddress", 2000, false, null); + send(0, "queues.testaddress", 100, false, null); removeConsumer(0); addConsumer(0, 0, "queue0", null); @@ -335,6 +340,90 @@ public void testRedistributionWhenConsumerIsClosed() throws Exception { logger.debug("Test done"); } + protected void verifyReceiveRoundRobinInSomeOrderWithCounts(final boolean ack, + final int[] messageCounts, + final int... consumerIDs) throws Exception { + List> receivedCounts = new ArrayList<>(); + + Set counts = new HashSet<>(); + + for (int consumerID : consumerIDs) { + ConsumerHolder holder = consumers[consumerID]; + + if (holder == null) { + throw new IllegalArgumentException("No consumer at " + consumerID); + } + + LinkedList list = new LinkedList<>(); + + receivedCounts.add(list); + + for (long timeout = System.currentTimeMillis() + 5000; !matchCounters(messageCounts, counts) && timeout > System.currentTimeMillis();) { + ClientMessage message = holder.consumer.receiveImmediate(); + + if (message != null) { + int count = (Integer) message.getObjectProperty(ClusterTestBase.COUNT_PROP); + + checkMessageBody(message); + + assertFalse(counts.contains(count)); + + counts.add(count); + + list.add(count); + + if (ack) { + message.acknowledge(); + } + } + } + } + + assertTrue(matchCounters(messageCounts, counts)); + + @SuppressWarnings("unchecked") + LinkedList[] lists = new LinkedList[consumerIDs.length]; + + for (int i = 0; i < messageCounts.length; i++) { + for (LinkedList list : receivedCounts) { + int elem = list.get(0); + + if (elem == messageCounts[i]) { + lists[i] = list; + + break; + } + } + } + int index = 0; + + for (int messageCount : messageCounts) { + LinkedList list = lists[index]; + + assertNotNull(list); + + int elem = list.poll(); + + assertEquals(messageCount, elem); + + index++; + + if (index == consumerIDs.length) { + index = 0; + } + } + + } + + private static boolean matchCounters(int[] messageCounts, Set counts) { + for (int messageCount : messageCounts) { + if (!counts.contains(messageCount)) { + return false; + } + } + return true; + } + @Test public void testRedistributionWhenConsumerIsClosedDifferentQueues() throws Exception { setupCluster(MessageLoadBalancingType.ON_DEMAND); @@ -368,9 +457,9 @@ public void testRedistributionWhenConsumerIsClosedDifferentQueues() throws Excep waitForBindings(1, "queues.testaddress", 2, 2, false); waitForBindings(2, "queues.testaddress", 2, 2, false); - final int NUMBER_OF_MESSAGES = 1000; + final int NUMBER_OF_MESSAGES = 100; - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < NUMBER_OF_MESSAGES; i++) { producer0.send(sess0.createMessage(true).putIntProperty("count", i)); } @@ -387,10 +476,7 @@ public void testRedistributionWhenConsumerIsClosedDifferentQueues() throws Excep assertNull(consumer0.receiveImmediate()); - // closing consumer1... it shouldn't redistribute anything as the other nodes don't have such queues consumer1.close(); - Thread.sleep(500); // wait some time giving time to redistribution break something - // (it shouldn't redistribute anything here since there are no queues on the other nodes) for (int i = 0; i < NUMBER_OF_MESSAGES; i++) { ClientMessage msg = consumer2.receive(5000); @@ -557,7 +643,7 @@ public void testNoRedistributionWhenConsumerIsClosedNoConsumersOnOtherNodes() th public void testRedistributeWithScheduling() throws Exception { setupCluster(MessageLoadBalancingType.ON_DEMAND); - AddressSettings setting = new AddressSettings().setRedeliveryDelay(10000); + AddressSettings setting = new AddressSettings().setRedeliveryDelay(100); servers[0].getAddressSettingsRepository().addMatch("queues.testaddress", setting); servers[0].getAddressSettingsRepository().addMatch("queue0", setting); servers[1].getAddressSettingsRepository().addMatch("queue0", setting); @@ -573,7 +659,9 @@ public void testRedistributeWithScheduling() throws Exception { ClientProducer prod0 = session0.createProducer("queues.testaddress"); - for (int i = 0; i < 100; i++) { + final int numberOfMessages = 10; + + for (int i = 0; i < numberOfMessages; i++) { ClientMessage msg = session0.createMessage(true); msg.putIntProperty("key", i); @@ -600,7 +688,7 @@ public void testRedistributeWithScheduling() throws Exception { ArrayList xids = new ArrayList<>(); - for (int i = 0; i < 100; i++) { + for (int i = 0; i < numberOfMessages; i++) { Xid xid = newXID(); session0.start(xid, XAResource.TMNOFLAGS); @@ -648,8 +736,8 @@ public void testRedistributeWithScheduling() throws Exception { session0.rollback(xid); } - for (int i = 0; i < 100; i++) { - ClientMessage msg = consumer1.receive(15000); + for (int i = 0; i < numberOfMessages; i++) { + ClientMessage msg = consumer1.receive(5000); assertNotNull(msg); msg.acknowledge(); } @@ -774,8 +862,6 @@ public void testRedistributionWithPrefixesWhenRemoteConsumerIsAdded() throws Exc removeConsumer(0); - Thread.sleep(2000); - send(0, "jms.queue." + name, 20, false, null); addConsumer(1, 1, name, null); @@ -1050,91 +1136,86 @@ public void testRedistributionToRemoteMulticastConsumerLbOffWithRedistribution() @Test public void testBackAndForth() throws Exception { - for (int i = 0; i < 10; i++) { - setupCluster(MessageLoadBalancingType.ON_DEMAND); - - startServers(0, 1, 2); + setupCluster(MessageLoadBalancingType.ON_DEMAND); - setupSessionFactory(0, isNetty()); - setupSessionFactory(1, isNetty()); - setupSessionFactory(2, isNetty()); + startServers(0, 1, 2); - final String ADDRESS = "queues.testaddress"; - final String QUEUE = "queue0"; + setupSessionFactory(0, isNetty()); + setupSessionFactory(1, isNetty()); + setupSessionFactory(2, isNetty()); - createQueue(0, ADDRESS, QUEUE, null, false); - createQueue(1, ADDRESS, QUEUE, null, false); - createQueue(2, ADDRESS, QUEUE, null, false); + final String ADDRESS = "queues.testaddress"; + final String QUEUE = "queue0"; - addConsumer(0, 0, QUEUE, null); + createQueue(0, ADDRESS, QUEUE, null, false); + createQueue(1, ADDRESS, QUEUE, null, false); + createQueue(2, ADDRESS, QUEUE, null, false); - waitForBindings(0, ADDRESS, 1, 1, true); - waitForBindings(1, ADDRESS, 1, 0, true); - waitForBindings(2, ADDRESS, 1, 0, true); + addConsumer(0, 0, QUEUE, null); - waitForBindings(0, ADDRESS, 2, 0, false); - waitForBindings(1, ADDRESS, 2, 1, false); - waitForBindings(2, ADDRESS, 2, 1, false); + waitForBindings(0, ADDRESS, 1, 1, true); + waitForBindings(1, ADDRESS, 1, 0, true); + waitForBindings(2, ADDRESS, 1, 0, true); - send(0, ADDRESS, 20, false, null); + waitForBindings(0, ADDRESS, 2, 0, false); + waitForBindings(1, ADDRESS, 2, 1, false); + waitForBindings(2, ADDRESS, 2, 1, false); - waitForMessages(0, ADDRESS, 20); + send(0, ADDRESS, 20, false, null); - removeConsumer(0); + waitForMessages(0, ADDRESS, 20); - waitForBindings(0, ADDRESS, 1, 0, true); - waitForBindings(1, ADDRESS, 1, 0, true); - waitForBindings(2, ADDRESS, 1, 0, true); + removeConsumer(0); - waitForBindings(0, ADDRESS, 2, 0, false); - waitForBindings(1, ADDRESS, 2, 0, false); - waitForBindings(2, ADDRESS, 2, 0, false); + waitForBindings(0, ADDRESS, 1, 0, true); + waitForBindings(1, ADDRESS, 1, 0, true); + waitForBindings(2, ADDRESS, 1, 0, true); - addConsumer(1, 1, QUEUE, null); + waitForBindings(0, ADDRESS, 2, 0, false); + waitForBindings(1, ADDRESS, 2, 0, false); + waitForBindings(2, ADDRESS, 2, 0, false); - waitForBindings(0, ADDRESS, 1, 0, true); - waitForBindings(1, ADDRESS, 1, 1, true); - waitForBindings(2, ADDRESS, 1, 0, true); + addConsumer(1, 1, QUEUE, null); - waitForMessages(1, ADDRESS, 20); - waitForMessages(0, ADDRESS, 0); + waitForBindings(0, ADDRESS, 1, 0, true); + waitForBindings(1, ADDRESS, 1, 1, true); + waitForBindings(2, ADDRESS, 1, 0, true); - waitForBindings(0, ADDRESS, 2, 1, false); - waitForBindings(1, ADDRESS, 2, 0, false); - waitForBindings(2, ADDRESS, 2, 1, false); + waitForMessages(1, ADDRESS, 20); + waitForMessages(0, ADDRESS, 0); - removeConsumer(1); + waitForBindings(0, ADDRESS, 2, 1, false); + waitForBindings(1, ADDRESS, 2, 0, false); + waitForBindings(2, ADDRESS, 2, 1, false); - waitForBindings(0, ADDRESS, 1, 0, true); - waitForBindings(1, ADDRESS, 1, 0, true); - waitForBindings(2, ADDRESS, 1, 0, true); + removeConsumer(1); - waitForBindings(0, ADDRESS, 2, 0, false); - waitForBindings(1, ADDRESS, 2, 0, false); - waitForBindings(2, ADDRESS, 2, 0, false); + waitForBindings(0, ADDRESS, 1, 0, true); + waitForBindings(1, ADDRESS, 1, 0, true); + waitForBindings(2, ADDRESS, 1, 0, true); - addConsumer(0, 0, QUEUE, null); + waitForBindings(0, ADDRESS, 2, 0, false); + waitForBindings(1, ADDRESS, 2, 0, false); + waitForBindings(2, ADDRESS, 2, 0, false); - waitForBindings(0, ADDRESS, 1, 1, true); - waitForBindings(1, ADDRESS, 1, 0, true); - waitForBindings(2, ADDRESS, 1, 0, true); + addConsumer(0, 0, QUEUE, null); - waitForBindings(0, ADDRESS, 2, 0, false); - waitForBindings(1, ADDRESS, 2, 1, false); - waitForBindings(2, ADDRESS, 2, 1, false); + waitForBindings(0, ADDRESS, 1, 1, true); + waitForBindings(1, ADDRESS, 1, 0, true); + waitForBindings(2, ADDRESS, 1, 0, true); - waitForMessages(0, ADDRESS, 20); + waitForBindings(0, ADDRESS, 2, 0, false); + waitForBindings(1, ADDRESS, 2, 1, false); + waitForBindings(2, ADDRESS, 2, 1, false); - verifyReceiveAll(20, 0); - verifyNotReceive(0); + waitForMessages(0, ADDRESS, 20); - addConsumer(1, 1, QUEUE, null); - verifyNotReceive(1); - removeConsumer(1); + verifyReceiveAll(20, 0); + verifyNotReceive(0); - stopServers(); - start(); - } + addConsumer(1, 1, QUEUE, null); + verifyNotReceive(1); + removeConsumer(1); } @@ -1155,67 +1236,61 @@ public void internalTestBackAndForth2(final boolean useDuplicateDetection) throw if (useDuplicateDetection) { duplDetection = new AtomicInteger(0); } - for (int i = 0; i < 10; i++) { - setupCluster(MessageLoadBalancingType.ON_DEMAND); - - startServers(0, 1); + setupCluster(MessageLoadBalancingType.ON_DEMAND); - setupSessionFactory(0, isNetty()); - setupSessionFactory(1, isNetty()); + startServers(0, 1); - final String ADDRESS = "queues.testaddress"; - final String QUEUE = "queue0"; + setupSessionFactory(0, isNetty()); + setupSessionFactory(1, isNetty()); - createQueue(0, ADDRESS, QUEUE, null, false); - createQueue(1, ADDRESS, QUEUE, null, false); + final String ADDRESS = "queues.testaddress"; + final String QUEUE = "queue0"; - addConsumer(0, 0, QUEUE, null); + createQueue(0, ADDRESS, QUEUE, null, false); + createQueue(1, ADDRESS, QUEUE, null, false); - waitForBindings(0, ADDRESS, 1, 1, true); - waitForBindings(1, ADDRESS, 1, 0, true); + addConsumer(0, 0, QUEUE, null); - waitForBindings(0, ADDRESS, 1, 0, false); - waitForBindings(1, ADDRESS, 1, 1, false); - - send(1, ADDRESS, 20, false, null, duplDetection); + waitForBindings(0, ADDRESS, 1, 1, true); + waitForBindings(1, ADDRESS, 1, 0, true); - waitForMessages(0, ADDRESS, 20); + waitForBindings(0, ADDRESS, 1, 0, false); + waitForBindings(1, ADDRESS, 1, 1, false); - removeConsumer(0); + send(1, ADDRESS, 20, false, null, duplDetection); - waitForBindings(0, ADDRESS, 1, 0, true); - waitForBindings(1, ADDRESS, 1, 0, true); + waitForMessages(0, ADDRESS, 20); - waitForBindings(0, ADDRESS, 1, 0, false); - waitForBindings(1, ADDRESS, 1, 0, false); + removeConsumer(0); - addConsumer(1, 1, QUEUE, null); + waitForBindings(0, ADDRESS, 1, 0, true); + waitForBindings(1, ADDRESS, 1, 0, true); - waitForMessages(1, ADDRESS, 20); - waitForMessages(0, ADDRESS, 0); + waitForBindings(0, ADDRESS, 1, 0, false); + waitForBindings(1, ADDRESS, 1, 0, false); - waitForBindings(0, ADDRESS, 1, 1, false); - waitForBindings(1, ADDRESS, 1, 0, false); + addConsumer(1, 1, QUEUE, null); - removeConsumer(1); + waitForMessages(1, ADDRESS, 20); + waitForMessages(0, ADDRESS, 0); - addConsumer(0, 0, QUEUE, null); + waitForBindings(0, ADDRESS, 1, 1, false); + waitForBindings(1, ADDRESS, 1, 0, false); - waitForMessages(1, ADDRESS, 0); - waitForMessages(0, ADDRESS, 20); + removeConsumer(1); - removeConsumer(0); - addConsumer(1, 1, QUEUE, null); + addConsumer(0, 0, QUEUE, null); - waitForMessages(1, ADDRESS, 20); - waitForMessages(0, ADDRESS, 0); + waitForMessages(1, ADDRESS, 0); + waitForMessages(0, ADDRESS, 20); - verifyReceiveAll(20, 1); + removeConsumer(0); + addConsumer(1, 1, QUEUE, null); - stopServers(); - start(); - } + waitForMessages(1, ADDRESS, 20); + waitForMessages(0, ADDRESS, 0); + verifyReceiveAll(20, 1); } @Test @@ -1258,7 +1333,7 @@ public void testRedistributionToQueuesWhereNotAllMessagesMatch() throws Exceptio @Test public void testDelayedRedistribution() throws Exception { - final long delay = 1000; + final long delay = 200; setRedistributionDelay(delay); setupCluster(MessageLoadBalancingType.ON_DEMAND); @@ -1297,7 +1372,7 @@ public void testDelayedRedistribution() throws Exception { @Test public void testDelayedRedistributionCancelled() throws Exception { - final long delay = 1000; + final long delay = 200; setRedistributionDelay(delay); setupCluster(MessageLoadBalancingType.ON_DEMAND); @@ -1361,16 +1436,16 @@ public void testRedistributionNumberOfMessagesGreaterThanBatchSize() throws Exce waitForBindings(1, "queues.testaddress", 2, 1, false); waitForBindings(2, "queues.testaddress", 2, 1, false); - send(0, "queues.testaddress", 200, false, null); + send(0, "queues.testaddress", 10, false, null); removeConsumer(0); addConsumer(1, 1, "queue0", null); Queue queue = servers[1].locateQueue(SimpleString.of("queue0")); assertNotNull(queue); - Wait.waitFor(() -> queue.getMessageCount() == 200); + Wait.waitFor(() -> queue.getMessageCount() == 10); - for (int i = 0; i < 200; i++) { + for (int i = 0; i < 10; i++) { ClientMessage message = consumers[1].getConsumer().receive(5000); assertNotNull(message); message.acknowledge(); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/SymmetricClusterTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/SymmetricClusterTest.java index 63c51eb8c42..86c77e51036 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/SymmetricClusterTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/SymmetricClusterTest.java @@ -1396,7 +1396,7 @@ public void testNoLocalQueueLoadBalancedQueues() throws Exception { @Test public void testStartStopServers() throws Exception { - doTestStartStopServers(1, 3000); + doTestStartStopServers(); } protected void validateTopologSize(int expectedSize, int... serverParameters) throws Exception { @@ -1411,7 +1411,7 @@ protected void validateTopologSize(int expectedSize, int... serverParameters) th } } - public void doTestStartStopServers(long pauseBeforeServerRestarts, long pauseAfterServerRestarts) throws Exception { + public void doTestStartStopServers() throws Exception { setupCluster(); startServers(); @@ -1535,14 +1535,10 @@ public void doTestStartStopServers(long pauseBeforeServerRestarts, long pauseAft stopServers(0, 3); - Thread.sleep(pauseBeforeServerRestarts); - validateTopologSize(3, 1, 2, 4); startServers(3, 0); - Thread.sleep(pauseAfterServerRestarts); - validateTopologSize(5, 0, 1, 2, 3, 4); setupSessionFactory(0, isNetty()); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/SymmetricClusterWithBackupTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/SymmetricClusterWithBackupTest.java index af2aa428dab..6db73320384 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/SymmetricClusterWithBackupTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/SymmetricClusterWithBackupTest.java @@ -359,8 +359,6 @@ public void testStartStopServers() throws Exception { startServers(0, 3, 5, 8); - Thread.sleep(2000); - setupSessionFactory(0, isNetty()); setupSessionFactory(3, isNetty()); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/SymmetricClusterWithDiscoveryTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/SymmetricClusterWithDiscoveryTest.java index 2f8f0e3f4d9..ab4b5133f90 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/SymmetricClusterWithDiscoveryTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/SymmetricClusterWithDiscoveryTest.java @@ -35,7 +35,7 @@ protected boolean isNetty() { @Test public void testStartStopServers() throws Exception { // When using discovery starting and stopping it too fast could have a race condition with UDP - doTestStartStopServers(3000, 3000); + doTestStartStopServers(); } @Override @@ -71,6 +71,6 @@ protected void setupServers() throws Exception { */ @Test public void testStartStopServersWithPauseBeforeRestarting() throws Exception { - doTestStartStopServers(10000, 3000); + doTestStartStopServers(); } } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/TwoWayTwoNodeClusterTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/TwoWayTwoNodeClusterTest.java index 59e91c834fb..de9b6b6f1c4 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/TwoWayTwoNodeClusterTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/distribution/TwoWayTwoNodeClusterTest.java @@ -29,6 +29,7 @@ import org.apache.activemq.artemis.core.server.cluster.impl.MessageLoadBalancingType; import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy; import org.apache.activemq.artemis.core.settings.impl.AddressSettings; +import org.apache.activemq.artemis.utils.Wait; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; @@ -108,15 +109,7 @@ public void testClusterRestartWithConfigChanged() throws Exception { session0.commit(); session0.close(); - while (true) { - long msgCount0 = getMessageCount(servers[0], "queues"); - long msgCount1 = getMessageCount(servers[1], "queues"); - - if (msgCount0 + msgCount1 >= numSent) { - break; - } - Thread.sleep(100); - } + Wait.assertTrue(() -> getMessageCount(servers[0], "queues") + getMessageCount(servers[1], "queues") >= numSent, 5000); Queue queue0 = servers[0].locateQueue(SimpleString.of("queue0")); assertTrue(queue0.getPageSubscription().isPaging()); @@ -153,9 +146,8 @@ private void configureBeforeStart(Configuration... serverConfigs) { for (Configuration config : serverConfigs) { config.setPersistenceEnabled(true); config.setMessageCounterEnabled(true); - config.setJournalFileSize(20971520); - config.setJournalMinFiles(20); - config.setJournalCompactPercentage(50); + config.setJournalFileSize(20 * 1024); + config.setJournalMinFiles(5); Map addressSettingsMap0 = config.getAddressSettings(); AddressSettings addrSettings = addressSettingsMap0.get("#"); @@ -230,34 +222,6 @@ public void testStartPauseStartOther() throws Exception { stopServers(0, 1); } - @Test - public void testRestartServers() throws Throwable { - String name = Thread.currentThread().getName(); - try { - Thread.currentThread().setName("ThreadOnTestRestartTest"); - startServers(0, 1); - waitForTopology(servers[0], 2); - - waitForTopology(servers[1], 2); - - for (int i = 0; i < 10; i++) { - logger.debug("Sleep #test {}", i); - logger.debug("#stop #test #{}", i); - Thread.sleep(500); - stopServers(1); - - waitForTopology(servers[0], 1, -1, 2000); - logger.debug("#start #test #{}", i); - startServers(1); - waitForTopology(servers[0], 2, -1, 2000); - waitForTopology(servers[1], 2, -1, 2000); - } - } finally { - Thread.currentThread().setName(name); - } - - } - @Test public void testStopStart() throws Exception { startServers(0, 1); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailBackAutoTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailBackAutoTest.java index 6351915d9d5..47f7925da33 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailBackAutoTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailBackAutoTest.java @@ -19,15 +19,12 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import java.lang.invoke.MethodHandles; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import org.apache.activemq.artemis.api.core.QueueConfiguration; -import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.api.core.TransportConfiguration; import org.apache.activemq.artemis.api.core.client.ClientConsumer; import org.apache.activemq.artemis.api.core.client.ClientMessage; @@ -41,7 +38,6 @@ import org.apache.activemq.artemis.core.config.ha.SharedStorePrimaryPolicyConfiguration; import org.apache.activemq.artemis.core.server.cluster.ha.SharedStoreBackupPolicy; import org.apache.activemq.artemis.core.server.impl.InVMNodeManager; -import org.apache.activemq.artemis.jms.client.ActiveMQTextMessage; import org.apache.activemq.artemis.tests.util.CountDownSessionFailureListener; import org.apache.activemq.artemis.tests.util.TransportConfigurationUtils; import org.junit.jupiter.api.BeforeEach; @@ -277,45 +273,4 @@ protected TransportConfiguration getAcceptorTransportConfiguration(final boolean protected TransportConfiguration getConnectorTransportConfiguration(final boolean primary) { return TransportConfigurationUtils.getInVMConnector(primary); } - - private ClientSession sendAndConsume(final ClientSessionFactory sf, final boolean createQueue) throws Exception { - ClientSession session = sf.createSession(false, true, true); - - if (createQueue) { - session.createQueue(QueueConfiguration.of(ADDRESS)); - } - - ClientProducer producer = session.createProducer(ADDRESS); - - final int numMessages = 1000; - - for (int i = 0; i < numMessages; i++) { - ClientMessage message = session.createMessage(ActiveMQTextMessage.TYPE, false, 0, System.currentTimeMillis(), (byte) 1); - message.putIntProperty(SimpleString.of("count"), i); - message.getBodyBuffer().writeString("aardvarks"); - producer.send(message); - } - - ClientConsumer consumer = session.createConsumer(ADDRESS); - - session.start(); - - for (int i = 0; i < numMessages; i++) { - ClientMessage message2 = consumer.receive(); - - assertEquals("aardvarks", message2.getBodyBuffer().readString()); - - assertEquals(i, message2.getObjectProperty(SimpleString.of("count"))); - - message2.acknowledge(); - } - - ClientMessage message3 = consumer.receiveImmediate(); - - consumer.close(); - - assertNull(message3); - - return session; - } } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailBackManualTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailBackManualTest.java index bb022492c1f..aaf1be0c66e 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailBackManualTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailBackManualTest.java @@ -17,25 +17,19 @@ package org.apache.activemq.artemis.tests.integration.cluster.failover; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.concurrent.TimeUnit; -import org.apache.activemq.artemis.api.core.QueueConfiguration; -import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.api.core.TransportConfiguration; -import org.apache.activemq.artemis.api.core.client.ClientConsumer; import org.apache.activemq.artemis.api.core.client.ClientMessage; import org.apache.activemq.artemis.api.core.client.ClientProducer; import org.apache.activemq.artemis.api.core.client.ClientSession; -import org.apache.activemq.artemis.api.core.client.ClientSessionFactory; import org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryInternal; import org.apache.activemq.artemis.core.client.impl.ServerLocatorInternal; import org.apache.activemq.artemis.core.config.ha.SharedStoreBackupPolicyConfiguration; import org.apache.activemq.artemis.core.config.ha.SharedStorePrimaryPolicyConfiguration; import org.apache.activemq.artemis.core.server.impl.InVMNodeManager; -import org.apache.activemq.artemis.jms.client.ActiveMQTextMessage; import org.apache.activemq.artemis.tests.integration.cluster.util.TestableServer; import org.apache.activemq.artemis.tests.util.CountDownSessionFailureListener; import org.apache.activemq.artemis.tests.util.TransportConfigurationUtils; @@ -129,45 +123,6 @@ protected TransportConfiguration getConnectorTransportConfiguration(final boolea return TransportConfigurationUtils.getInVMConnector(live); } - private ClientSession sendAndConsume(final ClientSessionFactory sf, final boolean createQueue) throws Exception { - ClientSession session = sf.createSession(false, true, true); - - if (createQueue) { - session.createQueue(QueueConfiguration.of(ADDRESS).setDurable(false)); - } - - ClientProducer producer = session.createProducer(ADDRESS); - - final int numMessages = 1000; - - for (int i = 0; i < numMessages; i++) { - ClientMessage message = session.createMessage(ActiveMQTextMessage.TYPE, false, 0, System.currentTimeMillis(), (byte) 1); - message.putIntProperty(SimpleString.of("count"), i); - message.getBodyBuffer().writeString("aardvarks"); - producer.send(message); - } - - ClientConsumer consumer = session.createConsumer(ADDRESS); - - session.start(); - - for (int i = 0; i < numMessages; i++) { - ClientMessage message2 = consumer.receive(); - - assertEquals("aardvarks", message2.getBodyBuffer().readString()); - - assertEquals(i, message2.getObjectProperty(SimpleString.of("count"))); - - message2.acknowledge(); - } - - ClientMessage message3 = consumer.receiveImmediate(); - - assertNull(message3); - - return session; - } - /** * @param i * @param message diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailoverListenerTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailoverListenerTest.java index 38ced7d2f2f..2bc7d9fb092 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailoverListenerTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailoverListenerTest.java @@ -18,7 +18,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import java.lang.invoke.MethodHandles; @@ -26,8 +25,6 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import org.apache.activemq.artemis.api.core.QueueConfiguration; -import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.api.core.TransportConfiguration; import org.apache.activemq.artemis.api.core.client.ClientConsumer; import org.apache.activemq.artemis.api.core.client.ClientMessage; @@ -42,7 +39,6 @@ import org.apache.activemq.artemis.core.config.ha.SharedStoreBackupPolicyConfiguration; import org.apache.activemq.artemis.core.config.ha.SharedStorePrimaryPolicyConfiguration; import org.apache.activemq.artemis.core.server.impl.InVMNodeManager; -import org.apache.activemq.artemis.jms.client.ActiveMQTextMessage; import org.apache.activemq.artemis.tests.util.TransportConfigurationUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -215,47 +211,6 @@ protected TransportConfiguration getConnectorTransportConfiguration(final boolea return TransportConfigurationUtils.getInVMConnector(primary); } - private ClientSession sendAndConsume(final ClientSessionFactory sf, final boolean createQueue) throws Exception { - ClientSession session = sf.createSession(false, true, true); - - if (createQueue) { - session.createQueue(QueueConfiguration.of(ADDRESS)); - } - - ClientProducer producer = session.createProducer(ADDRESS); - - final int numMessages = 1000; - - for (int i = 0; i < numMessages; i++) { - ClientMessage message = session.createMessage(ActiveMQTextMessage.TYPE, false, 0, System.currentTimeMillis(), (byte) 1); - message.putIntProperty(SimpleString.of("count"), i); - message.getBodyBuffer().writeString("aardvarks"); - producer.send(message); - } - - ClientConsumer consumer = session.createConsumer(ADDRESS); - - session.start(); - - for (int i = 0; i < numMessages; i++) { - ClientMessage message2 = consumer.receive(); - - assertEquals("aardvarks", message2.getBodyBuffer().readString()); - - assertEquals(i, message2.getObjectProperty(SimpleString.of("count"))); - - message2.acknowledge(); - } - - ClientMessage message3 = consumer.receiveImmediate(); - - consumer.close(); - - assertNull(message3); - - return session; - } - public class SessionFactoryFailoverListener implements FailoverEventListener { private final ArrayList failoverTypeEvent = new ArrayList<>(); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailoverTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailoverTest.java index 7f711034d3c..2ab4b172e20 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailoverTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailoverTest.java @@ -16,30 +16,11 @@ */ package org.apache.activemq.artemis.tests.integration.cluster.failover; -import javax.transaction.xa.XAException; -import javax.transaction.xa.XAResource; -import javax.transaction.xa.Xid; import java.lang.invoke.MethodHandles; import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import org.apache.activemq.artemis.api.core.ActiveMQDuplicateIdException; import org.apache.activemq.artemis.api.core.ActiveMQException; -import org.apache.activemq.artemis.api.core.ActiveMQExceptionType; -import org.apache.activemq.artemis.api.core.ActiveMQInternalErrorException; -import org.apache.activemq.artemis.api.core.ActiveMQObjectClosedException; -import org.apache.activemq.artemis.api.core.ActiveMQTransactionOutcomeUnknownException; -import org.apache.activemq.artemis.api.core.ActiveMQTransactionRolledBackException; -import org.apache.activemq.artemis.api.core.Interceptor; -import org.apache.activemq.artemis.api.core.Message; import org.apache.activemq.artemis.api.core.QueueConfiguration; import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.api.core.TransportConfiguration; @@ -47,42 +28,13 @@ import org.apache.activemq.artemis.api.core.client.ClientMessage; import org.apache.activemq.artemis.api.core.client.ClientProducer; import org.apache.activemq.artemis.api.core.client.ClientSession; -import org.apache.activemq.artemis.api.core.client.ClientSessionFactory; -import org.apache.activemq.artemis.api.core.client.FailoverEventType; -import org.apache.activemq.artemis.api.core.client.ServerLocator; -import org.apache.activemq.artemis.api.core.client.SessionFailureListener; import org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl; import org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryInternal; -import org.apache.activemq.artemis.core.client.impl.ClientSessionInternal; -import org.apache.activemq.artemis.core.client.impl.ServerLocatorImpl; -import org.apache.activemq.artemis.core.protocol.core.Channel; -import org.apache.activemq.artemis.core.protocol.core.Packet; -import org.apache.activemq.artemis.core.protocol.core.impl.ActiveMQSessionContext; -import org.apache.activemq.artemis.core.protocol.core.impl.ChannelImpl; -import org.apache.activemq.artemis.core.protocol.core.impl.PacketImpl; -import org.apache.activemq.artemis.core.protocol.core.impl.RemotingConnectionImpl; -import org.apache.activemq.artemis.core.protocol.core.impl.wireformat.ActiveMQExceptionMessage; -import org.apache.activemq.artemis.core.server.cluster.BackupManager; -import org.apache.activemq.artemis.core.server.cluster.ClusterController; -import org.apache.activemq.artemis.core.server.cluster.ha.BackupPolicy; import org.apache.activemq.artemis.core.server.cluster.ha.HAPolicy; import org.apache.activemq.artemis.core.server.cluster.ha.ReplicaPolicy; -import org.apache.activemq.artemis.core.server.cluster.ha.ReplicatedPolicy; import org.apache.activemq.artemis.core.server.cluster.ha.ReplicationBackupPolicy; -import org.apache.activemq.artemis.core.server.cluster.ha.ReplicationPrimaryPolicy; -import org.apache.activemq.artemis.core.server.cluster.ha.SharedStoreBackupPolicy; -import org.apache.activemq.artemis.core.server.cluster.ha.SharedStorePrimaryPolicy; -import org.apache.activemq.artemis.core.server.cluster.impl.ClusterConnectionImpl; import org.apache.activemq.artemis.core.server.files.FileMoveManager; -import org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl; -import org.apache.activemq.artemis.core.server.impl.InVMNodeManager; -import org.apache.activemq.artemis.core.transaction.impl.XidImpl; -import org.apache.activemq.artemis.jms.client.ActiveMQTextMessage; -import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection; import org.apache.activemq.artemis.tests.integration.cluster.util.TestableServer; -import org.apache.activemq.artemis.tests.util.CountDownSessionFailureListener; -import org.apache.activemq.artemis.tests.util.TransportConfigurationUtils; -import org.apache.activemq.artemis.utils.RandomUtil; import org.apache.activemq.artemis.utils.Wait; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -92,2517 +44,299 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; -import static org.junit.jupiter.api.Assumptions.assumeTrue; public class FailoverTest extends FailoverTestBase { private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - protected static final int NUM_MESSAGES = 100; - - protected ServerLocator locator; - protected ClientSessionFactoryInternal sf; - - @Override - @BeforeEach - public void setUp() throws Exception { - super.setUp(); - locator = getServerLocator(); - } - - protected ClientSession createSession(ClientSessionFactory sf1, - boolean autoCommitSends, - boolean autoCommitAcks, - int ackBatchSize) throws Exception { - return addClientSession(sf1.createSession(autoCommitSends, autoCommitAcks, ackBatchSize)); - } - - protected ClientSession createSession(ClientSessionFactory sf1, - boolean autoCommitSends, - boolean autoCommitAcks) throws Exception { - return addClientSession(sf1.createSession(autoCommitSends, autoCommitAcks)); - } - - protected ClientSession createSession(ClientSessionFactory sf1) throws Exception { - return addClientSession(sf1.createSession()); - } - - protected ClientSession createSession(ClientSessionFactory sf1, - boolean xa, - boolean autoCommitSends, - boolean autoCommitAcks) throws Exception { - return addClientSession(sf1.createSession(xa, autoCommitSends, autoCommitAcks)); - } - - // https://issues.jboss.org/browse/HORNETQ-685 - @Test - @Timeout(120) - public void testTimeoutOnFailover() throws Exception { - locator.setCallTimeout(1000).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setAckBatchSize(0).setReconnectAttempts(300).setRetryInterval(10); - - if (nodeManager instanceof InVMNodeManager) { - ((InVMNodeManager) nodeManager).failoverPause = 500L; - } - - ClientSessionFactoryInternal sf1 = (ClientSessionFactoryInternal) createSessionFactory(locator); - - final ClientSession session = createSession(sf1, true, true); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - - final ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - final CountDownLatch latch = new CountDownLatch(10); - final CountDownLatch latchFailed = new CountDownLatch(1); - - Runnable r = () -> { - for (int i = 0; i < 500; i++) { - ClientMessage message = session.createMessage(true); - message.putIntProperty("counter", i); - try { - producer.send(message); - if (i < 10) { - latch.countDown(); - if (latch.getCount() == 0) { - latchFailed.await(10, TimeUnit.SECONDS); - } - } - } catch (Exception e) { - // this is our retry - try { - if (!producer.isClosed()) - producer.send(message); - } catch (ActiveMQException e1) { - e1.printStackTrace(); - } - } - } - }; - Thread t = new Thread(r); - t.start(); - assertTrue(latch.await(10, TimeUnit.SECONDS), "latch released"); - crash(session); - latchFailed.countDown(); - t.join(30000); - if (t.isAlive()) { - t.interrupt(); - fail("Thread still alive"); - } - assertTrue(backupServer.getServer().waitForActivation(5, TimeUnit.SECONDS)); - ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - session.start(); - for (int i = 0; i < 500; i++) { - ClientMessage m = consumer.receive(1000); - assertNotNull(m, "message #=" + i); - // assertEquals(i, m.getIntProperty("counter").intValue()); - } - } - - // https://issues.jboss.org/browse/HORNETQ-685 - @Test - @Timeout(120) - public void testTimeoutOnFailoverConsume() throws Exception { - locator.setCallTimeout(1000).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setAckBatchSize(0).setBlockOnAcknowledge(true).setReconnectAttempts(-1).setRetryInterval(10).setAckBatchSize(0); - - if (nodeManager instanceof InVMNodeManager) { - ((InVMNodeManager) nodeManager).failoverPause = 2000L; - } - - ClientSessionFactoryInternal sf1 = (ClientSessionFactoryInternal) createSessionFactory(locator); - - final ClientSession session = createSession(sf1, true, false); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - - final ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - for (int i = 0; i < 500; i++) { - ClientMessage message = session.createMessage(true); - message.putIntProperty("counter", i); - producer.send(message); - } - - final CountDownLatch latch = new CountDownLatch(1); - final CountDownLatch endLatch = new CountDownLatch(1); - - final ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - session.start(); - - final Map received = new HashMap<>(); - - consumer.setMessageHandler(message -> { - - Integer counter = message.getIntProperty("counter"); - received.put(counter, message); - try { - logger.debug("acking message = id = {}, counter = {}", message.getMessageID(), message.getIntProperty("counter")); - message.acknowledge(); - session.commit(); - } catch (ActiveMQException e) { - try { - session.rollback(); - } catch (Exception e2) { - e.printStackTrace(); - } - e.printStackTrace(); - return; - } - logger.debug("Acked counter = {}", counter); - if (counter.equals(10)) { - latch.countDown(); - } - if (received.size() == 100) { - endLatch.countDown(); - } - }); - latch.await(10, TimeUnit.SECONDS); - logger.debug("crashing session"); - crash(session); - assertTrue(endLatch.await(60, TimeUnit.SECONDS)); - - session.close(); - } - - @Test - @Timeout(120) - public void testTimeoutOnFailoverConsumeBlocked() throws Exception { - locator.setCallTimeout(1000).setBlockOnNonDurableSend(true).setConsumerWindowSize(0).setBlockOnDurableSend(true).setAckBatchSize(0).setBlockOnAcknowledge(true).setReconnectAttempts(-1).setAckBatchSize(0).setRetryInterval(10); - - if (nodeManager instanceof InVMNodeManager) { - ((InVMNodeManager) nodeManager).failoverPause = 200L; - } - - ClientSessionFactoryInternal sf1 = (ClientSessionFactoryInternal) createSessionFactory(locator); - - final ClientSession session = createSession(sf1, true, true); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - - final ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - for (int i = 0; i < 500; i++) { - ClientMessage message = session.createMessage(true); - message.putIntProperty("counter", i); - message.putBooleanProperty("end", i == 499); - producer.send(message); - } - - final CountDownLatch latch = new CountDownLatch(1); - final CountDownLatch endLatch = new CountDownLatch(1); - - final ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - session.start(); - - final Map received = new HashMap<>(); - - Thread t = new Thread() { - @Override - public void run() { - ClientMessage message = null; - try { - while ((message = getMessage()) != null) { - Integer counter = message.getIntProperty("counter"); - received.put(counter, message); - try { - logger.debug("acking message = id = {}, counter = {}", message.getMessageID(), message.getIntProperty("counter")); - message.acknowledge(); - } catch (ActiveMQException e) { - e.printStackTrace(); - continue; - } - logger.debug("Acked counter = {}", counter); - if (counter.equals(10)) { - latch.countDown(); - } - if (received.size() == 500) { - endLatch.countDown(); - } - - if (message.getBooleanProperty("end")) { - break; - } - } - } catch (Exception e) { - fail("failing due to exception " + e); - } - - } - - private ClientMessage getMessage() { - while (true) { - try { - ClientMessage msg = consumer.receive(20000); - if (msg == null) { - logger.debug("Returning null message on consuming"); - } - return msg; - } catch (ActiveMQObjectClosedException oce) { - throw new RuntimeException(oce); - } catch (ActiveMQException ignored) { - // retry - ignored.printStackTrace(); - } - } - } - }; - t.start(); - latch.await(10, TimeUnit.SECONDS); - logger.debug("crashing session"); - crash(session); - endLatch.await(60, TimeUnit.SECONDS); - t.join(); - assertTrue(received.size() == 500, "received only " + received.size()); - - session.close(); - } - - // https://issues.jboss.org/browse/HORNETQ-685 - @Test - @Timeout(120) - public void testTimeoutOnFailoverTransactionCommit() throws Exception { - locator.setCallTimeout(1000).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setAckBatchSize(0).setReconnectAttempts(300).setRetryInterval(10); - - if (nodeManager instanceof InVMNodeManager) { - ((InVMNodeManager) nodeManager).failoverPause = 2000L; - } - - ClientSessionFactoryInternal sf1 = (ClientSessionFactoryInternal) createSessionFactory(locator); - - final ClientSession session = createSession(sf1, true, false, false); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - - final CountDownLatch connectionFailed = new CountDownLatch(1); - - session.addFailureListener(new SessionFailureListener() { - @Override - public void beforeReconnect(ActiveMQException exception) { - } - - @Override - public void connectionFailed(ActiveMQException exception, boolean failedOver) { - } - - @Override - public void connectionFailed(ActiveMQException exception, boolean failedOver, String scaleDownTargetNodeID) { - connectionFailed.countDown(); - } - }); - - final ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - Xid xid = new XidImpl("uhuhuhu".getBytes(), 126512, "auhsduashd".getBytes()); - - session.start(xid, XAResource.TMNOFLAGS); - - for (int i = 0; i < 500; i++) { - ClientMessage message = session.createMessage(true); - message.putIntProperty("counter", i); - - producer.send(message); - - } - session.end(xid, XAResource.TMSUCCESS); - session.prepare(xid); - crash(true, session); - - try { - session.commit(xid, false); - } catch (XAException e) { - //there is still an edge condition that we must deal with - assertTrue(connectionFailed.await(10, TimeUnit.SECONDS)); - session.commit(xid, false); - } - - ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - session.start(); - for (int i = 0; i < 500; i++) { - ClientMessage m = consumer.receive(1000); - assertNotNull(m); - assertEquals(i, m.getIntProperty("counter").intValue()); - } - } - - /** - * This test would fail one in three or five times, - * where the commit would leave the session dirty after a timeout. - */ - @Test - @Timeout(120) - public void testTimeoutOnFailoverTransactionCommitTimeoutCommunication() throws Exception { - locator.setCallTimeout(1000).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setAckBatchSize(0).setReconnectAttempts(300).setRetryInterval(50); - - if (nodeManager instanceof InVMNodeManager) { - ((InVMNodeManager) nodeManager).failoverPause = 2000L; - } - - ClientSessionFactoryInternal sf1 = (ClientSessionFactoryInternal) createSessionFactory(locator); - final ClientSession session = createSession(sf1, false, false, false); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - - final CountDownLatch connectionFailed = new CountDownLatch(1); - - session.addFailureListener(new SessionFailureListener() { - @Override - public void beforeReconnect(ActiveMQException exception) { - } - - @Override - public void connectionFailed(ActiveMQException exception, boolean failedOver) { - } - - @Override - public void connectionFailed(ActiveMQException exception, boolean failedOver, String scaleDownTargetNodeID) { - connectionFailed.countDown(); - } - }); - - final ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - for (int i = 0; i < 500; i++) { - ClientMessage message = session.createMessage(true); - message.putIntProperty("counter", i); - - producer.send(message); - - } - - session.commit(); - - - ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - session.start(); - ClientMessage m = null; - for (int i = 0; i < 500; i++) { - m = consumer.receive(1000); - assertNotNull(m); - assertEquals(i, m.getIntProperty("counter").intValue()); - } - - m.acknowledge(); - - crash(false, session); - try { - session.commit(); - fail("Exception expected"); - } catch (Exception expected) { - expected.printStackTrace(); - } - - Thread.sleep(1000); - - m = null; - for (int i = 0; i < 500; i++) { - m = consumer.receive(1000); - assertNotNull(m); - assertEquals(i, m.getIntProperty("counter").intValue()); - } - - m.acknowledge(); - - session.commit(); - - } - - // https://issues.jboss.org/browse/HORNETQ-685 - @Test - @Timeout(120) - public void testTimeoutOnFailoverTransactionRollback() throws Exception { - locator.setCallTimeout(2000).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setAckBatchSize(0).setReconnectAttempts(300).setRetryInterval(10); - - if (nodeManager instanceof InVMNodeManager) { - ((InVMNodeManager) nodeManager).failoverPause = 1000L; - } - - ClientSessionFactoryInternal sf1 = (ClientSessionFactoryInternal) createSessionFactory(locator); - - final ClientSession session = createSession(sf1, true, false, false); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - - final ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - Xid xid = new XidImpl("uhuhuhu".getBytes(), 126512, "auhsduashd".getBytes()); - - session.start(xid, XAResource.TMNOFLAGS); - - for (int i = 0; i < 500; i++) { - ClientMessage message = session.createMessage(true); - message.putIntProperty("counter", i); - - producer.send(message); - } - - session.end(xid, XAResource.TMSUCCESS); - session.prepare(xid); - crash(true, session); - - try { - session.rollback(xid); - } catch (XAException e) { - try { - //there is still an edge condition that we must deal with - session.rollback(xid); - } catch (Exception ignored) { - logger.trace(ignored.getMessage(), ignored); - } - } - - ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - session.start(); - - ClientMessage m = consumer.receiveImmediate(); - assertNull(m); - - } - - /** - * see http://jira.jboss.org/browse/HORNETQ-522 - * - * @throws Exception - */ - @Test - @Timeout(120) - public void testNonTransactedWithZeroConsumerWindowSize() throws Exception { - locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setAckBatchSize(0).setReconnectAttempts(300).setRetryInterval(10); - - createClientSessionFactory(); - - ClientSession session = createSession(sf, true, true); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - for (int i = 0; i < NUM_MESSAGES; i++) { - ClientMessage message = session.createMessage(true); - - setBody(i, message); - - message.putIntProperty("counter", i); - - producer.send(message); - } - - ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - - final CountDownLatch latch = new CountDownLatch(NUM_MESSAGES); - - consumer.setMessageHandler(message -> latch.countDown()); - - session.start(); - - crash(session); - - assertTrue(latch.await(10, TimeUnit.SECONDS)); - - } - - protected void createClientSessionFactory() throws Exception { - sf = (ClientSessionFactoryInternal) createSessionFactory(locator); - } - - @Test - @Timeout(120) - public void testNonTransacted() throws Exception { - createSessionFactory(); - - ClientSession session = createSession(sf, true, true); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - sendMessagesSomeDurable(session, producer); - - crash(session); - - ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - - session.start(); - - receiveDurableMessages(consumer); - - session.close(); - - sf.close(); - - assertEquals(0, sf.numSessions()); - - assertEquals(0, sf.numConnections()); - } - - @Test - @Timeout(60) - public void testFailBothRestartPrimary() throws Exception { - ServerLocator locator = getServerLocator(); - - locator.setReconnectAttempts(-1).setRetryInterval(10); - - sf = (ClientSessionFactoryInternal)locator.createSessionFactory(); - - ClientSession session = createSession(sf, true, true); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - sendMessagesSomeDurable(session, producer); - - crash(session); - - ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - - session.start(); - - receiveDurableMessages(consumer); - - backupServer.getServer().fail(true); - - decrementActivationSequenceForForceRestartOf(primaryServer); - - primaryServer.start(); - - consumer.close(); - - producer.close(); - - producer = session.createProducer(FailoverTestBase.ADDRESS); - - sendMessagesSomeDurable(session, producer); - - sf.close(); - assertEquals(0, sf.numSessions()); - assertEquals(0, sf.numConnections()); - } - - @Test - public void testFailPrimaryTooSoon() throws Exception { - ServerLocator locator = getServerLocator(); - - locator.setReconnectAttempts(-1); - locator.setRetryInterval(10); - - sf = (ClientSessionFactoryInternal)locator.createSessionFactory(); - - waitForBackupConfig(sf); - - TransportConfiguration initialPrimary = getFieldFromSF(sf, "currentConnectorConfig"); - TransportConfiguration initialBackup = getFieldFromSF(sf, "backupConnectorConfig"); - - logger.debug("initprimary: {}", initialPrimary); - logger.debug("initback: {}", initialBackup); - - TransportConfiguration last = getFieldFromSF(sf, "connectorConfig"); - TransportConfiguration current = getFieldFromSF(sf, "currentConnectorConfig"); - - logger.debug("now last: {}", last); - logger.debug("now current: {}", current); - assertTrue(current.equals(initialPrimary)); - - ClientSession session = createSession(sf, true, true); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - - //crash 1 - crash(); - - //make sure failover is ok - createSession(sf, true, true).close(); - - last = getFieldFromSF(sf, "connectorConfig"); - current = getFieldFromSF(sf, "currentConnectorConfig"); - - logger.debug("now after primary crashed last: {}", last); - logger.debug("now current: {}", current); - - assertTrue(current.equals(initialBackup)); - - //fail back - beforeRestart(primaryServer); - adaptPrimaryConfigForReplicatedFailBack(primaryServer); - primaryServer.getServer().start(); - - assertTrue(primaryServer.getServer().waitForActivation(40, TimeUnit.SECONDS), "primary initialized..."); - Wait.assertTrue(backupServer::isStarted); - primaryServer.getServer().waitForActivation(5, TimeUnit.SECONDS); - assertTrue(backupServer.isStarted()); - - //make sure failover is ok - createSession(sf, true, true).close(); - - last = getFieldFromSF(sf, "connectorConfig"); - current = getFieldFromSF(sf, "currentConnectorConfig"); - - logger.debug("now after primary back again last: {}", last); - logger.debug("now current: {}", current); - - //cannot use equals here because the config's name (uuid) changes - //after failover - assertTrue(current.isSameParams(initialPrimary)); - - //now manually corrupt the backup in sf - setSFFieldValue(sf, "backupConnectorConfig", null); - - //crash 2 - crash(); - - beforeRestart(backupServer); - createSession(sf, true, true).close(); - - sf.close(); - assertEquals(0, sf.numSessions()); - assertEquals(0, sf.numConnections()); - } - - protected void waitForBackupConfig(ClientSessionFactoryInternal sf) throws NoSuchFieldException, IllegalAccessException, InterruptedException { - TransportConfiguration initialBackup = getFieldFromSF(sf, "backupConnectorConfig"); - int cnt = 50; - while (initialBackup == null && cnt > 0) { - cnt--; - Thread.sleep(200); - initialBackup = getFieldFromSF(sf, "backupConnectorConfig"); - } - } - - protected void setSFFieldValue(ClientSessionFactoryInternal sf, String tcName, Object value) throws NoSuchFieldException, IllegalAccessException { - Field tcField = ClientSessionFactoryImpl.class.getDeclaredField(tcName); - tcField.setAccessible(true); - tcField.set(sf, value); - } - - protected TransportConfiguration getFieldFromSF(ClientSessionFactoryInternal sf, String tcName) throws NoSuchFieldException, IllegalAccessException { - Field tcField = ClientSessionFactoryImpl.class.getDeclaredField(tcName); - tcField.setAccessible(true); - return (TransportConfiguration) tcField.get(sf); - } - - /** - * Basic fail-back test. - * - * @throws Exception - */ - @Test - @Timeout(120) - public void testFailBack() throws Exception { - boolean doFailBack = true; - HAPolicy haPolicy = backupServer.getServer().getHAPolicy(); - if (haPolicy instanceof ReplicaPolicy) { - ((ReplicaPolicy) haPolicy).setMaxSavedReplicatedJournalsSize(1); - } - - simpleFailover(haPolicy instanceof ReplicaPolicy || haPolicy instanceof ReplicationBackupPolicy, doFailBack); - } - - @Test - @Timeout(120) - public void testFailBackPrimaryRestartsBackupIsGone() throws Exception { - createSessionFactory(); - ClientSession session = createSessionAndQueue(); - - ClientProducer producer = addClientProducer(session.createProducer(FailoverTestBase.ADDRESS)); - - sendMessages(session, producer, NUM_MESSAGES); - producer.close(); - session.commit(); - SimpleString primaryId = primaryServer.getServer().getNodeID(); - crash(session); - - session.start(); - ClientConsumer consumer = addClientConsumer(session.createConsumer(FailoverTestBase.ADDRESS)); - receiveMessages(consumer); - assertNoMoreMessages(consumer); - consumer.close(); - session.commit(); - - assertEquals(primaryId, backupServer.getServer().getNodeID(), "backup must be running with the same nodeID"); - sf.close(); - - backupServer.crash(); - Thread.sleep(100); - assertFalse(backupServer.isStarted(), "backup is not running"); - - final boolean isBackup = primaryServer.getServer().getHAPolicy() instanceof BackupPolicy || - primaryServer.getServer().getHAPolicy() instanceof ReplicationBackupPolicy; - assertFalse(isBackup, "must NOT be a backup"); - adaptPrimaryConfigForReplicatedFailBack(primaryServer); - beforeRestart(primaryServer); - decrementActivationSequenceForForceRestartOf(primaryServer); - primaryServer.start(); - assertTrue(primaryServer.getServer().waitForActivation(15, TimeUnit.SECONDS), "primary initialized..."); - - sf = (ClientSessionFactoryInternal) createSessionFactory(locator); - - ClientSession session2 = createSession(sf, false, false); - session2.start(); - ClientConsumer consumer2 = session2.createConsumer(FailoverTestBase.ADDRESS); - final boolean replication = primaryServer.getServer().getHAPolicy() instanceof ReplicatedPolicy || - primaryServer.getServer().getHAPolicy() instanceof ReplicationPrimaryPolicy; - if (replication) - receiveMessages(consumer2, 0, NUM_MESSAGES, true); - assertNoMoreMessages(consumer2); - session2.commit(); - } - - @Test - @Timeout(120) - public void testSimpleFailover() throws Exception { - HAPolicy haPolicy = backupServer.getServer().getHAPolicy(); - - simpleFailover(haPolicy instanceof ReplicaPolicy || haPolicy instanceof ReplicationBackupPolicy, false); - } - - @Test - @Timeout(120) - public void testWithoutUsingTheBackup() throws Exception { - createSessionFactory(); - ClientSession session = createSessionAndQueue(); - - ClientProducer producer = addClientProducer(session.createProducer(FailoverTestBase.ADDRESS)); - - sendMessages(session, producer, NUM_MESSAGES); - producer.close(); - session.commit(); - - backupServer.stop(); // Backup stops! - backupServer.start(); - - waitForRemoteBackupSynchronization(backupServer.getServer()); - - session.start(); - ClientConsumer consumer = addClientConsumer(session.createConsumer(FailoverTestBase.ADDRESS)); - receiveMessages(consumer); - assertNoMoreMessages(consumer); - consumer.close(); - session.commit(); - - session.start(); - producer = addClientProducer(session.createProducer(FailoverTestBase.ADDRESS)); - sendMessages(session, producer, NUM_MESSAGES); - producer.close(); - session.commit(); - backupServer.stop(); // Backup stops! - beforeRestart(backupServer); - backupServer.start(); - waitForRemoteBackupSynchronization(backupServer.getServer()); - backupServer.stop(); // Backup stops! - - primaryServer.stop(); - beforeRestart(primaryServer); - primaryServer.start(); - primaryServer.getServer().waitForActivation(10, TimeUnit.SECONDS); - - ClientSession session2 = createSession(sf, false, false); - session2.start(); - ClientConsumer consumer2 = session2.createConsumer(FailoverTestBase.ADDRESS); - receiveMessages(consumer2, 0, NUM_MESSAGES, true); - assertNoMoreMessages(consumer2); - session2.commit(); - } - - /** - * @param doFailBack - * @throws Exception - */ - private void simpleFailover(boolean isReplicated, boolean doFailBack) throws Exception { - createSessionFactory(); - ClientSession session = createSessionAndQueue(); - - ClientProducer producer = addClientProducer(session.createProducer(FailoverTestBase.ADDRESS)); - - sendMessages(session, producer, NUM_MESSAGES); - producer.close(); - session.commit(); - SimpleString primaryId = primaryServer.getServer().getNodeID(); - crash(session); - - session.start(); - ClientConsumer consumer = addClientConsumer(session.createConsumer(FailoverTestBase.ADDRESS)); - receiveMessages(consumer); - assertNoMoreMessages(consumer); - consumer.close(); - - producer = addClientProducer(session.createProducer(FailoverTestBase.ADDRESS)); - sendMessages(session, producer, NUM_MESSAGES); - producer.close(); - session.commit(); - - assertEquals(primaryId, backupServer.getServer().getNodeID(), "backup must be running with the same nodeID"); - if (doFailBack) { - assertFalse(primaryServer.getServer().getHAPolicy().isBackup(), "must NOT be a backup"); - adaptPrimaryConfigForReplicatedFailBack(primaryServer); - beforeRestart(primaryServer); - primaryServer.start(); - assertTrue(primaryServer.getServer().waitForActivation(40, TimeUnit.SECONDS), "primary initialized..."); - if (isReplicated) { - // wait until it switch role again - Wait.assertTrue(() -> backupServer.getServer().getHAPolicy().isBackup()); - // wait until started - Wait.assertTrue(backupServer::isStarted); - // wait until is an in-sync replica - Wait.assertTrue(backupServer.getServer()::isReplicaSync); - } else { - Wait.assertTrue(backupServer::isStarted); - backupServer.getServer().waitForActivation(5, TimeUnit.SECONDS); - assertTrue(backupServer.isStarted()); - } - if (isReplicated) { - FileMoveManager moveManager = new FileMoveManager(backupServer.getServer().getConfiguration().getJournalLocation(), 0); - // backup has not had a chance to restart as a backup and cleanup - Wait.assertTrue(() -> moveManager.getNumberOfFolders() <= 2); - } - } else { - backupServer.stop(); - beforeRestart(backupServer); - backupServer.start(); - assertTrue(backupServer.getServer().waitForActivation(10, TimeUnit.SECONDS)); - } - - ClientSession session2 = createSession(sf, false, false); - session2.start(); - ClientConsumer consumer2 = session2.createConsumer(FailoverTestBase.ADDRESS); - receiveMessages(consumer2, 0, NUM_MESSAGES, true); - assertNoMoreMessages(consumer2); - session2.commit(); - } - - /** - * @param consumer - * @throws ActiveMQException - */ - private void assertNoMoreMessages(ClientConsumer consumer) throws ActiveMQException { - ClientMessage msg = consumer.receiveImmediate(); - assertNull(msg, "there should be no more messages to receive! " + msg); - } - - protected void createSessionFactory() throws Exception { - locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setReconnectAttempts(300).setRetryInterval(100); - - sf = createSessionFactoryAndWaitForTopology(locator, 2); - } - - @Test - @Timeout(120) - public void testConsumeTransacted() throws Exception { - createSessionFactory(); - - ClientSession session = createSessionAndQueue(); - - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - final int numMessages = 10; - - sendMessages(session, producer, numMessages); - - session.commit(); - - ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - - session.start(); - - for (int i = 0; i < numMessages; i++) { - ClientMessage message = consumer.receive(1000); - assertNotNull(message, "Just crashed? " + (i == 6) + " " + i); - - message.acknowledge(); - - // TODO: The test won't pass if you uncomment this line - // assertEquals(i, (int)message.getIntProperty("counter")); - - if (i == 5) { - crash(session); - } - } - - try { - session.commit(); - fail("session must have rolled back on failover"); - } catch (ActiveMQTransactionRolledBackException trbe) { - //ok - } catch (ActiveMQException e) { - fail("Invalid Exception type:" + e.getType()); - } - - consumer.close(); - - consumer = session.createConsumer(FailoverTestBase.ADDRESS); - - session.start(); - - for (int i = 0; i < numMessages; i++) { - ClientMessage message = consumer.receive(1000); - - assertNotNull(message, "Expecting message #" + i); - - message.acknowledge(); - } - - session.commit(); - - session.close(); - } - - /** - * @return - * @throws Exception - */ - protected ClientSession createSessionAndQueue() throws Exception { - ClientSession session = createSession(sf, false, false); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - return session; - } - - // https://jira.jboss.org/jira/browse/HORNETQ-285 - @Test - @Timeout(120) - public void testFailoverOnInitialConnection() throws Exception { - locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setReconnectAttempts(300).setRetryInterval(100); - - sf = createSessionFactoryAndWaitForTopology(locator, 2); - - // Crash primary server - crash(); - - ClientSession session = createSession(sf); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - sendMessages(session, producer, NUM_MESSAGES); - - ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - - session.start(); - - receiveMessages(consumer); - - session.close(); - } - - @Test - @Timeout(120) - public void testTransactedMessagesSentSoRollback() throws Exception { - createSessionFactory(); - - ClientSession session = createSessionAndQueue(); - - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - sendMessagesSomeDurable(session, producer); - - crash(session); - - assertTrue(session.isRollbackOnly()); - - try { - session.commit(); - - fail("Should throw exception"); - } catch (ActiveMQTransactionRolledBackException trbe) { - //ok - } catch (ActiveMQException e) { - fail("Invalid Exception type:" + e.getType()); - } - - ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - - session.start(); - - ClientMessage message = consumer.receiveImmediate(); - - assertNull(message, "message should be null! Was: " + message); - - session.close(); - } - - /** - * Test that once the transacted session has throw a TRANSACTION_ROLLED_BACK exception, - * it can be reused again - */ - @Test - @Timeout(120) - public void testTransactedMessagesSentSoRollbackAndContinueWork() throws Exception { - createSessionFactory(); - - ClientSession session = createSessionAndQueue(); - - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - sendMessagesSomeDurable(session, producer); - - crash(session); - - assertTrue(session.isRollbackOnly()); - - try { - session.commit(); - - fail("Should throw exception"); - } catch (ActiveMQTransactionRolledBackException trbe) { - //ok - } catch (ActiveMQException e) { - fail("Invalid Exception type:" + e.getType()); - } - - ClientMessage message = session.createMessage(false); - int counter = RandomUtil.randomInt(); - message.putIntProperty("counter", counter); - - producer.send(message); - - // session is working again - session.commit(); - - session.start(); - - ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - - session.start(); - message = consumer.receive(1000); - - assertNotNull(message, "expecting a message"); - assertEquals(counter, message.getIntProperty("counter").intValue()); - - session.close(); - } - - @Test - @Timeout(120) - public void testTransactedMessagesNotSentSoNoRollback() throws Exception { - try { - createSessionFactory(); - - ClientSession session = createSessionAndQueue(); - - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - sendMessagesSomeDurable(session, producer); - - session.commit(); - - crash(session); - - // committing again should work since didn't send anything since last commit - - assertFalse(session.isRollbackOnly()); - - session.commit(); - - ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - - session.start(); - - receiveDurableMessages(consumer); - - assertNull(consumer.receiveImmediate()); - - session.commit(); - - session.close(); - } finally { - try { - primaryServer.getServer().stop(); - } catch (Throwable ignored) { - } - try { - backupServer.getServer().stop(); - } catch (Throwable ignored) { - } - } - } - - @Test - @Timeout(120) - public void testTransactedMessagesWithConsumerStartedBeforeFailover() throws Exception { - createSessionFactory(); - - ClientSession session = createSessionAndQueue(); - - // create a consumer and start the session before failover - ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - - session.start(); - - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - sendMessagesSomeDurable(session, producer); - - // messages will be delivered to the consumer when the session is committed - session.commit(); - - assertFalse(session.isRollbackOnly()); - - crash(session); - - session.commit(); - - session.close(); - - session = createSession(sf, false, false); - - consumer = session.createConsumer(FailoverTestBase.ADDRESS); - - session.start(); - - receiveDurableMessages(consumer); - - assertNull(consumer.receiveImmediate()); - - session.commit(); - } - - @Test - @Timeout(120) - public void testTransactedMessagesConsumedSoRollback() throws Exception { - createSessionFactory(); - - ClientSession session1 = createSessionAndQueue(); - - ClientProducer producer = session1.createProducer(FailoverTestBase.ADDRESS); - - sendMessagesSomeDurable(session1, producer); - - session1.commit(); - - ClientSession session2 = createSession(sf, false, false); - - ClientConsumer consumer = session2.createConsumer(FailoverTestBase.ADDRESS); - - session2.start(); - - receiveMessages(consumer); - - crash(session2); - - assertTrue(session2.isRollbackOnly()); - - try { - session2.commit(); - - fail("Should throw exception"); - } catch (ActiveMQTransactionRolledBackException trbe) { - //ok - } catch (ActiveMQException e) { - fail("Invalid Exception type:" + e.getType()); - } - } - - @Test - @Timeout(120) - public void testTransactedMessagesNotConsumedSoNoRollback() throws Exception { - createSessionFactory(); - - ClientSession session1 = createSessionAndQueue(); - - ClientProducer producer = session1.createProducer(FailoverTestBase.ADDRESS); - - sendMessages(session1, producer, NUM_MESSAGES); - session1.commit(); - - ClientSession session2 = createSession(sf, false, false); - - ClientConsumer consumer = session2.createConsumer(FailoverTestBase.ADDRESS); - - session2.start(); - - receiveMessages(consumer, 0, NUM_MESSAGES / 2, true); - - session2.commit(); - - consumer.close(); - - crash(session2); - - assertFalse(session2.isRollbackOnly()); - - consumer = session2.createConsumer(FailoverTestBase.ADDRESS); - - for (int i = NUM_MESSAGES / 2; i < NUM_MESSAGES; i++) { - ClientMessage message = consumer.receive(1000); - - assertNotNull(message, "expecting message " + i); - - assertMessageBody(i, message); - - assertEquals(i, message.getIntProperty("counter").intValue()); - - message.acknowledge(); - } - - session2.commit(); - - assertNull(consumer.receiveImmediate()); - } - - @Test - @Timeout(120) - public void testXAMessagesSentSoRollbackOnEnd() throws Exception { - createSessionFactory(); - - ClientSession session = createSession(sf, true, false, false); - - Xid xid = new XidImpl("uhuhuhu".getBytes(), 126512, "auhsduashd".getBytes()); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - session.start(xid, XAResource.TMNOFLAGS); - - sendMessagesSomeDurable(session, producer); - - crash(session); - - try { - session.end(xid, XAResource.TMSUCCESS); - - fail("Should throw exception"); - } catch (XAException e) { - assertEquals(XAException.XAER_RMFAIL, e.errorCode); - } - - ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - - session.start(); - - ClientMessage message = consumer.receiveImmediate(); - - assertNull(message); - } - - @Test - @Timeout(120) - //start a tx but sending messages after crash - public void testXAMessagesSentSoRollbackOnEnd2() throws Exception { - createSessionFactory(); - - ClientSession session = createSession(sf, true, false, false); - - Xid xid = new XidImpl("uhuhuhu".getBytes(), 126512, "auhsduashd".getBytes()); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - session.start(xid, XAResource.TMNOFLAGS); - - crash(session); - - // sendMessagesSomeDurable(session, producer); - - producer.send(createMessage(session, 1, true)); - - try { - session.end(xid, XAResource.TMSUCCESS); - - fail("Should throw exception"); - } catch (XAException e) { - // Assert.assertEquals(XAException.XAER_NOTA, e.errorCode); - } - - ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - - session.start(); - - ClientMessage message = consumer.receiveImmediate(); - - assertNull(message); - } - - @Test - @Timeout(120) - public void testXAMessagesSentSoRollbackOnPrepare() throws Exception { - createSessionFactory(); - - final ClientSession session = createSession(sf, true, false, false); - - Xid xid = new XidImpl("uhuhuhu".getBytes(), 126512, "auhsduashd".getBytes()); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - - final ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - session.start(xid, XAResource.TMNOFLAGS); - - sendMessagesSomeDurable(session, producer); - - session.end(xid, XAResource.TMSUCCESS); - - crash(session); - - try { - session.prepare(xid); - - fail("Should throw exception"); - } catch (XAException e) { - assertEquals(XAException.XAER_RMFAIL, e.errorCode); - // XXXX session.rollback(); - } - - ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - - session.start(); - - ClientMessage message = consumer.receiveImmediate(); - - assertNull(message); - - producer.close(); - consumer.close(); - } - - // This might happen if 1PC optimisation kicks in - @Test - @Timeout(120) - public void testXAMessagesSentSoRollbackOnCommit() throws Exception { - createSessionFactory(); - - ClientSession session = createSession(sf, true, false, false); - - Xid xid = new XidImpl("uhuhuhu".getBytes(), 126512, "auhsduashd".getBytes()); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - session.start(xid, XAResource.TMNOFLAGS); - - sendMessagesSomeDurable(session, producer); - - session.end(xid, XAResource.TMSUCCESS); - - crash(session); - - try { - session.commit(xid, false); - - fail("Should throw exception"); - } catch (XAException e) { - assertEquals(XAException.XAER_NOTA, e.errorCode); - } - - ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - - session.start(); - - ClientMessage message = consumer.receiveImmediate(); - - assertNull(message); - } - - @Test - @Timeout(120) - public void testXAMessagesNotSentSoNoRollbackOnCommit() throws Exception { - createSessionFactory(); - - ClientSession session = createSession(sf, true, false, false); - - Xid xid = new XidImpl("uhuhuhu".getBytes(), 126512, "auhsduashd".getBytes()); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - session.start(xid, XAResource.TMNOFLAGS); - - sendMessagesSomeDurable(session, producer); - - session.end(xid, XAResource.TMSUCCESS); - - session.prepare(xid); - - session.commit(xid, false); - - crash(session); - - ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - - session.start(); - - Xid xid2 = new XidImpl("tfytftyf".getBytes(), 54654, "iohiuohiuhgiu".getBytes()); - - session.start(xid2, XAResource.TMNOFLAGS); - - receiveDurableMessages(consumer); - - session.end(xid2, XAResource.TMSUCCESS); - - session.prepare(xid2); - - session.commit(xid2, false); - } - - @Test - @Timeout(120) - public void testXAMessagesConsumedSoRollbackOnEnd() throws Exception { - createSessionFactory(); - - ClientSession session1 = createSessionAndQueue(); - - ClientProducer producer = session1.createProducer(FailoverTestBase.ADDRESS); - - sendMessagesSomeDurable(session1, producer); - - session1.commit(); - - ClientSession session2 = createSession(sf, true, false, false); - - ClientConsumer consumer = session2.createConsumer(FailoverTestBase.ADDRESS); - - session2.start(); - - Xid xid = new XidImpl("uhuhuhu".getBytes(), 126512, "auhsduashd".getBytes()); - - session2.start(xid, XAResource.TMNOFLAGS); - - receiveMessages(consumer); - - crash(session2); - - try { - session2.end(xid, XAResource.TMSUCCESS); - - fail("Should throw exception"); - } catch (XAException e) { - assertEquals(XAException.XAER_RMFAIL, e.errorCode); - } - } - - @Test - @Timeout(120) - public void testXAMessagesConsumedSoRollbackOnEnd2() throws Exception { - createSessionFactory(); - - ClientSession session1 = createSessionAndQueue(); - - ClientProducer producer = session1.createProducer(FailoverTestBase.ADDRESS); - - for (int i = 0; i < NUM_MESSAGES; i++) { - // some are durable, some are not! - producer.send(createMessage(session1, i, true)); - } - - session1.commit(); - - ClientSession session2 = createSession(sf, true, false, false); - - ClientConsumer consumer = session2.createConsumer(FailoverTestBase.ADDRESS); - - session2.start(); - - Xid xid = new XidImpl("uhuhuhu".getBytes(), 126512, "auhsduashd".getBytes()); - - session2.start(xid, XAResource.TMNOFLAGS); - - crash(session2); - - receiveMessages(consumer); - - try { - session2.end(xid, XAResource.TMSUCCESS); - - fail("Should throw exception"); - } catch (XAException e) { - } - - // Since the end was not accepted, the messages should be redelivered - receiveMessages(consumer); - } - - @Test - @Timeout(120) - public void testXAMessagesConsumedSoRollbackOnPrepare() throws Exception { - createSessionFactory(); - - ClientSession session1 = createSessionAndQueue(); - - ClientProducer producer = session1.createProducer(FailoverTestBase.ADDRESS); - - sendMessagesSomeDurable(session1, producer); - - session1.commit(); - - ClientSession session2 = createSession(sf, true, false, false); - - ClientConsumer consumer = session2.createConsumer(FailoverTestBase.ADDRESS); - - session2.start(); - - Xid xid = new XidImpl("uhuhuhu".getBytes(), 126512, "auhsduashd".getBytes()); - - session2.start(xid, XAResource.TMNOFLAGS); - - receiveMessages(consumer); - - session2.end(xid, XAResource.TMSUCCESS); - - crash(session2); - - try { - session2.prepare(xid); - - fail("Should throw exception"); - } catch (XAException e) { - assertEquals(XAException.XAER_RMFAIL, e.errorCode); - } - } - - // 1PC optimisation - @Test - @Timeout(120) - public void testXAMessagesConsumedSoRollbackOnCommit() throws Exception { - createSessionFactory(); - ClientSession session1 = createSessionAndQueue(); - - ClientProducer producer = session1.createProducer(FailoverTestBase.ADDRESS); - - sendMessagesSomeDurable(session1, producer); - - session1.commit(); - - ClientSession session2 = createSession(sf, true, false, false); - - ClientConsumer consumer = session2.createConsumer(FailoverTestBase.ADDRESS); - - session2.start(); - - Xid xid = new XidImpl("uhuhuhu".getBytes(), 126512, "auhsduashd".getBytes()); - - session2.start(xid, XAResource.TMNOFLAGS); - - receiveMessages(consumer); - - session2.end(xid, XAResource.TMSUCCESS); - - // session2.prepare(xid); - - crash(session2); - - try { - session2.commit(xid, false); - - fail("Should throw exception"); - } catch (XAException e) { - // it should be rolled back - assertEquals(XAException.XAER_NOTA, e.errorCode); - } - - session1.close(); - - session2.close(); - } - - @Test - @Timeout(120) - public void testCreateNewFactoryAfterFailover() throws Exception { - locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true); - sf = createSessionFactoryAndWaitForTopology(locator, 2); - - ClientSession session = sendAndConsume(sf, true); - - crash(true, session); - - session.close(); - - long timeout; - timeout = System.currentTimeMillis() + 5000; - while (timeout > System.currentTimeMillis()) { - try { - createClientSessionFactory(); - break; - } catch (Exception e) { - // retrying - Thread.sleep(100); - } - } - - session = sendAndConsume(sf, true); - } - - @Test - @Timeout(120) - public void testFailoverMultipleSessionsWithConsumers() throws Exception { - createSessionFactory(); - - final int numSessions = 5; - - final int numConsumersPerSession = 5; - - Map> sessionConsumerMap = new HashMap<>(); - - for (int i = 0; i < numSessions; i++) { - ClientSession session = createSession(sf, true, true); - - List consumers = new ArrayList<>(); - - for (int j = 0; j < numConsumersPerSession; j++) { - SimpleString queueName = SimpleString.of("queue" + i + "-" + j); - - session.createQueue(QueueConfiguration.of(queueName).setAddress(FailoverTestBase.ADDRESS)); - - ClientConsumer consumer = session.createConsumer(queueName); - - consumers.add(consumer); - } - - sessionConsumerMap.put(session, consumers); - } - - ClientSession sendSession = createSession(sf, true, true); - - ClientProducer producer = sendSession.createProducer(FailoverTestBase.ADDRESS); - - sendMessages(sendSession, producer, NUM_MESSAGES); - - Set sessionSet = sessionConsumerMap.keySet(); - ClientSession[] sessions = new ClientSession[sessionSet.size()]; - sessionSet.toArray(sessions); - crash(sessions); - - for (ClientSession session : sessionConsumerMap.keySet()) { - session.start(); - } - - for (List consumerList : sessionConsumerMap.values()) { - for (ClientConsumer consumer : consumerList) { - receiveMessages(consumer); - } - } - } - - /* - * Browser will get reset to beginning after failover - */ - @Test - @Timeout(120) - public void testFailWithBrowser() throws Exception { - createSessionFactory(); - ClientSession session = createSession(sf, true, true); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - sendMessagesSomeDurable(session, producer); - - ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS, true); - - session.start(); - - receiveMessages(consumer, 0, NUM_MESSAGES, false); - - crash(session); - - receiveDurableMessages(consumer); - } - - protected void sendMessagesSomeDurable(ClientSession session, ClientProducer producer) throws Exception { - for (int i = 0; i < NUM_MESSAGES; i++) { - // some are durable, some are not! - producer.send(createMessage(session, i, isDurable(i))); - } - } - - @Test - @Timeout(120) - public void testFailThenReceiveMoreMessagesAfterFailover() throws Exception { - createSessionFactory(); - - ClientSession session = createSession(sf, true, true); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - sendMessagesSomeDurable(session, producer); - - ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - - session.start(); - - // Receive MSGs but don't ack! - for (int i = 0; i < NUM_MESSAGES; i++) { - ClientMessage message = consumer.receive(1000); - - assertNotNull(message); - - assertMessageBody(i, message); - - assertEquals(i, message.getIntProperty("counter").intValue()); - } - - crash(session); - - // Should get the same ones after failover since we didn't ack - - receiveDurableMessages(consumer); - } - - protected void receiveDurableMessages(ClientConsumer consumer) throws ActiveMQException { - // During failover non-persistent messages may disappear but in certain cases they may survive. - // For that reason the test is validating all the messages but being permissive with non-persistent messages - // The test will just ack any non-persistent message, however when arriving it must be in order - ClientMessage repeatMessage = null; - for (int i = 0; i < NUM_MESSAGES; i++) { - ClientMessage message; - - if (repeatMessage != null) { - message = repeatMessage; - repeatMessage = null; - } else { - message = consumer.receive(50); - } - - if (message != null) { - int msgInternalCounter = message.getIntProperty("counter").intValue(); - - if (msgInternalCounter == i + 1) { - // The test can only jump to the next message if the current iteration is meant for non-durable - assertFalse(isDurable(i), "a message on counter=" + i + " was expected"); - // message belongs to the next iteration.. let's just ignore it - repeatMessage = message; - continue; - } - } - - if (isDurable(i)) { - assertNotNull(message); - } - - if (message != null) { - assertMessageBody(i, message); - assertEquals(i, message.getIntProperty("counter").intValue()); - message.acknowledge(); - } - } - } - - private boolean isDurable(int i) { - return i % 2 == 0; - } - - @Test - @Timeout(120) - public void testFailThenReceiveMoreMessagesAfterFailover2() throws Exception { - locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setReconnectAttempts(300).setRetryInterval(100); - - sf = createSessionFactoryAndWaitForTopology(locator, 2); - - ClientSession session = createSession(sf, true, true, 0); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - sendMessagesSomeDurable(session, producer); - - ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - - session.start(); - receiveMessages(consumer); - - crash(session); - - // Send some more - - for (int i = NUM_MESSAGES; i < NUM_MESSAGES * 2; i++) { - producer.send(createMessage(session, i, isDurable(i))); - } - receiveMessages(consumer, NUM_MESSAGES, NUM_MESSAGES * 2, true); - } - - protected void receiveMessages(ClientConsumer consumer) throws ActiveMQException { - receiveMessages(consumer, 0, NUM_MESSAGES, true); - } - - @Test - @Timeout(120) - public void testSimpleSendAfterFailoverDurableTemporary() throws Exception { - doSimpleSendAfterFailover(true, true); - } - - @Test - @Timeout(120) - public void testSimpleSendAfterFailoverNonDurableTemporary() throws Exception { - doSimpleSendAfterFailover(false, true); - } - - @Test - @Timeout(120) - public void testSimpleSendAfterFailoverDurableNonTemporary() throws Exception { - doSimpleSendAfterFailover(true, false); - } - - @Test - @Timeout(120) - public void testSimpleSendAfterFailoverNonDurableNonTemporary() throws Exception { - doSimpleSendAfterFailover(false, false); - } - - private void doSimpleSendAfterFailover(final boolean durable, final boolean temporary) throws Exception { - locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setReconnectAttempts(300).setRetryInterval(100); - - sf = createSessionFactoryAndWaitForTopology(locator, 2); - - ClientSession session = createSession(sf, true, true, 0); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS).setDurable(durable && !temporary).setTemporary(temporary)); - - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - - session.start(); - - crash(session); - - sendMessagesSomeDurable(session, producer); - - receiveMessages(consumer); - } - - @Test - @Timeout(120) - public void testMultipleSessionFailover() throws Exception { - final String address = "TEST"; - locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setReconnectAttempts(300).setRetryInterval(100); - - sf = createSessionFactoryAndWaitForTopology(locator, 2); - - ClientSession session1 = createSession(sf, true, true, 0); - ClientSession session2 = createSession(sf, true, true, 0); - - backupServer.addInterceptor( - new Interceptor() { - private int index = 0; - - @Override - public boolean intercept(Packet packet, RemotingConnection connection) throws ActiveMQException { - if (packet.getType() == PacketImpl.CREATESESSION) { - index++; - if (index == 2 || index == 3) { - Channel sessionChannel = ((RemotingConnectionImpl) connection).getChannel(ChannelImpl.CHANNEL_ID.SESSION.id, -1); - sessionChannel.send(new ActiveMQExceptionMessage(new ActiveMQInternalErrorException())); - return false; - } - } - return true; - } - }); - - session1.start(); - session2.start(); - - crash(session1, session2); - - session1.createQueue(QueueConfiguration.of(address).setAddress(address)); - - ClientProducer clientProducer = session1.createProducer(address); - clientProducer.send(session1.createMessage(false)); - - ClientConsumer clientConsumer = session2.createConsumer(address); - ClientMessage message = clientConsumer.receive(3000); - assertNotNull(message); - } - - @Test - @Timeout(120) - public void testChannelStateDuringFailover() throws Exception { - locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setReconnectAttempts(300).setRetryInterval(100); - - sf = createSessionFactoryAndWaitForTopology(locator, 2); - - final int reconnectFailures = 3; - final AtomicInteger reconnectRetries = new AtomicInteger(0); - final AtomicBoolean channelLockedDuringFailover = new AtomicBoolean(true); - - ClientSession session = createSession(sf, true, true, 0); - - backupServer.addInterceptor((packet, connection) -> { - if (packet.getType() == PacketImpl.CREATESESSION) { - if (reconnectRetries.getAndIncrement() < reconnectFailures) { - Channel sessionChannel = ((RemotingConnectionImpl)connection).getChannel(ChannelImpl.CHANNEL_ID.SESSION.id, -1); - sessionChannel.send(new ActiveMQExceptionMessage(new ActiveMQInternalErrorException())); - return false; - } - - ActiveMQSessionContext sessionContext = (ActiveMQSessionContext)((ClientSessionInternal)session).getSessionContext(); - channelLockedDuringFailover.compareAndSet(true, sessionContext.getSessionChannel().isLocked()); - } - return true; - }); - - session.start(); - - crash(session); - - assertTrue(channelLockedDuringFailover.get()); - assertEquals(reconnectFailures + 1, reconnectRetries.get()); - } - - @Test - @Timeout(120) - public void testForceBlockingReturn() throws Exception { - locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setReconnectAttempts(300).setRetryInterval(100); - - createClientSessionFactory(); - - // Add an interceptor to delay the send method so we can get time to cause failover before it returns - DelayInterceptor interceptor = new DelayInterceptor(); - primaryServer.getServer().getRemotingService().addIncomingInterceptor(interceptor); - - final ClientSession session = createSession(sf, true, true, 0); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - - final ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - class Sender extends Thread { - - @Override - public void run() { - ClientMessage message = session.createMessage(true); - - message.getBodyBuffer().writeString("message"); - - try { - producer.send(message); - } catch (ActiveMQException e1) { - this.e = e1; - } - } - - volatile ActiveMQException e; - } - - Sender sender = new Sender(); - - sender.start(); - - //if server crash too early, - //sender will directly send to backup. so - //need some waiting here. - assertTrue(interceptor.await()); - - crash(session); - - sender.join(); - - assertNotNull(sender.e); - - assertNotNull(sender.e.getCause()); - - assertEquals(sender.e.getType(), ActiveMQExceptionType.UNBLOCKED); - - assertEquals(((ActiveMQException) sender.e.getCause()).getType(), ActiveMQExceptionType.DISCONNECTED); - - session.close(); - } - - @Test - @Timeout(120) - public void testCommitOccurredUnblockedAndResendNoDuplicates() throws Exception { - locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setReconnectAttempts(300).setRetryInterval(100).setBlockOnAcknowledge(true); - - sf = createSessionFactoryAndWaitForTopology(locator, 2); - - final ClientSession session = createSession(sf, false, false); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - String txID = "my-tx-id"; - - for (int i = 0; i < NUM_MESSAGES; i++) { - ClientMessage message = session.createMessage(true); - - if (i == 0) { - // Only need to add it on one message per tx - message.putStringProperty(Message.HDR_DUPLICATE_DETECTION_ID, SimpleString.of(txID)); - } - - setBody(i, message); - - message.putIntProperty("counter", i); - - producer.send(message); - } - - class Committer extends Thread { - - DelayInterceptor2 interceptor = new DelayInterceptor2(); - - @Override - public void run() { - try { - sf.getServerLocator().addIncomingInterceptor(interceptor); - - session.commit(); - } catch (ActiveMQTransactionRolledBackException trbe) { - // Ok - now we retry the commit after removing the interceptor - - sf.getServerLocator().removeIncomingInterceptor(interceptor); - - try { - session.commit(); - - failed = false; - } catch (ActiveMQException e2) { - throw new RuntimeException(e2); - } - } catch (ActiveMQTransactionOutcomeUnknownException toue) { - // Ok - now we retry the commit after removing the interceptor - - sf.getServerLocator().removeIncomingInterceptor(interceptor); - - try { - session.commit(); - - failed = false; - } catch (ActiveMQException e2) { - throw new RuntimeException(e2); - } - } catch (ActiveMQException e) { - //ignore - } - } - - volatile boolean failed = true; - } - - Committer committer = new Committer(); - - // Commit will occur, but response will never get back, connection is failed, and commit - // should be unblocked with transaction rolled back - - committer.start(); - - // Wait for the commit to occur and the response to be discarded - assertTrue(committer.interceptor.await()); - - crash(session); - - committer.join(); - - assertFalse(committer.failed, "second attempt succeed?"); - - session.close(); - - ClientSession session2 = createSession(sf, false, false); - - producer = session2.createProducer(FailoverTestBase.ADDRESS); - - // We now try and resend the messages since we get a transaction rolled back exception - // but the commit actually succeeded, duplicate detection should kick in and prevent dups - - for (int i = 0; i < NUM_MESSAGES; i++) { - ClientMessage message = session2.createMessage(true); - - if (i == 0) { - // Only need to add it on one message per tx - message.putStringProperty(Message.HDR_DUPLICATE_DETECTION_ID, SimpleString.of(txID)); - } - - setBody(i, message); - - message.putIntProperty("counter", i); - - producer.send(message); - } - - try { - session2.commit(); - fail("expecting DUPLICATE_ID_REJECTED exception"); - } catch (ActiveMQDuplicateIdException dide) { - //ok - } catch (ActiveMQException e) { - fail("Invalid Exception type:" + e.getType()); - } - - ClientConsumer consumer = session2.createConsumer(FailoverTestBase.ADDRESS); - - session2.start(); - - receiveMessages(consumer); - - ClientMessage message = consumer.receiveImmediate(); - - assertNull(message); - } - - @Test - @Timeout(120) - public void testCommitDidNotOccurUnblockedAndResend() throws Exception { - locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setReconnectAttempts(300).setRetryInterval(100); - - sf = createSessionFactoryAndWaitForTopology(locator, 2); - - final ClientSession session = createSession(sf, false, false); - - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - sendMessages(session, producer, NUM_MESSAGES); - - class Committer extends Thread { - - @Override - public void run() { - Interceptor interceptor = new DelayInterceptor3(); - - try { - primaryServer.addInterceptor(interceptor); - - session.commit(); - } catch (ActiveMQTransactionRolledBackException trbe) { - // Ok - now we retry the commit after removing the interceptor - - primaryServer.removeInterceptor(interceptor); - - try { - session.commit(); - - failed = false; - } catch (ActiveMQException e2) { - } - } catch (ActiveMQTransactionOutcomeUnknownException toue) { - // Ok - now we retry the commit after removing the interceptor - - primaryServer.removeInterceptor(interceptor); - - try { - session.commit(); - - failed = false; - } catch (ActiveMQException e2) { - } - } catch (ActiveMQException e) { - //ignore - } - } - - volatile boolean failed = true; - } - - Committer committer = new Committer(); - - committer.start(); - - crash(session); - - committer.join(); - - assertFalse(committer.failed, "commiter failed should be false"); - - session.close(); - - ClientSession session2 = createSession(sf, false, false); - - producer = session2.createProducer(FailoverTestBase.ADDRESS); - - // We now try and resend the messages since we get a transaction rolled back exception - sendMessages(session2, producer, NUM_MESSAGES); - - session2.commit(); - - ClientConsumer consumer = session2.createConsumer(FailoverTestBase.ADDRESS); - - session2.start(); - - receiveMessages(consumer); - - ClientMessage message = consumer.receiveImmediate(); - - assertNull(message, "expecting null message"); - } - - @Test - @Timeout(120) - public void testBackupServerNotRemoved() throws Exception { - // HORNETQ-720 Disabling test for replicating backups. - if (!(backupServer.getServer().getHAPolicy() instanceof SharedStoreBackupPolicy)) { - return; - } - createSessionFactory(); - - ClientSession session = sendAndConsume(sf, true); - CountDownSessionFailureListener listener = new CountDownSessionFailureListener(session); - - session.addFailureListener(listener); - - backupServer.stop(); - - primaryServer.crash(); - - // To reload security or other settings that are read during startup - beforeRestart(backupServer); - - backupServer.start(); - - assertTrue(listener.getLatch().await(5, TimeUnit.SECONDS), "session failure listener"); - - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - ClientMessage message = session.createMessage(true); - - setBody(0, message); - - producer.send(message); - } - - @Test - @Timeout(120) - public void testPrimaryAndBackupPrimaryComesBack() throws Exception { - createSessionFactory(); - final CountDownLatch latch = new CountDownLatch(1); - - ClientSession session = sendAndConsume(sf, true); - - session.addFailureListener(new CountDownSessionFailureListener(latch, session)); - - backupServer.stop(); - - primaryServer.crash(); - - beforeRestart(primaryServer); - - // To reload security or other settings that are read during startup - beforeRestart(primaryServer); - - primaryServer.start(); - - assertTrue(latch.await(5, TimeUnit.SECONDS)); - - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - ClientMessage message = session.createMessage(true); - - setBody(0, message); - - producer.send(message); + @Override + @BeforeEach + public void setUp() throws Exception { + super.setUp(); + locator = getServerLocator(); } @Test @Timeout(120) - public void testPrimaryAndBackupPrimaryComesBackNewFactory() throws Exception { + public void testNonTransacted() throws Exception { createSessionFactory(); - final CountDownLatch latch = new CountDownLatch(1); - - ClientSession session = sendAndConsume(sf, true); - - session.addFailureListener(new CountDownSessionFailureListener(latch, session)); - - backupServer.stop(); - - primaryServer.crash(); + ClientSession session = createSession(sf, true, true); - // To reload security or other settings that are read during startup - beforeRestart(primaryServer); + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); - primaryServer.start(); + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - assertTrue(latch.await(5, TimeUnit.SECONDS)); + sendMessagesSomeDurable(session, producer); - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + crash(session); - ClientMessage message = session.createMessage(true); + ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); - setBody(0, message); + session.start(); - producer.send(message); + receiveDurableMessages(consumer); session.close(); sf.close(); - createClientSessionFactory(); - - session = createSession(sf); - - ClientConsumer cc = session.createConsumer(FailoverTestBase.ADDRESS); + assertEquals(0, sf.numSessions()); - session.start(); + assertEquals(0, sf.numConnections()); + } - ClientMessage cm = cc.receive(5000); + protected void waitForBackupConfig(ClientSessionFactoryInternal sf) throws NoSuchFieldException, IllegalAccessException, InterruptedException { + TransportConfiguration initialBackup = getFieldFromSF(sf, "backupConnectorConfig"); + int cnt = 50; + while (initialBackup == null && cnt > 0) { + cnt--; + Thread.sleep(200); + initialBackup = getFieldFromSF(sf, "backupConnectorConfig"); + } + } - assertNotNull(cm); + protected void setSFFieldValue(ClientSessionFactoryInternal sf, + String tcName, + Object value) throws NoSuchFieldException, IllegalAccessException { + Field tcField = ClientSessionFactoryImpl.class.getDeclaredField(tcName); + tcField.setAccessible(true); + tcField.set(sf, value); + } - assertEquals("message0", cm.getBodyBuffer().readString()); + protected TransportConfiguration getFieldFromSF(ClientSessionFactoryInternal sf, + String tcName) throws NoSuchFieldException, IllegalAccessException { + Field tcField = ClientSessionFactoryImpl.class.getDeclaredField(tcName); + tcField.setAccessible(true); + return (TransportConfiguration) tcField.get(sf); } + /** + * Basic fail-back test. + * + * @throws Exception + */ @Test @Timeout(120) - public void testPrimaryAndBackupBackupComesBackNewFactory() throws Exception { - locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setReconnectAttempts(300).setRetryInterval(100); - - sf = createSessionFactoryAndWaitForTopology(locator, 2); - - ClientSession session = sendAndConsume(sf, true); + public void testFailBack() throws Exception { + boolean doFailBack = true; + HAPolicy haPolicy = backupServer.getServer().getHAPolicy(); + if (haPolicy instanceof ReplicaPolicy) { + ((ReplicaPolicy) haPolicy).setMaxSavedReplicatedJournalsSize(1); + } - CountDownSessionFailureListener listener = new CountDownSessionFailureListener(session); + simpleFailover(haPolicy instanceof ReplicaPolicy || haPolicy instanceof ReplicationBackupPolicy, doFailBack); + } - session.addFailureListener(listener); + @Test + @Timeout(120) + public void testSimpleFailover() throws Exception { + HAPolicy haPolicy = backupServer.getServer().getHAPolicy(); - backupServer.stop(); + simpleFailover(haPolicy instanceof ReplicaPolicy || haPolicy instanceof ReplicationBackupPolicy, false); + } - primaryServer.crash(); + @Test + @Timeout(120) + public void testWithoutUsingTheBackup() throws Exception { + createSessionFactory(); + ClientSession session = createSessionAndQueue(); - // To reload security or other settings that are read during startup - beforeRestart(backupServer); + ClientProducer producer = addClientProducer(session.createProducer(FailoverTestBase.ADDRESS)); - if (!backupServer.getServer().getHAPolicy().isSharedStore()) { - // XXX - // this test would not make sense in the remote replication use case, without the following - backupServer.getServer().setHAPolicy(new SharedStorePrimaryPolicy()); - } + sendMessages(session, producer, NUM_MESSAGES); + producer.close(); + session.commit(); + backupServer.stop(); // Backup stops! backupServer.start(); - assertTrue(listener.getLatch().await(5, TimeUnit.SECONDS), "session failure listener"); - - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); - - ClientMessage message = session.createMessage(true); + waitForRemoteBackupSynchronization(backupServer.getServer()); - setBody(0, message); + session.start(); + ClientConsumer consumer = addClientConsumer(session.createConsumer(FailoverTestBase.ADDRESS)); + receiveMessages(consumer); + assertNoMoreMessages(consumer); + consumer.close(); + session.commit(); - producer.send(message); + session.start(); + producer = addClientProducer(session.createProducer(FailoverTestBase.ADDRESS)); + sendMessages(session, producer, NUM_MESSAGES); + producer.close(); + session.commit(); + backupServer.stop(); // Backup stops! + beforeRestart(backupServer); + backupServer.start(); + waitForRemoteBackupSynchronization(backupServer.getServer()); + backupServer.stop(); // Backup stops! - session.close(); + primaryServer.stop(); + beforeRestart(primaryServer); + primaryServer.start(); + primaryServer.getServer().waitForActivation(10, TimeUnit.SECONDS); - sf.close(); + ClientSession session2 = createSession(sf, false, false); + session2.start(); + ClientConsumer consumer2 = session2.createConsumer(FailoverTestBase.ADDRESS); + receiveMessages(consumer2, 0, NUM_MESSAGES, true); + assertNoMoreMessages(consumer2); + session2.commit(); + } - createClientSessionFactory(); + /** + * @param doFailBack + * @throws Exception + */ + private void simpleFailover(boolean isReplicated, boolean doFailBack) throws Exception { + createSessionFactory(); + ClientSession session = createSessionAndQueue(); - session = createSession(sf); + ClientProducer producer = addClientProducer(session.createProducer(FailoverTestBase.ADDRESS)); - ClientConsumer cc = session.createConsumer(FailoverTestBase.ADDRESS); + sendMessages(session, producer, NUM_MESSAGES); + producer.close(); + session.commit(); + SimpleString primaryId = primaryServer.getServer().getNodeID(); + crash(session); session.start(); + ClientConsumer consumer = addClientConsumer(session.createConsumer(FailoverTestBase.ADDRESS)); + receiveMessages(consumer); + assertNoMoreMessages(consumer); + consumer.close(); - ClientMessage cm = cc.receive(5000); - - assertNotNull(cm); - - assertEquals("message0", cm.getBodyBuffer().readString()); - } - - @Test - @Timeout(120) - public void testBackupConnections() throws Exception { - assumeTrue(backupServer.getServer().getHAPolicy().isBackup()); - - createSessionFactory(); + producer = addClientProducer(session.createProducer(FailoverTestBase.ADDRESS)); + sendMessages(session, producer, NUM_MESSAGES); + producer.close(); + session.commit(); - CountDownLatch latch = new CountDownLatch(1); - sf.addFailoverListener(eventType -> { - if (eventType == FailoverEventType.FAILOVER_COMPLETED) { - latch.countDown(); + assertEquals(primaryId, backupServer.getServer().getNodeID(), "backup must be running with the same nodeID"); + if (doFailBack) { + assertFalse(primaryServer.getServer().getHAPolicy().isBackup(), "must NOT be a backup"); + adaptPrimaryConfigForReplicatedFailBack(primaryServer); + beforeRestart(primaryServer); + primaryServer.start(); + assertTrue(primaryServer.getServer().waitForActivation(40, TimeUnit.SECONDS), "primary initialized..."); + if (isReplicated) { + // wait until it switch role again + Wait.assertTrue(() -> backupServer.getServer().getHAPolicy().isBackup()); + // wait until started + Wait.assertTrue(backupServer::isStarted); + // wait until is an in-sync replica + Wait.assertTrue(backupServer.getServer()::isReplicaSync); + } else { + Wait.assertTrue(backupServer::isStarted); + backupServer.getServer().waitForActivation(5, TimeUnit.SECONDS); + assertTrue(backupServer.isStarted()); } - }); - - BackupManager backupManager = ((ActiveMQServerImpl)backupServer.getServer()).getBackupManager(); - ClusterController backupClusterController = backupServer.getServer().getClusterManager().getClusterController(); - ClusterConnectionImpl backupClusterConnection = (ClusterConnectionImpl)backupServer.getServer().getClusterManager().getClusterConnections().stream().findFirst().get(); - - for (BackupManager.BackupConnector backupConnector : backupManager.getBackupConnectors()) { - for (ClientSessionFactoryInternal factory : ((ServerLocatorImpl)backupConnector.getBackupServerLocator()).getFactories()) { - assertNotNull(factory.getConnection()); + if (isReplicated) { + FileMoveManager moveManager = new FileMoveManager(backupServer.getServer().getConfiguration().getJournalLocation(), 0); + // backup has not had a chance to restart as a backup and cleanup + Wait.assertTrue(() -> moveManager.getNumberOfFolders() <= 2); } + } else { + backupServer.stop(); + beforeRestart(backupServer); + backupServer.start(); + assertTrue(backupServer.getServer().waitForActivation(10, TimeUnit.SECONDS)); } - for (ClientSessionFactoryInternal factory : ((ServerLocatorImpl)backupClusterController.getDefaultLocator()).getFactories()) { - assertNotNull(factory.getConnection()); - } - - assertNull(backupClusterConnection.getServerLocator()); + ClientSession session2 = createSession(sf, false, false); + session2.start(); + ClientConsumer consumer2 = session2.createConsumer(FailoverTestBase.ADDRESS); + receiveMessages(consumer2, 0, NUM_MESSAGES, true); + assertNoMoreMessages(consumer2); + session2.commit(); + } - assertNotNull(sf.getConnection()); + /** + * @param consumer + * @throws ActiveMQException + */ + protected void assertNoMoreMessages(ClientConsumer consumer) throws ActiveMQException { + ClientMessage msg = consumer.receiveImmediate(); + assertNull(msg, "there should be no more messages to receive! " + msg); + } - crash(); + protected void createSessionFactory() throws Exception { + locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setReconnectAttempts(300).setRetryInterval(100); - latch.await(); + sf = createSessionFactoryAndWaitForTopology(locator, 2); + } - for (BackupManager.BackupConnector backupConnector : backupManager.getBackupConnectors()) { - assertNull(backupConnector.getBackupServerLocator()); - } + /** + * @return + * @throws Exception + */ + protected ClientSession createSessionAndQueue() throws Exception { + ClientSession session = createSession(sf, false, false); - for (ClientSessionFactoryInternal factory : ((ServerLocatorImpl)backupServer.getServer().getClusterManager().getClusterController().getDefaultLocator()).getFactories()) { - assertNull(factory.getConnection()); - } + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); + return session; + } - for (ClientSessionFactoryInternal factory : ((ServerLocatorImpl)backupClusterConnection.getServerLocator()).getFactories()) { - assertNull(factory.getConnection()); + protected void sendMessagesSomeDurable(ClientSession session, ClientProducer producer) throws Exception { + for (int i = 0; i < NUM_MESSAGES; i++) { + // some are durable, some are not! + producer.send(createMessage(session, i, isDurable(i))); } - - assertNotNull(sf.getConnection()); } - - - @Override - protected TransportConfiguration getAcceptorTransportConfiguration(final boolean primary) { - return TransportConfigurationUtils.getInVMAcceptor(primary); + @Test + @Timeout(120) + public void testSimpleSendAfterFailoverDurableTemporary() throws Exception { + doSimpleSendAfterFailover(true, true); } - @Override - protected TransportConfiguration getConnectorTransportConfiguration(final boolean primary) { - return TransportConfigurationUtils.getInVMConnector(primary); + @Test + @Timeout(120) + public void testSimpleSendAfterFailoverNonDurableTemporary() throws Exception { + doSimpleSendAfterFailover(false, true); } - protected void beforeRestart(TestableServer primaryServer1) { - // no-op + @Test + @Timeout(120) + public void testSimpleSendAfterFailoverDurableNonTemporary() throws Exception { + doSimpleSendAfterFailover(true, false); } - protected void decrementActivationSequenceForForceRestartOf(TestableServer primaryServer) throws Exception { - // no-op + @Test + @Timeout(120) + public void testSimpleSendAfterFailoverNonDurableNonTemporary() throws Exception { + doSimpleSendAfterFailover(false, false); } - protected ClientSession sendAndConsume(final ClientSessionFactory sf1, final boolean createQueue) throws Exception { - ClientSession session = createSession(sf1, false, true, true); + private void doSimpleSendAfterFailover(final boolean durable, final boolean temporary) throws Exception { + locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setReconnectAttempts(300).setRetryInterval(100); + + sf = createSessionFactoryAndWaitForTopology(locator, 2); - if (createQueue) { - session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS).setDurable(false)); - } + ClientSession session = createSession(sf, true, true, 0); - ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS).setDurable(durable && !temporary).setTemporary(temporary)); - for (int i = 0; i < NUM_MESSAGES; i++) { - ClientMessage message = session.createMessage(ActiveMQTextMessage.TYPE, false, 0, System.currentTimeMillis(), (byte) 1); - message.putIntProperty(SimpleString.of("count"), i); - message.getBodyBuffer().writeString("aardvarks"); - producer.send(message); - } + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); session.start(); - for (int i = 0; i < NUM_MESSAGES; i++) { - ClientMessage message2 = consumer.receive(); - - assertEquals("aardvarks", message2.getBodyBuffer().readString()); - - assertEquals(i, message2.getObjectProperty(SimpleString.of("count"))); - - message2.acknowledge(); - } + crash(session); - ClientMessage message3 = consumer.receiveImmediate(); + sendMessagesSomeDurable(session, producer); - assertNull(message3); + receiveMessages(consumer); + } - return session; + protected void beforeRestart(TestableServer primaryServer1) { + // no-op } + protected void decrementActivationSequenceForForceRestartOf(TestableServer primaryServer) throws Exception { + // no-op + } } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailoverTestBase.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailoverTestBase.java index 27960fb0853..87e12f1e9b5 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailoverTestBase.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailoverTestBase.java @@ -17,7 +17,9 @@ package org.apache.activemq.artemis.tests.integration.cluster.failover; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.File; @@ -30,11 +32,16 @@ import java.util.concurrent.TimeUnit; import org.apache.activemq.artemis.api.core.ActiveMQBuffer; +import org.apache.activemq.artemis.api.core.ActiveMQException; +import org.apache.activemq.artemis.api.core.QueueConfiguration; import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.api.core.TransportConfiguration; import org.apache.activemq.artemis.api.core.client.ActiveMQClient; +import org.apache.activemq.artemis.api.core.client.ClientConsumer; import org.apache.activemq.artemis.api.core.client.ClientMessage; +import org.apache.activemq.artemis.api.core.client.ClientProducer; import org.apache.activemq.artemis.api.core.client.ClientSession; +import org.apache.activemq.artemis.api.core.client.ClientSessionFactory; import org.apache.activemq.artemis.api.core.client.ClusterTopologyListener; import org.apache.activemq.artemis.api.core.client.ServerLocator; import org.apache.activemq.artemis.api.core.client.TopologyMember; @@ -53,11 +60,13 @@ import org.apache.activemq.artemis.core.server.cluster.ha.ReplicatedPolicy; import org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl; import org.apache.activemq.artemis.core.server.impl.InVMNodeManager; +import org.apache.activemq.artemis.jms.client.ActiveMQTextMessage; import org.apache.activemq.artemis.lockmanager.file.FileBasedLockManager; import org.apache.activemq.artemis.tests.integration.cluster.util.SameProcessActiveMQServer; import org.apache.activemq.artemis.tests.integration.cluster.util.TestableServer; import org.apache.activemq.artemis.tests.util.ActiveMQTestBase; import org.apache.activemq.artemis.tests.util.ReplicatedBackupUtils; +import org.apache.activemq.artemis.tests.util.TransportConfigurationUtils; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -65,6 +74,8 @@ public abstract class FailoverTestBase extends ActiveMQTestBase { protected static final SimpleString ADDRESS = SimpleString.of("FailoverTestAddress"); + protected static final int NUM_MESSAGES = 100; + /* * Used only by tests of large messages. */ @@ -74,6 +85,8 @@ public abstract class FailoverTestBase extends ActiveMQTestBase { protected static final int PAGE_MAX = 2 * 1024; protected static final int PAGE_SIZE = 1024; + protected ServerLocator locator; + protected ClientSessionFactoryInternal sf; protected TestableServer primaryServer; @@ -110,6 +123,121 @@ public void setUp() throws Exception { } } + protected ClientSession sendAndConsume(final ClientSessionFactory sf, final boolean createQueue) throws Exception { + ClientSession session = sf.createSession(false, true, true); + + if (createQueue) { + session.createQueue(QueueConfiguration.of(ADDRESS)); + } + + ClientProducer producer = session.createProducer(ADDRESS); + + + for (int i = 0; i < NUM_MESSAGES; i++) { + ClientMessage message = session.createMessage(ActiveMQTextMessage.TYPE, false, 0, System.currentTimeMillis(), (byte) 1); + message.putIntProperty(SimpleString.of("count"), i); + message.getBodyBuffer().writeString("aardvarks"); + producer.send(message); + } + + ClientConsumer consumer = session.createConsumer(ADDRESS); + + session.start(); + + for (int i = 0; i < NUM_MESSAGES; i++) { + ClientMessage message2 = consumer.receive(); + + assertEquals("aardvarks", message2.getBodyBuffer().readString()); + + assertEquals(i, message2.getObjectProperty(SimpleString.of("count"))); + + message2.acknowledge(); + } + + ClientMessage message3 = consumer.receiveImmediate(); + + consumer.close(); + + assertNull(message3); + + return session; + } + + protected void receiveDurableMessages(ClientConsumer consumer) throws ActiveMQException { + // During failover non-persistent messages may disappear but in certain cases they may survive. + // For that reason the test is validating all the messages but being permissive with non-persistent messages + // The test will just ack any non-persistent message, however when arriving it must be in order + ClientMessage repeatMessage = null; + for (int i = 0; i < NUM_MESSAGES; i++) { + ClientMessage message; + + if (repeatMessage != null) { + message = repeatMessage; + repeatMessage = null; + } else { + message = consumer.receive(50); + } + + if (message != null) { + int msgInternalCounter = message.getIntProperty("counter").intValue(); + + if (msgInternalCounter == i + 1) { + // The test can only jump to the next message if the current iteration is meant for non-durable + assertFalse(isDurable(i), "a message on counter=" + i + " was expected"); + // message belongs to the next iteration.. let's just ignore it + repeatMessage = message; + continue; + } + } + + if (isDurable(i)) { + assertNotNull(message); + } + + if (message != null) { + assertMessageBody(i, message); + assertEquals(i, message.getIntProperty("counter").intValue()); + message.acknowledge(); + } + } + } + + protected boolean isDurable(int i) { + return i % 2 == 0; + } + + protected void receiveMessages(ClientConsumer consumer) throws ActiveMQException { + receiveMessages(consumer, 0, NUM_MESSAGES, true); + } + + protected ClientSession createSession(ClientSessionFactory sf1, + boolean autoCommitSends, + boolean autoCommitAcks, + int ackBatchSize) throws Exception { + return addClientSession(sf1.createSession(autoCommitSends, autoCommitAcks, ackBatchSize)); + } + + protected ClientSession createSession(ClientSessionFactory sf1, + boolean autoCommitSends, + boolean autoCommitAcks) throws Exception { + return addClientSession(sf1.createSession(autoCommitSends, autoCommitAcks)); + } + + protected ClientSession createSession(ClientSessionFactory sf1) throws Exception { + return addClientSession(sf1.createSession()); + } + + protected ClientSession createSession(ClientSessionFactory sf1, + boolean xa, + boolean autoCommitSends, + boolean autoCommitAcks) throws Exception { + return addClientSession(sf1.createSession(xa, autoCommitSends, autoCommitAcks)); + } + + protected void createClientSessionFactory() throws Exception { + sf = (ClientSessionFactoryInternal) createSessionFactory(locator); + } + protected void waitForBackup() { waitForRemoteBackupSynchronization(backupServer.getServer()); } @@ -343,9 +471,13 @@ protected void waitForBackup(ClientSessionFactoryInternal sessionFactory, int se } } - protected abstract TransportConfiguration getAcceptorTransportConfiguration(boolean live); + protected TransportConfiguration getAcceptorTransportConfiguration(final boolean primary) { + return TransportConfigurationUtils.getInVMAcceptor(primary); + } - protected abstract TransportConfiguration getConnectorTransportConfiguration(boolean live); + protected TransportConfiguration getConnectorTransportConfiguration(final boolean primary) { + return TransportConfigurationUtils.getInVMConnector(primary); + } protected ServerLocatorInternal getServerLocator() throws Exception { return (ServerLocatorInternal) addServerLocator(ActiveMQClient.createServerLocatorWithHA(getConnectorTransportConfiguration(true), getConnectorTransportConfiguration(false))).setRetryInterval(50).setInitialConnectAttempts(50); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FileLockNodeManagerTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FileLockNodeManagerTest.java index 6f00aaea9b8..c9e07fc1c51 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FileLockNodeManagerTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FileLockNodeManagerTest.java @@ -35,7 +35,6 @@ import org.apache.activemq.artemis.api.core.client.ClientConsumer; import org.apache.activemq.artemis.api.core.client.ClientProducer; import org.apache.activemq.artemis.api.core.client.ClientSession; -import org.apache.activemq.artemis.api.core.client.ClientSessionFactory; import org.apache.activemq.artemis.api.core.client.ServerLocator; import org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryInternal; import org.apache.activemq.artemis.core.config.Configuration; @@ -67,30 +66,6 @@ public enum NodeManagerType { InVM, Jdbc, File } - protected ClientSession createSession(ClientSessionFactory sf1, - boolean autoCommitSends, - boolean autoCommitAcks, - int ackBatchSize) throws Exception { - return addClientSession(sf1.createSession(autoCommitSends, autoCommitAcks, ackBatchSize)); - } - - protected ClientSession createSession(ClientSessionFactory sf1, - boolean autoCommitSends, - boolean autoCommitAcks) throws Exception { - return addClientSession(sf1.createSession(autoCommitSends, autoCommitAcks)); - } - - protected ClientSession createSession(ClientSessionFactory sf1) throws Exception { - return addClientSession(sf1.createSession()); - } - - protected ClientSession createSession(ClientSessionFactory sf1, - boolean xa, - boolean autoCommitSends, - boolean autoCommitAcks) throws Exception { - return addClientSession(sf1.createSession(xa, autoCommitSends, autoCommitAcks)); - } - @Parameters(name = "{0} Node Manager, Use Separate Lock Folder = {1}") public static Iterable nodeManagerTypes() { return Arrays.asList(new Object[][]{ diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/LargeMessageFailoverTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/LargeMessageFailoverTest.java index ded567d8e35..9a9e2184e3e 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/LargeMessageFailoverTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/LargeMessageFailoverTest.java @@ -18,25 +18,9 @@ import org.apache.activemq.artemis.api.core.client.ClientMessage; import org.apache.activemq.artemis.core.client.impl.ServerLocatorInternal; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; public class LargeMessageFailoverTest extends FailoverTest { - @Override - @Test - @Disabled - public void testPrimaryAndBackupPrimaryComesBackNewFactory() throws Exception { - // skip test because it triggers OutOfMemoryError. - } - - @Override - @Test - @Disabled - public void testPrimaryAndBackupBackupComesBackNewFactory() throws Exception { - // skip test because it triggers OutOfMemoryError. - } - /** * @param i * @param message diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/NettyReplicatedFailoverTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/NettyReplicatedFailoverTest.java index 389d29c36c5..e710dbbaca0 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/NettyReplicatedFailoverTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/NettyReplicatedFailoverTest.java @@ -21,25 +21,88 @@ import javax.jms.MessageProducer; import javax.jms.Queue; import javax.jms.Session; +import javax.transaction.xa.XAException; +import javax.transaction.xa.XAResource; +import javax.transaction.xa.Xid; import java.lang.invoke.MethodHandles; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import org.apache.activemq.artemis.api.core.ActiveMQDuplicateIdException; +import org.apache.activemq.artemis.api.core.ActiveMQException; +import org.apache.activemq.artemis.api.core.ActiveMQExceptionType; +import org.apache.activemq.artemis.api.core.ActiveMQInternalErrorException; +import org.apache.activemq.artemis.api.core.ActiveMQObjectClosedException; +import org.apache.activemq.artemis.api.core.ActiveMQTransactionOutcomeUnknownException; +import org.apache.activemq.artemis.api.core.ActiveMQTransactionRolledBackException; +import org.apache.activemq.artemis.api.core.Interceptor; +import org.apache.activemq.artemis.api.core.Message; +import org.apache.activemq.artemis.api.core.QueueConfiguration; import org.apache.activemq.artemis.api.core.SimpleString; +import org.apache.activemq.artemis.api.core.TransportConfiguration; +import org.apache.activemq.artemis.api.core.client.ClientConsumer; +import org.apache.activemq.artemis.api.core.client.ClientMessage; +import org.apache.activemq.artemis.api.core.client.ClientProducer; import org.apache.activemq.artemis.api.core.client.ClientSession; +import org.apache.activemq.artemis.api.core.client.FailoverEventType; +import org.apache.activemq.artemis.api.core.client.ServerLocator; +import org.apache.activemq.artemis.api.core.client.SessionFailureListener; +import org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryInternal; +import org.apache.activemq.artemis.core.client.impl.ClientSessionInternal; +import org.apache.activemq.artemis.core.client.impl.ServerLocatorImpl; import org.apache.activemq.artemis.core.config.Configuration; import org.apache.activemq.artemis.core.paging.PagingStore; import org.apache.activemq.artemis.core.paging.impl.Page; +import org.apache.activemq.artemis.core.protocol.core.Channel; +import org.apache.activemq.artemis.core.protocol.core.Packet; +import org.apache.activemq.artemis.core.protocol.core.impl.ActiveMQSessionContext; +import org.apache.activemq.artemis.core.protocol.core.impl.ChannelImpl; +import org.apache.activemq.artemis.core.protocol.core.impl.PacketImpl; +import org.apache.activemq.artemis.core.protocol.core.impl.RemotingConnectionImpl; +import org.apache.activemq.artemis.core.protocol.core.impl.wireformat.ActiveMQExceptionMessage; +import org.apache.activemq.artemis.core.server.cluster.BackupManager; +import org.apache.activemq.artemis.core.server.cluster.ClusterController; +import org.apache.activemq.artemis.core.server.cluster.ha.BackupPolicy; +import org.apache.activemq.artemis.core.server.cluster.ha.ReplicatedPolicy; +import org.apache.activemq.artemis.core.server.cluster.ha.ReplicationBackupPolicy; +import org.apache.activemq.artemis.core.server.cluster.ha.ReplicationPrimaryPolicy; +import org.apache.activemq.artemis.core.server.cluster.ha.SharedStoreBackupPolicy; +import org.apache.activemq.artemis.core.server.cluster.ha.SharedStorePrimaryPolicy; +import org.apache.activemq.artemis.core.server.cluster.impl.ClusterConnectionImpl; +import org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl; +import org.apache.activemq.artemis.core.server.impl.InVMNodeManager; import org.apache.activemq.artemis.core.server.impl.SharedNothingBackupActivation; +import org.apache.activemq.artemis.core.transaction.impl.XidImpl; +import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection; import org.apache.activemq.artemis.tests.integration.cluster.util.SameProcessActiveMQServer; import org.apache.activemq.artemis.tests.integration.cluster.util.TestableServer; import org.apache.activemq.artemis.tests.util.CFUtil; +import org.apache.activemq.artemis.tests.util.CountDownSessionFailureListener; import org.apache.activemq.artemis.tests.util.Wait; +import org.apache.activemq.artemis.utils.RandomUtil; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assumptions.assumeTrue; + public class NettyReplicatedFailoverTest extends NettyFailoverInVMTest { private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); @@ -49,6 +112,14 @@ protected TestableServer createTestableServer(Configuration config) { return new SameProcessActiveMQServer(createServer(true, config)); } + @BeforeEach + @Override + public void setUp() throws Exception { + super.setUp(); + locator = getServerLocator(); + } + + @Override protected void createConfigs() throws Exception { createReplicatedConfigs(); @@ -137,4 +208,2100 @@ public void testPagedInSync() throws Exception { } } + + // https://issues.jboss.org/browse/HORNETQ-685 + @Test + @Timeout(120) + public void testTimeoutOnFailover() throws Exception { + locator.setCallTimeout(1000).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setAckBatchSize(0).setReconnectAttempts(300).setRetryInterval(10); + + if (nodeManager instanceof InVMNodeManager) { + ((InVMNodeManager) nodeManager).failoverPause = 500L; + } + + ClientSessionFactoryInternal sf1 = (ClientSessionFactoryInternal) createSessionFactory(locator); + + final ClientSession session = createSession(sf1, true, true); + + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); + + final ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + final CountDownLatch latch = new CountDownLatch(10); + final CountDownLatch latchFailed = new CountDownLatch(1); + + Runnable r = () -> { + for (int i = 0; i < 500; i++) { + ClientMessage message = session.createMessage(true); + message.putIntProperty("counter", i); + try { + producer.send(message); + if (i < 10) { + latch.countDown(); + if (latch.getCount() == 0) { + latchFailed.await(10, TimeUnit.SECONDS); + } + } + } catch (Exception e) { + // this is our retry + try { + if (!producer.isClosed()) + producer.send(message); + } catch (ActiveMQException e1) { + e1.printStackTrace(); + } + } + } + }; + Thread t = new Thread(r); + t.start(); + assertTrue(latch.await(10, TimeUnit.SECONDS), "latch released"); + crash(session); + latchFailed.countDown(); + t.join(30000); + if (t.isAlive()) { + t.interrupt(); + fail("Thread still alive"); + } + assertTrue(backupServer.getServer().waitForActivation(5, TimeUnit.SECONDS)); + ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); + session.start(); + for (int i = 0; i < 500; i++) { + ClientMessage m = consumer.receive(1000); + assertNotNull(m, "message #=" + i); + // assertEquals(i, m.getIntProperty("counter").intValue()); + } + } + + // https://issues.jboss.org/browse/HORNETQ-685 + @Test + @Timeout(120) + public void testTimeoutOnFailoverConsume() throws Exception { + locator.setCallTimeout(1000).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setAckBatchSize(0).setBlockOnAcknowledge(true).setReconnectAttempts(-1).setRetryInterval(10).setAckBatchSize(0); + + if (nodeManager instanceof InVMNodeManager) { + ((InVMNodeManager) nodeManager).failoverPause = 2000L; + } + + ClientSessionFactoryInternal sf1 = (ClientSessionFactoryInternal) createSessionFactory(locator); + + final ClientSession session = createSession(sf1, true, false); + + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); + + final ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + for (int i = 0; i < 500; i++) { + ClientMessage message = session.createMessage(true); + message.putIntProperty("counter", i); + producer.send(message); + } + + final CountDownLatch latch = new CountDownLatch(1); + final CountDownLatch endLatch = new CountDownLatch(1); + + final ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); + session.start(); + + final Map received = new HashMap<>(); + + consumer.setMessageHandler(message -> { + + Integer counter = message.getIntProperty("counter"); + received.put(counter, message); + try { + logger.debug("acking message = id = {}, counter = {}", message.getMessageID(), message.getIntProperty("counter")); + message.acknowledge(); + session.commit(); + } catch (ActiveMQException e) { + try { + session.rollback(); + } catch (Exception e2) { + e.printStackTrace(); + } + e.printStackTrace(); + return; + } + logger.debug("Acked counter = {}", counter); + if (counter.equals(10)) { + latch.countDown(); + } + if (received.size() == 100) { + endLatch.countDown(); + } + }); + latch.await(10, TimeUnit.SECONDS); + logger.debug("crashing session"); + crash(session); + assertTrue(endLatch.await(60, TimeUnit.SECONDS)); + + session.close(); + } + + @Test + @Timeout(120) + public void testTimeoutOnFailoverConsumeBlocked() throws Exception { + locator.setCallTimeout(1000).setBlockOnNonDurableSend(true).setConsumerWindowSize(0).setBlockOnDurableSend(true).setAckBatchSize(0).setBlockOnAcknowledge(true).setReconnectAttempts(-1).setAckBatchSize(0).setRetryInterval(10); + + if (nodeManager instanceof InVMNodeManager) { + ((InVMNodeManager) nodeManager).failoverPause = 200L; + } + + ClientSessionFactoryInternal sf1 = (ClientSessionFactoryInternal) createSessionFactory(locator); + + final ClientSession session = createSession(sf1, true, true); + + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); + + final ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + for (int i = 0; i < 500; i++) { + ClientMessage message = session.createMessage(true); + message.putIntProperty("counter", i); + message.putBooleanProperty("end", i == 499); + producer.send(message); + } + + final CountDownLatch latch = new CountDownLatch(1); + final CountDownLatch endLatch = new CountDownLatch(1); + + final ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); + session.start(); + + final Map received = new HashMap<>(); + + Thread t = new Thread() { + @Override + public void run() { + ClientMessage message = null; + try { + while ((message = getMessage()) != null) { + Integer counter = message.getIntProperty("counter"); + received.put(counter, message); + try { + logger.debug("acking message = id = {}, counter = {}", message.getMessageID(), message.getIntProperty("counter")); + message.acknowledge(); + } catch (ActiveMQException e) { + e.printStackTrace(); + continue; + } + logger.debug("Acked counter = {}", counter); + if (counter.equals(10)) { + latch.countDown(); + } + if (received.size() == 500) { + endLatch.countDown(); + } + + if (message.getBooleanProperty("end")) { + break; + } + } + } catch (Exception e) { + fail("failing due to exception " + e); + } + + } + + private ClientMessage getMessage() { + while (true) { + try { + ClientMessage msg = consumer.receive(20000); + if (msg == null) { + logger.debug("Returning null message on consuming"); + } + return msg; + } catch (ActiveMQObjectClosedException oce) { + throw new RuntimeException(oce); + } catch (ActiveMQException ignored) { + // retry + ignored.printStackTrace(); + } + } + } + }; + t.start(); + latch.await(10, TimeUnit.SECONDS); + logger.debug("crashing session"); + crash(session); + endLatch.await(60, TimeUnit.SECONDS); + t.join(); + assertTrue(received.size() == 500, "received only " + received.size()); + + session.close(); + } + + // https://issues.jboss.org/browse/HORNETQ-685 + @Test + @Timeout(120) + public void testTimeoutOnFailoverTransactionCommit() throws Exception { + locator.setCallTimeout(1000).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setAckBatchSize(0).setReconnectAttempts(300).setRetryInterval(10); + + if (nodeManager instanceof InVMNodeManager) { + ((InVMNodeManager) nodeManager).failoverPause = 2000L; + } + + ClientSessionFactoryInternal sf1 = (ClientSessionFactoryInternal) createSessionFactory(locator); + + final ClientSession session = createSession(sf1, true, false, false); + + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); + + final CountDownLatch connectionFailed = new CountDownLatch(1); + + session.addFailureListener(new SessionFailureListener() { + @Override + public void beforeReconnect(ActiveMQException exception) { + } + + @Override + public void connectionFailed(ActiveMQException exception, boolean failedOver) { + } + + @Override + public void connectionFailed(ActiveMQException exception, boolean failedOver, String scaleDownTargetNodeID) { + connectionFailed.countDown(); + } + }); + + final ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + Xid xid = new XidImpl("uhuhuhu".getBytes(), 126512, "auhsduashd".getBytes()); + + session.start(xid, XAResource.TMNOFLAGS); + + for (int i = 0; i < 500; i++) { + ClientMessage message = session.createMessage(true); + message.putIntProperty("counter", i); + + producer.send(message); + + } + session.end(xid, XAResource.TMSUCCESS); + session.prepare(xid); + crash(true, session); + + try { + session.commit(xid, false); + } catch (XAException e) { + //there is still an edge condition that we must deal with + assertTrue(connectionFailed.await(10, TimeUnit.SECONDS)); + session.commit(xid, false); + } + + ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); + session.start(); + for (int i = 0; i < 500; i++) { + ClientMessage m = consumer.receive(1000); + assertNotNull(m); + assertEquals(i, m.getIntProperty("counter").intValue()); + } + } + + /** + * This test would fail one in three or five times, + * where the commit would leave the session dirty after a timeout. + */ + @Test + @Timeout(120) + public void testTimeoutOnFailoverTransactionCommitTimeoutCommunication() throws Exception { + locator.setCallTimeout(1000).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setAckBatchSize(0).setReconnectAttempts(300).setRetryInterval(50); + + if (nodeManager instanceof InVMNodeManager) { + ((InVMNodeManager) nodeManager).failoverPause = 2000L; + } + + ClientSessionFactoryInternal sf1 = (ClientSessionFactoryInternal) createSessionFactory(locator); + final ClientSession session = createSession(sf1, false, false, false); + + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); + + final CountDownLatch connectionFailed = new CountDownLatch(1); + + session.addFailureListener(new SessionFailureListener() { + @Override + public void beforeReconnect(ActiveMQException exception) { + } + + @Override + public void connectionFailed(ActiveMQException exception, boolean failedOver) { + } + + @Override + public void connectionFailed(ActiveMQException exception, boolean failedOver, String scaleDownTargetNodeID) { + connectionFailed.countDown(); + } + }); + + final ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + for (int i = 0; i < 500; i++) { + ClientMessage message = session.createMessage(true); + message.putIntProperty("counter", i); + + producer.send(message); + + } + + session.commit(); + + + ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); + session.start(); + ClientMessage m = null; + for (int i = 0; i < 500; i++) { + m = consumer.receive(1000); + assertNotNull(m); + assertEquals(i, m.getIntProperty("counter").intValue()); + } + + m.acknowledge(); + + crash(false, session); + try { + session.commit(); + fail("Exception expected"); + } catch (Exception expected) { + expected.printStackTrace(); + } + + Thread.sleep(1000); + + m = null; + for (int i = 0; i < 500; i++) { + m = consumer.receive(1000); + assertNotNull(m); + assertEquals(i, m.getIntProperty("counter").intValue()); + } + + m.acknowledge(); + + session.commit(); + + } + + // https://issues.jboss.org/browse/HORNETQ-685 + @Test + @Timeout(120) + public void testTimeoutOnFailoverTransactionRollback() throws Exception { + locator.setCallTimeout(2000).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setAckBatchSize(0).setReconnectAttempts(300).setRetryInterval(10); + + if (nodeManager instanceof InVMNodeManager) { + ((InVMNodeManager) nodeManager).failoverPause = 1000L; + } + + ClientSessionFactoryInternal sf1 = (ClientSessionFactoryInternal) createSessionFactory(locator); + + final ClientSession session = createSession(sf1, true, false, false); + + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); + + final ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + Xid xid = new XidImpl("uhuhuhu".getBytes(), 126512, "auhsduashd".getBytes()); + + session.start(xid, XAResource.TMNOFLAGS); + + for (int i = 0; i < 500; i++) { + ClientMessage message = session.createMessage(true); + message.putIntProperty("counter", i); + + producer.send(message); + } + + session.end(xid, XAResource.TMSUCCESS); + session.prepare(xid); + crash(true, session); + + try { + session.rollback(xid); + } catch (XAException e) { + try { + //there is still an edge condition that we must deal with + session.rollback(xid); + } catch (Exception ignored) { + logger.trace(ignored.getMessage(), ignored); + } + } + + ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); + session.start(); + + ClientMessage m = consumer.receiveImmediate(); + assertNull(m); + + } + + /** + * see http://jira.jboss.org/browse/HORNETQ-522 + * + * @throws Exception + */ + @Test + @Timeout(120) + public void testNonTransactedWithZeroConsumerWindowSize() throws Exception { + locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setAckBatchSize(0).setReconnectAttempts(300).setRetryInterval(10); + + createClientSessionFactory(); + + ClientSession session = createSession(sf, true, true); + + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); + + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + for (int i = 0; i < NUM_MESSAGES; i++) { + ClientMessage message = session.createMessage(true); + + setBody(i, message); + + message.putIntProperty("counter", i); + + producer.send(message); + } + + ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); + + final CountDownLatch latch = new CountDownLatch(NUM_MESSAGES); + + consumer.setMessageHandler(message -> latch.countDown()); + + session.start(); + + crash(session); + + assertTrue(latch.await(10, TimeUnit.SECONDS)); + + } + + + @Test + @Timeout(60) + public void testFailBothRestartPrimary() throws Exception { + ServerLocator locator = getServerLocator(); + + locator.setReconnectAttempts(-1).setRetryInterval(10); + + sf = (ClientSessionFactoryInternal)locator.createSessionFactory(); + + ClientSession session = createSession(sf, true, true); + + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); + + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + sendMessagesSomeDurable(session, producer); + + crash(session); + + ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); + + session.start(); + + receiveDurableMessages(consumer); + + backupServer.getServer().fail(true); + + decrementActivationSequenceForForceRestartOf(primaryServer); + + primaryServer.start(); + + consumer.close(); + + producer.close(); + + producer = session.createProducer(FailoverTestBase.ADDRESS); + + sendMessagesSomeDurable(session, producer); + + sf.close(); + assertEquals(0, sf.numSessions()); + assertEquals(0, sf.numConnections()); + } + + @Test + public void testFailPrimaryTooSoon() throws Exception { + ServerLocator locator = getServerLocator(); + + locator.setReconnectAttempts(-1); + locator.setRetryInterval(10); + + sf = (ClientSessionFactoryInternal)locator.createSessionFactory(); + + waitForBackupConfig(sf); + + TransportConfiguration initialPrimary = getFieldFromSF(sf, "currentConnectorConfig"); + TransportConfiguration initialBackup = getFieldFromSF(sf, "backupConnectorConfig"); + + logger.debug("initprimary: {}", initialPrimary); + logger.debug("initback: {}", initialBackup); + + TransportConfiguration last = getFieldFromSF(sf, "connectorConfig"); + TransportConfiguration current = getFieldFromSF(sf, "currentConnectorConfig"); + + logger.debug("now last: {}", last); + logger.debug("now current: {}", current); + assertTrue(current.equals(initialPrimary)); + + ClientSession session = createSession(sf, true, true); + + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); + + //crash 1 + crash(); + + //make sure failover is ok + createSession(sf, true, true).close(); + + last = getFieldFromSF(sf, "connectorConfig"); + current = getFieldFromSF(sf, "currentConnectorConfig"); + + logger.debug("now after primary crashed last: {}", last); + logger.debug("now current: {}", current); + + assertTrue(current.equals(initialBackup)); + + //fail back + beforeRestart(primaryServer); + adaptPrimaryConfigForReplicatedFailBack(primaryServer); + primaryServer.getServer().start(); + + assertTrue(primaryServer.getServer().waitForActivation(40, TimeUnit.SECONDS), "primary initialized..."); + org.apache.activemq.artemis.utils.Wait.assertTrue(backupServer::isStarted); + primaryServer.getServer().waitForActivation(5, TimeUnit.SECONDS); + assertTrue(backupServer.isStarted()); + + //make sure failover is ok + createSession(sf, true, true).close(); + + last = getFieldFromSF(sf, "connectorConfig"); + current = getFieldFromSF(sf, "currentConnectorConfig"); + + logger.debug("now after primary back again last: {}", last); + logger.debug("now current: {}", current); + + //cannot use equals here because the config's name (uuid) changes + //after failover + assertTrue(current.isSameParams(initialPrimary)); + + //now manually corrupt the backup in sf + setSFFieldValue(sf, "backupConnectorConfig", null); + + //crash 2 + crash(); + + beforeRestart(backupServer); + createSession(sf, true, true).close(); + + sf.close(); + assertEquals(0, sf.numSessions()); + assertEquals(0, sf.numConnections()); + } + + + @Test + @Timeout(120) + public void testFailBackPrimaryRestartsBackupIsGone() throws Exception { + createSessionFactory(); + ClientSession session = createSessionAndQueue(); + + ClientProducer producer = addClientProducer(session.createProducer(FailoverTestBase.ADDRESS)); + + sendMessages(session, producer, NUM_MESSAGES); + producer.close(); + session.commit(); + SimpleString primaryId = primaryServer.getServer().getNodeID(); + crash(session); + + session.start(); + ClientConsumer consumer = addClientConsumer(session.createConsumer(FailoverTestBase.ADDRESS)); + receiveMessages(consumer); + assertNoMoreMessages(consumer); + consumer.close(); + session.commit(); + + assertEquals(primaryId, backupServer.getServer().getNodeID(), "backup must be running with the same nodeID"); + sf.close(); + + backupServer.crash(); + Thread.sleep(100); + assertFalse(backupServer.isStarted(), "backup is not running"); + + final boolean isBackup = primaryServer.getServer().getHAPolicy() instanceof BackupPolicy || + primaryServer.getServer().getHAPolicy() instanceof ReplicationBackupPolicy; + assertFalse(isBackup, "must NOT be a backup"); + adaptPrimaryConfigForReplicatedFailBack(primaryServer); + beforeRestart(primaryServer); + decrementActivationSequenceForForceRestartOf(primaryServer); + primaryServer.start(); + assertTrue(primaryServer.getServer().waitForActivation(15, TimeUnit.SECONDS), "primary initialized..."); + + sf = (ClientSessionFactoryInternal) createSessionFactory(locator); + + ClientSession session2 = createSession(sf, false, false); + session2.start(); + ClientConsumer consumer2 = session2.createConsumer(FailoverTestBase.ADDRESS); + final boolean replication = primaryServer.getServer().getHAPolicy() instanceof ReplicatedPolicy || + primaryServer.getServer().getHAPolicy() instanceof ReplicationPrimaryPolicy; + if (replication) + receiveMessages(consumer2, 0, NUM_MESSAGES, true); + assertNoMoreMessages(consumer2); + session2.commit(); + } + + @Test + @Timeout(120) + public void testConsumeTransacted() throws Exception { + createSessionFactory(); + + ClientSession session = createSessionAndQueue(); + + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + final int numMessages = 10; + + sendMessages(session, producer, numMessages); + + session.commit(); + + ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); + + session.start(); + + for (int i = 0; i < numMessages; i++) { + ClientMessage message = consumer.receive(1000); + assertNotNull(message, "Just crashed? " + (i == 6) + " " + i); + + message.acknowledge(); + + // TODO: The test won't pass if you uncomment this line + // assertEquals(i, (int)message.getIntProperty("counter")); + + if (i == 5) { + crash(session); + } + } + + try { + session.commit(); + fail("session must have rolled back on failover"); + } catch (ActiveMQTransactionRolledBackException trbe) { + //ok + } catch (ActiveMQException e) { + fail("Invalid Exception type:" + e.getType()); + } + + consumer.close(); + + consumer = session.createConsumer(FailoverTestBase.ADDRESS); + + session.start(); + + for (int i = 0; i < numMessages; i++) { + ClientMessage message = consumer.receive(1000); + + assertNotNull(message, "Expecting message #" + i); + + message.acknowledge(); + } + + session.commit(); + + session.close(); + } + + + // https://jira.jboss.org/jira/browse/HORNETQ-285 + @Test + @Timeout(120) + public void testFailoverOnInitialConnection() throws Exception { + locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setReconnectAttempts(300).setRetryInterval(100); + + sf = createSessionFactoryAndWaitForTopology(locator, 2); + + // Crash primary server + crash(); + + ClientSession session = createSession(sf); + + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); + + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + sendMessages(session, producer, NUM_MESSAGES); + + ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); + + session.start(); + + receiveMessages(consumer); + + session.close(); + } + + + @Test + @Timeout(120) + public void testTransactedMessagesSentSoRollback() throws Exception { + createSessionFactory(); + + ClientSession session = createSessionAndQueue(); + + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + sendMessagesSomeDurable(session, producer); + + crash(session); + + assertTrue(session.isRollbackOnly()); + + try { + session.commit(); + + fail("Should throw exception"); + } catch (ActiveMQTransactionRolledBackException trbe) { + //ok + } catch (ActiveMQException e) { + fail("Invalid Exception type:" + e.getType()); + } + + ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); + + session.start(); + + ClientMessage message = consumer.receiveImmediate(); + + assertNull(message, "message should be null! Was: " + message); + + session.close(); + } + + /** + * Test that once the transacted session has throw a TRANSACTION_ROLLED_BACK exception, + * it can be reused again + */ + @Test + @Timeout(120) + public void testTransactedMessagesSentSoRollbackAndContinueWork() throws Exception { + createSessionFactory(); + + ClientSession session = createSessionAndQueue(); + + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + sendMessagesSomeDurable(session, producer); + + crash(session); + + assertTrue(session.isRollbackOnly()); + + try { + session.commit(); + + fail("Should throw exception"); + } catch (ActiveMQTransactionRolledBackException trbe) { + //ok + } catch (ActiveMQException e) { + fail("Invalid Exception type:" + e.getType()); + } + + ClientMessage message = session.createMessage(false); + int counter = RandomUtil.randomInt(); + message.putIntProperty("counter", counter); + + producer.send(message); + + // session is working again + session.commit(); + + session.start(); + + ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); + + session.start(); + message = consumer.receive(1000); + + assertNotNull(message, "expecting a message"); + assertEquals(counter, message.getIntProperty("counter").intValue()); + + session.close(); + } + + @Test + @Timeout(120) + public void testTransactedMessagesNotSentSoNoRollback() throws Exception { + try { + createSessionFactory(); + + ClientSession session = createSessionAndQueue(); + + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + sendMessagesSomeDurable(session, producer); + + session.commit(); + + crash(session); + + // committing again should work since didn't send anything since last commit + + assertFalse(session.isRollbackOnly()); + + session.commit(); + + ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); + + session.start(); + + receiveDurableMessages(consumer); + + assertNull(consumer.receiveImmediate()); + + session.commit(); + + session.close(); + } finally { + try { + primaryServer.getServer().stop(); + } catch (Throwable ignored) { + } + try { + backupServer.getServer().stop(); + } catch (Throwable ignored) { + } + } + } + + @Test + @Timeout(120) + public void testTransactedMessagesWithConsumerStartedBeforeFailover() throws Exception { + createSessionFactory(); + + ClientSession session = createSessionAndQueue(); + + // create a consumer and start the session before failover + ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); + + session.start(); + + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + sendMessagesSomeDurable(session, producer); + + // messages will be delivered to the consumer when the session is committed + session.commit(); + + assertFalse(session.isRollbackOnly()); + + crash(session); + + session.commit(); + + session.close(); + + session = createSession(sf, false, false); + + consumer = session.createConsumer(FailoverTestBase.ADDRESS); + + session.start(); + + receiveDurableMessages(consumer); + + assertNull(consumer.receiveImmediate()); + + session.commit(); + } + + @Test + @Timeout(120) + public void testTransactedMessagesConsumedSoRollback() throws Exception { + createSessionFactory(); + + ClientSession session1 = createSessionAndQueue(); + + ClientProducer producer = session1.createProducer(FailoverTestBase.ADDRESS); + + sendMessagesSomeDurable(session1, producer); + + session1.commit(); + + ClientSession session2 = createSession(sf, false, false); + + ClientConsumer consumer = session2.createConsumer(FailoverTestBase.ADDRESS); + + session2.start(); + + receiveMessages(consumer); + + crash(session2); + + assertTrue(session2.isRollbackOnly()); + + try { + session2.commit(); + + fail("Should throw exception"); + } catch (ActiveMQTransactionRolledBackException trbe) { + //ok + } catch (ActiveMQException e) { + fail("Invalid Exception type:" + e.getType()); + } + } + + @Test + @Timeout(120) + public void testTransactedMessagesNotConsumedSoNoRollback() throws Exception { + createSessionFactory(); + + ClientSession session1 = createSessionAndQueue(); + + ClientProducer producer = session1.createProducer(FailoverTestBase.ADDRESS); + + sendMessages(session1, producer, NUM_MESSAGES); + session1.commit(); + + ClientSession session2 = createSession(sf, false, false); + + ClientConsumer consumer = session2.createConsumer(FailoverTestBase.ADDRESS); + + session2.start(); + + receiveMessages(consumer, 0, NUM_MESSAGES / 2, true); + + session2.commit(); + + consumer.close(); + + crash(session2); + + assertFalse(session2.isRollbackOnly()); + + consumer = session2.createConsumer(FailoverTestBase.ADDRESS); + + for (int i = NUM_MESSAGES / 2; i < NUM_MESSAGES; i++) { + ClientMessage message = consumer.receive(1000); + + assertNotNull(message, "expecting message " + i); + + assertMessageBody(i, message); + + assertEquals(i, message.getIntProperty("counter").intValue()); + + message.acknowledge(); + } + + session2.commit(); + + assertNull(consumer.receiveImmediate()); + } + + @Test + @Timeout(120) + public void testXAMessagesSentSoRollbackOnEnd() throws Exception { + createSessionFactory(); + + ClientSession session = createSession(sf, true, false, false); + + Xid xid = new XidImpl("uhuhuhu".getBytes(), 126512, "auhsduashd".getBytes()); + + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); + + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + session.start(xid, XAResource.TMNOFLAGS); + + sendMessagesSomeDurable(session, producer); + + crash(session); + + try { + session.end(xid, XAResource.TMSUCCESS); + + fail("Should throw exception"); + } catch (XAException e) { + assertEquals(XAException.XAER_RMFAIL, e.errorCode); + } + + ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); + + session.start(); + + ClientMessage message = consumer.receiveImmediate(); + + assertNull(message); + } + + @Test + @Timeout(120) + //start a tx but sending messages after crash + public void testXAMessagesSentSoRollbackOnEnd2() throws Exception { + createSessionFactory(); + + ClientSession session = createSession(sf, true, false, false); + + Xid xid = new XidImpl("uhuhuhu".getBytes(), 126512, "auhsduashd".getBytes()); + + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); + + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + session.start(xid, XAResource.TMNOFLAGS); + + crash(session); + + // sendMessagesSomeDurable(session, producer); + + producer.send(createMessage(session, 1, true)); + + try { + session.end(xid, XAResource.TMSUCCESS); + + fail("Should throw exception"); + } catch (XAException e) { + // Assert.assertEquals(XAException.XAER_NOTA, e.errorCode); + } + + ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); + + session.start(); + + ClientMessage message = consumer.receiveImmediate(); + + assertNull(message); + } + + @Test + @Timeout(120) + public void testXAMessagesSentSoRollbackOnPrepare() throws Exception { + createSessionFactory(); + + final ClientSession session = createSession(sf, true, false, false); + + Xid xid = new XidImpl("uhuhuhu".getBytes(), 126512, "auhsduashd".getBytes()); + + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); + + final ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + session.start(xid, XAResource.TMNOFLAGS); + + sendMessagesSomeDurable(session, producer); + + session.end(xid, XAResource.TMSUCCESS); + + crash(session); + + try { + session.prepare(xid); + + fail("Should throw exception"); + } catch (XAException e) { + assertEquals(XAException.XAER_RMFAIL, e.errorCode); + // XXXX session.rollback(); + } + + ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); + + session.start(); + + ClientMessage message = consumer.receiveImmediate(); + + assertNull(message); + + producer.close(); + consumer.close(); + } + + // This might happen if 1PC optimisation kicks in + @Test + @Timeout(120) + public void testXAMessagesSentSoRollbackOnCommit() throws Exception { + createSessionFactory(); + + ClientSession session = createSession(sf, true, false, false); + + Xid xid = new XidImpl("uhuhuhu".getBytes(), 126512, "auhsduashd".getBytes()); + + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); + + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + session.start(xid, XAResource.TMNOFLAGS); + + sendMessagesSomeDurable(session, producer); + + session.end(xid, XAResource.TMSUCCESS); + + crash(session); + + try { + session.commit(xid, false); + + fail("Should throw exception"); + } catch (XAException e) { + assertEquals(XAException.XAER_NOTA, e.errorCode); + } + + ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); + + session.start(); + + ClientMessage message = consumer.receiveImmediate(); + + assertNull(message); + } + + @Test + @Timeout(120) + public void testXAMessagesNotSentSoNoRollbackOnCommit() throws Exception { + createSessionFactory(); + + ClientSession session = createSession(sf, true, false, false); + + Xid xid = new XidImpl("uhuhuhu".getBytes(), 126512, "auhsduashd".getBytes()); + + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); + + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + session.start(xid, XAResource.TMNOFLAGS); + + sendMessagesSomeDurable(session, producer); + + session.end(xid, XAResource.TMSUCCESS); + + session.prepare(xid); + + session.commit(xid, false); + + crash(session); + + ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); + + session.start(); + + Xid xid2 = new XidImpl("tfytftyf".getBytes(), 54654, "iohiuohiuhgiu".getBytes()); + + session.start(xid2, XAResource.TMNOFLAGS); + + receiveDurableMessages(consumer); + + session.end(xid2, XAResource.TMSUCCESS); + + session.prepare(xid2); + + session.commit(xid2, false); + } + + @Test + @Timeout(120) + public void testXAMessagesConsumedSoRollbackOnEnd() throws Exception { + createSessionFactory(); + + ClientSession session1 = createSessionAndQueue(); + + ClientProducer producer = session1.createProducer(FailoverTestBase.ADDRESS); + + sendMessagesSomeDurable(session1, producer); + + session1.commit(); + + ClientSession session2 = createSession(sf, true, false, false); + + ClientConsumer consumer = session2.createConsumer(FailoverTestBase.ADDRESS); + + session2.start(); + + Xid xid = new XidImpl("uhuhuhu".getBytes(), 126512, "auhsduashd".getBytes()); + + session2.start(xid, XAResource.TMNOFLAGS); + + receiveMessages(consumer); + + crash(session2); + + try { + session2.end(xid, XAResource.TMSUCCESS); + + fail("Should throw exception"); + } catch (XAException e) { + assertEquals(XAException.XAER_RMFAIL, e.errorCode); + } + } + + @Test + @Timeout(120) + public void testXAMessagesConsumedSoRollbackOnEnd2() throws Exception { + createSessionFactory(); + + ClientSession session1 = createSessionAndQueue(); + + ClientProducer producer = session1.createProducer(FailoverTestBase.ADDRESS); + + for (int i = 0; i < NUM_MESSAGES; i++) { + // some are durable, some are not! + producer.send(createMessage(session1, i, true)); + } + + session1.commit(); + + ClientSession session2 = createSession(sf, true, false, false); + + ClientConsumer consumer = session2.createConsumer(FailoverTestBase.ADDRESS); + + session2.start(); + + Xid xid = new XidImpl("uhuhuhu".getBytes(), 126512, "auhsduashd".getBytes()); + + session2.start(xid, XAResource.TMNOFLAGS); + + crash(session2); + + receiveMessages(consumer); + + try { + session2.end(xid, XAResource.TMSUCCESS); + + fail("Should throw exception"); + } catch (XAException e) { + } + + // Since the end was not accepted, the messages should be redelivered + receiveMessages(consumer); + } + + @Test + @Timeout(120) + public void testXAMessagesConsumedSoRollbackOnPrepare() throws Exception { + createSessionFactory(); + + ClientSession session1 = createSessionAndQueue(); + + ClientProducer producer = session1.createProducer(FailoverTestBase.ADDRESS); + + sendMessagesSomeDurable(session1, producer); + + session1.commit(); + + ClientSession session2 = createSession(sf, true, false, false); + + ClientConsumer consumer = session2.createConsumer(FailoverTestBase.ADDRESS); + + session2.start(); + + Xid xid = new XidImpl("uhuhuhu".getBytes(), 126512, "auhsduashd".getBytes()); + + session2.start(xid, XAResource.TMNOFLAGS); + + receiveMessages(consumer); + + session2.end(xid, XAResource.TMSUCCESS); + + crash(session2); + + try { + session2.prepare(xid); + + fail("Should throw exception"); + } catch (XAException e) { + assertEquals(XAException.XAER_RMFAIL, e.errorCode); + } + } + + // 1PC optimisation + @Test + @Timeout(120) + public void testXAMessagesConsumedSoRollbackOnCommit() throws Exception { + createSessionFactory(); + ClientSession session1 = createSessionAndQueue(); + + ClientProducer producer = session1.createProducer(FailoverTestBase.ADDRESS); + + sendMessagesSomeDurable(session1, producer); + + session1.commit(); + + ClientSession session2 = createSession(sf, true, false, false); + + ClientConsumer consumer = session2.createConsumer(FailoverTestBase.ADDRESS); + + session2.start(); + + Xid xid = new XidImpl("uhuhuhu".getBytes(), 126512, "auhsduashd".getBytes()); + + session2.start(xid, XAResource.TMNOFLAGS); + + receiveMessages(consumer); + + session2.end(xid, XAResource.TMSUCCESS); + + // session2.prepare(xid); + + crash(session2); + + try { + session2.commit(xid, false); + + fail("Should throw exception"); + } catch (XAException e) { + // it should be rolled back + assertEquals(XAException.XAER_NOTA, e.errorCode); + } + + session1.close(); + + session2.close(); + } + + @Test + @Timeout(120) + public void testCreateNewFactoryAfterFailover() throws Exception { + locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true); + sf = createSessionFactoryAndWaitForTopology(locator, 2); + + ClientSession session = sendAndConsume(sf, true); + + crash(true, session); + + session.close(); + + long timeout; + timeout = System.currentTimeMillis() + 5000; + while (timeout > System.currentTimeMillis()) { + try { + createClientSessionFactory(); + break; + } catch (Exception e) { + // retrying + Thread.sleep(100); + } + } + + session = sendAndConsume(sf, false); + } + + @Test + @Timeout(120) + public void testFailoverMultipleSessionsWithConsumers() throws Exception { + createSessionFactory(); + + final int numSessions = 5; + + final int numConsumersPerSession = 5; + + Map> sessionConsumerMap = new HashMap<>(); + + for (int i = 0; i < numSessions; i++) { + ClientSession session = createSession(sf, true, true); + + List consumers = new ArrayList<>(); + + for (int j = 0; j < numConsumersPerSession; j++) { + SimpleString queueName = SimpleString.of("queue" + i + "-" + j); + + session.createQueue(QueueConfiguration.of(queueName).setAddress(FailoverTestBase.ADDRESS)); + + ClientConsumer consumer = session.createConsumer(queueName); + + consumers.add(consumer); + } + + sessionConsumerMap.put(session, consumers); + } + + ClientSession sendSession = createSession(sf, true, true); + + ClientProducer producer = sendSession.createProducer(FailoverTestBase.ADDRESS); + + sendMessages(sendSession, producer, NUM_MESSAGES); + + Set sessionSet = sessionConsumerMap.keySet(); + ClientSession[] sessions = new ClientSession[sessionSet.size()]; + sessionSet.toArray(sessions); + crash(sessions); + + for (ClientSession session : sessionConsumerMap.keySet()) { + session.start(); + } + + for (List consumerList : sessionConsumerMap.values()) { + for (ClientConsumer consumer : consumerList) { + receiveMessages(consumer); + } + } + } + + /* + * Browser will get reset to beginning after failover + */ + @Test + @Timeout(120) + public void testFailWithBrowser() throws Exception { + createSessionFactory(); + ClientSession session = createSession(sf, true, true); + + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); + + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + sendMessagesSomeDurable(session, producer); + + ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS, true); + + session.start(); + + receiveMessages(consumer, 0, NUM_MESSAGES, false); + + crash(session); + + receiveDurableMessages(consumer); + } + + + @Test + @Timeout(120) + public void testFailThenReceiveMoreMessagesAfterFailover() throws Exception { + createSessionFactory(); + + ClientSession session = createSession(sf, true, true); + + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); + + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + sendMessagesSomeDurable(session, producer); + + ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); + + session.start(); + + // Receive MSGs but don't ack! + for (int i = 0; i < NUM_MESSAGES; i++) { + ClientMessage message = consumer.receive(1000); + + assertNotNull(message); + + assertMessageBody(i, message); + + assertEquals(i, message.getIntProperty("counter").intValue()); + } + + crash(session); + + // Should get the same ones after failover since we didn't ack + + receiveDurableMessages(consumer); + } + + @Test + @Timeout(120) + public void testFailThenReceiveMoreMessagesAfterFailover2() throws Exception { + locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setReconnectAttempts(300).setRetryInterval(100); + + sf = createSessionFactoryAndWaitForTopology(locator, 2); + + ClientSession session = createSession(sf, true, true, 0); + + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); + + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + sendMessagesSomeDurable(session, producer); + + ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); + + session.start(); + receiveMessages(consumer); + + crash(session); + + // Send some more + + for (int i = NUM_MESSAGES; i < NUM_MESSAGES * 2; i++) { + producer.send(createMessage(session, i, isDurable(i))); + } + receiveMessages(consumer, NUM_MESSAGES, NUM_MESSAGES * 2, true); + } + + @Test + @Timeout(120) + public void testMultipleSessionFailover() throws Exception { + final String address = "TEST"; + locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setReconnectAttempts(300).setRetryInterval(100); + + sf = createSessionFactoryAndWaitForTopology(locator, 2); + + ClientSession session1 = createSession(sf, true, true, 0); + ClientSession session2 = createSession(sf, true, true, 0); + + backupServer.addInterceptor( + new Interceptor() { + private int index = 0; + + @Override + public boolean intercept(Packet packet, RemotingConnection connection) throws ActiveMQException { + if (packet.getType() == PacketImpl.CREATESESSION) { + index++; + if (index == 2 || index == 3) { + Channel sessionChannel = ((RemotingConnectionImpl) connection).getChannel(ChannelImpl.CHANNEL_ID.SESSION.id, -1); + sessionChannel.send(new ActiveMQExceptionMessage(new ActiveMQInternalErrorException())); + return false; + } + } + return true; + } + }); + + session1.start(); + session2.start(); + + crash(session1, session2); + + session1.createQueue(QueueConfiguration.of(address).setAddress(address)); + + ClientProducer clientProducer = session1.createProducer(address); + clientProducer.send(session1.createMessage(false)); + + ClientConsumer clientConsumer = session2.createConsumer(address); + ClientMessage message = clientConsumer.receive(3000); + assertNotNull(message); + } + + @Test + @Timeout(120) + public void testChannelStateDuringFailover() throws Exception { + locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setReconnectAttempts(300).setRetryInterval(100); + + sf = createSessionFactoryAndWaitForTopology(locator, 2); + + final int reconnectFailures = 3; + final AtomicInteger reconnectRetries = new AtomicInteger(0); + final AtomicBoolean channelLockedDuringFailover = new AtomicBoolean(true); + + ClientSession session = createSession(sf, true, true, 0); + + backupServer.addInterceptor((packet, connection) -> { + if (packet.getType() == PacketImpl.CREATESESSION) { + if (reconnectRetries.getAndIncrement() < reconnectFailures) { + Channel sessionChannel = ((RemotingConnectionImpl)connection).getChannel(ChannelImpl.CHANNEL_ID.SESSION.id, -1); + sessionChannel.send(new ActiveMQExceptionMessage(new ActiveMQInternalErrorException())); + return false; + } + + ActiveMQSessionContext sessionContext = (ActiveMQSessionContext)((ClientSessionInternal)session).getSessionContext(); + channelLockedDuringFailover.compareAndSet(true, sessionContext.getSessionChannel().isLocked()); + } + return true; + }); + + session.start(); + + crash(session); + + assertTrue(channelLockedDuringFailover.get()); + assertEquals(reconnectFailures + 1, reconnectRetries.get()); + } + + @Test + @Timeout(120) + public void testForceBlockingReturn() throws Exception { + locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setReconnectAttempts(300).setRetryInterval(100); + + createClientSessionFactory(); + + // Add an interceptor to delay the send method so we can get time to cause failover before it returns + DelayInterceptor interceptor = new DelayInterceptor(); + primaryServer.getServer().getRemotingService().addIncomingInterceptor(interceptor); + + final ClientSession session = createSession(sf, true, true, 0); + + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); + + final ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + class Sender extends Thread { + + @Override + public void run() { + ClientMessage message = session.createMessage(true); + + message.getBodyBuffer().writeString("message"); + + try { + producer.send(message); + } catch (ActiveMQException e1) { + this.e = e1; + } + } + + volatile ActiveMQException e; + } + + Sender sender = new Sender(); + + sender.start(); + + //if server crash too early, + //sender will directly send to backup. so + //need some waiting here. + assertTrue(interceptor.await()); + + crash(session); + + sender.join(); + + assertNotNull(sender.e); + + assertNotNull(sender.e.getCause()); + + assertEquals(sender.e.getType(), ActiveMQExceptionType.UNBLOCKED); + + assertEquals(((ActiveMQException) sender.e.getCause()).getType(), ActiveMQExceptionType.DISCONNECTED); + + session.close(); + } + + @Test + @Timeout(120) + public void testCommitOccurredUnblockedAndResendNoDuplicates() throws Exception { + locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setReconnectAttempts(300).setRetryInterval(100).setBlockOnAcknowledge(true); + + sf = createSessionFactoryAndWaitForTopology(locator, 2); + + final ClientSession session = createSession(sf, false, false); + + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); + + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + String txID = "my-tx-id"; + + for (int i = 0; i < NUM_MESSAGES; i++) { + ClientMessage message = session.createMessage(true); + + if (i == 0) { + // Only need to add it on one message per tx + message.putStringProperty(Message.HDR_DUPLICATE_DETECTION_ID, SimpleString.of(txID)); + } + + setBody(i, message); + + message.putIntProperty("counter", i); + + producer.send(message); + } + + class Committer extends Thread { + + DelayInterceptor2 interceptor = new DelayInterceptor2(); + + @Override + public void run() { + try { + sf.getServerLocator().addIncomingInterceptor(interceptor); + + session.commit(); + } catch (ActiveMQTransactionRolledBackException trbe) { + // Ok - now we retry the commit after removing the interceptor + + sf.getServerLocator().removeIncomingInterceptor(interceptor); + + try { + session.commit(); + + failed = false; + } catch (ActiveMQException e2) { + throw new RuntimeException(e2); + } + } catch (ActiveMQTransactionOutcomeUnknownException toue) { + // Ok - now we retry the commit after removing the interceptor + + sf.getServerLocator().removeIncomingInterceptor(interceptor); + + try { + session.commit(); + + failed = false; + } catch (ActiveMQException e2) { + throw new RuntimeException(e2); + } + } catch (ActiveMQException e) { + //ignore + } + } + + volatile boolean failed = true; + } + + Committer committer = new Committer(); + + // Commit will occur, but response will never get back, connection is failed, and commit + // should be unblocked with transaction rolled back + + committer.start(); + + // Wait for the commit to occur and the response to be discarded + assertTrue(committer.interceptor.await()); + + crash(session); + + committer.join(); + + assertFalse(committer.failed, "second attempt succeed?"); + + session.close(); + + ClientSession session2 = createSession(sf, false, false); + + producer = session2.createProducer(FailoverTestBase.ADDRESS); + + // We now try and resend the messages since we get a transaction rolled back exception + // but the commit actually succeeded, duplicate detection should kick in and prevent dups + + for (int i = 0; i < NUM_MESSAGES; i++) { + ClientMessage message = session2.createMessage(true); + + if (i == 0) { + // Only need to add it on one message per tx + message.putStringProperty(Message.HDR_DUPLICATE_DETECTION_ID, SimpleString.of(txID)); + } + + setBody(i, message); + + message.putIntProperty("counter", i); + + producer.send(message); + } + + try { + session2.commit(); + fail("expecting DUPLICATE_ID_REJECTED exception"); + } catch (ActiveMQDuplicateIdException dide) { + //ok + } catch (ActiveMQException e) { + fail("Invalid Exception type:" + e.getType()); + } + + ClientConsumer consumer = session2.createConsumer(FailoverTestBase.ADDRESS); + + session2.start(); + + receiveMessages(consumer); + + ClientMessage message = consumer.receiveImmediate(); + + assertNull(message); + } + + @Test + @Timeout(120) + public void testCommitDidNotOccurUnblockedAndResend() throws Exception { + locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setReconnectAttempts(300).setRetryInterval(100); + + sf = createSessionFactoryAndWaitForTopology(locator, 2); + + final ClientSession session = createSession(sf, false, false); + + session.createQueue(QueueConfiguration.of(FailoverTestBase.ADDRESS)); + + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + sendMessages(session, producer, NUM_MESSAGES); + + class Committer extends Thread { + + @Override + public void run() { + Interceptor interceptor = new DelayInterceptor3(); + + try { + primaryServer.addInterceptor(interceptor); + + session.commit(); + } catch (ActiveMQTransactionRolledBackException trbe) { + // Ok - now we retry the commit after removing the interceptor + + primaryServer.removeInterceptor(interceptor); + + try { + session.commit(); + + failed = false; + } catch (ActiveMQException e2) { + } + } catch (ActiveMQTransactionOutcomeUnknownException toue) { + // Ok - now we retry the commit after removing the interceptor + + primaryServer.removeInterceptor(interceptor); + + try { + session.commit(); + + failed = false; + } catch (ActiveMQException e2) { + } + } catch (ActiveMQException e) { + //ignore + } + } + + volatile boolean failed = true; + } + + Committer committer = new Committer(); + + committer.start(); + + crash(session); + + committer.join(); + + assertFalse(committer.failed, "commiter failed should be false"); + + session.close(); + + ClientSession session2 = createSession(sf, false, false); + + producer = session2.createProducer(FailoverTestBase.ADDRESS); + + // We now try and resend the messages since we get a transaction rolled back exception + sendMessages(session2, producer, NUM_MESSAGES); + + session2.commit(); + + ClientConsumer consumer = session2.createConsumer(FailoverTestBase.ADDRESS); + + session2.start(); + + receiveMessages(consumer); + + ClientMessage message = consumer.receiveImmediate(); + + assertNull(message, "expecting null message"); + } + + @Test + @Timeout(120) + public void testBackupServerNotRemoved() throws Exception { + // HORNETQ-720 Disabling test for replicating backups. + if (!(backupServer.getServer().getHAPolicy() instanceof SharedStoreBackupPolicy)) { + return; + } + createSessionFactory(); + + ClientSession session = sendAndConsume(sf, true); + CountDownSessionFailureListener listener = new CountDownSessionFailureListener(session); + + session.addFailureListener(listener); + + backupServer.stop(); + + primaryServer.crash(); + + // To reload security or other settings that are read during startup + beforeRestart(backupServer); + + backupServer.start(); + + assertTrue(listener.getLatch().await(5, TimeUnit.SECONDS), "session failure listener"); + + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + ClientMessage message = session.createMessage(true); + + setBody(0, message); + + producer.send(message); + } + + @Test + @Timeout(120) + public void testPrimaryAndBackupPrimaryComesBack() throws Exception { + createSessionFactory(); + final CountDownLatch latch = new CountDownLatch(1); + + ClientSession session = sendAndConsume(sf, true); + + session.addFailureListener(new CountDownSessionFailureListener(latch, session)); + + backupServer.stop(); + + primaryServer.crash(); + + beforeRestart(primaryServer); + + // To reload security or other settings that are read during startup + beforeRestart(primaryServer); + + primaryServer.start(); + + assertTrue(latch.await(5, TimeUnit.SECONDS)); + + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + ClientMessage message = session.createMessage(true); + + setBody(0, message); + + producer.send(message); + } + + @Test + @Timeout(120) + public void testPrimaryAndBackupPrimaryComesBackNewFactory() throws Exception { + createSessionFactory(); + + final CountDownLatch latch = new CountDownLatch(1); + + ClientSession session = sendAndConsume(sf, true); + + session.addFailureListener(new CountDownSessionFailureListener(latch, session)); + + backupServer.stop(); + + primaryServer.crash(); + + // To reload security or other settings that are read during startup + beforeRestart(primaryServer); + + primaryServer.start(); + + assertTrue(latch.await(5, TimeUnit.SECONDS)); + + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + ClientMessage message = session.createMessage(true); + + setBody(0, message); + + producer.send(message); + + session.close(); + + sf.close(); + + createClientSessionFactory(); + + session = createSession(sf); + + ClientConsumer cc = session.createConsumer(FailoverTestBase.ADDRESS); + + session.start(); + + ClientMessage cm = cc.receive(5000); + + assertNotNull(cm); + + assertEquals("message0", cm.getBodyBuffer().readString()); + } + + @Test + @Timeout(120) + public void testPrimaryAndBackupBackupComesBackNewFactory() throws Exception { + locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setReconnectAttempts(300).setRetryInterval(100); + + sf = createSessionFactoryAndWaitForTopology(locator, 2); + + ClientSession session = sendAndConsume(sf, true); + + CountDownSessionFailureListener listener = new CountDownSessionFailureListener(session); + + session.addFailureListener(listener); + + backupServer.stop(); + + primaryServer.crash(); + + // To reload security or other settings that are read during startup + beforeRestart(backupServer); + + if (!backupServer.getServer().getHAPolicy().isSharedStore()) { + // XXX + // this test would not make sense in the remote replication use case, without the following + backupServer.getServer().setHAPolicy(new SharedStorePrimaryPolicy()); + } + + backupServer.start(); + + assertTrue(listener.getLatch().await(5, TimeUnit.SECONDS), "session failure listener"); + + ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); + + ClientMessage message = session.createMessage(true); + + setBody(0, message); + + producer.send(message); + + session.close(); + + sf.close(); + + createClientSessionFactory(); + + session = createSession(sf); + + ClientConsumer cc = session.createConsumer(FailoverTestBase.ADDRESS); + + session.start(); + + ClientMessage cm = cc.receive(5000); + + assertNotNull(cm); + + assertEquals("message0", cm.getBodyBuffer().readString()); + } + + @Test + @Timeout(120) + public void testBackupConnections() throws Exception { + assumeTrue(backupServer.getServer().getHAPolicy().isBackup()); + + createSessionFactory(); + + CountDownLatch latch = new CountDownLatch(1); + sf.addFailoverListener(eventType -> { + if (eventType == FailoverEventType.FAILOVER_COMPLETED) { + latch.countDown(); + } + }); + + BackupManager backupManager = ((ActiveMQServerImpl)backupServer.getServer()).getBackupManager(); + ClusterController backupClusterController = backupServer.getServer().getClusterManager().getClusterController(); + ClusterConnectionImpl backupClusterConnection = (ClusterConnectionImpl)backupServer.getServer().getClusterManager().getClusterConnections().stream().findFirst().get(); + + for (BackupManager.BackupConnector backupConnector : backupManager.getBackupConnectors()) { + for (ClientSessionFactoryInternal factory : ((ServerLocatorImpl)backupConnector.getBackupServerLocator()).getFactories()) { + assertNotNull(factory.getConnection()); + } + } + + for (ClientSessionFactoryInternal factory : ((ServerLocatorImpl)backupClusterController.getDefaultLocator()).getFactories()) { + assertNotNull(factory.getConnection()); + } + + assertNull(backupClusterConnection.getServerLocator()); + + assertNotNull(sf.getConnection()); + + crash(); + + latch.await(); + + for (BackupManager.BackupConnector backupConnector : backupManager.getBackupConnectors()) { + assertNull(backupConnector.getBackupServerLocator()); + } + + for (ClientSessionFactoryInternal factory : ((ServerLocatorImpl)backupServer.getServer().getClusterManager().getClusterController().getDefaultLocator()).getFactories()) { + assertNull(factory.getConnection()); + } + + for (ClientSessionFactoryInternal factory : ((ServerLocatorImpl)backupClusterConnection.getServerLocator()).getFactories()) { + assertNull(factory.getConnection()); + } + + assertNotNull(sf.getConnection()); + } + + + } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/NetworkFailureFailoverTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/NetworkFailureFailoverTest.java index 4ac18b03253..69ea86d3a4c 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/NetworkFailureFailoverTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/NetworkFailureFailoverTest.java @@ -34,7 +34,6 @@ import org.apache.activemq.artemis.api.core.client.ClientMessage; import org.apache.activemq.artemis.api.core.client.ClientProducer; import org.apache.activemq.artemis.api.core.client.ClientSession; -import org.apache.activemq.artemis.api.core.client.ClientSessionFactory; import org.apache.activemq.artemis.api.core.client.ServerLocator; import org.apache.activemq.artemis.api.core.client.SessionFailureListener; import org.apache.activemq.artemis.api.core.client.TopologyMember; @@ -103,30 +102,6 @@ protected TransportConfiguration getConnectorTransportConfiguration(final boolea return getNettyConnectorTransportConfiguration(live); } - protected ClientSession createSession(ClientSessionFactory sf1, - boolean autoCommitSends, - boolean autoCommitAcks, - int ackBatchSize) throws Exception { - return addClientSession(sf1.createSession(autoCommitSends, autoCommitAcks, ackBatchSize)); - } - - protected ClientSession createSession(ClientSessionFactory sf1, - boolean autoCommitSends, - boolean autoCommitAcks) throws Exception { - return addClientSession(sf1.createSession(autoCommitSends, autoCommitAcks)); - } - - protected ClientSession createSession(ClientSessionFactory sf1) throws Exception { - return addClientSession(sf1.createSession()); - } - - protected ClientSession createSession(ClientSessionFactory sf1, - boolean xa, - boolean autoCommitSends, - boolean autoCommitAcks) throws Exception { - return addClientSession(sf1.createSession(xa, autoCommitSends, autoCommitAcks)); - } - @Override protected TransportConfiguration getNettyAcceptorTransportConfiguration(final boolean live) { Map server1Params = new HashMap<>(); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/NetworkIsolationTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/NetworkIsolationTest.java index 41d447477c0..03f0e677b00 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/NetworkIsolationTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/NetworkIsolationTest.java @@ -61,13 +61,6 @@ protected TransportConfiguration getConnectorTransportConfiguration(final boolea return TransportConfigurationUtils.getNettyConnector(live, 1); } - protected ClientSession createSession(ClientSessionFactory sf1, - boolean xa, - boolean autoCommitSends, - boolean autoCommitAcks) throws Exception { - return addClientSession(sf1.createSession(xa, autoCommitSends, autoCommitAcks)); - } - @Test public void testReactivate() throws Exception { primaryServer.getServer().getConfiguration().setNetworkCheckPeriod(100).setNetworkCheckTimeout(200); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/PrimaryToPrimaryFailoverTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/PrimaryToPrimaryFailoverTest.java index 6b422415b77..8471b80bdc7 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/PrimaryToPrimaryFailoverTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/PrimaryToPrimaryFailoverTest.java @@ -41,10 +41,9 @@ import org.apache.activemq.artemis.tests.util.TransportConfigurationUtils; import org.apache.activemq.artemis.tests.util.Wait; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -public class PrimaryToPrimaryFailoverTest extends FailoverTest { +public class PrimaryToPrimaryFailoverTest extends FailoverTestBase { private InVMNodeManager nodeManager0; private InVMNodeManager nodeManager1; @@ -54,6 +53,7 @@ public class PrimaryToPrimaryFailoverTest extends FailoverTest { @Override public void setUp() throws Exception { super.setUp(); + locator = getServerLocator(); } @Override @@ -170,7 +170,6 @@ protected void createClientSessionFactory() throws Exception { } } - @Override protected void createSessionFactory() throws Exception { locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setReconnectAttempts(300).setRetryInterval(100); @@ -196,6 +195,7 @@ private TransportConfiguration getAcceptorTransportConfiguration(boolean primary * TODO: https://issues.apache.org/jira/browse/ARTEMIS-2709 * this test has been intermittently failing since its day one. * Ignoring the test for now until we can fix it. + * * @throws Exception */ @Test @@ -234,7 +234,6 @@ public void scaleDownDelay() throws Exception { } // https://jira.jboss.org/jira/browse/HORNETQ-285 - @Override @Test public void testFailoverOnInitialConnection() throws Exception { locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setReconnectAttempts(300).setRetryInterval(100); @@ -261,7 +260,6 @@ public void testFailoverOnInitialConnection() throws Exception { session.close(); } - @Override @Test public void testCreateNewFactoryAfterFailover() throws Exception { locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true); @@ -287,124 +285,6 @@ public void testCreateNewFactoryAfterFailover() throws Exception { session = sendAndConsume(sf, false); } - - @Override - @Test - public void testTimeoutOnFailoverTransactionCommitTimeoutCommunication() throws Exception { - } - - @Override - @Test - @Disabled - public void testFailBothRestartPrimary() throws Exception { - } - - //invalid tests for primary to primary failover - //all the timeout ones aren't as we don't migrate timeouts, any failback or server restart - //or replicating tests aren't either - @Override - @Test - @Disabled - public void testPrimaryAndBackupBackupComesBackNewFactory() throws Exception { - } - - @Override - @Test - @Disabled - public void testPrimaryAndBackupPrimaryComesBackNewFactory() { - } - - @Override - @Test - @Disabled - public void testTimeoutOnFailoverConsumeBlocked() throws Exception { - } - - @Override - @Test - @Disabled - public void testFailoverMultipleSessionsWithConsumers() throws Exception { - // - } - - @Override - @Test - @Disabled - public void testTimeoutOnFailover() throws Exception { - } - - @Override - @Test - @Disabled - public void testTimeoutOnFailoverTransactionRollback() throws Exception { - } - - @Override - @Test - @Disabled - public void testTimeoutOnFailoverConsume() throws Exception { - } - - @Override - @Test - @Disabled - public void testTimeoutOnFailoverTransactionCommit() throws Exception { - } - - @Override - @Test - @Disabled - public void testFailBack() throws Exception { - } - - @Override - @Test - @Disabled - public void testFailBackPrimaryRestartsBackupIsGone() throws Exception { - } - - @Override - @Test - @Disabled - public void testPrimaryAndBackupPrimaryComesBack() throws Exception { - } - - @Override - @Test - @Disabled - public void testSimpleFailover() throws Exception { - } - - @Override - @Test - @Disabled - public void testFailThenReceiveMoreMessagesAfterFailover2() throws Exception { - } - - @Override - @Test - @Disabled - public void testWithoutUsingTheBackup() throws Exception { - } - - //todo check to see which failing tests are valid, - @Override - @Test - @Disabled - public void testSimpleSendAfterFailoverDurableNonTemporary() throws Exception { - } - - @Override - @Test - @Disabled - public void testCommitOccurredUnblockedAndResendNoDuplicates() throws Exception { - } - - @Override - @Test - @Disabled - public void testFailPrimaryTooSoon() throws Exception { - } } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/ReplicatedManyMultipleServerFailoverNoNodeGroupNameTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/ReplicatedManyMultipleServerFailoverNoNodeGroupNameTest.java index 3df49057f7c..d3d8cdf2d6c 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/ReplicatedManyMultipleServerFailoverNoNodeGroupNameTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/ReplicatedManyMultipleServerFailoverNoNodeGroupNameTest.java @@ -20,7 +20,7 @@ import org.junit.jupiter.api.extension.ExtendWith; @ExtendWith(ParameterizedTestExtension.class) -public class ReplicatedManyMultipleServerFailoverNoNodeGroupNameTest extends ReplicatedManyMultipleServerFailoverTest { +public class ReplicatedManyMultipleServerFailoverNoNodeGroupNameTest extends ReplicatedMultipleServerFailoverTest { @Override public String getNodeGroupName() { diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/ReplicatedManyMultipleServerFailoverTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/ReplicatedManyMultipleServerFailoverTest.java deleted file mode 100644 index a39d4e28cb0..00000000000 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/ReplicatedManyMultipleServerFailoverTest.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.activemq.artemis.tests.integration.cluster.failover; - -import org.apache.activemq.artemis.tests.extensions.parameterized.ParameterizedTestExtension; -import org.junit.jupiter.api.extension.ExtendWith; - -@ExtendWith(ParameterizedTestExtension.class) -public class ReplicatedManyMultipleServerFailoverTest extends ReplicatedMultipleServerFailoverTest { - - @Override - public int getPrimaryServerCount() { - return 6; - } - - @Override - public int getBackupServerCount() { - return 6; - } -} diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/ReplicatedMultipleServerFailoverExtraBackupsTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/ReplicatedMultipleServerFailoverExtraBackupsTest.java index 55d004456c0..f1af803f20f 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/ReplicatedMultipleServerFailoverExtraBackupsTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/ReplicatedMultipleServerFailoverExtraBackupsTest.java @@ -198,4 +198,11 @@ protected void sendCrashBackupReceive() throws Exception { public int getBackupServerCount() { return 4; } + + + @Override + public int getPrimaryServerCount() { + return 2; + } + } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/ReplicatedMultipleServerFailoverTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/ReplicatedMultipleServerFailoverTest.java index 13b34711b02..3c12e65c4bb 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/ReplicatedMultipleServerFailoverTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/ReplicatedMultipleServerFailoverTest.java @@ -144,12 +144,12 @@ protected void sendCrashReceive() throws Exception { @Override public int getPrimaryServerCount() { - return 2; + return 6; } @Override public int getBackupServerCount() { - return 2; + return 6; } @Override diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/ReplicatedPagedFailoverTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/ReplicatedPagedFailoverTest.java index 787d0d05791..35108cd1066 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/ReplicatedPagedFailoverTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/ReplicatedPagedFailoverTest.java @@ -50,12 +50,6 @@ protected ActiveMQServer createInVMFailoverServer(final boolean realFiles, return createInVMFailoverServer(realFiles, configuration, PAGE_SIZE, PAGE_MAX, new HashMap<>(), nodeManager, id); } - @Override - @Test - public void testFailWithBrowser() throws Exception { - internalBrowser(0); - } - @Test public void testFailWithBrowserWithClose() throws Exception { internalBrowser(1); @@ -73,13 +67,6 @@ public void testReplicatedFailback() throws Exception { super.testReplicatedFailback(); } - @Override - @Test - @Timeout(120) - public void testFailoverOnInitialConnection() throws Exception { - super.testFailoverOnInitialConnection(); - } - // // 0 - no tamper // 1 - close files diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/scheduling/DelayedMessageTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/scheduling/DelayedMessageTest.java index 3cf157b8bec..ad719fd4074 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/scheduling/DelayedMessageTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/scheduling/DelayedMessageTest.java @@ -78,8 +78,6 @@ public void testDelayedRedeliveryDefaultOnClose() throws Exception { final int NUM_MESSAGES = 5; - ActiveMQTestBase.forceGC(); - for (int i = 0; i < NUM_MESSAGES; i++) { ClientMessage tm = createDurableMessage(session1, "message" + i); producer.send(tm); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/scheduling/MultipliedDelayedMessageTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/scheduling/MultipliedDelayedMessageTest.java index 7dbdea4e2f7..c027085b7e4 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/scheduling/MultipliedDelayedMessageTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/scheduling/MultipliedDelayedMessageTest.java @@ -86,7 +86,6 @@ public void testMultipliedDelayedRedeliveryOnClose() throws Exception { // Session for sending the message session = sessionFactory.createSession(false, true, true); ClientProducer producer = session.createProducer(queueName); - ActiveMQTestBase.forceGC(); ClientMessage tm = createDurableMessage(session, "message"); producer.send(tm); session.close(); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/scheduling/ScheduledMessageTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/scheduling/ScheduledMessageTest.java index b9e6ad1d83a..d71f5686004 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/scheduling/ScheduledMessageTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/scheduling/ScheduledMessageTest.java @@ -902,8 +902,6 @@ public void testRedeliveryAfterPrepare() throws Exception { private void scheduledDelivery(final boolean tx) throws Exception { - ActiveMQTestBase.forceGC(); - Xid xid = new XidImpl("xa1".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes()); ClientSessionFactory sessionFactory = createSessionFactory(locator); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/spring/SpringIntegrationTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/spring/SpringIntegrationTest.java index dc8b72a3d42..2a8a934c3ca 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/spring/SpringIntegrationTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/spring/SpringIntegrationTest.java @@ -23,7 +23,6 @@ import org.apache.activemq.artemis.core.server.embedded.EmbeddedActiveMQ; import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory; import org.apache.activemq.artemis.tests.util.ActiveMQTestBase; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; @@ -31,15 +30,6 @@ public class SpringIntegrationTest extends ActiveMQTestBase { - @Override - @BeforeEach - public void setUp() throws Exception { - super.setUp(); - // Need to force GC as the connection on the spring needs to be cleared - // otherwise the sprint thread may leak here - forceGC(); - } - @Test public void testSpring() throws Exception { ApplicationContext context = null; diff --git a/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/ActiveMQServerTestCase.java b/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/ActiveMQServerTestCase.java index 123742119f2..0d18815aadf 100644 --- a/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/ActiveMQServerTestCase.java +++ b/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/ActiveMQServerTestCase.java @@ -29,7 +29,6 @@ import javax.jms.TopicConnectionFactory; import javax.jms.XAConnectionFactory; import javax.naming.InitialContext; -import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -73,21 +72,6 @@ public abstract class ActiveMQServerTestCase { private static final int DRAIN_WAIT_TIME = 250; - /** - * Some testcases are time sensitive, and we need to make sure a GC would happen before certain scenarios - */ - public static void forceGC() { - WeakReference dumbReference = new WeakReference<>(new Object()); - // A loop that will wait GC, using the minimal time as possible - while (dumbReference.get() != null) { - System.gc(); - try { - Thread.sleep(500); - } catch (InterruptedException e) { - } - } - } - protected static List servers = new ArrayList<>(); protected static Topic topic1; diff --git a/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/MessageConsumerTest.java b/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/MessageConsumerTest.java index 61062ae0fb6..0e2003893a7 100644 --- a/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/MessageConsumerTest.java +++ b/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/MessageConsumerTest.java @@ -1998,7 +1998,6 @@ public void testTimeoutReceiveOnClose() throws Exception { // This is a really weird test - the received object is always going to be null since no message is sent!! - ActiveMQServerTestCase.forceGC(); // / If A GC need to be executed, it' s better to be executed now logger.trace("testTimeoutReceiveOnClose"); Object monitor = new Object(); diff --git a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/chunk/LargeMessageStressTest.java b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/chunk/LargeMessageStressTest.java deleted file mode 100644 index 81fc7dfdc4c..00000000000 --- a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/chunk/LargeMessageStressTest.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.activemq.artemis.tests.stress.chunk; - -import org.apache.activemq.artemis.core.config.StoreConfiguration; -import org.apache.activemq.artemis.tests.extensions.parameterized.ParameterizedTestExtension; -import org.apache.activemq.artemis.tests.integration.largemessage.LargeMessageTestBase; -import org.junit.jupiter.api.TestTemplate; -import org.junit.jupiter.api.extension.ExtendWith; - -//Parameters set in superclass -@ExtendWith(ParameterizedTestExtension.class) -public class LargeMessageStressTest extends LargeMessageTestBase { - - public LargeMessageStressTest(StoreConfiguration.StoreType storeType) { - super(storeType); - } - - - - @TestTemplate - public void testMessageChunkFilePersistenceOneHugeMessage() throws Exception { - testChunks(false, false, false, true, true, false, false, false, true, 1, 200 * 1024L * 1024L + 1024L, 120000, 0, 10 * 1024 * 1024, 1024 * 1024); - } - -} diff --git a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/paging/PageCursorStressTest.java b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/paging/PageCursorStressTest.java index 9fec0a360db..5d4ef5308cb 100644 --- a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/paging/PageCursorStressTest.java +++ b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/paging/PageCursorStressTest.java @@ -109,8 +109,6 @@ public void testSimpleCursor() throws Exception { assertEquals(1, lookupPageStore(ADDRESS).getNumberOfPages()); - forceGC(); - server.stop(); createServer(); waitCleanup(); @@ -212,10 +210,6 @@ public SimpleString getFilterString() { } assertEquals(NUM_MESSAGES + 1, key); - forceGC(); - - // assertTrue(lookupCursorProvider().getCacheSize() < numberOfPages); - server.stop(); createServer(); waitCleanup(); diff --git a/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/util/UTF8Test.java b/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/util/UTF8Test.java index 6480ca5ae97..58f71b6a42b 100644 --- a/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/util/UTF8Test.java +++ b/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/util/UTF8Test.java @@ -62,7 +62,6 @@ public void testReadUTF() throws Exception { buffer.writeUTF(str); for (int c = 0; c < TIMES; c++) { - forceGC(); final long start = System.currentTimeMillis(); for (long i = 0; i < numberOfIteractions; i++) { buffer.resetReaderIndex();