Java Testcontainers-无法连接到公开的端口
我使用javax.mail实现了一个POP3服务器和客户端,只是为了尝试与Docker进行集成测试。因此,我基于openjdk:8-jre映像创建了两个Docker映像,并将我的JAR复制到它们并启动了它。根据我的配置(见下文),它正在工作。他们正在互相交谈 但是,如果您希望进行多个集成测试,那么为每个测试构建一个映像并启动它们将是一件乏味的事情。我也不知道如何自动生成结果。 但后来我偶然发现了TestContainers,这似乎对实现这些测试有很大帮助 因此,我开始使用POP3服务器映像作为GenericContainer将这些测试移植到TestContainers,并在JUnit测试方法中启动POP3客户机类。我暴露了我的POP3服务器正在监听的端口24999。但当我尝试连接到服务器时,出现以下错误:Java Testcontainers-无法连接到公开的端口,java,docker,junit,dockerfile,testcontainers,Java,Docker,Junit,Dockerfile,Testcontainers,我使用javax.mail实现了一个POP3服务器和客户端,只是为了尝试与Docker进行集成测试。因此,我基于openjdk:8-jre映像创建了两个Docker映像,并将我的JAR复制到它们并启动了它。根据我的配置(见下文),它正在工作。他们正在互相交谈 但是,如果您希望进行多个集成测试,那么为每个测试构建一个映像并启动它们将是一件乏味的事情。我也不知道如何自动生成结果。 但后来我偶然发现了TestContainers,这似乎对实现这些测试有很大帮助 因此,我开始使用POP3服务器映像作为G
com.sun.mail.util.MailConnectException: Couldn't connect to host, port: localhost, 32782; timeout -1;
nested exception is:
java.net.ConnectException: Connection refused
...
TestContainers中可能缺少一些设置。你能帮帮我吗
以下是我正在使用的代码:
public class DockerPop3AutocryptKeyProvidingAndReceivingTest {
@Test
public void test() throws InterruptedException {
GenericContainer container = new GenericContainer<>("immerfroehlich/emailfilter:latest")
.withExposedPorts(24999);
container.start();
String host = container.getContainerIpAddress();
String port = container.getFirstMappedPort().toString();
//The following is simplified, but copied from the working jar used in the Docker Client image/container
MyPOP3Client client = new MyPOP3Client(host, port);
client.connect();
container.stop();
}
}
这是在服务器Jar中运行的代码的简化版本:
MyPOP3Server server = new MyPOP3Server();
server.listenToPort(24999);
请告诉我我错过了什么。这里怎么了
谢谢并致以亲切的问候。由于您的邮件服务器和客户端正在容器中运行,我认为您应该连接到端口24999,而不是映射端口尝试
容器。getMappedPort(24999)
而不是getFirstMappedPort
。您的docker映像可能会暴露几个端口。尝试添加http检查
new GenericContainer<>("immerfroehlich/emailfilter:latest")
.withExposedPorts(24999)
.waitingFor(new HttpWaitStrategy().forPort(24999)
.withStartupTimeout(Duration.ofMinutes(5)));
其他答案中有一些很好的建议;我将用几个其他提示来补充这些内容: 正如已经建议的那样:
- 绝对要添加
,这样您就可以看到容器的日志输出——也许现在或将来会出现一些有用的东西。拥有总是好的LogConsumer
- 在容器启动后,即启动客户端之前,设置断点
- 在终端中运行
docker ps-a
- 首先,检查您的容器是否正在运行且未退出。如果它已退出,请从终端查看容器的日志
- 其次,检查
输出中的端口映射。您应该看到类似于docker ps
(但第一个端口号是随机的)0.0.0.0:32768->24999/tcp
- 在IDE中评估container.getFirstMappedPort(),并检查返回的端口号是否与随机公开的端口号相同。除非您在本地计算机上安装了非常不寻常的Docker,否则应该可以通过
+此端口访问此容器localhost:
- 如果您已经做到这一点,那么很可能是容器或客户机代码出了问题。您可以尝试将不同的客户端连接到正在运行的容器,如果手头没有另一个POP3客户端,甚至可以使用类似的方法
docker run -p 24999 immerfroehlich/emailfilter:latest
您可能会发现,这有助于将问题空间划分为更小的部分。谢谢您的帮助。这使我找到了解决办法。这是缺少WaitStrategy和端口映射问题的结合 以下是我所做的: 1) 在MyPop3Server.listenToPort(字符串端口)方法中,我添加了System.out.println:
public class MyPop3Server {
public void listenToPort(String port) {
//simplified: do initialization and listenToPort
System.out.println("Awaiting Connection...");
}
}
在我的测试中,我添加了一个LogMessageWaitStrategy,用于侦听“等待连接”
以下是整个已更改且正在运行的测试代码:
public class DockerPop3AutocryptKeyProvidingAndReceivingTest {
@Test
public void test() throws InterruptedException {
GenericContainer container = new GenericContainer<>("immerfroehlich/emailfilter:latest")
.waitingFor(Wait.forLogMessage("Awaiting Connection.*", 1))
.withExposedPorts(24999);
container.start();
String host = container.getContainerIpAddress();
String port = container.getMappedPort(24999).toString();
//The following is simplified, but copied from the working jar used in the Docker Client image/container
MyPOP3Client client = new MyPOP3Client(host, port);
client.connect();
container.stop();
}
}
公共类Dockerp3AutocryptKeyProvisingandReceivingTest{
@试验
public void test()引发InterruptedException{
GenericContainer=新的GenericContainer(“immerfroehlich/emailfilter:最新”)
.waitingFor(Wait.forLogMessage(“waiting Connection.*”,1))
.具有暴露端口(24999);
container.start();
字符串host=container.getContainerIpAddress();
String port=container.getMappedPort(24999.toString();
//以下内容已简化,但复制自Docker客户端映像/容器中使用的工作jar
MyPOP3Client client=新的MyPOP3Client(主机、端口);
client.connect();
container.stop();
}
}
谢谢大家。您能否在容器启动后创建一个断点,并检查它以查看映射了哪个端口。无论如何,如果您执行类似于port=container.getMappedPort(24999)的操作,好的,我将更改为port=container.getMappedPort(24999),但它无论如何都不工作。我做了调试,但我不确定在哪里看。container.exposedPorts为[24999];container.portBindings是[]。不,这是我最初做的。我只是想提一下,这样就没有人会问你的服务器是否正常工作了。目前,服务器在容器中运行,客户端在JUnit测试中本地运行。我试过了,但没用。如果你在客户端连接之前设置了一个断点,你能使用telnet或其他邮件客户端连接到映射端口吗?不,它也不起作用。但后来我在命令行上用Docker启动了容器,它也不起作用。然后我读了docker手册中关于网络的内容,我有了一个想法。因此,两个容器可以相互通信,但主机不能与容器通信。手册中说网桥网络是默认网络。它有什么作用?它允许两个容器相互通信(可能更多)。所以我读了关于主机网络的文章。它基本上说在Linux上它和主机在同一个网络上。。。。。。我直接用“docker run-I-t——网络主机immerfroehlich/emailfilter:latest”和tada启动容器,我可以连接到
public class MyPop3Server {
public void listenToPort(String port) {
//simplified: do initialization and listenToPort
System.out.println("Awaiting Connection...");
}
}
GenericContainer container = new GenericContainer<>("immerfroehlich/emailfilter:latest")
.waitingFor(Wait.forLogMessage("Awaiting Connection.*", 1))
.withExposedPorts(24999);
container.getMappedPort(24999);
public class DockerPop3AutocryptKeyProvidingAndReceivingTest {
@Test
public void test() throws InterruptedException {
GenericContainer container = new GenericContainer<>("immerfroehlich/emailfilter:latest")
.waitingFor(Wait.forLogMessage("Awaiting Connection.*", 1))
.withExposedPorts(24999);
container.start();
String host = container.getContainerIpAddress();
String port = container.getMappedPort(24999).toString();
//The following is simplified, but copied from the working jar used in the Docker Client image/container
MyPOP3Client client = new MyPOP3Client(host, port);
client.connect();
container.stop();
}
}