Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct testcontainers for use with latest MySQL 8.3 version #8131

Merged
merged 5 commits into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/src/test/resources/compose-test.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
redis:
image: redis
db:
image: mysql:5.7.34
image: mysql:8.0.36
environment:
MYSQL_RANDOM_ROOT_PASSWORD: "true"
2 changes: 1 addition & 1 deletion core/src/test/resources/composev2/compose-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ services:
redis:
image: redis
db:
image: mysql:8.0.33
image: mysql:8.0.36
environment:
MYSQL_RANDOM_ROOT_PASSWORD: "true"
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ public void simpleExample() {
try (
// spotless:off
// directDockerHubReference {
// Referring directly to an image on Docker Hub (mysql:8.0.24)
// Referring directly to an image on Docker Hub (mysql:8.0.36)
final MySQLContainer<?> mysql = new MySQLContainer<>(
DockerImageName.parse("mysql:8.0.24")
DockerImageName.parse("mysql:8.0.36")
)
// start the container and use it for testing
// }
Expand All @@ -36,7 +36,7 @@ public void substitutedExample() {
// hardcodedMirror {
// Referring directly to an image on a private registry - image name will vary
final MySQLContainer<?> mysql = new MySQLContainer<>(
DockerImageName.parse("registry.mycompany.com/mirror/mysql:8.0.24")
DockerImageName.parse("registry.mycompany.com/mirror/mysql:8.0.36")
.asCompatibleSubstituteFor("mysql")
)
// start the container and use it for testing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class TestSpecificImageNameSubstitutor extends ImageNameSubstitutor {

@Override
public DockerImageName apply(final DockerImageName original) {
if (original.equals(DockerImageName.parse("registry.mycompany.com/mirror/mysql:8.0.24"))) {
if (original.equals(DockerImageName.parse("registry.mycompany.com/mirror/mysql:8.0.36"))) {
return DockerImageName.parse("mysql");
} else {
return original;
Expand Down
2 changes: 1 addition & 1 deletion docs/features/image_name_substitution.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Consider this if:

* Developers and CI machines need to use different image names. For example, developers are able to pull images from Docker Hub, but CI machines need to pull from a private registry
* Your private registry has copies of images from Docker Hub where the names are predictable, and just adding a prefix is enough.
For example, `registry.mycompany.com/mirror/mysql:8.0.24` can be derived from the original Docker Hub image name (`mysql:8.0.24`) with a consistent prefix string: `registry.mycompany.com/mirror/`
For example, `registry.mycompany.com/mirror/mysql:8.0.36` can be derived from the original Docker Hub image name (`mysql:8.0.36`) with a consistent prefix string: `registry.mycompany.com/mirror/`

In this case, image name references in code are **unchanged**.
i.e. you would leave as-is:
Expand Down
2 changes: 1 addition & 1 deletion docs/features/reuse.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ GenericContainer container = new GenericContainer("redis:6-alpine")
### Reusable Container with Testcontainers JDBC URL

If using the [Testcontainers JDBC URL support](../../modules/databases/jdbc#database-containers-launched-via-jdbc-url-scheme)
the URL **must** follow the pattern of `jdbc:tc:mysql:5.7.34:///databasename?TC_REUSABLE=true`.
the URL **must** follow the pattern of `jdbc:tc:mysql:8.0.36:///databasename?TC_REUSABLE=true`.
`TC_REUSABLE=true` is set as a parameter of the JDBC URL.
14 changes: 7 additions & 7 deletions docs/modules/databases/jdbc.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Insert `tc:` after `jdbc:` as follows. Note that the hostname, port and database

!!! note
We will use `///` (host-less URIs) from now on to emphasis the unimportance of the `host:port` pair.
From Testcontainers' perspective, `jdbc:mysql:5.7.34://localhost:3306/databasename` and `jdbc:mysql:5.7.34:///databasename` is the same URI.
From Testcontainers' perspective, `jdbc:mysql:8.0.36://localhost:3306/databasename` and `jdbc:mysql:8.0.36:///databasename` is the same URI.

!!! warning
If you're using the JDBC URL support, there is no need to instantiate an instance of the container - Testcontainers will do it automagically.
Expand All @@ -45,11 +45,11 @@ Insert `tc:` after `jdbc:` as follows. Note that the hostname, port and database

#### Using MariaDB

`jdbc:tc:mariadb:10.2.14:///databasename`
`jdbc:tc:mariadb:10.3.39:///databasename`

#### Using MySQL

`jdbc:tc:mysql:5.7.34:///databasename`
`jdbc:tc:mysql:8.0.36:///databasename`

#### Using MSSQL Server

Expand Down Expand Up @@ -92,21 +92,21 @@ Insert `tc:` after `jdbc:` as follows. Note that the hostname, port and database

Testcontainers can run an init script after the database container is started, but before your code is given a connection to it. The script must be on the classpath, and is referenced as follows:

`jdbc:tc:mysql:5.7.34:///databasename?TC_INITSCRIPT=somepath/init_mysql.sql`
`jdbc:tc:mysql:8.0.36:///databasename?TC_INITSCRIPT=somepath/init_mysql.sql`

This is useful if you have a fixed script for setting up database schema, etc.

### Using an init script from a file

If the init script path is prefixed `file:`, it will be loaded from a file (relative to the working directory, which will usually be the project root).

`jdbc:tc:mysql:5.7.34:///databasename?TC_INITSCRIPT=file:src/main/resources/init_mysql.sql`
`jdbc:tc:mysql:8.0.36:///databasename?TC_INITSCRIPT=file:src/main/resources/init_mysql.sql`

### Using an init function

Instead of running a fixed script for DB setup, it may be useful to call a Java function that you define. This is intended to allow you to trigger database schema migration tools. To do this, add TC_INITFUNCTION to the URL as follows, passing a full path to the class name and method:

`jdbc:tc:mysql:5.7.34:///databasename?TC_INITFUNCTION=org.testcontainers.jdbc.JDBCDriverTest::sampleInitFunction`
`jdbc:tc:mysql:8.0.36:///databasename?TC_INITFUNCTION=org.testcontainers.jdbc.JDBCDriverTest::sampleInitFunction`

The init function must be a public static method which takes a `java.sql.Connection` as its only parameter, e.g.
```java
Expand All @@ -121,7 +121,7 @@ public class JDBCDriverTest {

By default database container is being stopped as soon as last connection is closed. There are cases when you might need to start container and keep it running till you stop it explicitly or JVM is shutdown. To do this, add `TC_DAEMON` parameter to the URL as follows:

`jdbc:tc:mysql:5.7.34:///databasename?TC_DAEMON=true`
`jdbc:tc:mysql:8.0.36:///databasename?TC_DAEMON=true`

With this parameter database container will keep running even when there're no open connections.

Expand Down
2 changes: 1 addition & 1 deletion docs/modules/databases/mysql.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ See [Database containers](./index.md) for documentation and usage that is common
For MySQL databases, it is possible to override configuration settings using resources on the classpath. Assuming `somepath/mysql_conf_override`
is a directory on the classpath containing .cnf files, the following URL can be used:

`jdbc:tc:mysql:5.7.34://hostname/databasename?TC_MY_CNF=somepath/mysql_conf_override`
`jdbc:tc:mysql:8.0.36://hostname/databasename?TC_MY_CNF=somepath/mysql_conf_override`

Any .cnf files in this classpath directory will be mapped into the database container's /etc/mysql/conf.d directory,
and will be able to override server settings when the container starts.
Expand Down
6 changes: 3 additions & 3 deletions docs/modules/databases/r2dbc.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ The started container will be terminated when the `ConnectionFactory` is closed.
**Note that, unlike Testcontainers' JDBC URL support, it is not possible to specify an image tag in the 'scheme' part of the URL, and it is always necessary to specify a tag using `TC_IMAGE_TAG`.**

So that the URL becomes:
`r2dbc:tc:mysql:///databasename?TC_IMAGE_TAG=5.7.34`
`r2dbc:tc:mysql:///databasename?TC_IMAGE_TAG=8.0.36`

!!! note
We will use `///` (host-less URIs) from now on to emphasis the unimportance of the `host:port` pair.
Expand All @@ -35,11 +35,11 @@ So that the URL becomes:

#### Using MySQL

`r2dbc:tc:mysql:///databasename?TC_IMAGE_TAG=5.7.34`
`r2dbc:tc:mysql:///databasename?TC_IMAGE_TAG=8.0.36`

#### Using MariaDB

`r2dbc:tc:mariadb:///databasename?TC_IMAGE_TAG=10.3.6`
`r2dbc:tc:mariadb:///databasename?TC_IMAGE_TAG=10.3.39`

#### Using PostgreSQL

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,13 +204,13 @@ private HikariDataSource verifyCharacterSet(String jdbcUrl) throws SQLException
private void performTestForCustomIniFile(HikariDataSource dataSource) throws SQLException {
assumeFalse(SystemUtils.IS_OS_WINDOWS);
Statement statement = dataSource.getConnection().createStatement();
statement.execute("SELECT @@GLOBAL.innodb_file_format");
statement.execute("SELECT @@GLOBAL.innodb_max_undo_log_size");
ResultSet resultSet = statement.getResultSet();

assertThat(resultSet.next()).as("The query returns a result").isTrue();
String result = resultSet.getString(1);
long result = resultSet.getLong(1);

assertThat(result).as("The InnoDB file format has been set by the ini file content").isEqualTo("Barracuda");
assertThat(result).as("The InnoDB max undo log size has been set by the ini file content").isEqualTo(20000000);
}

private HikariDataSource getDataSource(String jdbcUrl, int poolSize) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class ConnectionUrlDriversTests {
public static Iterable<Object[]> data() {
return Arrays.asList(
new Object[][] {
{ "jdbc:tc:mysql:5.7.34://hostname/test", "mysql", Optional.of("5.7.34"), "hostname/test", "test" },
{ "jdbc:tc:mysql:8.0.36://hostname/test", "mysql", Optional.of("8.0.36"), "hostname/test", "test" },
{ "jdbc:tc:mysql://hostname/test", "mysql", Optional.empty(), "hostname/test", "test" },
{
"jdbc:tc:postgresql:1.2.3://hostname/test",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ public class ConnectionUrlTest {

@Test
public void testConnectionUrl1() {
String urlString = "jdbc:tc:mysql:5.7.34://somehostname:3306/databasename?a=b&c=d";
String urlString = "jdbc:tc:mysql:8.0.36://somehostname:3306/databasename?a=b&c=d";
ConnectionUrl url = ConnectionUrl.newInstance(urlString);

assertThat(url.getDatabaseType()).as("Database Type value is as expected").isEqualTo("mysql");
assertThat(url.getImageTag()).as("Database Image tag value is as expected").contains("5.7.34");
assertThat(url.getImageTag()).as("Database Image tag value is as expected").contains("8.0.36");
assertThat(url.getDbHostString())
.as("Database Host String is as expected")
.isEqualTo("somehostname:3306/databasename");
Expand Down Expand Up @@ -71,7 +71,7 @@ public void testTmpfsOption() {
@Test
public void testInitScriptPathCapture() {
String urlString =
"jdbc:tc:mysql:5.7.34://somehostname:3306/databasename?a=b&c=d&TC_INITSCRIPT=somepath/init_mysql.sql";
"jdbc:tc:mysql:8.0.36://somehostname:3306/databasename?a=b&c=d&TC_INITSCRIPT=somepath/init_mysql.sql";
ConnectionUrl url = ConnectionUrl.newInstance(urlString);

assertThat(url.getInitScriptPath())
Expand All @@ -91,7 +91,7 @@ public void testInitScriptPathCapture() {
@Test
public void testInitFunctionCapture() {
String urlString =
"jdbc:tc:mysql:5.7.34://somehostname:3306/databasename?a=b&c=d&TC_INITFUNCTION=org.testcontainers.jdbc.JDBCDriverTest::sampleInitFunction";
"jdbc:tc:mysql:8.0.36://somehostname:3306/databasename?a=b&c=d&TC_INITFUNCTION=org.testcontainers.jdbc.JDBCDriverTest::sampleInitFunction";
ConnectionUrl url = ConnectionUrl.newInstance(urlString);

assertThat(url.getInitFunction()).as("Init Function parameter exists").isPresent();
Expand All @@ -106,7 +106,7 @@ public void testInitFunctionCapture() {

@Test
public void testDaemonCapture() {
String urlString = "jdbc:tc:mysql:5.7.34://somehostname:3306/databasename?a=b&c=d&TC_DAEMON=true";
String urlString = "jdbc:tc:mysql:8.0.36://somehostname:3306/databasename?a=b&c=d&TC_DAEMON=true";
ConnectionUrl url = ConnectionUrl.newInstance(urlString);

assertThat(url.isInDaemonMode()).as("Daemon flag is set to true.").isTrue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ static class MissingDriverContainer extends JdbcDatabaseContainer {
private final AtomicInteger connectionAttempts = new AtomicInteger();

MissingDriverContainer() {
super(DockerImageName.parse("mysql:5.7.34"));
super(DockerImageName.parse("mysql:8.0.36"));
withEnv("MYSQL_ROOT_PASSWORD", "test");
withExposedPorts(3306);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class MariaDBContainer<SELF extends MariaDBContainer<SELF>> extends JdbcD
private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("mariadb");

@Deprecated
public static final String DEFAULT_TAG = "10.3.6";
public static final String DEFAULT_TAG = "10.3.39";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any issue is we keep 10.3.6 as a default? I would like to avoid breaking existing test that relies on default constructor.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes in fact, because 10.3.6 does not have ARM image variants and crashes when you try to run on Colima under emulation as noted in #8131 (comment)

Copy link
Contributor Author

@chadlwilson chadlwilson Jan 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


public static final String NAME = "mariadb";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
import org.testcontainers.utility.DockerImageName;

public interface MariaDBTestImages {
DockerImageName MARIADB_IMAGE = DockerImageName.parse("mariadb:10.3.6");
DockerImageName MARIADB_IMAGE = DockerImageName.parse("mariadb:10.3.39");
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ protected ConnectionFactoryOptions getOptions(MariaDBContainer<?> container) {

@Override
protected String createR2DBCUrl() {
return "r2dbc:tc:mariadb:///db?TC_IMAGE_TAG=10.3.6";
return "r2dbc:tc:mariadb:///db?TC_IMAGE_TAG=10.3.39";
}

@Override
protected MariaDBContainer<?> createContainer() {
return new MariaDBContainer<>(DockerImageName.parse("mariadb:10.3.6"));
return new MariaDBContainer<>(DockerImageName.parse("mariadb:10.3.39"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,29 @@ public static Iterable<Object[]> data() {
"jdbc:tc:mariadb://hostname/databasename?user=someuser&TC_INITSCRIPT=somepath/init_mariadb.sql",
EnumSet.of(Options.ScriptedSchema, Options.JDBCParams),
},
{ "jdbc:tc:mariadb:10.2.14://hostname/databasename", EnumSet.noneOf(Options.class) },
{ "jdbc:tc:mariadb:10.3.39://hostname/databasename", EnumSet.noneOf(Options.class) },
{
"jdbc:tc:mariadb:10.2.14://hostname/databasename?TC_INITSCRIPT=somepath/init_unicode_mariadb.sql&useUnicode=yes&characterEncoding=utf8",
"jdbc:tc:mariadb:10.3.39://hostname/databasename?TC_INITSCRIPT=somepath/init_unicode_mariadb.sql&useUnicode=yes&characterEncoding=utf8",
EnumSet.of(Options.CharacterSet),
},
{
"jdbc:tc:mariadb:10.2.14://hostname/databasename?user=someuser&TC_INITSCRIPT=somepath/init_mariadb.sql",
"jdbc:tc:mariadb:10.3.39://hostname/databasename?user=someuser&TC_INITSCRIPT=somepath/init_mariadb.sql",
EnumSet.of(Options.ScriptedSchema, Options.JDBCParams),
},
{
"jdbc:tc:mariadb:10.2.14://hostname/databasename?user=someuser&TC_INITFUNCTION=org.testcontainers.jdbc.AbstractJDBCDriverTest::sampleInitFunction",
"jdbc:tc:mariadb:10.3.39://hostname/databasename?user=someuser&TC_INITFUNCTION=org.testcontainers.jdbc.AbstractJDBCDriverTest::sampleInitFunction",
EnumSet.of(Options.ScriptedSchema, Options.JDBCParams),
},
{
"jdbc:tc:mariadb:10.2.14://hostname/databasename?user=someuser&password=somepwd&TC_INITSCRIPT=somepath/init_mariadb.sql",
"jdbc:tc:mariadb:10.3.39://hostname/databasename?user=someuser&password=somepwd&TC_INITSCRIPT=somepath/init_mariadb.sql",
EnumSet.of(Options.ScriptedSchema, Options.JDBCParams),
},
{
"jdbc:tc:mariadb:10.2.14://hostname/databasename?user=someuser&password=somepwd&TC_INITFUNCTION=org.testcontainers.jdbc.AbstractJDBCDriverTest::sampleInitFunction",
"jdbc:tc:mariadb:10.3.39://hostname/databasename?user=someuser&password=somepwd&TC_INITFUNCTION=org.testcontainers.jdbc.AbstractJDBCDriverTest::sampleInitFunction",
EnumSet.of(Options.ScriptedSchema, Options.JDBCParams),
},
{
"jdbc:tc:mariadb:10.2.14://hostname/databasename?TC_MY_CNF=somepath/mariadb_conf_override",
"jdbc:tc:mariadb:10.3.39://hostname/databasename?TC_MY_CNF=somepath/mariadb_conf_override",
EnumSet.of(Options.CustomIniFile),
},
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void testSimple() throws SQLException {
public void testSpecificVersion() throws SQLException {
try (
MariaDBContainer<?> mariadbOldVersion = new MariaDBContainer<>(
MariaDBTestImages.MARIADB_IMAGE.withTag("5.5.51")
MariaDBTestImages.MARIADB_IMAGE.withTag("10.3.39")
)
) {
mariadbOldVersion.start();
Expand All @@ -49,7 +49,7 @@ public void testSpecificVersion() throws SQLException {

assertThat(resultSetString)
.as("The database version can be set using a container rule parameter")
.startsWith("5.5.51");
.startsWith("10.3.39");
}
}

Expand All @@ -59,7 +59,7 @@ public void testMariaDBWithCustomIniFile() throws SQLException {

try (
MariaDBContainer<?> mariadbCustomConfig = new MariaDBContainer<>(
MariaDBTestImages.MARIADB_IMAGE.withTag("10.1.16")
MariaDBTestImages.MARIADB_IMAGE.withTag("10.3.39")
)
.withConfigurationOverride("somepath/mariadb_conf_override")
) {
Expand Down Expand Up @@ -107,7 +107,7 @@ public void testWithOnlyUserReadableCustomIniFile() throws Exception {

try (
MariaDBContainer<?> mariadbCustomConfig = new MariaDBContainer<>(
MariaDBTestImages.MARIADB_IMAGE.withTag("10.1.16")
MariaDBTestImages.MARIADB_IMAGE.withTag("10.3.39")
)
.withConfigurationOverride("somepath/mariadb_conf_override")
) {
Expand All @@ -133,9 +133,11 @@ public void testWithOnlyUserReadableCustomIniFile() throws Exception {
}

private void assertThatCustomIniFileWasUsed(MariaDBContainer<?> mariadb) throws SQLException {
try (ResultSet resultSet = performQuery(mariadb, "SELECT @@GLOBAL.innodb_file_format")) {
String result = resultSet.getString(1);
assertThat(result).as("The InnoDB file format has been set by the ini file content").isEqualTo("Barracuda");
try (ResultSet resultSet = performQuery(mariadb, "SELECT @@GLOBAL.innodb_max_undo_log_size")) {
long result = resultSet.getLong(1);
assertThat(result)
.as("The InnoDB max undo log size has been set by the ini file content")
.isEqualTo(20000000);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,12 @@ sort_buffer_size = 64K
read_buffer_size = 256K
read_rnd_buffer_size = 256K
net_buffer_length = 2K
thread_stack = 128K
thread_stack = 512K
skip-host-cache
skip-name-resolve


innodb_file_format=Barracuda




# This configuration is custom to test whether config override works
innodb_max_undo_log_size = 20000000

# Don't listen on a TCP/IP port at all. This can be a security enhancement,
# if all processes that need to connect to mysqld run on the same host.
Expand Down Expand Up @@ -52,4 +48,4 @@ innodb_buffer_pool_size = 16M
innodb_log_file_size = 5M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50
innodb_lock_wait_timeout = 50
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class MySQLContainer<SELF extends MySQLContainer<SELF>> extends JdbcDatab
private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("mysql");

@Deprecated
public static final String DEFAULT_TAG = "5.7.34";
public static final String DEFAULT_TAG = "5.7.44";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any issue is we keep 5.7.34 as a default? I would like to avoid breaking existing test that relies on default constructor.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see why a patch/bugfix release would be expected to break things for people and if you check the history it was previously changed to a new patch releases.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


@Deprecated
public static final String IMAGE = DEFAULT_IMAGE_NAME.getUnversionedPart();
Expand Down
Loading
Loading