Skip to content

Commit 41b3177

Browse files
committed
HHH-14892 Enable parallel testing for PostgreSQL
1 parent 978042e commit 41b3177

File tree

18 files changed

+104
-68
lines changed

18 files changed

+104
-68
lines changed

docker_db.sh

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -172,34 +172,57 @@ postgresql() {
172172
postgresql_13() {
173173
$CONTAINER_CLI rm -f postgres || true
174174
$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}
175-
$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;"'
175+
$CONTAINER_CLI exec postgres bash -c '/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && apt install -y postgresql-13-pgvector'
176+
postgresql_setup
176177
}
177178

178179
postgresql_14() {
179180
$CONTAINER_CLI rm -f postgres || true
180181
$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}
181-
$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;"'
182+
$CONTAINER_CLI exec postgres bash -c '/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && apt install -y postgresql-14-pgvector'
183+
postgresql_setup
182184
}
183185

184186
postgresql_15() {
185187
$CONTAINER_CLI rm -f postgres || true
186188
$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} \
187189
-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
188-
$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;"'
190+
$CONTAINER_CLI exec postgres bash -c '/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && apt install -y postgresql-15-pgvector'
191+
postgresql_setup
189192
}
190193

191194
postgresql_16() {
192195
$CONTAINER_CLI rm -f postgres || true
193196
$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} \
194197
-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
195-
$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;"'
198+
$CONTAINER_CLI exec postgres bash -c '/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && apt install -y postgresql-16-pgvector'
199+
postgresql_setup
196200
}
197201

198202
postgresql_17() {
199203
$CONTAINER_CLI rm -f postgres || true
200204
$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} \
201205
-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
202-
$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;"'
206+
$CONTAINER_CLI exec postgres bash -c '/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && apt install -y postgresql-17-pgvector'
207+
postgresql_setup
208+
}
209+
210+
postgresql_setup() {
211+
databases=()
212+
for n in $(seq 1 $(($(nproc)/2)))
213+
do
214+
databases+=("hibernate_orm_test_${n}")
215+
done
216+
create_cmd=
217+
for i in "${!databases[@]}";do
218+
create_cmd+="psql -U hibernate_orm_test -d postgres -c \"create database ${databases[i]};\";"
219+
done
220+
$CONTAINER_CLI exec postgres bash -c "until pg_isready -U hibernate_orm_test; do sleep 1; done"
221+
$CONTAINER_CLI exec postgres bash -c "${create_cmd}"
222+
$CONTAINER_CLI exec postgres bash -c 'psql -U hibernate_orm_test -d hibernate_orm_test -c "create extension vector;"'
223+
for i in "${!databases[@]}";do
224+
$CONTAINER_CLI exec postgres bash -c "psql -U hibernate_orm_test -d ${databases[i]} -c \"create extension vector; create extension postgis;\""
225+
done
203226
}
204227

205228
gaussdb() {

hibernate-agroal/src/test/java/org/hibernate/test/agroal/util/GradleParallelTestingAgroalConnectionProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
import java.util.Map;
1111

12-
import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.resolveFromSettings;
12+
import static org.hibernate.testing.jdbc.GradleParallelTestingResolver.resolveFromSettings;
1313

1414
/**
1515
* @author Loïc Lefèvre

hibernate-c3p0/src/test/java/org/hibernate/test/c3p0/util/GradleParallelTestingC3P0ConnectionProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
import java.util.Map;
1111

12-
import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.resolveFromSettings;
12+
import static org.hibernate.testing.jdbc.GradleParallelTestingResolver.resolveFromSettings;
1313

1414
/**
1515
* @author Loïc Lefèvre

hibernate-core/hibernate-core.gradle

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -259,17 +259,17 @@ tasks.withType( Test.class ).each { test ->
259259
//Avoid Log4J2 classloader leaks:
260260
test.jvmArgs( ['-Dlog4j2.disableJmx=true'] )
261261

262-
test.beforeTest { descriptor ->
263-
//println "Starting test: " + descriptor
264-
}
265-
if ( project.db == "h2" || project.db == "hsqldb" ) {
266-
// Parallel test runs when running with in-memory databases
267-
test.maxParallelForks = Runtime.runtime.availableProcessors().intdiv( 2 ) ?: 1
262+
// see GradleParallelTestingResolver for how the test worker id is resolved in JDBC configs
263+
if ( project.db == "h2" || project.db == "hsqldb" || project.db == "pgsql_ci" ) {
264+
// Most systems have multi-threading and maxing out a core on both threads will hurt performance
265+
// Also, as soon as we hit 16+ threads, the returns are diminishing, so divide by 4
266+
def threadCount = Runtime.runtime.availableProcessors()
267+
test.maxParallelForks = threadCount >= 16 ? threadCount.intdiv( 4 ) : (threadCount.intdiv( 2 ) ?: 1)
268+
test.systemProperty 'maxParallelForks', test.maxParallelForks
268269
}
269270
else if ( project.db == "oracle_test_pilot_database" ) {
270-
// Parallel test runs when running with Oracle Test Pilot databases
271-
// see GradleParallelTestingUsernameResolver
272-
test.maxParallelForks = Runtime.runtime.availableProcessors() ?: 1
271+
// Since Oracle TestPilot databases run on separate machines, use all threads for testing
272+
test.maxParallelForks = Runtime.runtime.availableProcessors()
273273
test.systemProperty 'maxParallelForks', test.maxParallelForks
274274
}
275275
}

hibernate-core/src/test/java/org/hibernate/orm/test/datasource/DataSourceTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424

2525
import static org.hibernate.internal.util.StringHelper.split;
26+
import static org.hibernate.testing.jdbc.GradleParallelTestingResolver.resolveUrl;
2627
import static org.junit.jupiter.api.Assertions.assertTrue;
2728

2829
@Jpa(annotatedClasses = DataSourceTest.TestEntity.class,
@@ -54,7 +55,7 @@ private static class Listener implements LogListener {
5455
@Override
5556
public void loggedEvent(Logger.Level level, String renderedMessage, Throwable thrown) {
5657
if ( renderedMessage.contains( "Database info:" ) ) {
57-
final String url = Environment.getProperties().getProperty( JdbcSettings.URL );
58+
final String url = resolveUrl( Environment.getProperties().getProperty( JdbcSettings.URL ) );
5859
final String firstUrlPart = split( "?", split( ";", url )[0])[0];
5960
final String baseUrl = firstUrlPart.endsWith( "/" ) ? firstUrlPart.substring( 0, firstUrlPart.length() - 1 ) : firstUrlPart;
6061
seen = renderedMessage.contains( baseUrl );

hibernate-core/src/test/java/org/hibernate/orm/test/jpa/jakarta/JakartaSchemaToolingTests.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_PASSWORD;
3838
import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_URL;
3939
import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_USER;
40-
import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.*;
40+
import static org.hibernate.testing.jdbc.GradleParallelTestingResolver.*;
4141

4242

4343
/**
@@ -66,8 +66,8 @@ private void verifySchemaCreation(
6666
final SessionFactoryImplementor sessionFactory = buildSessionFactory(
6767
actionSettingName, Action.CREATE_DROP,
6868
driverSettingName, Environment.getProperties().get( AvailableSettings.DRIVER ),
69-
urlSettingName, Environment.getProperties().get( AvailableSettings.URL ),
70-
userSettingName, resolveUsername( (String)Environment.getProperties().get( AvailableSettings.USER ) ),
69+
urlSettingName, resolveUrl( (String) Environment.getProperties().get( AvailableSettings.URL ) ),
70+
userSettingName, resolveUsername( (String) Environment.getProperties().get( AvailableSettings.USER ) ),
7171
passwordSettingName, Environment.getProperties().get( AvailableSettings.PASS )
7272
);
7373
try {
@@ -94,9 +94,9 @@ public void testPrecedence() {
9494
HBM2DDL_DATABASE_ACTION, Action.NONE,
9595
JAKARTA_JDBC_DRIVER, Environment.getProperties().get( AvailableSettings.DRIVER ),
9696
JPA_JDBC_DRIVER, "does.not.exist",
97-
JAKARTA_JDBC_URL, Environment.getProperties().get( AvailableSettings.URL ),
97+
JAKARTA_JDBC_URL, resolveUrl( (String) Environment.getProperties().get( AvailableSettings.URL ) ),
9898
JPA_JDBC_URL, "jdbc:na:nowhere",
99-
JAKARTA_JDBC_USER, resolveUsername( (String)Environment.getProperties().get( AvailableSettings.USER ) ),
99+
JAKARTA_JDBC_USER, resolveUsername( (String) Environment.getProperties().get( AvailableSettings.USER ) ),
100100
JPA_JDBC_USER, "goofy",
101101
JAKARTA_JDBC_PASSWORD, Environment.getProperties().get( AvailableSettings.PASS ),
102102
JPA_JDBC_PASSWORD, "goober"
@@ -112,8 +112,8 @@ public void testCreateDropWithFailureInBetween() {
112112
assertThatThrownBy( () -> buildSessionFactory(
113113
JAKARTA_HBM2DDL_DATABASE_ACTION, Action.CREATE_DROP,
114114
JAKARTA_JDBC_DRIVER, Environment.getProperties().get( AvailableSettings.DRIVER ),
115-
JAKARTA_JDBC_URL, Environment.getProperties().get( AvailableSettings.URL ),
116-
JAKARTA_JDBC_USER, resolveUsername( (String)Environment.getProperties().get( AvailableSettings.USER ) ),
115+
JAKARTA_JDBC_URL, resolveUrl( (String) Environment.getProperties().get( AvailableSettings.URL ) ),
116+
JAKARTA_JDBC_USER, resolveUsername( (String) Environment.getProperties().get( AvailableSettings.USER ) ),
117117
JAKARTA_JDBC_PASSWORD, Environment.getProperties().get( AvailableSettings.PASS ),
118118
// Simulates a failure from e.g. the Hibernate Search observer
119119
AvailableSettings.SESSION_FACTORY_OBSERVER, new SessionFactoryObserver() {
@@ -129,7 +129,7 @@ public void sessionFactoryCreated(org.hibernate.SessionFactory factory) {
129129
try ( SessionFactoryImplementor sessionFactory = buildSessionFactory(
130130
JAKARTA_HBM2DDL_DATABASE_ACTION, Action.NONE,
131131
JAKARTA_JDBC_DRIVER, Environment.getProperties().get( AvailableSettings.DRIVER ),
132-
JAKARTA_JDBC_URL, Environment.getProperties().get( AvailableSettings.URL ),
132+
JAKARTA_JDBC_URL, resolveUrl( (String) Environment.getProperties().get( AvailableSettings.URL ) ),
133133
JAKARTA_JDBC_USER, resolveUsername( (String)Environment.getProperties().get( AvailableSettings.USER ) ),
134134
JAKARTA_JDBC_PASSWORD, Environment.getProperties().get( AvailableSettings.PASS )
135135
) ) {

hibernate-core/src/test/java/org/hibernate/orm/test/util/connections/BaseDataSource.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
import org.hibernate.cfg.Environment;
1616

17-
import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.*;
17+
import static org.hibernate.testing.jdbc.GradleParallelTestingResolver.*;
1818

1919
/**
2020
* Simple {@link DataSource} implementation useful in various integration tests,
@@ -26,7 +26,7 @@ public class BaseDataSource implements DataSource {
2626
private final String url;
2727

2828
public BaseDataSource(Properties configuration) {
29-
url = configuration.getProperty( Environment.URL );
29+
url = resolveUrl( configuration.getProperty( Environment.URL ) );
3030
connectionProperties = new Properties();
3131
resolveFromSettings( configuration );
3232
connectionProperties.put( "user", configuration.getProperty( Environment.USER ) );

hibernate-envers/hibernate-envers.gradle

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,17 @@ configurations {
5555
}
5656

5757
tasks.withType( Test.class ).each { test ->
58-
if ( project.db == "h2" || project.db == "hsqldb" ) {
59-
// Parallel test runs when running with in-memory databases
60-
test.maxParallelForks = Runtime.runtime.availableProcessors().intdiv( 2 ) ?: 1
58+
// see GradleParallelTestingResolver for how the test worker id is resolved in JDBC configs
59+
if ( project.db == "h2" || project.db == "hsqldb" || project.db == "pgsql_ci" ) {
60+
// Most systems have multi-threading and maxing out a core on both threads will hurt performance
61+
// Also, as soon as we hit 16+ threads, the returns are diminishing, so divide by 4
62+
def threadCount = Runtime.runtime.availableProcessors()
63+
test.maxParallelForks = threadCount >= 16 ? threadCount.intdiv( 4 ) : (threadCount.intdiv( 2 ) ?: 1)
64+
test.systemProperty 'maxParallelForks', test.maxParallelForks
6165
}
6266
else if ( project.db == "oracle_test_pilot_database" ) {
63-
// Parallel test runs when running with Oracle Test Pilot databases
64-
// see GradleParallelTestingUsernameResolver
65-
test.maxParallelForks = Runtime.runtime.availableProcessors() ?: 1
67+
// Since Oracle TestPilot databases run on separate machines, use all threads for testing
68+
test.maxParallelForks = Runtime.runtime.availableProcessors()
6669
test.systemProperty 'maxParallelForks', test.maxParallelForks
6770
}
6871
}

hibernate-hikaricp/src/test/java/org/hibernate/test/hikaricp/util/GradleParallelTestingHikariCPConnectionProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
import java.util.Map;
1111

12-
import static org.hibernate.testing.jdbc.GradleParallelTestingUsernameResolver.resolveFromSettings;
12+
import static org.hibernate.testing.jdbc.GradleParallelTestingResolver.resolveFromSettings;
1313

1414
/**
1515
* @author Loïc Lefèvre

hibernate-jfr/src/test/resources/hibernate.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#
55
hibernate.dialect @db.dialect@
66
hibernate.connection.driver_class @jdbc.driver@
7+
hibernate.connection.creator_factory_class org.hibernate.testing.jdbc.GradleParallelTestingConnectionCreatorFactoryImpl
78
hibernate.connection.url @jdbc.url@
89
hibernate.connection.username @jdbc.user@
910
hibernate.connection.password @jdbc.pass@

0 commit comments

Comments
 (0)