Clover coverage report -
Coverage timestamp: Thu Jul 5 2007 20:02:32 EDT
file stats: LOC: 235   Methods: 15
NCLOC: 172   Classes: 3
 
 Source file Conditionals Statements Methods TOTAL
AbortionTest.java 87.5% 98.8% 100% 98.1%
coverage coverage
 1    /*
 2    * JBoss, Home of Professional Open Source
 3    *
 4    * Distributable under LGPL license.
 5    * See terms of license at gnu.org.
 6    */
 7    package org.jboss.cache.transaction;
 8   
 9    import junit.framework.TestCase;
 10    import org.jboss.cache.CacheException;
 11    import org.jboss.cache.CacheImpl;
 12    import org.jboss.cache.interceptors.OrderedSynchronizationHandler;
 13    import org.jboss.cache.misc.TestingUtil;
 14    import org.jboss.cache.transaction.NotifyingTransactionManager.Notification;
 15    import org.jgroups.Channel;
 16    import org.jgroups.JChannel;
 17   
 18    import javax.transaction.RollbackException;
 19    import javax.transaction.Synchronization;
 20    import javax.transaction.SystemException;
 21    import javax.transaction.Transaction;
 22    import javax.transaction.TransactionManager;
 23   
 24    /**
 25    * @author <a href="mailto:manik@jboss.org">Manik Surtani (manik@jboss.org)</a>
 26    */
 27    public class AbortionTest extends TestCase
 28    {
 29    private MyTC cache1, cache2, cache3;
 30   
 31  3 protected void setUp() throws Exception
 32    {
 33  3 super.setUp();
 34  3 System.out.println("********* START: SET UP *************");
 35  3 cache1 = initCache(false);
 36  3 TestingUtil.sleepThread(1500); // to ensure cache1 is the coordinator
 37  3 cache2 = initCache(false);
 38  3 cache3 = initCache(true);
 39  3 System.out.println("********* END: SET UP *************");
 40    }
 41   
 42   
 43  3 protected void tearDown() throws Exception
 44    {
 45  3 System.out.println("********* START: TEAR DOWN *************");
 46  3 destroyCache(cache3);
 47  3 destroyCache(cache2);
 48  3 destroyCache(cache1);
 49  3 cache1 = null;
 50  3 cache2 = null;
 51  3 cache3 = null;
 52  3 super.tearDown();
 53  3 System.out.println("********* END: TEAR DOWN *************");
 54    }
 55   
 56  9 private MyTC initCache(boolean notifying) throws Exception
 57    {
 58  9 MyTC c = new MyTC();
 59  9 c.getConfiguration().setCacheMode("REPL_SYNC");
 60  9 c.getConfiguration().setClusterConfig(getJGroupsStack());
 61  9 c.getConfiguration().setFetchInMemoryState(false);
 62  9 if (!notifying)
 63    {
 64  6 c.getConfiguration().setTransactionManagerLookupClass("org.jboss.cache.transaction.DummyTransactionManagerLookup");
 65    }
 66    else
 67    {
 68  3 c.getConfiguration().setTransactionManagerLookupClass("org.jboss.cache.transaction.NotifyingTransactionManager");
 69    }
 70  9 c.start();
 71  9 return c;
 72    }
 73   
 74    // we need a 'special' stack that does not attempt redelivery since we kill a channel midway during a tx in this test.
 75  9 private String getJGroupsStack()
 76    {
 77    // return "UDP(mcast_addr=224.0.0.36;mcast_port=55566;ip_ttl=32;" +
 78    // "mcast_send_buf_size=150000;mcast_recv_buf_size=80000):" +
 79    // "PING(timeout=10;num_initial_members=1):" +
 80    // "pbcast.NAKACK(gc_lag=50;max_xmit_size=8192;retransmit_timeout=10):" +
 81    // "UNICAST(timeout=600):" +
 82    // "FRAG(frag_size=8192;down_thread=false;up_thread=false):" +
 83    // "pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;" +
 84    // "shun=false;print_local_addr=true):" +
 85    // "pbcast.STATE_TRANSFER";
 86  9 return JChannel.DEFAULT_PROTOCOL_STACK;
 87    }
 88   
 89  9 private void destroyCache(MyTC c)
 90    {
 91  9 if (c != null)
 92    {
 93  9 c.stop();
 94  9 c.destroy();
 95    }
 96    }
 97   
 98  1 public void testSyncCaches() throws Exception
 99    {
 100  1 performTest(false, false);
 101    }
 102   
 103  1 public void testSyncCachesSyncCommitRollback() throws Exception
 104    {
 105  1 performTest(true, false);
 106    }
 107   
 108    /**
 109    * Note that this tests a *remote* beforeCompletion abort - which is a part of the calling instance's afterCompletion.
 110    *
 111    * @throws Exception
 112    */
 113  1 public void testAbortBeforeCompletion() throws Exception
 114    {
 115  1 performTest(true, true);
 116    }
 117   
 118  3 private void performTest(boolean syncCommitRollback, boolean abortBeforeCompletion) throws Exception
 119    {
 120  3 cache1.getConfiguration().setSyncCommitPhase(syncCommitRollback);
 121  3 cache1.getConfiguration().setSyncRollbackPhase(syncCommitRollback);
 122  3 cache2.getConfiguration().setSyncCommitPhase(syncCommitRollback);
 123  3 cache2.getConfiguration().setSyncRollbackPhase(syncCommitRollback);
 124  3 cache3.getConfiguration().setSyncCommitPhase(syncCommitRollback);
 125  3 cache3.getConfiguration().setSyncRollbackPhase(syncCommitRollback);
 126   
 127  3 TransactionManager mgr1 = cache1.getTransactionManager();
 128  3 TransactionManager mgr2 = cache2.getTransactionManager();
 129  3 assertTrue(cache3.getTransactionManager() instanceof NotifyingTransactionManager);
 130  3 NotifyingTransactionManager mgr3 = (NotifyingTransactionManager) cache3.getTransactionManager();
 131   
 132  3 assertSame(mgr1, mgr2);
 133  3 assertNotSame(mgr1, mgr3);
 134  3 assertNotSame(mgr2, mgr3);
 135   
 136  3 assertTrue(mgr1 instanceof DummyTransactionManager);
 137  3 assertTrue(mgr2 instanceof DummyTransactionManager);
 138   
 139  3 cache1.put("/test", "key", "value");
 140   
 141  3 assertEquals("value", cache1.get("/test", "key"));
 142  3 assertEquals("value", cache2.get("/test", "key"));
 143  3 assertEquals("value", cache3.get("/test", "key"));
 144   
 145  3 mgr3.setNotification(new TestNotification(abortBeforeCompletion));
 146   
 147  3 mgr1.begin();
 148  3 Transaction tx = mgr1.getTransaction();
 149  3 cache1.put("/test", "key", "value2");
 150  3 tx.commit();
 151   
 152  3 TestingUtil.sleepThread(5000);
 153   
 154    // only test cache1 and cache2. Assume cache3 has crashed out.
 155  3 assertEquals(0, cache1.getNumberOfLocksHeld());
 156  3 assertEquals(0, cache2.getNumberOfLocksHeld());
 157  3 assertEquals("put in transaction should NOT have been rolled back", "value2", cache1.get("/test", "key"));
 158  3 assertEquals("put in transaction should NOT have been rolled back", "value2", cache2.get("/test", "key"));
 159   
 160    }
 161   
 162   
 163    class TestNotification implements Notification
 164    {
 165    boolean abortBeforeCompletion;
 166   
 167  3 public TestNotification(boolean abortBeforeCompletion)
 168    {
 169  3 this.abortBeforeCompletion = abortBeforeCompletion;
 170    }
 171   
 172  3 public void notify(Transaction tx) throws SystemException, RollbackException
 173    {
 174  3 final Transaction finalTx = tx;
 175  3 System.out.println("Notify called.");
 176    // add an aborting sync handler.
 177  3 Synchronization abort = new Synchronization()
 178    {
 179   
 180  3 public void beforeCompletion()
 181    {
 182  3 if (abortBeforeCompletion)
 183    {
 184  1 cache3.myChannel.close();
 185  1 System.out.println("Returning from abort.beforeCompletion");
 186  1 try
 187    {
 188  1 finalTx.setRollbackOnly();
 189    }
 190    catch (SystemException e)
 191    {
 192  0 throw new RuntimeException("Unable to set rollback", e);
 193    }
 194  1 throw new RuntimeException("Dummy exception");
 195    }
 196    }
 197   
 198  3 public void afterCompletion(int i)
 199    {
 200  3 if (!abortBeforeCompletion)
 201    {
 202  2 cache3.myChannel.close();
 203  2 System.out.println("Returning from abort.afterCompletion");
 204  2 throw new RuntimeException("Dummy exception");
 205    }
 206    }
 207    };
 208   
 209  3 OrderedSynchronizationHandler osh = OrderedSynchronizationHandler.getInstance(tx);
 210  3 osh.registerAtHead(abort);
 211  3 System.out.println("Added sync handler.");
 212    }
 213   
 214    }
 215   
 216    ;
 217   
 218   
 219    public static class MyTC extends CacheImpl
 220    {
 221    Channel myChannel;
 222   
 223  9 public MyTC() throws Exception
 224    {
 225  9 super();
 226    }
 227   
 228  9 public void start() throws CacheException
 229    {
 230  9 super.start();
 231  9 myChannel = channel;
 232    }
 233    }
 234   
 235    }