Clover coverage report -
Coverage timestamp: Thu Jul 5 2007 20:02:32 EDT
file stats: LOC: 349   Methods: 9
NCLOC: 274   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
IsolationLevelTestBase.java 58.3% 90.2% 100% 84.6%
coverage coverage
 1    package org.jboss.cache.transaction.isolationlevels;
 2   
 3    import junit.framework.TestCase;
 4    import org.jboss.cache.Cache;
 5    import org.jboss.cache.CacheFactory;
 6    import org.jboss.cache.DefaultCacheFactory;
 7    import org.jboss.cache.Fqn;
 8    import org.jboss.cache.lock.IsolationLevel;
 9    import static org.jboss.cache.lock.IsolationLevel.*;
 10    import org.jboss.cache.transaction.DummyTransactionManagerLookup;
 11   
 12    import javax.transaction.Transaction;
 13    import javax.transaction.TransactionManager;
 14    import java.util.Collection;
 15    import java.util.HashSet;
 16   
 17    /**
 18    * Base class for testing isolation levels.
 19    *
 20    * @author <a href="mailto:manik@jboss.org">Manik Surtani</a>
 21    * @since 2.0.0
 22    */
 23    public abstract class IsolationLevelTestBase extends TestCase
 24    {
 25    protected IsolationLevel isolationLevel;
 26    protected Cache<String, String> cache;
 27    protected TransactionManager transactionManager;
 28    protected Fqn<String> fqn = Fqn.fromString("/a/b/c");
 29    protected Fqn<String> fqnChild1 = Fqn.fromString("/a/b/c/child1");
 30    protected Fqn<String> fqnChild2 = Fqn.fromString("/a/b/c/child2");
 31    protected String k = "key", v = "value";
 32    protected Collection<IsolationLevel> allowedLevels;
 33   
 34  35 protected void setUp()
 35    {
 36  35 CacheFactory<String, String> cf = DefaultCacheFactory.getInstance();
 37  35 cache = cf.createCache(false);
 38  35 cache.getConfiguration().setIsolationLevel(isolationLevel);
 39  35 cache.getConfiguration().setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
 40    // very short so the tests don't take ages
 41  35 cache.getConfiguration().setLockAcquisitionTimeout(250);
 42  35 cache.start();
 43  35 transactionManager = cache.getConfiguration().getRuntimeConfig().getTransactionManager();
 44  35 allowedLevels = new HashSet<IsolationLevel>();
 45    }
 46   
 47  35 protected void tearDown()
 48    {
 49  35 if (transactionManager != null)
 50    {
 51    // roll back any ongoing, potentially stuck transactions from failed tests.
 52  35 try
 53    {
 54  35 transactionManager.rollback();
 55    }
 56    catch (Exception e)
 57    {
 58    // no-op
 59    }
 60    }
 61  35 cache.stop();
 62  35 cache.destroy();
 63  35 cache = null;
 64  35 allowedLevels = null;
 65    }
 66   
 67  5 public void testDirtyRead() throws Exception
 68    {
 69    // should be allowed in all cases except R_C, R_R and Serializable
 70  5 allowedLevels.add(NONE);
 71  5 allowedLevels.add(READ_UNCOMMITTED);
 72   
 73    // do a write
 74  5 transactionManager.begin();
 75  5 cache.put(fqn, k, v);
 76  5 Transaction t1 = transactionManager.suspend();
 77   
 78    // and now a simultaneous read
 79  5 transactionManager.begin();
 80  5 try
 81    {
 82  5 assertEquals(v, cache.get(fqn, k));
 83  2 transactionManager.commit();
 84  2 if (!allowedLevels.contains(isolationLevel))
 85    {
 86  0 fail("Should have thrown an exception");
 87    }
 88    }
 89    catch (Exception e)
 90    {
 91  3 if (allowedLevels.contains(isolationLevel))
 92    {
 93  0 throw e;
 94    }
 95    }
 96   
 97  5 transactionManager.resume(t1);
 98  5 transactionManager.rollback();
 99    }
 100   
 101  5 public void testDirtyReadWithNoData() throws Exception
 102    {
 103    // should be allowed in all cases except Serializable
 104  5 allowedLevels.add(NONE);
 105  5 allowedLevels.add(READ_UNCOMMITTED);
 106  5 allowedLevels.add(READ_COMMITTED);
 107  5 allowedLevels.add(REPEATABLE_READ);
 108   
 109    // do a write
 110  5 transactionManager.begin();
 111  5 assertNull(cache.get(fqn, k));
 112  5 Transaction t1 = transactionManager.suspend();
 113   
 114    // and now a simultaneous read
 115  5 transactionManager.begin();
 116  5 try
 117    {
 118  5 cache.put(fqn, k, v);
 119  4 transactionManager.commit();
 120  4 if (!allowedLevels.contains(isolationLevel))
 121    {
 122  0 fail("Should have thrown an exception");
 123    }
 124    }
 125    catch (Exception e)
 126    {
 127  1 if (allowedLevels.contains(isolationLevel))
 128    {
 129  0 throw e;
 130    }
 131    }
 132   
 133  5 transactionManager.resume(t1);
 134  5 if (allowedLevels.contains(isolationLevel))
 135    {
 136  4 assertEquals(v, cache.get(fqn, k));
 137    }
 138    else
 139    {
 140  1 assertNull(cache.get(fqn, k));
 141    }
 142  5 transactionManager.rollback();
 143    }
 144   
 145  5 public void testTwoReads() throws Exception
 146    {
 147    // should be allowed in all cases except Serializable
 148  5 allowedLevels.add(NONE);
 149  5 allowedLevels.add(READ_UNCOMMITTED);
 150  5 allowedLevels.add(READ_COMMITTED);
 151  5 allowedLevels.add(REPEATABLE_READ);
 152   
 153    // set up some data
 154  5 cache.put(fqn, k, v);
 155   
 156    // do a read
 157  5 transactionManager.begin();
 158  5 assertEquals(v, cache.get(fqn, k));
 159  5 Transaction t1 = transactionManager.suspend();
 160   
 161    // and now another simultaneous read
 162  5 transactionManager.begin();
 163  5 try
 164    {
 165  5 assertEquals(v, cache.get(fqn, k));
 166  4 transactionManager.commit();
 167  4 if (!allowedLevels.contains(isolationLevel))
 168    {
 169  0 fail("Should have thrown an exception");
 170    }
 171    }
 172    catch (Exception e)
 173    {
 174  1 if (allowedLevels.contains(isolationLevel))
 175    {
 176  0 throw e;
 177    }
 178    }
 179   
 180  5 transactionManager.resume(t1);
 181  5 transactionManager.rollback();
 182    }
 183   
 184  5 public void testTwoWrites() throws Exception
 185    {
 186    // should only be allowed for IsolationLevel.NONE
 187  5 allowedLevels.add(NONE);
 188   
 189    // set up some data
 190  5 cache.put(fqn, k, v);
 191   
 192    // do a write
 193  5 transactionManager.begin();
 194  5 cache.put(fqn, k, v);
 195  5 Transaction t1 = transactionManager.suspend();
 196   
 197    // and now another simultaneous write
 198  5 transactionManager.begin();
 199  5 try
 200    {
 201  5 cache.put(fqn, k, v);
 202  1 transactionManager.commit();
 203  1 if (!allowedLevels.contains(isolationLevel))
 204    {
 205  0 fail("Should have thrown an exception");
 206    }
 207    }
 208    catch (Exception e)
 209    {
 210  4 if (allowedLevels.contains(isolationLevel))
 211    {
 212  0 throw e;
 213    }
 214    }
 215   
 216  5 transactionManager.resume(t1);
 217  5 transactionManager.rollback();
 218    }
 219   
 220  5 public void testNonRepeatableRead() throws Exception
 221    {
 222    // should be allowed in all cases except R_R and Serializable
 223  5 allowedLevels.add(NONE);
 224  5 allowedLevels.add(READ_UNCOMMITTED);
 225  5 allowedLevels.add(READ_COMMITTED);
 226   
 227    // set up some data
 228  5 cache.put(fqn, k, v);
 229   
 230    // do a read
 231  5 transactionManager.begin();
 232  5 assertEquals(v, cache.get(fqn, k));
 233  5 Transaction t1 = transactionManager.suspend();
 234   
 235    // and now a simultaneous write
 236  5 transactionManager.begin();
 237  5 try
 238    {
 239  5 cache.put(fqn, k, v);
 240  3 transactionManager.commit();
 241  3 if (!allowedLevels.contains(isolationLevel))
 242    {
 243  0 fail("Should have thrown an exception");
 244    }
 245    }
 246    catch (Exception e)
 247    {
 248  2 if (allowedLevels.contains(isolationLevel))
 249    {
 250  0 throw e;
 251    }
 252    }
 253   
 254  5 transactionManager.resume(t1);
 255  5 assertEquals(v, cache.get(fqn, k));
 256  5 transactionManager.rollback();
 257    }
 258   
 259  5 public void testNonRepeatableReadWithNoData() throws Exception
 260    {
 261    // should be allowed in all cases except R_R and Serializable
 262    // This still does happen with R_R though since the database analogy breaks down here.
 263    // Since the node does not exist, it cannot be locked for repeatable read.
 264    // See http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4036036
 265   
 266  5 allowedLevels.add(NONE);
 267  5 allowedLevels.add(READ_UNCOMMITTED);
 268  5 allowedLevels.add(READ_COMMITTED);
 269  5 allowedLevels.add(REPEATABLE_READ);
 270   
 271    // do a read
 272  5 transactionManager.begin();
 273  5 assertNull(cache.get(fqn, k));
 274  5 Transaction t1 = transactionManager.suspend();
 275   
 276    // and now a simultaneous write
 277  5 transactionManager.begin();
 278  5 try
 279    {
 280  5 cache.put(fqn, k, v);
 281  4 transactionManager.commit();
 282  4 if (!allowedLevels.contains(isolationLevel))
 283    {
 284  0 fail("Should have thrown an exception");
 285    }
 286    }
 287    catch (Exception e)
 288    {
 289  1 if (allowedLevels.contains(isolationLevel))
 290    {
 291  0 throw e;
 292    }
 293    }
 294   
 295  5 transactionManager.resume(t1);
 296  5 if (allowedLevels.contains(isolationLevel))
 297    {
 298  4 assertEquals(v, cache.get(fqn, k));
 299    }
 300    else
 301    {
 302  1 assertNull(cache.get(fqn, k));
 303    }
 304  5 transactionManager.rollback();
 305    }
 306   
 307  5 public void testPhantomRead() throws Exception
 308    {
 309    // should be allowed in all cases except Serializable
 310  5 allowedLevels.add(NONE);
 311  5 allowedLevels.add(READ_UNCOMMITTED);
 312  5 allowedLevels.add(READ_COMMITTED);
 313  5 allowedLevels.add(REPEATABLE_READ);
 314   
 315    // set up some data
 316  5 cache.put(fqn, k, v);
 317  5 cache.put(fqnChild1, k, v);
 318   
 319    // do a read
 320  5 transactionManager.begin();
 321  5 int numChildren = cache.getRoot().getChild(fqn).getChildren().size();
 322  5 assertEquals(1, numChildren);
 323  5 Transaction t1 = transactionManager.suspend();
 324   
 325    // and now a simultaneous write
 326  5 transactionManager.begin();
 327  5 try
 328    {
 329  5 cache.put(fqnChild2, k, v);
 330  4 transactionManager.commit();
 331  4 if (!allowedLevels.contains(isolationLevel))
 332    {
 333  0 fail("Should have thrown an exception");
 334    }
 335    }
 336    catch (Exception e)
 337    {
 338  1 if (allowedLevels.contains(isolationLevel))
 339    {
 340  0 throw e;
 341    }
 342    }
 343   
 344  5 transactionManager.resume(t1);
 345  5 numChildren = cache.getRoot().getChild(fqn).getChildren().size();
 346  5 assertEquals(allowedLevels.contains(isolationLevel) ? 2 : 1, numChildren);
 347  5 transactionManager.rollback();
 348    }
 349    }