Jenkins Junit 中的 WireMock - BindException:地址已在使用中

WireMock in Junit in Jenkins - BindException: Address already in use

我有一些使用 WireMock 的 Junit 测试。在本地测试通过,但在 Jenkins 上我得到一个错误 java.lang.RuntimeException: java.net.BindException: Address already in use

在 WireMock 配置中,我设置了 dynamicHttpsPort()(根据文档“在启动时随机分配 HTTPS 端口”)并且它在本地工作,但在 Jenkins 上它失败。

我的 WireMock 配置是

    @Rule
    public WireMockRule wireMockRule = new WireMockRule(wireMockConfig()
            .dynamicHttpsPort()
            .keystorePath(certsDir.resolve("server.jks").toString())
            .keystorePassword(MY_PASS)
            .keystoreType("JKS")
    );

我有 2 个 JUnit 类,我在其中创建了一个新的 WireMockRule,它们可以同时 运行。在 类 之一中,我有 4 个测试,在另一个中,我有一个测试。 5 个测试全部失败。

完整的堆栈跟踪是:

com.github.tomakehurst.wiremock.common.FatalStartupException: java.lang.RuntimeException: java.net.BindException: Address already in use
    at com.github.tomakehurst.wiremock.WireMockServer.start(WireMockServer.java:146)
    at com.github.tomakehurst.wiremock.junit.WireMockRule.evaluate(WireMockRule.java:68)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access[=11=]0(ParentRunner.java:53)
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
    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.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:172)
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:104)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:70)
Caused by: java.lang.RuntimeException: java.net.BindException: Address already in use
    at com.github.tomakehurst.wiremock.jetty9.JettyHttpServer.start(JettyHttpServer.java:139)
    at com.github.tomakehurst.wiremock.WireMockServer.start(WireMockServer.java:144)
    ... 23 more
Caused by: java.net.BindException: Address already in use
    at sun.nio.ch.Net.bind0(Native Method)
    at sun.nio.ch.Net.bind(Net.java:433)
    at sun.nio.ch.Net.bind(Net.java:425)
    at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
    at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
    at wiremock.org.eclipse.jetty.server.ServerConnector.open(ServerConnector.java:321)
    at wiremock.org.eclipse.jetty.server.AbstractNetworkConnector.doStart(AbstractNetworkConnector.java:80)
    at wiremock.org.eclipse.jetty.server.ServerConnector.doStart(ServerConnector.java:236)
    at wiremock.org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at wiremock.org.eclipse.jetty.server.Server.doStart(Server.java:366)
    at wiremock.org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at com.github.tomakehurst.wiremock.jetty9.JettyHttpServer.start(JettyHttpServer.java:137)
    ... 24 more

找到解决方案here

The problem is that you're not setting the HTTP port on either, which will always be active and default to 8080 (hence them clashing). If you add dynamicPort() to both configs it should fix it.

所以添加 dynamicPort() 修复了它:

    @Rule
    public WireMockRule wireMockRule = new WireMockRule(wireMockConfig()
            .dynamicPort()
            .dynamicHttpsPort()
            .keystorePath(certsDir.resolve("server.jks").toString())
            .keystorePassword(MY_PASS)
            .keystoreType("JKS")
    );