Extended DbMigrationTest to run on all platforms

This commit is contained in:
Roland Praml
2022-02-25 12:04:24 +01:00
parent 897a97d415
commit 95b1488aed
4 changed files with 184 additions and 18 deletions
@@ -1,11 +1,18 @@
package io.ebeaninternal.dbmigration;
import io.ebean.BaseTestCase;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.SqlRow;
import io.ebean.SqlUpdate;
import io.ebean.Version;
import io.ebean.annotation.IgnorePlatform;
import io.ebean.annotation.Platform;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.dbplatform.DbHistorySupport;
import io.ebean.datasource.pool.ConnectionPool;
import misc.migration.v1_1.EHistory;
import misc.migration.v1_1.EHistory2;
import org.junit.jupiter.api.Test;
@@ -13,12 +20,20 @@ import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
/**
* This testcase tries to apply the migrationtests that are genearated by {@link DbMigrationGenerateTest}.
*
* It does also some basic checks, if the migration is applied correctly.
*
* Please note, that this test requires the scripts generated by DbMigrationGenerateTest. So you may have to execute this test
* first.
*
* @author Roland Praml, FOCONIS AG
*
*/
@@ -29,7 +44,7 @@ public class DbMigrationTest extends BaseTestCase {
assert url != null : scriptName + " not found";
server().script().run(url);
}
@Test
public void lastVersion() {
File d = new File("src/test/resources/migrationtest/dbmigration/h2");
@@ -38,20 +53,6 @@ public class DbMigrationTest extends BaseTestCase {
assertThat(LastMigration.nextVersion(d, null, true)).isEqualTo("1.4");
}
@IgnorePlatform({
Platform.DB2, // currently does not work due missing reorg feature
//Platform.CLICKHOUSE, // test(s) do not start at all
//Platform.COCKROACH, // does not see applied DDL? commit missing?
// Platform.NUODB nuodb container does not start
// Yugabyte does not see column updates on table alters:
// update table T set C = 'value'; alter table T alter column C set not null -> error column C has null values
// do we need a commit after update?
Platform.YUGABYTE,
})
//Platform.ORACLE, Platform.NUODB, Platform.POSTGRES, Platform.YUGABYTE})
// Note: Postgres locks up on build server
// Note: YUGABYTE complains on "alter table migtest_e_basic alter column status set not null;"
@Test
public void testRunMigration() throws IOException, SQLException {
// Shutdown and reconnect - this prevents postgres from lock up
@@ -87,13 +88,17 @@ public class DbMigrationTest extends BaseTestCase {
((ConnectionPool)server().dataSource()).offline();
((ConnectionPool)server().dataSource()).online();
if (isSqlServer() || isMariaDB() || isMySql()) {
if (isSqlServer() || isMariaDB() || isMySql() || isHana()) {
runScript("I__create_procs.sql");
}
runScript("1.0__initial.sql");
if (isOracle() || isHana()) {
if (isClickHouse()) {
// ClickHouse does not support transactions, so we cannot do update statements
// Add column is also not implemented. So exit here
return;
} else if (isOracle() || isHana()) {
SqlUpdate update = server().sqlUpdate("insert into migtest_e_basic (id, old_boolean, user_id) values (1, :false, 1)");
update.setParameter("false", false);
assertThat(server().execute(update)).isEqualTo(1);
@@ -110,6 +115,15 @@ public class DbMigrationTest extends BaseTestCase {
}
createHistoryEntities();
if (isOracle()) {
// Oracle does not like to convert varchar to integer
// ORA-01439. "column to be modified must be empty to change datatype".
// If the current table is not empty, you may have to create a temp-table
// with correct data types or do it with DBMS_REDEFINITION - to get the test
// working, we clear all data in the table
server().sqlUpdate("delete from migtest_e_history").execute();
server().sqlUpdate("delete from migtest_e_history4").execute();
}
// Run migration
runScript("1.1.sql");
@@ -136,6 +150,11 @@ public class DbMigrationTest extends BaseTestCase {
assertThat(row.getBoolean("new_boolean_field2")).isTrue();
//assertThat(row.getTimestamp("some_date")).isCloseTo(new Date(), 60_000); // allow 1 minute delta
testVersioning();
if (isSqLite()) {
// SqLite does not support drops on columns with foreign keys, so we end with the test here.
return;
}
runScript("1.2__dropsFor_1.1.sql");
// Oracle caches the statement and does not detect schema change. It fails with
@@ -145,16 +164,98 @@ public class DbMigrationTest extends BaseTestCase {
row = result.get(0);
assertThat(row.keySet()).doesNotContain("old_boolean", "old_boolean2");
if (isYugabyte()) {
// there are some unsupported alter commands in 1.3 - so we exit here
return;
}
runScript("1.3.sql");
runScript("1.4__dropsFor_1.3.sql");
// now DB structure shoud be the same as v1_0 - perform a diffent query.
// now DB structure should be the same as v1_0 - perform a diffent query.
result = server().sqlQuery("select * from migtest_e_basic order by id,name").findList();
assertThat(result).hasSize(2);
row = result.get(0);
assertThat(row.keySet()).contains("old_boolean", "old_boolean2");
}
// do some history tests with V1.1 models
private void testVersioning() {
if (isOracle()) {
System.err.println("FIXME: Oracle history support seems to be broken");
return;
}
DbHistorySupport history = server().pluginApi().databasePlatform().getHistorySupport();
if (history == null) {
return;
}
DatabaseConfig config = new DatabaseConfig();
config.setName(server().name());
config.loadFromProperties(server().pluginApi().config().getProperties());
config.setDataSource(server().dataSource());
config.setReadOnlyDataSource(server().dataSource());
config.setDdlGenerate(false);
config.setDdlRun(false);
config.setRegister(false);
config.setPackages(Arrays.asList("misc.migration.v1_1"));
Database tmpServer = DatabaseFactory.create(config);
try {
EHistory hist = new misc.migration.v1_1.EHistory();
hist.setId(2);
hist.setTestString(42L);
tmpServer.save(hist);
hist = tmpServer.find(EHistory.class).where().eq("testString", 42L).findOne();
hist.setTestString(45L);
tmpServer.save(hist);
List<Version<EHistory>> versions = tmpServer.find(EHistory.class).setId(hist.getId())
.findVersionsBetween(Timestamp.valueOf("1970-01-01 00:00:00"), Timestamp.valueOf("2100-01-01 00:00:00"));
assertThat(versions).hasSize(2);
assertThat(versions.get(0).getDiff().toString()).isEqualTo("{testString=45,42}");
EHistory2 hist2 = new misc.migration.v1_1.EHistory2();
hist2.setId(2);
hist2.setTestString("foo1");
hist2.setTestString2("bar1");
hist2.setTestString3("baz1");
tmpServer.save(hist2);
hist2.setTestString("foo2");
hist2.setTestString2("bar2");
tmpServer.save(hist2);
List<Version<EHistory2>> versions2 = tmpServer.find(EHistory2.class).setId(hist.getId())
.findVersionsBetween(Timestamp.valueOf("1970-01-01 00:00:00"), Timestamp.valueOf("2100-01-01 00:00:00"));
assertThat(versions2).hasSize(2);
// not all platforms will support history exclusions
switch (server().platform()) {
case H2: // Trigger ignores HistoryExclude
case SQLSERVER17: // these DBs are 'standard based' so they also do not support HistoryExclude
case MARIADB:
case HANA:
assertThat(versions2.get(0).getDiff().toString())
.contains("testString=foo2,foo1")
.contains("testString2=bar2,bar1");
break;
case MYSQL:
case POSTGRES:
case YUGABYTE:
assertThat(versions2.get(0).getDiff().toString())
.contains("testString=foo2,foo1")
.contains("testString2=bar2,null");
break;
default:
throw new IllegalArgumentException(server().platform() + " not expected");
}
} finally {
tmpServer.shutdown(false, false);
}
}
/**
*
*/