Clover coverage report -
Coverage timestamp: Thu Jul 5 2007 20:02:32 EDT
file stats: LOC: 487   Methods: 16
NCLOC: 314   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
CacheTest.java 75% 99.5% 100% 98.4%
coverage coverage
 1    /*
 2    * Created on 17-Feb-2005
 3    *
 4    */
 5    package org.jboss.cache.optimistic;
 6   
 7    import junit.framework.Assert;
 8    import org.apache.commons.logging.Log;
 9    import org.apache.commons.logging.LogFactory;
 10    import org.jboss.cache.CacheImpl;
 11    import org.jboss.cache.Fqn;
 12    import org.jboss.cache.config.Configuration;
 13    import org.jboss.cache.loader.SamplePojo;
 14    import org.jboss.cache.marshall.MethodCall;
 15    import org.jboss.cache.marshall.MethodCallFactory;
 16    import org.jboss.cache.marshall.MethodDeclarations;
 17    import org.jboss.cache.transaction.DummyTransactionManager;
 18    import org.jboss.cache.transaction.GlobalTransaction;
 19    import org.jboss.cache.transaction.OptimisticTransactionEntry;
 20    import org.jboss.cache.transaction.TransactionTable;
 21   
 22    import javax.transaction.RollbackException;
 23    import javax.transaction.Transaction;
 24    import javax.transaction.TransactionManager;
 25    import java.util.List;
 26    import java.util.concurrent.CountDownLatch;
 27   
 28    public class CacheTest extends AbstractOptimisticTestCase
 29    {
 30    Log log = LogFactory.getLog(CacheTest.class);
 31   
 32  12 public CacheTest(String s)
 33    {
 34  12 super(s);
 35    }
 36   
 37    private CacheImpl c;
 38   
 39  12 protected void setUp() throws Exception
 40    {
 41  12 c = createCache();
 42    }
 43   
 44  12 protected void tearDown()
 45    {
 46  12 super.tearDown();
 47  12 if (c != null)
 48  12 destroyCache(c);
 49  12 c = null;
 50    }
 51   
 52  1 public void testExplicitTxFailure() throws Exception
 53    {
 54    // explicit.
 55  1 TransactionManager mgr = c.getTransactionManager();
 56  1 try
 57    {
 58  1 mgr.begin();
 59  1 c.put("/a", "k", "v");
 60  1 Transaction t = mgr.suspend();
 61  1 c.put("/a", "k2", "v2");
 62  1 mgr.resume(t);
 63  1 mgr.commit();
 64  0 Assert.assertTrue("Expecting a rollback exception!", false);
 65    }
 66    catch (RollbackException re)
 67    {
 68  1 Assert.assertTrue("Expecting a rollback exception!", true);
 69    }
 70    }
 71   
 72  1 public void testImplicitTxFailure() throws Exception
 73    {
 74    // implicit (much harder to orchestrate...
 75  1 int numThreads = 50;
 76  1 ExceptionThread thread[] = new ExceptionThread[numThreads];
 77  1 final CountDownLatch latch = new CountDownLatch(1);
 78   
 79  1 for (int i = 0; i < numThreads; i++)
 80    {
 81  50 thread[i] = new ExceptionThread()
 82    {
 83  50 public void run()
 84    {
 85  50 try
 86    {
 87  50 latch.await();
 88  50 c.put("/a", "k", "v");
 89    }
 90    catch (Exception e)
 91    {
 92  6 log.fatal("*** Thew an exception!!", e);
 93  6 setException(e);
 94    }
 95    }
 96    };
 97    }
 98   
 99  50 for (int i = 0; i < numThreads; i++) thread[i].start();
 100  1 latch.countDown();
 101  50 for (int i = 0; i < numThreads; i++) thread[i].join();
 102    // test exceptions. Expecting at least one exception
 103  1 Exception e;
 104  1 int exceptionCount = 0;
 105  1 for (int i = 0; i < numThreads; i++)
 106    {
 107   
 108  ? if ((e = thread[i].getException()) != null)
 109    {
 110  6 assertFalse("Should never see a RollbackException - instead, expecting the CAUSE of the rollback.", e instanceof RollbackException);
 111  6 exceptionCount++;
 112    }
 113    }
 114   
 115  1 assertTrue("Expecting at least ONE concurrent write exception!!", exceptionCount > 0);
 116    }
 117   
 118  1 public void testLocalTransaction() throws Exception
 119    {
 120  1 MockInterceptor dummy = new MockInterceptor();
 121  1 dummy.setCache(c);
 122   
 123  1 c.setInterceptorChain(getAlteredInterceptorChain(dummy, c, true));
 124   
 125  1 DummyTransactionManager mgr = DummyTransactionManager.getInstance();
 126  1 assertNull(mgr.getTransaction());
 127   
 128  1 mgr.begin();
 129   
 130  1 assertEquals(0, c.getTransactionTable().getNumGlobalTransactions());
 131  1 assertEquals(0, c.getTransactionTable().getNumLocalTransactions());
 132   
 133  1 SamplePojo pojo = new SamplePojo(21, "test");
 134   
 135  1 c.put("/one/two", "key1", pojo);
 136   
 137  1 mgr.commit();
 138   
 139  1 assertNull(mgr.getTransaction());
 140  1 assertEquals(0, c.getTransactionTable().getNumGlobalTransactions());
 141  1 assertEquals(0, c.getTransactionTable().getNumLocalTransactions());
 142   
 143    //make sure all calls were done in right order
 144   
 145  1 List calls = dummy.getAllCalled();
 146   
 147  1 assertEquals(MethodDeclarations.optimisticPrepareMethod, calls.get(0));
 148  1 assertEquals(MethodDeclarations.commitMethod, calls.get(1));
 149    }
 150   
 151  1 public void testRollbackTransaction() throws Exception
 152    {
 153   
 154  1 destroyCache(c);
 155  1 c = createCacheWithListener();
 156   
 157  1 MockInterceptor dummy = new MockInterceptor();
 158  1 dummy.setCache(c);
 159   
 160  1 c.setInterceptorChain(getAlteredInterceptorChain(dummy, c, true));
 161   
 162  1 DummyTransactionManager mgr = DummyTransactionManager.getInstance();
 163  1 assertNull(mgr.getTransaction());
 164  1 assertEquals(0, c.getTransactionTable().getNumGlobalTransactions());
 165  1 assertEquals(0, c.getTransactionTable().getNumLocalTransactions());
 166   
 167  1 SamplePojo pojo = new SamplePojo(21, "test");
 168  1 mgr.begin();
 169  1 c.put("/one/two", "key1", pojo);
 170  1 mgr.rollback();
 171  1 assertNull(mgr.getTransaction());
 172  1 assertEquals(0, c.getTransactionTable().getNumGlobalTransactions());
 173  1 assertEquals(0, c.getTransactionTable().getNumLocalTransactions());
 174   
 175    //make sure all calls were done in right order
 176   
 177  1 List calls = dummy.getAllCalled();
 178   
 179  1 assertEquals(1, calls.size());
 180  1 assertEquals(MethodDeclarations.rollbackMethod, calls.get(0));
 181    }
 182   
 183  1 public void testRemotePrepareTransaction() throws Throwable
 184    {
 185  1 destroyCache(c);
 186  1 c = createCacheWithListener();
 187   
 188  1 MockInterceptor dummy = new MockInterceptor();
 189  1 dummy.setCache(c);
 190   
 191  1 c.setInterceptorChain(getAlteredInterceptorChain(dummy, c, true));
 192  1 DummyTransactionManager mgr = DummyTransactionManager.getInstance();
 193   
 194    //start local transaction
 195  1 mgr.begin();
 196  1 Transaction tx = mgr.getTransaction();
 197   
 198    //this sets
 199  1 c.getCurrentTransaction(tx);
 200   
 201  1 SamplePojo pojo = new SamplePojo(21, "test");
 202   
 203  1 c.put("/one/two", "key1", pojo);
 204   
 205  1 GlobalTransaction gtx = c.getCurrentTransaction(tx);
 206  1 TransactionTable table = c.getTransactionTable();
 207  1 OptimisticTransactionEntry entry = (OptimisticTransactionEntry) table.get(gtx);
 208  1 assertNotNull(mgr.getTransaction());
 209  1 mgr.commit();
 210   
 211   
 212  1 GlobalTransaction remoteGtx = new GlobalTransaction();
 213   
 214  1 remoteGtx.setAddress(new DummyAddress());
 215    //hack the method call to make it have the remote gtx
 216  1 MethodCall meth = entry.getModifications().get(0);
 217   
 218  1 meth.getArgs()[0] = remoteGtx;
 219    //call our remote method
 220  1 MethodCall prepareMethod = MethodCallFactory.create(MethodDeclarations.optimisticPrepareMethod, remoteGtx, injectDataVersion(entry.getModifications()), null, remoteGtx.getAddress(), Boolean.FALSE);
 221  1 c._replicate(prepareMethod);
 222   
 223    //our thread should be null
 224  1 assertNull(mgr.getTransaction());
 225   
 226    // there should be a registration for the remote gtx
 227  1 assertNotNull(table.get(remoteGtx));
 228  1 assertNotNull(table.getLocalTransaction(remoteGtx));
 229    //assert that this is populated
 230  1 assertEquals(1, table.get(remoteGtx).getModifications().size());
 231   
 232    //assert that the remote prepare has populated the local workspace
 233  1 OptimisticTransactionEntry opEntry = (OptimisticTransactionEntry) table.get(gtx);
 234   
 235  1 assertEquals(3, entry.getTransactionWorkSpace().getNodes().size());
 236  1 assertEquals(1, entry.getModifications().size());
 237  1 List calls = dummy.getAllCalled();
 238  1 assertEquals(MethodDeclarations.optimisticPrepareMethod, calls.get(2));
 239   
 240  1 assertEquals(1, c.getTransactionTable().getNumGlobalTransactions());
 241  1 assertEquals(1, c.getTransactionTable().getNumLocalTransactions());
 242    }
 243   
 244  1 public void testRemoteCacheBroadcast() throws Exception
 245    {
 246  1 destroyCache(c);
 247   
 248  1 CacheImpl cache = createReplicatedCache(Configuration.CacheMode.REPL_SYNC);
 249  1 CacheImpl cache2 = createReplicatedCache(Configuration.CacheMode.REPL_SYNC);
 250  1 assertEquals(2, cache.getMembers().size());
 251  1 assertEquals(2, cache2.getMembers().size());
 252   
 253   
 254  1 DummyTransactionManager mgr = DummyTransactionManager.getInstance();
 255   
 256    //start local transaction
 257  1 mgr.begin();
 258  1 Transaction tx = mgr.getTransaction();
 259   
 260    //this sets
 261  1 GlobalTransaction gtx = cache.getCurrentTransaction(tx);
 262   
 263  1 SamplePojo pojo = new SamplePojo(21, "test");
 264   
 265  1 cache.put("/one/two", "key1", pojo);
 266   
 267    //GlobalTransaction gtx = cache.getCurrentTransaction(tx);
 268  1 TransactionTable table = cache.getTransactionTable();
 269  1 assertNotNull(mgr.getTransaction());
 270  1 mgr.commit();
 271   
 272   
 273  1 assertNull(mgr.getTransaction());
 274   
 275    //assert that the local cache is in the right state
 276  1 assertEquals(0, cache.getTransactionTable().getNumGlobalTransactions());
 277  1 assertEquals(0, cache.getTransactionTable().getNumLocalTransactions());
 278   
 279  1 assertTrue(cache.exists(Fqn.fromString("/one/two")));
 280  1 assertTrue(cache.exists(Fqn.fromString("/one")));
 281  1 assertEquals(pojo, cache.get(Fqn.fromString("/one/two"), "key1"));
 282   
 283  1 assertEquals(0, cache2.getTransactionTable().getNumGlobalTransactions());
 284  1 assertEquals(0, cache2.getTransactionTable().getNumLocalTransactions());
 285   
 286  1 assertTrue(cache2.exists(Fqn.fromString("/one/two")));
 287  1 assertTrue(cache2.exists(Fqn.fromString("/one")));
 288  1 assertEquals(pojo, cache2.get(Fqn.fromString("/one/two"), "key1"));
 289   
 290   
 291  1 destroyCache(cache);
 292  1 destroyCache(cache2);
 293    }
 294   
 295   
 296  1 public void testTwoWayRemoteCacheBroadcast() throws Exception
 297    {
 298   
 299  1 destroyCache(c);
 300  1 CacheImpl cache = createReplicatedCache(Configuration.CacheMode.REPL_SYNC);
 301  1 CacheImpl cache2 = createReplicatedCache(Configuration.CacheMode.REPL_SYNC);
 302  1 assertEquals(2, cache.getMembers().size());
 303  1 assertEquals(2, cache2.getMembers().size());
 304   
 305   
 306  1 DummyTransactionManager mgr = DummyTransactionManager.getInstance();
 307   
 308    //start local transaction
 309  1 mgr.begin();
 310  1 Transaction tx = mgr.getTransaction();
 311   
 312    //this sets
 313  1 cache.getCurrentTransaction(tx);
 314   
 315  1 SamplePojo pojo = new SamplePojo(21, "test");
 316   
 317  1 cache.put("/one/two", "key1", pojo);
 318   
 319  1 GlobalTransaction gtx = cache.getCurrentTransaction(tx);
 320  1 TransactionTable table = cache.getTransactionTable();
 321  1 assertNotNull(mgr.getTransaction());
 322  1 mgr.commit();
 323   
 324   
 325  1 assertNull(mgr.getTransaction());
 326   
 327    //assert that the local cache is in the right state
 328  1 assertEquals(0, cache.getTransactionTable().getNumGlobalTransactions());
 329  1 assertEquals(0, cache.getTransactionTable().getNumLocalTransactions());
 330   
 331  1 assertTrue(cache.exists(Fqn.fromString("/one/two")));
 332  1 assertTrue(cache.exists(Fqn.fromString("/one")));
 333  1 assertEquals(pojo, cache.get(Fqn.fromString("/one/two"), "key1"));
 334   
 335   
 336  1 assertEquals(0, cache2.getTransactionTable().getNumGlobalTransactions());
 337  1 assertEquals(0, cache2.getTransactionTable().getNumLocalTransactions());
 338   
 339  1 assertTrue(cache2.exists(Fqn.fromString("/one/two")));
 340  1 assertTrue(cache2.exists(Fqn.fromString("/one")));
 341   
 342  1 assertEquals(pojo, cache2.get(Fqn.fromString("/one/two"), "key1"));
 343   
 344   
 345  1 destroyCache(cache);
 346  1 destroyCache(cache2);
 347   
 348   
 349    }
 350   
 351    // public void testRemotePessCacheBroadcast() throws Exception
 352    // {
 353    // destroyCache(c);
 354    //
 355    // CacheImpl cache = createPessimisticCache();
 356    // CacheImpl cache2 = createPessimisticCache();
 357    //
 358    // DummyTransactionManager mgr = DummyTransactionManager.getInstance();
 359    //
 360    // //start local transaction
 361    // mgr.begin();
 362    // Transaction tx = mgr.getTransaction();
 363    //
 364    // //this sets
 365    // cache.getCurrentTransaction(tx);
 366    //
 367    // SamplePojo pojo = new SamplePojo(21, "test");
 368    //
 369    // cache.put("/one/two", "key1", pojo);
 370    //
 371    //
 372    // mgr.commit();
 373    //
 374    // destroyCache(cache);
 375    // destroyCache(cache2);
 376    //
 377    // }
 378   
 379  1 public void testConcurrentNodeRemoval() throws Exception
 380    {
 381  1 c.put(fqn, "key", "value");
 382   
 383    // now start a tx to change the value in fqn
 384  1 TransactionManager mgr = c.getTransactionManager();
 385  1 mgr.begin();
 386   
 387  1 c.put(fqn, "key2", "value2");
 388   
 389  1 Transaction tx = mgr.suspend();
 390   
 391    // now remove the original node...
 392  1 c.remove(fqn);
 393   
 394  1 mgr.resume(tx);
 395    // now try and commit this - this should fail.
 396  1 boolean ok = false;
 397  1 try
 398    {
 399  1 mgr.commit();
 400    }
 401    catch (RollbackException rbe)
 402    {
 403  1 ok = true;
 404    }
 405   
 406  1 Assert.assertTrue("Concurrent mod should result in a rollback", ok);
 407    // now assert that the node has in fact been removed.
 408  1 Assert.assertTrue("The node should have been removed!", !c.exists(fqn));
 409   
 410    }
 411   
 412  1 public void testConcurrentNodeModification() throws Exception
 413    {
 414  1 c.put(fqn, "key", "value");
 415   
 416    // now start a tx to change the value in fqn
 417  1 TransactionManager mgr = c.getTransactionManager();
 418  1 mgr.begin();
 419   
 420  1 c.put(fqn, "key2", "value2");
 421   
 422  1 Transaction tx = mgr.suspend();
 423   
 424    // now change the original node...
 425  1 c.put(fqn, "key3", "value3");
 426   
 427  1 mgr.resume(tx);
 428    // now try and commit this - this should fail.
 429  1 boolean ok = false;
 430  1 try
 431    {
 432  1 mgr.commit();
 433    }
 434    catch (RollbackException rbe)
 435    {
 436  1 ok = true;
 437    }
 438   
 439  1 Assert.assertTrue("Concurrent mod should result in a rollback", ok);
 440    }
 441   
 442  1 public void testRemoveAndCreate() throws Exception
 443    {
 444  1 c = createCache();
 445  1 c.put(fqn, "key", "value");
 446  1 TransactionManager tm = c.getTransactionManager();
 447  1 tm.begin();
 448  1 c.put(fqn, "test", "test");
 449  1 tm.commit();
 450   
 451  1 assertEquals(1, c.getRoot().getChildrenNames().size());
 452   
 453  1 tm.begin();
 454  1 c.removeNode(fqn);
 455  1 c.put(fqn, "test", "test");
 456  1 tm.commit();
 457   
 458  1 assertEquals(1, c.getRoot().getChildrenNames().size());
 459   
 460    }
 461   
 462  1 public void testRemoveChildAfterRemoveParent() throws Exception
 463    {
 464  1 c = createCache();
 465  1 TransactionManager tm = c.getTransactionManager();
 466  1 c.put(Fqn.fromString("/a/b"), "k", "v");
 467  1 tm.begin();
 468  1 c.remove(Fqn.fromString("/a"));
 469  1 c.remove(Fqn.fromString("/a/b"));
 470  1 tm.commit();
 471   
 472  1 destroyCache(c);
 473    }
 474   
 475  1 public void testAddChildAfterRemoveParent() throws Exception
 476    {
 477  1 c = createCache();
 478  1 TransactionManager tm = c.getTransactionManager();
 479  1 c.put(Fqn.fromString("/a/b"), "k", "v");
 480  1 tm.begin();
 481  1 c.remove(Fqn.fromString("/a"));
 482  1 c.put(Fqn.fromString("/a/b"), "k", "v");
 483  1 tm.commit();
 484   
 485  1 destroyCache(c);
 486    }
 487    }