Fix PostgreSQL cleanup wrt extensions, fix Oracle cleanup wrt sys objects, always drop id tables in tests, fix global temp table tests, add on commit delete rows for hana dialects

This commit is contained in:
Christian Beikov 2021-02-09 13:03:18 +01:00 committed by Andrea Boriero
parent 2eaa0f8c67
commit 15caff9cbc
21 changed files with 157 additions and 29 deletions

7
.github/ci-prerequisites.sh vendored Executable file
View File

@ -0,0 +1,7 @@
# Reclaim disk space, otherwise we only have 13 GB free at the start of a job
docker rmi node:10 node:12 mcr.microsoft.com/azure-pipelines/node8-typescript:latest
# That is 18 GB
sudo rm -rf /usr/share/dotnet
# That is 1.2 GB
sudo rm -rf /usr/share/swift

View File

@ -43,6 +43,8 @@ jobs:
experimental: true
steps:
- uses: actions/checkout@v2
- name: Reclaim Disk Space
run: .github/ci-prerequisites.sh
- name: Set up Java 8
uses: actions/setup-java@v1
with:

View File

@ -87,6 +87,70 @@ alter database drop logfile group 3;
EOF\""
}
oracle_ee() {
docker rm -f oracle || true
# We need to use the defaults
# sys as sysdba/Oradoc_db1
docker run --name oracle -d -p 1521:1521 store/oracle/database-enterprise:12.2.0.1-slim
# Give the container some time to start
OUTPUT=
while [[ $OUTPUT != *"NLS_CALENDAR"* ]]; do
echo "Waiting for Oracle to start..."
sleep 10
OUTPUT=$(docker logs oracle)
done
echo "Oracle successfully started"
# We increase file sizes to avoid online resizes as that requires lots of CPU which is restricted in XE
docker exec oracle bash -c "source /home/oracle/.bashrc; \$ORACLE_HOME/bin/sqlplus sys/Oradoc_db1@ORCLCDB as sysdba <<EOF
create user c##hibernate_orm_test identified by hibernate_orm_test container=all;
grant connect, resource, dba to c##hibernate_orm_test container=all;
alter database tempfile '/u02/app/oracle/oradata/ORCL/temp01.dbf' resize 400M;
alter database datafile '/u02/app/oracle/oradata/ORCL/system01.dbf' resize 1000M;
alter database datafile '/u02/app/oracle/oradata/ORCL/sysaux01.dbf' resize 900M;
alter database datafile '/u02/app/oracle/oradata/ORCL/undotbs01.dbf' resize 300M;
alter database add logfile group 4 '/u02/app/oracle/oradata/ORCL/redo04.log' size 500M reuse;
alter database add logfile group 5 '/u02/app/oracle/oradata/ORCL/redo05.log' size 500M reuse;
alter database add logfile group 6 '/u02/app/oracle/oradata/ORCL/redo06.log' size 500M reuse;
alter system switch logfile;
alter system switch logfile;
alter system switch logfile;
alter system checkpoint;
alter database drop logfile group 1;
alter database drop logfile group 2;
alter database drop logfile group 3;
alter session set container=ORCLPDB1;
alter database datafile '/u02/app/oracle/oradata/ORCLCDB/orclpdb1/system01.dbf' resize 500M;
alter database datafile '/u02/app/oracle/oradata/ORCLCDB/orclpdb1/sysaux01.dbf' resize 500M;
EOF"
}
hana() {
temp_dir=$(mktemp -d)
echo '{"master_password" : "H1bernate_test"}' >$temp_dir/password.json
chmod 777 -R $temp_dir
docker rm -f hana || true
docker run -d --name hana -p 39013:39013 -p 39017:39017 -p 39041-39045:39041-39045 -p 1128-1129:1128-1129 -p 59013-59014:59013-59014 \
--ulimit nofile=1048576:1048576 \
--sysctl kernel.shmmax=1073741824 \
--sysctl net.ipv4.ip_local_port_range='40000 60999' \
--sysctl kernel.shmmni=524288 \
--sysctl kernel.shmall=8388608 \
-v $temp_dir:/config \
store/saplabs/hanaexpress:2.00.045.00.20200121.1 \
--passwords-url file:///config/password.json \
--agree-to-sap-license
# Give the container some time to start
OUTPUT=
while [[ $OUTPUT != *"Startup finished"* ]]; do
echo "Waiting for HANA to start..."
sleep 10
OUTPUT=$(docker logs hana)
done
echo "HANA successfully started"
}
if [ -z ${1} ]; then
echo "No db name provided"
echo "Provide one of:"

View File

@ -36,7 +36,8 @@ ext {
'jdbc.driver': 'org.postgresql.Driver',
'jdbc.user' : 'hibernate_orm_test',
'jdbc.pass' : 'hibernate_orm_test',
'jdbc.url' : 'jdbc:postgresql: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'
],
pgsql_docker : [
'db.dialect' : 'org.hibernate.dialect.PostgreSQL10Dialect',
@ -87,7 +88,8 @@ ext {
'jdbc.driver': 'org.postgresql.Driver',
'jdbc.user' : 'hibernate_orm_test',
'jdbc.pass' : 'hibernate_orm_test',
'jdbc.url' : 'jdbc:postgresql: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'
],
oracle : [
'db.dialect' : 'org.hibernate.dialect.Oracle10gDialect',
@ -96,15 +98,13 @@ ext {
'jdbc.pass' : 'hibernate_orm_test',
'jdbc.url' : 'jdbc:oracle:thin:@localhost:1521/xe'
],
// Uses the default settings for using https://hub.docker.com/_/oracle-database-enterprise-edition
// After registering to get access (see instructions at above link), start it for testing with:
// docker run --ulimit memlock=-1:-1 -it --rm=true --memory-swappiness=0 --name ORCLCDB -p 1521:1521 store/oracle/database-enterprise:12.2.0.1-slim
// Use ./docker_db.sh oracle_ee to start the database
oracle_docker : [
'db.dialect' : 'org.hibernate.dialect.Oracle12cDialect',
'jdbc.driver': 'oracle.jdbc.OracleDriver',
'jdbc.user' : 'sys as sysdba',
'jdbc.pass' : 'Oradoc_db1',
'jdbc.url' : 'jdbc:oracle:thin:@localhost:1521:ORCLCDB'
'jdbc.user' : 'c##hibernate_orm_test',
'jdbc.pass' : 'hibernate_orm_test',
'jdbc.url' : 'jdbc:oracle:thin:@' + dbHost + ':1521/ORCLPDB1.localdomain'
],
oracle_ci : [
'db.dialect' : 'org.hibernate.dialect.Oracle12cDialect',
@ -153,21 +153,32 @@ ext {
'jdbc.driver': 'com.sap.db.jdbc.Driver',
'jdbc.user' : 'HIBERNATE_TEST',
'jdbc.pass' : 'H1bernate_test',
'jdbc.url' : 'jdbc:sap://localhost:30015/'
// Disable prepared statement caching due to https://help.sap.com/viewer/0eec0d68141541d1b07893a39944924e/2.0.04/en-US/78f2163887814223858e4369d18e2847.html
'jdbc.url' : 'jdbc:sap://localhost:30015/?statementCacheSize=0'
],
hana_cloud : [
'db.dialect' : 'org.hibernate.dialect.HANACloudColumnStoreDialect',
'jdbc.driver': 'com.sap.db.jdbc.Driver',
'jdbc.user' : 'HIBERNATE_TEST',
'jdbc.pass' : 'H1bernate_test',
'jdbc.url' : 'jdbc:sap://localhost:443/?encrypt=true&validateCertificate=false'
// Disable prepared statement caching due to https://help.sap.com/viewer/0eec0d68141541d1b07893a39944924e/2.0.04/en-US/78f2163887814223858e4369d18e2847.html
'jdbc.url' : 'jdbc:sap://localhost:443/?encrypt=true&validateCertificate=false&statementCacheSize=0'
],
hana_vlad : [
'db.dialect' : 'org.hibernate.dialect.HANAColumnStoreDialect',
'jdbc.driver': 'com.sap.db.jdbc.Driver',
'jdbc.user' : 'VLAD',
'jdbc.pass' : 'V1ad_test',
'jdbc.url' : 'jdbc:sap://localhost:39015/'
// Disable prepared statement caching due to https://help.sap.com/viewer/0eec0d68141541d1b07893a39944924e/2.0.04/en-US/78f2163887814223858e4369d18e2847.html
'jdbc.url' : 'jdbc:sap://localhost:39015/?statementCacheSize=0'
],
hana_docker : [
'db.dialect' : 'org.hibernate.dialect.HANAColumnStoreDialect',
'jdbc.driver': 'com.sap.db.jdbc.Driver',
'jdbc.user' : 'SYSTEM',
'jdbc.pass' : 'H1bernate_test',
// Disable prepared statement caching due to https://help.sap.com/viewer/0eec0d68141541d1b07893a39944924e/2.0.04/en-US/78f2163887814223858e4369d18e2847.html
'jdbc.url' : 'jdbc:sap://' + dbHost + ':39017/?statementCacheSize=0'
],
cockroachdb : [
'db.dialect' : 'org.hibernate.dialect.CockroachDB192Dialect',

View File

@ -287,6 +287,8 @@ test {
systemProperty 'user.country', 'US'
systemProperty 'user.timezone', 'UTC'
systemProperty 'file.encoding', 'UTF-8'
// Needed for AdoptOpenJDK on alpine? The problem is similar to this: https://github.com/mockito/mockito/issues/978
jvmArgs '-XX:+StartAttachListener'
}
// Enable the experimental features of ByteBuddy with JDK 15+

View File

@ -103,6 +103,11 @@ public class HANACloudColumnStoreDialect extends AbstractHANADialect {
return "truncate table";
}
@Override
public String getCreateIdTableStatementOptions() {
return "on commit delete rows";
}
}, AfterUseAction.CLEAN );
}

View File

@ -62,6 +62,11 @@ public class HANAColumnStoreDialect extends AbstractHANADialect {
return "truncate table";
}
@Override
public String getCreateIdTableStatementOptions() {
return "on commit delete rows";
}
}, AfterUseAction.CLEAN );
}

View File

@ -44,6 +44,11 @@ public class HANARowStoreDialect extends AbstractHANADialect {
public String getCreateIdTableCommand() {
return "create global temporary row table";
}
@Override
public String getCreateIdTableStatementOptions() {
return "on commit delete rows";
}
}, AfterUseAction.CLEAN );
}

View File

@ -184,7 +184,7 @@ public class IdTableHelper {
target.accept( createStatement );
}
catch ( CommandAcceptanceException e) {
// The exception will be logged, so ignore this
log.debugf( "Error attempting to export id-table [%s] : %s", createStatement, e.getMessage() );
}
}
}
@ -215,7 +215,7 @@ public class IdTableHelper {
target.accept( dropStatement );
}
catch ( CommandAcceptanceException e) {
// The exception will be logged, so ignore this
log.debugf( "Error attempting to drop id-table : [%s]", e.getMessage() );
}
}
}

View File

@ -228,9 +228,9 @@ public abstract class BaseEntityManagerFunctionalTestCase extends BaseUnitTestCa
config.put( AvailableSettings.XML_FILE_NAMES, dds );
}
config.put( GlobalTemporaryTableBulkIdStrategy.DROP_ID_TABLES, "true" );
config.put( LocalTemporaryTableBulkIdStrategy.DROP_ID_TABLES, "true" );
if ( !config.containsKey( Environment.CONNECTION_PROVIDER ) ) {
config.put( GlobalTemporaryTableBulkIdStrategy.DROP_ID_TABLES, "true" );
config.put( LocalTemporaryTableBulkIdStrategy.DROP_ID_TABLES, "true" );
config.put(
AvailableSettings.CONNECTION_PROVIDER,
SharedDriverManagerConnectionProviderImpl.getInstance()

View File

@ -61,8 +61,7 @@ public class LockTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected void addConfigOptions(Map options) {
super.addConfigOptions( options );
// Looks like Oracle Connections that experience a timeout produce different errors when they timeout again?!
SharedDriverManagerConnectionProviderImpl.getInstance().reset();
// We can't use a shared connection provider if we use TransactionUtil.setJdbcTimeout because that is set on the connection level
options.remove( org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER );
}

View File

@ -44,7 +44,7 @@ public class StatementIsClosedAfterALockExceptionTest extends BaseEntityManagerF
@Override
protected Map getConfig() {
Map config = super.getConfig();
CONNECTION_PROVIDER.setConnectionProvider( (ConnectionProvider) config.get( AvailableSettings.CONNECTION_PROVIDER ) );
// We can't use a shared connection provider if we use TransactionUtil.setJdbcTimeout because that is set on the connection level
config.put(
org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER,
CONNECTION_PROVIDER

View File

@ -35,7 +35,10 @@ public abstract class AbstractBulkCompositeIdTest extends BaseCoreFunctionalTest
@Override
protected Configuration constructConfiguration() {
Configuration configuration = super.constructConfiguration();
configuration.setProperty( AvailableSettings.HQL_BULK_ID_STRATEGY, getMultiTableBulkIdStrategyClass().getName() );
Class<? extends MultiTableBulkIdStrategy> strategyClass = getMultiTableBulkIdStrategyClass();
if ( strategyClass != null ) {
configuration.setProperty( AvailableSettings.HQL_BULK_ID_STRATEGY, strategyClass.getName() );
}
return configuration;
}

View File

@ -14,6 +14,8 @@ public class GlobalTemporaryTableBulkCompositeIdTest extends AbstractBulkComposi
@Override
protected Class<? extends MultiTableBulkIdStrategy> getMultiTableBulkIdStrategyClass() {
return GlobalTemporaryTableBulkIdStrategy.class;
// Since we only allow dialects that support global temporary tables, we avoid overriding the strategy
// This is important because otherwise we would loose id table configurations that are made in the dialects
return null;
}
}

View File

@ -14,6 +14,8 @@ import javax.persistence.LockModeType;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.Session;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.dialect.CockroachDB192Dialect;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.dialect.SybaseASE15Dialect;
@ -53,6 +55,12 @@ public class LockModeTest extends BaseCoreFunctionalTestCase {
return new Class[] { A.class };
}
@Override
protected void configure(Configuration configuration) {
// We can't use a shared connection provider if we use TransactionUtil.setJdbcTimeout because that is set on the connection level
configuration.getProperties().remove( AvailableSettings.CONNECTION_PROVIDER );
}
@Override
public void prepareTest() throws Exception {
doInHibernate( this::sessionFactory, session -> {

View File

@ -125,6 +125,7 @@
FROM ORGANIZATION org
LEFT OUTER JOIN EMPLOYMENT emp ON org.ORGID = emp.EMPLOYER
WHERE org.ORGID=?
ORDER BY emp.EMPID
</sql-query>

View File

@ -143,9 +143,9 @@ public abstract class BaseEnversJPAFunctionalTestCase extends AbstractEnversTest
config.put( AvailableSettings.XML_FILE_NAMES, dds );
}
config.put( GlobalTemporaryTableBulkIdStrategy.DROP_ID_TABLES, "true" );
config.put( LocalTemporaryTableBulkIdStrategy.DROP_ID_TABLES, "true" );
if ( !Environment.getProperties().containsKey( Environment.CONNECTION_PROVIDER ) ) {
config.put( GlobalTemporaryTableBulkIdStrategy.DROP_ID_TABLES, "true" );
config.put( LocalTemporaryTableBulkIdStrategy.DROP_ID_TABLES, "true" );
config.put(
org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER,
SharedDriverManagerConnectionProviderImpl.getInstance()

View File

@ -67,8 +67,8 @@ public class OracleDatabaseCleaner implements DatabaseCleaner {
return statement.executeQuery(
"SELECT 'DROP TABLE ' || owner || '.\"' || table_name || '\" CASCADE CONSTRAINTS' " +
"FROM all_tables " +
// Exclude the tables owner by sys
"WHERE owner NOT IN ('SYS')" +
// Only look at tables owned by the current user
"WHERE owner = sys_context('USERENV', 'SESSION_USER')" +
// Normally, user tables aren't in sysaux
" AND tablespace_name NOT IN ('SYSAUX')" +
// Apparently, user tables have global stats off
@ -76,7 +76,7 @@ public class OracleDatabaseCleaner implements DatabaseCleaner {
// Exclude the tables with names starting like 'DEF$_'
" AND table_name NOT LIKE 'DEF$\\_%' ESCAPE '\\'" +
" UNION ALL " +
"SELECT 'DROP SEQUENCE ' || sequence_owner || '.' || sequence_name FROM all_sequences WHERE sequence_owner NOT IN (" + SYSTEM_SEQUENCE_OWNERS + ")"
"SELECT 'DROP SEQUENCE ' || sequence_owner || '.' || sequence_name FROM all_sequences WHERE sequence_owner = sys_context('USERENV', 'SESSION_USER') and sequence_name not like 'ISEQ$$%'"
);
}
catch (SQLException sqlException) {

View File

@ -85,12 +85,26 @@ public class PostgreSQLDatabaseCleaner implements DatabaseCleaner {
// Collect schema objects
String user = c.getMetaData().getUserName();
LOG.log( Level.FINEST, "Collect schema objects: START" );
Map<String, List<String>> schemaExtensions = new HashMap<>();
try (Statement s2 = c.createStatement()) {
rs = s2.executeQuery(
"SELECT ns.nspname, 'CREATE EXTENSION ' || e.extname || ' SCHEMA \"' || ns.nspname || '\" VERSION ' || e.extversion FROM pg_extension e JOIN pg_catalog.pg_namespace ns ON e.extnamespace = ns.oid WHERE e.extname <> 'plpgsql'"
);
while ( rs.next() ) {
schemaExtensions.computeIfAbsent( rs.getString( 1 ), k -> new ArrayList<>() )
.add( rs.getString( 2 ) );
}
}
rs = schemasProvider.apply( s );
while ( rs.next() ) {
String schema = rs.getString( 1 );
sqls.add( "DROP SCHEMA \"" + schema + "\" CASCADE" );
sqls.add( "CREATE SCHEMA \"" + schema + "\"" );
sqls.add( "GRANT ALL ON SCHEMA \"" + schema + "\" TO \"" + user + "\"" );
List<String> extensions = schemaExtensions.get( schema );
if ( extensions != null ) {
sqls.addAll( extensions );
}
}
LOG.log( Level.FINEST, "Collect schema objects: END" );

View File

@ -179,9 +179,9 @@ public abstract class BaseCoreFunctionalTestCase extends BaseUnitTestCase {
}
configuration.setImplicitNamingStrategy( ImplicitNamingStrategyLegacyJpaImpl.INSTANCE );
configuration.setProperty( Environment.DIALECT, getDialect().getClass().getName() );
configuration.getProperties().put( GlobalTemporaryTableBulkIdStrategy.DROP_ID_TABLES, "true" );
configuration.getProperties().put( LocalTemporaryTableBulkIdStrategy.DROP_ID_TABLES, "true" );
if ( !Environment.getProperties().containsKey( Environment.CONNECTION_PROVIDER ) ) {
configuration.getProperties().put( GlobalTemporaryTableBulkIdStrategy.DROP_ID_TABLES, "true" );
configuration.getProperties().put( LocalTemporaryTableBulkIdStrategy.DROP_ID_TABLES, "true" );
configuration.getProperties().put(
AvailableSettings.CONNECTION_PROVIDER,
SharedDriverManagerConnectionProviderImpl.getInstance()

View File

@ -179,9 +179,9 @@ public class BaseNonConfigCoreFunctionalTestCase extends BaseUnitTestCase {
afterBootstrapServiceRegistryBuilt( bsr );
final Map settings = new HashMap();
settings.put( GlobalTemporaryTableBulkIdStrategy.DROP_ID_TABLES, "true" );
settings.put( LocalTemporaryTableBulkIdStrategy.DROP_ID_TABLES, "true" );
if ( !Environment.getProperties().containsKey( Environment.CONNECTION_PROVIDER ) ) {
settings.put( GlobalTemporaryTableBulkIdStrategy.DROP_ID_TABLES, "true" );
settings.put( LocalTemporaryTableBulkIdStrategy.DROP_ID_TABLES, "true" );
settings.put(
AvailableSettings.CONNECTION_PROVIDER,
SharedDriverManagerConnectionProviderImpl.getInstance()