1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2002,2008 Oracle. All rights reserved. 5 * 6 * $Id: TxnTestCase.java,v 12.1 2008/02/07 17:12:33 mark Exp $ 7 */ 8 9package com.sleepycat.util.test; 10 11import java.io.File; 12import java.io.IOException; 13import java.util.Enumeration; 14 15import junit.framework.TestCase; 16import junit.framework.TestSuite; 17 18import com.sleepycat.db.DatabaseException; 19import com.sleepycat.db.Environment; 20import com.sleepycat.db.EnvironmentConfig; 21import com.sleepycat.db.Transaction; 22import com.sleepycat.db.TransactionConfig; 23 24/** 25 * Permuates test cases over three transaction types: null (non-transactional), 26 * auto-commit, and user (explicit). 27 * 28 * <p>Overrides runTest, setUp and tearDown to open/close the environment and to 29 * set up protected members for use by test cases.</p> 30 * 31 * <p>If a subclass needs to override setUp or tearDown, the overridden method 32 * should call super.setUp or super.tearDown.</p> 33 * 34 * <p>When writing a test case based on this class, write it as if a user txn 35 * were always used: call txnBegin, txnCommit and txnAbort for all write 36 * operations. Use the isTransactional protected field for setup of a database 37 * config.</p> 38 */ 39public abstract class TxnTestCase extends TestCase { 40 41 public static final String TXN_NULL = "txn-null"; 42 public static final String TXN_AUTO = "txn-auto"; 43 public static final String TXN_USER = "txn-user"; 44 45 protected File envHome; 46 protected Environment env; 47 protected EnvironmentConfig envConfig; 48 protected String txnType; 49 protected boolean isTransactional; 50 51 /** 52 * Returns a txn test suite. If txnTypes is null, all three types are run. 53 */ 54 public static TestSuite txnTestSuite(Class testCaseClass, 55 EnvironmentConfig envConfig, 56 String[] txnTypes) { 57 if (txnTypes == null) { 58 txnTypes = new String[] { TxnTestCase.TXN_NULL, 59 TxnTestCase.TXN_USER, 60 TxnTestCase.TXN_AUTO }; 61 } 62 if (envConfig == null) { 63 envConfig = new EnvironmentConfig(); 64 envConfig.setAllowCreate(true); 65 } 66 TestSuite suite = new TestSuite(); 67 for (int i = 0; i < txnTypes.length; i += 1) { 68 TestSuite baseSuite = new TestSuite(testCaseClass); 69 Enumeration e = baseSuite.tests(); 70 while (e.hasMoreElements()) { 71 TxnTestCase test = (TxnTestCase) e.nextElement(); 72 test.txnInit(envConfig, txnTypes[i]); 73 suite.addTest(test); 74 } 75 } 76 return suite; 77 } 78 79 private void txnInit(EnvironmentConfig envConfig, String txnType) { 80 81 this.envConfig = envConfig; 82 this.txnType = txnType; 83 isTransactional = (txnType != TXN_NULL); 84 } 85 86 public void setUp() 87 throws Exception { 88 89 envHome = SharedTestUtils.getNewDir(); 90 } 91 92 public void runTest() 93 throws Throwable { 94 95 openEnv(); 96 super.runTest(); 97 closeEnv(); 98 } 99 100 public void tearDown() 101 throws Exception { 102 103 /* Set test name for reporting; cannot be done in the ctor or setUp. */ 104 setName(txnType + ':' + getName()); 105 106 if (env != null) { 107 try { 108 env.close(); 109 } catch (Throwable e) { 110 System.out.println("tearDown: " + e); 111 } 112 env = null; 113 } 114 115 try { 116 SharedTestUtils.emptyDir(envHome); 117 } catch (Throwable e) { 118 System.out.println("tearDown: " + e); 119 } 120 } 121 122 /** 123 * Closes the environment and sets the env field to null. 124 * Used for closing and reopening the environment. 125 */ 126 public void closeEnv() 127 throws DatabaseException { 128 129 if (env != null) { 130 env.close(); 131 env = null; 132 } 133 } 134 135 /** 136 * Opens the environment based on the txnType for this test case. 137 * Used for closing and reopening the environment. 138 */ 139 public void openEnv() 140 throws IOException, DatabaseException { 141 142 if (txnType == TXN_NULL) { 143 TestEnv.BDB.copyConfig(envConfig); 144 env = new Environment(envHome, envConfig); 145 } else if (txnType == TXN_AUTO) { 146 TestEnv.TXN.copyConfig(envConfig); 147 env = new Environment(envHome, envConfig); 148 } else if (txnType == TXN_USER) { 149 TestEnv.TXN.copyConfig(envConfig); 150 env = new Environment(envHome, envConfig); 151 } else { 152 assert false; 153 } 154 } 155 156 /** 157 * Begin a txn if in TXN_USER mode; otherwise return null; 158 */ 159 protected Transaction txnBegin() 160 throws DatabaseException { 161 162 return txnBegin(null, null); 163 } 164 165 /** 166 * Begin a txn if in TXN_USER mode; otherwise return null; 167 */ 168 protected Transaction txnBegin(Transaction parentTxn, 169 TransactionConfig config) 170 throws DatabaseException { 171 172 if (txnType == TXN_USER) { 173 return env.beginTransaction(parentTxn, config); 174 } else { 175 return null; 176 } 177 } 178 179 /** 180 * Begin a txn if in TXN_USER or TXN_AUTO mode; otherwise return null; 181 */ 182 protected Transaction txnBeginCursor() 183 throws DatabaseException { 184 185 return txnBeginCursor(null, null); 186 } 187 188 /** 189 * Begin a txn if in TXN_USER or TXN_AUTO mode; otherwise return null; 190 */ 191 protected Transaction txnBeginCursor(Transaction parentTxn, 192 TransactionConfig config) 193 throws DatabaseException { 194 195 if (txnType == TXN_USER || txnType == TXN_AUTO) { 196 return env.beginTransaction(parentTxn, config); 197 } else { 198 return null; 199 } 200 } 201 202 /** 203 * Commit a txn if non-null. 204 */ 205 protected void txnCommit(Transaction txn) 206 throws DatabaseException { 207 208 if (txn != null) { 209 txn.commit(); 210 } 211 } 212 213 /** 214 * Commit a txn if non-null. 215 */ 216 protected void txnAbort(Transaction txn) 217 throws DatabaseException { 218 219 if (txn != null) { 220 txn.abort(); 221 } 222 } 223} 224