在詹金斯上运行Wiremock时如何解决“ NoHttpResponseException”?

Alv*_*vin 1 spring-boot wiremock

我在集成测试中启动了一个Wiremock服务器。

jenkins服务器中的IT在我的本地BUT中通过失败,错误是

localhost:8089 failed to respond; nested exception is org.apache.http.NoHttpResponseException: localhost:8089 failed to respond
Run Code Online (Sandbox Code Playgroud)

我尝试添加sleep(3000)可以解决问题的测试,但是我不知道问题的根本原因,因此解决此问题不是一个好主意

我也尝试使用@AutoConfigureWireMock(port=8089)替换WireMockServer来启动Wiremock服务器,这可以解决问题,但是我不知道如何使用注释对Wiremock服务器进行一些配置@AutoConfigureWireMock(port=8089)

在这里,我的代码启动一个Wiremock服务器,对解决“ NoHttpResponseException”有什么建议吗?

@ContextConfiguration(
initializers = ConfigFileApplicationContextInitializer.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
class BaseSpec extends Specification {
@Shared
WireMockServer wireMockServer

def setupSpec() {

wireMockServer = new WireMockServer(options().port(PORT).jettyHeaderBufferSize(12345)
.notifier(new ConsoleNotifier(new Boolean(System.getenv(“IT_WIREMOCK_LOG”) ?: ‘false’))) 
.extensions(new ResponseTemplateTransformer(true)))

wireMockServer.start()

}
Run Code Online (Sandbox Code Playgroud)

小智 9

Coorect,正如 G. Demecki 已经写的那样,它与 Wiremock 无关。它与调用wiremock 的应用程序服务器有关。今天,重用连接来提高微服务基础设施的性能是很常见的。所以 connection-close-header、RequestScoped 客户端等没有用。

检查 apache http 客户端:

httpclient-4.5.2 - PoolingHttpClientConnectionManager

文件

旧连接的处理在 4.4 版中发生了变化。以前,代码会默认检查每个连接,然后再重新使用它。如果自上次使用连接以来经过的时间超过已设置的超时,代码现在只检查连接。默认超时设置为 2000 毫秒

每次销毁一个 wiremock 端点并为新的测试类创建一个新的端点时,需要 2 秒钟,直到您的应用程序检测到之前的连接中断并且必须打开一个新的连接。如果您不等待 2 秒,则可能会抛出此类 NoHttpResponseException,具体取决于上次检查。

所以aThread.sleep(2000);看起来很丑。但它并没有那么糟糕,只要我们知道为什么需要这样做。

  • 感谢这篇有用的文档 - 我不知道它被精确设置为 2 秒!顺便说一句:在测试中睡 2 秒是非常低效的想法,很抱歉,但我不能投票;) (3认同)
  • 为其测试实例定制 apache http 客户端为我解决了这个问题。修复方法是创建新的 PoolingHttpClientConnectionManager 并将超时从 2 秒更改为 10 毫秒:按照 https://github.com/tomakehurst/wiremock/issues/97#issuecomment-605041024 中的建议`setValidateAfterInactivity(10)` (2认同)

Rol*_*and 8

每次销毁一个wiremock端点(因为wiremock服务器在测试之间重新启动)并为新测试创建一个新端点时,需要2秒(如文档中所述),直到应用程序检测到先前的http连接已断开并且必须打开一个新的。

解决方案是简单地使用 覆盖每个存根的默认保持活动连接行为.withHeader("Connection", "close")。就像是:

  givenThat(get("/endpoint_path")
            .withHeader("Authorization", equalTo(authHeader))
            .willReturn(
               ok()
                 .withBody(body)
                 .withHeader(HttpHeaders.CONNECTION, "close")
            )
  )
Run Code Online (Sandbox Code Playgroud)

也可以使用变压器全局执行此操作:

public class NoKeepAliveTransformer extends ResponseDefinitionTransformer {

    @Override
    public ResponseDefinition transform(Request request,
                                        ResponseDefinition responseDefinition,
                                        FileSource files,
                                        Parameters parameters) {
        return ResponseDefinitionBuilder
            .like(responseDefinition)
            .withHeader(CONNECTION, "close")
            .build();
    }

    @Override
    public String getName() {
        return "keep-alive-disabler";
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在创建wiremock服务器时必须注册这个变压器:

new WireMockServer(
    options()
        .port(port)
        .extensions(NoKeepAliveTransformer.class)
)
Run Code Online (Sandbox Code Playgroud)


G. *_*cki 5

Apache HttpClient时常遭受痛苦NoHttpResponseException。这是一个非常老的问题。

无论如何,我想就您而言,问题可能是由在测试之间重新启动WireMock服务器引起的,同时,Apache HttpClient池化HTTP连接并尝试在测试之间重用它们。在这种情况下,有两种解决方案:

  1. 在测试中禁用池HTTP连接。这是有道理的,因为在测试执行期间可以重新启动WireMock服务器被认为是正常的。或者,制作WireMock存根以始终"Connection": "close"在标头之间发送。结果将是相同的。

  2. 从Apache HttpClient切换到Square OkHttp。OkHttp虽然默认情况下会合并http连接,但始终能够从过时的连接中正常恢复。不幸的是,Apache的库不是那么聪明。