001/*
002 * Licensed under the Apache License, Version 2.0 (the "License");
003 * you may not use this file except in compliance with the License.
004 * You may obtain a copy of the License at
005 *
006 * http://www.apache.org/licenses/LICENSE-2.0
007 *
008 * Unless required by applicable law or agreed to in writing, software
009 * distributed under the License is distributed on an "AS IS" BASIS,
010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011 * See the License for the specific language governing permissions and
012 * limitations under the License.
013 */
014package de.softwareforge.testing.postgres.embedded;
015
016import static org.junit.jupiter.api.Assertions.assertEquals;
017import static org.junit.jupiter.api.Assertions.assertNotEquals;
018import static org.junit.jupiter.api.Assertions.assertThrows;
019import static org.junit.jupiter.api.Assertions.assertTrue;
020
021import java.io.IOException;
022import java.sql.Connection;
023import java.sql.ResultSet;
024import java.sql.SQLException;
025import java.sql.Statement;
026
027import de.softwareforge.testing.postgres.junit5.RequirePostgresVersion;
028import org.flywaydb.core.api.FlywayException;
029import org.junit.jupiter.api.Test;
030
031@RequirePostgresVersion(atLeast = "10")
032public class FlywayPreparerTest {
033
034    @Test
035    public void testWorking() throws Exception {
036        try (DatabaseManager manager = DatabaseManager.multiDatabases()
037                .withInstancePreparer(EmbeddedPostgres.Builder::withDefaults)
038                .withDatabasePreparer(FlywayPreparer.forClasspathLocation("db/testing"))
039                .build()
040                .start()) {
041
042            DatabaseInfo firstDatabaseInfo = manager.getDatabaseInfo();
043            DatabaseInfo secondDatabaseInfo = manager.getDatabaseInfo();
044
045            // different databases
046            assertNotEquals(firstDatabaseInfo, secondDatabaseInfo);
047
048            // both database contain the data
049            assertEquals("bar", fetchData(firstDatabaseInfo));
050            assertEquals("bar", fetchData(secondDatabaseInfo));
051        }
052    }
053
054    @Test
055    public void testMissing() throws Exception {
056        try (DatabaseManager manager = DatabaseManager.singleDatabase()
057                .withInstancePreparer(EmbeddedPostgres.Builder::withDefaults)
058                .withDatabasePreparer(FlywayPreparer
059                        .forClasspathLocation("db/non-existing")
060                        .addCustomizer(c -> c.failOnMissingLocations(true)))
061                .build()
062                ) {
063
064            IOException e = assertThrows(IOException.class, manager::start);
065
066            assertTrue(e.getCause() instanceof FlywayException);
067            assertTrue(e.getMessage().contains("Unable to resolve location classpath:db/non-existing"));
068        }
069    }
070
071
072    @Test
073    public void testBroken() throws Exception {
074        try (DatabaseManager manager = DatabaseManager.singleDatabase()
075                .withInstancePreparer(EmbeddedPostgres.Builder::withDefaults)
076                .withDatabasePreparer(FlywayPreparer
077                        .forClasspathLocation("db/broken")
078                        .addCustomizer(c -> c.failOnMissingLocations(true)))
079                .build()
080        ) {
081
082            IOException e = assertThrows(IOException.class, manager::start);
083
084            assertTrue(e.getCause() instanceof FlywayException);
085            // 42P01 - relation does not exist
086            assertTrue(e.getMessage().contains("42P01"));
087        }
088    }
089
090
091    private static String fetchData(DatabaseInfo databaseInfo) throws SQLException {
092        try (Connection c = databaseInfo.asDataSource().getConnection();
093                Statement s = c.createStatement()) {
094            try (ResultSet rs = s.executeQuery("SELECT * FROM foo")) {
095                if (!rs.next()) {
096                    return null;
097                }
098                return rs.getString(1);
099            }
100        }
101    }
102}