blob: 117ba23720d92710808856addc4af5ae56d52642 [file] [log] [blame]
/*
*
* 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.qpid.test.unit.xa;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.XAQueueConnection;
import javax.jms.XAQueueConnectionFactory;
import javax.jms.XAQueueSession;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FaultTest extends AbstractXATestCase
{
private static final Logger _logger = LoggerFactory.getLogger(FaultTest.class);
/**
* the queue use by all the tests
*/
private static Queue _queue = null;
/**
* the queue connection factory used by all tests
*/
private static XAQueueConnectionFactory _queueFactory = null;
/**
* standard xa queue connection
*/
private static XAQueueConnection _xaqueueConnection = null;
/**
* standard xa queue connection
*/
private static QueueConnection _queueConnection = null;
/**
* standard queue session created from the standard connection
*/
private static QueueSession _nonXASession = null;
/** ----------------------------------------------------------------------------------- **/
/**
* ----------------------------- JUnit support ----------------------------------------- *
*/
@Override
public void tearDown() throws Exception
{
try
{
if (_xaqueueConnection != null)
{
_xaqueueConnection.close();
}
if (_queueConnection != null)
{
_queueConnection.close();
}
}
finally
{
super.tearDown();
}
}
/**
* Initialize standard actors
*/
public void init() throws Exception
{
if (isBroker010())
{
_queueFactory = (XAQueueConnectionFactory) getConnectionFactory();
_xaqueueConnection = _queueFactory.createXAQueueConnection(GUEST_USERNAME, GUEST_PASSWORD);
XAQueueSession session = _xaqueueConnection.createXAQueueSession();
_queue = session.createQueue(getTestQueueName());
_queueConnection = _queueFactory.createQueueConnection(GUEST_USERNAME, GUEST_PASSWORD);
_nonXASession = _queueConnection.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
init(session, _queue);
}
}
/** -------------------------------------------------------------------------------------- **/
/** ----------------------------- Test Suite -------------------------------------------- **/
/** -------------------------------------------------------------------------------------- **/
/**
* Strategy:
* Invoke start twice with the same xid on an XA resource.
* Check that the second
* invocation is throwing the expected XA exception.
*/
public void testSameXID() throws Exception
{
Xid xid = getNewXid();
_xaResource.start(xid, XAResource.TMNOFLAGS);
// we now exepct this operation to fail
try
{
_xaResource.start(xid, XAResource.TMNOFLAGS);
fail("We managed to start a transaction with the same xid");
}
catch (XAException e)
{
assertEquals("Wrong error code: ", XAException.XAER_DUPID, e.errorCode);
}
}
/**
* Strategy:
* Invoke start on a XA resource with flag other than TMNOFLAGS, TMJOIN, or TMRESUME.
* Check that a XA Exception is thrown.
*/
public void testWrongStartFlag()
{
Xid xid = getNewXid();
try
{
_xaResource.start(xid, XAResource.TMONEPHASE);
fail("We managed to start a transaction with a wrong flag");
}
catch (XAException e)
{
assertEquals("Wrong error code: ", XAException.XAER_INVAL, e.errorCode);
}
}
/**
* Strategy:
* Check that a XA exception is thrown when:
* A non started xid is ended
*/
public void testEnd()
{
Xid xid = getNewXid();
try
{
_xaResource.end(xid, XAResource.TMSUCCESS);
fail("We managed to end a transaction before it is started");
}
catch (XAException e)
{
assertEquals("Wrong error code: ", XAException.XAER_PROTO, e.errorCode);
}
}
/**
* Strategy:
* Check that a XA exception is thrown when:
* Call forget on an unknown xid
* call forget on a started xid
* A non started xid is prepared
* A non ended xis is prepared
*/
public void testForget()
{
Xid xid = getNewXid();
try
{
_xaResource.forget(xid);
fail("We managed to forget an unknown xid");
}
catch (XAException e)
{
// assertEquals("Wrong error code: ", XAException.XAER_NOTA, e.errorCode);
}
xid = getNewXid();
try
{
_xaResource.start(xid, XAResource.TMNOFLAGS);
_xaResource.forget(xid);
fail("We managed to forget a started xid");
}
catch (XAException e)
{
assertEquals("Wrong error code: ", XAException.XAER_PROTO, e.errorCode);
}
}
/**
* Strategy:
* Check that a XA exception is thrown when:
* A non started xid is prepared
* A non ended xid is prepared
*/
public void testPrepare()
{
Xid xid = getNewXid();
try
{
_xaResource.prepare(xid);
fail("We managed to prepare an unknown xid");
}
catch (XAException e)
{
assertEquals("Wrong error code: ", XAException.XAER_NOTA, e.errorCode);
}
xid = getNewXid();
try
{
_xaResource.start(xid, XAResource.TMNOFLAGS);
_xaResource.prepare(xid);
fail("We managed to prepare a started xid");
}
catch (XAException e)
{
assertEquals("Wrong error code: ", XAException.XAER_PROTO, e.errorCode);
}
}
/**
* Strategy:
* Check that the expected XA exception is thrown when:
* A non started xid is committed
* A non ended xid is committed
* A non prepared xid is committed with one phase set to false.
* A prepared xid is committed with one phase set to true.
*/
public void testCommit() throws Exception
{
Xid xid = getNewXid();
try
{
_xaResource.commit(xid, true);
fail("We managed to commit an unknown xid");
}
catch (XAException e)
{
assertEquals("Wrong error code: ", XAException.XAER_NOTA, e.errorCode);
}
xid = getNewXid();
try
{
_xaResource.start(xid, XAResource.TMNOFLAGS);
_xaResource.commit(xid, true);
fail("We managed to commit a not ended xid");
}
catch (XAException e)
{
assertEquals("Wrong error code: ", XAException.XAER_PROTO, e.errorCode);
}
xid = getNewXid();
try
{
_xaResource.start(xid, XAResource.TMNOFLAGS);
_xaResource.end(xid, XAResource.TMSUCCESS);
_xaResource.commit(xid, false);
fail("We managed to commit a not prepared xid");
}
catch (XAException e)
{
assertEquals("Wrong error code: ", XAException.XAER_PROTO, e.errorCode);
}
xid = getNewXid();
try
{
_xaResource.start(xid, XAResource.TMNOFLAGS);
_xaResource.end(xid, XAResource.TMSUCCESS);
_xaResource.prepare(xid);
_xaResource.commit(xid, true);
fail("We managed to commit a prepared xid");
}
catch (XAException e)
{
assertEquals("Wrong error code: ", XAException.XAER_PROTO, e.errorCode);
}
finally
{
_xaResource.commit(xid, false);
}
}
/**
* Strategy:
* Check that the expected XA exception is thrown when:
* A non started xid is rolled back
* A non ended xid is rolled back
*/
public void testRollback()
{
Xid xid = getNewXid();
try
{
_xaResource.rollback(xid);
fail("We managed to rollback an unknown xid");
}
catch (XAException e)
{
assertEquals("Wrong error code: ", XAException.XAER_NOTA, e.errorCode);
}
xid = getNewXid();
try
{
_xaResource.start(xid, XAResource.TMNOFLAGS);
_xaResource.rollback(xid);
fail("We managed to rollback a not ended xid");
}
catch (XAException e)
{
assertEquals("Wrong error code: ", XAException.XAER_PROTO, e.errorCode);
}
}
/**
* Strategy:
* Check that the timeout is set correctly
*/
public void testTransactionTimeoutvalue() throws Exception
{
Xid xid = getNewXid();
_xaResource.start(xid, XAResource.TMNOFLAGS);
assertEquals("Wrong timeout", _xaResource.getTransactionTimeout(), 0);
_xaResource.setTransactionTimeout(1000);
assertEquals("Wrong timeout", _xaResource.getTransactionTimeout(), 1000);
_xaResource.end(xid, XAResource.TMSUCCESS);
xid = getNewXid();
_xaResource.start(xid, XAResource.TMNOFLAGS);
assertEquals("Wrong timeout", _xaResource.getTransactionTimeout(), 1000);
}
/**
* Strategy:
* Check that a transaction timeout as expected
* - set timeout to 1s
* - sleep 1500ms
* - call end and check that the expected exception is thrown
*/
public void testTransactionTimeout() throws Exception
{
_xaResource.setTransactionTimeout(1);
Xid xid = getNewXid();
try
{
_xaResource.start(xid, XAResource.TMNOFLAGS);
Thread.sleep(1500);
_xaResource.end(xid, XAResource.TMSUCCESS);
fail("Timeout expected ");
}
catch (XAException e)
{
assertEquals("Wrong error code: ", XAException.XA_RBTIMEOUT, e.errorCode);
}
}
/**
* Strategy:
* Set the transaction timeout to 1000
*/
public void testTransactionTimeoutAfterCommit() throws Exception
{
Xid xid = getNewXid();
_xaResource.start(xid, XAResource.TMNOFLAGS);
_xaResource.setTransactionTimeout(1000);
assertEquals("Wrong timeout", 1000,_xaResource.getTransactionTimeout());
//_xaResource.prepare(xid);
_xaResource.end(xid, XAResource.TMSUCCESS);
_xaResource.commit(xid, true);
_xaResource.setTransactionTimeout(2000);
assertEquals("Wrong timeout", 2000,_xaResource.getTransactionTimeout());
xid = getNewXid();
_xaResource.start(xid, XAResource.TMNOFLAGS);
assertEquals("Wrong timeout", 2000, _xaResource.getTransactionTimeout());
}
}