使用测试容器播种 mysql 数据库
Posted
技术标签:
【中文标题】使用测试容器播种 mysql 数据库【英文标题】:Seeding a mysql db with testcontainers 【发布时间】:2020-05-02 11:09:14 【问题描述】:我有一个非常简单的情况:AWS 中有一个现有的 mysql 数据库,我想使用 testcontainers 对其进行测试。
我已遵循官方指南 (https://www.testcontainers.org/modules/databases/) 及其示例 (https://github.com/testcontainers/testcontainers-java/blob/master/modules/jdbc-test/src/test/java/org/testcontainers/junit/SimpleMySQLTest.java),但是我无法加载使用 mysqldump 创建的转储。
每次我得到以下错误:
Caused by: java.sql.SQLSyntaxErrorException: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
根据其他用户的建议,我尝试了以下方法:
MySQLContainer mysql = (MySQLContainer) new MySQLContainer()
.withInitScript("foodmart_department.sql")
.withUsername("root")
.withPassword("test")
.withLogConsumer(new Slf4jLogConsumer(logger));
mysql.start();
但它会挂起几分钟并终止并出现此错误:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
ℹ︎ Checking the system...
✔ Docker version should be at least 1.6.0
✔ Docker environment should have more than 2GB free disk space
org.testcontainers.containers.ContainerLaunchException: Container startup failed
at org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:307)
at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:287)
at com.Foodmart.testSimple(Foodmart.java:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:628)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:117)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:184)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:180)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:127)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.rnorth.ducttape.RetryCountExceededException: Retry limit hit with exception
at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:88)
at org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:300)
... 53 more
Caused by: org.testcontainers.containers.ContainerLaunchException: Could not create/start container
at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:418)
at org.testcontainers.containers.GenericContainer.lambda$doStart$0(GenericContainer.java:302)
at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:81)
... 54 more
Caused by: org.testcontainers.ext.ScriptUtils$UncategorizedScriptException: Failed to execute database script from resource [-- MySQL dump 10.13 Distrib 8.0.19, for osx10.14 (x86_64)
--
-- Host: mysql-technical-test.cq5i4y35n9gg.eu-west-1.rds.amazonaws.com Database: foodmart
-- ------------------------------------------------------
-- Server version 5.7.26-log
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
SET @MYSQLDUMP_TEMP_LOG_BIN = @@SESSION.SQL_LOG_BIN;
SET @@SESSION.SQL_LOG_BIN= 0;
--
-- GTID state at the beginning of the backup
--
SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '';
--
-- Table structure for table `department`
--
DROP TABLE IF EXISTS `department`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `department` (
`department_id` int(11) NOT NULL,
`department_description` varchar(30) NOT NULL,
UNIQUE KEY `i_department_id` (`department_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `department`
--
LOCK TABLES `department` WRITE;
/*!40000 ALTER TABLE `department` DISABLE KEYS */;
INSERT INTO `department` VALUES (1,'HQ General Management'),(2,'HQ Information Systems'),(3,'HQ Marketing'),(4,'HQ Human Resources'),(5,'HQ Finance and Accounting'),(11,'Store Management'),(14,'Store Information Systems'),(15,'Permanent Checkers'),(16,'Temp Checkers'),(17,'Permanent Stockers'),(18,'Temp Stockers'),(19,'Store Permanent Butchers');
/*!40000 ALTER TABLE `department` ENABLE KEYS */;
UNLOCK TABLES;
]
at org.testcontainers.ext.ScriptUtils.executeDatabaseScript(ScriptUtils.java:375)
at org.testcontainers.ext.ScriptUtils.executeDatabaseScript(ScriptUtils.java:313)
at org.testcontainers.ext.ScriptUtils.runInitScript(ScriptUtils.java:302)
at org.testcontainers.containers.JdbcDatabaseContainer.runInitScriptIfRequired(JdbcDatabaseContainer.java:240)
at org.testcontainers.containers.JdbcDatabaseContainer.containerIsStarted(JdbcDatabaseContainer.java:154)
at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:403)
... 56 more
Caused by: org.testcontainers.exception.ConnectionCreationException: Could not obtain JDBC connection
at org.testcontainers.jdbc.JdbcDatabaseDelegate.createNewConnection(JdbcDatabaseDelegate.java:34)
at org.testcontainers.jdbc.JdbcDatabaseDelegate.createNewConnection(JdbcDatabaseDelegate.java:17)
at org.testcontainers.delegate.AbstractDatabaseDelegate.getConnection(AbstractDatabaseDelegate.java:23)
at org.testcontainers.jdbc.JdbcDatabaseDelegate.execute(JdbcDatabaseDelegate.java:42)
at org.testcontainers.delegate.AbstractDatabaseDelegate.execute(AbstractDatabaseDelegate.java:34)
at org.testcontainers.ext.ScriptUtils.executeDatabaseScript(ScriptUtils.java:362)
... 61 more
Caused by: java.sql.SQLException: Could not create new connection
at org.testcontainers.containers.JdbcDatabaseContainer.createConnection(JdbcDatabaseContainer.java:210)
at org.testcontainers.jdbc.JdbcDatabaseDelegate.createNewConnection(JdbcDatabaseDelegate.java:31)
... 66 more
所以,为了实现如此简单的事情,我肯定做错了什么。
【问题讨论】:
引起:java.sql.SQLSyntaxErrorException: INSERT 命令拒绝用户 'test'@'172.17.0.1' 用于表 'department' 忘了说:它只是一个带有 maven 的纯 java 应用程序。不支持 Spring 框架。 MysqlContainer 似乎有问题,我也遇到了同样的问题,发现了这个问题github.com/testcontainers/testcontainers-java/issues/2878,你找到解决方案了吗? 【参考方案1】:既然是mysql,就把.withUsername("root")
去掉。
来自容器的日志:
2020-10-08 12:35:53+00:00 [Note] [Entrypoint]: Creating user root ERROR 1396 (HY000) at line 1: Operation CREATE USER failed for 'root'@'%'
【讨论】:
以上是关于使用测试容器播种 mysql 数据库的主要内容,如果未能解决你的问题,请参考以下文章
为 Dockerized Django 应用程序播种 MySQL 数据库
如何在 Laravel 中使用内存数据库的完整测试套件之前迁移和播种?