Author: steve.ebersole(a)jboss.com
Date: 2006-09-01 14:43:11 -0400 (Fri, 01 Sep 2006)
New Revision: 10408
Modified:
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/TestCase.java
Log:
code cleanup; javadoc
Modified: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/TestCase.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/TestCase.java 2006-09-01
18:42:57 UTC (rev 10407)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/TestCase.java 2006-09-01
18:43:11 UTC (rev 10408)
@@ -7,9 +7,10 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Properties;
import junit.framework.AssertionFailedError;
+import junit.framework.TestResult;
+import junit.framework.TestListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -28,6 +29,7 @@
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.dialect.SybaseDialect;
import org.hibernate.dialect.TimesTenDialect;
+import org.hibernate.dialect.DerbyDialect;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
@@ -41,46 +43,146 @@
private static Dialect dialect;
private static Class lastTestClass;
private org.hibernate.classic.Session session;
-
+
+ public TestCase(String name) {
+ super( name );
+ }
+
+
+ // methods for subclasses to change test environment ~~~~~~~~~~~~~~~~~~~~~~
+
+ /**
+ * Get the mapping resources to be used to build the configuration.
+ * <p/>
+ * Resources should be relative to {@link #getBaseForMappings()}
+ *
+ * @return The mapping resources
+ */
+ protected abstract String[] getMappings();
+
+ /**
+ * The base name for relative mapping resources. The default is
+ * <tt>org/hibernate/test/</tt>
+ *
+ * @return the mapping resource base
+ */
+ protected String getBaseForMappings() {
+ return "org/hibernate/test/";
+ }
+
+ /**
+ * Should the database schema be (re)created
+ *
+ * @return True for auto export (including recreation on test failure).
+ */
protected boolean recreateSchema() {
return true;
}
- public TestCase(String name) {
- super( name );
+ protected boolean dropAfterFailure() {
+ return true;
}
- protected void configure(Configuration cfg) {}
+ /**
+ * Apply any test-specific configuration prior to building the factory.
+ *
+ * @param cfg The configuration which will be used to construct the factory.
+ */
+ protected void configure(Configuration cfg) {
+ }
- private void buildSessionFactory(String[] files) throws Exception {
+ protected boolean overrideCacheStrategy() {
+ return true;
+ }
- if ( getSessions()!=null ) getSessions().close();
+ protected String getCacheConcurrencyStrategy() {
+ return "nonstrict-read-write";
+ }
- setDialect( Dialect.getDialect() );
- if ( ! appliesTo( getDialect() ) ) {
- return;
- }
- try {
+ // methods for subclasses to access environment ~~~~~~~~~~~~~~~~~~~~~~~~~~~
- setCfg( new Configuration() );
+ /**
+ * Get the factory for this test environment.
+ *
+ * @return The factory.
+ */
+ protected SessionFactory getSessions() {
+ return sessions;
+ }
- cfg.addProperties( getExtraProperties() );
+ /**
+ * Get the factory for this test environment, casted to {@link
SessionFactoryImplementor}.
+ * <p/>
+ * Shorthand for ( {@link SessionFactoryImplementor} ) {@link #getSessions()}...
+ *
+ * @return The factory
+ */
+ protected SessionFactoryImplementor sfi() {
+ return ( SessionFactoryImplementor ) getSessions();
+ }
- if( recreateSchema() ) {
- cfg.setProperty(Environment.HBM2DDL_AUTO, "create-drop");
- }
+ protected Dialect getDialect() {
+ return dialect;
+ }
- Configuration cfg2 = getCfg();
+ protected Configuration getCfg() {
+ return cfg;
+ }
- addMappings( files, cfg2 );
+ public org.hibernate.classic.Session openSession() throws HibernateException {
+ session = getSessions().openSession();
+ return session;
+ }
- cfg.setProperty( Environment.CACHE_PROVIDER,
"org.hibernate.cache.HashtableCacheProvider" );
+ public org.hibernate.classic.Session openSession(Interceptor interceptor)
+ throws HibernateException {
+ session = getSessions().openSession(interceptor);
+ return session;
+ }
- configure(cfg);
- if ( getCacheConcurrencyStrategy()!=null ) {
+ // JUnit hooks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ /**
+ * The Hibernate test suite tries to only build the db schema once
+ * per test class (not test case which = instance) hence all the
+ * static vars.
+ * <p/>
+ * Here is the crux of that attempt. We only build a factory when one was
+ * not previously built, or when we start a new test class.
+ *
+ * @throws Exception
+ */
+ protected void setUp() throws Exception {
+ if ( getSessions() == null || lastTestClass != getClass() ) {
+ buildSessionFactory();
+ lastTestClass = getClass();
+ }
+ }
+
+
+ private void buildSessionFactory() throws Exception {
+ if ( getSessions()!=null ) {
+ getSessions().close();
+ }
+
+ TestCase.dialect = Dialect.getDialect();
+ if ( ! appliesTo( getDialect() ) ) {
+ return;
+ }
+
+ try {
+
+ TestCase.cfg = new Configuration();
+ cfg.setProperty( Environment.CACHE_PROVIDER,
"org.hibernate.cache.HashtableCacheProvider" );
+ if( recreateSchema() ) {
+ cfg.setProperty( Environment.HBM2DDL_AUTO, "create-drop" );
+ }
+ addMappings( getMappings(), cfg );
+ configure( cfg );
+
+ if ( getCacheConcurrencyStrategy() != null ) {
Iterator iter = cfg.getClassMappings();
while ( iter.hasNext() ) {
PersistentClass clazz = (PersistentClass) iter.next();
@@ -90,8 +192,12 @@
Property prop = (Property) props.next();
if ( prop.getValue().isSimpleValue() ) {
String type = ( (SimpleValue) prop.getValue() ).getTypeName();
- if ( "blob".equals(type) || "clob".equals(type) ) hasLob =
true;
- if ( Blob.class.getName().equals(type) || Clob.class.getName().equals(type) )
hasLob = true;
+ if ( "blob".equals( type ) || "clob".equals( type ) ) {
+ hasLob = true;
+ }
+ if ( Blob.class.getName().equals( type ) || Clob.class.getName().equals( type ) )
{
+ hasLob = true;
+ }
}
}
if ( !hasLob && !clazz.isInherited() && overrideCacheStrategy() ) {
@@ -101,7 +207,6 @@
);
}
}
-
iter = cfg.getCollectionMappings();
while ( iter.hasNext() ) {
Collection coll = (Collection) iter.next();
@@ -110,22 +215,24 @@
getCacheConcurrencyStrategy()
);
}
-
}
- setSessions( cfg2.buildSessionFactory( /*new TestInterceptor()*/ ) );
-
+ // make sure we use the same dialect...
+ cfg.setProperty( Environment.DIALECT, TestCase.dialect.getClass().getName() );
+ TestCase.sessions = cfg.buildSessionFactory();
afterSessionFactoryBuilt();
}
- catch (Exception e) {
+ catch ( Exception e ) {
e.printStackTrace();
throw e;
}
}
protected void addMappings(String[] files, Configuration cfg) {
- for (int i=0; i<files.length; i++) {
- if ( !files[i].startsWith("net/") ) files[i] = getBaseForMappings() +
files[i];
+ for ( int i = 0; i < files.length; i++ ) {
+ if ( !files[i].startsWith( "net/" ) ) {
+ files[i] = getBaseForMappings() + files[i];
+ }
cfg.addResource( files[i], TestCase.class.getClassLoader() );
}
}
@@ -135,146 +242,120 @@
// when SF (re)built...
}
- protected boolean overrideCacheStrategy() {
- return true;
- }
-
- protected String getBaseForMappings() {
- return "org/hibernate/test/";
- }
-
- public String getCacheConcurrencyStrategy() {
- return "nonstrict-read-write";
- }
-
- protected void setUp() throws Exception {
- if ( getSessions()==null || lastTestClass!=getClass() ) {
- buildSessionFactory( getMappings() );
- lastTestClass = getClass();
- }
- }
-
protected void runTest() throws Throwable {
- final boolean stats = ( (SessionFactoryImplementor) sessions
).getStatistics().isStatisticsEnabled();
+ final boolean stats = sessions.getStatistics().isStatisticsEnabled();
try {
- if (stats) sessions.getStatistics().clear();
+ if ( stats ) {
+ sessions.getStatistics().clear();
+ }
super.runTest();
- if (stats) sessions.getStatistics().logSummary();
+ if ( stats ) {
+ sessions.getStatistics().logSummary();
+ }
- if ( session!=null && session.isOpen() ) {
- if ( session.isConnected() ) session.connection().rollback();
+ if ( session != null && session.isOpen() ) {
+ if ( session.isConnected() ) {
+ session.connection().rollback();
+ }
session.close();
session = null;
- fail("unclosed session");
+ fail( "unclosed session" );
}
else {
- session=null;
-
- //assertAllDataRemoved();
-
+ session = null;
}
+ assertAllDataRemoved();
}
- catch (Throwable e) {
+ catch ( Throwable e ) {
try {
- if ( session!=null && session.isOpen() ) {
- if ( session.isConnected() ) session.connection().rollback();
+ if ( session != null && session.isOpen() ) {
+ if ( session.isConnected() ) {
+ session.connection().rollback();
+ }
session.close();
}
}
- catch (Exception ignore) {}
+ catch ( Exception ignore ) {
+ }
try {
- if ( dropAfterFailure() && sessions!=null ) {
+ if ( dropAfterFailure() && sessions != null ) {
sessions.close();
- sessions=null;
+ sessions = null;
}
}
- catch (Exception ignore) {}
+ catch ( Exception ignore ) {
+ }
throw e;
}
}
+ public void runBare() throws Throwable {
+ String sysPropName = "hibernate.test.validatefailureexpected";
+ assertNotNull( getName() );
+ if ( Boolean.getBoolean( sysPropName ) ) {
+ if ( getName().endsWith( "FailureExpected" ) ) {
+ Throwable t = null;
+ try {
+ super.runBare();
+ }
+ catch ( Throwable afe ) {
+ t = afe;
+ }
+ if ( t == null ) {
+ fail( "Test where marked as FailureExpected, but did not fail!" );
+ }
+ else {
+ reportSkip( "ignoring *FailuredExpected methods", "Failed with:
" + t.toString() );
+ }
+ }
+ else {
+ super.runBare();
+ }
+ }
+ else {
+ super.runBare();
+ }
+ }
+
protected void assertAllDataRemoved() {
- if(!recreateSchema()) {
+ if ( !recreateSchema() ) {
return; // no tables were created...
}
-
- Session tmpSession = openSession();
- List list = tmpSession.createQuery( "from java.lang.Object" ).list();
-
- StringBuffer sb = new StringBuffer();
- Map items = new HashMap();
-
- if(!list.isEmpty()) {
- for (Iterator iter = list.iterator(); iter.hasNext();) {
- Object element = iter.next();
- Integer l = (Integer) items.get(tmpSession.getEntityName( element ));
- if(l==null) {
- l = new Integer(0);
+ if ( Boolean.getBoolean( "hibernate.test.skipCleanupValidation" ) ) {
+ return;
+ }
+
+ Session tmpSession = sessions.openSession();
+ try {
+ List list = tmpSession.createQuery( "from java.lang.Object" ).list();
+
+ Map items = new HashMap();
+ if ( !list.isEmpty() ) {
+ for ( Iterator iter = list.iterator(); iter.hasNext(); ) {
+ Object element = iter.next();
+ Integer l = ( Integer ) items.get( tmpSession.getEntityName( element ) );
+ if ( l == null ) {
+ l = new Integer( 0 );
+ }
+ l = new Integer( l.intValue() + 1 );
+ items.put( tmpSession.getEntityName( element ), l );
+ System.out.println( "Data left: " + element );
}
- l = new Integer(l.intValue()+1);
- items.put(tmpSession.getEntityName( element ), l);
- System.out.println("Data left: " + element);
+ fail( "Data is left in the database: " + items.toString() );
}
+ }
+ finally {
try {
tmpSession.close();
- } finally {
- fail("Data is left in the database: " + items.toString() );
}
- } else {
- tmpSession.close();
+ catch( Throwable t ) {
+ // intentionally empty
+ }
}
}
- protected boolean dropAfterFailure() {
- return true;
- }
-
- public org.hibernate.classic.Session openSession() throws HibernateException {
- session = getSessions().openSession();
- return session;
- }
-
- public org.hibernate.classic.Session openSession(Interceptor interceptor)
- throws HibernateException {
- session = getSessions().openSession(interceptor);
- return session;
- }
-
- protected abstract String[] getMappings();
-
- private void setSessions(SessionFactory sessions) {
- TestCase.sessions = sessions;
- }
-
- protected SessionFactory getSessions() {
- return sessions;
- }
-
- private void setDialect(Dialect dialect) {
- TestCase.dialect = dialect;
- }
-
- protected Dialect getDialect() {
- return dialect;
- }
-
- protected static void setCfg(Configuration cfg) {
- TestCase.cfg = cfg;
- }
-
- protected static Configuration getCfg() {
- return cfg;
- }
-
- /**
- * @deprecated
- */
- public Properties getExtraProperties() {
- return new Properties();
- }
-
public static void assertElementTypeAssignability(java.util.Collection collection, Class
clazz) throws AssertionFailedError {
Iterator itr = collection.iterator();
while ( itr.hasNext() ) {
@@ -291,6 +372,19 @@
}
}
+
+ // test skipping ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ protected static final Log SKIP_LOG =
LogFactory.getLog("org.hibernate.test.SKIPPED");
+
+ public String fullTestName() {
+ return this.getName() + " (" + this.getClass().getName() + ")";
+ }
+
+ protected void reportSkip(String reason, String testDescription) {
+ SKIP_LOG.warn( "*** skipping [" + fullTestName() + "] - " +
testDescription + " : " + reason, new Exception() );
+ }
+
/**
* Intended to indicate that this test class as a whole is intended for
* a dialect or series of dialects. Skips here (appliesTo = false), therefore
@@ -303,8 +397,18 @@
return true;
}
- protected static final Log SKIP_LOG =
LogFactory.getLog("org.hibernate.test.SKIPPED");
-
+ /**
+ * Is connection at least read committed?
+ * <p/>
+ * Not, that this skip check relies on the JDBC driver reporting
+ * the true isolation level correctly. HSQLDB, for example, will
+ * report whatever you specify as the isolation
+ * (Connection.setTransationIsolation()), even though it only supports
+ * read-uncommitted.
+ *
+ * @param scenario text description of the scenario being tested.
+ * @return true if read-committed isolation is maintained.
+ */
protected boolean readCommittedIsolationMaintained(String scenario) {
int isolation = java.sql.Connection.TRANSACTION_READ_UNCOMMITTED;
Session testSession = null;
@@ -315,9 +419,9 @@
catch( Throwable ignore ) {
}
finally {
- if ( session != null ) {
+ if ( testSession != null ) {
try {
- session.close();
+ testSession.close();
}
catch( Throwable ignore ) {
}
@@ -332,33 +436,86 @@
}
}
- protected boolean dialectSupportsEmptyInList(String testdescription) {
- return reportSkip( "Dialect does not support SQL: \'x in ()\'.",
testdescription, dialectIsNot(new Class[] {
- Oracle9Dialect.class,
- MySQLDialect.class,
- DB2Dialect.class,
- HSQLDialect.class,
- SQLServerDialect.class,
- SybaseDialect.class,
- PostgreSQLDialect.class,
- TimesTenDialect.class
- } ));
+ /**
+ * Does the db/dialect support using a column's physical name in the order-by
clause
+ * even after it has been aliased in the select clause. This is not actually
+ * required by the SQL spec, although virtually ever DB in the world supports this
+ * (the most glaring omission here being IBM-variant DBs ala DB2 and Derby).
+ *
+ * @param testDescription description of the scenario being tested.
+ * @return true if is allowed
+ */
+ protected boolean allowsPhysicalColumnNameInOrderby(String testDescription) {
+ if ( DB2Dialect.class.isInstance( getDialect() ) ) {
+ //
https://issues.apache.org/jira/browse/DERBY-1624
+ reportSkip( "Dialect does not support physical column name in order-by clause
after it is aliased", testDescription );
+ return false;
+ }
+ return true;
}
- protected boolean dialectIsCaseSensitive(String testdescription) {
- // MySQL and SQLServer is case insensitive on strings (at least in default
installation)
- return reportSkip( "Dialect is case sensitive. ", testdescription,
dialectIsNot(new Class[] { MySQLDialect.class, SQLServerDialect.class }));
+ /**
+ * Does the db/dialect support using a column's physical name in the having clause
+ * even after it has been aliased in the select/group-by clause. This is not actually
+ * required by the SQL spec, although virtually ever DB in the world supports this.
+ *
+ * @param testDescription description of the scenario being tested.
+ * @return true if is allowed
+ */
+ protected boolean allowsPhysicalColumnNameInHaving(String testDescription) {
+ // I only *know* of this being a limitation on Derby, although I highly suspect
+ // it is a limitation on any IBM/DB2 variant
+ if ( DerbyDialect.class.isInstance( getDialect() ) ) {
+ //
https://issues.apache.org/jira/browse/DERBY-1624
+ reportSkip( "Dialect does not support physical column name in having clause after
it is aliased", testDescription );
+ return false;
+ }
+ return true;
}
- protected boolean reportSkip(String reason, String testDescription, boolean canDoIt) {
+ /**
+ * Does the db/dialect support empty lists in the IN operator?
+ * <p/>
+ * For example, is "... a.b IN () ..." supported?
+ *
+ * @param testDescription description of the scenario being tested.
+ * @return true if is allowed
+ */
+ protected boolean dialectSupportsEmptyInList(String testDescription) {
+ boolean canDoIt = dialectIsNot(
+ new Class[] {
+ Oracle9Dialect.class,
+ MySQLDialect.class,
+ DB2Dialect.class,
+ HSQLDialect.class,
+ SQLServerDialect.class,
+ SybaseDialect.class,
+ PostgreSQLDialect.class,
+ TimesTenDialect.class
+ }
+ );
+
if ( !canDoIt ) {
- reportSkip( reason, testDescription );
+ reportSkip( "Dialect does not support SQL: \'x in ()\'.",
testDescription );
}
return canDoIt;
}
- protected void reportSkip(String reason, String testDescription) {
- SKIP_LOG.warn( "*** skipping [" + fullTestName() + "] - " +
testDescription + " : " + reason, new Exception() );
+ /**
+ * Is the db/dialect sensitive in terms of string comparisons?
+ * @param testDescription description of the scenario being tested.
+ * @return true if sensitive
+ */
+ protected boolean dialectIsCaseSensitive(String testDescription) {
+ // MySQL and SQLServer is case insensitive on strings (at least in default
installation)
+ boolean canDoIt = dialectIsNot(
+ new Class[] { MySQLDialect.class, SQLServerDialect.class }
+ );
+
+ if ( !canDoIt ) {
+ reportSkip( "Dialect is case sensitive. ", testDescription );
+ }
+ return canDoIt;
}
private boolean dialectIsNot(Class[] dialectClasses) {
@@ -371,35 +528,4 @@
return true;
}
- public String fullTestName() {
- return this.getName() + " (" + this.getClass().getName() + ")";
- }
-
- protected SessionFactoryImplementor sfi() {
- return ( SessionFactoryImplementor ) getSessions();
- }
-
- public void runBare() throws Throwable {
- assertNotNull(getName());
- String string = "hibernate.test.validatefailureexpected";
- if(Boolean.getBoolean( string )) {
- if(getName().endsWith( "FailureExpected" ) ) {
- Throwable t = null;
- try {
- super.runBare();
- } catch(Throwable afe) {
- t = afe;
- }
- if(t==null) {
- fail("Test where marked as FailureExpected, but did not fail!");
- } else {
- reportSkip( "ignoring *FailuredExpected methods", "Failed with:
" + t.toString() );
- }
- } else {
- super.runBare();
- }
- } else {
- super.runBare();
- }
- }
}
\ No newline at end of file