Browse Source

Delete test annotations in spring-orm

This commit deletes all test annotations from the spring-orm module in
order to reduce unnecessary confusion between these "copies" and the
real, current versions of such classes in the spring-test module.

Furthermore, the legacy abstract JUnit 3.8 base classes and test cases
have been refactored accordingly.
pull/568/head
Sam Brannen 12 years ago
parent
commit
502022acca
  1. 58
      spring-orm/src/test/java/org/springframework/orm/jpa/AbstractContainerEntityManagerFactoryIntegrationTests.java
  2. 9
      spring-orm/src/test/java/org/springframework/orm/jpa/ApplicationManagedEntityManagerIntegrationTests.java
  3. 26
      spring-orm/src/test/java/org/springframework/orm/jpa/ContainerManagedEntityManagerIntegrationTests.java
  4. 15
      spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateEntityManagerFactoryIntegrationTests.java
  5. 4
      spring-orm/src/test/java/org/springframework/test/AbstractDependencyInjectionSpringContextTests.java
  6. 4
      spring-orm/src/test/java/org/springframework/test/AbstractSingleSpringContextTests.java
  7. 4
      spring-orm/src/test/java/org/springframework/test/AbstractSpringContextTests.java
  8. 6
      spring-orm/src/test/java/org/springframework/test/AbstractTransactionalDataSourceSpringContextTests.java
  9. 6
      spring-orm/src/test/java/org/springframework/test/AbstractTransactionalSpringContextTests.java
  10. 6
      spring-orm/src/test/java/org/springframework/test/ConditionalTestCase.java
  11. 203
      spring-orm/src/test/java/org/springframework/test/annotation/AbstractAnnotationAwareTransactionalTests.java
  12. 51
      spring-orm/src/test/java/org/springframework/test/annotation/DirtiesContext.java
  13. 40
      spring-orm/src/test/java/org/springframework/test/annotation/ExpectedException.java
  14. 102
      spring-orm/src/test/java/org/springframework/test/annotation/IfProfileValue.java
  15. 37
      spring-orm/src/test/java/org/springframework/test/annotation/NotTransactional.java
  16. 52
      spring-orm/src/test/java/org/springframework/test/annotation/ProfileValueSource.java
  17. 56
      spring-orm/src/test/java/org/springframework/test/annotation/ProfileValueSourceConfiguration.java
  18. 213
      spring-orm/src/test/java/org/springframework/test/annotation/ProfileValueUtils.java
  19. 43
      spring-orm/src/test/java/org/springframework/test/annotation/Repeat.java
  20. 47
      spring-orm/src/test/java/org/springframework/test/annotation/Rollback.java
  21. 59
      spring-orm/src/test/java/org/springframework/test/annotation/SystemProfileValueSource.java
  22. 57
      spring-orm/src/test/java/org/springframework/test/annotation/Timed.java
  23. 15
      spring-orm/src/test/java/org/springframework/test/jpa/AbstractJpaTests.java

58
spring-orm/src/test/java/org/springframework/orm/jpa/AbstractContainerEntityManagerFactoryIntegrationTests.java

@ -28,10 +28,8 @@ import javax.persistence.Query;
import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.orm.jpa.domain.DriversLicense; import org.springframework.orm.jpa.domain.DriversLicense;
import org.springframework.orm.jpa.domain.Person; import org.springframework.orm.jpa.domain.Person;
import org.springframework.test.annotation.ExpectedException; import org.springframework.transaction.annotation.Propagation;
import org.springframework.test.annotation.NotTransactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.test.annotation.Repeat;
import org.springframework.test.annotation.Timed;
import org.springframework.util.SerializationTestUtils; import org.springframework.util.SerializationTestUtils;
/** /**
@ -42,14 +40,13 @@ import org.springframework.util.SerializationTestUtils;
* @author Juergen Hoeller * @author Juergen Hoeller
*/ */
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public abstract class AbstractContainerEntityManagerFactoryIntegrationTests public abstract class AbstractContainerEntityManagerFactoryIntegrationTests extends
extends AbstractEntityManagerFactoryIntegrationTests { AbstractEntityManagerFactoryIntegrationTests {
@NotTransactional @Transactional(propagation = Propagation.NOT_SUPPORTED)
public void testEntityManagerFactoryImplementsEntityManagerFactoryInfo() { public void testEntityManagerFactoryImplementsEntityManagerFactoryInfo() {
assertTrue(Proxy.isProxyClass(entityManagerFactory.getClass())); assertTrue(Proxy.isProxyClass(entityManagerFactory.getClass()));
assertTrue("Must have introduced config interface", assertTrue("Must have introduced config interface", entityManagerFactory instanceof EntityManagerFactoryInfo);
entityManagerFactory instanceof EntityManagerFactoryInfo);
EntityManagerFactoryInfo emfi = (EntityManagerFactoryInfo) entityManagerFactory; EntityManagerFactoryInfo emfi = (EntityManagerFactoryInfo) entityManagerFactory;
// assertEquals("Person", emfi.getPersistenceUnitName()); // assertEquals("Person", emfi.getPersistenceUnitName());
assertNotNull("PersistenceUnitInfo must be available", emfi.getPersistenceUnitInfo()); assertNotNull("PersistenceUnitInfo must be available", emfi.getPersistenceUnitInfo());
@ -57,24 +54,26 @@ public abstract class AbstractContainerEntityManagerFactoryIntegrationTests
} }
public void testStateClean() { public void testStateClean() {
assertEquals("Should be no people from previous transactions", assertEquals("Should be no people from previous transactions", 0, countRowsInTable("person"));
0, countRowsInTable("person")); }
public void testJdbcTx1_1() {
testJdbcTx2();
}
public void testJdbcTx1_2() {
testJdbcTx2();
} }
@Repeat(5) public void testJdbcTx1_3() {
public void testJdbcTx1() throws Exception {
testJdbcTx2(); testJdbcTx2();
} }
@Timed(millis=273) public void testJdbcTx2() {
public void testJdbcTx2() throws InterruptedException {
//Thread.sleep(2000);
assertEquals("Any previous tx must have been rolled back", 0, countRowsInTable("person")); assertEquals("Any previous tx must have been rolled back", 0, countRowsInTable("person"));
//insertPerson("foo");
executeSqlScript("/org/springframework/orm/jpa/insertPerson.sql", false); executeSqlScript("/org/springframework/orm/jpa/insertPerson.sql", false);
} }
//@NotTransactional
@SuppressWarnings({ "unused", "unchecked" }) @SuppressWarnings({ "unused", "unchecked" })
public void testEntityManagerProxyIsProxy() { public void testEntityManagerProxyIsProxy() {
assertTrue(Proxy.isProxyClass(sharedEntityManager.getClass())); assertTrue(Proxy.isProxyClass(sharedEntityManager.getClass()));
@ -86,21 +85,31 @@ public abstract class AbstractContainerEntityManagerFactoryIntegrationTests
assertTrue("Close should have been silently ignored", sharedEntityManager.isOpen()); assertTrue("Close should have been silently ignored", sharedEntityManager.isOpen());
} }
@ExpectedException(RuntimeException.class)
public void testBogusQuery() { public void testBogusQuery() {
try {
Query query = sharedEntityManager.createQuery("It's raining toads"); Query query = sharedEntityManager.createQuery("It's raining toads");
// required in OpenJPA case // required in OpenJPA case
query.executeUpdate(); query.executeUpdate();
fail("Should have thrown a RuntimeException");
}
catch (RuntimeException e) {
/* expected */
}
} }
@ExpectedException(EntityNotFoundException.class)
public void testGetReferenceWhenNoRow() { public void testGetReferenceWhenNoRow() {
try {
Person notThere = sharedEntityManager.getReference(Person.class, 666); Person notThere = sharedEntityManager.getReference(Person.class, 666);
// We may get here (as with Hibernate). // We may get here (as with Hibernate).
// Either behaviour is valid: throw exception on first access // Either behaviour is valid: throw exception on first access
// or on getReference itself. // or on getReference itself.
notThere.getFirstName(); notThere.getFirstName();
fail("Should have thrown an EntityNotFoundException");
}
catch (EntityNotFoundException e) {
/* expected */
}
} }
public void testLazyLoading() { public void testLazyLoading() {
@ -125,7 +134,6 @@ public abstract class AbstractContainerEntityManagerFactoryIntegrationTests
} }
finally { finally {
deleteFromTables(new String[] { "person", "drivers_license" }); deleteFromTables(new String[] { "person", "drivers_license" });
//setComplete();
} }
} }
@ -194,7 +202,7 @@ public abstract class AbstractContainerEntityManagerFactoryIntegrationTests
} }
} }
@NotTransactional @Transactional(propagation = Propagation.NOT_SUPPORTED)
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void testQueryNoPersonsNotTransactional() { public void testQueryNoPersonsNotTransactional() {
EntityManager em = entityManagerFactory.createEntityManager(); EntityManager em = entityManagerFactory.createEntityManager();
@ -225,7 +233,7 @@ public abstract class AbstractContainerEntityManagerFactoryIntegrationTests
} }
} }
@NotTransactional @Transactional(propagation = Propagation.NOT_SUPPORTED)
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void testQueryNoPersonsSharedNotTransactional() { public void testQueryNoPersonsSharedNotTransactional() {
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(entityManagerFactory); EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(entityManagerFactory);
@ -238,7 +246,9 @@ public abstract class AbstractContainerEntityManagerFactoryIntegrationTests
fail("Should have thrown IllegalStateException"); fail("Should have thrown IllegalStateException");
} }
catch (Exception ex) { catch (Exception ex) {
// IllegalStateException expected, but PersistenceException thrown by Hibernate // IllegalStateException expected, but PersistenceException thrown by
// Hibernate
System.err.println(ex);
assertTrue(ex.getMessage().indexOf("closed") != -1); assertTrue(ex.getMessage().indexOf("closed") != -1);
} }
q = em.createQuery("select p from Person as p"); q = em.createQuery("select p from Person as p");

9
spring-orm/src/test/java/org/springframework/orm/jpa/ApplicationManagedEntityManagerIntegrationTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2013 the original author or authors. * Copyright 2002-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,16 +16,15 @@
package org.springframework.orm.jpa; package org.springframework.orm.jpa;
import java.util.List;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.util.List;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.Query; import javax.persistence.Query;
import javax.persistence.TransactionRequiredException; import javax.persistence.TransactionRequiredException;
import org.springframework.orm.jpa.domain.Person; import org.springframework.orm.jpa.domain.Person;
import org.springframework.orm.jpa.AbstractEntityManagerFactoryIntegrationTests; import org.springframework.transaction.annotation.Propagation;
import org.springframework.test.annotation.NotTransactional;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
@ -38,7 +37,7 @@ import org.springframework.transaction.annotation.Transactional;
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public class ApplicationManagedEntityManagerIntegrationTests extends AbstractEntityManagerFactoryIntegrationTests { public class ApplicationManagedEntityManagerIntegrationTests extends AbstractEntityManagerFactoryIntegrationTests {
@NotTransactional @Transactional(propagation = Propagation.NOT_SUPPORTED)
public void testEntityManagerIsProxy() { public void testEntityManagerIsProxy() {
assertTrue("EntityManagerFactory is proxied", Proxy.isProxyClass(entityManagerFactory.getClass())); assertTrue("EntityManagerFactory is proxied", Proxy.isProxyClass(entityManagerFactory.getClass()));
} }

26
spring-orm/src/test/java/org/springframework/orm/jpa/ContainerManagedEntityManagerIntegrationTests.java

@ -16,8 +16,8 @@
package org.springframework.orm.jpa; package org.springframework.orm.jpa;
import java.util.List;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.util.List;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.PersistenceException; import javax.persistence.PersistenceException;
@ -27,8 +27,8 @@ import javax.persistence.TransactionRequiredException;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.orm.jpa.domain.Person; import org.springframework.orm.jpa.domain.Person;
import org.springframework.test.annotation.ExpectedException; import org.springframework.transaction.annotation.Propagation;
import org.springframework.test.annotation.NotTransactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* Integration tests using in-memory database for container-managed JPA * Integration tests using in-memory database for container-managed JPA
@ -39,12 +39,12 @@ import org.springframework.test.annotation.NotTransactional;
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public class ContainerManagedEntityManagerIntegrationTests extends AbstractEntityManagerFactoryIntegrationTests { public class ContainerManagedEntityManagerIntegrationTests extends AbstractEntityManagerFactoryIntegrationTests {
@NotTransactional @Transactional(propagation = Propagation.NOT_SUPPORTED)
public void testExceptionTranslationWithDialectFoundOnIntroducedEntityManagerInfo() throws Exception { public void testExceptionTranslationWithDialectFoundOnIntroducedEntityManagerInfo() throws Exception {
doTestExceptionTranslationWithDialectFound(((EntityManagerFactoryInfo) entityManagerFactory).getJpaDialect()); doTestExceptionTranslationWithDialectFound(((EntityManagerFactoryInfo) entityManagerFactory).getJpaDialect());
} }
@NotTransactional @Transactional(propagation = Propagation.NOT_SUPPORTED)
public void testExceptionTranslationWithDialectFoundOnEntityManagerFactoryBean() throws Exception { public void testExceptionTranslationWithDialectFoundOnEntityManagerFactoryBean() throws Exception {
AbstractEntityManagerFactoryBean aefb = AbstractEntityManagerFactoryBean aefb =
(AbstractEntityManagerFactoryBean) applicationContext.getBean("&entityManagerFactory"); (AbstractEntityManagerFactoryBean) applicationContext.getBean("&entityManagerFactory");
@ -80,9 +80,14 @@ public class ContainerManagedEntityManagerIntegrationTests extends AbstractEntit
} }
// This would be legal, at least if not actually _starting_ a tx // This would be legal, at least if not actually _starting_ a tx
@ExpectedException(IllegalStateException.class)
public void testEntityManagerProxyRejectsProgrammaticTxManagement() { public void testEntityManagerProxyRejectsProgrammaticTxManagement() {
try {
createContainerManagedEntityManager().getTransaction(); createContainerManagedEntityManager().getTransaction();
fail("Should have thrown an IllegalStateException");
}
catch (IllegalStateException e) {
/* expected */
}
} }
/* /*
@ -93,10 +98,15 @@ public class ContainerManagedEntityManagerIntegrationTests extends AbstractEntit
createContainerManagedEntityManager().joinTransaction(); createContainerManagedEntityManager().joinTransaction();
} }
@NotTransactional @Transactional(propagation = Propagation.NOT_SUPPORTED)
@ExpectedException(TransactionRequiredException.class)
public void testContainerEntityManagerProxyRejectsJoinTransactionWithoutTransaction() { public void testContainerEntityManagerProxyRejectsJoinTransactionWithoutTransaction() {
try {
createContainerManagedEntityManager().joinTransaction(); createContainerManagedEntityManager().joinTransaction();
fail("Should have thrown a TransactionRequiredException");
}
catch (TransactionRequiredException e) {
/* expected */
}
} }
public void testInstantiateAndSave() { public void testInstantiateAndSave() {

15
spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateEntityManagerFactoryIntegrationTests.java

@ -25,7 +25,6 @@ import org.hibernate.ejb.HibernateEntityManagerFactory;
import org.springframework.orm.jpa.AbstractContainerEntityManagerFactoryIntegrationTests; import org.springframework.orm.jpa.AbstractContainerEntityManagerFactoryIntegrationTests;
import org.springframework.orm.jpa.EntityManagerFactoryInfo; import org.springframework.orm.jpa.EntityManagerFactoryInfo;
import org.springframework.orm.jpa.domain.Person; import org.springframework.orm.jpa.domain.Person;
import org.springframework.test.annotation.IfProfileValue;
/** /**
* Hibernate-specific JPA tests. * Hibernate-specific JPA tests.
@ -33,8 +32,8 @@ import org.springframework.test.annotation.IfProfileValue;
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Rod Johnson * @author Rod Johnson
*/ */
// Essentially @Ignore-d since AnnotationBeanConfigurerAspect cannot be found // TODO Decide what to do with broken HibernateEntityManagerFactoryIntegrationTests.
@IfProfileValue(name="test-group", value="broken") // See isDisabledInThisEnvironment() for details.
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public class HibernateEntityManagerFactoryIntegrationTests extends public class HibernateEntityManagerFactoryIntegrationTests extends
AbstractContainerEntityManagerFactoryIntegrationTests { AbstractContainerEntityManagerFactoryIntegrationTests {
@ -42,6 +41,15 @@ public class HibernateEntityManagerFactoryIntegrationTests extends
private SessionFactory sessionFactory; private SessionFactory sessionFactory;
/**
* Always returns {@code true}, thereby disabling this entire test class
* since AnnotationBeanConfigurerAspect cannot be found.
*/
@Override
protected boolean isDisabledInThisEnvironment(String testMethodName) {
return true;
}
public void setSessionFactory(SessionFactory sessionFactory) { public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory; this.sessionFactory = sessionFactory;
} }
@ -51,7 +59,6 @@ public class HibernateEntityManagerFactoryIntegrationTests extends
return HIBERNATE_CONFIG_LOCATIONS; return HIBERNATE_CONFIG_LOCATIONS;
} }
public void testCanCastNativeEntityManagerFactoryToHibernateEntityManagerFactoryImpl() { public void testCanCastNativeEntityManagerFactoryToHibernateEntityManagerFactoryImpl() {
EntityManagerFactoryInfo emfi = (EntityManagerFactoryInfo) entityManagerFactory; EntityManagerFactoryInfo emfi = (EntityManagerFactoryInfo) entityManagerFactory;
assertTrue(emfi.getNativeEntityManagerFactory() instanceof HibernateEntityManagerFactory); assertTrue(emfi.getNativeEntityManagerFactory() instanceof HibernateEntityManagerFactory);

4
spring-orm/src/test/java/org/springframework/test/AbstractDependencyInjectionSpringContextTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -27,6 +27,8 @@ import org.springframework.context.ApplicationContext;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
* This class is only used within tests in the spring-orm module.
*
* <p> * <p>
* Convenient superclass for JUnit 3.8 based tests depending on a Spring * Convenient superclass for JUnit 3.8 based tests depending on a Spring
* context. The test instance itself is populated by Dependency Injection. * context. The test instance itself is populated by Dependency Injection.

4
spring-orm/src/test/java/org/springframework/test/AbstractSingleSpringContextTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -26,6 +26,8 @@ import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
* This class is only used within tests in the spring-orm module.
*
* <p> * <p>
* Abstract JUnit 3.8 test class that holds and exposes a single Spring * Abstract JUnit 3.8 test class that holds and exposes a single Spring
* {@link org.springframework.context.ApplicationContext ApplicationContext}. * {@link org.springframework.context.ApplicationContext ApplicationContext}.

4
spring-orm/src/test/java/org/springframework/test/AbstractSpringContextTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -25,6 +25,8 @@ import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
* This class is only used within tests in the spring-orm module.
*
* <p> * <p>
* Superclass for JUnit 3.8 test cases using Spring * Superclass for JUnit 3.8 test cases using Spring
* {@link org.springframework.context.ApplicationContext ApplicationContexts}. * {@link org.springframework.context.ApplicationContext ApplicationContexts}.

6
spring-orm/src/test/java/org/springframework/test/AbstractTransactionalDataSourceSpringContextTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -31,7 +31,9 @@ import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.jdbc.JdbcTestUtils; import org.springframework.test.jdbc.JdbcTestUtils;
/** /**
* Subclass of AbstractTransactionalSpringContextTests that adds some convenience * This class is only used within tests in the spring-orm module.
*
* <p>Subclass of AbstractTransactionalSpringContextTests that adds some convenience
* functionality for JDBC access. Expects a {@link javax.sql.DataSource} bean * functionality for JDBC access. Expects a {@link javax.sql.DataSource} bean
* to be defined in the Spring application context. * to be defined in the Spring application context.
* *

6
spring-orm/src/test/java/org/springframework/test/AbstractTransactionalSpringContextTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -23,7 +23,9 @@ import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition; import org.springframework.transaction.support.DefaultTransactionDefinition;
/** /**
* Convenient base class for JUnit 3.8 based tests that should occur in a * This class is only used within tests in the spring-orm module.
*
* <p>Convenient base class for JUnit 3.8 based tests that should occur in a
* transaction, but normally will roll the transaction back on the completion of * transaction, but normally will roll the transaction back on the completion of
* each test. * each test.
* *

6
spring-orm/src/test/java/org/springframework/test/ConditionalTestCase.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,7 +21,9 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
/** /**
* Superclass for JUnit 3.8 based tests that allows conditional test execution * This class is only used within tests in the spring-orm module.
*
* <p>Superclass for JUnit 3.8 based tests that allows conditional test execution
* at the individual test method level. The * at the individual test method level. The
* {@link #isDisabledInThisEnvironment(String) isDisabledInThisEnvironment()} * {@link #isDisabledInThisEnvironment(String) isDisabledInThisEnvironment()}
* method is invoked before the execution of each test method. Subclasses can * method is invoked before the execution of each test method. Subclasses can

203
spring-orm/src/test/java/org/springframework/test/annotation/AbstractAnnotationAwareTransactionalTests.java

@ -18,54 +18,30 @@ package org.springframework.test.annotation;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.Map;
import junit.framework.AssertionFailedError;
import org.springframework.context.ApplicationContext;
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests; import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource; import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
import org.springframework.transaction.interceptor.TransactionAttributeSource; import org.springframework.transaction.interceptor.TransactionAttributeSource;
import org.springframework.util.Assert;
/** /**
* <p> * This class is only used within tests in the spring-orm module.
* Java 5 specific subclass of *
* <p>Java 5 specific subclass of
* {@link AbstractTransactionalDataSourceSpringContextTests}, obeying annotations * {@link AbstractTransactionalDataSourceSpringContextTests}, obeying annotations
* for transaction control. * for transaction control.
* </p> *
* <p> * <p>For example, test methods can be annotated with the regular Spring
* For example, test methods can be annotated with the regular Spring
* {@link org.springframework.transaction.annotation.Transactional @Transactional} * {@link org.springframework.transaction.annotation.Transactional @Transactional}
* annotation (e.g., to force execution in a read-only transaction) or with the * annotation &mdash; for example, to force execution in a read-only transaction
* {@link NotTransactional @NotTransactional} annotation to prevent any * or to prevent any transaction from being created at all by setting the propagation
* transaction being created at all. In addition, individual test methods can be * level to {@code NOT_SUPPORTED}.
* annotated with {@link Rollback @Rollback} to override the
* {@link #isDefaultRollback() default rollback} settings.
* </p>
* <p>
* The following list constitutes all annotations currently supported by
* AbstractAnnotationAwareTransactionalTests:
* </p>
* <ul>
* <li>{@link DirtiesContext @DirtiesContext}</li>
* <li>{@link ProfileValueSourceConfiguration @ProfileValueSourceConfiguration}</li>
* <li>{@link IfProfileValue @IfProfileValue}</li>
* <li>{@link ExpectedException @ExpectedException}</li>
* <li>{@link Timed @Timed}</li>
* <li>{@link Repeat @Repeat}</li>
* <li>{@link org.springframework.transaction.annotation.Transactional @Transactional}</li>
* <li>{@link NotTransactional @NotTransactional}</li>
* <li>{@link Rollback @Rollback}</li>
* </ul>
* *
* @author Rod Johnson * @author Rod Johnson
* @author Sam Brannen * @author Sam Brannen
* @author Juergen Hoeller * @author Juergen Hoeller
* @since 2.0 * @since 2.0
* @deprecated as of Spring 3.0, in favor of using the listener-based test context framework * @deprecated as of Spring 3.0, in favor of using the listener-based TestContext framework
* ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests})
*/ */
@Deprecated @Deprecated
public abstract class AbstractAnnotationAwareTransactionalTests extends public abstract class AbstractAnnotationAwareTransactionalTests extends
@ -73,15 +49,6 @@ public abstract class AbstractAnnotationAwareTransactionalTests extends
private final TransactionAttributeSource transactionAttributeSource = new AnnotationTransactionAttributeSource(); private final TransactionAttributeSource transactionAttributeSource = new AnnotationTransactionAttributeSource();
/**
* {@link ProfileValueSource} available to subclasses but primarily intended
* for use in {@link #isDisabledInThisEnvironment(Method)}.
* <p>Set to {@link SystemProfileValueSource} by default for backwards
* compatibility; however, the value may be changed in the
* {@link #AbstractAnnotationAwareTransactionalTests(String)} constructor.
*/
protected ProfileValueSource profileValueSource = SystemProfileValueSource.getInstance();
/** /**
* Default constructor for AbstractAnnotationAwareTransactionalTests, which * Default constructor for AbstractAnnotationAwareTransactionalTests, which
@ -93,37 +60,11 @@ public abstract class AbstractAnnotationAwareTransactionalTests extends
/** /**
* Constructs a new AbstractAnnotationAwareTransactionalTests instance with * Constructs a new AbstractAnnotationAwareTransactionalTests instance with
* the specified JUnit {@code name} and retrieves the configured (or * the specified JUnit {@code name}.
* default) {@link ProfileValueSource}.
* @param name the name of the current test * @param name the name of the current test
* @see ProfileValueUtils#retrieveProfileValueSource(Class)
*/ */
public AbstractAnnotationAwareTransactionalTests(String name) { public AbstractAnnotationAwareTransactionalTests(String name) {
super(name); super(name);
this.profileValueSource = ProfileValueUtils.retrieveProfileValueSource(getClass());
}
/**
* Search for a unique {@link ProfileValueSource} in the supplied
* {@link ApplicationContext}. If found, the
* {@code profileValueSource} for this test will be set to the unique
* {@link ProfileValueSource}.
* @param applicationContext the ApplicationContext in which to search for
* the ProfileValueSource; may not be {@code null}
* @deprecated Use {@link ProfileValueSourceConfiguration @ProfileValueSourceConfiguration} instead.
*/
@Deprecated
protected void findUniqueProfileValueSourceFromContext(ApplicationContext applicationContext) {
Assert.notNull(applicationContext, "Can not search for a ProfileValueSource in a null ApplicationContext.");
ProfileValueSource uniqueProfileValueSource = null;
Map<?, ?> beans = applicationContext.getBeansOfType(ProfileValueSource.class);
if (beans.size() == 1) {
uniqueProfileValueSource = (ProfileValueSource) beans.values().iterator().next();
}
if (uniqueProfileValueSource != null) {
this.profileValueSource = uniqueProfileValueSource;
}
} }
/** /**
@ -140,55 +81,19 @@ public abstract class AbstractAnnotationAwareTransactionalTests extends
final Method testMethod = getTestMethod(); final Method testMethod = getTestMethod();
if (isDisabledInThisEnvironment(testMethod)) { TransactionDefinition explicitTransactionDefinition = this.transactionAttributeSource.getTransactionAttribute(
recordDisabled(); testMethod, getClass());
this.logger.info("**** " + getClass().getName() + "." + getName() + " is disabled in this environment: "
+ "Total disabled tests=" + getDisabledTestCount());
return;
}
TransactionDefinition explicitTransactionDefinition =
this.transactionAttributeSource.getTransactionAttribute(testMethod, getClass());
if (explicitTransactionDefinition != null) { if (explicitTransactionDefinition != null) {
this.logger.info("Custom transaction definition [" + explicitTransactionDefinition + "] for test method [" this.logger.info("Custom transaction definition [" + explicitTransactionDefinition + "] for test method ["
+ getName() + "]."); + getName() + "].");
setTransactionDefinition(explicitTransactionDefinition); setTransactionDefinition(explicitTransactionDefinition);
} }
else if (testMethod.isAnnotationPresent(NotTransactional.class)) {
// Don't have any transaction...
preventTransaction();
}
// Let JUnit handle execution. We're just changing the state of the test class first. if (this.transactionDefinition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
runTestTimed(new TestExecutionCallback() { preventTransaction();
@Override
public void run() throws Throwable {
try {
AbstractAnnotationAwareTransactionalTests.super.runBare();
}
finally {
// Mark the context to be blown away if the test was
// annotated to result in setDirty being invoked
// automatically.
if (testMethod.isAnnotationPresent(DirtiesContext.class)) {
AbstractAnnotationAwareTransactionalTests.this.setDirty();
}
}
}
}, testMethod);
} }
/** super.runBare();
* Determine if the test for the supplied {@code testMethod} should
* run in the current environment.
* <p>The default implementation is based on
* {@link IfProfileValue @IfProfileValue} semantics.
* @param testMethod the test method
* @return {@code true} if the test is <em>disabled</em> in the current environment
* @see ProfileValueUtils#isTestEnabledInThisEnvironment
*/
protected boolean isDisabledInThisEnvironment(Method testMethod) {
return !ProfileValueUtils.isTestEnabledInThisEnvironment(this.profileValueSource, testMethod, getClass());
} }
/** /**
@ -213,89 +118,17 @@ public abstract class AbstractAnnotationAwareTransactionalTests extends
} }
/** /**
* Determine whether or not to rollback transactions for the current test * Determine whether or not to roll back transactions for the current test.
* by taking into consideration the * <p>The default implementation simply delegates to {@link #isDefaultRollback()}.
* {@link #isDefaultRollback() default rollback} flag and a possible
* method-level override via the {@link Rollback @Rollback} annotation.
* @return the <em>rollback</em> flag for the current test * @return the <em>rollback</em> flag for the current test
*/ */
@Override @Override
protected boolean isRollback() { protected boolean isRollback() {
boolean rollback = isDefaultRollback(); boolean rollback = isDefaultRollback();
Rollback rollbackAnnotation = getTestMethod().getAnnotation(Rollback.class);
if (rollbackAnnotation != null) {
boolean rollbackOverride = rollbackAnnotation.value();
if (this.logger.isDebugEnabled()) { if (this.logger.isDebugEnabled()) {
this.logger.debug("Method-level @Rollback(" + rollbackOverride + ") overrides default rollback [" this.logger.debug("Using default rollback [" + rollback + "] for test [" + getName() + "].");
+ rollback + "] for test [" + getName() + "].");
}
rollback = rollbackOverride;
}
else {
if (this.logger.isDebugEnabled()) {
this.logger.debug("No method-level @Rollback override: using default rollback [" + rollback
+ "] for test [" + getName() + "].");
}
} }
return rollback; return rollback;
} }
private void runTestTimed(TestExecutionCallback tec, Method testMethod) throws Throwable {
Timed timed = testMethod.getAnnotation(Timed.class);
if (timed == null) {
runTest(tec, testMethod);
}
else {
long startTime = System.currentTimeMillis();
try {
runTest(tec, testMethod);
}
finally {
long elapsed = System.currentTimeMillis() - startTime;
if (elapsed > timed.millis()) {
fail("Took " + elapsed + " ms; limit was " + timed.millis());
}
}
}
}
private void runTest(TestExecutionCallback tec, Method testMethod) throws Throwable {
ExpectedException expectedExceptionAnnotation = testMethod.getAnnotation(ExpectedException.class);
boolean exceptionIsExpected = (expectedExceptionAnnotation != null && expectedExceptionAnnotation.value() != null);
Class<? extends Throwable> expectedException = (exceptionIsExpected ? expectedExceptionAnnotation.value() : null);
Repeat repeat = testMethod.getAnnotation(Repeat.class);
int runs = ((repeat != null) && (repeat.value() > 1)) ? repeat.value() : 1;
for (int i = 0; i < runs; i++) {
try {
if (runs > 1 && this.logger != null && this.logger.isInfoEnabled()) {
this.logger.info("Repetition " + (i + 1) + " of test " + testMethod.getName());
}
tec.run();
if (exceptionIsExpected) {
fail("Expected exception: " + expectedException.getName());
}
}
catch (Throwable t) {
if (!exceptionIsExpected) {
throw t;
}
if (!expectedException.isAssignableFrom(t.getClass())) {
// Wrap the unexpected throwable with an explicit message.
AssertionFailedError assertionError = new AssertionFailedError("Unexpected exception, expected<" +
expectedException.getName() + "> but was<" + t.getClass().getName() + ">");
assertionError.initCause(t);
throw assertionError;
}
}
}
}
private static interface TestExecutionCallback {
void run() throws Throwable;
}
} }

51
spring-orm/src/test/java/org/springframework/test/annotation/DirtiesContext.java

@ -1,51 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed 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.springframework.test.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* Test annotation to indicate that a test method <em>dirties</em> the context
* for the current test.
* </p>
* <p>
* Using this annotation in conjunction with
* {@link AbstractAnnotationAwareTransactionalTests} is less error-prone than
* calling
* {@link org.springframework.test.AbstractSingleSpringContextTests#setDirty() setDirty()}
* explicitly because the call to {@code setDirty()} is guaranteed to
* occur, even if the test failed. If only a particular code path in the test
* dirties the context, prefer calling {@code setDirty()} explicitly --
* and take care!
* </p>
*
* @author Rod Johnson
* @author Sam Brannen
* @since 2.0
* @see org.springframework.test.AbstractSingleSpringContextTests
*/
@Target( { ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DirtiesContext {
}

40
spring-orm/src/test/java/org/springframework/test/annotation/ExpectedException.java

@ -1,40 +0,0 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed 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.springframework.test.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Test annotation to indicate that a test method is required to throw the
* specified exception.
*
* @author Rod Johnson
* @author Sam Brannen
* @since 2.0
*/
@Target( { ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExpectedException {
Class<? extends Throwable> value();
}

102
spring-orm/src/test/java/org/springframework/test/annotation/IfProfileValue.java

@ -1,102 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed 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.springframework.test.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* Test annotation to indicate that a test is enabled for a specific testing
* profile or environment. If the configured {@link ProfileValueSource} returns
* a matching {@link #value() value} for the provided {@link #name() name}, the
* test will be enabled.
* </p>
* <p>
* Note: {@link IfProfileValue @IfProfileValue} can be applied at either the
* class or method level.
* </p>
* <p>
* Examples: when using {@link SystemProfileValueSource} as the
* {@link ProfileValueSource} implementation, you can configure a test method to
* run only on Java VMs from Sun Microsystems as follows:
* </p>
*
* <pre class="code">
* {@link IfProfileValue @IfProfileValue}(name=&quot;java.vendor&quot;, value=&quot;Sun Microsystems Inc.&quot;)
* testSomething() {
* // ...
* }
* </pre>
*
* <p>
* You can alternatively configure {@link IfProfileValue @IfProfileValue} with
* <em>OR</em> semantics for multiple {@link #values() values} as follows
* (assuming a {@link ProfileValueSource} has been appropriately configured for
* the &quot;test-groups&quot; name):
* </p>
*
* <pre class="code">
* {@link IfProfileValue @IfProfileValue}(name=&quot;test-groups&quot;, values={&quot;unit-tests&quot;, &quot;integration-tests&quot;})
* public void testWhichRunsForUnitOrIntegrationTestGroups() {
* // ...
* }
* </pre>
*
* @author Rod Johnson
* @author Sam Brannen
* @since 2.0
* @see ProfileValueSource
* @see ProfileValueSourceConfiguration
* @see ProfileValueUtils
* @see AbstractAnnotationAwareTransactionalTests
* @see org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests
* @see org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface IfProfileValue {
/**
* The {@code name} of the <em>profile value</em> against which to test.
*/
String name();
/**
* A single, permissible {@code value} of the <em>profile value</em>
* for the given {@link #name() name}.
* <p>Note: Assigning values to both {@link #value()} and {@link #values()}
* will lead to a configuration conflict.
*/
String value() default "";
/**
* A list of all permissible {@code values} of the
* <em>profile value</em> for the given {@link #name() name}.
* <p>Note: Assigning values to both {@link #value()} and {@link #values()}
* will lead to a configuration conflict.
*/
String[] values() default {};
}

37
spring-orm/src/test/java/org/springframework/test/annotation/NotTransactional.java

@ -1,37 +0,0 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed 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.springframework.test.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Test annotation to indicate that a method is not transactional.
*
* @author Rod Johnson
* @author Sam Brannen
* @since 2.0
*/
@Target( { ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NotTransactional {
}

52
spring-orm/src/test/java/org/springframework/test/annotation/ProfileValueSource.java

@ -1,52 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed 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.springframework.test.annotation;
/**
* <p>
* Strategy interface for retrieving <em>profile values</em> for a given
* testing environment.
* </p>
* <p>
* Concrete implementations must provide a {@code public} no-args
* constructor.
* </p>
* <p>
* Spring provides the following out-of-the-box implementations:
* </p>
* <ul>
* <li>{@link SystemProfileValueSource}</li>
* </ul>
*
* @author Rod Johnson
* @author Sam Brannen
* @since 2.0
* @see ProfileValueSourceConfiguration
* @see IfProfileValue
* @see ProfileValueUtils
*/
public interface ProfileValueSource {
/**
* Get the <em>profile value</em> indicated by the specified key.
* @param key the name of the <em>profile value</em>
* @return the String value of the <em>profile value</em>, or {@code null}
* if there is no <em>profile value</em> with that key
*/
String get(String key);
}

56
spring-orm/src/test/java/org/springframework/test/annotation/ProfileValueSourceConfiguration.java

@ -1,56 +0,0 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed 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.springframework.test.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* ProfileValueSourceConfiguration is a class-level annotation which is used to
* specify what type of {@link ProfileValueSource} to use when retrieving
* <em>profile values</em> configured via the
* {@link IfProfileValue @IfProfileValue} annotation.
* </p>
*
* @author Sam Brannen
* @since 2.5
* @see ProfileValueSource
* @see IfProfileValue
* @see ProfileValueUtils
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
@Documented
public @interface ProfileValueSourceConfiguration {
/**
* <p>
* The type of {@link ProfileValueSource} to use when retrieving
* <em>profile values</em>.
* </p>
*
* @see SystemProfileValueSource
*/
Class<? extends ProfileValueSource> value() default SystemProfileValueSource.class;
}

213
spring-orm/src/test/java/org/springframework/test/annotation/ProfileValueUtils.java

@ -1,213 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed 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.springframework.test.annotation;
import java.lang.reflect.Method;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
* General utility methods for working with <em>profile values</em>.
*
* @author Sam Brannen
* @author Juergen Hoeller
* @since 2.5
* @see ProfileValueSource
* @see ProfileValueSourceConfiguration
* @see IfProfileValue
*/
public abstract class ProfileValueUtils {
private static final Log logger = LogFactory.getLog(ProfileValueUtils.class);
/**
* Retrieves the {@link ProfileValueSource} type for the specified
* {@link Class test class} as configured via the
* {@link ProfileValueSourceConfiguration @ProfileValueSourceConfiguration}
* annotation and instantiates a new instance of that type.
* <p>
* If
* {@link ProfileValueSourceConfiguration @ProfileValueSourceConfiguration}
* is not present on the specified class or if a custom
* {@link ProfileValueSource} is not declared, the default
* {@link SystemProfileValueSource} will be returned instead.
*
* @param testClass The test class for which the ProfileValueSource should
* be retrieved
* @return the configured (or default) ProfileValueSource for the specified
* class
* @see SystemProfileValueSource
*/
@SuppressWarnings("unchecked")
public static ProfileValueSource retrieveProfileValueSource(Class<?> testClass) {
Assert.notNull(testClass, "testClass must not be null");
Class<ProfileValueSourceConfiguration> annotationType = ProfileValueSourceConfiguration.class;
ProfileValueSourceConfiguration config = testClass.getAnnotation(annotationType);
if (logger.isDebugEnabled()) {
logger.debug("Retrieved @ProfileValueSourceConfiguration [" + config + "] for test class ["
+ testClass.getName() + "]");
}
Class<? extends ProfileValueSource> profileValueSourceType;
if (config != null) {
profileValueSourceType = config.value();
}
else {
profileValueSourceType = (Class<? extends ProfileValueSource>) AnnotationUtils.getDefaultValue(annotationType);
}
if (logger.isDebugEnabled()) {
logger.debug("Retrieved ProfileValueSource type [" + profileValueSourceType + "] for class ["
+ testClass.getName() + "]");
}
ProfileValueSource profileValueSource;
if (SystemProfileValueSource.class.equals(profileValueSourceType)) {
profileValueSource = SystemProfileValueSource.getInstance();
}
else {
try {
profileValueSource = profileValueSourceType.newInstance();
}
catch (Exception e) {
if (logger.isWarnEnabled()) {
logger.warn("Could not instantiate a ProfileValueSource of type [" + profileValueSourceType
+ "] for class [" + testClass.getName() + "]: using default.", e);
}
profileValueSource = SystemProfileValueSource.getInstance();
}
}
return profileValueSource;
}
/**
* Determine if the supplied {@code testClass} is <em>enabled</em>
* in the current environment, as specified by the
* {@link IfProfileValue @IfProfileValue} annotation at the class level.
* <p>
* Defaults to {@code true} if no
* {@link IfProfileValue @IfProfileValue} annotation is declared.
*
* @param testClass the test class
* @return {@code true} if the test is <em>enabled</em> in the
* current environment
*/
public static boolean isTestEnabledInThisEnvironment(Class<?> testClass) {
IfProfileValue ifProfileValue = testClass.getAnnotation(IfProfileValue.class);
if (ifProfileValue == null) {
return true;
}
ProfileValueSource profileValueSource = retrieveProfileValueSource(testClass);
return isTestEnabledInThisEnvironment(profileValueSource, ifProfileValue);
}
/**
* Determine if the supplied {@code testMethod} is <em>enabled</em>
* in the current environment, as specified by the
* {@link IfProfileValue @IfProfileValue} annotation, which may be declared
* on the test method itself or at the class level.
* <p>
* Defaults to {@code true} if no
* {@link IfProfileValue @IfProfileValue} annotation is declared.
*
* @param testMethod the test method
* @param testClass the test class
* @return {@code true} if the test is <em>enabled</em> in the
* current environment
*/
public static boolean isTestEnabledInThisEnvironment(Method testMethod, Class<?> testClass) {
IfProfileValue ifProfileValue = testMethod.getAnnotation(IfProfileValue.class);
if (ifProfileValue == null) {
ifProfileValue = testClass.getAnnotation(IfProfileValue.class);
if (ifProfileValue == null) {
return true;
}
}
ProfileValueSource profileValueSource = retrieveProfileValueSource(testClass);
return isTestEnabledInThisEnvironment(profileValueSource, ifProfileValue);
}
/**
* Determine if the supplied {@code testMethod} is <em>enabled</em>
* in the current environment, as specified by the
* {@link IfProfileValue @IfProfileValue} annotation, which may be declared
* on the test method itself or at the class level.
* <p>
* Defaults to {@code true} if no
* {@link IfProfileValue @IfProfileValue} annotation is declared.
*
* @param profileValueSource the ProfileValueSource to use to determine if
* the test is enabled
* @param testMethod the test method
* @param testClass the test class
* @return {@code true} if the test is <em>enabled</em> in the
* current environment
*/
public static boolean isTestEnabledInThisEnvironment(ProfileValueSource profileValueSource, Method testMethod,
Class<?> testClass) {
IfProfileValue ifProfileValue = testMethod.getAnnotation(IfProfileValue.class);
if (ifProfileValue == null) {
ifProfileValue = testClass.getAnnotation(IfProfileValue.class);
if (ifProfileValue == null) {
return true;
}
}
return isTestEnabledInThisEnvironment(profileValueSource, ifProfileValue);
}
/**
* Determine if the {@code value} (or one of the {@code values})
* in the supplied {@link IfProfileValue @IfProfileValue} annotation is
* <em>enabled</em> in the current environment.
*
* @param profileValueSource the ProfileValueSource to use to determine if
* the test is enabled
* @param ifProfileValue the annotation to introspect
* @return {@code true} if the test is <em>enabled</em> in the
* current environment
*/
private static boolean isTestEnabledInThisEnvironment(ProfileValueSource profileValueSource,
IfProfileValue ifProfileValue) {
String environmentValue = profileValueSource.get(ifProfileValue.name());
String[] annotatedValues = ifProfileValue.values();
if (StringUtils.hasLength(ifProfileValue.value())) {
if (annotatedValues.length > 0) {
throw new IllegalArgumentException("Setting both the 'value' and 'values' attributes "
+ "of @IfProfileValue is not allowed: choose one or the other.");
}
annotatedValues = new String[] { ifProfileValue.value() };
}
for (String value : annotatedValues) {
if (ObjectUtils.nullSafeEquals(value, environmentValue)) {
return true;
}
}
return false;
}
}

43
spring-orm/src/test/java/org/springframework/test/annotation/Repeat.java

@ -1,43 +0,0 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed 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.springframework.test.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Test annotation to indicate that a test method should be invoked repeatedly.
* <p />
* Note that the scope of execution to be repeated includes execution of the
* test method itself as well as any <em>set up</em> or <em>tear down</em>
* of the test fixture.
*
* @author Rod Johnson
* @author Sam Brannen
* @since 2.0
*/
@Target( { ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Repeat {
int value() default 1;
}

47
spring-orm/src/test/java/org/springframework/test/annotation/Rollback.java

@ -1,47 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed 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.springframework.test.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Test annotation to indicate whether or not the transaction for the annotated
* test method should be <em>rolled back</em> after the test method has
* completed. If {@code true}, the transaction will be rolled back;
* otherwise, the transaction will be committed.
*
* @author Sam Brannen
* @since 2.5
*/
@Target( { ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Rollback {
/**
* <p>
* Whether or not the transaction for the annotated method should be rolled
* back after the method has completed.
* </p>
*/
boolean value() default true;
}

59
spring-orm/src/test/java/org/springframework/test/annotation/SystemProfileValueSource.java

@ -1,59 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed 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.springframework.test.annotation;
import org.springframework.util.Assert;
/**
* Implementation of {@link ProfileValueSource} which uses system properties as
* the underlying source.
*
* @author Rod Johnson
* @author Sam Brannen
* @since 2.0
*/
public class SystemProfileValueSource implements ProfileValueSource {
private static final SystemProfileValueSource INSTANCE = new SystemProfileValueSource();
/**
* Obtain the canonical instance of this ProfileValueSource.
*/
public static final SystemProfileValueSource getInstance() {
return INSTANCE;
}
/**
* Private constructor, enforcing the singleton pattern.
*/
private SystemProfileValueSource() {
}
/**
* Get the <em>profile value</em> indicated by the specified key from the
* system properties.
* @see System#getProperty(String)
*/
@Override
public String get(String key) {
Assert.hasText(key, "'key' must not be empty");
return System.getProperty(key);
}
}

57
spring-orm/src/test/java/org/springframework/test/annotation/Timed.java

@ -1,57 +0,0 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed 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.springframework.test.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* Test-specific annotation to indicate that a test method has to finish
* execution in a {@link #millis() specified time period}.
* </p>
* <p>
* If the text execution takes longer than the specified time period, then the
* test is to be considered failed.
* </p>
* <p>
* Note that the time period includes execution of the test method itself, any
* {@link Repeat repetitions} of the test, and any <em>set up</em> or
* <em>tear down</em> of the test fixture.
* </p>
*
* @author Rod Johnson
* @author Sam Brannen
* @since 2.0
* @see Repeat
* @see AbstractAnnotationAwareTransactionalTests
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Timed {
/**
* The maximum amount of time (in milliseconds) that a test execution can
* take without being marked as failed due to taking too long.
*/
long millis();
}

15
spring-orm/src/test/java/org/springframework/test/jpa/AbstractJpaTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -50,7 +50,9 @@ import org.springframework.test.annotation.AbstractAnnotationAwareTransactionalT
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
* Convenient support class for JPA-related tests. Offers the same contract as * This class is only used within tests in the spring-orm module.
*
* <p>Convenient support class for JPA-related tests. Offers the same contract as
* AbstractTransactionalDataSourceSpringContextTests and equally good performance, * AbstractTransactionalDataSourceSpringContextTests and equally good performance,
* even when performing the instrumentation required by the JPA specification. * even when performing the instrumentation required by the JPA specification.
* *
@ -171,15 +173,6 @@ public abstract class AbstractJpaTests extends AbstractAnnotationAwareTransactio
return; return;
} }
final Method testMethod = getTestMethod();
if (isDisabledInThisEnvironment(testMethod)) {
recordDisabled();
this.logger.info("**** " + getClass().getName() + "." + getName() + " is disabled in this environment: "
+ "Total disabled tests=" + getDisabledTestCount());
return;
}
if (!shouldUseShadowLoader()) { if (!shouldUseShadowLoader()) {
super.runBare(); super.runBare();
return; return;

Loading…
Cancel
Save