diff --git a/testing/testcontainers/java/README.rst b/testing/testcontainers/java/README.rst index 208ba9f8..8d3d40ff 100644 --- a/testing/testcontainers/java/README.rst +++ b/testing/testcontainers/java/README.rst @@ -42,6 +42,8 @@ of examples you can explore here: Testcontainer instance honoring the ``CRATEDB_VERSION`` environment variable, suitable for running a test matrix on different versions of CrateDB, shared across multiple test classes. +- ``TestSqlInitialization``: Demonstrate different ways how Testcontainers can run an init script after + the database container is started, but before your code initiates a connection to it. [1]: Sometimes, it might be useful to define a container that is only started once for several test classes. There is no special support for this use case provided by @@ -64,6 +66,9 @@ Usage # Run individual tests. ./gradlew test --tests TestFunctionScope + # Inspect tracebacks on failures. + ./gradlew test --tests TestFunctionScope --info + # Run test case showing how to select CrateDB version per environment variable. export CRATEDB_VERSION=5.2.3 export CRATEDB_VERSION=nightly diff --git a/testing/testcontainers/java/src/main/java/io/crate/example/testing/Application.java b/testing/testcontainers/java/src/main/java/io/crate/example/testing/Application.java index 89a877de..48593766 100644 --- a/testing/testcontainers/java/src/main/java/io/crate/example/testing/Application.java +++ b/testing/testcontainers/java/src/main/java/io/crate/example/testing/Application.java @@ -74,6 +74,10 @@ public Results querySummitsTable() throws IOException, SQLException { return this.query("SELECT * FROM sys.summits ORDER BY height DESC LIMIT 3"); } + public Results showCreateTable(String tablename) throws IOException, SQLException { + return this.query("SHOW CREATE TABLE " + tablename); + } + public Results query(String sql) throws IOException, SQLException { Properties connectionProps = new Properties(); connectionProps.put("user", user); diff --git a/testing/testcontainers/java/src/test/java/io/crate/example/testing/TestSqlInitialization.java b/testing/testcontainers/java/src/test/java/io/crate/example/testing/TestSqlInitialization.java new file mode 100644 index 00000000..3fe9f03d --- /dev/null +++ b/testing/testcontainers/java/src/test/java/io/crate/example/testing/TestSqlInitialization.java @@ -0,0 +1,67 @@ +package io.crate.example.testing; + +import org.junit.Test; + +import java.io.IOException; +import java.sql.SQLException; + +import static org.assertj.core.api.Assertions.assertThat; + + +/** + * Database containers launched with SQL initialization/provisioning script/routine. + *
+ */ +public class TestSqlInitialization { + + /** + * Launch container with CrateDB 5.2, using `TC_INITSCRIPT` to address a file in Java's CLASSPATH. + * + */ + @Test + public void testTcInitClasspathFile() throws SQLException, IOException { + String connectionUrl = "jdbc:tc:cratedb:5.2://localhost/doc?user=crate&TC_REUSABLE=true&TC_INITSCRIPT=init.sql"; + System.out.printf("Connecting to %s%n", connectionUrl); + + // Invoke `SHOW CREATE TABLE ...` query. + Application app = new Application(connectionUrl); + var results= app.showCreateTable("alltypes"); + assertThat(results.metaData().getColumnCount()).isEqualTo(1); + assertThat(results.rows()).hasSize(1); + } + + /** + * Launch container with CrateDB 5.2, using `TC_INITSCRIPT` to address an arbitrary file on the filesystem. + * + */ + @Test + public void testTcInitArbitraryFile() throws SQLException, IOException { + String connectionUrl = "jdbc:tc:cratedb:5.2://localhost/doc?user=crate&TC_REUSABLE=true&TC_INITSCRIPT=file:src/test/resources/init.sql"; + System.out.printf("Connecting to %s%n", connectionUrl); + + // Invoke `SHOW CREATE TABLE ...` query. + Application app = new Application(connectionUrl); + var results= app.showCreateTable("alltypes"); + assertThat(results.metaData().getColumnCount()).isEqualTo(1); + assertThat(results.rows()).hasSize(1); + } + + /** + * Launch container with CrateDB 5.2, using an init function. + * + */ + @Test + public void testTcInitFunction() throws SQLException, IOException { + String connectionUrl = "jdbc:tc:cratedb:5.2://localhost/doc?user=crate&TC_INITFUNCTION=io.crate.example.testing.utils.TestingHelpers::sqlInitFunction"; + System.out.printf("Connecting to %s%n", connectionUrl); + + // Invoke `SHOW CREATE TABLE ...` query. + Application app = new Application(connectionUrl); + var results= app.showCreateTable("foobar_init"); + assertThat(results.metaData().getColumnCount()).isEqualTo(1); + assertThat(results.rows()).hasSize(1); + } +} diff --git a/testing/testcontainers/java/src/test/java/io/crate/example/testing/utils/TestingHelpers.java b/testing/testcontainers/java/src/test/java/io/crate/example/testing/utils/TestingHelpers.java index 2afdb154..77fc7419 100644 --- a/testing/testcontainers/java/src/test/java/io/crate/example/testing/utils/TestingHelpers.java +++ b/testing/testcontainers/java/src/test/java/io/crate/example/testing/utils/TestingHelpers.java @@ -3,7 +3,10 @@ import io.crate.example.testing.Application; import org.testcontainers.utility.DockerImageName; +import java.io.IOException; +import java.sql.Connection; import java.sql.SQLException; +import java.sql.Statement; import static org.assertj.core.api.Assertions.assertThat; @@ -36,4 +39,15 @@ public static void assertResults(Application.Results results) throws SQLExceptio "Monte Rosa", "Dom"); } + + /** + * Support function for initializing CrateDB with SQL using an init function. + * You can run a simple schema setup or Flyway/liquibase DB migrations here, at your disposal. + * + */ + public static void sqlInitFunction(Connection connection) throws SQLException, IOException, InterruptedException { + try (Statement stmt = connection.createStatement()) { + stmt.execute("CREATE TABLE IF NOT EXISTS foobar_init (id INTEGER)"); + } + } } diff --git a/testing/testcontainers/java/src/test/resources/init.sql b/testing/testcontainers/java/src/test/resources/init.sql new file mode 100644 index 00000000..8a1bd89e --- /dev/null +++ b/testing/testcontainers/java/src/test/resources/init.sql @@ -0,0 +1,15 @@ +CREATE TABLE alltypes ( + name STRING PRIMARY KEY, + date TIMESTAMP, + datetime_tz TIMESTAMP WITH TIME ZONE, + datetime_notz TIMESTAMP WITHOUT TIME ZONE, + nullable_datetime TIMESTAMP, + nullable_date TIMESTAMP, + kind STRING, + flag BOOLEAN, + position INTEGER, + description STRING, + details ARRAY(OBJECT), + attributes OBJECT(DYNAMIC), + coordinates GEO_POINT +) WITH (number_of_replicas=0);