GithubHelp home page GithubHelp logo

flyway-test-extensions's Introduction

flyway-test-extensions

flyway-test-extension logo

Test extensions for the Flyway project

For Flyway's features, see the Flyway Db Org Page

Version 10.0.0 Released

2024-01-24 flyway-test-extensions version 10.0.0 released.

Version number 10.x are used to show the dependency or compatibility to Flyway version 10.x. The main feature can also be used with older features, see the corresponding examples.

See also Release Notes

Central maven repository under http://search.maven.org/#search|ga|1|flyway-test-extensions contains all project jars.

Project

This extension gives the ability to reset and/or fill the database with defined content.
With this precondition, each test provides a reproducible database start point.

  • Annotation FlywayTest for database unit testing. Use Flyway feature.

    • clean - execution of flyway task clean
    • init - execution of flyway task init
    • migrate - execution of flyway task migrate
  • Annotation FlywayTest for a single database control.
    Annotation FlywayTests if more than one database must be controlled during a test.
    Annotations can be used

    Test Setup Junit 4 Junit 5 TestNG
    Once per Class
    Once per Class with test annotation @BeforeClass @BeforeAll @BeforeClass
    Once per Method @Before @BeforeEach @BeforeMethod
    per Method @Test @Test @Test
  • Sample projects on how to use the annotations inside a unit testing environment

  • Additional project supports a DBUnit annotation use together with FlywayTest DBUnitSupport. A usage example you will find at UsageFlywayDBUnitTest.

How to use it

The flyway test extensions are available at Maven Central.

For a detail usage description see the UsageFlywaySpringTest usage page.
Attention:

  • this version has a default dependency on Spring 6. Examples show also how to use it with older versions.
  • The project is build with Java 8 compiler settings for backward compatibility.
    If other compiler classes are needed use flyway-test-spring5 or flyway-test-spring4.
  • Important: for usage with Flyway version 9, and spring properties spring.flyway.clean-disabled=false should be set to false otherwise CleanDB will not work.

Integration

  • Add dependency to flyway-spring-test to your Maven pom file
    <dependency>
       <groupId>org.flywaydb.flyway-test-extensions</groupId>
       <artifactId>flyway-spring-test</artifactId>
       <version>10.0.0</version>
       <scope>test</scope>
    </dependency>
  • Extend your test class with the Spring test runner annotation (Junit 4). The context file should be part of your test project.
    @RunWith(SpringRunner.class)
    @ContextConfiguration(locations = {"/context/simple_applicationContext.xml" })
    @TestExecutionListeners({DependencyInjectionTestExecutionListener.class, 
                             FlywayTestExecutionListener.class })
  • Add the @FlywayTest annotation on each class or method were you need a clean database. You can also use the anntotation on class basis and every test method in the class where a clean database is also needed.
    // usage as once per class
    @FlywayTest
    public class Spring4JUnitTest 

    // another TestClass
    
    public class Spring4JUnitTest {
    
    // usage as per test method
    @Test
    @FlywayTest
    public void testMethod() { 
  • Add the @FlywayTests with @FlywayTest annotation on each class or method were you need a clean multiple database setup.
    // usage as once per class
    @FlywayTests(value = {
	@FlywayTest(flywayName = "flyway1"),   // Flyway configuration for database 1
	@FlywayTest(flywayName = "flyway2")    // Flyway configuration for database 2
    })
    public class Spring4JUnitTest 

    // another TestClass
    
    public class Spring4JUnitTest {
    
    // usage as per test method
    @Test
    @FlywayTests(value = {
	@FlywayTest(flywayName = "flyway3"), // Flyway configuration for database 3
	@FlywayTest(flywayName = "flyway4")  // Flyway configuration for database 4
    })
    public void testMethod() { 
  • Junit 5 support is only available together with Spring5 or newer and need a different Spring setup.
    A step by step setup can be found here.
@ExtendWith({SpringExtension.class})
@ExtendWith({FlywayTestExtension.class})
@ContextConfiguration(locations = { "/context/simple_applicationContext.xml" })
@FlywayTest         // as class annotation
public class Junit5SpringTest ...

    @BeforeEach
    @FlywayTest(locationsForMigrate = {"loadmsqlbefore"})  // together with BeforeEach
    public void before() {
    ...

    @Test
    @FlywayTest       // as method annotation
    public void testMethodLoad() {
  • TestNG support is only available with Spring5 or newer and need a different Test setup.
@ContextConfiguration(locations = {"/context/simple_applicationContext.xml"})
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class,
        FlywayTestExecutionListener.class})
@Test
@FlywayTest(locationsForMigrate = {"loadmsql"}) // execution once per class
public class MethodTest extends AbstractTestNGSpringContextTests {
    
    @BeforeClass
    @FlywayTest(locationsForMigrate = {"loadmsql"}) // execution once per class
    public static void beforeClass(
    
    @BeforeMethod
    @FlywayTest(locationsForMigrate = {"loadmsql"}) // execution before each test method
    public void beforeMethod(


    @Test
    @FlywayTest(locationsForMigrate = {"loadmsql"}) // as method annotation
    public void simpleCountWithoutAny(

Project depend on

  • Flyway (10.6.0), and show also examples for version 9.16.1 and 8.5.13
  • Spring Framework test, context, jdbc (6.0.7, 5.2.6, 4.3.30)

Notes

  • The project depends on flyway version 10.6.0
  • The project will be supported until the extension will be integrated into the flyway project.
  • The project depends on Spring version 6.x (see flyway-spring6-test)
  • The project depends on Spring version 5.x (see flyway-spring5-test)
  • The project depends on Spring version 4.x (see flyway-spring4-test and flyway-dbunit-spring4-test)
  • At the moment the code is tested with database H2 and Oracle.
    Only the DBunit part contains database specific code.
  • it shows also examples how different version from flyway can be used with Spring Boot 2.x and 3.x. See the example projects SpringBoot 2 test example (FlywayTestApplicationTest ) and SpringBoot 3 test example (FlywayTestApplicationTest )

flyway-test-extensions's People

Contributors

bloomper avatar dependabot[bot] avatar eddumelendez avatar florian-e-zeiss avatar floriangwe avatar hafarey avatar ka1amita avatar madhur avatar stlhrt avatar sullis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

flyway-test-extensions's Issues

ERROR: cannot drop type <type> because extension <extension> requires it

I am using

<dependency>
    <groupId>org.flywaydb.flyway-test-extensions</groupId>
    <artifactId>flyway-spring-test</artifactId>
    <version>5.0.0</version>
    <scope>test</scope>
</dependency>

With Spring Boot 2.0.1.RELEASE with the following configuration:

@RunWith(SpringRunner.class)
@SpringBootTest(
        webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, 
        properties = "spring.profiles.active=test")
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
@TestExecutionListeners({
        DependencyInjectionTestExecutionListener.class,
        FlywayTestExecutionListener.class
})
public abstract class AbstractLiveTest {
}

However, if I run my unit tests Flyway does not seem to be able to drop the installed extension.

These extensions are installed in my initial V1__initialize.sql script.

org.flywaydb.core.internal.exception.FlywaySqlException: 
Unable to clean schema "public"
-------------------------------
SQL State  : 2BP01
Error Code : 0
Message    : ERROR: cannot drop type cube because extension cube requires it
  Hint: You can drop extension cube instead.


	at org.flywaydb.core.internal.database.Schema.clean(Schema.java:151)
	at org.flywaydb.core.internal.command.DbClean$4.call(DbClean.java:179)
	at org.flywaydb.core.internal.command.DbClean$4.call(DbClean.java:176)
	at org.flywaydb.core.internal.util.jdbc.TransactionTemplate.execute(TransactionTemplate.java:75)
	at org.flywaydb.core.internal.command.DbClean.cleanSchema(DbClean.java:176)
	at org.flywaydb.core.internal.command.DbClean.clean(DbClean.java:124)
	at org.flywaydb.core.Flyway$3.execute(Flyway.java:1306)
	at org.flywaydb.core.Flyway$3.execute(Flyway.java:1299)
	at org.flywaydb.core.Flyway.execute(Flyway.java:1655)
	at org.flywaydb.core.Flyway.clean(Flyway.java:1299)
	at org.flywaydb.test.FlywayTestExecutionListener.dbResetWithAnnotation(FlywayTestExecutionListener.java:378)
	at org.flywaydb.test.FlywayTestExecutionListener.handleFlywayTestAnnotationForClass(FlywayTestExecutionListener.java:178)
	at org.flywaydb.test.FlywayTestExecutionListener.beforeTestClass(FlywayTestExecutionListener.java:157)
	at org.springframework.test.context.TestContextManager.beforeTestClass(TestContextManager.java:215)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:60)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.postgresql.util.PSQLException: ERROR: cannot drop type cube because extension cube requires it
  Hint: You can drop extension cube instead.
	at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2477)
	at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2190)
	at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:300)
	at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:428)
	at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:354)
	at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:169)
	at org.postgresql.jdbc.PgPreparedStatement.execute(PgPreparedStatement.java:158)
	at com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
	at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.execute(HikariProxyPreparedStatement.java)
	at org.flywaydb.core.internal.util.jdbc.JdbcTemplate.execute(JdbcTemplate.java:246)
	at org.flywaydb.core.internal.database.postgresql.PostgreSQLSchema.doClean(PostgreSQLSchema.java:90)
	at org.flywaydb.core.internal.database.Schema.clean(Schema.java:149)
	... 22 more

Is there an easy workaround?

Extract Annotation to own module

For future support of guice the annotation should be provided in a own module.

This will be possible for

  • FlywayTest
  • DbUnitSupport

Strange exception when running tests in CI

Hi,

I'm getting a very strange exception when running tests that use flyway extension in the CI box (bamboo). Tests seem to work perfectly fine locally. It appears that configuration cannot be found.

This is how our tests are annotated. Application.class is the java spring config. We are using spring boot and all of our db settings come from application.properties.

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@TransactionConfiguration
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, FlywayTestExecutionListener.class })
@FlywayTest

This is the exception we are seeing in the CI box:

org.flywaydb.test.junit.FlywayTestExecutionListener@54997f67] to process 'before class' callback for test class [class com.test.service.FormActualServiceTest]
build   18-Mar-2015 14:05:52    
build   18-Mar-2015 14:05:52    java.lang.IllegalArgumentException: Annotation class com.sun.proxy.$Proxy10 was set, but no Flyway configuration was given.
build   18-Mar-2015 14:05:52        at org.flywaydb.test.junit.FlywayTestExecutionListener.dbResetWithAnotation(FlywayTestExecutionListener.java:280)
build   18-Mar-2015 14:05:52        at org.flywaydb.test.junit.FlywayTestExecutionListener.beforeTestClass(FlywayTestExecutionListener.java:152)
build   18-Mar-2015 14:05:52        at org.springframework.test.context.TestContextManager.beforeTestClass(TestContextManager.java:179)
build   18-Mar-2015 14:05:52        at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:60)
build   18-Mar-2015 14:05:52        at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
build   18-Mar-2015 14:05:52        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
build   18-Mar-2015 14:05:52        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
build   18-Mar-2015 14:05:52        at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:264)
build   18-Mar-2015 14:05:52        at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
build   18-Mar-2015 14:05:52        at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:124)
build   18-Mar-2015 14:05:52        at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:200)
build   18-Mar-2015 14:05:52        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:153)
build   18-Mar-2015 14:05:52        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)

Any help would be greatly appreciated.

Thanks,
-Paul

Migrate is called only on first test run

Hi

I'm not sure is this flyway-test-extensions or flyway issue (or issue at all ;)), but I'll post it here.

So I have sql file called V1__schema.sql and it looks like this:

drop schema if exists system_user cascade;
create schema system_user;

create table system_user.system_user ...

drop schema if exists security cascade;
create schema security;

create table security.role ...
create table security.user_role ...
create table security.permission ...
create table security.role_permission ...

After running one test annotated with @FlywayTest against clean database, new rows are inserted but after the method has executed the data in tables is not cleared by the drop schema and create table commands. And the the schema_version table looks like this:
http://i.imgur.com/eaCGikm.png

But if I change the name of the sql file to V2__schema.sql and run it against clean database, it works, on every run. And the the schema_version table looks like this:
http://imgur.com/mGM8lmr.png

Is this normal behaviour?

And if it matters, this is how I have configured my Flyway bean:

@Bean(initMethod = "migrate")
public Flyway flyway() {
    Flyway flyway = new Flyway();

    flyway.setDataSource(dataSource());
    flyway.setSchemas("flyway");

    return flyway;
}

Release Version 2.3.0.1

When next release with spring 4 support will be published?

  • New description for spring 4 pages are needed.
  • Warning about spring 3 dependency for default modules needed.

@FlywayTest is superfluous

Why do we need to annotate the test with @FlywayTest?? The test is already annotated with FlywayTestExecutionListener, which should let the Listener know that the test needs test data.

Would it be possible to just assume the defaults if @FlywayTest isn't present?

Multiple database migrations in tests

Hi,

My Spring Boot app needs to talk to two separate databases. Ideally, I'd like to have two separate sets of migrations, which would both be executed when I annotate my tests with FlywayTest.

The FlywayTestExecutionListener looks for a single Flyway bean in the context and uses it for migration. I guess I could write my own TextExecutionListener, which would get all Flyway beans in the context and migrate them all. Does that sound ok? - if not, what would you suggest?

Regards

Add functionality to reset DB state before each test in a test class (without explicitly adding @FlywayTest to every test)

It is a common use case to reset the DB-state to a known base-state before each test, so they can all be run independently of each other, and not pass/break depending on which tests were run previously. I cannot find a simple way to perform this use case with this library.

I initially expected that annotating the test class with @FlywayTest would be the same as adding the annotation to every test, i.e. would reset the DB-state (maybe by performing a clean & migrate) before every single test in that test class.
However, per the documentation of org.flywaydb.test.junit.FlywayTestExecutionListener

If the annotation FlywayTest used on class level a clean , init , migrate cycle is done during class load.

it seems that adding the annotation at the class level will only perform these actions before the first test, not before every test.

I feel that having to add this annotation to every test is unnecessary boilerplate I want to avoid. One solution is as explained in https://stackoverflow.com/a/41929329/854151 by explicitly autowiring-in the Flyway instance and calling clean() and migrate() on it in a @Before-method. But, since the @FlywayTest annotation already exists and is intended to do pretty much what we want, it would be better to change the behaviour of this annotation instead.

Possible solutions using the @FlywayTest annotation:

  • Changing the behaviour of @FlywayTest when used on class level. This might not be preferable, as it will change the behaviour of existing code.
  • Adding an option/element to @FlywayTest allowing us to specify whether we want the behaviour to trigger only once for the class, or once for each test. For comparison, see the 4 different available options of the classMode element of annotation @org.springframework.test.annotation.DirtiesContext: BEFORE_CLASS, BEFORE_EACH_TEST_METHOD, AFTER_EACH_TEST_METHOD, AFTER_CLASS. This strikes me as the best option.
  • Make the @FlywayTest work together with @Before or @After annotations, when both annotations are present on the same method. This approach would work, but is a little inelegant if you have to create a method that would otherwise be empty, just so you can apply to annotations to it. See: https://stackoverflow.com/questions/18390817/junit-testing-flyway-can-you-combine-before-and-flyway-annotations

No source or target Java version settings in POM

Currently released 3.0 JAR contains classes compatible with Java 7+ only.
Since Spring extensions target also Spring 3 which supports Java 1.5 this should be the minimum source and target compatibility for flyway-spring3-test and Java 6 for the rest of artifacts.

Flyway 5.1.x support

Any plans for this?
It's needed in order to be able to execute flyway in tests which use Spring 5.1.X / Spring Boot 2.1.X

@FlywayTest not working on abstract classes?

So I am having this abstract class to make life easier with unit tests:

@RunWith(SpringRunner.class)
@SpringBootTest(
        webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,
        properties = "spring.profiles.active=test")
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
@TestExecutionListeners({
        DependencyInjectionTestExecutionListener.class,
        FlywayTestExecutionListener.class
})
@FlywayTest
public abstract class AbstractLiveTest {

    @Value("${security.jwt.client-id}")
    protected String clientId;

    @Value("${security.jwt.client-secret}")
    protected String clientSecret;

    @Value("${security.jwt.client-secret-plain}")
    protected String clientSecretPlain;

    @Value("${server.port}")
    protected Integer serverPort;

    @Autowired
    protected TestRestTemplate template;

}

Notice the @FlywayTest annotation. This does not seem to work. I have to add @FlywayTest to all test classes separately e.g.

@FlywayTest
public class MyTests extends AbstractLiveTest {
}

otherwise it won't work. I do not know if this is expected or even intended but I thought I raise that issue here in case it isn't.


I am using org.flywaydb:flyway-core and org.flywaydb.flyway-test-extensions:flyway-spring-test in a Spring Boot (2.0.1.RELEASE) application.

<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
</dependency>
<dependency>
    <groupId>org.flywaydb.flyway-test-extensions</groupId>
    <artifactId>flyway-spring-test</artifactId>
    <version>5.0.0</version>
    <scope>test</scope>
</dependency>
$ mvn dependency:tree
..
[INFO] +- org.flywaydb:flyway-core:jar:5.0.7:compile
[INFO] +- org.flywaydb.flyway-test-extensions:flyway-spring-test:jar:5.0.0:test
..

Remove dependency to slf4j-simple

All your spring libraries contain a dependency to the Simple Log Implementation of SLF4J. Please remove all of them. A library should never ever come with a dependency to an slf4j log implementation. The whole purpose of slf4j is the separation of API and implementation, so that the user of the library has the ability to add the logging implementation of his choice. Because there is only one logging implementation per VM allowed, all users now are forced to explicitly exclude the simple log jar if they want a different logging implementation.

Otherwise: Very useful extension!

Cheers,

Andreas

Working with multiple datasources

Hey all !

I would like to propose a feature - support for multiple datasources. You could easily (at least I think so) achieve that by extending @FlywayTest annotation and FlywayTestExecutionListener class. This could look like this:

@Retention(RetentionPolicy.RUNTIME)
public @interface FlywayTest {
  // current implementation goes here
  public String datasourceName() default "";
  // more current implementation goes here
}

In FlywayTestExecutionListener when reading from Spring context you are just picking correct datasource. I put default to empty String so :

  • this change will not break any current code
  • empty string could be an indicator that default datasource should be used

Hope you like the idea !

org.postgresql.util.PSQLException: ERROR: cached plan must not change result type

I randomly receive the following error when running my tests on CI. It does not happen locally. I believe it is a race condition related to dropping a type.

Stack trace from gradle ./gradlew clean test

 org.springframework.orm.jpa.JpaSystemException: could not extract ResultSet; nested exception is org.hibernate.exception.GenericJDBCException: could not extract ResultSet
        at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:333)
        at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:244)
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:488)
        at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
        at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
        at com.sun.proxy.$Proxy179.findByUsernameOrEmailEager(Unknown Source)
        at io.sumu.backend.user.UserServiceImpl.findByUsernameOrEmail(UserServiceImpl.java:166)
        at sun.reflect.GeneratedMethodAccessor259.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
        at org.springframework.cache.interceptor.CacheInterceptor$1.invoke(CacheInterceptor.java:52)
        at org.springframework.cache.interceptor.CacheAspectSupport.invokeOperation(CacheAspectSupport.java:345)
        at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:408)
        at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:327)
        at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
        at com.sun.proxy.$Proxy193.findByUsernameOrEmail(Unknown Source)
        at io.sumu.backend.security.FacebookAuthenticationProvider.retrieveUser(FacebookAuthenticationProvider.java:199)
        at io.sumu.backend.security.FacebookAuthenticationProvider.authenticate(FacebookAuthenticationProvider.java:84)
        at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174)
        at io.sumu.backend.security.FacebookLoginFilter.attemptAuthentication(FacebookLoginFilter.java:55)
        at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at io.sumu.backend.security.StatelessAuthenticationFilter.doFilter(StatelessAuthenticationFilter.java:28)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
        at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
        at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:155)
        at io.sumu.backend.user.FacebookLoginTests.createsNewUser_whenLoggingInWithFacebook_withoutExistingUserMatchingEmail(FacebookLoginTests.java:111)

        Caused by:
        org.hibernate.exception.GenericJDBCException: could not extract ResultSet
            at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
            at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111)
            at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:97)
            at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:69)
            at org.hibernate.loader.Loader.getResultSet(Loader.java:2178)
            at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1941)
            at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1903)
            at org.hibernate.loader.Loader.doQuery(Loader.java:948)
            at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:351)
            at org.hibernate.loader.Loader.doList(Loader.java:2702)
            at org.hibernate.loader.Loader.doList(Loader.java:2685)
            at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2517)
            at org.hibernate.loader.Loader.list(Loader.java:2512)
            at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:502)
            at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:384)
            at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216)
            at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1490)
            at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1445)
            at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1414)
            at org.hibernate.query.Query.getResultList(Query.java:146)
            at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:121)
            at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:85)
            at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:116)
            at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:106)
            at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:483)
            at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:461)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
            at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:56)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
            at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
            at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
            at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
            at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
            ... 46 more

            Caused by:
            org.postgresql.util.PSQLException: ERROR: cached plan must not change result type
                at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2477)
                at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2190)
                at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:300)
                at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:428)
                at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:354)
                at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:169)
                at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:117)
                at sun.reflect.GeneratedMethodAccessor24.invoke(Unknown Source)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                at java.lang.reflect.Method.invoke(Method.java:498)
                at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114)
                at com.sun.proxy.$Proxy105.executeQuery(Unknown Source)
                at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:60)
                ... 76 more

Lifecycle:

public class MigrationLifecycle implements FlywayCallback {
  @Override
  public void beforeClean(Connection connection) {
    try {
      connection.prepareStatement("DROP EXTENSION IF EXISTS \"hstore\"; DROP EXTENSION IF EXISTS \"postgis\" CASCADE; DROP SCHEMA IF EXISTS \"analytics\" CASCADE;").execute();
    } catch (SQLException e) {
      throw new RuntimeException("message:" + e.getMessage(), e.getCause());
    }
  }

  @Override
  public void afterClean(Connection connection) {
    try {
      // uuid-ossp has to be dropped after clean since some tables require the extension to be present
      connection.prepareStatement("DROP EXTENSION IF EXISTS \"uuid-ossp\";").execute();
    } catch (SQLException e) {
      throw new RuntimeException("message:" + e.getMessage(), e.getCause());
    }
  }

  @Override
  public void beforeMigrate(Connection connection) {

  }

  @Override
  public void afterMigrate(Connection connection) {

  }

  @Override
  public void beforeEachMigrate(Connection connection, MigrationInfo info) {

  }

  @Override
  public void afterEachMigrate(Connection connection, MigrationInfo info) {

  }

  @Override
  public void beforeValidate(Connection connection) {

  }

  @Override
  public void afterValidate(Connection connection) {

  }

  @Override
  public void beforeBaseline(Connection connection) {

  }

  @Override
  public void afterBaseline(Connection connection) {

  }

  @Override
  public void beforeRepair(Connection connection) {

  }

  @Override
  public void afterRepair(Connection connection) {

  }

  @Override
  public void beforeInfo(Connection connection) {

  }

  @Override
  public void afterInfo(Connection connection) {

  }
}

Spring Boot Application:

  @Bean(initMethod = "migrate")
  @ConfigurationProperties(prefix = "flyway")
  public Flyway flyway(DataSource dataSource) {
    Flyway flyway = new Flyway();
    flyway.setDataSource(dataSource);
    flyway.setSqlMigrationPrefix("");
    flyway.setSchemas("public", "analytics");
    flyway.setCallbacks(new MigrationLifecycle());
    return flyway;
  }

Test

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT, properties = {"management.port=0"})
@ActiveProfiles("test")
@TestExecutionListeners(value = FlywayTestExecutionListener.class, mergeMode = MERGE_WITH_DEFAULTS)
@FlywayTest
@Transactional
public abstract class AbstractWebIntegrationTest {

Change Flyway Test groupid

Flyway change the group id of the maven deployment structure.
Flyway Test should do similar step to follow the new structure

@Flywaytest when using different application.properties

Hi,

I'm using flyway with springboot and want to use flyway-test-extensions to make life easier with testing.

In my test folder, I'm using a different application.properties in order to change the database to a different one (using the spring.datasource property). My JPA is configured as follows:

# jpa config
spring.jpa.database=POSTGRESQL
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=validate

These are the annotations that I'm using.

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class,
FlywayTestExecutionListener.class })
@FlywayTest
public class CaseServiceImplTest {
}

I have two migrations in my db.migration folder:

  • V1__init.sql
  • V2__second.sql

When I run my tests using the annotations above, it only seems to execute the V2__second.sql and not the V1_init.sql, and my test complains about missing tables (defined in V1__init.sql). However, when I leave out the following flyway-test-extensions annotations:

 @TestExecutionListeners({DependencyInjectionTestExecutionListener.class,
 FlywayTestExecutionListener.class })
 @FlywayTest

My tests run fine, and I can see that Flyway created the tables in my test-database defined in V1__init.sql as well as the ones in V2__second.sql. (This however requires that I clear out the wrongly migrated database by the first try with the annotations) But sadly I'm losing the functionality that @flywaytest offers.

I also tried variations of my JPA settings setting generate-ddl to false, and ddl-auto to none.

This could be a bug, but probably a mistake on my part. Any help with this would be appreciated.

Kind Regards,
@DenEwout

Avoid code dupplication for spring 3 and spring 4 support.

At the moment spring 3 and spring 4 support are done with code duplication.
Spring 3 and Spring 4 have compile incompatible changes:

  • TestContext in Spring 3 is a class
  • TestContext in Spring 4 is a inteface

Following projects for spring are effected:

  • flyway-spring-test
  • flyway-spring3-test
  • flyway-spring4-test

Following project for dbunit are effected:

  • flyway-dbunit-test
  • flyway-dbnit-spring3-test
  • flyway-dbunit-spring4-test

It should be tested if it is possible to use the source files from one module to use it in spring3 or spring4 and compile it against the correct Spring version again.

Feature request: migration version aware test method.

Hi
May I suggest a callback-like JUnit test method that should be invoked before/after migrating to specific version ?
The intention is to be able to test DB at specific version/state.
If this can be done with existing API, will be glad to get the guidlines.
Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.