Search in sources :

Example 1 with JdbcDatabaseContainer

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());
        }
    }
}
Also used : JdbcDatabaseContainer(org.testcontainers.containers.JdbcDatabaseContainer)

Example 2 with JdbcDatabaseContainer

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);
    }
}
Also used : JdbcDatabaseContainerProvider(org.testcontainers.containers.JdbcDatabaseContainerProvider) Matcher(java.util.regex.Matcher) JdbcDatabaseContainer(org.testcontainers.containers.JdbcDatabaseContainer) DatabaseDelegate(org.testcontainers.delegate.DatabaseDelegate)

Example 3 with JdbcDatabaseContainer

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);
}
Also used : SQLException(java.sql.SQLException) JdbcDatabaseContainer(org.testcontainers.containers.JdbcDatabaseContainer) MySQLContainer(org.testcontainers.containers.MySQLContainer) PostgreSQLContainer(org.testcontainers.containers.PostgreSQLContainer) Connection(java.sql.Connection) JdbcConnection(liquibase.database.jvm.JdbcConnection)

Aggregations

JdbcDatabaseContainer (org.testcontainers.containers.JdbcDatabaseContainer)3 Connection (java.sql.Connection)1 SQLException (java.sql.SQLException)1 Matcher (java.util.regex.Matcher)1 JdbcConnection (liquibase.database.jvm.JdbcConnection)1 JdbcDatabaseContainerProvider (org.testcontainers.containers.JdbcDatabaseContainerProvider)1 MySQLContainer (org.testcontainers.containers.MySQLContainer)1 PostgreSQLContainer (org.testcontainers.containers.PostgreSQLContainer)1 DatabaseDelegate (org.testcontainers.delegate.DatabaseDelegate)1