From b7676aa1563aeddf3d663ef7366683a16a8e89c9 Mon Sep 17 00:00:00 2001 From: loic_lefevre Date: Wed, 10 Sep 2025 16:09:45 +0200 Subject: [PATCH 1/2] HHH-19762 - Enable Parallel Testing for OTP --- .../AgroalTransactionIsolationConfigTest.java | 4 +- ...rallelTestingAgroalConnectionProvider.java | 23 +++++ ...reparedStatementSpyConnectionProvider.java | 3 +- .../src/test/resources/hibernate.properties | 2 +- .../C3p0TransactionIsolationConfigTest.java | 3 +- .../OracleSQLCallableStatementProxyTest.java | 4 +- ...ParallelTestingC3P0ConnectionProvider.java | 23 +++++ .../src/test/resources/hibernate.properties | 2 +- hibernate-core/hibernate-core.gradle | 6 ++ .../test/jpa/pack/cfgxmlpar/hibernate.cfg.xml | 3 +- .../defaultpar/META-INF/persistence.xml | 1 + .../defaultpar_1_0/META-INF/persistence.xml | 1 + .../excludehbmpar/META-INF/persistence.xml | 1 + .../explicitpar/META-INF/persistence.xml | 1 + .../explicitpar2/META-INF/persistence.xml | 1 + .../explodedpar/META-INF/persistence.xml | 1 + .../overridenpar/overridenpar.properties | 3 +- .../space par/META-INF/persistence.xml | 1 + .../WEB-INF/classes/META-INF/persistence.xml | 1 + .../orm/test/datasource/DataSourceTest.java | 2 +- .../jakarta/JakartaSchemaToolingTests.java | 9 +- .../test/util/connections/BaseDataSource.java | 3 + .../src/test/resources/hibernate.properties | 3 +- .../xml/jakarta/simple/persistence.xml | 1 + hibernate-envers/hibernate-envers.gradle | 6 ++ .../src/test/resources/hibernate.properties | 3 +- .../HikariTransactionIsolationConfigTest.java | 4 +- ...llelTestingHikariCPConnectionProvider.java | 23 +++++ .../src/test/resources/hibernate.properties | 2 +- .../src/test/resources/hibernate.properties | 3 +- .../src/test/resources/hibernate.properties | 3 +- .../cleaner/JdbcConnectionContext.java | 5 +- .../jdbc/ConnectionProviderDelegate.java | 3 + ...elTestingConnectionCreatorFactoryImpl.java | 65 +++++++++++++ ...GradleParallelTestingUsernameResolver.java | 93 +++++++++++++++++++ .../testing/jdbc/JdbcProperties.java | 3 + .../testing/orm/junit/DialectContext.java | 3 + .../src/test/resources/hibernate.properties | 1 + .../vector/SparseByteVectorTest.java | 4 + 39 files changed, 299 insertions(+), 24 deletions(-) create mode 100644 hibernate-agroal/src/test/java/org/hibernate/test/agroal/util/GradleParallelTestingAgroalConnectionProvider.java create mode 100644 hibernate-c3p0/src/test/java/org/hibernate/test/c3p0/util/GradleParallelTestingC3P0ConnectionProvider.java create mode 100644 hibernate-hikaricp/src/test/java/org/hibernate/test/hikaricp/util/GradleParallelTestingHikariCPConnectionProvider.java create mode 100644 hibernate-testing/src/main/java/org/hibernate/testing/jdbc/GradleParallelTestingConnectionCreatorFactoryImpl.java create mode 100644 hibernate-testing/src/main/java/org/hibernate/testing/jdbc/GradleParallelTestingUsernameResolver.java diff --git a/hibernate-agroal/src/test/java/org/hibernate/test/agroal/AgroalTransactionIsolationConfigTest.java b/hibernate-agroal/src/test/java/org/hibernate/test/agroal/AgroalTransactionIsolationConfigTest.java index 352b9484047b..be8b8dc972bb 100644 --- a/hibernate-agroal/src/test/java/org/hibernate/test/agroal/AgroalTransactionIsolationConfigTest.java +++ b/hibernate-agroal/src/test/java/org/hibernate/test/agroal/AgroalTransactionIsolationConfigTest.java @@ -8,8 +8,8 @@ import org.hibernate.community.dialect.TiDBDialect; import org.hibernate.community.dialect.GaussDBDialect; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; -import org.hibernate.agroal.internal.AgroalConnectionProvider; +import org.hibernate.test.agroal.util.GradleParallelTestingAgroalConnectionProvider; import org.hibernate.testing.SkipForDialect; import org.hibernate.testing.common.connections.BaseTransactionIsolationConfigTest; @@ -22,6 +22,6 @@ public class AgroalTransactionIsolationConfigTest extends BaseTransactionIsolationConfigTest { @Override protected ConnectionProvider getConnectionProviderUnderTest() { - return new AgroalConnectionProvider(); + return new GradleParallelTestingAgroalConnectionProvider(); } } diff --git a/hibernate-agroal/src/test/java/org/hibernate/test/agroal/util/GradleParallelTestingAgroalConnectionProvider.java b/hibernate-agroal/src/test/java/org/hibernate/test/agroal/util/GradleParallelTestingAgroalConnectionProvider.java new file mode 100644 index 000000000000..e8e150421676 --- /dev/null +++ b/hibernate-agroal/src/test/java/org/hibernate/test/agroal/util/GradleParallelTestingAgroalConnectionProvider.java @@ -0,0 +1,23 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.test.agroal.util; + +import org.hibernate.HibernateException; +import org.hibernate.agroal.internal.AgroalConnectionProvider; + +import java.util.Map; + +import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.resolveFromSettings; + +/** + * @author Loïc Lefèvre + */ +public class GradleParallelTestingAgroalConnectionProvider extends AgroalConnectionProvider { + @Override + public void configure(Map properties) throws HibernateException { + resolveFromSettings( properties ); + super.configure( properties ); + } +} diff --git a/hibernate-agroal/src/test/java/org/hibernate/test/agroal/util/PreparedStatementSpyConnectionProvider.java b/hibernate-agroal/src/test/java/org/hibernate/test/agroal/util/PreparedStatementSpyConnectionProvider.java index 8d710f4ee308..559a23d73dae 100644 --- a/hibernate-agroal/src/test/java/org/hibernate/test/agroal/util/PreparedStatementSpyConnectionProvider.java +++ b/hibernate-agroal/src/test/java/org/hibernate/test/agroal/util/PreparedStatementSpyConnectionProvider.java @@ -10,7 +10,6 @@ import java.util.ArrayList; import java.util.List; -import org.hibernate.agroal.internal.AgroalConnectionProvider; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; import org.hibernate.testing.jdbc.JdbcSpies; @@ -21,7 +20,7 @@ * * @author Vlad Mihalcea */ -public class PreparedStatementSpyConnectionProvider extends AgroalConnectionProvider { +public class PreparedStatementSpyConnectionProvider extends GradleParallelTestingAgroalConnectionProvider { public final JdbcSpies.SpyContext spyContext = new JdbcSpies.SpyContext(); private final List acquiredConnections = new ArrayList<>( ); diff --git a/hibernate-agroal/src/test/resources/hibernate.properties b/hibernate-agroal/src/test/resources/hibernate.properties index 334df1bfeecf..ad08ececb219 100644 --- a/hibernate-agroal/src/test/resources/hibernate.properties +++ b/hibernate-agroal/src/test/resources/hibernate.properties @@ -10,7 +10,7 @@ hibernate.connection.password @jdbc.pass@ hibernate.connection.init_sql @connection.init_sql@ hibernate.jdbc.batch_size 10 -hibernate.connection.provider_class AgroalConnectionProvider +hibernate.connection.provider_class org.hibernate.test.agroal.util.GradleParallelTestingAgroalConnectionProvider hibernate.agroal.maxSize 2 hibernate.agroal.acquisitionTimeout PT1s diff --git a/hibernate-c3p0/src/test/java/org/hibernate/test/c3p0/C3p0TransactionIsolationConfigTest.java b/hibernate-c3p0/src/test/java/org/hibernate/test/c3p0/C3p0TransactionIsolationConfigTest.java index 062235e9eb0a..37acc98e93c7 100644 --- a/hibernate-c3p0/src/test/java/org/hibernate/test/c3p0/C3p0TransactionIsolationConfigTest.java +++ b/hibernate-c3p0/src/test/java/org/hibernate/test/c3p0/C3p0TransactionIsolationConfigTest.java @@ -14,6 +14,7 @@ import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; import org.hibernate.service.spi.ServiceRegistryImplementor; +import org.hibernate.test.c3p0.util.GradleParallelTestingC3P0ConnectionProvider; import org.hibernate.testing.SkipForDialect; import org.hibernate.testing.common.connections.BaseTransactionIsolationConfigTest; import org.junit.Before; @@ -35,7 +36,7 @@ public void setUp() { @Override protected ConnectionProvider getConnectionProviderUnderTest() { - C3P0ConnectionProvider provider = new C3P0ConnectionProvider(); + C3P0ConnectionProvider provider = new GradleParallelTestingC3P0ConnectionProvider(); provider.injectServices( (ServiceRegistryImplementor) ssr ); return provider; } diff --git a/hibernate-c3p0/src/test/java/org/hibernate/test/c3p0/OracleSQLCallableStatementProxyTest.java b/hibernate-c3p0/src/test/java/org/hibernate/test/c3p0/OracleSQLCallableStatementProxyTest.java index cd0f30f165f4..aa9da49f04dc 100644 --- a/hibernate-c3p0/src/test/java/org/hibernate/test/c3p0/OracleSQLCallableStatementProxyTest.java +++ b/hibernate-c3p0/src/test/java/org/hibernate/test/c3p0/OracleSQLCallableStatementProxyTest.java @@ -17,10 +17,10 @@ import jakarta.persistence.SqlResultSetMappings; import jakarta.persistence.StoredProcedureParameter; -import org.hibernate.c3p0.internal.C3P0ConnectionProvider; import org.hibernate.cfg.Configuration; import org.hibernate.dialect.OracleDialect; +import org.hibernate.test.c3p0.util.GradleParallelTestingC3P0ConnectionProvider; import org.hibernate.testing.RequiresDialect; import org.hibernate.testing.orm.junit.JiraKey; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; @@ -41,7 +41,7 @@ public class OracleSQLCallableStatementProxyTest extends protected void configure(Configuration configuration) { configuration.setProperty( org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER, - C3P0ConnectionProvider.class + GradleParallelTestingC3P0ConnectionProvider.class ); } diff --git a/hibernate-c3p0/src/test/java/org/hibernate/test/c3p0/util/GradleParallelTestingC3P0ConnectionProvider.java b/hibernate-c3p0/src/test/java/org/hibernate/test/c3p0/util/GradleParallelTestingC3P0ConnectionProvider.java new file mode 100644 index 000000000000..2b63b3476d49 --- /dev/null +++ b/hibernate-c3p0/src/test/java/org/hibernate/test/c3p0/util/GradleParallelTestingC3P0ConnectionProvider.java @@ -0,0 +1,23 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.test.c3p0.util; + +import org.hibernate.HibernateException; +import org.hibernate.c3p0.internal.C3P0ConnectionProvider; + +import java.util.Map; + +import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.resolveFromSettings; + +/** + * @author Loïc Lefèvre + */ +public class GradleParallelTestingC3P0ConnectionProvider extends C3P0ConnectionProvider { + @Override + public void configure(Map properties) throws HibernateException { + resolveFromSettings( properties ); + super.configure( properties ); + } +} diff --git a/hibernate-c3p0/src/test/resources/hibernate.properties b/hibernate-c3p0/src/test/resources/hibernate.properties index 87221627ab28..ed2b68ede3d2 100644 --- a/hibernate-c3p0/src/test/resources/hibernate.properties +++ b/hibernate-c3p0/src/test/resources/hibernate.properties @@ -21,7 +21,7 @@ hibernate.c3p0.testConnectionOnCheckout true hibernate.show_sql false hibernate.max_fetch_depth 5 -hibernate.connection.provider_class C3P0ConnectionProvider +hibernate.connection.provider_class org.hibernate.test.c3p0.util.GradleParallelTestingC3P0ConnectionProvider hibernate.cache.region_prefix hibernate.test hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFactory diff --git a/hibernate-core/hibernate-core.gradle b/hibernate-core/hibernate-core.gradle index f55e56a55df1..7c595a46f441 100644 --- a/hibernate-core/hibernate-core.gradle +++ b/hibernate-core/hibernate-core.gradle @@ -266,6 +266,12 @@ tasks.withType( Test.class ).each { test -> // Parallel test runs when running with in-memory databases test.maxParallelForks = Runtime.runtime.availableProcessors().intdiv( 2 ) ?: 1 } + else if ( project.db == "oracle_test_pilot_database" ) { + // Parallel test runs when running with Oracle Test Pilot databases + // see GradleParallelTestingUsernameResolver + test.maxParallelForks = Runtime.runtime.availableProcessors() ?: 1 + test.systemProperty 'maxParallelForks', test.maxParallelForks + } } tasks.named( "javadoc", Javadoc ) { diff --git a/hibernate-core/src/test/bundles/templates/cfgxmlpar/org/hibernate/orm/test/jpa/pack/cfgxmlpar/hibernate.cfg.xml b/hibernate-core/src/test/bundles/templates/cfgxmlpar/org/hibernate/orm/test/jpa/pack/cfgxmlpar/hibernate.cfg.xml index 83f5347dfdae..792991448b6c 100644 --- a/hibernate-core/src/test/bundles/templates/cfgxmlpar/org/hibernate/orm/test/jpa/pack/cfgxmlpar/hibernate.cfg.xml +++ b/hibernate-core/src/test/bundles/templates/cfgxmlpar/org/hibernate/orm/test/jpa/pack/cfgxmlpar/hibernate.cfg.xml @@ -10,6 +10,7 @@ @db.dialect@ @jdbc.driver@ + org.hibernate.testing.jdbc.GradleParallelTestingConnectionCreatorFactoryImpl @jdbc.user@ @jdbc.pass@ @connection.init_sql@ @@ -30,4 +31,4 @@ - \ No newline at end of file + diff --git a/hibernate-core/src/test/bundles/templates/defaultpar/META-INF/persistence.xml b/hibernate-core/src/test/bundles/templates/defaultpar/META-INF/persistence.xml index ef41c8e75e11..f14a6fa0b37d 100644 --- a/hibernate-core/src/test/bundles/templates/defaultpar/META-INF/persistence.xml +++ b/hibernate-core/src/test/bundles/templates/defaultpar/META-INF/persistence.xml @@ -15,6 +15,7 @@ + diff --git a/hibernate-core/src/test/bundles/templates/defaultpar_1_0/META-INF/persistence.xml b/hibernate-core/src/test/bundles/templates/defaultpar_1_0/META-INF/persistence.xml index 406e5cc6074f..08cbec19285a 100644 --- a/hibernate-core/src/test/bundles/templates/defaultpar_1_0/META-INF/persistence.xml +++ b/hibernate-core/src/test/bundles/templates/defaultpar_1_0/META-INF/persistence.xml @@ -14,6 +14,7 @@ + diff --git a/hibernate-core/src/test/bundles/templates/excludehbmpar/META-INF/persistence.xml b/hibernate-core/src/test/bundles/templates/excludehbmpar/META-INF/persistence.xml index fc2442c5d5ba..40709a2f6bf9 100644 --- a/hibernate-core/src/test/bundles/templates/excludehbmpar/META-INF/persistence.xml +++ b/hibernate-core/src/test/bundles/templates/excludehbmpar/META-INF/persistence.xml @@ -14,6 +14,7 @@ + diff --git a/hibernate-core/src/test/bundles/templates/explicitpar/META-INF/persistence.xml b/hibernate-core/src/test/bundles/templates/explicitpar/META-INF/persistence.xml index fdefb28a8187..73701949c042 100644 --- a/hibernate-core/src/test/bundles/templates/explicitpar/META-INF/persistence.xml +++ b/hibernate-core/src/test/bundles/templates/explicitpar/META-INF/persistence.xml @@ -20,6 +20,7 @@ + diff --git a/hibernate-core/src/test/bundles/templates/explicitpar2/META-INF/persistence.xml b/hibernate-core/src/test/bundles/templates/explicitpar2/META-INF/persistence.xml index 5b3532aca65c..124d1cf78329 100644 --- a/hibernate-core/src/test/bundles/templates/explicitpar2/META-INF/persistence.xml +++ b/hibernate-core/src/test/bundles/templates/explicitpar2/META-INF/persistence.xml @@ -20,6 +20,7 @@ + diff --git a/hibernate-core/src/test/bundles/templates/explodedpar/META-INF/persistence.xml b/hibernate-core/src/test/bundles/templates/explodedpar/META-INF/persistence.xml index ccde2379f1ff..4b37f69094b8 100644 --- a/hibernate-core/src/test/bundles/templates/explodedpar/META-INF/persistence.xml +++ b/hibernate-core/src/test/bundles/templates/explodedpar/META-INF/persistence.xml @@ -13,6 +13,7 @@ + diff --git a/hibernate-core/src/test/bundles/templates/overridenpar/overridenpar.properties b/hibernate-core/src/test/bundles/templates/overridenpar/overridenpar.properties index 72a957294661..2489b512b8a1 100644 --- a/hibernate-core/src/test/bundles/templates/overridenpar/overridenpar.properties +++ b/hibernate-core/src/test/bundles/templates/overridenpar/overridenpar.properties @@ -3,7 +3,8 @@ # Copyright Red Hat Inc. and Hibernate Authors # hibernate.connection.driver_class @jdbc.driver@ +hibernate.connection.creator_factory_class org.hibernate.testing.jdbc.GradleParallelTestingConnectionCreatorFactoryImpl hibernate.connection.url @jdbc.url@ hibernate.connection.username @jdbc.user@ hibernate.connection.password @jdbc.pass@ -hibernate.connection.init_sql @connection.init_sql@ \ No newline at end of file +hibernate.connection.init_sql @connection.init_sql@ diff --git a/hibernate-core/src/test/bundles/templates/space par/META-INF/persistence.xml b/hibernate-core/src/test/bundles/templates/space par/META-INF/persistence.xml index 39eed2e71f86..9569a304e1b0 100644 --- a/hibernate-core/src/test/bundles/templates/space par/META-INF/persistence.xml +++ b/hibernate-core/src/test/bundles/templates/space par/META-INF/persistence.xml @@ -13,6 +13,7 @@ + diff --git a/hibernate-core/src/test/bundles/templates/war/WEB-INF/classes/META-INF/persistence.xml b/hibernate-core/src/test/bundles/templates/war/WEB-INF/classes/META-INF/persistence.xml index e21ff64f3b48..871c6a718872 100644 --- a/hibernate-core/src/test/bundles/templates/war/WEB-INF/classes/META-INF/persistence.xml +++ b/hibernate-core/src/test/bundles/templates/war/WEB-INF/classes/META-INF/persistence.xml @@ -14,6 +14,7 @@ + diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/datasource/DataSourceTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/datasource/DataSourceTest.java index 4dca9176791d..a4f75b5c769d 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/datasource/DataSourceTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/datasource/DataSourceTest.java @@ -36,7 +36,7 @@ void test(EntityManagerFactoryScope scope) { scope.getEntityManagerFactory(); LogInspectionHelper.clearAllListeners( ConnectionInfoLogger.INSTANCE ); Dialect dialect = scope.getDialect(); - assertTrue( dialect instanceof OracleDialect od && od.isAutonomous() + assertTrue( dialect instanceof OracleDialect || dialect instanceof DB2Dialect || dialect instanceof InformixDialect // Informix metadata does not include the URL || listener.seen ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/jakarta/JakartaSchemaToolingTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/jakarta/JakartaSchemaToolingTests.java index d3c64b8f8f41..52c816123b7a 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/jakarta/JakartaSchemaToolingTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/jakarta/JakartaSchemaToolingTests.java @@ -37,6 +37,7 @@ import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_PASSWORD; import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_URL; import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_USER; +import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.*; /** @@ -66,7 +67,7 @@ private void verifySchemaCreation( actionSettingName, Action.CREATE_DROP, driverSettingName, Environment.getProperties().get( AvailableSettings.DRIVER ), urlSettingName, Environment.getProperties().get( AvailableSettings.URL ), - userSettingName, Environment.getProperties().get( AvailableSettings.USER ), + userSettingName, resolveUsername( (String)Environment.getProperties().get( AvailableSettings.USER ) ), passwordSettingName, Environment.getProperties().get( AvailableSettings.PASS ) ); try { @@ -95,7 +96,7 @@ public void testPrecedence() { JPA_JDBC_DRIVER, "does.not.exist", JAKARTA_JDBC_URL, Environment.getProperties().get( AvailableSettings.URL ), JPA_JDBC_URL, "jdbc:na:nowhere", - JAKARTA_JDBC_USER, Environment.getProperties().get( AvailableSettings.USER ), + JAKARTA_JDBC_USER, resolveUsername( (String)Environment.getProperties().get( AvailableSettings.USER ) ), JPA_JDBC_USER, "goofy", JAKARTA_JDBC_PASSWORD, Environment.getProperties().get( AvailableSettings.PASS ), JPA_JDBC_PASSWORD, "goober" @@ -112,7 +113,7 @@ public void testCreateDropWithFailureInBetween() { JAKARTA_HBM2DDL_DATABASE_ACTION, Action.CREATE_DROP, JAKARTA_JDBC_DRIVER, Environment.getProperties().get( AvailableSettings.DRIVER ), JAKARTA_JDBC_URL, Environment.getProperties().get( AvailableSettings.URL ), - JAKARTA_JDBC_USER, Environment.getProperties().get( AvailableSettings.USER ), + JAKARTA_JDBC_USER, resolveUsername( (String)Environment.getProperties().get( AvailableSettings.USER ) ), JAKARTA_JDBC_PASSWORD, Environment.getProperties().get( AvailableSettings.PASS ), // Simulates a failure from e.g. the Hibernate Search observer AvailableSettings.SESSION_FACTORY_OBSERVER, new SessionFactoryObserver() { @@ -129,7 +130,7 @@ public void sessionFactoryCreated(org.hibernate.SessionFactory factory) { JAKARTA_HBM2DDL_DATABASE_ACTION, Action.NONE, JAKARTA_JDBC_DRIVER, Environment.getProperties().get( AvailableSettings.DRIVER ), JAKARTA_JDBC_URL, Environment.getProperties().get( AvailableSettings.URL ), - JAKARTA_JDBC_USER, Environment.getProperties().get( AvailableSettings.USER ), + JAKARTA_JDBC_USER, resolveUsername( (String)Environment.getProperties().get( AvailableSettings.USER ) ), JAKARTA_JDBC_PASSWORD, Environment.getProperties().get( AvailableSettings.PASS ) ) ) { assertThatThrownBy( () -> tryQuery( sessionFactory ) ).isNotNull(); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/util/connections/BaseDataSource.java b/hibernate-core/src/test/java/org/hibernate/orm/test/util/connections/BaseDataSource.java index 0747eb07ed8b..02daf514b90b 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/util/connections/BaseDataSource.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/util/connections/BaseDataSource.java @@ -14,6 +14,8 @@ import org.hibernate.cfg.Environment; +import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.*; + /** * Simple {@link DataSource} implementation useful in various integration tests, * or possibly to be used as base class to extend. @@ -26,6 +28,7 @@ public class BaseDataSource implements DataSource { public BaseDataSource(Properties configuration) { url = configuration.getProperty( Environment.URL ); connectionProperties = new Properties(); + resolveFromSettings( configuration ); connectionProperties.put( "user", configuration.getProperty( Environment.USER ) ); connectionProperties.put( "password", configuration.getProperty( Environment.PASS ) ); } diff --git a/hibernate-core/src/test/resources/hibernate.properties b/hibernate-core/src/test/resources/hibernate.properties index e3fea8b55699..5c1c93c51c58 100644 --- a/hibernate-core/src/test/resources/hibernate.properties +++ b/hibernate-core/src/test/resources/hibernate.properties @@ -5,6 +5,7 @@ hibernate.dialect @db.dialect@ hibernate.connection.driver_class @jdbc.driver@ +hibernate.connection.creator_factory_class org.hibernate.testing.jdbc.GradleParallelTestingConnectionCreatorFactoryImpl hibernate.connection.url @jdbc.url@ hibernate.connection.username @jdbc.user@ hibernate.connection.password @jdbc.pass@ @@ -28,4 +29,4 @@ hibernate.service.allow_crawling=false hibernate.session.events.log=true hibernate.query.mutation_strategy.global_temporary.drop_tables=true -#hibernate.transform_hbm_xml.enabled=true \ No newline at end of file +#hibernate.transform_hbm_xml.enabled=true diff --git a/hibernate-core/src/test/resources/xml/jakarta/simple/persistence.xml b/hibernate-core/src/test/resources/xml/jakarta/simple/persistence.xml index 7ce811bbccca..aa68f51fa79f 100644 --- a/hibernate-core/src/test/resources/xml/jakarta/simple/persistence.xml +++ b/hibernate-core/src/test/resources/xml/jakarta/simple/persistence.xml @@ -12,6 +12,7 @@ + diff --git a/hibernate-envers/hibernate-envers.gradle b/hibernate-envers/hibernate-envers.gradle index 24988993ffd2..b2b170138b2b 100644 --- a/hibernate-envers/hibernate-envers.gradle +++ b/hibernate-envers/hibernate-envers.gradle @@ -59,6 +59,12 @@ tasks.withType( Test.class ).each { test -> // Parallel test runs when running with in-memory databases test.maxParallelForks = Runtime.runtime.availableProcessors().intdiv( 2 ) ?: 1 } + else if ( project.db == "oracle_test_pilot_database" ) { + // Parallel test runs when running with Oracle Test Pilot databases + // see GradleParallelTestingUsernameResolver + test.maxParallelForks = Runtime.runtime.availableProcessors() ?: 1 + test.systemProperty 'maxParallelForks', test.maxParallelForks + } } sourcesJar { diff --git a/hibernate-envers/src/test/resources/hibernate.properties b/hibernate-envers/src/test/resources/hibernate.properties index c90744fca4ac..0b61b5cd7ea2 100644 --- a/hibernate-envers/src/test/resources/hibernate.properties +++ b/hibernate-envers/src/test/resources/hibernate.properties @@ -4,6 +4,7 @@ # hibernate.dialect @db.dialect@ hibernate.connection.driver_class @jdbc.driver@ +hibernate.connection.creator_factory_class org.hibernate.testing.jdbc.GradleParallelTestingConnectionCreatorFactoryImpl hibernate.connection.url @jdbc.url@ hibernate.connection.username @jdbc.user@ hibernate.connection.password @jdbc.pass@ @@ -22,4 +23,4 @@ hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFa hibernate.service.allow_crawling=false ## make sure we use bag semantics for "implicit" List mappings -hibernate.mapping.default_list_semantics=bag \ No newline at end of file +hibernate.mapping.default_list_semantics=bag diff --git a/hibernate-hikaricp/src/test/java/org/hibernate/test/hikaricp/HikariTransactionIsolationConfigTest.java b/hibernate-hikaricp/src/test/java/org/hibernate/test/hikaricp/HikariTransactionIsolationConfigTest.java index 6d19b77ecb42..74c16ab7b4ec 100644 --- a/hibernate-hikaricp/src/test/java/org/hibernate/test/hikaricp/HikariTransactionIsolationConfigTest.java +++ b/hibernate-hikaricp/src/test/java/org/hibernate/test/hikaricp/HikariTransactionIsolationConfigTest.java @@ -9,8 +9,8 @@ import org.hibernate.dialect.SybaseDialect; import org.hibernate.community.dialect.TiDBDialect; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; -import org.hibernate.hikaricp.internal.HikariCPConnectionProvider; +import org.hibernate.test.hikaricp.util.GradleParallelTestingHikariCPConnectionProvider; import org.hibernate.testing.SkipForDialect; import org.hibernate.testing.common.connections.BaseTransactionIsolationConfigTest; @@ -24,6 +24,6 @@ public class HikariTransactionIsolationConfigTest extends BaseTransactionIsolationConfigTest { @Override protected ConnectionProvider getConnectionProviderUnderTest() { - return new HikariCPConnectionProvider(); + return new GradleParallelTestingHikariCPConnectionProvider(); } } diff --git a/hibernate-hikaricp/src/test/java/org/hibernate/test/hikaricp/util/GradleParallelTestingHikariCPConnectionProvider.java b/hibernate-hikaricp/src/test/java/org/hibernate/test/hikaricp/util/GradleParallelTestingHikariCPConnectionProvider.java new file mode 100644 index 000000000000..9fbb6a258ff3 --- /dev/null +++ b/hibernate-hikaricp/src/test/java/org/hibernate/test/hikaricp/util/GradleParallelTestingHikariCPConnectionProvider.java @@ -0,0 +1,23 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.test.hikaricp.util; + +import org.hibernate.HibernateException; +import org.hibernate.hikaricp.internal.HikariCPConnectionProvider; + +import java.util.Map; + +import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.resolveFromSettings; + +/** + * @author Loïc Lefèvre + */ +public class GradleParallelTestingHikariCPConnectionProvider extends HikariCPConnectionProvider { + @Override + public void configure(Map properties) throws HibernateException { + resolveFromSettings( properties ); + super.configure( properties ); + } +} diff --git a/hibernate-hikaricp/src/test/resources/hibernate.properties b/hibernate-hikaricp/src/test/resources/hibernate.properties index 770ad29d39b2..729868517cba 100644 --- a/hibernate-hikaricp/src/test/resources/hibernate.properties +++ b/hibernate-hikaricp/src/test/resources/hibernate.properties @@ -10,7 +10,7 @@ hibernate.connection.password @jdbc.pass@ hibernate.connection.init_sql @connection.init_sql@ hibernate.jdbc.batch_size 10 -hibernate.connection.provider_class HikariCPConnectionProvider +hibernate.connection.provider_class org.hibernate.test.hikaricp.util.GradleParallelTestingHikariCPConnectionProvider hibernate.hikari.poolName testPool # Purposefully low and simplisitic. diff --git a/hibernate-jcache/src/test/resources/hibernate.properties b/hibernate-jcache/src/test/resources/hibernate.properties index 8d70d42dcfcb..4ee0e72dd66d 100644 --- a/hibernate-jcache/src/test/resources/hibernate.properties +++ b/hibernate-jcache/src/test/resources/hibernate.properties @@ -4,6 +4,7 @@ # hibernate.dialect @db.dialect@ hibernate.connection.driver_class @jdbc.driver@ +hibernate.connection.creator_factory_class org.hibernate.testing.jdbc.GradleParallelTestingConnectionCreatorFactoryImpl hibernate.connection.url @jdbc.url@ hibernate.connection.username @jdbc.user@ hibernate.connection.password @jdbc.pass@ @@ -13,4 +14,4 @@ hibernate.connection.pool_size 2 hibernate.cache.region_prefix hibernate.test -hibernate.service.allow_crawling=false \ No newline at end of file +hibernate.service.allow_crawling=false diff --git a/hibernate-micrometer/src/test/resources/hibernate.properties b/hibernate-micrometer/src/test/resources/hibernate.properties index ecd3aa6efc33..8506facd76a7 100644 --- a/hibernate-micrometer/src/test/resources/hibernate.properties +++ b/hibernate-micrometer/src/test/resources/hibernate.properties @@ -5,6 +5,7 @@ hibernate.dialect @db.dialect@ hibernate.connection.driver_class @jdbc.driver@ +hibernate.connection.creator_factory_class org.hibernate.testing.jdbc.GradleParallelTestingConnectionCreatorFactoryImpl hibernate.connection.url @jdbc.url@ hibernate.connection.username @jdbc.user@ hibernate.connection.password @jdbc.pass@ @@ -23,4 +24,4 @@ hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFa jakarta.persistence.validation.mode=NONE hibernate.service.allow_crawling=false hibernate.session.events.log=true -hibernate.query.mutation_strategy.global_temporary.drop_tables=true \ No newline at end of file +hibernate.query.mutation_strategy.global_temporary.drop_tables=true diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cleaner/JdbcConnectionContext.java b/hibernate-testing/src/main/java/org/hibernate/testing/cleaner/JdbcConnectionContext.java index 4b70afeb7ee5..ac1d89dfe5b6 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cleaner/JdbcConnectionContext.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cleaner/JdbcConnectionContext.java @@ -11,6 +11,8 @@ import org.hibernate.cfg.AvailableSettings; +import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.*; + /** * @author Christian Beikov */ @@ -31,11 +33,12 @@ public final class JdbcConnectionContext { driver = (Driver) Class.forName( driverClassName ).newInstance(); url = connectionProperties.getProperty( AvailableSettings.URL ); + resolveFromSettings(connectionProperties); user = connectionProperties.getProperty( AvailableSettings.USER ); password = connectionProperties.getProperty( AvailableSettings.PASS ); - Properties p = new Properties(); + final Properties p = new Properties(); if ( user != null ) { p.put( "user", user ); } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/ConnectionProviderDelegate.java b/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/ConnectionProviderDelegate.java index 2503a8157dbc..7b69ad200c9d 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/ConnectionProviderDelegate.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/ConnectionProviderDelegate.java @@ -20,6 +20,8 @@ import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.service.spi.Stoppable; +import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.resolveFromSettings; + /** * This {@link ConnectionProvider} extends any other ConnectionProvider * that would be used by default taken the current configuration properties. @@ -68,6 +70,7 @@ public void injectServices(ServiceRegistryImplementor serviceRegistry) { public void configure(Map configurationValues) { if ( !configured ) { if ( connectionProvider == null ) { + resolveFromSettings( configurationValues ); Map settings = new HashMap<>( configurationValues ); settings.remove( AvailableSettings.CONNECTION_PROVIDER ); connectionProvider = ConnectionProviderInitiator.INSTANCE.initiateService( diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/GradleParallelTestingConnectionCreatorFactoryImpl.java b/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/GradleParallelTestingConnectionCreatorFactoryImpl.java new file mode 100644 index 000000000000..a283aeb56cfe --- /dev/null +++ b/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/GradleParallelTestingConnectionCreatorFactoryImpl.java @@ -0,0 +1,65 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.testing.jdbc; + +import org.hibernate.engine.jdbc.connections.internal.ConnectionCreator; +import org.hibernate.engine.jdbc.connections.internal.ConnectionCreatorFactory; +import org.hibernate.engine.jdbc.connections.internal.DriverConnectionCreator; +import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionCreator; +import org.hibernate.service.ServiceRegistry; + +import java.sql.Driver; +import java.util.Map; +import java.util.Properties; + +import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.*; + +/** + * A factory for {@link ConnectionCreator} instances that can be used for Gradle Parallel Testing. + * + * @author Loïc Lefèvre + */ +public class GradleParallelTestingConnectionCreatorFactoryImpl implements ConnectionCreatorFactory { + + public GradleParallelTestingConnectionCreatorFactoryImpl() { + } + + @Override + public ConnectionCreator create( + Driver driver, + ServiceRegistry serviceRegistry, + String url, + Properties connectionProps, + Boolean autoCommit, + Integer isolation, + String initSql, + Map configurationValues) { + + // now resolve JDBC Username if needed for Gradle Parallel Testing + resolve( connectionProps ); + + if ( driver == null ) { + return new DriverManagerConnectionCreator( + serviceRegistry, + url, + connectionProps, + autoCommit, + isolation, + initSql + ); + } + else { + return new DriverConnectionCreator( + driver, + serviceRegistry, + url, + connectionProps, + autoCommit, + isolation, + initSql + ); + } + } +} diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/GradleParallelTestingUsernameResolver.java b/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/GradleParallelTestingUsernameResolver.java new file mode 100644 index 000000000000..4a4ae27a24fe --- /dev/null +++ b/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/GradleParallelTestingUsernameResolver.java @@ -0,0 +1,93 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.testing.jdbc; + +import org.hibernate.cfg.AvailableSettings; + +import java.util.Map; +import java.util.Properties; + +/** + * JDBC username resolver for parallel tests. + * + * @author Loïc Lefèvre + */ +public class GradleParallelTestingUsernameResolver { + + private static final String JDBC_USER_CONNECTION_PROPERTY = "user"; + + /** + * Pattern that will be replaced by the forked JVM ID used for tests by Gradle. + */ + private static final String GRADLE_WORKER_PATTERN = "$worker"; + + /** + * @see Gradle Test Execution + */ + private static final String GRADLE_WORKER_ID = "org.gradle.test.worker"; + + private static final String GRADLE_MAXIMUM_PARALLEL_FORKS = "maxParallelForks"; + + public static void resolve(final Properties connectionProps) { + if( connectionProps != null ) { + // If Gradle parallel testing is enabled (maxParallelForks > 1) + final String user = connectionProps.getProperty( JDBC_USER_CONNECTION_PROPERTY ); + if ( user.contains( GRADLE_WORKER_PATTERN ) ) { + connectionProps.put( JDBC_USER_CONNECTION_PROPERTY, + user.replace( GRADLE_WORKER_PATTERN, String.valueOf( getRunningID() ) ) ); + } + } + } + + public static void resolveFromSettings(final Properties settingsProps) { + if( settingsProps != null ) { + // If Gradle parallel testing is enabled (maxParallelForks > 1) + final String user = settingsProps.getProperty( AvailableSettings.USER ); + if ( user.contains( GRADLE_WORKER_PATTERN ) ) { + settingsProps.put( AvailableSettings.USER, + user.replace( GRADLE_WORKER_PATTERN, String.valueOf( getRunningID() ) ) ); + } + } + } + + public static void resolveFromSettings(final Map settingsProps) { + if( settingsProps != null ) { + // If Gradle parallel testing is enabled (maxParallelForks > 1) + final String user = (String) settingsProps.get( AvailableSettings.USER ); + if ( user.contains( GRADLE_WORKER_PATTERN ) ) { + settingsProps.put( AvailableSettings.USER, + user.replace( GRADLE_WORKER_PATTERN, String.valueOf( getRunningID() ) ) ); + } + } + } + + public static String resolveUsername(String username) { + if(username != null) { + if ( username.contains( GRADLE_WORKER_PATTERN ) ) { + return username.replace( GRADLE_WORKER_PATTERN, String.valueOf( getRunningID() ) ); + } + else { + return username; + } + } else { + throw new IllegalArgumentException("Username must not be null!"); + } + } + + /** + * Create a JVM Running ID based on the Gradle properties. + * Whenever a task is running in parallel, Gradle will fork JVMs and assign + * a monotonic sequence number to it (it may not start with 1) which can be + * retrieved using the system property {@link #GRADLE_WORKER_ID}. + * + * @return an integer between 1 and {@link #GRADLE_MAXIMUM_PARALLEL_FORKS} system property (inclusive) + */ + private static int getRunningID() { + // enable parallelization of up to GRADLE_MAXIMUM_PARALLEL_FORKS + final Integer maxParallelForks = Integer.valueOf( System.getProperty( GRADLE_MAXIMUM_PARALLEL_FORKS, "1" ) ); + final Integer worker = Integer.valueOf( System.getProperty( GRADLE_WORKER_ID, "1" ) ); + return (worker % maxParallelForks) + 1; // returns 1, 2, 3... + } +} diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/JdbcProperties.java b/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/JdbcProperties.java index 47224b0263c9..d951113c342f 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/JdbcProperties.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/JdbcProperties.java @@ -10,6 +10,8 @@ import org.jboss.logging.Logger; +import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.resolveFromSettings; + /** * @author Vlad Mihalcea */ @@ -36,6 +38,7 @@ public JdbcProperties() { connectionProperties.load( inputStream ); url = connectionProperties.getProperty( "hibernate.connection.url" ); + resolveFromSettings(connectionProperties); user = connectionProperties.getProperty( "hibernate.connection.username" ); password = connectionProperties.getProperty( diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/orm/junit/DialectContext.java b/hibernate-testing/src/main/java/org/hibernate/testing/orm/junit/DialectContext.java index bd1befcb5c3d..4834ce6834d1 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/orm/junit/DialectContext.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/orm/junit/DialectContext.java @@ -18,6 +18,8 @@ import org.hibernate.exception.JDBCConnectionException; import org.hibernate.internal.util.ReflectHelper; +import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.resolveFromSettings; + /** * @author Christian Beikov */ @@ -45,6 +47,7 @@ static void init() { final String driverClassName = properties.getProperty( Environment.DRIVER ); final String jdbcUrl = properties.getProperty( Environment.URL ); final Properties props = new Properties(); + resolveFromSettings(properties); props.setProperty( "user", properties.getProperty( Environment.USER ) ); props.setProperty( "password", properties.getProperty( Environment.PASS ) ); final Class dialectClass = getDialectClass(); diff --git a/hibernate-testing/src/test/resources/hibernate.properties b/hibernate-testing/src/test/resources/hibernate.properties index 38db07a4d2c7..8506facd76a7 100644 --- a/hibernate-testing/src/test/resources/hibernate.properties +++ b/hibernate-testing/src/test/resources/hibernate.properties @@ -5,6 +5,7 @@ hibernate.dialect @db.dialect@ hibernate.connection.driver_class @jdbc.driver@ +hibernate.connection.creator_factory_class org.hibernate.testing.jdbc.GradleParallelTestingConnectionCreatorFactoryImpl hibernate.connection.url @jdbc.url@ hibernate.connection.username @jdbc.user@ hibernate.connection.password @jdbc.pass@ diff --git a/hibernate-vector/src/test/java/org/hibernate/vector/SparseByteVectorTest.java b/hibernate-vector/src/test/java/org/hibernate/vector/SparseByteVectorTest.java index ee78cd363f77..a47649311d9f 100644 --- a/hibernate-vector/src/test/java/org/hibernate/vector/SparseByteVectorTest.java +++ b/hibernate-vector/src/test/java/org/hibernate/vector/SparseByteVectorTest.java @@ -10,11 +10,13 @@ import jakarta.persistence.Tuple; import org.hibernate.annotations.Array; import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.dialect.OracleDialect; import org.hibernate.testing.orm.junit.DialectFeatureChecks; import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.RequiresDialectFeature; import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.hibernate.testing.orm.junit.SkipForDialect; import org.hibernate.type.SqlTypes; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -128,6 +130,7 @@ public void testEuclideanSquaredDistance(SessionFactoryScope scope) { @Test @RequiresDialectFeature(feature = DialectFeatureChecks.SupportsTaxicabDistance.class) + @SkipForDialect(dialectClass = OracleDialect.class, reason = "Oracle 23.9 bug") public void testTaxicabDistance(SessionFactoryScope scope) { scope.inTransaction( em -> { final byte[] vector = new byte[]{ 1, 1, 1 }; @@ -162,6 +165,7 @@ public void testInnerProduct(SessionFactoryScope scope) { @Test @RequiresDialectFeature(feature = DialectFeatureChecks.SupportsHammingDistance.class) + @SkipForDialect(dialectClass = OracleDialect.class, reason = "Oracle 23.9 bug") public void testHammingDistance(SessionFactoryScope scope) { scope.inTransaction( em -> { final byte[] vector = new byte[]{ 1, 1, 1 }; From 6485533057da3963cd6700a15e29fd38ff073e44 Mon Sep 17 00:00:00 2001 From: Christian Beikov Date: Fri, 12 Sep 2025 11:20:35 +0200 Subject: [PATCH 2/2] HHH-14892 Enable parallel testing for PostgreSQL --- docker_db.sh | 33 ++++++++++++++--- ...rallelTestingAgroalConnectionProvider.java | 2 +- ...ParallelTestingC3P0ConnectionProvider.java | 2 +- hibernate-core/hibernate-core.gradle | 18 ++++----- .../orm/test/datasource/DataSourceTest.java | 3 +- .../jakarta/JakartaSchemaToolingTests.java | 16 ++++---- .../test/util/connections/BaseDataSource.java | 4 +- hibernate-envers/hibernate-envers.gradle | 15 +++++--- ...llelTestingHikariCPConnectionProvider.java | 2 +- .../src/test/resources/hibernate.properties | 1 + .../src/test/resources/hibernate.properties | 1 + .../cleaner/JdbcConnectionContext.java | 14 +++---- .../jdbc/ConnectionProviderDelegate.java | 2 +- ...elTestingConnectionCreatorFactoryImpl.java | 3 +- ...ava => GradleParallelTestingResolver.java} | 37 ++++++++++++------- .../testing/jdbc/JdbcProperties.java | 12 +++--- .../testing/orm/junit/DialectContext.java | 5 ++- .../src/main/groovy/local.databases.gradle | 2 +- 18 files changed, 104 insertions(+), 68 deletions(-) rename hibernate-testing/src/main/java/org/hibernate/testing/jdbc/{GradleParallelTestingUsernameResolver.java => GradleParallelTestingResolver.java} (70%) diff --git a/docker_db.sh b/docker_db.sh index 9478f8aaecac..b18cae94a056 100755 --- a/docker_db.sh +++ b/docker_db.sh @@ -172,34 +172,57 @@ postgresql() { postgresql_13() { $CONTAINER_CLI rm -f postgres || true $CONTAINER_CLI run --name postgres -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p5432:5432 -d ${DB_IMAGE_POSTGRESQL_13:-docker.io/postgis/postgis:13-3.1} - $CONTAINER_CLI exec postgres bash -c '/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && apt install -y postgresql-13-pgvector && psql -U hibernate_orm_test -d hibernate_orm_test -c "create extension vector;"' + $CONTAINER_CLI exec postgres bash -c '/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && apt install -y postgresql-13-pgvector' + postgresql_setup } postgresql_14() { $CONTAINER_CLI rm -f postgres || true $CONTAINER_CLI run --name postgres -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p5432:5432 -d ${DB_IMAGE_POSTGRESQL_14:-docker.io/postgis/postgis:14-3.3} - $CONTAINER_CLI exec postgres bash -c '/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && apt install -y postgresql-14-pgvector && psql -U hibernate_orm_test -d hibernate_orm_test -c "create extension vector;"' + $CONTAINER_CLI exec postgres bash -c '/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && apt install -y postgresql-14-pgvector' + postgresql_setup } postgresql_15() { $CONTAINER_CLI rm -f postgres || true $CONTAINER_CLI run --name postgres -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p5432:5432 --tmpfs /pgtmpfs:size=131072k -d ${DB_IMAGE_POSTGRESQL_15:-docker.io/postgis/postgis:15-3.3} \ -c fsync=off -c synchronous_commit=off -c full_page_writes=off -c shared_buffers=256MB -c maintenance_work_mem=256MB -c max_wal_size=1GB -c checkpoint_timeout=1d - $CONTAINER_CLI exec postgres bash -c '/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && apt install -y postgresql-15-pgvector && psql -U hibernate_orm_test -d hibernate_orm_test -c "create extension vector;"' + $CONTAINER_CLI exec postgres bash -c '/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && apt install -y postgresql-15-pgvector' + postgresql_setup } postgresql_16() { $CONTAINER_CLI rm -f postgres || true $CONTAINER_CLI run --name postgres -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p5432:5432 --tmpfs /pgtmpfs:size=131072k -d ${DB_IMAGE_POSTGRESQL_16:-docker.io/postgis/postgis:16-3.4} \ -c fsync=off -c synchronous_commit=off -c full_page_writes=off -c shared_buffers=256MB -c maintenance_work_mem=256MB -c max_wal_size=1GB -c checkpoint_timeout=1d - $CONTAINER_CLI exec postgres bash -c '/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && apt install -y postgresql-16-pgvector && psql -U hibernate_orm_test -d hibernate_orm_test -c "create extension vector;"' + $CONTAINER_CLI exec postgres bash -c '/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && apt install -y postgresql-16-pgvector' + postgresql_setup } postgresql_17() { $CONTAINER_CLI rm -f postgres || true $CONTAINER_CLI run --name postgres -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p5432:5432 --tmpfs /pgtmpfs:size=131072k -d ${DB_IMAGE_POSTGRESQL_17:-docker.io/postgis/postgis:17-3.5} \ -c fsync=off -c synchronous_commit=off -c full_page_writes=off -c shared_buffers=256MB -c maintenance_work_mem=256MB -c max_wal_size=1GB -c checkpoint_timeout=1d - $CONTAINER_CLI exec postgres bash -c '/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && apt install -y postgresql-17-pgvector && psql -U hibernate_orm_test -d hibernate_orm_test -c "create extension vector;"' + $CONTAINER_CLI exec postgres bash -c '/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && apt install -y postgresql-17-pgvector' + postgresql_setup +} + +postgresql_setup() { + databases=() + for n in $(seq 1 $(($(nproc)/2))) + do + databases+=("hibernate_orm_test_${n}") + done + create_cmd= + for i in "${!databases[@]}";do + create_cmd+="psql -U hibernate_orm_test -d postgres -c \"create database ${databases[i]};\";" + done + $CONTAINER_CLI exec postgres bash -c "until pg_isready -U hibernate_orm_test; do sleep 1; done" + $CONTAINER_CLI exec postgres bash -c "${create_cmd}" + $CONTAINER_CLI exec postgres bash -c 'psql -U hibernate_orm_test -d hibernate_orm_test -c "create extension vector;"' + for i in "${!databases[@]}";do + $CONTAINER_CLI exec postgres bash -c "psql -U hibernate_orm_test -d ${databases[i]} -c \"create extension vector; create extension postgis;\"" + done } gaussdb() { diff --git a/hibernate-agroal/src/test/java/org/hibernate/test/agroal/util/GradleParallelTestingAgroalConnectionProvider.java b/hibernate-agroal/src/test/java/org/hibernate/test/agroal/util/GradleParallelTestingAgroalConnectionProvider.java index e8e150421676..346bb20e4f46 100644 --- a/hibernate-agroal/src/test/java/org/hibernate/test/agroal/util/GradleParallelTestingAgroalConnectionProvider.java +++ b/hibernate-agroal/src/test/java/org/hibernate/test/agroal/util/GradleParallelTestingAgroalConnectionProvider.java @@ -9,7 +9,7 @@ import java.util.Map; -import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.resolveFromSettings; +import static org.hibernate.testing.jdbc.GradleParallelTestingResolver.resolveFromSettings; /** * @author Loïc Lefèvre diff --git a/hibernate-c3p0/src/test/java/org/hibernate/test/c3p0/util/GradleParallelTestingC3P0ConnectionProvider.java b/hibernate-c3p0/src/test/java/org/hibernate/test/c3p0/util/GradleParallelTestingC3P0ConnectionProvider.java index 2b63b3476d49..93b2899c29cc 100644 --- a/hibernate-c3p0/src/test/java/org/hibernate/test/c3p0/util/GradleParallelTestingC3P0ConnectionProvider.java +++ b/hibernate-c3p0/src/test/java/org/hibernate/test/c3p0/util/GradleParallelTestingC3P0ConnectionProvider.java @@ -9,7 +9,7 @@ import java.util.Map; -import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.resolveFromSettings; +import static org.hibernate.testing.jdbc.GradleParallelTestingResolver.resolveFromSettings; /** * @author Loïc Lefèvre diff --git a/hibernate-core/hibernate-core.gradle b/hibernate-core/hibernate-core.gradle index 7c595a46f441..c04990ee8c04 100644 --- a/hibernate-core/hibernate-core.gradle +++ b/hibernate-core/hibernate-core.gradle @@ -259,17 +259,17 @@ tasks.withType( Test.class ).each { test -> //Avoid Log4J2 classloader leaks: test.jvmArgs( ['-Dlog4j2.disableJmx=true'] ) - test.beforeTest { descriptor -> - //println "Starting test: " + descriptor - } - if ( project.db == "h2" || project.db == "hsqldb" ) { - // Parallel test runs when running with in-memory databases - test.maxParallelForks = Runtime.runtime.availableProcessors().intdiv( 2 ) ?: 1 + // see GradleParallelTestingResolver for how the test worker id is resolved in JDBC configs + if ( project.db == "h2" || project.db == "hsqldb" || project.db == "pgsql_ci" ) { + // Most systems have multi-threading and maxing out a core on both threads will hurt performance + // Also, as soon as we hit 16+ threads, the returns are diminishing, so divide by 4 + def threadCount = Runtime.runtime.availableProcessors() + test.maxParallelForks = threadCount >= 16 ? threadCount.intdiv( 4 ) : (threadCount.intdiv( 2 ) ?: 1) + test.systemProperty 'maxParallelForks', test.maxParallelForks } else if ( project.db == "oracle_test_pilot_database" ) { - // Parallel test runs when running with Oracle Test Pilot databases - // see GradleParallelTestingUsernameResolver - test.maxParallelForks = Runtime.runtime.availableProcessors() ?: 1 + // Since Oracle TestPilot databases run on separate machines, use all threads for testing + test.maxParallelForks = Runtime.runtime.availableProcessors() test.systemProperty 'maxParallelForks', test.maxParallelForks } } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/datasource/DataSourceTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/datasource/DataSourceTest.java index a4f75b5c769d..56a7d11f0b49 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/datasource/DataSourceTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/datasource/DataSourceTest.java @@ -23,6 +23,7 @@ import static org.hibernate.internal.util.StringHelper.split; +import static org.hibernate.testing.jdbc.GradleParallelTestingResolver.resolveUrl; import static org.junit.jupiter.api.Assertions.assertTrue; @Jpa(annotatedClasses = DataSourceTest.TestEntity.class, @@ -54,7 +55,7 @@ private static class Listener implements LogListener { @Override public void loggedEvent(Logger.Level level, String renderedMessage, Throwable thrown) { if ( renderedMessage.contains( "Database info:" ) ) { - final String url = Environment.getProperties().getProperty( JdbcSettings.URL ); + final String url = resolveUrl( Environment.getProperties().getProperty( JdbcSettings.URL ) ); final String firstUrlPart = split( "?", split( ";", url )[0])[0]; final String baseUrl = firstUrlPart.endsWith( "/" ) ? firstUrlPart.substring( 0, firstUrlPart.length() - 1 ) : firstUrlPart; seen = renderedMessage.contains( baseUrl ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/jakarta/JakartaSchemaToolingTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/jakarta/JakartaSchemaToolingTests.java index 52c816123b7a..02a882b31e75 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/jakarta/JakartaSchemaToolingTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/jakarta/JakartaSchemaToolingTests.java @@ -37,7 +37,7 @@ import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_PASSWORD; import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_URL; import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_USER; -import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.*; +import static org.hibernate.testing.jdbc.GradleParallelTestingResolver.*; /** @@ -66,8 +66,8 @@ private void verifySchemaCreation( final SessionFactoryImplementor sessionFactory = buildSessionFactory( actionSettingName, Action.CREATE_DROP, driverSettingName, Environment.getProperties().get( AvailableSettings.DRIVER ), - urlSettingName, Environment.getProperties().get( AvailableSettings.URL ), - userSettingName, resolveUsername( (String)Environment.getProperties().get( AvailableSettings.USER ) ), + urlSettingName, resolveUrl( (String) Environment.getProperties().get( AvailableSettings.URL ) ), + userSettingName, resolveUsername( (String) Environment.getProperties().get( AvailableSettings.USER ) ), passwordSettingName, Environment.getProperties().get( AvailableSettings.PASS ) ); try { @@ -94,9 +94,9 @@ public void testPrecedence() { HBM2DDL_DATABASE_ACTION, Action.NONE, JAKARTA_JDBC_DRIVER, Environment.getProperties().get( AvailableSettings.DRIVER ), JPA_JDBC_DRIVER, "does.not.exist", - JAKARTA_JDBC_URL, Environment.getProperties().get( AvailableSettings.URL ), + JAKARTA_JDBC_URL, resolveUrl( (String) Environment.getProperties().get( AvailableSettings.URL ) ), JPA_JDBC_URL, "jdbc:na:nowhere", - JAKARTA_JDBC_USER, resolveUsername( (String)Environment.getProperties().get( AvailableSettings.USER ) ), + JAKARTA_JDBC_USER, resolveUsername( (String) Environment.getProperties().get( AvailableSettings.USER ) ), JPA_JDBC_USER, "goofy", JAKARTA_JDBC_PASSWORD, Environment.getProperties().get( AvailableSettings.PASS ), JPA_JDBC_PASSWORD, "goober" @@ -112,8 +112,8 @@ public void testCreateDropWithFailureInBetween() { assertThatThrownBy( () -> buildSessionFactory( JAKARTA_HBM2DDL_DATABASE_ACTION, Action.CREATE_DROP, JAKARTA_JDBC_DRIVER, Environment.getProperties().get( AvailableSettings.DRIVER ), - JAKARTA_JDBC_URL, Environment.getProperties().get( AvailableSettings.URL ), - JAKARTA_JDBC_USER, resolveUsername( (String)Environment.getProperties().get( AvailableSettings.USER ) ), + JAKARTA_JDBC_URL, resolveUrl( (String) Environment.getProperties().get( AvailableSettings.URL ) ), + JAKARTA_JDBC_USER, resolveUsername( (String) Environment.getProperties().get( AvailableSettings.USER ) ), JAKARTA_JDBC_PASSWORD, Environment.getProperties().get( AvailableSettings.PASS ), // Simulates a failure from e.g. the Hibernate Search observer AvailableSettings.SESSION_FACTORY_OBSERVER, new SessionFactoryObserver() { @@ -129,7 +129,7 @@ public void sessionFactoryCreated(org.hibernate.SessionFactory factory) { try ( SessionFactoryImplementor sessionFactory = buildSessionFactory( JAKARTA_HBM2DDL_DATABASE_ACTION, Action.NONE, JAKARTA_JDBC_DRIVER, Environment.getProperties().get( AvailableSettings.DRIVER ), - JAKARTA_JDBC_URL, Environment.getProperties().get( AvailableSettings.URL ), + JAKARTA_JDBC_URL, resolveUrl( (String) Environment.getProperties().get( AvailableSettings.URL ) ), JAKARTA_JDBC_USER, resolveUsername( (String)Environment.getProperties().get( AvailableSettings.USER ) ), JAKARTA_JDBC_PASSWORD, Environment.getProperties().get( AvailableSettings.PASS ) ) ) { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/util/connections/BaseDataSource.java b/hibernate-core/src/test/java/org/hibernate/orm/test/util/connections/BaseDataSource.java index 02daf514b90b..df94d850466b 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/util/connections/BaseDataSource.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/util/connections/BaseDataSource.java @@ -14,7 +14,7 @@ import org.hibernate.cfg.Environment; -import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.*; +import static org.hibernate.testing.jdbc.GradleParallelTestingResolver.*; /** * Simple {@link DataSource} implementation useful in various integration tests, @@ -26,7 +26,7 @@ public class BaseDataSource implements DataSource { private final String url; public BaseDataSource(Properties configuration) { - url = configuration.getProperty( Environment.URL ); + url = resolveUrl( configuration.getProperty( Environment.URL ) ); connectionProperties = new Properties(); resolveFromSettings( configuration ); connectionProperties.put( "user", configuration.getProperty( Environment.USER ) ); diff --git a/hibernate-envers/hibernate-envers.gradle b/hibernate-envers/hibernate-envers.gradle index b2b170138b2b..1399c597cab4 100644 --- a/hibernate-envers/hibernate-envers.gradle +++ b/hibernate-envers/hibernate-envers.gradle @@ -55,14 +55,17 @@ configurations { } tasks.withType( Test.class ).each { test -> - if ( project.db == "h2" || project.db == "hsqldb" ) { - // Parallel test runs when running with in-memory databases - test.maxParallelForks = Runtime.runtime.availableProcessors().intdiv( 2 ) ?: 1 + // see GradleParallelTestingResolver for how the test worker id is resolved in JDBC configs + if ( project.db == "h2" || project.db == "hsqldb" || project.db == "pgsql_ci" ) { + // Most systems have multi-threading and maxing out a core on both threads will hurt performance + // Also, as soon as we hit 16+ threads, the returns are diminishing, so divide by 4 + def threadCount = Runtime.runtime.availableProcessors() + test.maxParallelForks = threadCount >= 16 ? threadCount.intdiv( 4 ) : (threadCount.intdiv( 2 ) ?: 1) + test.systemProperty 'maxParallelForks', test.maxParallelForks } else if ( project.db == "oracle_test_pilot_database" ) { - // Parallel test runs when running with Oracle Test Pilot databases - // see GradleParallelTestingUsernameResolver - test.maxParallelForks = Runtime.runtime.availableProcessors() ?: 1 + // Since Oracle TestPilot databases run on separate machines, use all threads for testing + test.maxParallelForks = Runtime.runtime.availableProcessors() test.systemProperty 'maxParallelForks', test.maxParallelForks } } diff --git a/hibernate-hikaricp/src/test/java/org/hibernate/test/hikaricp/util/GradleParallelTestingHikariCPConnectionProvider.java b/hibernate-hikaricp/src/test/java/org/hibernate/test/hikaricp/util/GradleParallelTestingHikariCPConnectionProvider.java index 9fbb6a258ff3..6e448b24068f 100644 --- a/hibernate-hikaricp/src/test/java/org/hibernate/test/hikaricp/util/GradleParallelTestingHikariCPConnectionProvider.java +++ b/hibernate-hikaricp/src/test/java/org/hibernate/test/hikaricp/util/GradleParallelTestingHikariCPConnectionProvider.java @@ -9,7 +9,7 @@ import java.util.Map; -import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.resolveFromSettings; +import static org.hibernate.testing.jdbc.GradleParallelTestingResolver.resolveFromSettings; /** * @author Loïc Lefèvre diff --git a/hibernate-jfr/src/test/resources/hibernate.properties b/hibernate-jfr/src/test/resources/hibernate.properties index 8d70d42dcfcb..6e2a831a5f6c 100644 --- a/hibernate-jfr/src/test/resources/hibernate.properties +++ b/hibernate-jfr/src/test/resources/hibernate.properties @@ -4,6 +4,7 @@ # hibernate.dialect @db.dialect@ hibernate.connection.driver_class @jdbc.driver@ +hibernate.connection.creator_factory_class org.hibernate.testing.jdbc.GradleParallelTestingConnectionCreatorFactoryImpl hibernate.connection.url @jdbc.url@ hibernate.connection.username @jdbc.user@ hibernate.connection.password @jdbc.pass@ diff --git a/hibernate-spatial/src/test/resources/hibernate.properties b/hibernate-spatial/src/test/resources/hibernate.properties index c72e0a90b69d..988074fb074e 100644 --- a/hibernate-spatial/src/test/resources/hibernate.properties +++ b/hibernate-spatial/src/test/resources/hibernate.properties @@ -5,6 +5,7 @@ # hibernate.dialect @db.dialect@ hibernate.connection.driver_class @jdbc.driver@ +hibernate.connection.creator_factory_class org.hibernate.testing.jdbc.GradleParallelTestingConnectionCreatorFactoryImpl hibernate.connection.url @jdbc.url@ hibernate.connection.username @jdbc.user@ hibernate.connection.password @jdbc.pass@ diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cleaner/JdbcConnectionContext.java b/hibernate-testing/src/main/java/org/hibernate/testing/cleaner/JdbcConnectionContext.java index ac1d89dfe5b6..07502da059fc 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cleaner/JdbcConnectionContext.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cleaner/JdbcConnectionContext.java @@ -11,7 +11,7 @@ import org.hibernate.cfg.AvailableSettings; -import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.*; +import static org.hibernate.testing.jdbc.GradleParallelTestingResolver.*; /** * @author Christian Beikov @@ -28,16 +28,12 @@ public final class JdbcConnectionContext { .getContextClassLoader() .getResourceAsStream( "hibernate.properties" )) { connectionProperties.load( inputStream ); - final String driverClassName = connectionProperties.getProperty( - AvailableSettings.DRIVER ); + final String driverClassName = connectionProperties.getProperty( AvailableSettings.DRIVER ); driver = (Driver) Class.forName( driverClassName ).newInstance(); - url = connectionProperties.getProperty( - AvailableSettings.URL ); + url = resolveUrl( connectionProperties.getProperty( AvailableSettings.URL ) ); resolveFromSettings(connectionProperties); - user = connectionProperties.getProperty( - AvailableSettings.USER ); - password = connectionProperties.getProperty( - AvailableSettings.PASS ); + user = connectionProperties.getProperty( AvailableSettings.USER ); + password = connectionProperties.getProperty( AvailableSettings.PASS ); final Properties p = new Properties(); if ( user != null ) { p.put( "user", user ); diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/ConnectionProviderDelegate.java b/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/ConnectionProviderDelegate.java index 7b69ad200c9d..6fad0ca99cf6 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/ConnectionProviderDelegate.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/ConnectionProviderDelegate.java @@ -20,7 +20,7 @@ import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.service.spi.Stoppable; -import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.resolveFromSettings; +import static org.hibernate.testing.jdbc.GradleParallelTestingResolver.resolveFromSettings; /** * This {@link ConnectionProvider} extends any other ConnectionProvider diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/GradleParallelTestingConnectionCreatorFactoryImpl.java b/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/GradleParallelTestingConnectionCreatorFactoryImpl.java index a283aeb56cfe..4a012fc26b59 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/GradleParallelTestingConnectionCreatorFactoryImpl.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/GradleParallelTestingConnectionCreatorFactoryImpl.java @@ -14,7 +14,7 @@ import java.util.Map; import java.util.Properties; -import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.*; +import static org.hibernate.testing.jdbc.GradleParallelTestingResolver.*; /** * A factory for {@link ConnectionCreator} instances that can be used for Gradle Parallel Testing. @@ -38,6 +38,7 @@ public ConnectionCreator create( Map configurationValues) { // now resolve JDBC Username if needed for Gradle Parallel Testing + url = resolveUrl( url ); resolve( connectionProps ); if ( driver == null ) { diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/GradleParallelTestingUsernameResolver.java b/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/GradleParallelTestingResolver.java similarity index 70% rename from hibernate-testing/src/main/java/org/hibernate/testing/jdbc/GradleParallelTestingUsernameResolver.java rename to hibernate-testing/src/main/java/org/hibernate/testing/jdbc/GradleParallelTestingResolver.java index 4a4ae27a24fe..cd34646ff773 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/GradleParallelTestingUsernameResolver.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/GradleParallelTestingResolver.java @@ -10,11 +10,11 @@ import java.util.Properties; /** - * JDBC username resolver for parallel tests. + * JDBC config resolver for parallel tests. * * @author Loïc Lefèvre */ -public class GradleParallelTestingUsernameResolver { +public class GradleParallelTestingResolver { private static final String JDBC_USER_CONNECTION_PROPERTY = "user"; @@ -38,6 +38,11 @@ public static void resolve(final Properties connectionProps) { connectionProps.put( JDBC_USER_CONNECTION_PROPERTY, user.replace( GRADLE_WORKER_PATTERN, String.valueOf( getRunningID() ) ) ); } + final String url = connectionProps.getProperty( AvailableSettings.URL ); + if ( url != null && url.contains( GRADLE_WORKER_PATTERN ) ) { + connectionProps.put( AvailableSettings.URL, + url.replace( GRADLE_WORKER_PATTERN, String.valueOf( getRunningID() ) ) ); + } } } @@ -49,6 +54,11 @@ public static void resolveFromSettings(final Properties settingsProps) { settingsProps.put( AvailableSettings.USER, user.replace( GRADLE_WORKER_PATTERN, String.valueOf( getRunningID() ) ) ); } + final String url = settingsProps.getProperty( AvailableSettings.URL ); + if ( url != null && url.contains( GRADLE_WORKER_PATTERN ) ) { + settingsProps.put( AvailableSettings.URL, + url.replace( GRADLE_WORKER_PATTERN, String.valueOf( getRunningID() ) ) ); + } } } @@ -60,20 +70,20 @@ public static void resolveFromSettings(final Map settingsProps) settingsProps.put( AvailableSettings.USER, user.replace( GRADLE_WORKER_PATTERN, String.valueOf( getRunningID() ) ) ); } + final String url = (String) settingsProps.get( AvailableSettings.URL ); + if ( url != null && url.contains( GRADLE_WORKER_PATTERN ) ) { + settingsProps.put( AvailableSettings.URL, + url.replace( GRADLE_WORKER_PATTERN, String.valueOf( getRunningID() ) ) ); + } } } + public static String resolveUrl(String url) { + return url.replace( GRADLE_WORKER_PATTERN, String.valueOf( getRunningID() ) ); + } + public static String resolveUsername(String username) { - if(username != null) { - if ( username.contains( GRADLE_WORKER_PATTERN ) ) { - return username.replace( GRADLE_WORKER_PATTERN, String.valueOf( getRunningID() ) ); - } - else { - return username; - } - } else { - throw new IllegalArgumentException("Username must not be null!"); - } + return username.replace( GRADLE_WORKER_PATTERN, String.valueOf( getRunningID() ) ); } /** @@ -87,7 +97,8 @@ public static String resolveUsername(String username) { private static int getRunningID() { // enable parallelization of up to GRADLE_MAXIMUM_PARALLEL_FORKS final Integer maxParallelForks = Integer.valueOf( System.getProperty( GRADLE_MAXIMUM_PARALLEL_FORKS, "1" ) ); + // Note that the worker ids are strictly monotonic final Integer worker = Integer.valueOf( System.getProperty( GRADLE_WORKER_ID, "1" ) ); - return (worker % maxParallelForks) + 1; // returns 1, 2, 3... + return (worker % maxParallelForks) + 1; } } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/JdbcProperties.java b/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/JdbcProperties.java index d951113c342f..172c3dd8a5b8 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/JdbcProperties.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/JdbcProperties.java @@ -10,7 +10,8 @@ import org.jboss.logging.Logger; -import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.resolveFromSettings; +import static org.hibernate.testing.jdbc.GradleParallelTestingResolver.resolveFromSettings; +import static org.hibernate.testing.jdbc.GradleParallelTestingResolver.resolveUrl; /** * @author Vlad Mihalcea @@ -36,13 +37,10 @@ public JdbcProperties() { .getResourceAsStream( "hibernate.properties" ); try { connectionProperties.load( inputStream ); - url = connectionProperties.getProperty( - "hibernate.connection.url" ); + url = resolveUrl( connectionProperties.getProperty( "hibernate.connection.url" ) ); resolveFromSettings(connectionProperties); - user = connectionProperties.getProperty( - "hibernate.connection.username" ); - password = connectionProperties.getProperty( - "hibernate.connection.password" ); + user = connectionProperties.getProperty( "hibernate.connection.username" ); + password = connectionProperties.getProperty( "hibernate.connection.password" ); } catch ( IOException e ) { throw new IllegalArgumentException( e ); diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/orm/junit/DialectContext.java b/hibernate-testing/src/main/java/org/hibernate/testing/orm/junit/DialectContext.java index 4834ce6834d1..20e52dfaf1a1 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/orm/junit/DialectContext.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/orm/junit/DialectContext.java @@ -18,7 +18,8 @@ import org.hibernate.exception.JDBCConnectionException; import org.hibernate.internal.util.ReflectHelper; -import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.resolveFromSettings; +import static org.hibernate.testing.jdbc.GradleParallelTestingResolver.resolveFromSettings; +import static org.hibernate.testing.jdbc.GradleParallelTestingResolver.resolveUrl; /** * @author Christian Beikov @@ -45,7 +46,7 @@ static void initDialectClass() { static void init() { final Properties properties = Environment.getProperties(); final String driverClassName = properties.getProperty( Environment.DRIVER ); - final String jdbcUrl = properties.getProperty( Environment.URL ); + final String jdbcUrl = resolveUrl( properties.getProperty( Environment.URL ) ); final Properties props = new Properties(); resolveFromSettings(properties); props.setProperty( "user", properties.getProperty( Environment.USER ) ); diff --git a/local-build-plugins/src/main/groovy/local.databases.gradle b/local-build-plugins/src/main/groovy/local.databases.gradle index 57bbda2dce3d..62b17a0153fa 100644 --- a/local-build-plugins/src/main/groovy/local.databases.gradle +++ b/local-build-plugins/src/main/groovy/local.databases.gradle @@ -70,7 +70,7 @@ ext { 'jdbc.user' : 'hibernate_orm_test', 'jdbc.pass' : 'hibernate_orm_test', // Disable prepared statement caching due to https://www.postgresql.org/message-id/CAEcMXhmmRd4-%2BNQbnjDT26XNdUoXdmntV9zdr8%3DTu8PL9aVCYg%40mail.gmail.com - 'jdbc.url' : 'jdbc:postgresql://' + dbHost + '/hibernate_orm_test?preparedStatementCacheQueries=0&escapeSyntaxCallMode=callIfNoReturn', + 'jdbc.url' : 'jdbc:postgresql://' + dbHost + '/hibernate_orm_test_$worker?preparedStatementCacheQueries=0&escapeSyntaxCallMode=callIfNoReturn', 'jdbc.datasource' : 'org.postgresql.Driver', // 'jdbc.datasource' : 'org.postgresql.ds.PGSimpleDataSource', 'connection.init_sql' : ''