[hibernate-commits] Hibernate SVN: r19398 - in core/branches/Branch_3_3_2_GA_CP/testing/src/main/java/org/hibernate: test and 1 other directories.
hibernate-commits at lists.jboss.org
hibernate-commits at lists.jboss.org
Fri May 7 03:10:14 EDT 2010
Author: stliu
Date: 2010-05-07 03:10:13 -0400 (Fri, 07 May 2010)
New Revision: 19398
Added:
core/branches/Branch_3_3_2_GA_CP/testing/src/main/java/org/hibernate/junit/FailureExpected.java
core/branches/Branch_3_3_2_GA_CP/testing/src/main/java/org/hibernate/junit/RequiresDialect.java
core/branches/Branch_3_3_2_GA_CP/testing/src/main/java/org/hibernate/junit/SkipForDialect.java
core/branches/Branch_3_3_2_GA_CP/testing/src/main/java/org/hibernate/test/annotations/
core/branches/Branch_3_3_2_GA_CP/testing/src/main/java/org/hibernate/test/annotations/HibernateTestCase.java
Log:
JBPAPP-4235 HHH-4822 Add @FailureExpected annotation to annotations and entitymananger modules to allow the skipping of tests
Added: core/branches/Branch_3_3_2_GA_CP/testing/src/main/java/org/hibernate/junit/FailureExpected.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testing/src/main/java/org/hibernate/junit/FailureExpected.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testing/src/main/java/org/hibernate/junit/FailureExpected.java 2010-05-07 07:10:13 UTC (rev 19398)
@@ -0,0 +1,51 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.junit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotations used to mark a test as an expected failure.
+ *
+ * @author Hardy Ferentschik
+ * @author Steve Ebersole
+ */
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target({ ElementType.METHOD, ElementType.TYPE })
+public @interface FailureExpected {
+ /**
+ * The key of a JIRA issue which covers this expected failure.
+ * @return The jira issue key
+ */
+ String jiraKey();
+
+ /**
+ * A message explaining the reason for the expected failure. Optional.
+ * @return The reason
+ */
+ String message() default "";
+}
\ No newline at end of file
Added: core/branches/Branch_3_3_2_GA_CP/testing/src/main/java/org/hibernate/junit/RequiresDialect.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testing/src/main/java/org/hibernate/junit/RequiresDialect.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testing/src/main/java/org/hibernate/junit/RequiresDialect.java 2010-05-07 07:10:13 UTC (rev 19398)
@@ -0,0 +1,54 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.junit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.hibernate.dialect.Dialect;
+
+/**
+ * Annotation used to indicate that a test should be run only when run against the
+ * indicated dialects.
+ *
+ * @author Hardy Ferentschik
+ */
+ at Target({ElementType.METHOD, ElementType.TYPE})
+ at Retention(RetentionPolicy.RUNTIME)
+public @interface RequiresDialect {
+ /**
+ * The dialects against which to run the test
+ * @return The dialects
+ */
+ Class<? extends Dialect>[] value();
+
+ /**
+ * Used to indicate if the dialects should be matched strictly (classes equal) or
+ * non-strictly (instanceof).
+ * @return Should strict matching be used?
+ */
+ boolean strictMatching() default false;
+}
Added: core/branches/Branch_3_3_2_GA_CP/testing/src/main/java/org/hibernate/junit/SkipForDialect.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testing/src/main/java/org/hibernate/junit/SkipForDialect.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testing/src/main/java/org/hibernate/junit/SkipForDialect.java 2010-05-07 07:10:13 UTC (rev 19398)
@@ -0,0 +1,68 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.junit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.hibernate.dialect.Dialect;
+
+/**
+ * Annotation used to indicate that a test should be skipped when run against the
+ * indicated dialects.
+ *
+ * @author Hardy Ferentschik
+ * @author Steve Ebersole
+ */
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target({ ElementType.METHOD, ElementType.TYPE })
+public @interface SkipForDialect {
+ /**
+ * The dialects against which to skip the test
+ * @return The dialects
+ */
+ Class<? extends Dialect>[] value();
+
+ /**
+ * Used to indicate if the dialects should be matched strictly (classes equal) or
+ * non-strictly (instanceof).
+ * @return Should strict matching be used?
+ */
+ boolean strictMatching() default false;
+
+ /**
+ * Comment describing the reason for the skip.
+ * @return The comment
+ */
+ String comment() default "";
+
+ /**
+ * The key of a JIRA issue which covers the reason for this skip. Eventually we should make this
+ * a requirement.
+ * @return The jira issue key
+ */
+ String jiraKey() default "";
+}
\ No newline at end of file
Added: core/branches/Branch_3_3_2_GA_CP/testing/src/main/java/org/hibernate/test/annotations/HibernateTestCase.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testing/src/main/java/org/hibernate/test/annotations/HibernateTestCase.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testing/src/main/java/org/hibernate/test/annotations/HibernateTestCase.java 2010-05-07 07:10:13 UTC (rev 19398)
@@ -0,0 +1,363 @@
+// $Id: HibernateTestCase.java 18858 2010-02-23 12:57:17Z hardy.ferentschik $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.test.annotations;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.HashSet;
+import java.util.Set;
+
+import junit.framework.TestCase;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.cfg.Configuration;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.jdbc.Work;
+import org.hibernate.junit.FailureExpected;
+import org.hibernate.junit.RequiresDialect;
+import org.hibernate.junit.SkipForDialect;
+import org.hibernate.junit.SkipLog;
+import org.hibernate.tool.hbm2ddl.SchemaExport;
+import org.hibernate.util.StringHelper;
+
+/**
+ * A base class for all tests.
+ *
+ * @author Emmnauel Bernand
+ * @author Hardy Ferentschik
+ */
+public abstract class HibernateTestCase extends TestCase {
+
+ public static final Logger log = LoggerFactory.getLogger( HibernateTestCase.class );
+
+ protected static Configuration cfg;
+ private static Class<?> lastTestClass;
+
+
+ /**
+ * Flag indicating whether the test should be run or skipped.
+ */
+ private boolean runTest = true;
+
+ /**
+ * List of required dialect for the current {@code runMethod}. If the list is empty any dialect is allowed.
+ * Otherwise the current dialect or a superclass of the current dialect must be in the list.
+ */
+ private final Set<Class<? extends Dialect>> requiredDialectList = new HashSet<Class<? extends Dialect>>();
+
+ /**
+ * List of dialects for which the current {@code runMethod} should be skipped.
+ */
+ private final Set<Class<? extends Dialect>> skipForDialectList = new HashSet<Class<? extends Dialect>>();
+
+ public HibernateTestCase() {
+ super();
+ }
+
+ public HibernateTestCase(String x) {
+ super( x );
+ }
+
+ @Override
+ public void runBare() throws Throwable {
+ Method runMethod = findTestMethod();
+
+ final Skip skip = determineSkipByDialect( Dialect.getDialect(), runMethod );
+ if ( skip != null ) {
+ reportSkip( skip );
+ return;
+ }
+
+ setUp();
+ try {
+ runTest();
+ }
+ finally {
+ tearDown();
+ }
+ }
+
+ @Override
+ protected void runTest() throws Throwable {
+ Method runMethod = findTestMethod();
+ FailureExpected failureExpected = locateAnnotation( FailureExpected.class, runMethod );
+ try {
+ super.runTest();
+ if ( failureExpected != null ) {
+ throw new FailureExpectedTestPassedException();
+ }
+ }
+ catch ( FailureExpectedTestPassedException t ) {
+ closeResources();
+ throw t;
+ }
+ catch ( Throwable t ) {
+ if ( t instanceof InvocationTargetException ) {
+ t = ( ( InvocationTargetException ) t ).getTargetException();
+ }
+ if ( t instanceof IllegalAccessException ) {
+ t.fillInStackTrace();
+ }
+ closeResources();
+ if ( failureExpected != null ) {
+ StringBuilder builder = new StringBuilder();
+ if ( StringHelper.isNotEmpty( failureExpected.message() ) ) {
+ builder.append( failureExpected.message() );
+ }
+ else {
+ builder.append( "ignoring @FailureExpected test" );
+ }
+ builder.append( " (" )
+ .append( failureExpected.jiraKey() )
+ .append( ")" );
+ SkipLog.LOG.warn( builder.toString(), t );
+ }
+ else {
+ throw t;
+ }
+ }
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ if ( cfg == null || lastTestClass != getClass() ) {
+ buildConfiguration();
+ lastTestClass = getClass();
+ }
+ else {
+ runSchemaGeneration();
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ runSchemaDrop();
+ handleUnclosedResources();
+ }
+
+ protected static class Skip {
+ private final String reason;
+ private final String testDescription;
+
+ public Skip(String reason, String testDescription) {
+ this.reason = reason;
+ this.testDescription = testDescription;
+ }
+ }
+
+ protected final Skip determineSkipByDialect(Dialect dialect, Method runMethod) {
+ // skips have precedence, so check them first
+ SkipForDialect skipForDialectAnn = locateAnnotation( SkipForDialect.class, runMethod );
+ if ( skipForDialectAnn != null ) {
+ for ( Class<? extends Dialect> dialectClass : skipForDialectAnn.value() ) {
+ if ( skipForDialectAnn.strictMatching() ) {
+ if ( dialectClass.equals( dialect.getClass() ) ) {
+ return buildSkip( dialect, skipForDialectAnn.comment(), skipForDialectAnn.jiraKey() );
+ }
+ }
+ else {
+ if ( dialectClass.isInstance( dialect ) ) {
+ return buildSkip( dialect, skipForDialectAnn.comment(), skipForDialectAnn.jiraKey() );
+ }
+ }
+ }
+ }
+
+ // then check against the requires
+ RequiresDialect requiresDialectAnn = locateAnnotation( RequiresDialect.class, runMethod );
+ if ( requiresDialectAnn != null ) {
+ for ( Class<? extends Dialect> dialectClass : requiresDialectAnn.value() ) {
+ if ( requiresDialectAnn.strictMatching() ) {
+ if ( dialectClass.equals( dialect.getClass() ) ) {
+ return buildSkip( dialect, null, null );
+ }
+ }
+ else {
+ if ( dialectClass.isInstance( dialect ) ) {
+ return buildSkip( dialect, null, null );
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ protected <T extends Annotation> T locateAnnotation(Class<T> annotationClass, Method runMethod) {
+ T annotation = runMethod.getAnnotation( annotationClass );
+ if ( annotation == null ) {
+ annotation = getClass().getAnnotation( annotationClass );
+ }
+ if ( annotation == null ) {
+ annotation = runMethod.getDeclaringClass().getAnnotation( annotationClass );
+ }
+ return annotation;
+ }
+
+ protected Skip buildSkip(Dialect dialect, String comment, String jiraKey) {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append( "skipping database-specific test [" );
+ buffer.append( fullTestName() );
+ buffer.append( "] for dialect [" );
+ buffer.append( dialect.getClass().getName() );
+ buffer.append( ']' );
+
+ if ( StringHelper.isNotEmpty( comment ) ) {
+ buffer.append( "; " ).append( comment );
+ }
+
+ if ( StringHelper.isNotEmpty( jiraKey ) ) {
+ buffer.append( " (" ).append( jiraKey ).append( ')' );
+ }
+
+ return new Skip( buffer.toString(), null );
+ }
+
+ public String fullTestName() {
+ return this.getClass().getName() + "#" + this.getName();
+ }
+
+ protected boolean runForCurrentDialect() {
+ boolean runTestForCurrentDialect = true;
+
+ // check whether the current dialect is assignableFrom from any of the specified required dialects.
+ for ( Class<? extends Dialect> dialect : requiredDialectList ) {
+ if ( dialect.isAssignableFrom( Dialect.getDialect().getClass() ) ) {
+ runTestForCurrentDialect = true;
+ break;
+ }
+ runTestForCurrentDialect = false;
+ }
+
+ // check whether the current dialect is assignableFrom from any of the specified skip for dialects.
+ for ( Class<? extends Dialect> dialect : skipForDialectList ) {
+ if ( dialect.isAssignableFrom( Dialect.getDialect().getClass() ) ) {
+ runTestForCurrentDialect = false;
+ break;
+ }
+ runTestForCurrentDialect = true;
+ }
+
+ return runTestForCurrentDialect;
+ }
+
+ private Method findTestMethod() {
+ String fName = getName();
+ assertNotNull( fName );
+ Method runMethod = null;
+ try {
+ runMethod = getClass().getMethod( fName );
+ }
+ catch ( NoSuchMethodException e ) {
+ fail( "Method \"" + fName + "\" not found" );
+ }
+ if ( !Modifier.isPublic( runMethod.getModifiers() ) ) {
+ fail( "Method \"" + fName + "\" should be public" );
+ }
+ return runMethod;
+ }
+
+ protected abstract void buildConfiguration() throws Exception;
+
+ protected abstract Class<?>[] getAnnotatedClasses();
+
+ protected String[] getMappings() {
+ return new String[]{};
+ }
+
+ protected abstract void handleUnclosedResources();
+
+ protected abstract void closeResources();
+
+ protected String[] getAnnotatedPackages() {
+ return new String[] { };
+ }
+
+ protected String[] getXmlFiles() {
+ return new String[] { };
+ }
+
+ protected Dialect getDialect() {
+ return Dialect.getDialect();
+ }
+
+ protected static void setCfg(Configuration cfg) {
+ HibernateTestCase.cfg = cfg;
+ }
+
+ protected static Configuration getCfg() {
+ return cfg;
+ }
+
+ protected void configure(Configuration cfg) {
+ }
+
+ protected boolean recreateSchema() {
+ return true;
+ }
+
+ protected void runSchemaGeneration() {
+ SchemaExport export = new SchemaExport( cfg );
+ export.create( true, true );
+ }
+
+ protected void runSchemaDrop() {
+ SchemaExport export = new SchemaExport( cfg );
+ export.drop( true, true );
+ }
+
+ private void reportSkip(Skip skip) {
+ reportSkip( skip.reason, skip.testDescription );
+ }
+
+ protected void reportSkip(String reason, String testDescription) {
+ StringBuilder builder = new StringBuilder();
+ builder.append( "*** skipping test [" );
+ builder.append( fullTestName() );
+ builder.append( "] - " );
+ builder.append( testDescription );
+ builder.append( " : " );
+ builder.append( reason );
+ SkipLog.LOG.warn( builder.toString() );
+ }
+
+ public class RollbackWork implements Work {
+
+ public void execute(Connection connection) throws SQLException {
+ connection.rollback();
+ }
+ }
+
+ private static class FailureExpectedTestPassedException extends Exception {
+ public FailureExpectedTestPassedException() {
+ super( "Test marked as @FailureExpected, but did not fail!" );
+ }
+ }
+}
More information about the hibernate-commits
mailing list