use of org.testcontainers.containers.JdbcDatabaseContainer in project testcontainers-java by testcontainers.
the class ContainerDatabaseDriver method killContainer.
/**
* Utility method to kill a database container directly from test support code. It shouldn't be necessary to use this,
* but it is provided for convenience - e.g. for situations where many different database containers are being
* tested and cleanup is needed to limit resource usage.
* @param jdbcUrl the JDBC URL of the container which should be killed
*/
public static void killContainer(String jdbcUrl) {
synchronized (jdbcUrlContainerCache) {
JdbcDatabaseContainer container = jdbcUrlContainerCache.get(jdbcUrl);
if (container != null) {
container.stop();
jdbcUrlContainerCache.remove(jdbcUrl);
containerConnections.remove(container.getContainerId());
initializedContainers.remove(container.getContainerId());
}
}
}
use of org.testcontainers.containers.JdbcDatabaseContainer in project testcontainers-java by testcontainers.
the class ContainerDatabaseDriver method connect.
@Override
public synchronized Connection connect(String url, final Properties info) throws SQLException {
/*
The driver should return "null" if it realizes it is the wrong kind of driver to connect to the given URL.
*/
if (!acceptsURL(url)) {
return null;
}
synchronized (jdbcUrlContainerCache) {
String queryString = "";
/*
If we already have a running container for this exact connection string, we want to connect
to that rather than create a new container
*/
JdbcDatabaseContainer container = jdbcUrlContainerCache.get(url);
if (container == null) {
/*
Extract from the JDBC connection URL:
* The database type (e.g. mysql, postgresql, ...)
* The docker tag, if provided.
* The URL query string, if provided
*/
Matcher urlMatcher = URL_MATCHING_PATTERN.matcher(url);
if (!urlMatcher.matches()) {
throw new IllegalArgumentException("JDBC URL matches jdbc:tc: prefix but the database or tag name could not be identified");
}
String databaseType = urlMatcher.group(1);
String tag = urlMatcher.group(3);
if (tag == null) {
tag = "latest";
}
queryString = urlMatcher.group(4);
if (queryString == null) {
queryString = "";
}
Map<String, String> parameters = getContainerParameters(url);
/*
Find a matching container type using ServiceLoader.
*/
ServiceLoader<JdbcDatabaseContainerProvider> databaseContainers = ServiceLoader.load(JdbcDatabaseContainerProvider.class);
for (JdbcDatabaseContainerProvider candidateContainerType : databaseContainers) {
if (candidateContainerType.supports(databaseType)) {
container = candidateContainerType.newInstance(tag);
delegate = container.getJdbcDriverInstance();
}
}
if (container == null) {
throw new UnsupportedOperationException("Database name " + databaseType + " not supported");
}
/*
Cache the container before starting to prevent race conditions when a connection
pool is started up
*/
jdbcUrlContainerCache.put(url, container);
/*
Pass possible container-specific parameters
*/
container.setParameters(parameters);
/*
Start the container
*/
container.start();
}
/*
Create a connection using the delegated driver. The container must be ready to accept connections.
*/
Connection connection = container.createConnection(queryString);
/*
If this container has not been initialized, AND
an init script or function has been specified, use it
*/
if (!initializedContainers.contains(container.getContainerId())) {
DatabaseDelegate databaseDelegate = new JdbcDatabaseDelegate(container);
runInitScriptIfRequired(url, databaseDelegate);
runInitFunctionIfRequired(url, connection);
initializedContainers.add(container.getContainerId());
}
return wrapConnection(connection, container, url);
}
}
use of org.testcontainers.containers.JdbcDatabaseContainer in project kork by spinnaker.
the class SqlTestUtil method initDualTcDatabases.
private static TestDatabase initDualTcDatabases(String imageName, SQLDialect dialect) {
JdbcDatabaseContainer container;
String rootUser;
String grantCommand;
switch(dialect) {
case MYSQL:
container = new MySQLContainer(imageName);
rootUser = "root";
grantCommand = "grant all privileges on previous.* to 'test'@'%'";
break;
case POSTGRES:
container = new PostgreSQLContainer(imageName);
// Testcontainers sets the PG superuser credentials to the container user/pass
// Since we're always superuser, we also don't need grants
rootUser = "test";
grantCommand = null;
break;
default:
throw new RuntimeException("Unsupported SQL dialect: " + dialect.getName());
}
container = container.withDatabaseName("current").withUsername("test").withPassword("test");
container.start();
// PostgreSQLContainer has a default query param already added to the JDBC URL
String queryStart = container.getJdbcUrl().contains("?") ? "&" : "?";
String rootJdbcUrl = String.format("%s%suser=%s&password=%s", container.getJdbcUrl(), queryStart, rootUser, container.getPassword());
try {
Connection rootCon = DriverManager.getConnection(rootJdbcUrl);
rootCon.createStatement().executeUpdate("create database previous");
if (grantCommand != null) {
rootCon.createStatement().executeUpdate(grantCommand);
}
rootCon.close();
} catch (SQLException e) {
throw new RuntimeException("Error setting up testcontainer database", e);
}
String currentJdbcUrl = String.format("%s%suser=%s&password=%s", container.getJdbcUrl(), queryStart, container.getUsername(), container.getPassword());
String previousJdbcUrl = currentJdbcUrl.replace("/current", "/previous");
TestDatabase currentTDB = initDatabase(currentJdbcUrl, dialect, "current");
TestDatabase previousTDB = initDatabase(previousJdbcUrl, dialect, "previous");
return new TestDatabase(currentTDB.dataSource, currentTDB.context, currentTDB.liquibase, previousTDB.dataSource, previousTDB.context, previousTDB.liquibase);
}
Aggregations