diff --git a/core/testsuite/pom.xml b/core/testsuite/pom.xml
index ab3fca21d8..928887806a 100644
--- a/core/testsuite/pom.xml
+++ b/core/testsuite/pom.xml
@@ -35,6 +35,7 @@
1.8
${test.java.version}
com.blazebit.persistence.core.testsuite
+ com.blazebit.persistence.testsuite
@@ -81,7 +82,6 @@
test
-
org.mockito
@@ -115,7 +115,6 @@
activation
${version.activation}
-
@@ -167,12 +166,14 @@
org.apache.maven.plugins
maven-surefire-plugin
- com.blazebit.persistence.testsuite.base.jpa.category.NoH2,${jpa.excludedGroups}
+ CoreTestsuite
jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
admin
admin
org.h2.Driver
+ com.blazebit.persistence.testsuite.base.jpa.category.NoH2,${jpa.excludedGroups}
+ ${testBasePackage}
@@ -220,12 +221,14 @@
org.apache.maven.plugins
maven-surefire-plugin
- com.blazebit.persistence.testsuite.base.jpa.category.NoMySQL,com.blazebit.persistence.testsuite.base.jpa.category.NoMySQLOld,${jpa.excludedGroups}
+ CoreTestsuite
jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
root
com.mysql.jdbc.Driver
+ com.blazebit.persistence.testsuite.base.jpa.category.NoMySQL,com.blazebit.persistence.testsuite.base.jpa.category.NoMySQLOld,${jpa.excludedGroups}
+ ${testBasePackage}
@@ -273,12 +276,14 @@
org.apache.maven.plugins
maven-surefire-plugin
- com.blazebit.persistence.testsuite.base.jpa.category.NoMySQL,${jpa.excludedGroups}
+ CoreTestsuite
jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
root
com.mysql.jdbc.Driver
+ com.blazebit.persistence.testsuite.base.jpa.category.NoMySQL,${jpa.excludedGroups}
+ ${testBasePackage}
@@ -326,13 +331,15 @@
org.apache.maven.plugins
maven-surefire-plugin
- com.blazebit.persistence.testsuite.base.jpa.category.NoPostgreSQL,${jpa.excludedGroups}
+ CoreTestsuite
jdbc:postgresql://localhost:5432/test
postgres
postgres
org.postgresql.Driver
public
+ com.blazebit.persistence.testsuite.base.jpa.category.NoPostgreSQL,${jpa.excludedGroups}
+ ${testBasePackage}
@@ -380,12 +387,14 @@
org.apache.maven.plugins
maven-surefire-plugin
- com.blazebit.persistence.testsuite.base.jpa.category.NoSQLite,${jpa.excludedGroups}
+ CoreTestsuite
jdbc:sqlite:test.db
org.sqlite.JDBC
+ com.blazebit.persistence.testsuite.base.jpa.category.NoSQLite,${jpa.excludedGroups}
+ ${testBasePackage}
@@ -438,12 +447,14 @@
org.apache.maven.plugins
maven-surefire-plugin
- com.blazebit.persistence.testsuite.base.jpa.category.NoDB2,${jpa.excludedGroups}
+ CoreTestsuite
jdbc:db2://localhost:50000/test
db2inst1
db2inst1-pwd
com.ibm.db2.jcc.DB2Driver
+ com.blazebit.persistence.testsuite.base.jpa.category.NoDB2,${jpa.excludedGroups}
+ ${testBasePackage}
@@ -498,12 +509,14 @@
org.apache.maven.plugins
maven-surefire-plugin
- com.blazebit.persistence.testsuite.base.jpa.category.NoFirebird,${jpa.excludedGroups}
+ CoreTestsuite
jdbc:firebirdsql:localhost:/tmp/test.fdb
SYSDBA
masterkey
org.firebirdsql.jdbc.FBDriver
+ com.blazebit.persistence.testsuite.base.jpa.category.NoFirebird,${jpa.excludedGroups}
+ ${testBasePackage}
@@ -551,7 +564,7 @@
org.apache.maven.plugins
maven-surefire-plugin
- com.blazebit.persistence.testsuite.base.jpa.category.NoOracle,${jpa.excludedGroups}
+ CoreTestsuite
jdbc:oracle:thin:@localhost:1521:XE
SYSTEM
@@ -563,6 +576,8 @@
true
+ com.blazebit.persistence.testsuite.base.jpa.category.NoOracle,${jpa.excludedGroups}
+ ${testBasePackage}
@@ -610,12 +625,14 @@
org.apache.maven.plugins
maven-surefire-plugin
- com.blazebit.persistence.testsuite.base.jpa.category.NoMSSQL,${jpa.excludedGroups}
+ CoreTestsuite
jdbc:sqlserver://localhost:1433
sa
Blaze-Persistence
com.microsoft.sqlserver.jdbc.SQLServerDriver
+ com.blazebit.persistence.testsuite.base.jpa.category.NoMSSQL,${jpa.excludedGroups}
+ ${testBasePackage}
diff --git a/core/testsuite/src/test/java/com/blazebit/persistence/testsuite/CoreTestsuite.java b/core/testsuite/src/test/java/com/blazebit/persistence/testsuite/CoreTestsuite.java
new file mode 100644
index 0000000000..7e46534239
--- /dev/null
+++ b/core/testsuite/src/test/java/com/blazebit/persistence/testsuite/CoreTestsuite.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2014 - 2020 Blazebit.
+ *
+ * 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 com.blazebit.persistence.testsuite;
+
+import com.blazebit.persistence.testsuite.base.jpa.BlazePersistenceTestsuite;
+import org.junit.runner.RunWith;
+import org.junit.runners.AllTests;
+
+/**
+ *
+ * @author Moritz Becker
+ * @since 1.5.0
+ */
+@RunWith(AllTests.class)
+public class CoreTestsuite extends BlazePersistenceTestsuite {
+}
diff --git a/core/testsuite/src/test/java/com/blazebit/persistence/testsuite/DateExtractTest.java b/core/testsuite/src/test/java/com/blazebit/persistence/testsuite/DateExtractTest.java
index 01602992b5..0e0bdc1d9b 100644
--- a/core/testsuite/src/test/java/com/blazebit/persistence/testsuite/DateExtractTest.java
+++ b/core/testsuite/src/test/java/com/blazebit/persistence/testsuite/DateExtractTest.java
@@ -94,7 +94,7 @@ public static Collection> producerConsumerTimezones() {
protected boolean recreateDataSource() {
// Some drivers have timezone information bound to the connection
// So we have to recreate the data source to get the newly configured time zones for connections
- boolean recreate = previousProducerTimeZone != null && previousClientTimeZone != null && (!producerTimeZone.equals(previousProducerTimeZone) || !clientTimeZone.equals(previousClientTimeZone));
+ boolean recreate = !producerTimeZone.equals(previousProducerTimeZone) || !clientTimeZone.equals(previousClientTimeZone);
previousProducerTimeZone = producerTimeZone;
previousClientTimeZone = clientTimeZone;
return recreate;
diff --git a/entity-view/testsuite/pom.xml b/entity-view/testsuite/pom.xml
index 19b4380af8..ff3d7217f5 100644
--- a/entity-view/testsuite/pom.xml
+++ b/entity-view/testsuite/pom.xml
@@ -35,6 +35,7 @@
1.8
${test.java.version}
com.blazebit.persistence.view.testsuite
+ com.blazebit.persistence.view.testsuite
@@ -170,12 +171,14 @@
org.apache.maven.plugins
maven-surefire-plugin
- com.blazebit.persistence.testsuite.base.jpa.category.NoH2,${jpa.excludedGroups}
+ EntityViewTestsuite
jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
admin
admin
org.h2.Driver
+ com.blazebit.persistence.testsuite.base.jpa.category.NoH2,${jpa.excludedGroups}
+ ${testBasePackage}
@@ -205,12 +208,14 @@
org.apache.maven.plugins
maven-surefire-plugin
- com.blazebit.persistence.testsuite.base.jpa.category.NoMySQL,com.blazebit.persistence.testsuite.base.jpa.category.NoMySQLOld,${jpa.excludedGroups}
+ EntityViewTestsuite
jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
root
com.mysql.jdbc.Driver
+ com.blazebit.persistence.testsuite.base.jpa.category.NoMySQL,com.blazebit.persistence.testsuite.base.jpa.category.NoMySQLOld,${jpa.excludedGroups}
+ ${testBasePackage}
@@ -239,12 +244,14 @@
org.apache.maven.plugins
maven-surefire-plugin
- com.blazebit.persistence.testsuite.base.jpa.category.NoMySQL,${jpa.excludedGroups}
+ EntityViewTestsuite
jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
root
com.mysql.jdbc.Driver
+ com.blazebit.persistence.testsuite.base.jpa.category.NoMySQL,${jpa.excludedGroups}
+ ${testBasePackage}
@@ -273,13 +280,15 @@
org.apache.maven.plugins
maven-surefire-plugin
- com.blazebit.persistence.testsuite.base.jpa.category.NoPostgreSQL,${jpa.excludedGroups}
+ EntityViewTestsuite
jdbc:postgresql://localhost:5432/test
postgres
postgres
org.postgresql.Driver
public
+ com.blazebit.persistence.testsuite.base.jpa.category.NoPostgreSQL,${jpa.excludedGroups}
+ ${testBasePackage}
@@ -308,12 +317,14 @@
org.apache.maven.plugins
maven-surefire-plugin
- com.blazebit.persistence.testsuite.base.jpa.category.NoSQLite,${jpa.excludedGroups}
+ EntityViewTestsuite
jdbc:sqlite:test.db
org.sqlite.JDBC
+ com.blazebit.persistence.testsuite.base.jpa.category.NoSQLite,${jpa.excludedGroups}
+ ${testBasePackage}
@@ -347,12 +358,14 @@
org.apache.maven.plugins
maven-surefire-plugin
- com.blazebit.persistence.testsuite.base.jpa.category.NoDB2,${jpa.excludedGroups}
+ EntityViewTestsuite
jdbc:db2://localhost:50000/test:fullyMaterializeLobData=true;progressiveStreaming=2;
db2inst1
db2inst1-pwd
com.ibm.db2.jcc.DB2Driver
+ com.blazebit.persistence.testsuite.base.jpa.category.NoDB2,${jpa.excludedGroups}
+ ${testBasePackage}
@@ -388,12 +401,14 @@
org.apache.maven.plugins
maven-surefire-plugin
- com.blazebit.persistence.testsuite.base.jpa.category.NoFirebird,${jpa.excludedGroups}
+ EntityViewTestsuite
jdbc:firebirdsql:localhost:/tmp/test.fdb
SYSDBA
masterkey
org.firebirdsql.jdbc.FBDriver
+ com.blazebit.persistence.testsuite.base.jpa.category.NoFirebird,${jpa.excludedGroups}
+ ${testBasePackage}
@@ -422,7 +437,7 @@
org.apache.maven.plugins
maven-surefire-plugin
- com.blazebit.persistence.testsuite.base.jpa.category.NoOracle,${jpa.excludedGroups}
+ EntityViewTestsuite
jdbc:oracle:thin:@localhost:1521:XE
SYSTEM
@@ -434,6 +449,8 @@
true
+ com.blazebit.persistence.testsuite.base.jpa.category.NoOracle,${jpa.excludedGroups}
+ ${testBasePackage}
@@ -462,12 +479,14 @@
org.apache.maven.plugins
maven-surefire-plugin
- com.blazebit.persistence.testsuite.base.jpa.category.NoMSSQL,${jpa.excludedGroups}
+ EntityViewTestsuite
jdbc:sqlserver://localhost:1433
sa
Blaze-Persistence
com.microsoft.sqlserver.jdbc.SQLServerDriver
+ com.blazebit.persistence.testsuite.base.jpa.category.NoMSSQL,${jpa.excludedGroups}
+ ${testBasePackage}
diff --git a/entity-view/testsuite/src/test/java/com/blazebit/persistence/view/testsuite/EntityViewTestsuite.java b/entity-view/testsuite/src/test/java/com/blazebit/persistence/view/testsuite/EntityViewTestsuite.java
new file mode 100644
index 0000000000..70a5f837ab
--- /dev/null
+++ b/entity-view/testsuite/src/test/java/com/blazebit/persistence/view/testsuite/EntityViewTestsuite.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2014 - 2020 Blazebit.
+ *
+ * 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 com.blazebit.persistence.view.testsuite;
+
+import com.blazebit.persistence.testsuite.base.jpa.BlazePersistenceTestsuite;
+import org.junit.runner.RunWith;
+import org.junit.runners.AllTests;
+
+/**
+ *
+ * @author Moritz Becker
+ * @since 1.5.0
+ */
+@RunWith(AllTests.class)
+public class EntityViewTestsuite extends BlazePersistenceTestsuite {
+}
diff --git a/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/AbstractSpringTest.java b/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/AbstractSpringTest.java
index 94a026b185..f0b5d11c4b 100644
--- a/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/AbstractSpringTest.java
+++ b/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/AbstractSpringTest.java
@@ -58,8 +58,8 @@ public void setUpContext() throws Exception {
cleanDatabase();
this.em.getTransaction().rollback();
this.em.close();
- this.emf.close();
- this.emf = null;
+ emf.close();
+ emf = null;
this.em = null;
this.cbf = null;
this.jpaProvider = null;
diff --git a/parent/pom.xml b/parent/pom.xml
index 1778daa64e..a3490f3c4d 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -109,6 +109,7 @@
2.4.5.Final
1.7.0.Final
2.0.4.Final
+ 4.8.89
3.3.2
@@ -579,6 +580,11 @@
${mssql.version}
test
+
+ io.github.classgraph
+ classgraph
+ ${version.classgraph}
+
diff --git a/testsuite-base/datanucleus/src/main/java/com/blazebit/persistence/testsuite/base/AbstractPersistenceTest.java b/testsuite-base/datanucleus/src/main/java/com/blazebit/persistence/testsuite/base/AbstractPersistenceTest.java
index a802618321..835555c470 100644
--- a/testsuite-base/datanucleus/src/main/java/com/blazebit/persistence/testsuite/base/AbstractPersistenceTest.java
+++ b/testsuite-base/datanucleus/src/main/java/com/blazebit/persistence/testsuite/base/AbstractPersistenceTest.java
@@ -22,6 +22,7 @@
import org.datanucleus.store.StoreManager;
import org.datanucleus.store.connection.ConnectionManager;
import org.datanucleus.store.connection.ManagedConnection;
+import org.junit.Before;
import javax.persistence.EntityManager;
import java.lang.reflect.Method;
@@ -35,6 +36,17 @@
*/
public abstract class AbstractPersistenceTest extends AbstractJpaPersistenceTest {
+ // We need to recreate the emf because Datanucleus uses messed up metadata otherwise
+ @Before
+ public void recreateEmf() {
+ if (emf != null && emf.isOpen()) {
+ emf.close();
+ }
+ emf = null;
+ em = null;
+ init();
+ }
+
@Override
protected Properties applyProperties(Properties properties) {
properties.put("datanucleus.rdbms.mysql.characterSet", "utf8mb3");
diff --git a/testsuite-base/eclipselink/src/main/java/com/blazebit/persistence/testsuite/base/AbstractPersistenceTest.java b/testsuite-base/eclipselink/src/main/java/com/blazebit/persistence/testsuite/base/AbstractPersistenceTest.java
index 97f5bd1297..499739308a 100644
--- a/testsuite-base/eclipselink/src/main/java/com/blazebit/persistence/testsuite/base/AbstractPersistenceTest.java
+++ b/testsuite-base/eclipselink/src/main/java/com/blazebit/persistence/testsuite/base/AbstractPersistenceTest.java
@@ -23,6 +23,7 @@
import org.eclipse.persistence.sessions.factories.SessionManager;
import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import java.sql.Connection;
import java.util.HashMap;
@@ -93,7 +94,8 @@ protected void dropSchema() {
}
}
- protected void recreateOrClearSchema() {
+ @Override
+ protected EntityManagerFactory recreateOrClearSchema() {
Map emSetupImpls = EntityManagerFactoryProvider.getEmSetupImpls();
Map copy = new HashMap<>(emSetupImpls);
emSetupImpls.clear();
@@ -102,7 +104,7 @@ protected void recreateOrClearSchema() {
manager.getSessions().remove(emSetupImpl.getSessionName());
}
try {
- super.recreateOrClearSchema();
+ return super.recreateOrClearSchema();
} finally {
emSetupImpls.putAll(copy);
for (EntityManagerSetupImpl emSetupImpl : copy.values()) {
diff --git a/testsuite-base/hibernate/src/main/java/com/blazebit/persistence/testsuite/base/AbstractPersistenceTest.java b/testsuite-base/hibernate/src/main/java/com/blazebit/persistence/testsuite/base/AbstractPersistenceTest.java
index fe6eaf89d1..4681857094 100644
--- a/testsuite-base/hibernate/src/main/java/com/blazebit/persistence/testsuite/base/AbstractPersistenceTest.java
+++ b/testsuite-base/hibernate/src/main/java/com/blazebit/persistence/testsuite/base/AbstractPersistenceTest.java
@@ -174,6 +174,11 @@ protected Properties applyProperties(Properties properties) {
// Needed for Envers tests in Hibernate >= 5.3.5, 5.4.x (HHH-12871)
properties.put("hibernate.ejb.metamodel.population", "enabled");
+
+ if (isHibernate53Or54()) {
+ properties.put("hibernate.archive.scanner", "org.hibernate.boot.archive.scan.internal.DisabledScanner");
+ }
+
// We use the following only for debugging purposes
// Normally these settings should be disabled since the output would be too big TravisCI
// properties.put("hibernate.show_sql", "true");
@@ -318,4 +323,12 @@ private boolean isHibernate526OrOlder() {
int fix = Integer.parseInt(versionParts[2]);
return major < 5 || major == 5 && minor < 2 || major == 5 && minor == 2 && fix < 7;
}
+
+ private boolean isHibernate53Or54() {
+ String version = org.hibernate.Version.getVersionString();
+ String[] versionParts = version.split("[\\.-]");
+ int major = Integer.parseInt(versionParts[0]);
+ int minor = Integer.parseInt(versionParts[1]);
+ return major == 5 && (minor == 3 || minor == 4);
+ }
}
diff --git a/testsuite-base/jpa/pom.xml b/testsuite-base/jpa/pom.xml
index c24d0ac083..416decd6b7 100644
--- a/testsuite-base/jpa/pom.xml
+++ b/testsuite-base/jpa/pom.xml
@@ -32,6 +32,8 @@
com.blazebit.persistence.testsuite.base.jpa
+ 1.8
+ 1.8
@@ -71,5 +73,9 @@
junit
compile
+
+ io.github.classgraph
+ classgraph
+
\ No newline at end of file
diff --git a/testsuite-base/jpa/src/main/java/com/blazebit/persistence/testsuite/base/jpa/AbstractJpaPersistenceTest.java b/testsuite-base/jpa/src/main/java/com/blazebit/persistence/testsuite/base/jpa/AbstractJpaPersistenceTest.java
index 161af99fe1..e31214e621 100644
--- a/testsuite-base/jpa/src/main/java/com/blazebit/persistence/testsuite/base/jpa/AbstractJpaPersistenceTest.java
+++ b/testsuite-base/jpa/src/main/java/com/blazebit/persistence/testsuite/base/jpa/AbstractJpaPersistenceTest.java
@@ -37,6 +37,7 @@
import net.ttddyy.dsproxy.listener.QueryExecutionListener;
import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder;
import org.junit.After;
+import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
@@ -82,6 +83,7 @@
*/
public abstract class AbstractJpaPersistenceTest {
+ protected static EntityManagerFactory emf;
private static boolean resolvedNoop = false;
private static boolean databaseClean = false;
private static Class> lastTestClass;
@@ -99,7 +101,6 @@ public abstract class AbstractJpaPersistenceTest {
new OracleDatabaseCleaner.Factory()
);
- protected EntityManagerFactory emf;
protected EntityManager em;
protected CriteriaBuilderFactory cbf;
protected JpaProvider jpaProvider;
@@ -143,33 +144,36 @@ protected final void cleanDatabaseWithCleaner() {
return;
}
- boolean wasAutoCommit = false;
- Connection connection = getConnection(getEm());
- try {
- // Turn off auto commit if necessary
- wasAutoCommit = connection.getAutoCommit();
- if (wasAutoCommit) {
- connection.setAutoCommit(false);
- }
- // Clear the data with the cleaner
- databaseCleaner.clearData(connection);
- databaseClean = true;
- } catch (SQLException ex) {
+ try (Connection connection = dataSource.getConnection()) {
+ boolean wasAutoCommit = false;
try {
- connection.rollback();
- } catch (SQLException e1) {
- ex.addSuppressed(e1);
- }
-
- throw new RuntimeException(ex);
- } finally {
- if (wasAutoCommit) {
+ // Turn off auto commit if necessary
+ wasAutoCommit = connection.getAutoCommit();
+ if (wasAutoCommit) {
+ connection.setAutoCommit(false);
+ }
+ // Clear the data with the cleaner
+ databaseCleaner.clearData(connection);
+ databaseClean = true;
+ } catch (Exception ex) {
try {
- connection.setAutoCommit(true);
- } catch (SQLException ex) {
- throw new RuntimeException(ex);
+ connection.rollback();
+ } catch (SQLException e1) {
+ ex.addSuppressed(e1);
+ }
+
+ throw new RuntimeException(ex);
+ } finally {
+ if (wasAutoCommit) {
+ try {
+ connection.setAutoCommit(true);
+ } catch (SQLException ex) {
+ throw new RuntimeException(ex);
+ }
}
}
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
}
}
@@ -197,36 +201,16 @@ protected void clearCollections(EntityManager em, Class>... entityClasses) {
}
private void clearSchema() {
- clearSchema(getEm(), databaseCleaner);
+ clearSchema(databaseCleaner);
}
- public void clearSchema(EntityManager em, DatabaseCleaner databaseCleaner) {
- boolean wasAutoCommit = false;
- Connection connection = getConnection(em);
- try {
- // Turn off auto commit if necessary
- wasAutoCommit = connection.getAutoCommit();
- if (wasAutoCommit) {
- connection.setAutoCommit(false);
- }
+ public void clearSchema(DatabaseCleaner databaseCleaner) {
+ try (Connection connection = dataSource.getConnection()) {
+ connection.setAutoCommit(false);
// Clear the data with the cleaner
databaseCleaner.clearSchema(connection);
- } catch (SQLException ex) {
- try {
- connection.rollback();
- } catch (SQLException e1) {
- ex.addSuppressed(e1);
- }
-
- throw new RuntimeException(ex);
- } finally {
- if (wasAutoCommit) {
- try {
- connection.setAutoCommit(true);
- } catch (SQLException ex) {
- throw new RuntimeException(ex);
- }
- }
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
}
}
@@ -293,21 +277,24 @@ public void init() {
recreateTestClass = getClass();
dataSource.close();
dataSource = null;
+ closeEmf();
} else if (recreateTestClass != null && recreateTestClass != getClass()) {
recreateTestClass = null;
if (dataSource != null) {
dataSource.close();
dataSource = null;
}
+ closeEmf();
}
- emf = createEntityManagerFactory("TestsuiteBase", createProperties("none"));
-
// Disable query collecting
QueryInspectorListener.enabled = false;
QueryInspectorListener.collectSequences = false;
if (!resolvedNoop && databaseCleaner == null) {
+ if (dataSource == null) {
+ getDataSource(createProperties("none"));
+ }
try (Connection c = dataSource.getConnection()) {
DatabaseCleaner applicableCleaner = getDatabaseCleaner(c);
@@ -326,23 +313,30 @@ public void init() {
setLastDatabaseCleaner(getDefaultDatabaseCleaner());
}
+ if (veryFirstTest || schemaChanged) {
+ getDataSource(createProperties("none"));
+ emf = recreateOrClearSchema();
+ if (emf == null) {
+ emf = createEntityManagerFactory("TestsuiteBase", createProperties("none"));
+ }
+ } else if (emf == null || !emf.isOpen()) {
+ emf = createEntityManagerFactory("TestsuiteBase", createProperties("none"));
+ }
+
CriteriaBuilderConfiguration config = Criteria.getDefault();
config = configure(config);
cbf = config.createCriteriaBuilderFactory(emf);
jpaProvider = cbf.getService(JpaProvider.class);
dbmsDialect = cbf.getService(DbmsDialect.class);
- if (veryFirstTest || schemaChanged || !databaseCleaner.supportsClearSchema()) {
- recreateOrClearSchema();
- setUpOnce();
- } else if (firstTest) {
+ getEm();
+ if (firstTest) {
setUpOnce();
}
if (runTestInTransaction() && !getEm().getTransaction().isActive()) {
getEm().getTransaction().begin();
}
- getEm();
}
private EntityManager getEm() {
@@ -387,15 +381,12 @@ protected static void resetTimeZoneCaches() {
}
}
- protected void createSchema() {
+ protected EntityManagerFactory createSchema() {
EntityManagerFactory entityManagerFactory = createEntityManagerFactory("TestsuiteBase", createProperties("create"));
if (needsEntityManagerForDbAction()) {
- try {
- entityManagerFactory.createEntityManager().close();
- } finally {
- entityManagerFactory.close();
- }
+ entityManagerFactory.createEntityManager().close();
}
+ return entityManagerFactory;
}
protected void dropSchema() {
@@ -409,23 +400,20 @@ protected void dropSchema() {
}
}
- protected void dropAndCreateSchema() {
+ protected EntityManagerFactory dropAndCreateSchema() {
EntityManagerFactory entityManagerFactory = createEntityManagerFactory("TestsuiteBase", createProperties("drop-and-create"));
if (needsEntityManagerForDbAction()) {
- try {
- entityManagerFactory.createEntityManager().close();
- } finally {
- entityManagerFactory.close();
- }
+ entityManagerFactory.createEntityManager().close();
}
+ return entityManagerFactory;
}
- protected void recreateOrClearSchema() {
+ protected EntityManagerFactory recreateOrClearSchema() {
if (databaseCleaner.supportsClearSchema()) {
clearSchema();
- createSchema();
+ return createSchema();
} else {
- dropAndCreateSchema();
+ return dropAndCreateSchema();
}
}
@@ -451,21 +439,14 @@ protected boolean doesJpaMergeOfRecentlyPersistedEntityForceUpdate() {
@After
public void destruct() {
- EntityManagerFactory factory;
// NOTE: We need to close the entity manager or else we could run into a deadlock on some dbms platforms
// I am looking at you MySQL..
if (em != null && em.isOpen()) {
- factory = em.getEntityManagerFactory();
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
em.close();
em = null;
- } else {
- factory = emf;
- }
- if (factory != null && factory.isOpen()) {
- factory.close();
}
if (databaseCleaner != null && !databaseCleaner.supportsClearSchema()) {
@@ -475,6 +456,15 @@ public void destruct() {
if (dataSource != null && recreateDataSource()) {
dataSource.close();
dataSource = null;
+ closeEmf();
+ }
+ }
+
+ @AfterClass
+ public static void closeEmf() {
+ if (emf != null && emf.isOpen()) {
+ emf.close();
+ emf = null;
}
}
diff --git a/testsuite-base/jpa/src/main/java/com/blazebit/persistence/testsuite/base/jpa/BlazePersistenceTestsuite.java b/testsuite-base/jpa/src/main/java/com/blazebit/persistence/testsuite/base/jpa/BlazePersistenceTestsuite.java
new file mode 100644
index 0000000000..16d7596a8e
--- /dev/null
+++ b/testsuite-base/jpa/src/main/java/com/blazebit/persistence/testsuite/base/jpa/BlazePersistenceTestsuite.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2014 - 2020 Blazebit.
+ *
+ * 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 com.blazebit.persistence.testsuite.base.jpa;
+
+import io.github.classgraph.ClassGraph;
+import io.github.classgraph.ClassInfo;
+import io.github.classgraph.ClassInfoList;
+import io.github.classgraph.MethodInfoList;
+import io.github.classgraph.ScanResult;
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.TestSuite;
+import org.junit.Test;
+import org.junit.experimental.categories.Categories;
+import org.junit.runner.manipulation.NoTestsRemainException;
+import org.junit.runners.Parameterized;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * We use dynamic testsuites to group test executions by the used entity classes in order to minimize schema dropping
+ * and entity manager factory recreation inbetween tests.
+ *
+ * @author Moritz Becker
+ * @since 1.5.0
+ */
+public abstract class BlazePersistenceTestsuite {
+
+ public static TestSuite suite() {
+ Class>[] excludedGroups = loadExcludedGroups();
+ TestClasses testClasses = loadAndGroupTestClasses();
+
+ TestSuite suite = new TestSuite();
+
+ testClasses.groupedJpaPersistenceTests.values().stream()
+ .sorted(Comparator.comparing(group ->
+ group.stream().map(Class::getCanonicalName).sorted().collect(Collectors.joining())
+ ))
+ .flatMap(List::stream)
+ .map(testClass -> {
+ JUnit4TestAdapter jUnit4TestAdapter = new JUnit4TestAdapter(testClass);
+ try {
+ jUnit4TestAdapter.filter(Categories.CategoryFilter.exclude(excludedGroups));
+ return jUnit4TestAdapter;
+ } catch (NoTestsRemainException e) {
+ return null;
+ }
+ })
+ .filter(Objects::nonNull)
+ .forEach(suite::addTest);
+
+ testClasses.nonJpaPersistenceTests.stream()
+ .sorted(Comparator.comparing(Class::getCanonicalName))
+ .map(testClass -> {
+ JUnit4TestAdapter jUnit4TestAdapter = new JUnit4TestAdapter(testClass);
+ try {
+ jUnit4TestAdapter.filter(Categories.CategoryFilter.exclude(excludedGroups));
+ return jUnit4TestAdapter;
+ } catch (NoTestsRemainException e) {
+ return null;
+ }
+ })
+ .filter(Objects::nonNull)
+ .forEach(suite::addTest);
+
+ return suite;
+ }
+
+ private static TestClasses loadAndGroupTestClasses() {
+ String testsuitePackage = System.getProperty("testBasePackage");
+ Map>, List>> groupedJpaPersistenceTests;
+ Set> nonJpaPersistenceTests = new HashSet<>();
+ try (ScanResult scanResult =
+ new ClassGraph()
+ .enableAnnotationInfo()
+ .enableMethodInfo()
+ .enableClassInfo()
+ .enableExternalClasses()
+ .acceptPackages(testsuitePackage)
+ .scan()) {
+
+ ClassInfoList allTests = scanResult.getClassesWithMethodAnnotation(Test.class.getName());
+ ClassInfoList potentialJpaPersistenceTests = scanResult.getSubclasses(AbstractJpaPersistenceTest.class.getName());
+
+ Set jpaPersistenceTests = new HashSet<>();
+ for (ClassInfo testClass : allTests) {
+ if (potentialJpaPersistenceTests.contains(testClass)) {
+ jpaPersistenceTests.add(testClass);
+ } else {
+ try {
+ nonJpaPersistenceTests.add(Thread.currentThread().getContextClassLoader().loadClass(testClass.getName()));
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ groupedJpaPersistenceTests = jpaPersistenceTests.stream()
+ .collect(Collectors.groupingBy(
+ jpaPersistenceTestInfo -> {
+ AbstractJpaPersistenceTest jpaPersistenceTest = instantiateAbstractJpaPersistenceTest(jpaPersistenceTestInfo);
+ return getEntityClasses(jpaPersistenceTest);
+ },
+ Collectors.mapping(jpaPersistenceTestInfo -> {
+ try {
+ return (Class) Thread.currentThread().getContextClassLoader().loadClass(jpaPersistenceTestInfo.getName());
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }, Collectors.toList())
+ ));
+ }
+ return new TestClasses(groupedJpaPersistenceTests, nonJpaPersistenceTests);
+ }
+
+ private static Class>[] loadExcludedGroups() {
+ String excludedGroupsProperty = System.getProperty("excludedGroups");
+ Class>[] excludedGroups;
+ if (excludedGroupsProperty == null) {
+ excludedGroups = new Class>[0];
+ } else {
+ excludedGroups = Arrays.stream(excludedGroupsProperty.split(","))
+ .map(groupName -> {
+ try {
+ return Thread.currentThread().getContextClassLoader().loadClass(groupName.trim());
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }).toArray(Class>[]::new);
+ }
+ return excludedGroups;
+ }
+
+ private static Set> getEntityClasses(AbstractJpaPersistenceTest jpaPersistenceTest) {
+ try {
+ Method m = AbstractJpaPersistenceTest.class.getDeclaredMethod("getEntityClasses");
+ m.setAccessible(true);
+ return new HashSet<>(Arrays.asList((Class>[]) m.invoke(jpaPersistenceTest)));
+ } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static AbstractJpaPersistenceTest instantiateAbstractJpaPersistenceTest(ClassInfo testClassInfo) {
+ AbstractJpaPersistenceTest testInstance;
+ Class testClass;
+ try {
+ testClass = (Class) Thread.currentThread().getContextClassLoader().loadClass(testClassInfo.getName());
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ MethodInfoList parametersMethods = testClassInfo.getMethodInfo()
+ .filter(methodInfo -> methodInfo.getAnnotationInfo(Parameterized.Parameters.class.getName()) != null);
+ if (parametersMethods.isEmpty()) {
+ try {
+ testInstance = testClass.newInstance();
+ } catch (InstantiationException | IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ } else if (parametersMethods.size() == 1) {
+ try {
+ Method parametersMethod = testClass.getMethod(parametersMethods.get(0).getName());
+ Object parameters = parametersMethod.invoke(null);
+ Object[] firstParameterSet;
+ if (parameters instanceof Collection) {
+ firstParameterSet = (Object[]) ((Collection>) parameters).iterator().next();
+ } else {
+ firstParameterSet = (Object[]) ((Object[]) parameters)[0];
+ }
+ Constructor targetConstructor = (Constructor) Arrays.stream(testClass.getConstructors())
+ .filter(constructor -> constructor.getParameterCount() == firstParameterSet.length)
+ .findFirst().get();
+ testInstance = targetConstructor.newInstance(firstParameterSet);
+ } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ } else {
+ throw new RuntimeException(
+ "Found more than 1 method annotated with " +
+ Parameterized.Parameters.class.getName() +
+ " in test class " + testClassInfo.getName());
+ }
+ return testInstance;
+ }
+
+ private static final class TestClasses {
+ private final Map>, List>> groupedJpaPersistenceTests;
+ private final Set> nonJpaPersistenceTests;
+
+ private TestClasses(Map>, List>> groupedJpaPersistenceTests, Set> nonJpaPersistenceTests) {
+ this.groupedJpaPersistenceTests = groupedJpaPersistenceTests;
+ this.nonJpaPersistenceTests = nonJpaPersistenceTests;
+ }
+ }
+}