Skip to content

Commit

Permalink
update assertj and removed cassandra driver dependency
Browse files Browse the repository at this point in the history
Signed-off-by: Srinivasa Vasu <srinivasan.surprise@gmail.com>
  • Loading branch information
srinivasa-vasu committed Oct 23, 2022
1 parent 2c27755 commit dba2a50
Show file tree
Hide file tree
Showing 11 changed files with 111 additions and 88 deletions.
1 change: 0 additions & 1 deletion modules/yugabytedb/build.gradle
Expand Up @@ -4,7 +4,6 @@ dependencies {
api project(':jdbc')
testImplementation project(':jdbc-test')
// YCQL driver
compileOnly 'com.yugabyte:java-driver-core:4.6.0-yb-11'
testImplementation 'com.yugabyte:java-driver-core:4.6.0-yb-11'
// YSQL driver
testImplementation 'com.yugabyte:jdbc-yugabytedb:42.3.4'
Expand Down

This file was deleted.

Expand Up @@ -27,7 +27,7 @@ public class YugabyteDBYCQLContainer extends GenericContainer<YugabyteDBYCQLCont

private static final Integer TSERVER_DASHBOARD_PORT = 9000;

private static final String ENTRYPOINT = "bin/yugabyted start --daemon=false";
private static final String ENTRYPOINT = "bin/yugabyted start --background=false";

private static final String LOCAL_DC = "datacenter1";

Expand Down
Expand Up @@ -29,7 +29,7 @@ public class YugabyteDBYSQLContainer extends JdbcDatabaseContainer<YugabyteDBYSQ

private static final String JDBC_CONNECT_PREFIX = "jdbc:yugabytedb";

private static final String ENTRYPOINT = "bin/yugabyted start --daemon=false";
private static final String ENTRYPOINT = "bin/yugabyted start --background=false";

private String database = "yugabyte";

Expand Down
Expand Up @@ -12,7 +12,7 @@ public class YugabyteDBYSQLContainerProvider extends JdbcDatabaseContainerProvid

private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("yugabytedb/yugabyte");

private static final String DEFAULT_TAG = "2.14.0.0-b94";
private static final String DEFAULT_TAG = "2.14.3.1-b1";

private static final String NAME = "yugabyte";

Expand Down
@@ -0,0 +1,23 @@
package org.testcontainers.containers.delegate;

import org.testcontainers.delegate.DatabaseDelegate;

/**
* An abstract delegate do-nothing class
*
* @author srinivasa-vasu
*/
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
}

}
@@ -1,37 +1,45 @@
package org.testcontainers.containers.delegate;

import com.datastax.oss.driver.api.core.CqlSession;
import java.util.Collection;

import lombok.RequiredArgsConstructor;
import org.testcontainers.containers.YCQLSessionDelegate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.testcontainers.containers.Container.ExecResult;
import org.testcontainers.containers.YugabyteDBYCQLContainer;
import org.testcontainers.delegate.AbstractDatabaseDelegate;
import org.testcontainers.ext.ScriptUtils.UncategorizedScriptException;

/**
* Query execution delegate class for YCQL API to delegate init-scripts statements.
* Query execution delegate class for YCQL API to delegate init-script statements. This
* invokes the in-built <code>ycqlsh</code> cli within the container to execute the
* statements at one go. It is recommended to use frameworks such as liquibase to manage
* this requirement. This functionality is kept to address the initialization requirements
* from standalone services that can't leverage liquibase or something similar.
*
* @author srinivasa-vasu
* @see YugabyteDBYCQLContainer
*/
@RequiredArgsConstructor
public final class YugabyteDBYCQLDelegate extends AbstractDatabaseDelegate<CqlSession> implements YCQLSessionDelegate {
@Slf4j
public final class YugabyteDBYCQLDelegate extends AbstractYCQLDelegate {

private final YugabyteDBYCQLContainer container;
private static final String BIN_PATH = "/home/yugabyte/tserver/bin/ycqlsh";

@Override
protected CqlSession createNewConnection() {
return builder(container);
}
private final YugabyteDBYCQLContainer container;

@Override
public void execute(String statement, String scriptPath, int lineNumber, boolean continueOnError,
public void execute(Collection<String> statements, String scriptPath, boolean continueOnError,
boolean ignoreFailedDrops) {
getConnection().execute(statement);
}

@Override
protected void closeConnectionQuietly(CqlSession session) {
if (session != null) {
session.close();
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);
}
}

Expand Down
@@ -1,10 +1,11 @@
package org.testcontainers.containers.strategy;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import com.datastax.oss.driver.api.core.CqlSession;
import lombok.RequiredArgsConstructor;
import org.testcontainers.containers.YCQLSessionDelegate;
import lombok.extern.slf4j.Slf4j;
import org.testcontainers.containers.Container.ExecResult;
import org.testcontainers.containers.YugabyteDBYCQLContainer;
import org.testcontainers.containers.wait.strategy.AbstractWaitStrategy;
import org.testcontainers.containers.wait.strategy.WaitStrategyTarget;
Expand All @@ -25,22 +26,40 @@
* @author srinivasa-vasu
*/
@RequiredArgsConstructor
public final class YugabyteDBYCQLWaitStrategy extends AbstractWaitStrategy implements YCQLSessionDelegate {
@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 final WaitStrategyTarget target;

@Override
public void waitUntilReady(WaitStrategyTarget target) {
YugabyteDBYCQLContainer container = (YugabyteDBYCQLContainer) target;
AtomicBoolean status = new AtomicBoolean(true);
retryUntilSuccess((int) startupTimeout.getSeconds(), TimeUnit.SECONDS, () -> {
getRateLimiter().doWhenReady(() -> {
try (CqlSession session = builder(container)) {
session.execute(YCQL_TEST_QUERY);
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 true;
return status;
});
}

Expand Down
Expand Up @@ -4,19 +4,20 @@

import com.datastax.oss.driver.api.core.CqlSession;
import com.datastax.oss.driver.api.core.cql.ResultSet;
import org.junit.Assert;
import org.junit.Test;
import org.testcontainers.containers.YugabyteDBYCQLContainer;
import org.testcontainers.utility.DockerImageName;

import static org.assertj.core.api.Assertions.assertThat;

/**
* YugabyteDB YCQL API unit test class
*
* @author srinivasa-vasu
*/
public class YugabyteDBYCQLTest {

private static final String IMAGE_NAME = "yugabytedb/yugabyte:2.14.0.0-b94";
private static final String IMAGE_NAME = "yugabytedb/yugabyte:2.14.3.1-b1";

private static final DockerImageName YBDB_TEST_IMAGE = DockerImageName.parse(IMAGE_NAME);

Expand All @@ -34,8 +35,8 @@ public void testSmoke() {
// startingYCQLContainer {
ycqlContainer.start();
// }
Assert.assertNotNull("Smoke test simple query execution fails!",
performQuery(ycqlContainer, "SELECT release_version FROM system.local").one().getString(0));
assertThat(performQuery(ycqlContainer, "SELECT release_version FROM system.local").wasApplied())
.as("A sample test query succeeds").isTrue();
}
}

Expand All @@ -45,10 +46,9 @@ public void testCustomKeyspace() throws InterruptedException {
try (final YugabyteDBYCQLContainer ycqlContainer = new YugabyteDBYCQLContainer(YBDB_TEST_IMAGE)
.withKeyspaceName(key)) {
ycqlContainer.start();
Assert.assertEquals("Custom keyspace creation fails!", key,
performQuery(ycqlContainer,
"SELECT keyspace_name FROM system_schema.keyspaces where keyspace_name='" + key + "'").one()
.getString(0));
assertThat(performQuery(ycqlContainer,
"SELECT keyspace_name FROM system_schema.keyspaces where keyspace_name='" + key + "'").one()
.getString(0)).as("Custom keyspace creation succeeds").isEqualTo(key);
}
}

Expand All @@ -58,9 +58,8 @@ public void testAuthenticationEnabled() throws InterruptedException {
try (final YugabyteDBYCQLContainer ycqlContainer = new YugabyteDBYCQLContainer(YBDB_TEST_IMAGE)
.withUsername(role).withPassword(role)) {
ycqlContainer.start();
Assert.assertEquals("Keyspace login fails with authentication enabled!", role,
performQuery(ycqlContainer, "SELECT role FROM system_auth.roles where role='" + role + "'").one()
.getString(0));
assertThat(performQuery(ycqlContainer, "SELECT role FROM system_auth.roles where role='" + role + "'").one()
.getString(0)).as("Keyspace login with authentication enabled succeeds").isEqualTo(role);
}
}

Expand All @@ -69,8 +68,8 @@ public void testAuthenticationDisabled() {
try (final YugabyteDBYCQLContainer ycqlContainer = new YugabyteDBYCQLContainer(YBDB_TEST_IMAGE).withPassword("")
.withUsername("")) {
ycqlContainer.start();
Assert.assertTrue("Query execution fails!",
performQuery(ycqlContainer, "SELECT release_version FROM system.local").wasApplied());
assertThat(performQuery(ycqlContainer, "SELECT release_version FROM system.local").wasApplied())
.as("Keyspace login with authentication disabled succeeds").isTrue();
}
}

Expand All @@ -80,8 +79,9 @@ public void testInitScript() throws InterruptedException {
try (final YugabyteDBYCQLContainer ycqlContainer = new YugabyteDBYCQLContainer(YBDB_TEST_IMAGE)
.withKeyspaceName(key).withUsername(key).withPassword(key).withInitScript("init/init_yql.sql")) {
ycqlContainer.start();
Assert.assertTrue("Query execution fails to execute statements from a custom script!",
performQuery(ycqlContainer, "SELECT * FROM random.bar").wasApplied());
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");
}
}

Expand Down
Expand Up @@ -2,22 +2,21 @@

import java.sql.SQLException;

import org.hamcrest.CoreMatchers;
import org.hamcrest.MatcherAssert;
import org.junit.Assert;
import org.junit.Test;
import org.testcontainers.containers.YugabyteDBYSQLContainer;
import org.testcontainers.db.AbstractContainerDatabaseTest;
import org.testcontainers.utility.DockerImageName;

import static org.assertj.core.api.Assertions.assertThat;

/**
* YugabyteDB YSQL API unit test class
*
* @author srinivasa-vasu
*/
public class YugabyteDBYSQLTest extends AbstractContainerDatabaseTest {

private static final String IMAGE_NAME = "yugabytedb/yugabyte:2.14.0.0-b94";
private static final String IMAGE_NAME = "yugabytedb/yugabyte:2.14.3.1-b1";

private static final DockerImageName YBDB_TEST_IMAGE = DockerImageName.parse(IMAGE_NAME);

Expand All @@ -31,7 +30,8 @@ public void testSmoke() throws SQLException {
// startingYSQLContainer {
ysqlContainer.start();
// }
Assert.assertEquals("Query execution fails!", 1, performQuery(ysqlContainer, "SELECT 1").getInt(1));
assertThat(performQuery(ysqlContainer, "SELECT 1").getInt(1)).as("A sample test query succeeds")
.isEqualTo(1);
}
}

Expand All @@ -41,18 +41,18 @@ public void testCustomDatabase() throws SQLException {
try (final YugabyteDBYSQLContainer ysqlContainer = new YugabyteDBYSQLContainer(YBDB_TEST_IMAGE)
.withDatabaseName(key)) {
ysqlContainer.start();
Assert.assertEquals("Query execution on a custom database fails!", 1,
performQuery(ysqlContainer, "SELECT 1").getInt(1));
assertThat(performQuery(ysqlContainer, "SELECT 1").getInt(1))
.as("A test query on a custom database succeeds").isEqualTo(1);
}
}

@Test
public void testExplicitInitScript() throws SQLException {
public void testInitScript() throws SQLException {
try (final YugabyteDBYSQLContainer ysqlContainer = new YugabyteDBYSQLContainer(YBDB_TEST_IMAGE)
.withInitScript("init/init_yql.sql")) {
ysqlContainer.start();
Assert.assertEquals("Value from the init script does not match the real value", "hello world",
performQuery(ysqlContainer, "SELECT foo FROM bar").getString(1));
assertThat(performQuery(ysqlContainer, "SELECT greet FROM dsql").getString(1))
.as("A record match succeeds").isEqualTo("Hello DSQL");
}
}

Expand All @@ -62,10 +62,9 @@ public void testWithAdditionalUrlParamInJdbcUrl() {
.withUrlParam("sslmode", "disable").withUrlParam("application_name", "yugabyte")) {
ysqlContainer.start();
String jdbcUrl = ysqlContainer.getJdbcUrl();
MatcherAssert.assertThat(jdbcUrl, CoreMatchers.containsString("?"));
MatcherAssert.assertThat(jdbcUrl, CoreMatchers.containsString("&"));
MatcherAssert.assertThat(jdbcUrl, CoreMatchers.containsString("sslmode=disable"));
MatcherAssert.assertThat(jdbcUrl, CoreMatchers.containsString("application_name=yugabyte"));
assertThat(jdbcUrl).contains("?").contains("&").contains("sslmode=disable")
.contains("application_name=yugabyte")
.as("A JDBC connection string with additional parameter validation succeeds");
}
}

Expand All @@ -74,8 +73,8 @@ public void testWithCustomRole() throws SQLException {
try (final YugabyteDBYSQLContainer ysqlContainer = new YugabyteDBYSQLContainer(YBDB_TEST_IMAGE)
.withDatabaseName("yugabyte").withPassword("yugabyte").withUsername("yugabyte")) {
ysqlContainer.start();
Assert.assertEquals("Query execution with a custom role fails!", 1,
performQuery(ysqlContainer, "SELECT 1").getInt(1));
assertThat(performQuery(ysqlContainer, "SELECT 1").getInt(1))
.as("A sample test query with a custom role succeeds").isEqualTo(1);
}
}

Expand Down
6 changes: 3 additions & 3 deletions modules/yugabytedb/src/test/resources/init/init_yql.sql
@@ -1,5 +1,5 @@
CREATE TABLE bar(
foo text primary key
CREATE TABLE dsql(
greet text primary key
);

INSERT INTO bar (foo) VALUES ('hello world');
INSERT INTO dsql (greet) VALUES ('Hello DSQL');

0 comments on commit dba2a50

Please sign in to comment.