package io.dropwizard.migrations;
import com.google.common.collect.ImmutableMap;
import net.jcip.annotations.NotThreadSafe;
import net.sourceforge.argparse4j.inf.Namespace;
import org.junit.Before;
import org.junit.Test;
import org.skife.jdbi.v2.DBI;
import org.skife.jdbi.v2.Handle;
import java.io.ByteArrayOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.regex.Pattern;
import static org.assertj.core.api.Assertions.assertThat;
@NotThreadSafe
public class DbFastForwardCommandTest extends AbstractMigrationTest {
private static final Pattern NEWLINE_PATTERN = Pattern.compile(System.lineSeparator());
private DbFastForwardCommand<TestMigrationConfiguration> fastForwardCommand = new DbFastForwardCommand<>(
TestMigrationConfiguration::getDataSource, TestMigrationConfiguration.class, "migrations.xml");
private TestMigrationConfiguration conf;
private DBI dbi;
@Before
public void setUp() throws Exception {
final String databaseUrl = getDatabaseUrl();
conf = createConfiguration(databaseUrl);
dbi = new DBI(databaseUrl, "sa", "");
}
@Test
public void testFastForwardFirst() throws Exception {
// Create the "persons" table manually
try (Handle handle = dbi.open()) {
handle.execute("create table persons(id int, name varchar(255))");
}
// Fast-forward one change
fastForwardCommand.run(null, new Namespace(ImmutableMap.of("all", false, "dry-run", false)), conf);
// 2nd and 3rd migrations is performed
new DbMigrateCommand<>(
TestMigrationConfiguration::getDataSource, TestMigrationConfiguration.class, "migrations.xml")
.run(null, new Namespace(ImmutableMap.of()), conf);
// 1 entry has been added to the persons table
try (Handle handle = dbi.open()) {
assertThat(handle.createQuery("select count(*) from persons")
.mapTo(Integer.class)
.first())
.isEqualTo(1);
}
}
@Test
public void testFastForwardAll() throws Exception {
// Create the "persons" table manually and add some data
try (Handle handle = dbi.open()) {
handle.execute("create table persons(id int, name varchar(255))");
handle.execute("insert into persons (id, name) values (12, 'Greg Young')");
}
// Fast-forward all the changes
fastForwardCommand.run(null, new Namespace(ImmutableMap.of("all", true, "dry-run", false)), conf);
// No migrations is performed
new DbMigrateCommand<>(
TestMigrationConfiguration::getDataSource, TestMigrationConfiguration.class, "migrations.xml")
.run(null, new Namespace(ImmutableMap.of()), conf);
// Nothing is added to the persons table
try (Handle handle = dbi.open()) {
assertThat(handle.createQuery("select count(*) from persons")
.mapTo(Integer.class)
.first())
.isEqualTo(1);
}
}
@Test
public void testFastForwardFirstDryRun() throws Exception {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
fastForwardCommand.setPrintStream(new PrintStream(baos));
// Fast-forward one change
fastForwardCommand.run(null, new Namespace(ImmutableMap.of("all", false, "dry-run", true)), conf);
assertThat(NEWLINE_PATTERN.splitAsStream(baos.toString(UTF_8))
.filter(s -> s.startsWith("INSERT INTO PUBLIC.DATABASECHANGELOG (")))
.hasSize(1);
}
@Test
public void testFastForwardAllDryRun() throws Exception {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
fastForwardCommand.setPrintStream(new PrintStream(baos));
// Fast-forward 3 changes
fastForwardCommand.run(null, new Namespace(ImmutableMap.of("all", true, "dry-run", true)), conf);
assertThat(NEWLINE_PATTERN.splitAsStream(baos.toString(UTF_8))
.filter(s -> s.startsWith("INSERT INTO PUBLIC.DATABASECHANGELOG (")))
.hasSize(3);
}
@Test
public void testPrintHelp() throws Exception {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
createSubparser(fastForwardCommand).printHelp(new PrintWriter(new OutputStreamWriter(baos, UTF_8), true));
assertThat(baos.toString(UTF_8)).isEqualTo(String.format(
"usage: db fast-forward [-h] [--migrations MIGRATIONS-FILE]%n" +
" [--catalog CATALOG] [--schema SCHEMA] [-n] [-a] [-i CONTEXTS]%n" +
" [file]%n" +
"%n" +
"Mark the next pending change set as applied without running it%n" +
"%n" +
"positional arguments:%n" +
" file application configuration file%n" +
"%n" +
"optional arguments:%n" +
" -h, --help show this help message and exit%n" +
" --migrations MIGRATIONS-FILE%n" +
" the file containing the Liquibase migrations for%n" +
" the application%n" +
" --catalog CATALOG Specify the database catalog (use database%n" +
" default if omitted)%n" +
" --schema SCHEMA Specify the database schema (use database default%n" +
" if omitted)%n" +
" -n, --dry-run output the DDL to stdout, don't run it%n" +
" -a, --all mark all pending change sets as applied%n" +
" -i CONTEXTS, --include CONTEXTS%n" +
" include change sets from the given context%n"));
}
}