Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix "NoHttpResponseException" when running Wiremock on jenkins?

I start a wiremock server in a integration test.

The IT pass in my local BUT some case failed in jenkins server, the error is

localhost:8089 failed to respond; nested exception is org.apache.http.NoHttpResponseException: localhost:8089 failed to respond

I try to add sleep(3000) in my test, that can fix the issue, But I don’t know the root cause of the issue, so the work around not a good idea

I also try to use @AutoConfigureWireMock(port=8089) to replace WireMockServer to start wiremock server, that could fix the problem, BUT I don't know how to do some configuration to the wiremock server using the annotation @AutoConfigureWireMock(port=8089).

Here my code to start a wiremock server, any suggestion to fix "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()

}
like image 654
Alvin Avatar asked Apr 11 '19 04:04

Alvin


People also ask

What does NoHttpResponseException mean?

NoHttpResponseException means that the client didn't get a response, not that the server didn't get and/or processed the request.

What is Wiremocks?

WireMock is a tool that can mimic the behavior of an HTTP API and capture the HTTP requests send to that API. It allows us to: Configure the response returned by the HTTP API when it receives a specific request. Capture the incoming HTTP requests and write assertions for the captured HTTP requests.


Video Answer


1 Answers

Each time a wiremock endpoint is destroyed (because the wiremock server is restarted between tests) and a new one is created for a new test, it takes 2 seconds (as stated in documentation), until the application detects that the previous http connection is broken and a new one has to be opened.

The solution is to simply override the default keep-alive connection behaviour for every stub using .withHeader("Connection", "close"). Something like:

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

Also possible to do it globally using a transformer:

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";
    }
}

Then this transformer have to be registered when you create the wiremock server:

new WireMockServer(
    options()
        .port(port)
        .extensions(NoKeepAliveTransformer.class)
)
like image 162
Roland Avatar answered Sep 20 '22 02:09

Roland