diff --git a/modules/database-commons/src/main/java/org/testcontainers/ext/ScriptUtils.java b/modules/database-commons/src/main/java/org/testcontainers/ext/ScriptUtils.java index d30064af28e..1567bb62525 100644 --- a/modules/database-commons/src/main/java/org/testcontainers/ext/ScriptUtils.java +++ b/modules/database-commons/src/main/java/org/testcontainers/ext/ScriptUtils.java @@ -16,18 +16,19 @@ package org.testcontainers.ext; +import java.io.IOException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.LinkedList; +import java.util.List; +import javax.script.ScriptException; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testcontainers.delegate.DatabaseDelegate; -import javax.script.ScriptException; -import java.io.IOException; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.LinkedList; -import java.util.List; +import static org.apache.commons.lang.ArrayUtils.isEmpty; /** * This is a modified version of the Spring-JDBC ScriptUtils class, adapted to reduce @@ -285,27 +286,47 @@ public static boolean containsSqlScriptDelimiters(String script, String delim) { return false; } + /** + * Load script from classpath and apply it to the given database + * + * @param databaseDelegate database delegate for script execution + * @param initScriptPath the resource to load the init script from + */ + public static void runInitScript(DatabaseDelegate databaseDelegate, String initScriptPath) { + runMultiInitScript(databaseDelegate, initScriptPath); + } + /** - * Load script from classpath and apply it to the given database + * Loads multiple scripts from classpath and applies it to the given database * * @param databaseDelegate database delegate for script execution - * @param initScriptPath the resource to load the init script from + * @param initScriptPaths the resources to load the init scripts from */ - public static void runInitScript(DatabaseDelegate databaseDelegate, String initScriptPath) { + public static void runMultiInitScript(DatabaseDelegate databaseDelegate, String... initScriptPaths) { + if (isEmpty(initScriptPaths)) { + LOGGER.warn("No initScriptPath provided. Skipping..."); + return; + } + + String initScriptPathCursor = ""; try { - URL resource = ScriptUtils.class.getClassLoader().getResource(initScriptPath); - if (resource == null) { - LOGGER.warn("Could not load classpath init script: {}", initScriptPath); - throw new ScriptLoadException("Could not load classpath init script: " + initScriptPath + ". Resource not found."); - } - String scripts = IOUtils.toString(resource, StandardCharsets.UTF_8); - executeDatabaseScript(databaseDelegate, initScriptPath, scripts); + ClassLoader loader = ScriptUtils.class.getClassLoader(); + for (String path : initScriptPaths) { + initScriptPathCursor = path; + URL resource = loader.getResource(path); + if (resource == null) { + LOGGER.warn("Could not load classpath init script: {}", path); + throw new ScriptLoadException("Could not load classpath init script: " + path + ". Resource not found."); + } + String scripts = IOUtils.toString(resource, StandardCharsets.UTF_8); + executeDatabaseScript(databaseDelegate, path, scripts); + } } catch (IOException e) { - LOGGER.warn("Could not load classpath init script: {}", initScriptPath); - throw new ScriptLoadException("Could not load classpath init script: " + initScriptPath, e); + LOGGER.warn("Could not load classpath init script: {}", initScriptPathCursor); + throw new ScriptLoadException("Could not load classpath init script: " + initScriptPathCursor, e); } catch (ScriptException e) { - LOGGER.error("Error while executing init script: {}", initScriptPath, e); - throw new UncategorizedScriptException("Error while executing init script: " + initScriptPath, e); + LOGGER.error("Error while executing init script: {}", initScriptPathCursor, e); + throw new UncategorizedScriptException("Error while executing init script: " + initScriptPathCursor, e); } } diff --git a/modules/jdbc-test/src/test/java/org/testcontainers/junit/SimplePostgreSQLTest.java b/modules/jdbc-test/src/test/java/org/testcontainers/junit/SimplePostgreSQLTest.java index 7189e05fb16..13e02a8bf2a 100644 --- a/modules/jdbc-test/src/test/java/org/testcontainers/junit/SimplePostgreSQLTest.java +++ b/modules/jdbc-test/src/test/java/org/testcontainers/junit/SimplePostgreSQLTest.java @@ -1,15 +1,14 @@ package org.testcontainers.junit; -import org.junit.Test; -import org.testcontainers.containers.PostgreSQLContainer; +import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; +import static org.rnorth.visibleassertions.VisibleAssertions.assertNotEquals; import java.sql.ResultSet; import java.sql.SQLException; import java.util.logging.Level; import java.util.logging.LogManager; - -import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; -import static org.rnorth.visibleassertions.VisibleAssertions.assertNotEquals; +import org.junit.Test; +import org.testcontainers.containers.PostgreSQLContainer; public class SimplePostgreSQLTest extends AbstractContainerDatabaseTest { @@ -62,4 +61,19 @@ public void testExplicitInitScript() throws SQLException { assertEquals("Value from init script should equal real value", "hello world", firstColumnValue); } } + @Test + public void testMultipleExplicitInitScript() throws SQLException { + try (PostgreSQLContainer postgres = new PostgreSQLContainer<>().withMultiInitScript("somepath/init_postgresql.sql", "somepath/init_postgresql_2.sql")) { + postgres.start(); + + ResultSet resultSet = performQuery(postgres, "SELECT foo AS value FROM bar UNION SELECT bar AS value FROM foo"); + + String columnValue1 = resultSet.getString(1); + resultSet.next(); + String columnValue2 = resultSet.getString(1); + assertEquals("Values from init scripts should equal real values", "hello world", columnValue1); + assertEquals("Value to init script 2 shoudl equal real value", "hello world 2", columnValue2); + } + } + } diff --git a/modules/jdbc-test/src/test/resources/somepath/init_postgresql_2.sql b/modules/jdbc-test/src/test/resources/somepath/init_postgresql_2.sql new file mode 100644 index 00000000000..c7141478056 --- /dev/null +++ b/modules/jdbc-test/src/test/resources/somepath/init_postgresql_2.sql @@ -0,0 +1,5 @@ +CREATE TABLE foo ( + bar VARCHAR(255) +); + +INSERT INTO foo (bar) VALUES ('hello world 2'); diff --git a/modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainer.java b/modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainer.java index 36a6461aa74..c9a87d790ec 100644 --- a/modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainer.java +++ b/modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainer.java @@ -26,7 +26,7 @@ public abstract class JdbcDatabaseContainer parameters = new HashMap<>(); private int startupTimeoutSeconds = 120; @@ -108,7 +108,11 @@ public SELF withConnectTimeoutSeconds(int connectTimeoutSeconds) { } public SELF withInitScript(String initScriptPath) { - this.initScriptPath = initScriptPath; + return withMultiInitScript(initScriptPath); + } + + public SELF withMultiInitScript(String... initScriptPaths) { + this.initScriptPaths = initScriptPaths; return self(); } @@ -236,8 +240,8 @@ protected void optionallyMapResourceParameterAsVolume(@NotNull String paramName, * Load init script content and apply it to the database if initScriptPath is set */ protected void runInitScriptIfRequired() { - if (initScriptPath != null) { - ScriptUtils.runInitScript(getDatabaseDelegate(), initScriptPath); + if (initScriptPaths != null) { + ScriptUtils.runMultiInitScript(getDatabaseDelegate(), initScriptPaths); } }