Author: steve.ebersole(a)jboss.com
Date: 2006-09-01 14:42:57 -0400 (Fri, 01 Sep 2006)
New Revision: 10407
Modified:
trunk/Hibernate3/test/org/hibernate/test/TestCase.java
Log:
code cleanup; javadoc
Modified: trunk/Hibernate3/test/org/hibernate/test/TestCase.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/TestCase.java 2006-09-01 18:41:02 UTC (rev
10406)
+++ trunk/Hibernate3/test/org/hibernate/test/TestCase.java 2006-09-01 18:42:57 UTC (rev
10407)
@@ -7,7 +7,6 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Properties;
import junit.framework.AssertionFailedError;
@@ -43,45 +42,145 @@
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();
@@ -102,7 +201,6 @@
);
}
}
-
iter = cfg.getCollectionMappings();
while ( iter.hasNext() ) {
Collection coll = (Collection) iter.next();
@@ -111,22 +209,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() );
}
}
@@ -136,66 +236,51 @@
// when SF (re)built...
}
- protected boolean overrideCacheStrategy() {
- return true;
- }
-
- protected String getBaseForMappings() {
- return "org/hibernate/test/";
- }
-
- public String getCacheConcurrencyStrategy() {
- return "nonstrict-read-write";
- }
-
- protected SessionFactoryImplementor sfi() {
- return ( SessionFactoryImplementor ) getSessions();
- }
-
- 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;
}
}
@@ -232,84 +317,39 @@
if ( !recreateSchema() ) {
return; // no tables were created...
}
+ if ( Boolean.getBoolean( "hibernate.test.skipCleanupValidation" ) ) {
+ return;
+ }
- Session tmpSession = openSession();
- List list = tmpSession.createQuery( "from java.lang.Object" ).list();
+ Session tmpSession = sessions.openSession();
+ try {
+ 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 );
+ 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() );
+ catch( Throwable t ) {
+ // intentionally empty
}
}
- else {
- tmpSession.close();
- }
}
- 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() ) {
@@ -329,6 +369,16 @@
// 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
@@ -341,8 +391,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;
@@ -353,9 +413,9 @@
catch( Throwable ignore ) {
}
finally {
- if ( session != null ) {
+ if ( testSession != null ) {
try {
- session.close();
+ testSession.close();
}
catch( Throwable ignore ) {
}
@@ -370,22 +430,51 @@
}
}
+ /**
+ * 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 ( DerbyDialect.class.isInstance( getDialect() ) ) {
+ 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;
}
+ /**
+ * 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;
}
+ /**
+ * 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[] {
@@ -406,6 +495,11 @@
return canDoIt;
}
+ /**
+ * 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(
@@ -418,14 +512,6 @@
return canDoIt;
}
- protected void reportSkip(String reason, String testDescription) {
- SKIP_LOG.warn( "*** skipping [" + fullTestName() + "] - " +
testDescription + " : " + reason, new Exception() );
- }
-
- public String fullTestName() {
- return this.getName() + " (" + this.getClass().getName() + ")";
- }
-
private boolean dialectIsNot(Class[] dialectClasses) {
for (int i = 0; i < dialectClasses.length; i++) {
Class dialectClass = dialectClasses[i];