Skip to content

Commit

Permalink
GH-237 - Add validateOnMigrate to skip validation of
Browse files Browse the repository at this point in the history
migration-checksums.

This closes #237.
  • Loading branch information
michael-simons committed Jul 27, 2021
1 parent ccaf581 commit c156245
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,13 @@ public static void main(String... args) {
)
private boolean verbose;

@Option(
names = { "--validate-on-migrate" },
description = "Validating helps you verify that the migrations applied to the database match the ones available locally and is on by default.",
defaultValue = Defaults.VALIDATE_ON_MIGRATE_VALUE
)
private boolean validateOnMigrate;

@Spec
private CommandSpec commandSpec;

Expand All @@ -148,6 +155,7 @@ MigrationsConfig getConfig() {
.withPackagesToScan(packagesToScan)
.withTransactionMode(transactionMode)
.withDatabase(database)
.withValidateOnMigrate(validateOnMigrate)
.build();

if (!config.hasPlacesToLookForMigrations()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ private Map<MigrationVersion, Element> buildChain0(MigrationContext context, Lis
"Unexpected migration at index " + i + ": " + Migrations.toString(newMigration));
}

if (!expectedChecksum.equals(newMigration.getChecksum())) {
if (context.getConfig().isValidateOnMigrate() && !expectedChecksum.equals(newMigration.getChecksum())) {
throw new MigrationsException(("Checksum of " + Migrations.toString(newMigration) + " changed!"));
}
// This is not a pending migration anymore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ public final class Defaults {
*/
public static final TransactionMode TRANSACTION_MODE = TransactionMode.PER_MIGRATION;

/**
* Default setting for {@code validateOnMigrate}.
*/
public static final boolean VALIDATE_ON_MIGRATE = true;

public static final String VALIDATE_ON_MIGRATE_VALUE = "true";

private Defaults() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ public static MigrationsConfig defaultConfig() {

private final String installedBy;

private final boolean validateOnMigrate;

private MigrationsConfig(Builder builder) {

this.packagesToScan = builder.packagesToScan == null ? Defaults.PACKAGES_TO_SCAN : builder.packagesToScan;
Expand All @@ -83,6 +85,7 @@ private MigrationsConfig(Builder builder) {
this.transactionMode = Optional.ofNullable(builder.transactionMode).orElse(TransactionMode.PER_MIGRATION);
this.database = builder.database;
this.installedBy = Optional.ofNullable(builder.installedBy).orElse(System.getProperty("user.name"));
this.validateOnMigrate = builder.validateOnMigrate;
}

public String[] getPackagesToScan() {
Expand All @@ -109,6 +112,10 @@ public String getInstalledBy() {
return installedBy;
}

public boolean isValidateOnMigrate() {
return validateOnMigrate;
}

/**
* A builder to create new instances of {@link MigrationsConfig configurations}.
*/
Expand All @@ -124,6 +131,8 @@ public static class Builder {

private String installedBy;

private boolean validateOnMigrate = Defaults.VALIDATE_ON_MIGRATE;

/**
* Configures the list of packages to scan. Default is an empty list.
*
Expand Down Expand Up @@ -188,6 +197,21 @@ public Builder withInstalledBy(String newInstalledBy) {
return this;
}

/**
* Validating helps you verify that the migrations applied to the database match the ones available locally and
* is on by default. It can be turned off by using a configuration with {@link MigrationsConfig#isValidateOnMigrate()}
* to {@literal false}.
*
* @param newValidateOnMigrate The new value for {@code validateOnMigrate}.
* @return The builder for further customization
* @since 0.1.5
*/
public Builder withValidateOnMigrate(boolean newValidateOnMigrate) {

this.validateOnMigrate = newValidateOnMigrate;
return this;
}

/**
* @return The immutable configuration
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,16 @@ void shouldConfigureDefaultClasspathPackage() {

assertThat(MigrationsConfig.builder().build().getLocationsToScan()).isEqualTo(Defaults.LOCATIONS_TO_SCAN);
}

@Test // GH-237
void validateOnInstallShouldBeTrueByDefault() {

assertThat(MigrationsConfig.builder().build().isValidateOnMigrate()).isTrue();
}

@Test // GH-237
void validateOnInstallShouldBeChangeable() {

assertThat(MigrationsConfig.builder().withValidateOnMigrate(false).build().isValidateOnMigrate()).isFalse();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,42 @@ void shouldFailWithChangedMigrations() throws IOException {
}
}

@Test // GH-237
void changedMigrationsShouldBeAllowedWhenValidateIsOff() throws IOException {

File dir = Files.createTempDirectory("neo4j-migrations").toFile();
List<File> files = createMigrationFiles(2, dir);

try {
String location = "file:" + dir.getAbsolutePath();
MigrationsConfig configuration = MigrationsConfig.builder().withLocationsToScan(location).withValidateOnMigrate(false).build();
Migrations migrations = new Migrations(configuration, driver);
migrations.apply();

assertThat(lengthOfMigrations(driver, null)).isEqualTo(2);

Files.write(files.get(1).toPath(), Arrays.asList("MATCH (n) RETURN n;", "CREATE (m:SomeNode) RETURN m;"));

File newMigration = new File(dir, "V3__SomethingNew.cypher");
files.add(newMigration);
Files.write(newMigration.toPath(), Arrays.asList("CREATE INDEX node_index_name FOR (n:Person) ON (n.surname)"));

migrations = new Migrations(configuration, driver);
migrations.apply();

try (Session session = driver.session()) {
String version = session.run(
"MATCH (:__Neo4jMigration {version: '2'}) -[r:MIGRATED_TO]->(t) RETURN t.version AS version")
.single().get("version").asString();
assertThat(version).isEqualTo("3");
}
} finally {
for (File file : files) {
file.delete();
}
}
}

@Test
void shouldVerifyChecksums() throws IOException {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ abstract class TestBase {

@BeforeAll
void initDriver() {

Config config = Config.builder().withLogging(Logging.none()).build();

neo4j.start();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ MigrationsConfig neo4jMigrationsConfig(ResourceLoader resourceLoader, Migrations
.withTransactionMode(migrationsProperties.getTransactionMode())
.withDatabase(migrationsProperties.getDatabase())
.withInstalledBy(migrationsProperties.getInstalledBy())
.withValidateOnMigrate(migrationsProperties.isValidateOnMigrate())
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ public class MigrationsProperties {
*/
private String installedBy;

/**
* Validating helps you verify that the migrations applied to the database match the ones available locally and is on by default.
*/
private boolean validateOnMigrate = Defaults.VALIDATE_ON_MIGRATE;

public boolean isEnabled() {
return enabled;
}
Expand Down Expand Up @@ -134,4 +139,12 @@ public String getDatabase() {
public void setDatabase(String database) {
this.database = database;
}

public boolean isValidateOnMigrate() {
return validateOnMigrate;
}

public void setValidateOnMigrate(boolean validateOnMigrate) {
this.validateOnMigrate = validateOnMigrate;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatNoException;

import ac.simons.neo4j.migrations.core.Migrations;
import ac.simons.neo4j.migrations.core.MigrationsConfig;
Expand Down Expand Up @@ -151,20 +152,40 @@ void shouldBeHappyWithAtLeastOneLocation() {
Mockito.when(resource.exists()).thenReturn(true);

MigrationsAutoConfiguration ac = new MigrationsAutoConfiguration();
ac.neo4jMigrationsConfig(resourceLoader, properties);
assertThatNoException().isThrownBy(() -> ac.neo4jMigrationsConfig(resourceLoader, properties));
}

@Test
void shouldBeHappyWithAtLeastOnePackage() {

MigrationsProperties properties = new MigrationsProperties();
properties.setPackagesToScan(new String[] { "na" });
properties.setLocationsToScan(new String[0]);

assertThat(properties.isCheckLocation()).isTrue();

MigrationsAutoConfiguration ac = new MigrationsAutoConfiguration();
ac.neo4jMigrationsConfig(resourceLoader, properties);
assertThatNoException().isThrownBy(() -> ac.neo4jMigrationsConfig(resourceLoader, properties));
}

@Test // GH-237
void validateOnMigrationShouldBeTrueByDefault() {

MigrationsProperties properties = new MigrationsProperties();
properties.setPackagesToScan(new String[] { "na" });

MigrationsConfig config = new MigrationsAutoConfiguration().neo4jMigrationsConfig(resourceLoader, properties);
assertThat(config.isValidateOnMigrate()).isTrue();
}

@Test // GH-237
void shouldApplyValidateOnMigration() {

MigrationsProperties properties = new MigrationsProperties();
properties.setPackagesToScan(new String[] { "na" });
properties.setValidateOnMigrate(false);

MigrationsConfig config = new MigrationsAutoConfiguration().neo4jMigrationsConfig(resourceLoader, properties);
assertThat(config.isValidateOnMigrate()).isFalse();
}
}

Expand Down

0 comments on commit c156245

Please sign in to comment.