diff --git a/modules/clickhouse/build.gradle b/modules/clickhouse/build.gradle index 39b269d794b..c82fbb27b2d 100644 --- a/modules/clickhouse/build.gradle +++ b/modules/clickhouse/build.gradle @@ -6,4 +6,6 @@ dependencies { testImplementation project(':jdbc-test') testImplementation 'ru.yandex.clickhouse:clickhouse-jdbc:0.3.1-patch' + testImplementation 'mysql:mysql-connector-java:8.0.24' + testImplementation 'io.vertx:vertx-mysql-client:4.0.2' } diff --git a/modules/clickhouse/src/main/java/org/testcontainers/containers/AbstractClickHouseContainerJdbc.java b/modules/clickhouse/src/main/java/org/testcontainers/containers/AbstractClickHouseContainerJdbc.java new file mode 100644 index 00000000000..3963c1a7d2e --- /dev/null +++ b/modules/clickhouse/src/main/java/org/testcontainers/containers/AbstractClickHouseContainerJdbc.java @@ -0,0 +1,47 @@ +package org.testcontainers.containers; + +import org.testcontainers.utility.DockerImageName; + +abstract class AbstractClickHouseContainerJdbc extends JdbcDatabaseContainer { + + public AbstractClickHouseContainerJdbc(final DockerImageName dockerImageName) { + super(dockerImageName); + dockerImageName.assertCompatibleWith(ClickHouseInit.DEFAULT_IMAGE_NAME); + ClickHouseInit.init(this); + } + + @Override + protected Integer getLivenessCheckPort() { + return getMappedPort(ClickHouseInit.HTTP_PORT); + } + + @Override + public String getDriverClassName() { + return ClickHouseInit.MYSQL_DRIVER_CLASS_NAME; + } + + @Override + public String getDatabaseName() { + return ClickHouseInit.DATABASE_NAME; + } + + @Override + public String getUsername() { + return ClickHouseInit.USERNAME; + } + + @Override + public String getPassword() { + return ClickHouseInit.PASSWORD; + } + + @Override + public String getTestQueryString() { + return ClickHouseInit.TEST_QUERY; + } + + @Override + public AbstractClickHouseContainerJdbc withUrlParam(String paramName, String paramValue) { + throw new UnsupportedOperationException("The ClickHouse does not support this"); + } +} diff --git a/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseContainer.java b/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseContainer.java index 9b5f130a323..eae65338bca 100644 --- a/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseContainer.java +++ b/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseContainer.java @@ -1,92 +1,41 @@ package org.testcontainers.containers; import com.google.common.collect.Sets; -import org.testcontainers.containers.wait.strategy.HttpWaitStrategy; import org.testcontainers.utility.DockerImageName; - -import java.time.Duration; import java.util.Set; -public class ClickHouseContainer extends JdbcDatabaseContainer { - public static final String NAME = "clickhouse"; - - private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("yandex/clickhouse-server"); - - @Deprecated - public static final String IMAGE = DEFAULT_IMAGE_NAME.getUnversionedPart(); - - @Deprecated - public static final String DEFAULT_TAG = "18.10.3"; - - public static final Integer HTTP_PORT = 8123; - public static final Integer NATIVE_PORT = 9000; +public class ClickHouseContainer extends GenericContainer { - 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 = ""; - - /** - * @deprecated use {@link ClickHouseContainer(DockerImageName)} instead - */ - @Deprecated public ClickHouseContainer() { - this(DEFAULT_IMAGE_NAME.withTag(DEFAULT_TAG)); + this(ClickHouseInit.DEFAULT_TAG); } - public ClickHouseContainer(String dockerImageName) { - this(DockerImageName.parse(dockerImageName)); + public ClickHouseContainer(String tag) { + this(ClickHouseInit.DEFAULT_IMAGE_NAME.withTag(tag)); } - public ClickHouseContainer(final DockerImageName dockerImageName) { + public ClickHouseContainer(DockerImageName dockerImageName) { super(dockerImageName); + dockerImageName.assertCompatibleWith(ClickHouseInit.DEFAULT_IMAGE_NAME); - dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME); - - withExposedPorts(HTTP_PORT, NATIVE_PORT); - waitingFor( - new HttpWaitStrategy() - .forStatusCode(200) - .forResponsePredicate(responseBody -> "Ok.".equals(responseBody)) - .withStartupTimeout(Duration.ofMinutes(1)) - ); + ClickHouseInit.init(this); } @Override public Set getLivenessCheckPortNumbers() { - return Sets.newHashSet(HTTP_PORT); + return Sets.newHashSet(ClickHouseInit.HTTP_PORT); } - @Override - public String getDriverClassName() { - return DRIVER_CLASS_NAME; + public String getDatabaseName() { + return ClickHouseInit.DATABASE_NAME; } - @Override - public String getJdbcUrl() { - return JDBC_URL_PREFIX + getHost() + ":" + getMappedPort(HTTP_PORT) + "/" + databaseName; - } - - @Override public String getUsername() { - return username; + return ClickHouseInit.USERNAME; } - @Override public String getPassword() { - return password; + return ClickHouseInit.PASSWORD; } - @Override - public String getTestQueryString() { - return TEST_QUERY; - } - - @Override - public ClickHouseContainer withUrlParam(String paramName, String paramValue) { - throw new UnsupportedOperationException("The ClickHouse does not support this"); - } } diff --git a/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseContainerJdbcMysql.java b/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseContainerJdbcMysql.java new file mode 100644 index 00000000000..e3dc1f9432f --- /dev/null +++ b/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseContainerJdbcMysql.java @@ -0,0 +1,20 @@ +package org.testcontainers.containers; + +import org.testcontainers.utility.DockerImageName; + +public class ClickHouseContainerJdbcMysql extends AbstractClickHouseContainerJdbc { + + public ClickHouseContainerJdbcMysql(DockerImageName dockerImageName) { + super(dockerImageName); + } + + @Override + public String getDriverClassName() { + return ClickHouseInit.MYSQL_DRIVER_CLASS_NAME; + } + + @Override + public String getJdbcUrl() { + return "jdbc:mysql://" + getHost() + ":" + getMappedPort(ClickHouseInit.MYSQL_PORT) + "/" + getDatabaseName() + "?user=" + getUsername() + "&password=" + getPassword(); + } +} diff --git a/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseContainerJdbcYandex.java b/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseContainerJdbcYandex.java new file mode 100644 index 00000000000..9985fc496e2 --- /dev/null +++ b/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseContainerJdbcYandex.java @@ -0,0 +1,23 @@ +package org.testcontainers.containers; + +import org.testcontainers.utility.DockerImageName; + +import static org.testcontainers.containers.ClickHouseInit.HTTP_PORT; + +public class ClickHouseContainerJdbcYandex extends ClickHouseContainerJdbcMysql { + + public ClickHouseContainerJdbcYandex(DockerImageName dockerImageName) { + super(dockerImageName); + } + + @Override + public String getDriverClassName() { + return ClickHouseInit.CLICKHOUSE_DRIVER_CLASS_NAME; + } + + @Override + public String getJdbcUrl() { + return "jdbc:clickhouse://" + getHost() + ":" + getMappedPort(HTTP_PORT) + "/" + getDatabaseName() + "?user=" + getUsername() + "&password=" + getPassword(); + } + +} diff --git a/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseInit.java b/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseInit.java new file mode 100644 index 00000000000..20a7bdd3ee3 --- /dev/null +++ b/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseInit.java @@ -0,0 +1,40 @@ +package org.testcontainers.containers; + +import org.testcontainers.containers.wait.strategy.HttpWaitStrategy; +import org.testcontainers.utility.DockerImageName; + +import java.time.Duration; + +public class ClickHouseInit { + public static final String JDBC_NAME_YANDEX = "clickhouse"; + public static final String JDBC_NAME_MYSQL = "mysql"; + + public static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("yandex/clickhouse-server"); + + public static final String CLICKHOUSE_DRIVER_CLASS_NAME = "ru.yandex.clickhouse.ClickHouseDriver"; + public static final String MYSQL_DRIVER_CLASS_NAME = "com.mysql.cj.jdbc.Driver"; + + public static final Integer HTTP_PORT = 8123; + public static final Integer NATIVE_PORT = 9000; + public static final Integer MYSQL_PORT = 9004; + + public static final String DATABASE_NAME = "default"; + public static final String USERNAME = "default"; + public static final String PASSWORD = ""; + + static final String TEST_QUERY = "SELECT 1"; + + public static final String DEFAULT_TAG = "21.3.8.76"; + + public static void init(GenericContainer container) { + container.withExposedPorts(HTTP_PORT, NATIVE_PORT, MYSQL_PORT); + + container.waitingFor( + new HttpWaitStrategy() + .forStatusCode(200) + .forPort(HTTP_PORT) + .forResponsePredicate(responseBody -> "Ok.".equals(responseBody)) + .withStartupTimeout(Duration.ofMinutes(1)) + ); + } +} diff --git a/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseProvider.java b/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseProvider.java index cd2453b8349..2d49ed89817 100644 --- a/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseProvider.java +++ b/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseProvider.java @@ -1,15 +1,18 @@ package org.testcontainers.containers; -import org.testcontainers.utility.DockerImageName; - public class ClickHouseProvider extends JdbcDatabaseContainerProvider { @Override public boolean supports(String databaseType) { - return databaseType.equals(ClickHouseContainer.NAME); + return databaseType.equals(ClickHouseInit.JDBC_NAME_YANDEX) || databaseType.equals(ClickHouseInit.JDBC_NAME_MYSQL); + } + + @Override + public JdbcDatabaseContainer newInstance() { + return newInstance(ClickHouseInit.DEFAULT_TAG); } @Override public JdbcDatabaseContainer newInstance(String tag) { - return new ClickHouseContainer(DockerImageName.parse(ClickHouseContainer.IMAGE).withTag(tag)); + return new ClickHouseContainerJdbcYandex(ClickHouseInit.DEFAULT_IMAGE_NAME.withTag(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 index 63e99284d2b..3c96af28ae9 100644 --- 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 @@ -1 +1 @@ -org.testcontainers.containers.ClickHouseProvider \ No newline at end of file +org.testcontainers.containers.ClickHouseProvider diff --git a/modules/clickhouse/src/test/java/org/testcontainers/ClickhouseTestImages.java b/modules/clickhouse/src/test/java/org/testcontainers/ClickhouseTestImages.java index 961df045bd1..a6b333b7d05 100644 --- a/modules/clickhouse/src/test/java/org/testcontainers/ClickhouseTestImages.java +++ b/modules/clickhouse/src/test/java/org/testcontainers/ClickhouseTestImages.java @@ -3,5 +3,5 @@ import org.testcontainers.utility.DockerImageName; public interface ClickhouseTestImages { - DockerImageName CLICKHOUSE_IMAGE = DockerImageName.parse("yandex/clickhouse-server:18.10.3"); + DockerImageName CLICKHOUSE_IMAGE = DockerImageName.parse("yandex/clickhouse-server:21.3.8.76"); } diff --git a/modules/clickhouse/src/test/java/org/testcontainers/jdbc/clickhouse/ClickhouseJDBCDriverTest.java b/modules/clickhouse/src/test/java/org/testcontainers/jdbc/clickhouse/ClickhouseJDBCDriverTest.java index f3946c8a317..7af3213cb09 100644 --- a/modules/clickhouse/src/test/java/org/testcontainers/jdbc/clickhouse/ClickhouseJDBCDriverTest.java +++ b/modules/clickhouse/src/test/java/org/testcontainers/jdbc/clickhouse/ClickhouseJDBCDriverTest.java @@ -16,6 +16,8 @@ public static Iterable data() { return asList( new Object[][]{ {"jdbc:tc:clickhouse://hostname/databasename", EnumSet.of(Options.PmdKnownBroken)}, + //Not testing jdbc:tc:mysql here because the connection pool used by AbstractJDBCDriverTest tries + //to several things that aren't currently support by the clickhouse-mysql-impl }); } } diff --git a/modules/clickhouse/src/test/java/org/testcontainers/junit/clickhouse/SimpleClickhouseJdbcMysqlTest.java b/modules/clickhouse/src/test/java/org/testcontainers/junit/clickhouse/SimpleClickhouseJdbcMysqlTest.java new file mode 100644 index 00000000000..f225e10b801 --- /dev/null +++ b/modules/clickhouse/src/test/java/org/testcontainers/junit/clickhouse/SimpleClickhouseJdbcMysqlTest.java @@ -0,0 +1,25 @@ +package org.testcontainers.junit.clickhouse; + +import org.junit.Test; +import org.testcontainers.containers.ClickHouseContainerJdbcMysql; + +import java.sql.Connection; +import java.sql.SQLException; + +import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue; +import static org.testcontainers.ClickhouseTestImages.CLICKHOUSE_IMAGE; + +public class SimpleClickhouseJdbcMysqlTest { + + @Test + public void testSimple() throws SQLException { + try (ClickHouseContainerJdbcMysql clickhouse = new ClickHouseContainerJdbcMysql(CLICKHOUSE_IMAGE)) { + clickhouse.start(); + + try (Connection connection = clickhouse.createConnection("")) { + boolean testQuerySucceeded = connection.createStatement().execute("SELECT 1"); + assertTrue("A basic SELECT query succeeds", testQuerySucceeded); + } + } + } +} diff --git a/modules/clickhouse/src/test/java/org/testcontainers/junit/clickhouse/SimpleClickhouseJdbcYandexTest.java b/modules/clickhouse/src/test/java/org/testcontainers/junit/clickhouse/SimpleClickhouseJdbcYandexTest.java new file mode 100644 index 00000000000..a5a4992673b --- /dev/null +++ b/modules/clickhouse/src/test/java/org/testcontainers/junit/clickhouse/SimpleClickhouseJdbcYandexTest.java @@ -0,0 +1,26 @@ +package org.testcontainers.junit.clickhouse; + +import org.junit.Test; +import org.testcontainers.containers.ClickHouseContainerJdbcYandex; +import org.testcontainers.db.AbstractContainerDatabaseTest; + +import java.sql.ResultSet; +import java.sql.SQLException; + +import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; +import static org.testcontainers.ClickhouseTestImages.CLICKHOUSE_IMAGE; + +public class SimpleClickhouseJdbcYandexTest extends AbstractContainerDatabaseTest { + + @Test + public void testSimple() throws SQLException { + try (ClickHouseContainerJdbcYandex clickhouse = new ClickHouseContainerJdbcYandex(CLICKHOUSE_IMAGE)) { + clickhouse.start(); + + ResultSet resultSet = performQuery(clickhouse, "SELECT 1"); + + int resultSetInt = resultSet.getInt(1); + assertEquals("A basic SELECT query succeeds", 1, resultSetInt); + } + } +} diff --git a/modules/clickhouse/src/test/java/org/testcontainers/junit/clickhouse/SimpleClickhouseTest.java b/modules/clickhouse/src/test/java/org/testcontainers/junit/clickhouse/SimpleClickhouseTest.java index 8f3879673a0..1e0624e03a3 100644 --- a/modules/clickhouse/src/test/java/org/testcontainers/junit/clickhouse/SimpleClickhouseTest.java +++ b/modules/clickhouse/src/test/java/org/testcontainers/junit/clickhouse/SimpleClickhouseTest.java @@ -1,26 +1,45 @@ package org.testcontainers.junit.clickhouse; +import io.vertx.core.Future; +import io.vertx.core.Vertx; +import io.vertx.mysqlclient.MySQLConnectOptions; +import io.vertx.mysqlclient.MySQLConnection; +import io.vertx.sqlclient.Row; +import io.vertx.sqlclient.RowSet; import org.junit.Test; +import org.testcontainers.containers.ClickHouseInit; import org.testcontainers.containers.ClickHouseContainer; -import org.testcontainers.db.AbstractContainerDatabaseTest; -import java.sql.ResultSet; -import java.sql.SQLException; +import java.util.concurrent.CountDownLatch; -import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; -import static org.testcontainers.ClickhouseTestImages.CLICKHOUSE_IMAGE; +import static org.junit.Assert.assertFalse; -public class SimpleClickhouseTest extends AbstractContainerDatabaseTest { +public class SimpleClickhouseTest { @Test - public void testSimple() throws SQLException { - try (ClickHouseContainer clickhouse = new ClickHouseContainer(CLICKHOUSE_IMAGE)) { - clickhouse.start(); + public void testRawMysql() throws Throwable { + try(ClickHouseContainer clickHouseContainer = new ClickHouseContainer()) { + clickHouseContainer.start(); - ResultSet resultSet = performQuery(clickhouse, "SELECT 1"); + MySQLConnectOptions connectOptions = new MySQLConnectOptions() + .setPort(clickHouseContainer.getMappedPort(ClickHouseInit.MYSQL_PORT)) + .setHost(clickHouseContainer.getHost()) + .setDatabase(clickHouseContainer.getDatabaseName()) + .setUser(clickHouseContainer.getUsername()) + .setPassword(clickHouseContainer.getPassword()); - int resultSetInt = resultSet.getInt(1); - assertEquals("A basic SELECT query succeeds", 1, resultSetInt); + CountDownLatch lock = new CountDownLatch(1); + + Vertx vertx = Vertx.vertx(); + Future> result = MySQLConnection + .connect(vertx, connectOptions) + .flatMap(conn -> conn.query("SELECT 1;").execute()) + .onComplete(r -> lock.countDown()); + + lock.await(); + + assertFalse(result.failed()); } } + }