[hibernate-commits] Hibernate SVN: r10408 - branches/Branch_3_2/Hibernate3/test/org/hibernate/test

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Fri Sep 1 14:43:12 EDT 2006


Author: steve.ebersole at 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




More information about the hibernate-commits mailing list