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 */
014
015package de.softwareforge.testing.postgres.embedded;
016
017import static org.junit.jupiter.api.Assertions.assertEquals;
018import static org.junit.jupiter.api.Assertions.assertNotEquals;
019import static org.junit.jupiter.api.Assertions.assertThrows;
020import static org.junit.jupiter.api.Assertions.assertTrue;
021
022import de.softwareforge.testing.postgres.junit5.RequirePostgresVersion;
023
024import java.io.IOException;
025import java.sql.Connection;
026import java.sql.ResultSet;
027import java.sql.SQLException;
028import java.sql.Statement;
029
030import org.flywaydb.core.api.FlywayException;
031import org.junit.jupiter.api.Test;
032
033@RequirePostgresVersion(atLeast = "10")
034public class FlywayPreparerTest {
035
036    @Test
037    public void testWorking() throws Exception {
038        try (DatabaseManager manager = DatabaseManager.multiDatabases()
039                .withInstancePreparer(EmbeddedPostgres.Builder::withDefaults)
040                .withDatabasePreparer(FlywayPreparer.forClasspathLocation("db/testing"))
041                .build()
042                .start()) {
043
044            DatabaseInfo firstDatabaseInfo = manager.getDatabaseInfo();
045            DatabaseInfo secondDatabaseInfo = manager.getDatabaseInfo();
046
047            // different databases
048            assertNotEquals(firstDatabaseInfo, secondDatabaseInfo);
049
050            // both database contain the data
051            assertEquals("bar", fetchData(firstDatabaseInfo));
052            assertEquals("bar", fetchData(secondDatabaseInfo));
053        }
054    }
055
056    @Test
057    public void testMissing() throws Exception {
058        try (DatabaseManager manager = DatabaseManager.singleDatabase()
059                .withInstancePreparer(EmbeddedPostgres.Builder::withDefaults)
060                .withDatabasePreparer(FlywayPreparer
061                        .forClasspathLocation("db/non-existing")
062                        .addCustomizer(c -> c.failOnMissingLocations(true)))
063                .build()
064        ) {
065
066            IOException e = assertThrows(IOException.class, manager::start);
067
068            assertTrue(e.getCause() instanceof FlywayException);
069            assertTrue(e.getMessage().contains("Unable to resolve location classpath:db/non-existing"));
070        }
071    }
072
073
074    @Test
075    public void testBroken() throws Exception {
076        try (DatabaseManager manager = DatabaseManager.singleDatabase()
077                .withInstancePreparer(EmbeddedPostgres.Builder::withDefaults)
078                .withDatabasePreparer(FlywayPreparer
079                        .forClasspathLocation("db/broken")
080                        .addCustomizer(c -> c.failOnMissingLocations(true)))
081                .build()
082        ) {
083
084            IOException e = assertThrows(IOException.class, manager::start);
085
086            assertTrue(e.getCause() instanceof FlywayException);
087            // 42P01 - relation does not exist
088            assertTrue(e.getMessage().contains("42P01"));
089        }
090    }
091
092
093    private static String fetchData(DatabaseInfo databaseInfo) throws SQLException {
094        try (Connection c = databaseInfo.asDataSource().getConnection();
095                Statement s = c.createStatement()) {
096            try (ResultSet rs = s.executeQuery("SELECT * FROM foo")) {
097                if (!rs.next()) {
098                    return null;
099                }
100                return rs.getString(1);
101            }
102        }
103    }
104}