Skip to content

Commit

Permalink
Use two variants, one with CrateDB driver, one with PGSQL
Browse files Browse the repository at this point in the history
  • Loading branch information
matriv committed Mar 20, 2023
1 parent 7106326 commit b4ba30e
Show file tree
Hide file tree
Showing 11 changed files with 237 additions and 6 deletions.
1 change: 1 addition & 0 deletions docs/modules/databases/cratedb.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ Add the following dependency to your `pom.xml`/`build.gradle` file:

!!! hint
Adding this Testcontainers library JAR will not automatically add a database driver JAR to your project. You should ensure that your project also has a suitable database driver as a dependency.
If you'd like to use the PostgreSQL JDBC Driver, use `org.postgresql:postgresql`, if you'd like to use CrateDB's JDBC driver, use `io.crate:crate-jdbc`.


2 changes: 1 addition & 1 deletion docs/modules/databases/jdbc.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Insert `tc:` after `jdbc:` as follows. Note that the hostname, port and database

#### Using CrateDB

`jdbc:tc:crate:5.2.3//localhost:5432/crate`
`jdbc:tc:cratedb:5.2.3//localhost:5432/crate` or `jdbc:tc:cratedbcustom:5.2.3//localhost:5432/crate`

#### Using PostgreSQL

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class CrateDBContainer<SELF extends CrateDBContainer<SELF>> extends JdbcD

public static final String DEFAULT_TAG = "latest";

private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("crate");
protected static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("crate");

public static final Integer CRATEDB_PG_PORT = 5432;

Expand Down Expand Up @@ -61,14 +61,14 @@ protected Set<Integer> getLivenessCheckPorts() {

@Override
public String getDriverClassName() {
return "io.crate.client.jdbc.CrateDriver";
return "org.postgresql.Driver";
}

@Override
public String getJdbcUrl() {
String additionalUrlParams = constructUrlParameters("?", "&");
return (
"jdbc:crate://" +
"jdbc:postgresql://" +
getHost() +
":" +
getMappedPort(CRATEDB_PG_PORT) +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import org.testcontainers.utility.DockerImageName;

/**
* Factory for CrateDB containers using its JDBC driver.
* Factory for CrateDB containers using PostgreSQL JDBC driver.
*/
public class CrateDBContainerProvider extends JdbcDatabaseContainerProvider {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.testcontainers.containers;

import org.testcontainers.utility.DockerImageName;

public class CrateDBCustomDriverContainer<SELF extends CrateDBContainer<SELF>> extends CrateDBContainer<SELF> {

public static final String NAME = "cratedbcustom";

public CrateDBCustomDriverContainer(final DockerImageName dockerImageName) {
super(dockerImageName);
}

@Override
public String getDriverClassName() {
return "io.crate.client.jdbc.CrateDriver";
}

@Override
public String getJdbcUrl() {
String additionalUrlParams = constructUrlParameters("?", "&");
return (
"jdbc:crate://" +
getHost() +
":" +
getMappedPort(CRATEDB_PG_PORT) +
"/" +
getDatabaseName() +
additionalUrlParams
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.testcontainers.containers;

import org.testcontainers.jdbc.ConnectionUrl;
import org.testcontainers.utility.DockerImageName;

/**
* Factory for CrateDB containers using its own JDBC driver.
*/
public class CrateDBCustomDriverContainerProvider extends JdbcDatabaseContainerProvider {

public static final String USER_PARAM = "user";

public static final String PASSWORD_PARAM = "password";

@Override
public boolean supports(String databaseType) {
return databaseType.equals(CrateDBCustomDriverContainer.NAME);
}

@Override
public JdbcDatabaseContainer newInstance() {
return newInstance(CrateDBContainer.DEFAULT_TAG);
}

@Override
public JdbcDatabaseContainer newInstance(String tag) {
return new CrateDBCustomDriverContainer(DockerImageName.parse(CrateDBContainer.IMAGE).withTag(tag));
}

@Override
public JdbcDatabaseContainer newInstance(ConnectionUrl connectionUrl) {
return newInstanceFromConnectionUrl(connectionUrl, USER_PARAM, PASSWORD_PARAM);
}
}
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
org.testcontainers.containers.CrateDBContainerProvider
org.testcontainers.containers.CrateDBCustomDriverContainerProvider
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public NoParamsUrlCrateDBContainer() {

@Override
public String getJdbcUrl() {
return "jdbc:crate://host:port/database";
return "jdbc:postgresql://host:port/database";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package org.testcontainers.containers;

import org.junit.Test;
import org.testcontainers.CrateDBTestImages;

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

public class CrateDBCustomDriverConnectionURLTest {

@Test
public void shouldCorrectlyAppendQueryString() {
CrateDBContainer<?> cratedb = new FixedJdbcUrlCrateDBContainer();
String connectionUrl = cratedb.constructUrlForConnection("?stringtype=unspecified&stringtype=unspecified");
String queryString = connectionUrl.substring(connectionUrl.indexOf('?'));

assertThat(queryString)
.as("Query String contains expected params")
.contains("?stringtype=unspecified&stringtype=unspecified");
assertThat(queryString.indexOf('?')).as("Query String starts with '?'").isZero();
assertThat(queryString.substring(1)).as("Query String does not contain extra '?'").doesNotContain("?");
}

@Test
public void shouldCorrectlyAppendQueryStringWhenNoBaseParams() {
CrateDBContainer<?> cratedb = new NoParamsUrlCrateDBContainer();
String connectionUrl = cratedb.constructUrlForConnection("?stringtype=unspecified&stringtype=unspecified");
String queryString = connectionUrl.substring(connectionUrl.indexOf('?'));

assertThat(queryString)
.as("Query String contains expected params")
.contains("?stringtype=unspecified&stringtype=unspecified");
assertThat(queryString.indexOf('?')).as("Query String starts with '?'").isZero();
assertThat(queryString.substring(1)).as("Query String does not contain extra '?'").doesNotContain("?");
}

@Test
public void shouldReturnOriginalURLWhenEmptyQueryString() {
CrateDBContainer<?> cratedb = new FixedJdbcUrlCrateDBContainer();
String connectionUrl = cratedb.constructUrlForConnection("");

assertThat(cratedb.getJdbcUrl()).as("Query String remains unchanged").isEqualTo(connectionUrl);
}

@Test
public void shouldRejectInvalidQueryString() {
assertThat(
catchThrowable(() -> {
new NoParamsUrlCrateDBContainer().constructUrlForConnection("stringtype=unspecified");
})
)
.as("Fails when invalid query string provided")
.isInstanceOf(IllegalArgumentException.class);
}

static class FixedJdbcUrlCrateDBContainer extends CrateDBCustomDriverContainer<FixedJdbcUrlCrateDBContainer> {

public FixedJdbcUrlCrateDBContainer() {
super(CrateDBTestImages.CRATEDB_TEST_IMAGE);
}

@Override
public String getHost() {
return "localhost";
}

@Override
public Integer getMappedPort(int originalPort) {
return 5432;
}
}

static class NoParamsUrlCrateDBContainer extends CrateDBCustomDriverContainer<FixedJdbcUrlCrateDBContainer> {

public NoParamsUrlCrateDBContainer() {
super(CrateDBTestImages.CRATEDB_TEST_IMAGE);
}

@Override
public String getJdbcUrl() {
return "jdbc:crate://host:port/database";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ public static Iterable<Object[]> data() {
return Arrays.asList(
new Object[][] {
{ "jdbc:tc:cratedb:5.2.3://hostname/crate?user=crate&password=somepwd", EnumSet.noneOf(Options.class) },
{
"jdbc:tc:cratedbcustom:5.2.3://hostname/crate?user=crate&password=somepwd",
EnumSet.noneOf(Options.class),
},
}
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package org.testcontainers.junit.cratedb;

import org.junit.Test;
import org.testcontainers.CrateDBTestImages;
import org.testcontainers.containers.CrateDBContainer;
import org.testcontainers.containers.CrateDBCustomDriverContainer;
import org.testcontainers.db.AbstractContainerDatabaseTest;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.LogManager;

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

public class SimpleCrateDBCustomDriverTest extends AbstractContainerDatabaseTest {
static {
// Postgres JDBC driver uses JUL; disable it to avoid annoying, irrelevant, stderr logs during connection testing
LogManager.getLogManager().getLogger("").setLevel(Level.OFF);
}

@Test
public void testSimple() throws SQLException {
try (
CrateDBCustomDriverContainer cratedb = new CrateDBCustomDriverContainer<>(
CrateDBTestImages.CRATEDB_TEST_IMAGE
)
) {
cratedb.start();

ResultSet resultSet = performQuery(cratedb, "SELECT 1");
int resultSetInt = resultSet.getInt(1);
assertThat(resultSetInt).as("A basic SELECT query succeeds").isEqualTo(1);
assertHasCorrectExposedAndLivenessCheckPorts(cratedb);
}
}

@Test
public void testCommandOverride() throws SQLException {
try (
CrateDBContainer<?> cratedb = new CrateDBCustomDriverContainer<>(CrateDBTestImages.CRATEDB_TEST_IMAGE)
.withCommand("crate -C cluster.name=testcontainers")
) {
cratedb.start();

ResultSet resultSet = performQuery(cratedb, "select name from sys.cluster");
String result = resultSet.getString(1);
assertThat(result).as("cluster name should be overriden").isEqualTo("testcontainers");
}
}

@Test
public void testExplicitInitScript() throws SQLException {
try (
CrateDBContainer<?> cratedb = new CrateDBCustomDriverContainer<>(CrateDBTestImages.CRATEDB_TEST_IMAGE)
.withInitScript("somepath/init_cratedb.sql")
) {
cratedb.start();

ResultSet resultSet = performQuery(cratedb, "SELECT foo FROM bar");

String firstColumnValue = resultSet.getString(1);
assertThat(firstColumnValue).as("Value from init script should equal real value").isEqualTo("hello world");
}
}

private void assertHasCorrectExposedAndLivenessCheckPorts(CrateDBCustomDriverContainer<?> cratedb) {
assertThat(cratedb.getExposedPorts())
.containsExactly(CrateDBContainer.CRATEDB_PG_PORT, CrateDBContainer.CRATEDB_HTTP_PORT);
assertThat(cratedb.getLivenessCheckPortNumbers())
.containsExactlyInAnyOrder(
cratedb.getMappedPort(CrateDBContainer.CRATEDB_PG_PORT),
cratedb.getMappedPort(CrateDBContainer.CRATEDB_HTTP_PORT)
);
}
}

0 comments on commit b4ba30e

Please sign in to comment.