diff --git a/modules/clickhouse/build.gradle b/modules/clickhouse/build.gradle new file mode 100644 index 00000000000..4f0e1a1fd90 --- /dev/null +++ b/modules/clickhouse/build.gradle @@ -0,0 +1,6 @@ +description = "Testcontainers :: JDBC :: ClickHouse" + +dependencies { + compile project(':testcontainers') + compile project(':jdbc') +} diff --git a/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseContainer.java b/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseContainer.java new file mode 100644 index 00000000000..0fd6174bf3b --- /dev/null +++ b/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseContainer.java @@ -0,0 +1,72 @@ +package org.testcontainers.containers; + +import org.testcontainers.containers.wait.HttpWaitStrategy; + +import java.time.Duration; + +public class ClickHouseContainer extends JdbcDatabaseContainer { + public static final String NAME = "clickhouse"; + public static final String IMAGE = "yandex/clickhouse-server"; + public static final String DEFAULT_TAG = "18.10.3"; + + public static final Integer HTTP_PORT = 8123; + public static final Integer NATIVE_PORT = 9000; + + private static final String DRIVER_CLASS_NAME = "ru.yandex.clickhouse.ClickHouseDriver"; + private static final String JDBC_URL_PREFIX = "jdbc:" + NAME + "://"; + private static final String TEST_QUERY = "SELECT 1"; + + private String databaseName = "default"; + private String username = "default"; + private String password = ""; + + public ClickHouseContainer() { + super(IMAGE + ":" + DEFAULT_TAG); + } + + public ClickHouseContainer(String dockerImageName) { + super(dockerImageName); + } + + @Override + protected void configure() { + withExposedPorts(HTTP_PORT, NATIVE_PORT); + waitingFor( + new HttpWaitStrategy() + .forStatusCode(200) + .forResponsePredicate(responseBody -> "Ok.".equals(responseBody)) + .withStartupTimeout(Duration.ofMinutes(1)) + ); + } + + @Override + protected Integer getLivenessCheckPort() { + return getMappedPort(HTTP_PORT); + } + + @Override + public String getDriverClassName() { + return DRIVER_CLASS_NAME; + } + + @Override + public String getJdbcUrl() { + return JDBC_URL_PREFIX + getContainerIpAddress() + ":" + getMappedPort(HTTP_PORT) + "/" + databaseName; + } + + @Override + public String getUsername() { + return username; + } + + @Override + public String getPassword() { + return password; + } + + @Override + public String getTestQueryString() { + return TEST_QUERY; + } + +} diff --git a/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseProvider.java b/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseProvider.java new file mode 100644 index 00000000000..be5a01657f0 --- /dev/null +++ b/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseProvider.java @@ -0,0 +1,13 @@ +package org.testcontainers.containers; + +public class ClickHouseProvider extends JdbcDatabaseContainerProvider { + @Override + public boolean supports(String databaseType) { + return databaseType.equals(ClickHouseContainer.NAME); + } + + @Override + public JdbcDatabaseContainer newInstance(String tag) { + return new ClickHouseContainer(ClickHouseContainer.IMAGE + ":" + tag); + } +} diff --git a/modules/clickhouse/src/main/resources/META-INF/services/org.testcontainers.containers.JdbcDatabaseContainerProvider b/modules/clickhouse/src/main/resources/META-INF/services/org.testcontainers.containers.JdbcDatabaseContainerProvider new file mode 100644 index 00000000000..63e99284d2b --- /dev/null +++ b/modules/clickhouse/src/main/resources/META-INF/services/org.testcontainers.containers.JdbcDatabaseContainerProvider @@ -0,0 +1 @@ +org.testcontainers.containers.ClickHouseProvider \ No newline at end of file diff --git a/modules/jdbc-test/build.gradle b/modules/jdbc-test/build.gradle index 0223781eecb..e631d2fa1a3 100644 --- a/modules/jdbc-test/build.gradle +++ b/modules/jdbc-test/build.gradle @@ -10,6 +10,7 @@ dependencies { compile project(':mariadb') compile project(':oracle-xe') compile project(':mssqlserver') + compile project(':clickhouse') testCompile 'com.google.guava:guava:18.0' testCompile 'org.postgresql:postgresql:42.0.0' @@ -17,6 +18,7 @@ dependencies { testCompile 'org.mariadb.jdbc:mariadb-java-client:1.4.6' testCompile 'com.oracle:ojdbc6:12.1.0.1-atlassian-hosted' testCompile 'com.microsoft.sqlserver:mssql-jdbc:6.1.0.jre8' + testCompile 'ru.yandex.clickhouse:clickhouse-jdbc:0.1.41' testCompile 'com.zaxxer:HikariCP-java6:2.3.8' testCompile 'org.apache.tomcat:tomcat-jdbc:8.5.4' diff --git a/modules/jdbc-test/src/test/java/org/testcontainers/jdbc/JDBCDriverTest.java b/modules/jdbc-test/src/test/java/org/testcontainers/jdbc/JDBCDriverTest.java index 762e2ab639a..5cd5f25ae3c 100644 --- a/modules/jdbc-test/src/test/java/org/testcontainers/jdbc/JDBCDriverTest.java +++ b/modules/jdbc-test/src/test/java/org/testcontainers/jdbc/JDBCDriverTest.java @@ -30,6 +30,7 @@ private enum Options { CharacterSet, CustomIniFile, JDBCParams, + PmdKnownBroken } @Parameter @@ -56,7 +57,9 @@ public static Iterable data() { {"jdbc:tc:mariadb:10.2.14://hostname/databasename?TC_INITSCRIPT=somepath/init_unicode_mysql.sql&useUnicode=yes&characterEncoding=utf8", EnumSet.of(Options.CharacterSet)}, {"jdbc:tc:mariadb:10.2.14://hostname/databasename?TC_INITSCRIPT=somepath/init_mariadb.sql", EnumSet.of(Options.ScriptedSchema)}, {"jdbc:tc:mariadb:10.2.14://hostname/databasename?TC_INITFUNCTION=org.testcontainers.jdbc.JDBCDriverTest::sampleInitFunction", EnumSet.of(Options.ScriptedSchema)}, - {"jdbc:tc:mariadb:10.2.14://hostname/databasename?TC_MY_CNF=somepath/mariadb_conf_override", EnumSet.of(Options.CustomIniFile)}}); + {"jdbc:tc:mariadb:10.2.14://hostname/databasename?TC_MY_CNF=somepath/mariadb_conf_override", EnumSet.of(Options.CustomIniFile)}, + {"jdbc:tc:clickhouse://hostname/databasename", EnumSet.of(Options.PmdKnownBroken)}, + }); } public static void sampleInitFunction(Connection connection) throws SQLException { @@ -102,7 +105,7 @@ public void test() throws SQLException { private void performSimpleTest(String jdbcUrl) throws SQLException { try (HikariDataSource dataSource = getDataSource(jdbcUrl, 1)) { - boolean result = new QueryRunner(dataSource).query("SELECT 1", rs -> { + boolean result = new QueryRunner(dataSource, options.contains(Options.PmdKnownBroken)).query("SELECT 1", rs -> { rs.next(); int resultSetInt = rs.getInt(1); assertEquals("A basic SELECT query succeeds", 1, resultSetInt); diff --git a/modules/jdbc-test/src/test/java/org/testcontainers/junit/SimpleClickhouseTest.java b/modules/jdbc-test/src/test/java/org/testcontainers/junit/SimpleClickhouseTest.java new file mode 100644 index 00000000000..4e123617b8d --- /dev/null +++ b/modules/jdbc-test/src/test/java/org/testcontainers/junit/SimpleClickhouseTest.java @@ -0,0 +1,36 @@ +package org.testcontainers.junit; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import org.junit.Rule; +import org.junit.Test; +import org.testcontainers.containers.ClickHouseContainer; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; + +public class SimpleClickhouseTest { + + @Rule + public ClickHouseContainer clickhouse = new ClickHouseContainer(); + + @Test + public void testSimple() throws SQLException { + HikariConfig hikariConfig = new HikariConfig(); + hikariConfig.setJdbcUrl(clickhouse.getJdbcUrl()); + hikariConfig.setUsername(clickhouse.getUsername()); + hikariConfig.setPassword(clickhouse.getPassword()); + + HikariDataSource ds = new HikariDataSource(hikariConfig); + Statement statement = ds.getConnection().createStatement(); + statement.execute("SELECT 1"); + ResultSet resultSet = statement.getResultSet(); + + resultSet.next(); + int resultSetInt = resultSet.getInt(1); + assertEquals("A basic SELECT query succeeds", 1, resultSetInt); + } +}