mirror of
https://github.com/google/nomulus.git
synced 2025-07-25 20:18:34 +02:00
Enhance the test for forbidden Schema changes (#815)
* Enhance the test for forbidden Schema changes Current test is git-based. It is difficult to maintain and does not catch out-of-order version numbers. It is also more aggressive than necessary, failing on changes to submitted scripts that have not been deployed yet. The new test starts a database, deploys the current schema to it, then deploys the set of Flyway scripts in this repository to the database.
This commit is contained in:
parent
aa217c2fcd
commit
959c7f7899
7 changed files with 115 additions and 22 deletions
|
@ -18,6 +18,7 @@ import static com.google.common.truth.Truth.assertThat;
|
|||
import static google.registry.testing.truth.TextDiffSubject.assertThat;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.google.common.io.Resources;
|
||||
import google.registry.persistence.NomulusPostgreSql;
|
||||
import java.io.File;
|
||||
|
@ -26,16 +27,41 @@ import java.nio.charset.StandardCharsets;
|
|||
import java.nio.file.Paths;
|
||||
import org.flywaydb.core.Flyway;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
|
||||
import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
|
||||
import org.testcontainers.containers.BindMode;
|
||||
import org.testcontainers.containers.Container.ExecResult;
|
||||
import org.testcontainers.containers.PostgreSQLContainer;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
/** Unit tests about Cloud SQL schema. */
|
||||
/**
|
||||
* Schema deployment tests using Flyway.
|
||||
*
|
||||
* <p>This class has two test methods:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link #deploySchema_emptyDb()} is invoked only in UNIT tests (:db:test in Gradle). It
|
||||
* deploys the entire set of Flyway scripts (found on classpath) to an empty database and
|
||||
* compares the resulting schema with the golden schema.
|
||||
* <li>{@link #deploySchema_existingDb()} is invoked only in an integration test
|
||||
* (:db:schemaIncrementalDeployTest in Gradle). It first populates the test database with an
|
||||
* earlier release of the schema (found on the classpath), then deploys the latest Flyway
|
||||
* scripts (found on local filesystem under the resources directory) to that database. This
|
||||
* test detects all forbidden changes to deployed scripts including content change, file
|
||||
* renaming, and file deletion.
|
||||
* <p>This test also checks for out-of-order version numbers, i.e., new scripts with lower
|
||||
* numbers than that of the last deployed script. Out-of-order versions are confusing to
|
||||
* maintainers, however, Flyway does not provide ways to check before schema deployment. In
|
||||
* this test, out-of-order scripts are ignored in the incremental-deployment phase (default
|
||||
* Flyway behavior). The final validate call will fail on them.
|
||||
* </ul>
|
||||
*/
|
||||
@Testcontainers
|
||||
class SchemaTest {
|
||||
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
|
||||
// Resource path that is mapped to the testcontainer instance.
|
||||
private static final String MOUNTED_RESOURCE_PATH = "testcontainer/mount";
|
||||
// The mount point in the container.
|
||||
|
@ -57,7 +83,8 @@ class SchemaTest {
|
|||
MOUNTED_RESOURCE_PATH, CONTAINER_MOUNT_POINT, BindMode.READ_WRITE);
|
||||
|
||||
@Test
|
||||
void deploySchema_success() throws Exception {
|
||||
@DisabledIfSystemProperty(named = "deploy_to_existing_db", matches = ".*")
|
||||
void deploySchema_emptyDb() throws Exception {
|
||||
Flyway flyway =
|
||||
Flyway.configure()
|
||||
.locations("sql/flyway")
|
||||
|
@ -86,6 +113,32 @@ class SchemaTest {
|
|||
.hasSameContentAs(Resources.getResource("sql/schema/nomulus.golden.sql"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledIfSystemProperty(named = "deploy_to_existing_db", matches = ".*")
|
||||
void deploySchema_existingDb() {
|
||||
// Initialize database with the base schema, which is on the classpath.
|
||||
Flyway flyway =
|
||||
Flyway.configure()
|
||||
.locations("sql/flyway")
|
||||
.dataSource(
|
||||
sqlContainer.getJdbcUrl(), sqlContainer.getUsername(), sqlContainer.getPassword())
|
||||
.load();
|
||||
flyway.migrate();
|
||||
logger.atInfo().log("Base schema version: %s", flyway.info().current().getVersion().toString());
|
||||
|
||||
// Deploy latest scripts from resources directory.
|
||||
flyway =
|
||||
Flyway.configure()
|
||||
.locations("filesystem:build/resources/main/sql/flyway")
|
||||
.dataSource(
|
||||
sqlContainer.getJdbcUrl(), sqlContainer.getUsername(), sqlContainer.getPassword())
|
||||
.load();
|
||||
flyway.migrate();
|
||||
flyway.validate();
|
||||
logger.atInfo().log(
|
||||
"Latest schema version: %s", flyway.info().current().getVersion().toString());
|
||||
}
|
||||
|
||||
private static String[] getSchemaDumpCommand(String username, String dbName) {
|
||||
return new String[] {
|
||||
"pg_dump",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue