ARTEMIS-3707 fixing tests

A handful of tests started to fail after the original fix was committed.
This commit fixes those failures mainly by using a mock
`TransactionSynchronizationRegistry`.

I changed `o.a.a.a.r.ActiveMQRAManagedConnection#checkTransactionActive`
slightly because `getTransactionStatus` will never return `null` unlike
`getTransaction` would. The semantics should still be the same, though.
This commit is contained in:
Justin Bertram 2022-12-20 13:18:12 -06:00
parent b3bd3a0f22
commit bf1d81e09e
7 changed files with 121 additions and 47 deletions

View File

@ -16,18 +16,6 @@
*/ */
package org.apache.activemq.artemis.ra; package org.apache.activemq.artemis.ra;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantLock;
import javax.jms.ExceptionListener; import javax.jms.ExceptionListener;
import javax.jms.JMSException; import javax.jms.JMSException;
import javax.jms.ResourceAllocationException; import javax.jms.ResourceAllocationException;
@ -46,6 +34,18 @@ import javax.security.auth.Subject;
import javax.transaction.Status; import javax.transaction.Status;
import javax.transaction.TransactionSynchronizationRegistry; import javax.transaction.TransactionSynchronizationRegistry;
import javax.transaction.xa.XAResource; import javax.transaction.xa.XAResource;
import java.io.PrintWriter;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.activemq.artemis.core.client.impl.ClientSessionInternal; import org.apache.activemq.artemis.core.client.impl.ClientSessionInternal;
import org.apache.activemq.artemis.jms.client.ActiveMQConnection; import org.apache.activemq.artemis.jms.client.ActiveMQConnection;
@ -56,7 +56,6 @@ import org.apache.activemq.artemis.service.extensions.xa.ActiveMQXAResourceWrapp
import org.apache.activemq.artemis.utils.VersionLoader; import org.apache.activemq.artemis.utils.VersionLoader;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.lang.invoke.MethodHandles;
/** /**
* The managed connection * The managed connection
@ -340,8 +339,18 @@ public final class ActiveMQRAManagedConnection implements ManagedConnection, Exc
if (!inManagedTx && tsr != null) { if (!inManagedTx && tsr != null) {
int status = tsr.getTransactionStatus(); int status = tsr.getTransactionStatus();
// Only allow states that will actually succeed // Only allow states that will actually succeed
if (status != Status.STATUS_ACTIVE && status != Status.STATUS_PREPARING && status != Status.STATUS_PREPARED && status != Status.STATUS_COMMITTING) { if (status == Status.STATUS_COMMITTED || status == Status.STATUS_MARKED_ROLLBACK || status == Status.STATUS_ROLLEDBACK || status == Status.STATUS_ROLLING_BACK) {
throw new javax.jms.IllegalStateException("Transaction " + tsr.getTransactionKey() + " not active"); String statusMessage = "";
if (status == Status.STATUS_COMMITTED) {
statusMessage = "committed";
} else if (status == Status.STATUS_MARKED_ROLLBACK) {
statusMessage = "marked for rollback";
} else if (status == Status.STATUS_ROLLEDBACK) {
statusMessage = "rolled back";
} else if (status == Status.STATUS_ROLLING_BACK) {
statusMessage = "rolling back";
}
throw new javax.jms.IllegalStateException("Transaction is " + statusMessage);
} }
} }
} }

View File

@ -19,6 +19,8 @@ package org.apache.activemq.artemis.tests.integration.ra;
import javax.jms.Message; import javax.jms.Message;
import javax.resource.ResourceException; import javax.resource.ResourceException;
import javax.resource.spi.ApplicationServerInternalException; import javax.resource.spi.ApplicationServerInternalException;
import javax.transaction.Status;
import javax.transaction.TransactionSynchronizationRegistry;
import javax.transaction.xa.XAException; import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource; import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid; import javax.transaction.xa.Xid;
@ -79,7 +81,8 @@ public class ActiveMQMessageHandlerXATest extends ActiveMQRATestBase {
@Test @Test
public void testXABeginFails() throws Exception { public void testXABeginFails() throws Exception {
ActiveMQResourceAdapter qResourceAdapter = newResourceAdapter(); ActiveMQResourceAdapter qResourceAdapter = newResourceAdapter();
MyBootstrapContext ctx = new MyBootstrapContext(); TransactionSynchronizationRegistry tsr = new DummyTransactionSynchronizationRegistry().setStatus(Status.STATUS_ACTIVE);
MyBootstrapContext ctx = new MyBootstrapContext().setTransactionSynchronizationRegistry(tsr);
qResourceAdapter.start(ctx); qResourceAdapter.start(ctx);
ActiveMQActivationSpec spec = new ActiveMQActivationSpec(); ActiveMQActivationSpec spec = new ActiveMQActivationSpec();
spec.setResourceAdapter(qResourceAdapter); spec.setResourceAdapter(qResourceAdapter);
@ -99,8 +102,7 @@ public class ActiveMQMessageHandlerXATest extends ActiveMQRATestBase {
session.close(); session.close();
latch.await(5, TimeUnit.SECONDS); latch.await(5, TimeUnit.SECONDS);
DummyTransaction transaction = (DummyTransaction) ServiceUtils.getTransactionManager().getTransaction(); assertTrue(tsr.getRollbackOnly());
assertTrue(transaction.rollbackOnly);
assertTrue(endpoint.afterDelivery); assertTrue(endpoint.afterDelivery);
qResourceAdapter.endpointDeactivation(endpointFactory, spec); qResourceAdapter.endpointDeactivation(endpointFactory, spec);
qResourceAdapter.stop(); qResourceAdapter.stop();

View File

@ -173,6 +173,12 @@ public abstract class ActiveMQRATestBase extends JMSTestBase {
} }
public class MyBootstrapContext implements BootstrapContext { public class MyBootstrapContext implements BootstrapContext {
TransactionSynchronizationRegistry tsr = null;
public MyBootstrapContext setTransactionSynchronizationRegistry(TransactionSynchronizationRegistry tsr) {
this.tsr = tsr;
return this;
}
WorkManager workManager = new DummyWorkManager(); WorkManager workManager = new DummyWorkManager();
@ -188,7 +194,7 @@ public abstract class ActiveMQRATestBase extends JMSTestBase {
@Override @Override
public TransactionSynchronizationRegistry getTransactionSynchronizationRegistry() { public TransactionSynchronizationRegistry getTransactionSynchronizationRegistry() {
return null; return tsr;
} }
@Override @Override

View File

@ -0,0 +1,66 @@
/*
* 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.ra;
import javax.transaction.Status;
import javax.transaction.Synchronization;
import javax.transaction.TransactionSynchronizationRegistry;
public class DummyTransactionSynchronizationRegistry implements TransactionSynchronizationRegistry {
private int status = Status.STATUS_NO_TRANSACTION;
private boolean rollbackOnly = false;
public DummyTransactionSynchronizationRegistry setStatus(int status) {
this.status = status;
return this;
}
@Override
public Object getTransactionKey() {
return null;
}
@Override
public void putResource(Object key, Object value) {
}
@Override
public Object getResource(Object key) {
return null;
}
@Override
public void registerInterposedSynchronization(Synchronization sync) {
}
@Override
public int getTransactionStatus() {
return status;
}
@Override
public void setRollbackOnly() {
rollbackOnly = true;
}
@Override
public boolean getRollbackOnly() {
return rollbackOnly;
}
}

View File

@ -37,6 +37,7 @@ import javax.jms.Queue;
import javax.jms.QueueConnection; import javax.jms.QueueConnection;
import javax.jms.Session; import javax.jms.Session;
import javax.jms.TextMessage; import javax.jms.TextMessage;
import javax.transaction.Status;
public class IgnoreJTATest extends ActiveMQRATestBase { public class IgnoreJTATest extends ActiveMQRATestBase {
@ -90,13 +91,12 @@ public class IgnoreJTATest extends ActiveMQRATestBase {
} }
private void testSendAndReceive(Boolean ignoreJTA) throws Exception { private void testSendAndReceive(Boolean ignoreJTA) throws Exception {
setDummyTX();
setupDLQ(10); setupDLQ(10);
resourceAdapter = newResourceAdapter(); resourceAdapter = newResourceAdapter();
if (ignoreJTA != null) { if (ignoreJTA != null) {
resourceAdapter.setIgnoreJTA(ignoreJTA); resourceAdapter.setIgnoreJTA(ignoreJTA);
} }
MyBootstrapContext ctx = new MyBootstrapContext(); MyBootstrapContext ctx = new MyBootstrapContext().setTransactionSynchronizationRegistry(new DummyTransactionSynchronizationRegistry().setStatus(Status.STATUS_ACTIVE));
resourceAdapter.start(ctx); resourceAdapter.start(ctx);
ActiveMQRAManagedConnectionFactory mcf = new ActiveMQRAManagedConnectionFactory(); ActiveMQRAManagedConnectionFactory mcf = new ActiveMQRAManagedConnectionFactory();
mcf.setResourceAdapter(resourceAdapter); mcf.setResourceAdapter(resourceAdapter);

View File

@ -23,7 +23,8 @@ import javax.jms.JMSRuntimeException;
import javax.jms.MessageFormatRuntimeException; import javax.jms.MessageFormatRuntimeException;
import javax.jms.Queue; import javax.jms.Queue;
import javax.jms.TextMessage; import javax.jms.TextMessage;
import javax.transaction.TransactionManager; import javax.resource.ResourceException;
import javax.transaction.Status;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -34,7 +35,6 @@ import org.apache.activemq.artemis.ra.ActiveMQRAConnectionFactoryImpl;
import org.apache.activemq.artemis.ra.ActiveMQRAConnectionManager; import org.apache.activemq.artemis.ra.ActiveMQRAConnectionManager;
import org.apache.activemq.artemis.ra.ActiveMQRAManagedConnectionFactory; import org.apache.activemq.artemis.ra.ActiveMQRAManagedConnectionFactory;
import org.apache.activemq.artemis.ra.ActiveMQResourceAdapter; import org.apache.activemq.artemis.ra.ActiveMQResourceAdapter;
import org.apache.activemq.artemis.service.extensions.ServiceUtils;
import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager; import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
@ -43,18 +43,13 @@ import org.junit.Test;
public class JMSContextTest extends ActiveMQRATestBase { public class JMSContextTest extends ActiveMQRATestBase {
private ActiveMQResourceAdapter resourceAdapter; private ActiveMQResourceAdapter resourceAdapter;
private DummyTransactionSynchronizationRegistry tsr;
ActiveMQRAConnectionManager qraConnectionManager = new ActiveMQRAConnectionManager(); ActiveMQRAConnectionManager qraConnectionManager = new ActiveMQRAConnectionManager();
private ActiveMQRAConnectionFactory qraConnectionFactory; private ActiveMQRAConnectionFactory qraConnectionFactory;
public TransactionManager getTm() {
return DummyTransactionManager.tm;
}
@Override @Override
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
useDummyTransactionManager();
super.setUp(); super.setUp();
ActiveMQJAASSecurityManager securityManager = (ActiveMQJAASSecurityManager) server.getSecurityManager(); ActiveMQJAASSecurityManager securityManager = (ActiveMQJAASSecurityManager) server.getSecurityManager();
securityManager.getConfiguration().addUser("testuser", "testpassword"); securityManager.getConfiguration().addUser("testuser", "testpassword");
@ -67,19 +62,21 @@ public class JMSContextTest extends ActiveMQRATestBase {
roles.add(role); roles.add(role);
server.getSecurityRepository().addMatch(MDBQUEUEPREFIXED, roles); server.getSecurityRepository().addMatch(MDBQUEUEPREFIXED, roles);
resourceAdapter = new ActiveMQResourceAdapter(); resourceAdapter = new ActiveMQResourceAdapter();
resourceAdapter.setConnectorClassName(InVMConnectorFactory.class.getName()); resourceAdapter.setConnectorClassName(InVMConnectorFactory.class.getName());
MyBootstrapContext ctx = new MyBootstrapContext(); tsr = new DummyTransactionSynchronizationRegistry();
MyBootstrapContext ctx = new MyBootstrapContext().setTransactionSynchronizationRegistry(tsr);
resourceAdapter.start(ctx); resourceAdapter.start(ctx);
ActiveMQRAManagedConnectionFactory mcf = new ActiveMQRAManagedConnectionFactory(); ActiveMQRAManagedConnectionFactory mcf = new ActiveMQRAManagedConnectionFactory();
mcf.setResourceAdapter(resourceAdapter); mcf.setResourceAdapter(resourceAdapter);
qraConnectionFactory = new ActiveMQRAConnectionFactoryImpl(mcf, qraConnectionManager); qraConnectionFactory = new ActiveMQRAConnectionFactoryImpl(mcf, qraConnectionManager);
} }
private void initRA(int status) throws ResourceException {
}
@Override @Override
@After @After
public void tearDown() throws Exception { public void tearDown() throws Exception {
DummyTransactionManager.tm.tx = null;
if (resourceAdapter != null) { if (resourceAdapter != null) {
resourceAdapter.stop(); resourceAdapter.stop();
} }
@ -126,7 +123,7 @@ public class JMSContextTest extends ActiveMQRATestBase {
@Test @Test
public void sessionTransactedTestNoActiveJTATx() throws Exception { public void sessionTransactedTestNoActiveJTATx() throws Exception {
((DummyTransactionManager) ServiceUtils.getTransactionManager()).tx = new DummyTransaction(); tsr.setStatus(Status.STATUS_ACTIVE);
JMSContext context = qraConnectionFactory.createContext(JMSContext.SESSION_TRANSACTED); JMSContext context = qraConnectionFactory.createContext(JMSContext.SESSION_TRANSACTED);
assertEquals(context.getSessionMode(), JMSContext.AUTO_ACKNOWLEDGE); assertEquals(context.getSessionMode(), JMSContext.AUTO_ACKNOWLEDGE);
} }
@ -143,7 +140,7 @@ public class JMSContextTest extends ActiveMQRATestBase {
@Test @Test
public void clientAckTestNoActiveJTATx() throws Exception { public void clientAckTestNoActiveJTATx() throws Exception {
((DummyTransactionManager) ServiceUtils.getTransactionManager()).tx = new DummyTransaction(); tsr.setStatus(Status.STATUS_ACTIVE);
JMSContext context = qraConnectionFactory.createContext(JMSContext.CLIENT_ACKNOWLEDGE); JMSContext context = qraConnectionFactory.createContext(JMSContext.CLIENT_ACKNOWLEDGE);
assertEquals(context.getSessionMode(), JMSContext.AUTO_ACKNOWLEDGE); assertEquals(context.getSessionMode(), JMSContext.AUTO_ACKNOWLEDGE);
} }

View File

@ -28,6 +28,7 @@ import javax.jms.Queue;
import javax.jms.QueueConnection; import javax.jms.QueueConnection;
import javax.jms.Session; import javax.jms.Session;
import javax.jms.TextMessage; import javax.jms.TextMessage;
import javax.transaction.Status;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -43,7 +44,6 @@ import org.apache.activemq.artemis.ra.ActiveMQRAConnectionFactoryImpl;
import org.apache.activemq.artemis.ra.ActiveMQRAConnectionManager; import org.apache.activemq.artemis.ra.ActiveMQRAConnectionManager;
import org.apache.activemq.artemis.ra.ActiveMQRAManagedConnectionFactory; import org.apache.activemq.artemis.ra.ActiveMQRAManagedConnectionFactory;
import org.apache.activemq.artemis.ra.ActiveMQResourceAdapter; import org.apache.activemq.artemis.ra.ActiveMQResourceAdapter;
import org.apache.activemq.artemis.service.extensions.ServiceUtils;
import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager; import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
@ -54,6 +54,7 @@ public class OutgoingConnectionJTATest extends ActiveMQRATestBase {
protected ActiveMQResourceAdapter resourceAdapter; protected ActiveMQResourceAdapter resourceAdapter;
protected ActiveMQRAConnectionFactory qraConnectionFactory; protected ActiveMQRAConnectionFactory qraConnectionFactory;
protected ActiveMQRAManagedConnectionFactory mcf; protected ActiveMQRAManagedConnectionFactory mcf;
private DummyTransactionSynchronizationRegistry tsr;
ActiveMQRAConnectionManager qraConnectionManager = new ActiveMQRAConnectionManager(); ActiveMQRAConnectionManager qraConnectionManager = new ActiveMQRAConnectionManager();
@Override @Override
@ -64,7 +65,6 @@ public class OutgoingConnectionJTATest extends ActiveMQRATestBase {
@Override @Override
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
useDummyTransactionManager();
super.setUp(); super.setUp();
((ActiveMQJAASSecurityManager) server.getSecurityManager()).getConfiguration().addUser("testuser", "testpassword"); ((ActiveMQJAASSecurityManager) server.getSecurityManager()).getConfiguration().addUser("testuser", "testpassword");
((ActiveMQJAASSecurityManager) server.getSecurityManager()).getConfiguration().addUser("guest", "guest"); ((ActiveMQJAASSecurityManager) server.getSecurityManager()).getConfiguration().addUser("guest", "guest");
@ -75,12 +75,11 @@ public class OutgoingConnectionJTATest extends ActiveMQRATestBase {
Set<Role> roles = new HashSet<>(); Set<Role> roles = new HashSet<>();
roles.add(role); roles.add(role);
server.getSecurityRepository().addMatch(MDBQUEUEPREFIXED, roles); server.getSecurityRepository().addMatch(MDBQUEUEPREFIXED, roles);
resourceAdapter = new ActiveMQResourceAdapter(); resourceAdapter = new ActiveMQResourceAdapter();
resourceAdapter.setEntries("[\"java://jmsXA\"]"); resourceAdapter.setEntries("[\"java://jmsXA\"]");
resourceAdapter.setConnectorClassName(InVMConnectorFactory.class.getName()); resourceAdapter.setConnectorClassName(InVMConnectorFactory.class.getName());
MyBootstrapContext ctx = new MyBootstrapContext(); tsr = new DummyTransactionSynchronizationRegistry();
MyBootstrapContext ctx = new MyBootstrapContext().setTransactionSynchronizationRegistry(tsr);
resourceAdapter.start(ctx); resourceAdapter.start(ctx);
mcf = new ActiveMQRAManagedConnectionFactory(); mcf = new ActiveMQRAManagedConnectionFactory();
mcf.setResourceAdapter(resourceAdapter); mcf.setResourceAdapter(resourceAdapter);
@ -90,7 +89,6 @@ public class OutgoingConnectionJTATest extends ActiveMQRATestBase {
@Override @Override
@After @After
public void tearDown() throws Exception { public void tearDown() throws Exception {
((DummyTransactionManager) ServiceUtils.getTransactionManager()).tx = null;
if (resourceAdapter != null) { if (resourceAdapter != null) {
resourceAdapter.stop(); resourceAdapter.stop();
} }
@ -101,10 +99,10 @@ public class OutgoingConnectionJTATest extends ActiveMQRATestBase {
@Test @Test
public void testSimpleMessageSendAndReceiveTransacted() throws Exception { public void testSimpleMessageSendAndReceiveTransacted() throws Exception {
setDummyTX(); tsr.setStatus(Status.STATUS_ACTIVE);
setupDLQ(10); setupDLQ(10);
resourceAdapter = newResourceAdapter(); resourceAdapter = newResourceAdapter();
MyBootstrapContext ctx = new MyBootstrapContext(); MyBootstrapContext ctx = new MyBootstrapContext().setTransactionSynchronizationRegistry(tsr);
resourceAdapter.start(ctx); resourceAdapter.start(ctx);
ActiveMQRAManagedConnectionFactory mcf = new ActiveMQRAManagedConnectionFactory(); ActiveMQRAManagedConnectionFactory mcf = new ActiveMQRAManagedConnectionFactory();
mcf.setResourceAdapter(resourceAdapter); mcf.setResourceAdapter(resourceAdapter);
@ -130,7 +128,7 @@ public class OutgoingConnectionJTATest extends ActiveMQRATestBase {
public void testQueuSessionAckMode(boolean inTx) throws Exception { public void testQueuSessionAckMode(boolean inTx) throws Exception {
if (inTx) { if (inTx) {
setDummyTX(); tsr.setStatus(Status.STATUS_ACTIVE);
} }
QueueConnection queueConnection = qraConnectionFactory.createQueueConnection(); QueueConnection queueConnection = qraConnectionFactory.createQueueConnection();
@ -249,8 +247,4 @@ public class OutgoingConnectionJTATest extends ActiveMQRATestBase {
assertEquals("hello", msg.getStringProperty("strvalue")); assertEquals("hello", msg.getStringProperty("strvalue"));
} }
} }
private void setDummyTX() {
((DummyTransactionManager) ServiceUtils.getTransactionManager()).tx = new DummyTransaction();
}
} }