schema migrator validation skips skippable tasks (#6050)

This commit is contained in:
TipzCM 2024-06-27 13:16:47 -04:00 committed by GitHub
parent 39396b136f
commit 315a05eeb8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 75 additions and 4 deletions

View File

@ -0,0 +1,6 @@
---
type: fix
issue: 6049
title: "Rolled back org.apache.derby dependency to one that
supports JREs 11 - 17.
"

View File

@ -0,0 +1,6 @@
---
type: fix
issue: 6049
title: "Fixed a bug in SchemaMigrator that would considered
skippable migration tasks as 'failed' migrations.
"

View File

@ -152,7 +152,6 @@
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
</plugins> </plugins>
</build> </build>

View File

@ -63,6 +63,12 @@ public class MigrationTaskList implements Iterable<BaseTask> {
return new MigrationTaskList(unappliedTasks); return new MigrationTaskList(unappliedTasks);
} }
public MigrationTaskList getUnskippableTasks() {
List<BaseTask> tasks =
myTasks.stream().filter(t -> !t.isHeavyweightSkippableTask()).collect(Collectors.toList());
return new MigrationTaskList(tasks);
}
public void append(Iterable<BaseTask> theMigrationTasks) { public void append(Iterable<BaseTask> theMigrationTasks) {
for (BaseTask next : theMigrationTasks) { for (BaseTask next : theMigrationTasks) {
myTasks.add(next); myTasks.add(next);

View File

@ -72,8 +72,10 @@ public class SchemaMigrator {
try (Connection connection = myDataSource.getConnection()) { try (Connection connection = myDataSource.getConnection()) {
MigrationTaskList unappliedMigrations = myHapiMigrationStorageSvc.diff(myMigrationTasks); MigrationTaskList unappliedMigrations = myHapiMigrationStorageSvc.diff(myMigrationTasks);
if (unappliedMigrations.size() > 0) { // remove skippable tasks
MigrationTaskList unappliedUnskippable = unappliedMigrations.getUnskippableTasks();
if (unappliedUnskippable.size() > 0) {
String url = connection.getMetaData().getURL(); String url = connection.getMetaData().getURL();
throw new ConfigurationException(Msg.code(27) + "The database schema for " + url + " is out of date. " throw new ConfigurationException(Msg.code(27) + "The database schema for " + url + " is out of date. "
+ "Current database schema version is " + "Current database schema version is "

View File

@ -6,12 +6,16 @@ import ca.uhn.fhir.jpa.migrate.entity.HapiMigrationEntity;
import ca.uhn.fhir.jpa.migrate.taskdef.AddTableRawSqlTask; import ca.uhn.fhir.jpa.migrate.taskdef.AddTableRawSqlTask;
import ca.uhn.fhir.jpa.migrate.taskdef.BaseTask; import ca.uhn.fhir.jpa.migrate.taskdef.BaseTask;
import ca.uhn.fhir.jpa.migrate.taskdef.BaseTest; import ca.uhn.fhir.jpa.migrate.taskdef.BaseTest;
import ca.uhn.fhir.jpa.migrate.tasks.api.TaskFlagEnum;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import jakarta.annotation.Nonnull; import jakarta.annotation.Nonnull;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.MethodSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
@ -19,13 +23,61 @@ import java.util.Set;
import java.util.function.Supplier; import java.util.function.Supplier;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class SchemaMigratorTest extends BaseTest { public class SchemaMigratorTest extends BaseTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SchemaMigratorTest.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SchemaMigratorTest.class);
@Test
public void validate_withSkippableTasks_returnsSuccessful() throws SQLException {
// setup
Connection connection = mock(Connection.class);
DataSource dataSource = mock(DataSource.class);
DriverTypeEnum driverTypeEnum = DriverTypeEnum.POSTGRES_9_4; // does not matter
HapiMigrationStorageSvc migrationStorageSvc = mock(HapiMigrationStorageSvc.class);
// create some tasks
AddTableRawSqlTask taskA = new AddTableRawSqlTask("V4_1_0", "20191214.1");
taskA.setTableName("SOMETABLE_A");
taskA.addSql(driverTypeEnum, "create table SOMETABLE_A (PID bigint not null, TEXTCOL varchar(255))");
AddTableRawSqlTask taskB = new AddTableRawSqlTask("V4_1_0", "20191214.2");
taskB.setTableName("SOMETABLE_B");
taskB.addSql(driverTypeEnum, "create table SOMETABLE_B (PID bigint not null, TEXTCOL varchar(255))");
AddTableRawSqlTask taskC = new AddTableRawSqlTask("V4_1_0", "20191214.3");
taskC.setTableName("SOMETABLE_C");
taskC.addSql(driverTypeEnum, "create table SOMETABLE_C (PID bigint not null, TEXTCOL varchar(255))");
AddTableRawSqlTask taskD = new AddTableRawSqlTask("V4_1_0", "20191214.4");
taskD.setTableName("SOMETABLE_D");
taskD.addSql(driverTypeEnum, "create table SOMETABLE_D (PID bigint not null, TEXTCOL varchar(255))");
List<BaseTask> tasks = ImmutableList.of(taskA, taskB, taskC, taskD);
for (BaseTask t : tasks) {
t.addFlag(TaskFlagEnum.HEAVYWEIGHT_SKIP_BY_DEFAULT);
}
MigrationTaskList taskList = new MigrationTaskList(tasks);
// when
when(migrationStorageSvc.diff(any(MigrationTaskList.class)))
.thenReturn(taskList);
when(dataSource.getConnection())
.thenReturn(connection);
// create a migrator (with empty task list)
SchemaMigrator schemaMigrator = new SchemaMigrator(getUrl(), SchemaMigrator.HAPI_FHIR_MIGRATION_TABLENAME, dataSource, new Properties(), new MigrationTaskList(), migrationStorageSvc);
schemaMigrator.setDriverType(driverTypeEnum);
// test
assertDoesNotThrow(schemaMigrator::validate);
}
@ParameterizedTest(name = "{index}: {0}") @ParameterizedTest(name = "{index}: {0}")
@MethodSource("data") @MethodSource("data")
@ -47,7 +99,6 @@ public class SchemaMigratorTest extends BaseTest {
schemaMigrator.validate(); schemaMigrator.validate();
} }
@ParameterizedTest(name = "{index}: {0}") @ParameterizedTest(name = "{index}: {0}")
@MethodSource("data") @MethodSource("data")
public void testRepairFailedMigration(Supplier<TestDatabaseDetails> theTestDatabaseDetails) { public void testRepairFailedMigration(Supplier<TestDatabaseDetails> theTestDatabaseDetails) {

View File

@ -969,7 +969,8 @@
<commons_io_version>2.11.0</commons_io_version> <commons_io_version>2.11.0</commons_io_version>
<commons_lang3_version>3.14.0</commons_lang3_version> <commons_lang3_version>3.14.0</commons_lang3_version>
<com_jamesmurty_utils_version>1.2</com_jamesmurty_utils_version> <com_jamesmurty_utils_version>1.2</com_jamesmurty_utils_version>
<derby_version>10.17.1.0</derby_version> <!-- Note: Derby is held to 10.15.x deliberately, as the 10.17+ version requires Java 21 to build -->
<derby_version>10.15.2.0</derby_version>
<error_prone_core_version>2.23.0</error_prone_core_version> <error_prone_core_version>2.23.0</error_prone_core_version>
<mockito_version>5.8.0</mockito_version> <mockito_version>5.8.0</mockito_version>
<nullaway_version>0.7.9</nullaway_version> <nullaway_version>0.7.9</nullaway_version>