Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IntegrationTest isolation fails in springboot 2.2.2.RELEASE (Error dopping tables after each SpringBootTest)

Our app is working in 2.0.4 release. After upgrade to 2.2.2.RELEASE we see integration tests failing. I suspect that there is some misconfiguration, and each integration test simply does not clean after itself or there is extra initialization which weren't here before. I really do not know how to fix it properly.

To be specific. Each test works when invoked separately. When executed all of them we do see errors like:

org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "drop table somewhere.sometable if exists" via JDBC Statement
...
caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Cannot drop "SOME_TABLE" because "FKKJEJC7GUX6OTX5NGANQCMN83R, FK7WLRCFA21PY7CI3R4OL1OWODT, FKQPMY4YOVD3D6HBNT0XX92149P, FK1TG6AMM2NSM6UJTO9EJHPJIXY, FKLPTBKDKFCHE72RJ5RRRIH4ORJ" depends on it; SQL statement:

and

2019-12-16 21:11:00.075 org.apache.tomcat.util.modeler.Registry  : The MBean registry cannot be disabled because it has already been initialised

which suggests me, that we're trying to re-initialize something already initialized + there is wrong order of drops in hibernate initialization. But I really cannot see anything wrong on our side. Lets show some excerpts:

annotations of test:

@RunWith(SpringRunner.class)
@ActiveProfiles(...)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class SomeIT {

tests are executed via:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-failsafe-plugin</artifactId>
  <version>2.22.2</version>
  <configuration>
    <useSystemClassLoader>false</useSystemClassLoader>
    <forkCount>0</forkCount>
    <reuseForks>false</reuseForks>
  </configuration>
  <executions>
    <execution>
      <id>integration-test</id>
      <goals>
        <goal>integration-test</goal>
      </goals>
    </execution>
    <execution>
      <id>verify</id>
      <goals>
        <goal>verify</goal>
      </goals>
    </execution>
  </executions>
</plugin>

and application.properties for tests:

spring.jpa.database=H2
spring.jpa.hibernate.ddl-auto=create
spring.jpa.properties.hibernate.jdbc.batch_size=5
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates=true
spring.jpa.properties.hibernate.jdbc.batch_versioned_data=true

#this disables option to have opened tx in view IIUC. We don't rely on that, so this just removes warning logging from console.
spring.jpa.open-in-view=false

#used to select db initialization scripts.
spring.datasource.platform=org.hibernate.dialect.H2Dialect

spring.datasource.url=jdbc:h2:mem:somewhere;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1;INIT=create schema if not exists somewhere
spring.datasource.driver-class-name = org.h2.Driver

#this is probably needed for @DataJpaTest: I have no idea how to configure @DataJpaTest so that it can run with
#autoconfigured H2 db, probably it's caused by having schema defined in entities. Anyways @DataJpaTest fails to
#create schema. So alternative is to configure one DB for whole app here, and this option forces all @DataJpaTest not to
#replace this configuration with autoconfigured db.
spring.test.database.replace=none

Tested changes:

  • I changed create to create-drop if it helps in any way and no, it does not help in any way.
  • I tried to @DirtiesContext on class level for every IT test, which is what I'd expect anyways, that context is created/killed with every IT test class, but that did not help either.
  • I tried to remove replace=none, but that just kills all unit tests(because schema is not created), and does not help in any way to integration tests.

Current workaround: well all I was able to come up with is not to reuse db. Which with replace=none is possible only via:

spring.datasource.url=jdbc:h2:mem:somewhere${random.uuid};DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1;INIT=create schema if not exists somewhere

but I deeply hate this "solution". What can cause incorrect db re-initialization / missing cleanups / or what the cause of all this could be?

(edit: if you know better title to this question, please suggest. Thanks).

like image 777
Martin Mucha Avatar asked Dec 16 '19 20:12

Martin Mucha


1 Answers

I had the same issue and unfortunately Melkor's answer did not work for us because our schema was too complex to write a script dropping tables in a correct order.

H2 supports dropping all objects regardless of their dependencies, so the following script can reset the whole db.

src/test/resources/drop-tables.sql

DROP ALL OBJECTS

Then, specify the test properties to use the script to drop tables

src/test/resources/application.properties

spring.jpa.properties.javax.persistence.schema-generation.drop-source=script
spring.jpa.properties.javax.persistence.schema-generation.drop-script-source=drop-tables.sql
like image 184
hota911 Avatar answered Dec 11 '22 05:12

hota911