diff --git a/modules/yugabytedb/src/main/java/org/testcontainers/containers/YugabyteDBYCQLContainer.java b/modules/yugabytedb/src/main/java/org/testcontainers/containers/YugabyteDBYCQLContainer.java index 09ccca9ace4..723eb50ec6d 100644 --- a/modules/yugabytedb/src/main/java/org/testcontainers/containers/YugabyteDBYCQLContainer.java +++ b/modules/yugabytedb/src/main/java/org/testcontainers/containers/YugabyteDBYCQLContainer.java @@ -1,16 +1,16 @@ package org.testcontainers.containers; -import java.net.InetSocketAddress; -import java.time.Duration; -import java.util.Collections; -import java.util.Set; - import com.github.dockerjava.api.command.InspectContainerResponse; import org.testcontainers.containers.delegate.YugabyteDBYCQLDelegate; import org.testcontainers.containers.strategy.YugabyteDBYCQLWaitStrategy; import org.testcontainers.ext.ScriptUtils; import org.testcontainers.utility.DockerImageName; +import java.net.InetSocketAddress; +import java.time.Duration; +import java.util.Collections; +import java.util.Set; + /** * Testcontainers implementation for YugabyteDB YCQL API. * @@ -19,150 +19,149 @@ */ public class YugabyteDBYCQLContainer extends GenericContainer { - private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("yugabytedb/yugabyte"); - - private static final Integer YCQL_PORT = 9042; - - private static final Integer MASTER_DASHBOARD_PORT = 7000; - - private static final Integer TSERVER_DASHBOARD_PORT = 9000; - - private static final String ENTRYPOINT = "bin/yugabyted start --background=false"; - - private static final String LOCAL_DC = "datacenter1"; - - private String keyspace; - - private String username; - - private String password; - - private String initScript; - - /** - * @param imageName image name - */ - public YugabyteDBYCQLContainer(final String imageName) { - this(DockerImageName.parse(imageName)); - } - - /** - * @param imageName image name - */ - public YugabyteDBYCQLContainer(final DockerImageName imageName) { - super(imageName); - imageName.assertCompatibleWith(DEFAULT_IMAGE_NAME); - withExposedPorts(YCQL_PORT, MASTER_DASHBOARD_PORT, TSERVER_DASHBOARD_PORT); - waitingFor(new YugabyteDBYCQLWaitStrategy(this).withStartupTimeout(Duration.ofSeconds(60))); - withCommand(ENTRYPOINT); - } - - @Override - public Set getLivenessCheckPortNumbers() { - return Collections.singleton(getMappedPort(YCQL_PORT)); - } - - /** - * Configures the environment variables. Setting up these variables would create the - * custom objects. Setting {@link #withKeyspaceName(String)}, - * {@link #withUsername(String)}, {@link #withPassword(String)} these parameters will - * initilaize the database with those custom values - */ - @Override - protected void configure() { - addEnv("YCQL_KEYSPACE", keyspace); - addEnv("YCQL_USER", username); - addEnv("YCQL_PASSWORD", password); - } - - /** - * @param initScript path of the initialization script file - * @return {@link YugabyteDBYCQLContainer} instance - */ - public YugabyteDBYCQLContainer withInitScript(String initScript) { - this.initScript = initScript; - return this; - } - - /** - * Setting this would create the keyspace - * @param keyspace keyspace - * @return {@link YugabyteDBYCQLContainer} instance - */ - public YugabyteDBYCQLContainer withKeyspaceName(final String keyspace) { - this.keyspace = keyspace; - return this; - } - - /** - * Setting this would create the custom user role - * @param username user name - * @return {@link YugabyteDBYCQLContainer} instance - */ - public YugabyteDBYCQLContainer withUsername(final String username) { - this.username = username; - return this; - } - - /** - * Setting this along with {@link #withUsername(String)} would enable authentication - * @param password password - * @return {@link YugabyteDBYCQLContainer} instance - */ - public YugabyteDBYCQLContainer withPassword(final String password) { - this.password = password; - return this; - } - - /** - * Executes the initilization script - * @param containerInfo containerInfo - */ - @Override - protected void containerIsStarted(InspectContainerResponse containerInfo) { - if (initScript != null) { - ScriptUtils.runInitScript(new YugabyteDBYCQLDelegate(this), initScript); - } - } - - /** - * Returns a {@link InetSocketAddress} representation of YCQL's contact point info - * @return contactpoint - */ - public InetSocketAddress getContactPoint() { - return new InetSocketAddress(getHost(), getMappedPort(YCQL_PORT)); - } - - /** - * Returns the local datacenter name - * @return localdc name - */ - public String getLocalDc() { - return LOCAL_DC; - } - - /** - * Username getter method - * @return username - */ - public String getUsername() { - return username; - } - - /** - * Password getter method - * @return password - */ - public String getPassword() { - return password; - } - - /** - * Keyspace getter method - * @return keyspace - */ - public String getKeyspace() { - return keyspace; - } - + private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("yugabytedb/yugabyte"); + + private static final Integer YCQL_PORT = 9042; + + private static final Integer MASTER_DASHBOARD_PORT = 7000; + + private static final Integer TSERVER_DASHBOARD_PORT = 9000; + + private static final String ENTRYPOINT = "bin/yugabyted start --background=false"; + + private static final String LOCAL_DC = "datacenter1"; + + private String keyspace; + + private String username; + + private String password; + + private String initScript; + + /** + * @param imageName image name + */ + public YugabyteDBYCQLContainer(final String imageName) { + this(DockerImageName.parse(imageName)); + } + + /** + * @param imageName image name + */ + public YugabyteDBYCQLContainer(final DockerImageName imageName) { + super(imageName); + imageName.assertCompatibleWith(DEFAULT_IMAGE_NAME); + withExposedPorts(YCQL_PORT, MASTER_DASHBOARD_PORT, TSERVER_DASHBOARD_PORT); + waitingFor(new YugabyteDBYCQLWaitStrategy(this).withStartupTimeout(Duration.ofSeconds(60))); + withCommand(ENTRYPOINT); + } + + @Override + public Set getLivenessCheckPortNumbers() { + return Collections.singleton(getMappedPort(YCQL_PORT)); + } + + /** + * Configures the environment variables. Setting up these variables would create the + * custom objects. Setting {@link #withKeyspaceName(String)}, + * {@link #withUsername(String)}, {@link #withPassword(String)} these parameters will + * initilaize the database with those custom values + */ + @Override + protected void configure() { + addEnv("YCQL_KEYSPACE", keyspace); + addEnv("YCQL_USER", username); + addEnv("YCQL_PASSWORD", password); + } + + /** + * @param initScript path of the initialization script file + * @return {@link YugabyteDBYCQLContainer} instance + */ + public YugabyteDBYCQLContainer withInitScript(String initScript) { + this.initScript = initScript; + return this; + } + + /** + * Setting this would create the keyspace + * @param keyspace keyspace + * @return {@link YugabyteDBYCQLContainer} instance + */ + public YugabyteDBYCQLContainer withKeyspaceName(final String keyspace) { + this.keyspace = keyspace; + return this; + } + + /** + * Setting this would create the custom user role + * @param username user name + * @return {@link YugabyteDBYCQLContainer} instance + */ + public YugabyteDBYCQLContainer withUsername(final String username) { + this.username = username; + return this; + } + + /** + * Setting this along with {@link #withUsername(String)} would enable authentication + * @param password password + * @return {@link YugabyteDBYCQLContainer} instance + */ + public YugabyteDBYCQLContainer withPassword(final String password) { + this.password = password; + return this; + } + + /** + * Executes the initilization script + * @param containerInfo containerInfo + */ + @Override + protected void containerIsStarted(InspectContainerResponse containerInfo) { + if (initScript != null) { + ScriptUtils.runInitScript(new YugabyteDBYCQLDelegate(this), initScript); + } + } + + /** + * Returns a {@link InetSocketAddress} representation of YCQL's contact point info + * @return contactpoint + */ + public InetSocketAddress getContactPoint() { + return new InetSocketAddress(getHost(), getMappedPort(YCQL_PORT)); + } + + /** + * Returns the local datacenter name + * @return localdc name + */ + public String getLocalDc() { + return LOCAL_DC; + } + + /** + * Username getter method + * @return username + */ + public String getUsername() { + return username; + } + + /** + * Password getter method + * @return password + */ + public String getPassword() { + return password; + } + + /** + * Keyspace getter method + * @return keyspace + */ + public String getKeyspace() { + return keyspace; + } } diff --git a/modules/yugabytedb/src/main/java/org/testcontainers/containers/YugabyteDBYSQLContainer.java b/modules/yugabytedb/src/main/java/org/testcontainers/containers/YugabyteDBYSQLContainer.java index b8d5215a3fc..290269dfe79 100644 --- a/modules/yugabytedb/src/main/java/org/testcontainers/containers/YugabyteDBYSQLContainer.java +++ b/modules/yugabytedb/src/main/java/org/testcontainers/containers/YugabyteDBYSQLContainer.java @@ -1,12 +1,11 @@ package org.testcontainers.containers; -import java.time.Duration; -import java.util.Set; - import org.testcontainers.containers.strategy.YugabyteDBYSQLWaitStrategy; import org.testcontainers.utility.DockerImageName; +import java.time.Duration; import java.util.Collections; +import java.util.Set; /** * Testcontainers implementation for YugabyteDB YSQL API. @@ -17,128 +16,135 @@ public class YugabyteDBYSQLContainer extends JdbcDatabaseContainer { - private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("yugabytedb/yugabyte"); - - private static final Integer YSQL_PORT = 5433; - - private static final Integer MASTER_DASHBOARD_PORT = 7000; - - private static final Integer TSERVER_DASHBOARD_PORT = 9000; - - private static final String JDBC_DRIVER_CLASS = "com.yugabyte.Driver"; - - private static final String JDBC_CONNECT_PREFIX = "jdbc:yugabytedb"; - - private static final String ENTRYPOINT = "bin/yugabyted start --background=false"; - - private String database = "yugabyte"; - - private String username = "yugabyte"; - - private String password = "yugabyte"; - - /** - * @param imageName image name - */ - public YugabyteDBYSQLContainer(final String imageName) { - this(DockerImageName.parse(imageName)); - } - - /** - * @param imageName image name - */ - public YugabyteDBYSQLContainer(final DockerImageName imageName) { - super(imageName); - imageName.assertCompatibleWith(DEFAULT_IMAGE_NAME); - withExposedPorts(YSQL_PORT, MASTER_DASHBOARD_PORT, TSERVER_DASHBOARD_PORT); - waitingFor(new YugabyteDBYSQLWaitStrategy(this).withStartupTimeout(Duration.ofSeconds(60))); - withCommand(ENTRYPOINT); - } - - @Override - public Set getLivenessCheckPortNumbers() { - return Collections.singleton(getMappedPort(YSQL_PORT)); - } - - /** - * Configures the environment variables. Setting up these variables would create the - * custom objects. Setting {@link #withDatabaseName(String)}, - * {@link #withUsername(String)}, {@link #withPassword(String)} these parameters will - * initilaize the database with those custom values - */ - - @Override - protected void configure() { - addEnv("YSQL_DB", database); - addEnv("YSQL_USER", username); - addEnv("YSQL_PASSWORD", password); - } - - @Override - public String getDriverClassName() { - return JDBC_DRIVER_CLASS; - } - - @Override - public String getJdbcUrl() { - return JDBC_CONNECT_PREFIX + "://" + getHost() + ":" + getMappedPort(YSQL_PORT) + "/" + database - + constructUrlParameters("?", "&"); - } - - @Override - public String getDatabaseName() { - return database; - } - - @Override - public String getUsername() { - return username; - } - - @Override - public String getPassword() { - return password; - } - - @Override - public String getTestQueryString() { - return "SELECT 1"; - } - - /** - * Setting this would create the keyspace - * @param database database name - * @return {@link YugabyteDBYSQLContainer} instance - */ - - @Override - public YugabyteDBYSQLContainer withDatabaseName(final String database) { - this.database = database; - return this; - } - - /** - * Setting this would create the custom user role - * @param username user name - * @return {@link YugabyteDBYSQLContainer} instance - */ - - @Override - public YugabyteDBYSQLContainer withUsername(final String username) { - this.username = username; - return this; - } - - /** - * Setting this along with {@link #withUsername(String)} would enable authentication - * @param password password - * @return {@link YugabyteDBYSQLContainer} instance - */ - - @Override - public YugabyteDBYSQLContainer withPassword(final String password) { - this.password = password; - return this; - } - + private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("yugabytedb/yugabyte"); + + private static final Integer YSQL_PORT = 5433; + + private static final Integer MASTER_DASHBOARD_PORT = 7000; + + private static final Integer TSERVER_DASHBOARD_PORT = 9000; + + private static final String JDBC_DRIVER_CLASS = "com.yugabyte.Driver"; + + private static final String JDBC_CONNECT_PREFIX = "jdbc:yugabytedb"; + + private static final String ENTRYPOINT = "bin/yugabyted start --background=false"; + + private String database = "yugabyte"; + + private String username = "yugabyte"; + + private String password = "yugabyte"; + + /** + * @param imageName image name + */ + public YugabyteDBYSQLContainer(final String imageName) { + this(DockerImageName.parse(imageName)); + } + + /** + * @param imageName image name + */ + public YugabyteDBYSQLContainer(final DockerImageName imageName) { + super(imageName); + imageName.assertCompatibleWith(DEFAULT_IMAGE_NAME); + withExposedPorts(YSQL_PORT, MASTER_DASHBOARD_PORT, TSERVER_DASHBOARD_PORT); + waitingFor(new YugabyteDBYSQLWaitStrategy(this).withStartupTimeout(Duration.ofSeconds(60))); + withCommand(ENTRYPOINT); + } + + @Override + public Set getLivenessCheckPortNumbers() { + return Collections.singleton(getMappedPort(YSQL_PORT)); + } + + /** + * Configures the environment variables. Setting up these variables would create the + * custom objects. Setting {@link #withDatabaseName(String)}, + * {@link #withUsername(String)}, {@link #withPassword(String)} these parameters will + * initilaize the database with those custom values + */ + + @Override + protected void configure() { + addEnv("YSQL_DB", database); + addEnv("YSQL_USER", username); + addEnv("YSQL_PASSWORD", password); + } + + @Override + public String getDriverClassName() { + return JDBC_DRIVER_CLASS; + } + + @Override + public String getJdbcUrl() { + return ( + JDBC_CONNECT_PREFIX + + "://" + + getHost() + + ":" + + getMappedPort(YSQL_PORT) + + "/" + + database + + constructUrlParameters("?", "&") + ); + } + + @Override + public String getDatabaseName() { + return database; + } + + @Override + public String getUsername() { + return username; + } + + @Override + public String getPassword() { + return password; + } + + @Override + public String getTestQueryString() { + return "SELECT 1"; + } + + /** + * Setting this would create the keyspace + * @param database database name + * @return {@link YugabyteDBYSQLContainer} instance + */ + + @Override + public YugabyteDBYSQLContainer withDatabaseName(final String database) { + this.database = database; + return this; + } + + /** + * Setting this would create the custom user role + * @param username user name + * @return {@link YugabyteDBYSQLContainer} instance + */ + + @Override + public YugabyteDBYSQLContainer withUsername(final String username) { + this.username = username; + return this; + } + + /** + * Setting this along with {@link #withUsername(String)} would enable authentication + * @param password password + * @return {@link YugabyteDBYSQLContainer} instance + */ + + @Override + public YugabyteDBYSQLContainer withPassword(final String password) { + this.password = password; + return this; + } } diff --git a/modules/yugabytedb/src/main/java/org/testcontainers/containers/YugabyteDBYSQLContainerProvider.java b/modules/yugabytedb/src/main/java/org/testcontainers/containers/YugabyteDBYSQLContainerProvider.java index 294493dadc8..d160ccdd223 100644 --- a/modules/yugabytedb/src/main/java/org/testcontainers/containers/YugabyteDBYSQLContainerProvider.java +++ b/modules/yugabytedb/src/main/java/org/testcontainers/containers/YugabyteDBYSQLContainerProvider.java @@ -10,34 +10,33 @@ */ public class YugabyteDBYSQLContainerProvider extends JdbcDatabaseContainerProvider { - private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("yugabytedb/yugabyte"); + private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("yugabytedb/yugabyte"); - private static final String DEFAULT_TAG = "2.14.3.1-b1"; + private static final String DEFAULT_TAG = "2.14.3.1-b1"; - private static final String NAME = "yugabyte"; + private static final String NAME = "yugabyte"; - private static final String USER_PARAM = "user"; + private static final String USER_PARAM = "user"; - private static final String PASSWORD_PARAM = "password"; + private static final String PASSWORD_PARAM = "password"; - @Override - public boolean supports(String databaseType) { - return databaseType.equals(NAME); - } + @Override + public boolean supports(String databaseType) { + return databaseType.equals(NAME); + } - @Override - public JdbcDatabaseContainer newInstance() { - return newInstance(DEFAULT_TAG); - } + @Override + public JdbcDatabaseContainer newInstance() { + return newInstance(DEFAULT_TAG); + } - @Override - public JdbcDatabaseContainer newInstance(String tag) { - return new YugabyteDBYSQLContainer(DEFAULT_IMAGE_NAME.withTag(tag)); - } - - @Override - public JdbcDatabaseContainer newInstance(ConnectionUrl connectionUrl) { - return newInstanceFromConnectionUrl(connectionUrl, USER_PARAM, PASSWORD_PARAM); - } + @Override + public JdbcDatabaseContainer newInstance(String tag) { + return new YugabyteDBYSQLContainer(DEFAULT_IMAGE_NAME.withTag(tag)); + } + @Override + public JdbcDatabaseContainer newInstance(ConnectionUrl connectionUrl) { + return newInstanceFromConnectionUrl(connectionUrl, USER_PARAM, PASSWORD_PARAM); + } } diff --git a/modules/yugabytedb/src/main/java/org/testcontainers/containers/delegate/AbstractYCQLDelegate.java b/modules/yugabytedb/src/main/java/org/testcontainers/containers/delegate/AbstractYCQLDelegate.java index 77f61e35340..c0e566c7ecf 100644 --- a/modules/yugabytedb/src/main/java/org/testcontainers/containers/delegate/AbstractYCQLDelegate.java +++ b/modules/yugabytedb/src/main/java/org/testcontainers/containers/delegate/AbstractYCQLDelegate.java @@ -9,15 +9,19 @@ */ public abstract class AbstractYCQLDelegate implements DatabaseDelegate { - @Override - public void execute(String statement, String scriptPath, int lineNumber, boolean continueOnError, - boolean ignoreFailedDrops) { - // do nothing - } - - @Override - public void close() { - // do nothing - } + @Override + public void execute( + String statement, + String scriptPath, + int lineNumber, + boolean continueOnError, + boolean ignoreFailedDrops + ) { + // do nothing + } + @Override + public void close() { + // do nothing + } } diff --git a/modules/yugabytedb/src/main/java/org/testcontainers/containers/delegate/YugabyteDBYCQLDelegate.java b/modules/yugabytedb/src/main/java/org/testcontainers/containers/delegate/YugabyteDBYCQLDelegate.java index ba440a7bbec..e324679713b 100644 --- a/modules/yugabytedb/src/main/java/org/testcontainers/containers/delegate/YugabyteDBYCQLDelegate.java +++ b/modules/yugabytedb/src/main/java/org/testcontainers/containers/delegate/YugabyteDBYCQLDelegate.java @@ -1,7 +1,5 @@ package org.testcontainers.containers.delegate; -import java.util.Collection; - import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -9,6 +7,8 @@ import org.testcontainers.containers.YugabyteDBYCQLContainer; import org.testcontainers.ext.ScriptUtils.UncategorizedScriptException; +import java.util.Collection; + /** * Query execution delegate class for YCQL API to delegate init-script statements. This * invokes the in-built ycqlsh cli within the container to execute the @@ -23,24 +23,35 @@ @Slf4j public final class YugabyteDBYCQLDelegate extends AbstractYCQLDelegate { - private static final String BIN_PATH = "/home/yugabyte/tserver/bin/ycqlsh"; - - private final YugabyteDBYCQLContainer container; + private static final String BIN_PATH = "/home/yugabyte/tserver/bin/ycqlsh"; - @Override - public void execute(Collection statements, String scriptPath, boolean continueOnError, - boolean ignoreFailedDrops) { - try { - ExecResult result = container.execInContainer(BIN_PATH, "-u", container.getUsername(), "-p", - container.getPassword(), "-k", container.getKeyspace(), "-e", StringUtils.join(statements, ";")); - if (result.getExitCode() != 0) { - throw new RuntimeException(result.getStderr()); - } - } - catch (Exception e) { - log.debug(e.getMessage(), e); - throw new UncategorizedScriptException(e.getMessage(), e); - } - } + private final YugabyteDBYCQLContainer container; + @Override + public void execute( + Collection statements, + String scriptPath, + boolean continueOnError, + boolean ignoreFailedDrops + ) { + try { + ExecResult result = container.execInContainer( + BIN_PATH, + "-u", + container.getUsername(), + "-p", + container.getPassword(), + "-k", + container.getKeyspace(), + "-e", + StringUtils.join(statements, ";") + ); + if (result.getExitCode() != 0) { + throw new RuntimeException(result.getStderr()); + } + } catch (Exception e) { + log.debug(e.getMessage(), e); + throw new UncategorizedScriptException(e.getMessage(), e); + } + } } diff --git a/modules/yugabytedb/src/main/java/org/testcontainers/containers/strategy/YugabyteDBYCQLWaitStrategy.java b/modules/yugabytedb/src/main/java/org/testcontainers/containers/strategy/YugabyteDBYCQLWaitStrategy.java index 245ca0ae5fa..dd775564941 100644 --- a/modules/yugabytedb/src/main/java/org/testcontainers/containers/strategy/YugabyteDBYCQLWaitStrategy.java +++ b/modules/yugabytedb/src/main/java/org/testcontainers/containers/strategy/YugabyteDBYCQLWaitStrategy.java @@ -1,8 +1,5 @@ package org.testcontainers.containers.strategy; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.testcontainers.containers.Container.ExecResult; @@ -10,6 +7,9 @@ import org.testcontainers.containers.wait.strategy.AbstractWaitStrategy; import org.testcontainers.containers.wait.strategy.WaitStrategyTarget; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + import static org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess; /** @@ -29,43 +29,54 @@ @Slf4j public final class YugabyteDBYCQLWaitStrategy extends AbstractWaitStrategy { - private static final String YCQL_TEST_QUERY = "SELECT release_version FROM system.local"; - - private static final String BIN_PATH = "/home/yugabyte/tserver/bin/ycqlsh"; + private static final String YCQL_TEST_QUERY = "SELECT release_version FROM system.local"; - private final WaitStrategyTarget target; + private static final String BIN_PATH = "/home/yugabyte/tserver/bin/ycqlsh"; - @Override - public void waitUntilReady(WaitStrategyTarget target) { - YugabyteDBYCQLContainer container = (YugabyteDBYCQLContainer) target; - AtomicBoolean status = new AtomicBoolean(true); - retryUntilSuccess((int) startupTimeout.getSeconds(), TimeUnit.SECONDS, () -> { - YugabyteDBYCQLWaitStrategy.this.getRateLimiter().doWhenReady(() -> { - try { - ExecResult result = container.execInContainer(BIN_PATH, "-u", container.getUsername(), "-p", - container.getPassword(), "-k", container.getKeyspace(), "-e", YCQL_TEST_QUERY); - if (result.getExitCode() != 0) { - status.set(false); - log.debug(result.getStderr()); - } - } - catch (Exception e) { - status.set(false); - log.debug(e.getMessage(), e); - } - finally { - if (!status.getAndSet(true)) { - throw new RuntimeException("container hasn't come up yet"); - } - } - }); - return status; - }); - } + private final WaitStrategyTarget target; - @Override - public void waitUntilReady() { - waitUntilReady(target); - } + @Override + public void waitUntilReady(WaitStrategyTarget target) { + YugabyteDBYCQLContainer container = (YugabyteDBYCQLContainer) target; + AtomicBoolean status = new AtomicBoolean(true); + retryUntilSuccess( + (int) startupTimeout.getSeconds(), + TimeUnit.SECONDS, + () -> { + YugabyteDBYCQLWaitStrategy.this.getRateLimiter() + .doWhenReady(() -> { + try { + ExecResult result = container.execInContainer( + BIN_PATH, + "-u", + container.getUsername(), + "-p", + container.getPassword(), + "-k", + container.getKeyspace(), + "-e", + YCQL_TEST_QUERY + ); + if (result.getExitCode() != 0) { + status.set(false); + log.debug(result.getStderr()); + } + } catch (Exception e) { + status.set(false); + log.debug(e.getMessage(), e); + } finally { + if (!status.getAndSet(true)) { + throw new RuntimeException("container hasn't come up yet"); + } + } + }); + return status; + } + ); + } + @Override + public void waitUntilReady() { + waitUntilReady(target); + } } diff --git a/modules/yugabytedb/src/main/java/org/testcontainers/containers/strategy/YugabyteDBYSQLWaitStrategy.java b/modules/yugabytedb/src/main/java/org/testcontainers/containers/strategy/YugabyteDBYSQLWaitStrategy.java index 03d6134123f..31fa52a4155 100644 --- a/modules/yugabytedb/src/main/java/org/testcontainers/containers/strategy/YugabyteDBYSQLWaitStrategy.java +++ b/modules/yugabytedb/src/main/java/org/testcontainers/containers/strategy/YugabyteDBYSQLWaitStrategy.java @@ -1,15 +1,15 @@ package org.testcontainers.containers.strategy; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.concurrent.TimeUnit; - import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.testcontainers.containers.YugabyteDBYSQLContainer; import org.testcontainers.containers.wait.strategy.AbstractWaitStrategy; import org.testcontainers.containers.wait.strategy.WaitStrategyTarget; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.concurrent.TimeUnit; + import static org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess; /** @@ -29,29 +29,32 @@ @Slf4j public final class YugabyteDBYSQLWaitStrategy extends AbstractWaitStrategy { - private static final String YSQL_TEST_QUERY = "SELECT 1"; - - private final WaitStrategyTarget target; - - @Override - public void waitUntilReady(WaitStrategyTarget target) { - YugabyteDBYSQLContainer container = (YugabyteDBYSQLContainer) target; - retryUntilSuccess((int) startupTimeout.getSeconds(), TimeUnit.SECONDS, () -> { - getRateLimiter().doWhenReady(() -> { - try (Connection con = container.createConnection(container.getJdbcUrl())) { - con.createStatement().execute(YSQL_TEST_QUERY); - } - catch (SQLException ex) { - log.error("Error connecting to the database", ex); - } - }); - return true; - }); - } - - @Override - public void waitUntilReady() { - waitUntilReady(target); - } - + private static final String YSQL_TEST_QUERY = "SELECT 1"; + + private final WaitStrategyTarget target; + + @Override + public void waitUntilReady(WaitStrategyTarget target) { + YugabyteDBYSQLContainer container = (YugabyteDBYSQLContainer) target; + retryUntilSuccess( + (int) startupTimeout.getSeconds(), + TimeUnit.SECONDS, + () -> { + getRateLimiter() + .doWhenReady(() -> { + try (Connection con = container.createConnection(container.getJdbcUrl())) { + con.createStatement().execute(YSQL_TEST_QUERY); + } catch (SQLException ex) { + log.error("Error connecting to the database", ex); + } + }); + return true; + } + ); + } + + @Override + public void waitUntilReady() { + waitUntilReady(target); + } } diff --git a/modules/yugabytedb/src/test/java/org/testcontainers/jdbc/yugabytedb/YugabyteDBYSQLJDBCDriverTest.java b/modules/yugabytedb/src/test/java/org/testcontainers/jdbc/yugabytedb/YugabyteDBYSQLJDBCDriverTest.java index 6e3790c92c1..09c0240e7db 100644 --- a/modules/yugabytedb/src/test/java/org/testcontainers/jdbc/yugabytedb/YugabyteDBYSQLJDBCDriverTest.java +++ b/modules/yugabytedb/src/test/java/org/testcontainers/jdbc/yugabytedb/YugabyteDBYSQLJDBCDriverTest.java @@ -1,12 +1,11 @@ package org.testcontainers.jdbc.yugabytedb; -import java.util.EnumSet; - import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.testcontainers.jdbc.AbstractJDBCDriverTest; -import static java.util.Arrays.asList; +import java.util.Arrays; +import java.util.EnumSet; /** * YugabyteDB YSQL API JDBC connectivity driver test class @@ -16,10 +15,15 @@ @RunWith(Parameterized.class) public class YugabyteDBYSQLJDBCDriverTest extends AbstractJDBCDriverTest { - @Parameterized.Parameters(name = "{index} - {0}") - public static Iterable data() { - return asList(new Object[][] { { "jdbc:tc:yugabyte://hostname/yugabyte?user=yugabyte&password=yugabyte", - EnumSet.noneOf(Options.class) }, }); - } - + @Parameterized.Parameters(name = "{index} - {0}") + public static Iterable data() { + return Arrays.asList( + new Object[][] { + { + "jdbc:tc:yugabyte://hostname/yugabyte?user=yugabyte&password=yugabyte", + EnumSet.noneOf(Options.class), + }, + } + ); + } } diff --git a/modules/yugabytedb/src/test/java/org/testcontainers/junit/yugabytedb/YugabyteDBYCQLTest.java b/modules/yugabytedb/src/test/java/org/testcontainers/junit/yugabytedb/YugabyteDBYCQLTest.java index 9e220f8c8fa..021d9a31989 100644 --- a/modules/yugabytedb/src/test/java/org/testcontainers/junit/yugabytedb/YugabyteDBYCQLTest.java +++ b/modules/yugabytedb/src/test/java/org/testcontainers/junit/yugabytedb/YugabyteDBYCQLTest.java @@ -1,13 +1,13 @@ package org.testcontainers.junit.yugabytedb; -import java.net.InetSocketAddress; - import com.datastax.oss.driver.api.core.CqlSession; import com.datastax.oss.driver.api.core.cql.ResultSet; import org.junit.Test; import org.testcontainers.containers.YugabyteDBYCQLContainer; import org.testcontainers.utility.DockerImageName; +import java.net.InetSocketAddress; + import static org.assertj.core.api.Assertions.assertThat; /** @@ -17,82 +17,112 @@ */ public class YugabyteDBYCQLTest { - private static final String IMAGE_NAME = "yugabytedb/yugabyte:2.14.3.1-b1"; + private static final String IMAGE_NAME = "yugabytedb/yugabyte:2.14.3.1-b1"; - private static final DockerImageName YBDB_TEST_IMAGE = DockerImageName.parse(IMAGE_NAME); + private static final DockerImageName YBDB_TEST_IMAGE = DockerImageName.parse(IMAGE_NAME); - private static final String LOCAL_DC = "datacenter1"; + private static final String LOCAL_DC = "datacenter1"; - private static final int YCQL_PORT = 9042; + private static final int YCQL_PORT = 9042; - @Test - public void testSmoke() { - try ( + @Test + public void testSmoke() { + try ( // creatingYCQLContainer { final YugabyteDBYCQLContainer ycqlContainer = new YugabyteDBYCQLContainer(IMAGE_NAME) - // } - ) { - // startingYCQLContainer { - ycqlContainer.start(); - // } - assertThat(performQuery(ycqlContainer, "SELECT release_version FROM system.local").wasApplied()) - .as("A sample test query succeeds").isTrue(); - } - } - - @Test - public void testCustomKeyspace() throws InterruptedException { - String key = "random"; - try (final YugabyteDBYCQLContainer ycqlContainer = new YugabyteDBYCQLContainer(YBDB_TEST_IMAGE) - .withKeyspaceName(key)) { - ycqlContainer.start(); - assertThat(performQuery(ycqlContainer, - "SELECT keyspace_name FROM system_schema.keyspaces where keyspace_name='" + key + "'").one() - .getString(0)).as("Custom keyspace creation succeeds").isEqualTo(key); - } - } + // } + ) { + // startingYCQLContainer { + ycqlContainer.start(); + // } + assertThat(performQuery(ycqlContainer, "SELECT release_version FROM system.local").wasApplied()) + .as("A sample test query succeeds") + .isTrue(); + } + } - @Test - public void testAuthenticationEnabled() throws InterruptedException { - String role = "random"; - try (final YugabyteDBYCQLContainer ycqlContainer = new YugabyteDBYCQLContainer(YBDB_TEST_IMAGE) - .withUsername(role).withPassword(role)) { - ycqlContainer.start(); - assertThat(performQuery(ycqlContainer, "SELECT role FROM system_auth.roles where role='" + role + "'").one() - .getString(0)).as("Keyspace login with authentication enabled succeeds").isEqualTo(role); - } - } + @Test + public void testCustomKeyspace() throws InterruptedException { + String key = "random"; + try ( + final YugabyteDBYCQLContainer ycqlContainer = new YugabyteDBYCQLContainer(YBDB_TEST_IMAGE) + .withKeyspaceName(key) + ) { + ycqlContainer.start(); + assertThat( + performQuery( + ycqlContainer, + "SELECT keyspace_name FROM system_schema.keyspaces where keyspace_name='" + key + "'" + ) + .one() + .getString(0) + ) + .as("Custom keyspace creation succeeds") + .isEqualTo(key); + } + } - @Test - public void testAuthenticationDisabled() { - try (final YugabyteDBYCQLContainer ycqlContainer = new YugabyteDBYCQLContainer(YBDB_TEST_IMAGE).withPassword("") - .withUsername("")) { - ycqlContainer.start(); - assertThat(performQuery(ycqlContainer, "SELECT release_version FROM system.local").wasApplied()) - .as("Keyspace login with authentication disabled succeeds").isTrue(); - } - } + @Test + public void testAuthenticationEnabled() throws InterruptedException { + String role = "random"; + try ( + final YugabyteDBYCQLContainer ycqlContainer = new YugabyteDBYCQLContainer(YBDB_TEST_IMAGE) + .withUsername(role) + .withPassword(role) + ) { + ycqlContainer.start(); + assertThat( + performQuery(ycqlContainer, "SELECT role FROM system_auth.roles where role='" + role + "'") + .one() + .getString(0) + ) + .as("Keyspace login with authentication enabled succeeds") + .isEqualTo(role); + } + } - @Test - public void testInitScript() throws InterruptedException { - String key = "random"; - try (final YugabyteDBYCQLContainer ycqlContainer = new YugabyteDBYCQLContainer(YBDB_TEST_IMAGE) - .withKeyspaceName(key).withUsername(key).withPassword(key).withInitScript("init/init_yql.sql")) { - ycqlContainer.start(); - ResultSet output = performQuery(ycqlContainer, "SELECT greet FROM random.dsql"); - assertThat(output.wasApplied()).as("Statements from a custom script execution succeeds").isTrue(); - assertThat(output.one().getString(0)).as("A record match succeeds").isEqualTo("Hello DSQL"); - } - } + @Test + public void testAuthenticationDisabled() { + try ( + final YugabyteDBYCQLContainer ycqlContainer = new YugabyteDBYCQLContainer(YBDB_TEST_IMAGE) + .withPassword("") + .withUsername("") + ) { + ycqlContainer.start(); + assertThat(performQuery(ycqlContainer, "SELECT release_version FROM system.local").wasApplied()) + .as("Keyspace login with authentication disabled succeeds") + .isTrue(); + } + } - private ResultSet performQuery(YugabyteDBYCQLContainer ycqlContainer, String cql) { - try (CqlSession session = CqlSession.builder().withKeyspace(ycqlContainer.getKeyspace()) - .withAuthCredentials(ycqlContainer.getUsername(), ycqlContainer.getPassword()) - .withLocalDatacenter(LOCAL_DC) - .addContactPoint(new InetSocketAddress(ycqlContainer.getHost(), ycqlContainer.getMappedPort(YCQL_PORT))) - .build()) { - return session.execute(cql); - } - } + @Test + public void testInitScript() throws InterruptedException { + String key = "random"; + try ( + final YugabyteDBYCQLContainer ycqlContainer = new YugabyteDBYCQLContainer(YBDB_TEST_IMAGE) + .withKeyspaceName(key) + .withUsername(key) + .withPassword(key) + .withInitScript("init/init_yql.sql") + ) { + ycqlContainer.start(); + ResultSet output = performQuery(ycqlContainer, "SELECT greet FROM random.dsql"); + assertThat(output.wasApplied()).as("Statements from a custom script execution succeeds").isTrue(); + assertThat(output.one().getString(0)).as("A record match succeeds").isEqualTo("Hello DSQL"); + } + } + private ResultSet performQuery(YugabyteDBYCQLContainer ycqlContainer, String cql) { + try ( + CqlSession session = CqlSession + .builder() + .withKeyspace(ycqlContainer.getKeyspace()) + .withAuthCredentials(ycqlContainer.getUsername(), ycqlContainer.getPassword()) + .withLocalDatacenter(LOCAL_DC) + .addContactPoint(new InetSocketAddress(ycqlContainer.getHost(), ycqlContainer.getMappedPort(YCQL_PORT))) + .build() + ) { + return session.execute(cql); + } + } } diff --git a/modules/yugabytedb/src/test/java/org/testcontainers/junit/yugabytedb/YugabyteDBYSQLTest.java b/modules/yugabytedb/src/test/java/org/testcontainers/junit/yugabytedb/YugabyteDBYSQLTest.java index 701af83cb04..0ea7be6846e 100644 --- a/modules/yugabytedb/src/test/java/org/testcontainers/junit/yugabytedb/YugabyteDBYSQLTest.java +++ b/modules/yugabytedb/src/test/java/org/testcontainers/junit/yugabytedb/YugabyteDBYSQLTest.java @@ -1,12 +1,12 @@ package org.testcontainers.junit.yugabytedb; -import java.sql.SQLException; - import org.junit.Test; import org.testcontainers.containers.YugabyteDBYSQLContainer; import org.testcontainers.db.AbstractContainerDatabaseTest; import org.testcontainers.utility.DockerImageName; +import java.sql.SQLException; + import static org.assertj.core.api.Assertions.assertThat; /** @@ -16,66 +16,83 @@ */ public class YugabyteDBYSQLTest extends AbstractContainerDatabaseTest { - private static final String IMAGE_NAME = "yugabytedb/yugabyte:2.14.3.1-b1"; + private static final String IMAGE_NAME = "yugabytedb/yugabyte:2.14.3.1-b1"; - private static final DockerImageName YBDB_TEST_IMAGE = DockerImageName.parse(IMAGE_NAME); + private static final DockerImageName YBDB_TEST_IMAGE = DockerImageName.parse(IMAGE_NAME); - @Test - public void testSmoke() throws SQLException { - try ( + @Test + public void testSmoke() throws SQLException { + try ( // creatingYSQLContainer { final YugabyteDBYSQLContainer ysqlContainer = new YugabyteDBYSQLContainer(IMAGE_NAME) - // } - ) { - // startingYSQLContainer { - ysqlContainer.start(); - // } - assertThat(performQuery(ysqlContainer, "SELECT 1").getInt(1)).as("A sample test query succeeds") - .isEqualTo(1); - } - } - - @Test - public void testCustomDatabase() throws SQLException { - String key = "random"; - try (final YugabyteDBYSQLContainer ysqlContainer = new YugabyteDBYSQLContainer(YBDB_TEST_IMAGE) - .withDatabaseName(key)) { - ysqlContainer.start(); - assertThat(performQuery(ysqlContainer, "SELECT 1").getInt(1)) - .as("A test query on a custom database succeeds").isEqualTo(1); - } - } + // } + ) { + // startingYSQLContainer { + ysqlContainer.start(); + // } + assertThat(performQuery(ysqlContainer, "SELECT 1").getInt(1)) + .as("A sample test query succeeds") + .isEqualTo(1); + } + } - @Test - public void testInitScript() throws SQLException { - try (final YugabyteDBYSQLContainer ysqlContainer = new YugabyteDBYSQLContainer(YBDB_TEST_IMAGE) - .withInitScript("init/init_yql.sql")) { - ysqlContainer.start(); - assertThat(performQuery(ysqlContainer, "SELECT greet FROM dsql").getString(1)) - .as("A record match succeeds").isEqualTo("Hello DSQL"); - } - } + @Test + public void testCustomDatabase() throws SQLException { + String key = "random"; + try ( + final YugabyteDBYSQLContainer ysqlContainer = new YugabyteDBYSQLContainer(YBDB_TEST_IMAGE) + .withDatabaseName(key) + ) { + ysqlContainer.start(); + assertThat(performQuery(ysqlContainer, "SELECT 1").getInt(1)) + .as("A test query on a custom database succeeds") + .isEqualTo(1); + } + } - @Test - public void testWithAdditionalUrlParamInJdbcUrl() { - try (final YugabyteDBYSQLContainer ysqlContainer = new YugabyteDBYSQLContainer(YBDB_TEST_IMAGE) - .withUrlParam("sslmode", "disable").withUrlParam("application_name", "yugabyte")) { - ysqlContainer.start(); - String jdbcUrl = ysqlContainer.getJdbcUrl(); - assertThat(jdbcUrl).contains("?").contains("&").contains("sslmode=disable") - .contains("application_name=yugabyte") - .as("A JDBC connection string with additional parameter validation succeeds"); - } - } + @Test + public void testInitScript() throws SQLException { + try ( + final YugabyteDBYSQLContainer ysqlContainer = new YugabyteDBYSQLContainer(YBDB_TEST_IMAGE) + .withInitScript("init/init_yql.sql") + ) { + ysqlContainer.start(); + assertThat(performQuery(ysqlContainer, "SELECT greet FROM dsql").getString(1)) + .as("A record match succeeds") + .isEqualTo("Hello DSQL"); + } + } - @Test - public void testWithCustomRole() throws SQLException { - try (final YugabyteDBYSQLContainer ysqlContainer = new YugabyteDBYSQLContainer(YBDB_TEST_IMAGE) - .withDatabaseName("yugabyte").withPassword("yugabyte").withUsername("yugabyte")) { - ysqlContainer.start(); - assertThat(performQuery(ysqlContainer, "SELECT 1").getInt(1)) - .as("A sample test query with a custom role succeeds").isEqualTo(1); - } - } + @Test + public void testWithAdditionalUrlParamInJdbcUrl() { + try ( + final YugabyteDBYSQLContainer ysqlContainer = new YugabyteDBYSQLContainer(YBDB_TEST_IMAGE) + .withUrlParam("sslmode", "disable") + .withUrlParam("application_name", "yugabyte") + ) { + ysqlContainer.start(); + String jdbcUrl = ysqlContainer.getJdbcUrl(); + assertThat(jdbcUrl) + .contains("?") + .contains("&") + .contains("sslmode=disable") + .contains("application_name=yugabyte") + .as("A JDBC connection string with additional parameter validation succeeds"); + } + } + @Test + public void testWithCustomRole() throws SQLException { + try ( + final YugabyteDBYSQLContainer ysqlContainer = new YugabyteDBYSQLContainer(YBDB_TEST_IMAGE) + .withDatabaseName("yugabyte") + .withPassword("yugabyte") + .withUsername("yugabyte") + ) { + ysqlContainer.start(); + assertThat(performQuery(ysqlContainer, "SELECT 1").getInt(1)) + .as("A sample test query with a custom role succeeds") + .isEqualTo(1); + } + } }