/*
* Copyright 2004-2015 the Seasar Foundation and the Others.
*
* Licensed 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.seasar.extension.jta;
import javax.transaction.RollbackException;
import javax.transaction.Status;
import javax.transaction.Synchronization;
import javax.transaction.Transaction;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import junit.framework.TestCase;
import org.seasar.extension.jta.xa.DefaultXAResource;
import org.seasar.framework.util.TransactionUtil;
/**
* @author higa
*
*/
public class TransactionImplTest extends TestCase {
private TransactionImpl tx_;
protected void setUp() throws Exception {
tx_ = new TransactionImpl();
}
/**
* @throws Exception
*/
public void testEquals() throws Exception {
assertEquals("1", tx_, tx_);
assertTrue("2", !tx_.equals(null));
assertTrue("3", !tx_.equals(new TransactionImpl()));
assertTrue("4", !tx_.equals("test"));
}
/**
* @throws Exception
*/
public void testBegin() throws Exception {
tx_.begin();
assertEquals("2", Status.STATUS_ACTIVE, tx_.getStatus());
}
/**
* @throws Exception
*/
public void testSuspend() throws Exception {
DefaultXAResource xaRes = new DefaultXAResource();
tx_.begin();
tx_.enlistResource(xaRes);
tx_.suspend();
assertEquals("1", true, tx_.isSuspended());
assertEquals("2", DefaultXAResource.RS_SUSPENDED, xaRes.getStatus());
try {
tx_.suspend();
fail("3");
} catch (IllegalStateException ex) {
System.out.println(ex);
}
tx_.resume();
tx_.commit();
try {
tx_.suspend();
fail("4");
} catch (IllegalStateException ex) {
System.out.println(ex);
}
}
/**
* @throws Exception
*/
public void testSuspend_MarkedRollback() throws Exception {
DefaultXAResource xaRes = new DefaultXAResource();
tx_.begin();
tx_.enlistResource(xaRes);
tx_.setRollbackOnly();
tx_.suspend();
assertEquals("1", true, tx_.isSuspended());
assertEquals("2", DefaultXAResource.RS_SUSPENDED, xaRes.getStatus());
try {
tx_.suspend();
fail("3");
} catch (IllegalStateException ex) {
System.out.println(ex);
}
tx_.resume();
tx_.rollback();
try {
tx_.suspend();
fail("4");
} catch (IllegalStateException ex) {
System.out.println(ex);
}
}
/**
* @throws Exception
*/
public void testResume() throws Exception {
DefaultXAResource xaRes = new DefaultXAResource();
tx_.begin();
tx_.enlistResource(xaRes);
tx_.suspend();
tx_.resume();
assertEquals("1", false, tx_.isSuspended());
assertEquals("2", DefaultXAResource.RS_ACTIVE, xaRes.getStatus());
try {
tx_.resume();
fail("3");
} catch (IllegalStateException ex) {
System.out.println(ex);
}
}
/**
* @throws Exception
*/
public void testOnePhaseCommit() throws Exception {
DefaultXAResource xaRes = new DefaultXAResource();
Sync sync = new Sync(tx_);
tx_.begin();
tx_.enlistResource(xaRes);
tx_.registerSynchronization(sync);
tx_.commit();
assertTrue("1", sync.beforeCompleted_);
assertTrue("2", sync.afterCompleted_);
assertEquals("3", Status.STATUS_COMMITTED, sync.completedStatus_);
assertEquals("4", DefaultXAResource.RS_NONE, xaRes.getStatus());
}
/**
* @throws Exception
*/
public void testTwoPhaseCommit() throws Exception {
DefaultXAResource xaRes = new DefaultXAResource();
DefaultXAResource xaRes2 = new DefaultXAResource();
tx_.begin();
tx_.enlistResource(xaRes);
tx_.enlistResource(xaRes2);
tx_.commit();
assertEquals("1", Status.STATUS_NO_TRANSACTION, tx_.getStatus());
assertEquals("2", DefaultXAResource.RS_NONE, xaRes.getStatus());
assertEquals("3", DefaultXAResource.RS_NONE, xaRes2.getStatus());
}
/**
* @throws Exception
*/
public void testLastResourceCommitOptimization() throws Exception {
final boolean[] onePhaseFlags = new boolean[3];
DefaultXAResource[] xaRes = new DefaultXAResource[3];
for (int i = 0; i < 3; ++i) {
final int index = i;
xaRes[i] = new DefaultXAResource() {
protected void doCommit(Xid xid, boolean onePhase)
throws XAException {
onePhaseFlags[index] = onePhase;
}
};
}
tx_.begin();
for (int i = 0; i < 3; ++i) {
tx_.enlistResource(xaRes[i]);
}
tx_.commit();
assertEquals("1", Status.STATUS_NO_TRANSACTION, tx_.getStatus());
assertTrue("2", onePhaseFlags[0]);
assertFalse("3", onePhaseFlags[1]);
assertFalse("4", onePhaseFlags[2]);
}
/**
* @throws Exception
*/
public void testCommitForException() throws Exception {
DefaultXAResource xaRes = new DefaultXAResource();
tx_.begin();
tx_.enlistResource(xaRes);
tx_.suspend();
try {
tx_.commit();
fail("1");
} catch (IllegalStateException ex) {
System.out.println(ex);
}
tx_.begin();
tx_.commit();
try {
tx_.commit();
fail("2");
} catch (IllegalStateException ex) {
System.out.println(ex);
}
}
/**
* @throws Exception
*/
public void testOnePhaseCommitFail() throws Exception {
DefaultXAResource xaRes = new DefaultXAResource() {
protected int doPrepare(Xid xid) throws XAException {
TransactionImplTest.fail("0");
return XAResource.XA_OK;
}
protected void doCommit(Xid xid, boolean onePhase)
throws XAException {
throw new XAException();
}
};
tx_.begin();
tx_.enlistResource(xaRes);
try {
tx_.commit();
fail("1");
} catch (RollbackException expected) {
System.out.println(expected);
}
}
/**
* @throws Exception
*/
public void testTwoPhaseCommitFail() throws Exception {
final boolean[] result = new boolean[4];
DefaultXAResource xaRes0 = new DefaultXAResource() {
protected int doPrepare(Xid xid) throws XAException {
return XAResource.XA_RDONLY;
}
protected void doCommit(Xid xid, boolean onePhase)
throws XAException {
TransactionImplTest.fail("0");
}
protected void doRollback(Xid xid) throws XAException {
result[0] = true;
}
};
DefaultXAResource xaRes1 = new DefaultXAResource() {
protected int doPrepare(Xid xid) throws XAException {
return XAResource.XA_OK;
}
protected void doCommit(Xid xid, boolean onePhase)
throws XAException {
TransactionImplTest.fail("1");
}
protected void doRollback(Xid xid) throws XAException {
result[1] = true;
}
};
DefaultXAResource xaRes2 = new DefaultXAResource() {
protected int doPrepare(Xid xid) throws XAException {
throw new XAException();
}
protected void doCommit(Xid xid, boolean onePhase)
throws XAException {
TransactionImplTest.fail("2");
}
protected void doRollback(Xid xid) throws XAException {
result[2] = true;
}
};
DefaultXAResource xaRes3 = new DefaultXAResource() {
protected int doPrepare(Xid xid) throws XAException {
TransactionImplTest.fail("3");
return XAResource.XA_OK;
}
protected void doCommit(Xid xid, boolean onePhase)
throws XAException {
TransactionImplTest.fail("4");
}
protected void doRollback(Xid xid) throws XAException {
result[3] = true;
}
};
tx_.begin();
tx_.enlistResource(xaRes3);
tx_.enlistResource(xaRes2);
tx_.enlistResource(xaRes1);
tx_.enlistResource(xaRes0);
try {
tx_.commit();
fail("5");
} catch (RollbackException ex) {
System.out.println(ex);
}
assertFalse("6", result[0]);
assertTrue("7", result[1]);
assertFalse("8", result[2]);
assertTrue("9", result[3]);
}
/**
* @throws Exception
*/
public void testRollback() throws Exception {
DefaultXAResource xaRes = new DefaultXAResource();
Sync sync = new Sync(tx_);
tx_.begin();
tx_.enlistResource(xaRes);
tx_.registerSynchronization(sync);
tx_.rollback();
assertFalse("1", sync.beforeCompleted_);
assertTrue("2", sync.afterCompleted_);
assertEquals("3", Status.STATUS_ROLLEDBACK, sync.completedStatus_);
assertEquals("4", DefaultXAResource.RS_NONE, xaRes.getStatus());
}
/**
* @throws Exception
*/
public void testRollbackForException() throws Exception {
DefaultXAResource xaRes = new DefaultXAResource();
tx_.begin();
tx_.enlistResource(xaRes);
tx_.suspend();
try {
tx_.rollback();
fail("1");
} catch (IllegalStateException ex) {
System.out.println(ex);
}
tx_.begin();
tx_.rollback();
try {
tx_.rollback();
fail("2");
} catch (IllegalStateException ex) {
System.out.println(ex);
}
}
/**
* @throws Exception
*/
public void testSetRollbackOnly() throws Exception {
tx_.begin();
tx_.setRollbackOnly();
assertEquals("1", Status.STATUS_MARKED_ROLLBACK, tx_.getStatus());
}
/**
* @throws Exception
*/
public void testSetRollbackOnlyForException() throws Exception {
tx_.begin();
tx_.commit();
try {
tx_.setRollbackOnly();
fail("1");
} catch (IllegalStateException ex) {
System.out.println(ex);
}
}
/**
* @throws Exception
*/
public void testDelistResource() throws Exception {
DefaultXAResource xaRes = new DefaultXAResource();
tx_.begin();
tx_.enlistResource(xaRes);
tx_.delistResource(xaRes, XAResource.TMSUCCESS);
assertEquals("1", DefaultXAResource.RS_SUCCESS, xaRes.getStatus());
}
/**
* @throws Exception
*/
public void testDelistResourceForException() throws Exception {
tx_.begin();
DefaultXAResource xaRes = new DefaultXAResource();
try {
tx_.delistResource(xaRes, XAResource.TMSUCCESS);
} catch (IllegalStateException ex) {
System.out.println(ex);
}
tx_.suspend();
tx_.resume();
tx_.commit();
try {
tx_.delistResource(xaRes, XAResource.TMSUCCESS);
} catch (IllegalStateException ex) {
System.out.println(ex);
}
}
/**
* @throws Exception
*/
public void testBeforeCompletion() throws Exception {
tx_.begin();
Sync sync = new Sync(tx_);
tx_.registerSynchronization(sync);
tx_.registerSynchronization(new ExceptionSync());
try {
tx_.commit();
fail("1");
} catch (RollbackException ex) {
System.out.println(ex);
}
assertTrue(sync.beforeCompleted_);
assertTrue(sync.afterCompleted_);
}
private class Sync implements Synchronization {
private boolean beforeCompleted_ = false;
private boolean afterCompleted_ = false;
private int completedStatus_ = Status.STATUS_UNKNOWN;
private Transaction tx_;
/**
* @param tx
*/
public Sync(Transaction tx) {
tx_ = tx;
}
public void beforeCompletion() {
beforeCompleted_ = true;
}
public void afterCompletion(int status) {
assertEquals(Status.STATUS_NO_TRANSACTION, TransactionUtil
.getStatus(tx_));
afterCompleted_ = true;
completedStatus_ = status;
}
}
private class ExceptionSync implements Synchronization {
public void beforeCompletion() {
throw new RuntimeException("hoge");
}
public void afterCompletion(int status) {
}
}
}