英文:
How to resolve org.testcontainers.containers.ContainerFetchException on Spring Boot?
问题
ContainerListener.java 类:
public class ContainerListener implements TestListener {
@ClassRule
public static Network sharedNetwork = Network.newNetwork();
@ClassRule
public static GenericContainer mongoDBContainer = new GenericContainer("mongo:3.2.4")
.withNetwork(sharedNetwork)
.withNetworkAliases("mongo")
.withExposedPorts(27017);
public static MockServerContainer mockServerContainer = new MockServerContainer()
.withNetwork(sharedNetwork)
.withNetworkAliases("mockserver")
.withExposedPorts(1080);
public static int getMockPort() {
return mockServerContainer.getMappedPort(1080);
}
public static int getMongoPort() {
return mongoDBContainer.getMappedPort(27017);
}
public static void runAll() {
List.of(mongoDBContainer, mockServerContainer).forEach(e -> e.start());
}
public static void stopAll() {
List.of(mongoDBContainer, mockServerContainer).forEach(e -> e.stop());
}
}
SomeControllerIntegrationTest.java 类:
import io.restassured.RestAssured;
import io.restassured.parsing.Parser;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;
public class RatingControllerIntegrationTest {
@BeforeAll
public static void setup() {
ContainerListener.runAll();
}
@AfterAll
public static void tearDown() {
ContainerListener.stopAll();
}
@Test
public void detailsTest() throws Exception {
RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
RestAssured.defaultParser = Parser.JSON;
given()
.log().all()
.when()
.get("http://localhost:8080/actuator/info/")
.then()
.log().all()
.statusCode(200);
}
}
尽管运行测试后出现以下错误:
org.testcontainers.containers.ContainerLaunchException: Container startup failed
Caused by: org.testcontainers.containers.ContainerFetchException: Can't get Docker image: RemoteDockerImage(imageName=mongo:3.2.4, imagePullPolicy=DefaultPullPolicy())
at org.testcontainers.containers.GenericContainer.getDockerImageName(GenericContainer.java:1279)
at org.testcontainers.containers.GenericContainer.logger(GenericContainer.java:613)
at org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:320)
... 58 more
Caused by: java.lang.IllegalStateException: Can not connect to Ryuk at localhost:32770
at org.testcontainers.utility.ResourceReaper.start(ResourceReaper.java:176)
at org.testcontainers.DockerClientFactory.client(DockerClientFactory.java:168)
at org.testcontainers.LazyDockerClient.getDockerClient(LazyDockerClient.java:14)
at org.testcontainers.LazyDockerClient.listImagesCmd(LazyDockerClient.java:12)
at org.testcontainers.images.LocalImagesCache.maybeInitCache(LocalImagesCache.java:68)
at org.testcontainers.images.LocalImagesCache.get(LocalImagesCache.java:32)
at org.testcontainers.images.AbstractImagePullPolicy.shouldPull(AbstractImagePullPolicy.java:18)
at org.testcontainers.images.RemoteDockerImage.resolve(RemoteDockerImage.java:59)
at org.testcontainers.images.RemoteDockerImage.resolve(RemoteDockerImage.java:26)
at org.testcontainers.utility.LazyFuture.getResolvedValue(LazyFuture.java:20)
at org.testcontainers.utility.LazyFuture.get(LazyFuture.java:27)
at org.testcontainers.containers.GenericContainer.getDockerImageName(GenericContainer.java:1277)
... 60 more
英文:
I am working on developing a few integration tests for my spring boot application. I am using testcontainers
in order to create a MongoDB
docker image. My code so far:
ContainerListener.java class:
public class ContainerListener implements TestListener {
@ClassRule
public static Network sharedNetwork = Network.newNetwork();
@ClassRule
public static GenericContainer mongoDBContainer = new GenericContainer("mongo:3.2.4").withNetwork(sharedNetwork)
.withNetworkAliases("mongo").withExposedPorts(27017);
public static MockServerContainer mockServerContainer = new MockServerContainer().withNetwork(sharedNetwork)
.withNetworkAliases("mockserver").withExposedPorts(1080);
public static int getMockPort() {
return mockServerContainer.getMappedPort(1080);
}
public static int getMongoPort() {
return mongoDBContainer.getMappedPort(27017);
}
public static void runAll() {
List.of(mongoDBContainer, mockServerContainer).forEach(e -> e.start());
}
public static void stopAll() {
List.of(mongoDBContainer, mockServerContainer).forEach(e -> e.stop());
}
}
And SomeControllerIntegrationTest.java class:
import io.restassured.RestAssured;
import io.restassured.parsing.Parser;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;
public class RatingControllerIntegrationTest {
@BeforeAll
public static void setuo() {
ContainerListener.runAll();
}
@AfterAll
public static void tearDown() {
ContainerListener.stopAll();
}
@Test
public void detailsTest() throws Exception {
RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
RestAssured.defaultParser = Parser.JSON;
given().log().all().when().get("http://localhost:8080/actuator/info/").then().log().all()
.statusCode(200);
}
}
Despite that after running the tests I get the following error:
org.testcontainers.containers.ContainerLaunchException: Container startup failed
Caused by: org.testcontainers.containers.ContainerFetchException: Can't get Docker image: RemoteDockerImage(imageName=mongo:3.2.4, imagePullPolicy=DefaultPullPolicy())
at org.testcontainers.containers.GenericContainer.getDockerImageName(GenericContainer.java:1279)
at org.testcontainers.containers.GenericContainer.logger(GenericContainer.java:613)
at org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:320)
... 58 more
Caused by: java.lang.IllegalStateException: Can not connect to Ryuk at localhost:32770
at org.testcontainers.utility.ResourceReaper.start(ResourceReaper.java:176)
at org.testcontainers.DockerClientFactory.client(DockerClientFactory.java:168)
at org.testcontainers.LazyDockerClient.getDockerClient(LazyDockerClient.java:14)
at org.testcontainers.LazyDockerClient.listImagesCmd(LazyDockerClient.java:12)
at org.testcontainers.images.LocalImagesCache.maybeInitCache(LocalImagesCache.java:68)
at org.testcontainers.images.LocalImagesCache.get(LocalImagesCache.java:32)
at org.testcontainers.images.AbstractImagePullPolicy.shouldPull(AbstractImagePullPolicy.java:18)
at org.testcontainers.images.RemoteDockerImage.resolve(RemoteDockerImage.java:59)
at org.testcontainers.images.RemoteDockerImage.resolve(RemoteDockerImage.java:26)
at org.testcontainers.utility.LazyFuture.getResolvedValue(LazyFuture.java:20)
at org.testcontainers.utility.LazyFuture.get(LazyFuture.java:27)
at org.testcontainers.containers.GenericContainer.getDockerImageName(GenericContainer.java:1277)
... 60 more
答案1
得分: 4
如果你还没有看过:https://github.com/testcontainers/testcontainers-java/issues/3166
GitHub用户@bsideup提出了三个选项。当然,这些只适用于使用Docker for Mac的Mac用户。
- 使用包含修复的Testcontainers 1.15.0-rc2版本
- 在Docker for Mac 2.4.0中禁用gRPC FUSE
- 降级到Docker for Mac 2.3.x版本
对我来说,禁用gRPC(使用这个方法)解决了这个问题,所以我将其作为一个参考留下。根据你的工作流程,不使用gRPC FUSE可能会产生重大影响。因此,最好检查一下是否可以接受,或者最好降级到Docker for Mac 2.3.x。我没有选择第一个选项,因为似乎它不会停止容器,这对我来说是所有选项中最糟糕的。
英文:
If you haven't seen yet: https://github.com/testcontainers/testcontainers-java/issues/3166
github user @bsideup outlined three options. This will of course only apply to you if you are a Mac User using Docker for Mac.
- use Testcontainers 1.15.0-rc2 that includes the fix
- Disable gRPC FUSE in Docker for Mac 2.4.0
- Downgrade to Docker for Mac 2.3.x
This (disable gRPC) solved the issue for me so I leave this as a reference. Not using gRPC FUSE can have significant impact depending on your workflow. So you better check if that is fine or better downgrade to Docker for Mac 2.3.x. I did not pick the first option as it seems it does not stop containers which is the worst of all the options for me.
答案2
得分: 0
这个异常出现在使用Ubuntu操作系统并构建Java项目时。集成测试立即开始失败。尝试了不同的选项,但无法解决这个问题。
在Ubuntu操作系统中,为了访问docker命令,我们使用root权限(即我们在docker命令前使用sudo命令)。为了构建Java项目,我使用了sudo命令。请参考下面的命令。
sudo ./gradlew clean build
上述命令解决了这个问题。
英文:
This exception came when using Ubuntu operating system and when building the java project. The integration test started to fail at once. Tried with different option but could not resolve the issue.
In Ubuntu OS, in order to access the docker command we use root permission(i.e We use sudo command with docker command). In order to build the java project I have used the sudo command. Please refer the below command.
> sudo ./gradlew clean build
The above command fixed the issue.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论