Refactor PersistenceTestCase to AbstractCachedEMFTestCase and AbstractPersistenceTestCase.

Deprecate old class to allow submodules to compile (can be removed after maven repos is updated).

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@804331 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael Dick 2009-08-14 19:28:39 +00:00
parent befee1a50b
commit 89a7f53db0
19 changed files with 679 additions and 17 deletions

View File

@ -30,6 +30,7 @@ import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.persistence.OpenJPAEntityManager;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
import org.apache.openjpa.persistence.OpenJPAPersistence;
import org.apache.openjpa.persistence.test.AbstractCachedEMFTestCase;
import org.apache.openjpa.persistence.test.PersistenceTestCase;
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
@ -77,7 +78,7 @@ import org.apache.openjpa.persistence.test.SingleEMFTestCase;
*
* @version $Rev$ $Date$
*/
public class TestConstraints extends PersistenceTestCase {
public class TestConstraints extends AbstractCachedEMFTestCase {
private static OpenJPAEntityManagerFactorySPI emf = null;

View File

@ -28,11 +28,12 @@ import javax.validation.Validation;
import org.apache.openjpa.persistence.OpenJPAEntityManager;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
import org.apache.openjpa.persistence.OpenJPAPersistence;
import org.apache.openjpa.persistence.test.AbstractCachedEMFTestCase;
import org.apache.openjpa.persistence.test.AllowFailure;
import org.apache.openjpa.persistence.test.PersistenceTestCase;
public class TestMappedSuper extends PersistenceTestCase {
public class TestMappedSuper extends AbstractCachedEMFTestCase {
/*
* Verify constraints defined via XML on a mapped superclass are validated.

View File

@ -32,6 +32,7 @@ import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.persistence.OpenJPAEntityManager;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
import org.apache.openjpa.persistence.OpenJPAPersistence;
import org.apache.openjpa.persistence.test.AbstractCachedEMFTestCase;
import org.apache.openjpa.persistence.test.PersistenceTestCase;
/**
@ -56,7 +57,7 @@ import org.apache.openjpa.persistence.test.PersistenceTestCase;
*
* @version $Rev$ $Date$
*/
public class TestValidationGroups extends PersistenceTestCase {
public class TestValidationGroups extends AbstractCachedEMFTestCase {
/**
* 1a) verify validation occurs using the default validation groups

View File

@ -30,11 +30,12 @@ import org.apache.openjpa.persistence.JPAFacadeHelper;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
import org.apache.openjpa.persistence.query.NamedQueryEntity;
import org.apache.openjpa.persistence.simple.AllFieldTypes;
import org.apache.openjpa.persistence.test.AbstractCachedEMFTestCase;
import org.apache.openjpa.persistence.test.PersistenceTestCase;
import org.apache.openjpa.lib.log.Log;
public class TestCacheMarshallerEndToEnd
extends PersistenceTestCase {
extends AbstractCachedEMFTestCase {
private static final Object[] STORE_PROPS = new Object[] {
"openjpa.CacheMarshallers",

View File

@ -31,12 +31,13 @@ import org.apache.openjpa.lib.util.BytecodeWriter;
import org.apache.openjpa.lib.util.J2DoPrivHelper;
import org.apache.openjpa.lib.util.Options;
import org.apache.openjpa.meta.MetaDataRepository;
import org.apache.openjpa.persistence.test.AbstractCachedEMFTestCase;
import org.apache.openjpa.persistence.test.PersistenceTestCase;
import serp.bytecode.BCClass;
import serp.bytecode.Project;
public class TestEnhancementWithMultiplePUs
extends PersistenceTestCase {
extends AbstractCachedEMFTestCase {
public void testExplicitEnhancementWithClassNotInFirstPU()
throws ClassNotFoundException {

View File

@ -23,13 +23,14 @@ import java.util.Map;
import java.util.Collections;
import javax.persistence.Persistence;
import org.apache.openjpa.persistence.test.AbstractCachedEMFTestCase;
import org.apache.openjpa.persistence.test.PersistenceTestCase;
import org.apache.openjpa.persistence.OpenJPAPersistence;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
import org.apache.openjpa.persistence.JPAFacadeHelper;
public class TestSJVMRemoteCommitProvider
extends PersistenceTestCase {
extends AbstractCachedEMFTestCase {
private OpenJPAEntityManagerFactorySPI emf1;
private OpenJPAEntityManagerFactorySPI emf2;

View File

@ -26,12 +26,13 @@ import org.apache.openjpa.jdbc.writebehind.entities.SimpleNonGeneratedIdEntity;
import org.apache.openjpa.jdbc.writebehind.entities.SimpleTableGeneratedIdEntity;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
import org.apache.openjpa.persistence.test.AbstractCachedEMFTestCase;
import org.apache.openjpa.persistence.test.PersistenceTestCase;
import org.apache.openjpa.writebehind.WriteBehindCache;
import org.apache.openjpa.writebehind.WriteBehindCacheManager;
import org.apache.openjpa.writebehind.WriteBehindCallback;
public abstract class AbstractWriteBehindTestCase extends PersistenceTestCase {
public abstract class AbstractWriteBehindTestCase extends AbstractCachedEMFTestCase {
protected static Object[] writeBehindProps =
new Object[] {
"openjpa.DataCache", "true",

View File

@ -29,10 +29,11 @@ import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.persistence.JPAFacadeHelper;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
import org.apache.openjpa.persistence.query.SimpleEntity;
import org.apache.openjpa.persistence.test.AbstractCachedEMFTestCase;
import org.apache.openjpa.persistence.test.PersistenceTestCase;
public class TestDynamicClassRegistration
extends PersistenceTestCase {
extends AbstractCachedEMFTestCase {
private OpenJPAEntityManagerFactorySPI emf;

View File

@ -20,10 +20,11 @@ package org.apache.openjpa.meta;
import javax.persistence.EntityManagerFactory;
import org.apache.openjpa.persistence.test.AbstractCachedEMFTestCase;
import org.apache.openjpa.persistence.test.PersistenceTestCase;
import org.apache.openjpa.persistence.JPAFacadeHelper;
public class TestMetaDataInheritanceComparator extends PersistenceTestCase {
public class TestMetaDataInheritanceComparator extends AbstractCachedEMFTestCase {
public void testInheritanceComparatorWithBase() {
inheritanceComparatorHelper(true);

View File

@ -22,10 +22,11 @@ import org.apache.openjpa.conf.Compatibility;
import org.apache.openjpa.conf.Specification;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
import org.apache.openjpa.persistence.OpenJPAPersistence;
import org.apache.openjpa.persistence.test.AbstractCachedEMFTestCase;
import org.apache.openjpa.persistence.test.PersistenceTestCase;
public class TestSpecCompatibilityOptions
extends PersistenceTestCase {
extends AbstractCachedEMFTestCase {
/*
* Verifies compatibility options and spec level are appropriate

View File

@ -28,9 +28,10 @@ import javax.persistence.Query;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
import org.apache.openjpa.persistence.StoreCache;
import org.apache.openjpa.persistence.test.AbstractCachedEMFTestCase;
import org.apache.openjpa.persistence.test.PersistenceTestCase;
public class TestCacheExclusions extends PersistenceTestCase {
public class TestCacheExclusions extends AbstractCachedEMFTestCase {
private OpenJPAEntityManagerFactorySPI emf = null;

View File

@ -24,9 +24,10 @@ import java.util.Map;
import javax.persistence.EntityManager;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
import org.apache.openjpa.persistence.test.AbstractCachedEMFTestCase;
import org.apache.openjpa.persistence.test.PersistenceTestCase;
public class TestEntitiesAsKeys extends PersistenceTestCase {
public class TestEntitiesAsKeys extends AbstractCachedEMFTestCase {
OpenJPAEntityManagerFactorySPI emf =
createEMF(MapHolder.class, MapEmbeddable.class, "openjpa.DataCache", "true", "openjpa.RemoteCommitProvider",

View File

@ -21,9 +21,10 @@ package org.apache.openjpa.persistence.jdbc.annotations;
import javax.persistence.PersistenceException;
import javax.persistence.EntityManagerFactory;
import org.apache.openjpa.persistence.test.AbstractCachedEMFTestCase;
import org.apache.openjpa.persistence.test.PersistenceTestCase;
public class TestMixedAccess extends PersistenceTestCase {
public class TestMixedAccess extends AbstractCachedEMFTestCase {
public void testMixedAccessEntityError() {
try {

View File

@ -44,9 +44,10 @@ import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
import org.apache.openjpa.persistence.OpenJPAPersistence;
import org.apache.openjpa.persistence.jdbc.XMLPersistenceMappingParser;
import org.apache.openjpa.persistence.jdbc.XMLPersistenceMappingSerializer;
import org.apache.openjpa.persistence.test.AbstractCachedEMFTestCase;
import org.apache.openjpa.persistence.test.PersistenceTestCase;
public class TestOrderColumnXML extends PersistenceTestCase {
public class TestOrderColumnXML extends AbstractCachedEMFTestCase {
/*
* Validates the use of the nullable attribute on OrderColumn through

View File

@ -0,0 +1,84 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.persistence.test;
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
/**
* Testcase which caches EntityManagerFactories based on the persistence unit name and the properties provided at
* runtime.
*
*/
public abstract class AbstractCachedEMFTestCase extends AbstractPersistenceTestCase {
private static FixedMap<EMFKey, OpenJPAEntityManagerFactorySPI> _emfs =
new FixedMap<EMFKey, OpenJPAEntityManagerFactorySPI>();
/**
* Create an entity manager factory for persistence unit <code>pu</code>. Put {@link #CLEAR_TABLES} in this list to
* tell the test framework to delete all table contents before running the tests.
*
* @param props
* list of persistent types used in testing and/or configuration values in the form
* key,value,key,value...
*/
protected OpenJPAEntityManagerFactorySPI createNamedEMF(String pu, Object... props) {
Map<String, Object> map = getPropertiesMap(props);
EMFKey key = new EMFKey(pu, map);
OpenJPAEntityManagerFactorySPI oemf = _emfs.get(key);
if (_fresh || oemf == null || !oemf.isOpen()) {
oemf = super.createNamedEMF(pu, props);
if (!_fresh) {
_emfs.put(key, oemf);
}
}
_fresh = false;
return oemf;
}
private static class FixedMap<K, V> extends LinkedHashMap<K, V> {
private static final long serialVersionUID = -3153852097468390779L;
public boolean removeEldestEntry(Map.Entry<K, V> entry) {
return this.size() > 2;
}
}
private static class EMFKey {
final String unit;
final Map<String, Object> config;
EMFKey(String unit, Map<String, Object> config) {
this.unit = unit;
this.config = config;
}
public int hashCode() {
return (unit != null ? unit.hashCode() : 0) + config.hashCode();
}
public boolean equals(Object other) {
EMFKey that = (EMFKey) other;
return (unit != null ? unit.equals(that.unit) : that.unit == null) && config.equals(that.config);
}
}
}

View File

@ -0,0 +1,563 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.persistence.test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import junit.framework.TestCase;
import junit.framework.TestResult;
import org.apache.openjpa.kernel.AbstractBrokerFactory;
import org.apache.openjpa.kernel.Broker;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.persistence.JPAFacadeHelper;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
/**
* Base class for Persistence TestCases. This class contains utility methods but does not maintain an EntityManager or
* EntityManagerFactory - these tasks are left for subclasses to handle.
*/
public abstract class AbstractPersistenceTestCase extends TestCase {
public static final String FRESH_EMF = "Creates new EntityManagerFactory";
public static final String RETAIN_DATA = "Retain data after test run";
private boolean retainDataOnTearDown;
protected boolean _fresh = false;
public static final String ALLOW_FAILURE_LOG = "log";
public static final String ALLOW_FAILURE_IGNORE = "ignore";
public static final String ALLOW_FAILURE_SYS_PROP = "tests.openjpa.allowfailure";
private static String allowFailureConfig = System.getProperty(ALLOW_FAILURE_SYS_PROP, ALLOW_FAILURE_IGNORE);
/**
* Marker object you pass to {@link #setUp} to indicate that the database table rows should be cleared.
*/
protected static final Object CLEAR_TABLES = new Object();
/**
* Marker object you pass to {@link #setUp} to indicate that the database table should be dropped and then
* recreated.
*/
protected static final Object DROP_TABLES = new Object();
/**
* The {@link TestResult} instance for the current test run.
*/
protected TestResult testResult;
/**
* Create an entity manager factory. Put {@link #CLEAR_TABLES} in this list to tell the test framework to delete all
* table contents before running the tests.
*
* @param props
* list of persistent types used in testing and/or configuration values in the form
* key,value,key,value...
*/
protected OpenJPAEntityManagerFactorySPI createEMF(final Object... props) {
return createNamedEMF(getPersistenceUnitName(), props);
}
/**
* The name of the persistence unit that this test class should use by default. This defaults to "test".
*/
protected String getPersistenceUnitName() {
return "test";
}
/**
* Create an entity manager factory for persistence unit <code>pu</code>. Put {@link #CLEAR_TABLES} in this list to
* tell the test framework to delete all table contents before running the tests.
*
* @param props
* list of persistent types used in testing and/or configuration values in the form
* key,value,key,value...
*/
protected OpenJPAEntityManagerFactorySPI createNamedEMF(final String pu, Object... props) {
Map<String, Object> map = getPropertiesMap(props);
OpenJPAEntityManagerFactorySPI oemf = null;
Map<Object, Object> config = new HashMap<Object, Object>(System.getProperties());
config.putAll(map);
oemf = (OpenJPAEntityManagerFactorySPI) Persistence.createEntityManagerFactory(pu, config);
if (oemf == null) {
throw new NullPointerException("Expected an entity manager factory " + "for the persistence unit named: \""
+ pu + "\"");
}
return oemf;
}
protected Map<String, Object> getPropertiesMap(Object... props) {
Map<String, Object> map = new HashMap<String, Object>();
List<Class<?>> types = new ArrayList<Class<?>>();
boolean prop = false;
for (int i = 0; props != null && i < props.length; i++) {
if (props[i] == FRESH_EMF) {
_fresh = true;
continue;
}
if (props[i] == RETAIN_DATA) {
retainDataOnTearDown = true;
continue;
}
if (prop) {
map.put((String) props[i - 1], props[i]);
prop = false;
} else if (props[i] == CLEAR_TABLES) {
map.put("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true,"
+ "SchemaAction='add,deleteTableContents')");
} else if (props[i] == DROP_TABLES) {
map.put("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true,"
+ "SchemaAction='drop,add')");
} else if (props[i] instanceof Class<?>) {
types.add((Class<?>) props[i]);
} else if (props[i] != null) {
prop = true;
}
}
if (!types.isEmpty()) {
StringBuffer buf = new StringBuffer();
for (Class<?> c : types) {
if (buf.length() > 0) {
buf.append(";");
}
buf.append(c.getName());
}
String oldValue =
map.containsKey("openjpa.MetaDataFactory") ? "," + map.get("openjpa.MetaDataFactory").toString() : "";
map.put("openjpa.MetaDataFactory", "jpa(Types=" + buf.toString() + oldValue + ")");
} else {
map.put("openjpa.MetaDataFactory", "jpa");
}
return map;
}
@Override
public void run(TestResult testResult) {
this.testResult = testResult;
super.run(testResult);
}
@Override
public void tearDown() throws Exception {
try {
super.tearDown();
} catch (Exception e) {
// if a test failed, swallow any exceptions that happen
// during tear-down, as these just mask the original problem.
if (testResult.wasSuccessful()) {
throw e;
}
}
}
/**
* Safely close the given factory.
*/
protected boolean closeEMF(EntityManagerFactory emf) {
if (emf == null || !emf.isOpen()) {
return false;
}
closeAllOpenEMs(emf);
emf.close();
return !emf.isOpen();
}
/**
* Closes all open entity managers after first rolling back any open transactions.
*/
protected void closeAllOpenEMs(EntityManagerFactory emf) {
if (emf == null || !emf.isOpen()) {
return;
}
for (Broker b : ((AbstractBrokerFactory) JPAFacadeHelper.toBrokerFactory(emf)).getOpenBrokers()) {
if (b != null && !b.isClosed()) {
EntityManager em = JPAFacadeHelper.toEntityManager(b);
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
em.close();
}
}
}
/**
* Delete all instances of the given types using bulk delete queries, but do not close any open entity managers.
*/
protected void clear(EntityManagerFactory emf, Class<?>... types) {
if (emf == null || types.length == 0) {
return;
}
List<ClassMetaData> metas = new ArrayList<ClassMetaData>(types.length);
for (Class<?> c : types) {
ClassMetaData meta = JPAFacadeHelper.getMetaData(emf, c);
if (meta != null) {
metas.add(meta);
}
}
clear(emf, false, metas.toArray(new ClassMetaData[metas.size()]));
}
/**
* Delete all instances of the persistent types registered with the given factory using bulk delete queries, after
* first closing all open entity managers (and rolling back any open transactions).
*/
protected void clear(EntityManagerFactory emf) {
if (emf == null) {
return;
}
clear(emf, true, ((OpenJPAEntityManagerFactorySPI) emf).getConfiguration().getMetaDataRepositoryInstance()
.getMetaDatas());
}
/**
* Delete all instances of the given types using bulk delete queries.
*
* @param emf
* The EntityManagerFactory to use. A new EntityManager will be created from this EMF and used to execute
* bulk updates.
* @param closeEMs
* Whether any open EMs should be closed
* @param types
* the types that will be cleared.
*/
private void clear(EntityManagerFactory emf, boolean closeEMs, ClassMetaData... types) {
if (emf == null || types.length == 0) {
return;
}
// prevent deadlock by closing the open entity managers
// and rolling back any open transactions
// before issuing delete statements on a new entity manager.
if (closeEMs) {
closeAllOpenEMs(emf);
}
if (retainDataOnTearDown) {
return;
}
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
for (ClassMetaData meta : types) {
if (!meta.isMapped() || meta.isEmbeddedOnly()
|| Modifier.isAbstract(meta.getDescribedType().getModifiers())
&& !isBaseManagedInterface(meta, types)) {
continue;
}
em.createQuery("DELETE FROM " + meta.getTypeAlias() + " o").executeUpdate();
}
em.getTransaction().commit();
em.close();
}
/**
* Return the entity name for the given type.
*/
protected String entityName(EntityManagerFactory emf, Class<?> c) {
ClassMetaData meta = JPAFacadeHelper.getMetaData(emf, c);
return (meta == null) ? null : meta.getTypeAlias();
}
/**
* Determines if the class associated with the provided {@link ClassMetaData} is a managed interface and does not
* extend another managed interface.
*
* @param meta
* {@link ClassMetaData} for the class to examine
* @param types
* array of class meta data for persistent types
* @return true if the {@link ClassMetaData} is for an interface and the interface does not extend another managed
* interface
*/
private boolean isBaseManagedInterface(ClassMetaData meta, ClassMetaData... types) {
if (Modifier.isInterface(meta.getDescribedType().getModifiers()) && !isExtendedManagedInterface(meta, types)) {
return true;
}
return false;
}
/**
* Determines if the class associated with the provided {@link ClassMetaData} is an interface and if it extends
* another managed interface.
*
* @param meta
* {@link ClassMetaData} for the class to examine
* @param types
* array of class meta data for persistent types
* @return true if the {@link ClassMetaData} is for an interface and the interface extends another managed interface
*/
private boolean isExtendedManagedInterface(ClassMetaData meta, ClassMetaData... types) {
if (!Modifier.isInterface(meta.getDescribedType().getModifiers())) {
return false;
}
// Run through the interface this class extends. If any of them
// are managed/have class metadata, return true.
Class<?>[] ifaces = meta.getDescribedType().getInterfaces();
for (int i = 0; ifaces != null && i < ifaces.length; i++) {
for (ClassMetaData meta2 : types) {
if (ifaces[i].equals(meta2.getDescribedType())) {
return true;
}
}
}
return false;
}
public static void assertNotEquals(Object o1, Object o2) {
if (o1 == o2) {
fail("expected args to be different; were the same instance.");
} else if (o1 == null || o2 == null) {
return;
} else if (o1.equals(o2)) {
fail("expected args to be different; compared equal.");
}
}
/**
* Round-trip a serializable object to bytes.
*/
@SuppressWarnings("unchecked")
public static <T> T roundtrip(T o) throws ClassNotFoundException, IOException {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bytes);
out.writeObject(o);
out.flush();
ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()));
return (T) in.readObject();
}
// ================================================
// Utility methods for exception handling
// ================================================
/**
* Asserts that the given targetType is assignable from given actual Throwable.
*/
protected void assertException(final Throwable actual, Class<?> targetType) {
assertException(actual, targetType, null);
}
/**
* Asserts that the given targetType is assignable from given actual Throwable. Asserts that the nestedType is
* nested (possibly recursively) within the given actual Throwable.
*
* @param actual
* is the actual throwable to be tested
* @param targetType
* is expected type or super type of actual. If null, then the check is omitted.
* @param nestedTargetType
* is expected type of exception nested within actual. If null this search is omitted.
*
*/
protected void assertException(final Throwable actual, Class<?> targetType, Class<?> nestedTargetType) {
assertNotNull(actual);
Class<?> actualType = actual.getClass();
if (targetType != null && !targetType.isAssignableFrom(actualType)) {
actual.printStackTrace();
fail(targetType.getName() + " is not assignable from " + actualType.getName());
}
if (nestedTargetType != null) {
Throwable nested = actual.getCause();
Class<?> nestedActualType = (nested == null) ? null : nested.getClass();
while (nestedActualType != null) {
if (nestedTargetType.isAssignableFrom(nestedActualType)) {
return;
} else {
Throwable next = nested.getCause();
if (next == null || next == nested) {
break;
}
nestedActualType = next.getClass();
nested = next;
}
}
actual.printStackTrace();
fail("No nested type " + nestedTargetType + " in " + actual);
}
}
/**
* Asserts that the given targetType is assignable from given actual Throwable and that the exception message
* contains the specified message or message fragments.
*/
protected void assertExceptionMessage(final Throwable actual, Class<?> targetType, String... messages) {
assertException(actual, targetType, null);
assertMessage(actual, messages);
}
/**
* Assert that each of given keys are present in the message of the given Throwable.
*/
protected void assertMessage(Throwable actual, String... keys) {
if (actual == null || keys == null) {
return;
}
String message = actual.getMessage();
for (String key : keys) {
assertTrue(key + " is not in " + message, message.contains(key));
}
}
public void printException(Throwable t) {
printException(t, 2);
}
public void printException(Throwable t, int tab) {
if (t == null) {
return;
}
for (int i = 0; i < tab * 4; i++) {
System.out.print(" ");
}
String sqlState =
(t instanceof SQLException) ? "(SQLState=" + ((SQLException) t).getSQLState() + ":" + t.getMessage() + ")"
: "";
System.out.println(t.getClass().getName() + sqlState);
if (t.getCause() == t) {
return;
}
printException(t.getCause(), tab + 2);
}
/**
* Overrides to allow tests annotated with @AllowFailure to fail. If the test is in error then the normal pathway is
* executed.
*/
@Override
public void runBare() throws Throwable {
if (!isRunsOnCurrentPlatform()) {
return;
}
runBare(getAllowFailure());
}
protected void runBare(AllowFailure allowFailureAnnotation) throws Throwable {
boolean allowFailureValue = allowFailureAnnotation == null ? false : allowFailureAnnotation.value();
if (allowFailureValue) {
if (ALLOW_FAILURE_IGNORE.equalsIgnoreCase(allowFailureConfig)) {
return; // skip this test
} else {
try {
super.runBare();
} catch (Throwable t) {
if (ALLOW_FAILURE_LOG.equalsIgnoreCase(allowFailureConfig)) {
System.err.println("*** FAILED (but ignored): " + this);
System.err.println("*** Reason : " + allowFailureAnnotation.message());
System.err.println("Stacktrace of failure");
t.printStackTrace();
} else {
throw t;
}
}
}
} else {
super.runBare();
}
}
/**
* Affirms if the test case or the test method is annotated with
*
* @AllowFailure. Method level annotation has higher precedence than Class level annotation.
*/
protected AllowFailure getAllowFailure() {
try {
Method runMethod = getClass().getMethod(getName(), (Class[]) null);
AllowFailure anno = runMethod.getAnnotation(AllowFailure.class);
if (anno != null) {
return anno;
}
} catch (SecurityException e) {
// ignore
} catch (NoSuchMethodException e) {
// ignore
}
return getClass().getAnnotation(AllowFailure.class);
}
/**
* Affirms if either this test has been annotated with @DatabasePlatform and at least one of the specified driver is
* available in the classpath, or no such annotation is used.
*
*/
protected boolean isRunsOnCurrentPlatform() {
DatabasePlatform anno = getClass().getAnnotation(DatabasePlatform.class);
if (anno == null) {
return true;
}
if (anno != null) {
String value = anno.value();
if (value == null || value.trim().length() == 0) {
return true;
}
String[] drivers = value.split("\\,");
for (String driver : drivers) {
try {
Class.forName(driver.trim(), false, Thread.currentThread().getContextClassLoader());
return true;
} catch (Throwable t) {
// ignore
}
}
}
return false;
}
/**
* Determines whether specified platform is the target database platform in use by the test framework.
*
* @param target
* platform name (derby, db2, oracle, etc.)
* @return true if the specified platform matches the platform in use
*/
public boolean isTargetPlatform(String target) {
String url = getPlatform();
return url != null && url.indexOf(target) != -1;
}
/**
* Returns the platform in use by the test framework
*
* @return the database platform
*/
public String getPlatform() {
return System.getProperty("platform", "derby");
}
}

View File

@ -57,7 +57,7 @@ import org.apache.openjpa.persistence.OpenJPAPersistence;
* If a extended test does not want cached EntityManagerFactory
* then it must specify FRESH_EMF as one of the arguments of #setUp(Object[]).
*
*
* @deprecated use AbstractEMFCacheTestCase or AbstractPersistenceTestCase instead
*/
public abstract class PersistenceTestCase
extends TestCase {

View File

@ -37,7 +37,7 @@ import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
*
*/
public abstract class SingleEMFTestCase
extends PersistenceTestCase {
extends AbstractCachedEMFTestCase {
protected OpenJPAEntityManagerFactorySPI emf;

View File

@ -20,11 +20,12 @@ package org.apache.openjpa.persistence.xml;
import javax.persistence.EntityManagerFactory;
import org.apache.openjpa.persistence.test.AbstractCachedEMFTestCase;
import org.apache.openjpa.persistence.test.PersistenceTestCase;
import org.apache.openjpa.persistence.OpenJPAPersistence;
import org.apache.openjpa.enhance.PCEnhancer;
public class TestPersistenceUnitWithoutXSD extends PersistenceTestCase {
public class TestPersistenceUnitWithoutXSD extends AbstractCachedEMFTestCase {
public void testPersistenceUnitWithoutXSD() {
EntityManagerFactory emf = OpenJPAPersistence