当启动大量测试容器时,我的 16GB MBP 变得非常慢。我想在运行 Windows 的强大桌面上运行它们。如果这可以在我的本地网络之外工作,那就更好了。
我正在使用测试容器,直到现在它都工作得很好。我最近更新了 docker 和 IntelliJ,但我不知道这是否是导致以下问题的原因。
这是我使用的依赖项:
testCompile 'org.testcontainers:testcontainers:1.12.3'
testCompile 'org.testcontainers:oracle-xe:1.12.3'
Run Code Online (Sandbox Code Playgroud)
这是堆栈跟踪:
2020-10-12T13:13:06.709 WARN testcontainers-ryuk [rg.testcontainers.utility.ResourceReaper] - Can not connect to Ryuk at localhost:32778
java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at java.net.Socket.<init>(Socket.java:434)
at java.net.Socket.<init>(Socket.java:211)
at org.testcontainers.utility.ResourceReaper.lambda$start$1(ResourceReaper.java:114)
at java.lang.Thread.run(Thread.java:748)
java.lang.ExceptionInInitializerError
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)
...
Caused by: org.testcontainers.containers.ContainerFetchException: Can't get Docker image: RemoteDockerImage(imageName=ryangoh/oracle_12c_r1_xe:latest)
at org.testcontainers.containers.GenericContainer.getDockerImageName(GenericContainer.java:1153)
at org.testcontainers.containers.GenericContainer.setDockerImageName(GenericContainer.java:1141)
at org.testcontainers.containers.GenericContainer.<init>(GenericContainer.java:246)
at org.testcontainers.containers.JdbcDatabaseContainer.<init>(JdbcDatabaseContainer.java:36)
at org.testcontainers.containers.OracleContainer.<init>(OracleContainer.java:40)
at …Run Code Online (Sandbox Code Playgroud) 我们在spring-boot-admin项目中大量使用testcontainers-java。由于我们还希望能够在 Windows 上运行 Maven 构建,因此我们使用矩阵策略构建(如本答案中假设的那样)向 GitHub Actions Pipeline 添加了一个环境,如下所示:windows-latest
name: build
on:
push:
jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build with Maven
run: |
mvn -B install --no-transfer-progress
Run Code Online (Sandbox Code Playgroud)
现在我们的 Testcontainers JUnit 测试用例失败(请参阅完整的构建日志):
[INFO] Running de.codecentric.boot.admin.server.eventstore.HazelcastEventStoreWithClientConfigTest
Error: Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.877 s <<< …Run Code Online (Sandbox Code Playgroud) 使用 spring boot + spring data jdbc 我必须DataSource自己连接 bean。就像这样:
@Bean\n public DataSource dataSource() {\n HikariConfig hikariConfig = new HikariConfig();\n hikariConfig.setJdbcUrl(this.environment.getRequiredProperty("url"));\n hikariConfig.setUsername("user");\n hikariConfig.setDriverClassName("org.postgresql.Driver");\n hikariConfig.setPassword("password");\n return new HikariDataSource(hikariConfig);\n }\nRun Code Online (Sandbox Code Playgroud)\n当我想使用 testcontainers 进行测试时,我DataSource还必须声明一个 bean:
@Bean\n @Primary\n DataSource testDataSource() {\n\n if (POSTGRESQL_CONTAINER == null) {\n PostgreSQLContainer<?> container = new PostgreSQLContainer<>(DockerImageName.parse("postgres").withTag("9.6.12"));\n container.withInitScript("schema.sql");\n container.start();\n POSTGRESQL_CONTAINER = container;\n }\n PGSimpleDataSource dataSource = new PGSimpleDataSource();\n dataSource.setUrl(POSTGRESQL_CONTAINER.getJdbcUrl());\n dataSource.setUser(POSTGRESQL_CONTAINER.getUsername());\n dataSource.setPassword(POSTGRESQL_CONTAINER.getPassword());\n\n return dataSource;\n }\nRun Code Online (Sandbox Code Playgroud)\n使用我的测试,SpringBootTest我几乎必须使用ComponentScan所有包,因为我不想模拟所有其他 bean。
\n所以我的问题是:
\n我可以以某种方式排除主要DataSource …
我正在尝试使用 GenericContainer 启动自定义 docker 容器。\n容器启动后,我想从测试类执行 http 请求。\n我看到此错误:
\nINFO: Exposed ports: 9000\n\njava.net.ConnectException: Failed to connect to localhost/0:0:0:0:0:0:0:1:9000\n at org.testcontainers.shaded.okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:265)\n\nCaused by: java.net.ConnectException: Connection refused (Connection refused)\n at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)\n\nRun Code Online (Sandbox Code Playgroud)\n该端口似乎已绑定:
\ndocker ps -a\nCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\nf311467dbd25 foo.bar.com/abc-def/testcontainer:4.30.65 "/bin/sh -c 'exec /o\xe2\x80\xa6" About a minute ago Up About a minute 0.0.0.0:55164->9000/tcp, :::55164->9000/tcp, 0.0.0.0:55163->9001/tcp, :::55163->9001/tcp happy_jepsen\nRun Code Online (Sandbox Code Playgroud)\n我正在使用以下代码创建容器:
\n myContainerInstance = new GenericContainer<>(MY_CONTAINER_IMAGE)\n .withNetworkAliases("foo")\n .withCreateContainerCmdModifier(createContainerCmd -> createContainerCmd.withHostName("foo"))\n .waitingFor(new WaitAllStrategy().withStrategy(new LogMessageWaitStrategy().withRegEx(".*Listening for HTTP on.*"))\n .withStartupTimeout(Duration.ofMinutes(4)))\n .withExposedPorts(9000)\nRun Code Online (Sandbox Code Playgroud)\n客户端代码: …
目前,我想为我的系统创建集成测试。我使用 testcontainers 生成临时数据库实例,并使用 R2DBC 数据库使我的系统具有反应性。问题是我不知道如何在 R2DBC testcontainer 实例中创建模式,testcontainers 网页中的R2DBC 支持和JDBC支持之间的文档存在明显差异。在 JDBC 中,在替换 JDBC URL 后有创建 schema 的部分,而在 R2DBC 中,在替换 R2DBC URL 后没有提及创建 schema。我已经尝试和探索了中的方法PostgreSQLR2DBCDatabaseContainer,但没有成功。
我还使用 spring boot 作为我们系统的框架,通常我使用初始值设定项替换 URL ContextConfiguration。替换 R2DBC 的 URL 后有什么方法可以创建架构吗?
postgresql integration-testing spring-boot testcontainers r2dbc
我有一些集成测试,我正在使用测试容器。但我突然意识到,当我的应用程序的带有数据库的 docker 容器关闭时,所有其他测试(不包括使用 Testcontainers 的集成测试)都会失败(甚至是contextLoads()Spring Bootinitializr 生成的测试)
我得到:
java.lang.IllegalStateException:无法在org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:132)加载ApplicationContext
导致:org.springframework.beans.factory.BeanCreationException:创建类路径资源中定义的名称为“liquibase”的bean时出错
[org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration$LiquibaseConfiguration.class]:调用init方法失败;嵌套异常是 liquibase.exception.DatabaseException: com.mysql.cj.jdbc.exceptions.CommunicationsException: 通信链接失败
很明显应用程序想要连接数据库,而数据库容器宕机了。
我一直在调查,但我不记得曾经需要仅为应用程序的测试/构建过程启动容器,所以这个问题对我来说是新问题。但如果有什么地方做错了,也可能是在我的AbstractDatabaseIT课堂上:
@ActiveProfiles("test")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ContextConfiguration(initializers = AbstractDatabaseIT.DockerMySqlDataSourceInitializer.class)
@Testcontainers
public abstract class AbstractDatabaseIT {
private static final String MYSQL_IMAGE_NAME = "mysql:5.7.24";
public static final MySQLContainer<?> mySQLContainer = new MySQLContainer<>(MYSQL_IMAGE_NAME);
static {
mySQLContainer.start();
}
public static class DockerMySqlDataSourceInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(@NotNull ConfigurableApplicationContext applicationContext) {
Map<String, String> parameters = new HashMap<>();
parameters.put("command", "--character-set-server=utf8");
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(
applicationContext,
"spring.datasource.url=" …Run Code Online (Sandbox Code Playgroud) 今天,我听到消息称 docker 桌面将不再免费。因此,我们团队的结论是删除 Docker Desktop 并使用 minikube。
然后,我们可以使用docker cli,但是,当我们在Java项目中使用testContainer(我们使用intellij)时,testContainer由于Docker而无法工作。我们怎样才能解决这个问题呢?
Can't get Docker image: RemoteDockerImage(imageName=docker.elastic.co/elasticsearch/elasticsearch:7.14.2, imagePullPolicy=DefaultPullPolicy())
org.testcontainers.containers.ContainerFetchException: Can't get Docker image: RemoteDockerImage(imageName=docker.elastic.co/elasticsearch/elasticsearch:7.14.2, imagePullPolicy=DefaultPullPolicy())
at org.testcontainers.containers.GenericContainer.getDockerImageName(GenericContainer.java:1326)
at org.testcontainers.containers.GenericContainer.logger(GenericContainer.java:643)
at org.testcontainers.elasticsearch.ElasticsearchContainer.<init>(ElasticsearchContainer.java:73)
at org.testcontainers.elasticsearch.ElasticsearchContainer.<init>(ElasticsearchContainer.java:57)
at com.wmp.ep.index.manager.service.IndexManageServiceTest.beforeClass(IndexManageServiceTest.java:40)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptLifecycleMethod(TimeoutExtension.java:126)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptBeforeAllMethod(TimeoutExtension.java:68)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllMethods$9(ClassBasedTestDescriptor.java:384)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeBeforeAllMethods(ClassBasedTestDescriptor.java:382)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:196)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:78)
at …Run Code Online (Sandbox Code Playgroud) 我正在使用官方Aerospike Docker 映像与 Testcontainers 一起运行它。我可以指定默认名称空间作为环境变量。不幸的是,我无法在容器启动时创建 2 个命名空间。
有什么方法可以实现吗?
我在 Java/maven 项目中使用 Testcontainer 进行单元测试和集成测试。测试按预期进行,直到我运行我用来工作的 VPN。使用 VPN,我可以看到错误消息“Can not connect to Ryuk at localhost:49198”
以下是完整的日志:
Connected to the target VM, address: '127.0.0.1:50813', transport: 'socket'
2022-10-03 18:01:49.728 INFO --- [ main] o.t.d.DockerClientProviderStrategy : Loaded org.testcontainers.dockerclient.UnixSocketClientProviderStrategy from ~/.testcontainers.properties, will try it first
2022-10-03 18:01:50.280 INFO --- [ main] o.t.d.DockerClientProviderStrategy : Found Docker environment with local Unix socket (unix:///var/run/docker.sock)
2022-10-03 18:01:50.282 INFO --- [ main] org.testcontainers.DockerClientFactory : Docker host IP address is localhost
2022-10-03 18:01:50.308 INFO --- [ main] org.testcontainers.DockerClientFactory : Connected to docker: …Run Code Online (Sandbox Code Playgroud) testcontainers ×10
java ×5
docker ×4
spring-boot ×4
junit ×2
spring ×2
windows ×2
aerospike ×1
dockerfile ×1
macos ×1
maven ×1
postgresql ×1
r2dbc ×1
testing ×1