/tests_bugs/com/google/appengine/datanucleus/bugs/jdo/JDOBugTestCase.java
Java | 224 lines | 166 code | 32 blank | 26 comment | 18 complexity | 1d86c44dd7cfc14eb16eaa8ceade99ca MD5 | raw file
1/********************************************************************** 2Copyright (c) 2009 Google Inc. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15**********************************************************************/ 16package com.google.appengine.datanucleus.bugs.jdo; 17 18import com.google.appengine.api.datastore.DatastoreService; 19import com.google.appengine.api.datastore.DatastoreServiceFactory; 20import com.google.appengine.datanucleus.DatastoreManager; 21import com.google.appengine.datanucleus.bugs.DatastoreTestCase; 22import com.google.appengine.datanucleus.EntityUtils; 23import com.google.appengine.datanucleus.Utils; 24 25import org.datanucleus.api.jdo.JDOPersistenceManager; 26import org.datanucleus.metadata.MetaDataManager; 27import org.datanucleus.ExecutionContext; 28import org.datanucleus.util.NucleusLogger; 29 30import java.util.Map; 31 32import javax.jdo.JDOHelper; 33import javax.jdo.PersistenceManager; 34import javax.jdo.PersistenceManagerFactory; 35 36/** 37 * Base testcase for tests that need a {@link PersistenceManagerFactory}. 38 * 39 * @author Max Ross <maxr@google.com> 40 */ 41public class JDOBugTestCase extends DatastoreTestCase { 42 43 private static 44 ThreadLocal<Map<PersistenceManagerFactoryName, PersistenceManagerFactory>> pmfCache = 45 new ThreadLocal<Map<PersistenceManagerFactoryName, PersistenceManagerFactory>>() { 46 @Override 47 protected Map<PersistenceManagerFactoryName, PersistenceManagerFactory> initialValue() { 48 return Utils.newHashMap(); 49 } 50 }; 51 52 protected PersistenceManagerFactory pmf; 53 protected PersistenceManager pm; 54 55 protected DatastoreService ds; 56 57 @Override 58 protected void setUp() throws Exception { 59 super.setUp(); 60 ds = DatastoreServiceFactory.getDatastoreService(); 61 pmf = pmfCache.get().get(getPersistenceManagerFactoryName()); 62 if (pmf == null) { 63 pmf = JDOHelper.getPersistenceManagerFactory(getPersistenceManagerFactoryName().name()); 64 if (cacheManagers()) { 65 pmfCache.get().put(getPersistenceManagerFactoryName(), pmf); 66 } 67 } 68 pm = pmf.getPersistenceManager(); 69 } 70 71 public enum PersistenceManagerFactoryName { transactional, nontransactional } 72 73 /** 74 * By default we use a datasource that requires txns. 75 * Override this if your test needs to use a different instance. 76 */ 77 protected PersistenceManagerFactoryName getPersistenceManagerFactoryName() { 78 return PersistenceManagerFactoryName.transactional; 79 } 80 81 @Override 82 protected void tearDown() throws Exception { 83 try { 84 if (!pm.isClosed()) { 85 if (pm.currentTransaction().isActive()) { 86 pm.currentTransaction().rollback(); 87 } 88 pm.close(); 89 } 90 pm = null; 91 // see if anybody closed any of our pmfs and if so just remove them from the cache - 92 // we'll rebuild it the next time it's needed. 93 for (Map.Entry<PersistenceManagerFactoryName, PersistenceManagerFactory> entry : pmfCache.get().entrySet()) { 94 if (entry.getValue().isClosed()) { 95 pmfCache.get().remove(entry.getKey()); 96 } 97 } 98 if (!cacheManagers() && !pmf.isClosed()) { 99 pmf.close(); 100 } 101 pmf = null; 102 } finally { 103 super.tearDown(); 104 } 105 } 106 107 108 protected void beginTxn() { 109 pm.currentTransaction().begin(); 110 } 111 112 protected void commitTxn() { 113 pm.currentTransaction().commit(); 114 } 115 116 protected void rollbackTxn() { 117 pm.currentTransaction().rollback(); 118 } 119 120 protected <T> T makePersistentInTxn(T obj, StartEnd startEnd) { 121 boolean success = false; 122 NucleusLogger.GENERAL.info(">> JDOTestCase.makePersistentInTxn"); 123 NucleusLogger.GENERAL.info(">> test START"); 124 startEnd.start(); 125 try { 126 NucleusLogger.GENERAL.info(">> test makePersistent"); 127 pm.makePersistent(obj); 128 NucleusLogger.GENERAL.info(">> test END"); 129 startEnd.end(); 130 success = true; 131 } finally { 132 if (!success && pm.currentTransaction().isActive()) { 133 NucleusLogger.GENERAL.info(">> test ROLLBACK"); 134 rollbackTxn(); 135 } 136 } 137 return obj; 138 } 139 140 protected void switchDatasource(PersistenceManagerFactoryName name) { 141 switchDatasource(null, name); 142 } 143 144 protected void switchDatasource(Map<String, String> props, PersistenceManagerFactoryName name) { 145 if (!pm.isClosed()) { 146 pm.close(); 147 } 148 if (!cacheManagers() && !pmf.isClosed()) { 149 pmf.close(); 150 } 151 if (props == null) { 152 pmf = JDOHelper.getPersistenceManagerFactory(name.name()); 153 } else { 154 pmf = JDOHelper.getPersistenceManagerFactory(props, name.name()); 155 } 156 pm = pmf.getPersistenceManager(); 157 } 158 159 @SuppressWarnings("deprecation") 160 protected int countForClass(Class<?> clazz) { 161 String kind = kindForClass(clazz); 162 return ds.prepare( 163 new com.google.appengine.api.datastore.Query(kind)).countEntities(); 164 } 165 166 protected String kindForClass(Class<?> clazz) { 167 ExecutionContext om = getExecutionContext(); 168 MetaDataManager mdm = om.getMetaDataManager(); 169 return EntityUtils.determineKind( 170 mdm.getMetaDataForClass(clazz, om.getClassLoaderResolver()), om); 171 } 172 173 protected String kindForObject(Object obj) { 174 return kindForClass(obj.getClass()); 175 } 176 177 protected ExecutionContext getExecutionContext() { 178 return ((JDOPersistenceManager)pm).getExecutionContext(); 179 } 180 181 private boolean cacheManagers() { 182 return !Boolean.valueOf(System.getProperty("do.not.cache.managers")); 183 } 184 185 interface StartEnd { 186 void start(); 187 void end(); 188 PersistenceManagerFactoryName getPmfName(); 189 } 190 191 public final StartEnd TXN_START_END = new StartEnd() { 192 public void start() { 193 beginTxn(); 194 } 195 196 public void end() { 197 commitTxn(); 198 } 199 200 public PersistenceManagerFactoryName getPmfName() { 201 return PersistenceManagerFactoryName.transactional; 202 } 203 }; 204 205 public final StartEnd NEW_PM_START_END = new StartEnd() { 206 public void start() { 207 if (pm.isClosed()) { 208 pm = pmf.getPersistenceManager(); 209 } 210 } 211 212 public void end() { 213 pm.close(); 214 } 215 216 public PersistenceManagerFactoryName getPmfName() { 217 return PersistenceManagerFactoryName.nontransactional; 218 } 219 }; 220 221 protected DatastoreManager getStoreManager() { 222 return (DatastoreManager) getExecutionContext().getStoreManager(); 223 } 224}