diff --git a/docs/modules/databases/mysql.md b/docs/modules/databases/mysql.md
index 825ab42f60c..46bf8b586de 100644
--- a/docs/modules/databases/mysql.md
+++ b/docs/modules/databases/mysql.md
@@ -7,7 +7,7 @@ Testcontainers module for [MySQL](https://hub.docker.com/_/mysql)
You can start a MySQL container instance from any Java application by using:
-[Container definition](../../../modules/mysql/src/test/java/org/testcontainers/junit/mysql/SimpleMySQLTest.java) inside_block:container
+[Container definition](../../../modules/mysql/src/test/java/org/testcontainers/mysql/MySQLContainerTest.java) inside_block:container
See [Database containers](./index.md) for documentation and usage that is common to all relational database container types.
diff --git a/modules/mysql/src/main/java/org/testcontainers/containers/MySQLContainer.java b/modules/mysql/src/main/java/org/testcontainers/containers/MySQLContainer.java
index 54f3952b6a2..9f5b31531c4 100644
--- a/modules/mysql/src/main/java/org/testcontainers/containers/MySQLContainer.java
+++ b/modules/mysql/src/main/java/org/testcontainers/containers/MySQLContainer.java
@@ -12,7 +12,10 @@
* Supported image: {@code mysql}
*
* Exposed ports: 3306
+ *
+ * @deprecated use {@link org.testcontainers.mysql.MySQLContainer} instead.
*/
+@Deprecated
public class MySQLContainer> extends JdbcDatabaseContainer {
public static final String NAME = "mysql";
diff --git a/modules/mysql/src/main/java/org/testcontainers/mysql/MySQLContainer.java b/modules/mysql/src/main/java/org/testcontainers/mysql/MySQLContainer.java
new file mode 100644
index 00000000000..e46bef6180d
--- /dev/null
+++ b/modules/mysql/src/main/java/org/testcontainers/mysql/MySQLContainer.java
@@ -0,0 +1,160 @@
+package org.testcontainers.mysql;
+
+import org.jetbrains.annotations.NotNull;
+import org.testcontainers.containers.ContainerLaunchException;
+import org.testcontainers.containers.JdbcDatabaseContainer;
+import org.testcontainers.images.builder.Transferable;
+import org.testcontainers.utility.DockerImageName;
+
+import java.util.Set;
+
+/**
+ * Testcontainers implementation for MySQL.
+ *
+ * Supported image: {@code mysql}
+ *
+ * Exposed ports: 3306
+ */
+public class MySQLContainer extends JdbcDatabaseContainer {
+
+ public static final String NAME = "mysql";
+
+ private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("mysql");
+
+ static final String DEFAULT_USER = "test";
+
+ static final String DEFAULT_PASSWORD = "test";
+
+ private static final String MY_CNF_CONFIG_OVERRIDE_PARAM_NAME = "TC_MY_CNF";
+
+ public static final Integer MYSQL_PORT = 3306;
+
+ private String databaseName = "test";
+
+ private String username = DEFAULT_USER;
+
+ private String password = DEFAULT_PASSWORD;
+
+ private static final String MYSQL_ROOT_USER = "root";
+
+ public MySQLContainer(String dockerImageName) {
+ this(DockerImageName.parse(dockerImageName));
+ }
+
+ public MySQLContainer(final DockerImageName dockerImageName) {
+ super(dockerImageName);
+ dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME);
+
+ addExposedPort(MYSQL_PORT);
+ }
+
+ /**
+ * @return the ports on which to check if the container is ready
+ * @deprecated use {@link #getLivenessCheckPortNumbers()} instead
+ */
+ @NotNull
+ @Override
+ @Deprecated
+ protected Set getLivenessCheckPorts() {
+ return super.getLivenessCheckPorts();
+ }
+
+ @Override
+ protected void configure() {
+ optionallyMapResourceParameterAsVolume(
+ MY_CNF_CONFIG_OVERRIDE_PARAM_NAME,
+ "/etc/mysql/conf.d",
+ "mysql-default-conf",
+ Transferable.DEFAULT_DIR_MODE
+ );
+
+ addEnv("MYSQL_DATABASE", databaseName);
+ if (!MYSQL_ROOT_USER.equalsIgnoreCase(username)) {
+ addEnv("MYSQL_USER", username);
+ }
+ if (password != null && !password.isEmpty()) {
+ addEnv("MYSQL_PASSWORD", password);
+ addEnv("MYSQL_ROOT_PASSWORD", password);
+ } else if (MYSQL_ROOT_USER.equalsIgnoreCase(username)) {
+ addEnv("MYSQL_ALLOW_EMPTY_PASSWORD", "yes");
+ } else {
+ throw new ContainerLaunchException("Empty password can be used only with the root user");
+ }
+ setStartupAttempts(3);
+ }
+
+ @Override
+ public String getDriverClassName() {
+ try {
+ Class.forName("com.mysql.cj.jdbc.Driver");
+ return "com.mysql.cj.jdbc.Driver";
+ } catch (ClassNotFoundException e) {
+ return "com.mysql.jdbc.Driver";
+ }
+ }
+
+ @Override
+ public String getJdbcUrl() {
+ String additionalUrlParams = constructUrlParameters("?", "&");
+ return "jdbc:mysql://" + getHost() + ":" + getMappedPort(MYSQL_PORT) + "/" + databaseName + additionalUrlParams;
+ }
+
+ @Override
+ protected String constructUrlForConnection(String queryString) {
+ String url = super.constructUrlForConnection(queryString);
+
+ if (!url.contains("useSSL=")) {
+ String separator = url.contains("?") ? "&" : "?";
+ url = url + separator + "useSSL=false";
+ }
+
+ if (!url.contains("allowPublicKeyRetrieval=")) {
+ url = url + "&allowPublicKeyRetrieval=true";
+ }
+
+ return url;
+ }
+
+ @Override
+ public String getDatabaseName() {
+ return databaseName;
+ }
+
+ @Override
+ public String getUsername() {
+ return username;
+ }
+
+ @Override
+ public String getPassword() {
+ return password;
+ }
+
+ @Override
+ public String getTestQueryString() {
+ return "SELECT 1";
+ }
+
+ public MySQLContainer withConfigurationOverride(String s) {
+ parameters.put(MY_CNF_CONFIG_OVERRIDE_PARAM_NAME, s);
+ return self();
+ }
+
+ @Override
+ public MySQLContainer withDatabaseName(final String databaseName) {
+ this.databaseName = databaseName;
+ return self();
+ }
+
+ @Override
+ public MySQLContainer withUsername(final String username) {
+ this.username = username;
+ return self();
+ }
+
+ @Override
+ public MySQLContainer withPassword(final String password) {
+ this.password = password;
+ return self();
+ }
+}
diff --git a/modules/mysql/src/test/java/org/testcontainers/junit/mysql/CustomizableMysqlTest.java b/modules/mysql/src/test/java/org/testcontainers/junit/mysql/CustomizableMysqlTest.java
deleted file mode 100644
index 9e9d97dc54e..00000000000
--- a/modules/mysql/src/test/java/org/testcontainers/junit/mysql/CustomizableMysqlTest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.testcontainers.junit.mysql;
-
-import org.junit.jupiter.api.Test;
-import org.testcontainers.MySQLTestImages;
-import org.testcontainers.containers.MySQLContainer;
-import org.testcontainers.db.AbstractContainerDatabaseTest;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-class CustomizableMysqlTest extends AbstractContainerDatabaseTest {
-
- private static final String DB_NAME = "foo";
-
- private static final String USER = "bar";
-
- private static final String PWD = "baz";
-
- @Test
- void testSimple() throws SQLException {
- // Add MYSQL_ROOT_HOST environment so that we can root login from anywhere for testing purposes
- try (
- MySQLContainer> mysql = new MySQLContainer<>(MySQLTestImages.MYSQL_80_IMAGE)
- .withDatabaseName(DB_NAME)
- .withUsername(USER)
- .withPassword(PWD)
- .withEnv("MYSQL_ROOT_HOST", "%")
- ) {
- mysql.start();
-
- ResultSet resultSet = performQuery(mysql, "SELECT 1");
-
- int resultSetInt = resultSet.getInt(1);
- assertThat(resultSetInt).as("A basic SELECT query succeeds").isEqualTo(1);
- }
- }
-}
diff --git a/modules/mysql/src/test/java/org/testcontainers/junit/mysql/MultiVersionMySQLTest.java b/modules/mysql/src/test/java/org/testcontainers/mysql/MultiVersionMySQLTest.java
similarity index 87%
rename from modules/mysql/src/test/java/org/testcontainers/junit/mysql/MultiVersionMySQLTest.java
rename to modules/mysql/src/test/java/org/testcontainers/mysql/MultiVersionMySQLTest.java
index d8e8b52dc56..8dc4454860b 100644
--- a/modules/mysql/src/test/java/org/testcontainers/junit/mysql/MultiVersionMySQLTest.java
+++ b/modules/mysql/src/test/java/org/testcontainers/mysql/MultiVersionMySQLTest.java
@@ -1,9 +1,8 @@
-package org.testcontainers.junit.mysql;
+package org.testcontainers.mysql;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.testcontainers.MySQLTestImages;
-import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.db.AbstractContainerDatabaseTest;
import org.testcontainers.utility.DockerImageName;
@@ -26,7 +25,7 @@ public static DockerImageName[] params() {
@ParameterizedTest
@MethodSource("params")
void versionCheckTest(DockerImageName dockerImageName) throws SQLException {
- try (MySQLContainer> mysql = new MySQLContainer<>(dockerImageName)) {
+ try (MySQLContainer mysql = new MySQLContainer(dockerImageName)) {
mysql.start();
final ResultSet resultSet = performQuery(mysql, "SELECT VERSION()");
final String resultSetString = resultSet.getString(1);
diff --git a/modules/mysql/src/test/java/org/testcontainers/junit/mysql/SimpleMySQLTest.java b/modules/mysql/src/test/java/org/testcontainers/mysql/MySQLContainerTest.java
similarity index 82%
rename from modules/mysql/src/test/java/org/testcontainers/junit/mysql/SimpleMySQLTest.java
rename to modules/mysql/src/test/java/org/testcontainers/mysql/MySQLContainerTest.java
index b3eac503c57..ad78781db5c 100644
--- a/modules/mysql/src/test/java/org/testcontainers/junit/mysql/SimpleMySQLTest.java
+++ b/modules/mysql/src/test/java/org/testcontainers/mysql/MySQLContainerTest.java
@@ -1,11 +1,10 @@
-package org.testcontainers.junit.mysql;
+package org.testcontainers.mysql;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.MySQLTestImages;
import org.testcontainers.containers.ContainerLaunchException;
-import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import org.testcontainers.db.AbstractContainerDatabaseTest;
@@ -30,14 +29,14 @@
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assumptions.assumeThat;
-class SimpleMySQLTest extends AbstractContainerDatabaseTest {
+class MySQLContainerTest extends AbstractContainerDatabaseTest {
- private static final Logger logger = LoggerFactory.getLogger(SimpleMySQLTest.class);
+ private static final Logger logger = LoggerFactory.getLogger(MySQLContainerTest.class);
@Test
void testSimple() throws SQLException {
try ( // container {
- MySQLContainer> mysql = new MySQLContainer<>("mysql:8.0.36")
+ MySQLContainer mysql = new MySQLContainer("mysql:8.0.36")
// }
) {
mysql.start();
@@ -53,7 +52,7 @@ void testSimple() throws SQLException {
@Test
void testSpecificVersion() throws SQLException {
try (
- MySQLContainer> mysqlOldVersion = new MySQLContainer<>(MySQLTestImages.MYSQL_80_IMAGE)
+ MySQLContainer mysqlOldVersion = new MySQLContainer(MySQLTestImages.MYSQL_80_IMAGE)
.withConfigurationOverride("somepath/mysql_conf_override")
.withLogConsumer(new Slf4jLogConsumer(logger))
) {
@@ -71,7 +70,7 @@ void testSpecificVersion() throws SQLException {
@Test
void testMySQLWithCustomIniFile() throws SQLException {
try (
- MySQLContainer> mysqlCustomConfig = new MySQLContainer<>(MySQLTestImages.MYSQL_80_IMAGE)
+ MySQLContainer mysqlCustomConfig = new MySQLContainer(MySQLTestImages.MYSQL_80_IMAGE)
.withConfigurationOverride("somepath/mysql_conf_override")
) {
mysqlCustomConfig.start();
@@ -83,7 +82,7 @@ void testMySQLWithCustomIniFile() throws SQLException {
@Test
void testCommandOverride() throws SQLException {
try (
- MySQLContainer> mysqlCustomConfig = new MySQLContainer<>(MySQLTestImages.MYSQL_80_IMAGE)
+ MySQLContainer mysqlCustomConfig = new MySQLContainer(MySQLTestImages.MYSQL_80_IMAGE)
.withCommand("mysqld --auto_increment_increment=42")
) {
mysqlCustomConfig.start();
@@ -98,7 +97,7 @@ void testCommandOverride() throws SQLException {
@Test
void testExplicitInitScript() throws SQLException {
try (
- MySQLContainer> container = new MySQLContainer<>(MySQLTestImages.MYSQL_80_IMAGE)
+ MySQLContainer container = new MySQLContainer(MySQLTestImages.MYSQL_80_IMAGE)
.withInitScript("somepath/init_mysql.sql")
.withLogConsumer(new Slf4jLogConsumer(logger))
) {
@@ -114,7 +113,7 @@ void testExplicitInitScript() throws SQLException {
@Test
void testEmptyPasswordWithNonRootUser() {
try (
- MySQLContainer> container = new MySQLContainer<>(MySQLTestImages.MYSQL_80_IMAGE)
+ MySQLContainer container = new MySQLContainer(MySQLTestImages.MYSQL_80_IMAGE)
.withDatabaseName("TEST")
.withUsername("test")
.withPassword("")
@@ -130,7 +129,7 @@ void testEmptyPasswordWithNonRootUser() {
void testEmptyPasswordWithRootUser() throws SQLException {
// Add MYSQL_ROOT_HOST environment so that we can root login from anywhere for testing purposes
try (
- MySQLContainer> mysql = new MySQLContainer<>(MySQLTestImages.MYSQL_80_IMAGE)
+ MySQLContainer mysql = new MySQLContainer(MySQLTestImages.MYSQL_80_IMAGE)
.withDatabaseName("foo")
.withUsername("root")
.withPassword("")
@@ -147,7 +146,7 @@ void testEmptyPasswordWithRootUser() throws SQLException {
@Test
void testWithAdditionalUrlParamTimeZone() throws SQLException {
- MySQLContainer> mysql = new MySQLContainer<>(MySQLTestImages.MYSQL_80_IMAGE)
+ MySQLContainer mysql = new MySQLContainer(MySQLTestImages.MYSQL_80_IMAGE)
.withUrlParam("serverTimezone", "Europe/Zurich")
.withEnv("TZ", "Europe/Zurich")
.withLogConsumer(new Slf4jLogConsumer(logger));
@@ -182,7 +181,7 @@ void testWithAdditionalUrlParamTimeZone() throws SQLException {
@Test
void testWithAdditionalUrlParamMultiQueries() throws SQLException {
- MySQLContainer> mysql = new MySQLContainer<>(MySQLTestImages.MYSQL_80_IMAGE)
+ MySQLContainer mysql = new MySQLContainer(MySQLTestImages.MYSQL_80_IMAGE)
.withUrlParam("allowMultiQueries", "true")
.withLogConsumer(new Slf4jLogConsumer(logger));
mysql.start();
@@ -207,7 +206,7 @@ void testWithAdditionalUrlParamMultiQueries() throws SQLException {
@Test
void testWithAdditionalUrlParamInJdbcUrl() {
- MySQLContainer> mysql = new MySQLContainer<>(MySQLTestImages.MYSQL_80_IMAGE)
+ MySQLContainer mysql = new MySQLContainer(MySQLTestImages.MYSQL_80_IMAGE)
.withUrlParam("allowMultiQueries", "true")
.withUrlParam("rewriteBatchedStatements", "true")
.withLogConsumer(new Slf4jLogConsumer(logger));
@@ -228,7 +227,7 @@ void testWithAdditionalUrlParamInJdbcUrl() {
void testWithOnlyUserReadableCustomIniFile() throws Exception {
assumeThat(FileSystems.getDefault().supportedFileAttributeViews().contains("posix")).isTrue();
try (
- MySQLContainer> mysql = new MySQLContainer<>(MySQLTestImages.MYSQL_80_IMAGE)
+ MySQLContainer mysql = new MySQLContainer(MySQLTestImages.MYSQL_80_IMAGE)
.withConfigurationOverride("somepath/mysql_conf_override")
.withLogConsumer(new Slf4jLogConsumer(logger))
) {
@@ -252,12 +251,31 @@ void testWithOnlyUserReadableCustomIniFile() throws Exception {
}
}
- private void assertHasCorrectExposedAndLivenessCheckPorts(MySQLContainer> mysql) {
+ @Test
+ void testCustom() throws SQLException {
+ // Add MYSQL_ROOT_HOST environment so that we can root login from anywhere for testing purposes
+ try (
+ MySQLContainer mysql = new MySQLContainer(MySQLTestImages.MYSQL_80_IMAGE)
+ .withDatabaseName("foo")
+ .withUsername("bar")
+ .withPassword("baz")
+ .withEnv("MYSQL_ROOT_HOST", "%")
+ ) {
+ mysql.start();
+
+ ResultSet resultSet = performQuery(mysql, "SELECT 1");
+
+ int resultSetInt = resultSet.getInt(1);
+ assertThat(resultSetInt).as("A basic SELECT query succeeds").isEqualTo(1);
+ }
+ }
+
+ private void assertHasCorrectExposedAndLivenessCheckPorts(MySQLContainer mysql) {
assertThat(mysql.getExposedPorts()).containsExactly(MySQLContainer.MYSQL_PORT);
assertThat(mysql.getLivenessCheckPortNumbers()).containsExactly(mysql.getMappedPort(MySQLContainer.MYSQL_PORT));
}
- private void assertThatCustomIniFileWasUsed(MySQLContainer> mysql) throws SQLException {
+ private void assertThatCustomIniFileWasUsed(MySQLContainer mysql) throws SQLException {
try (ResultSet resultSet = performQuery(mysql, "SELECT @@GLOBAL.innodb_max_undo_log_size")) {
long result = resultSet.getLong(1);
assertThat(result)