Developer87
Developer87

Reputation: 2708

Is it possible to simulate connection timeout using wiremock tools?

I know that it can simulate SocketTimeoutException by using withFixedDelay, but what about ConnectionTimeoutException?

Upvotes: 29

Views: 34935

Answers (5)

jfk
jfk

Reputation: 5307

The following code mock a get call to /service-url where it returns only after the duration specified.

import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder;
import java.time.Duration;
import static java.lang.Math.toIntExact;

void mockServiceUrlWithDelay(Duration delay) throws JSONException {
        ResponseDefinitionBuilder jsonResponse = aResponse()
                .withStatus(200)
                .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE)
                .withBody(new JSONObject() 
                        .put("key", "value") 
                        .toString())
                .withFixedDelay(toIntExact(delay.toMillis()));
        stubFor(get(urlPathEqualTo("/service-url")).willReturn(jsonResponse));
    }

Upvotes: 0

Stef Heyenrath
Stef Heyenrath

Reputation: 9830

When using WireMock.Net, adding a delay is also possible.

Example:

var server = WireMockServer.Start();

// add a delay of 30 seconds for all requests
server.AddRequestProcessingDelay(TimeSpan.FromSeconds(30));

or

var server = WireMockServer.Start();
server
  .Given(Request.Create().WithPath("/slow"))
  .RespondWith(
    Responses.Create()
      .WithStatusCode(200)
      .WithBody(@"{ ""msg"": ""Hello I'm a little bit slow!"" }")
      .WithDelay(TimeSpan.FromSeconds(10)
  )
);

Upvotes: 3

DaveyDaveDave
DaveyDaveDave

Reputation: 10612

It seems that the answer to this question has been "No", since version 2.0.8-beta.

Tom (author of WireMock) explains why in this GitHub issue:

It's basically impossible to reliably force connection timeouts in pure Java at the moment.

It used to be the case that you could inject a delay before calling .accept() on the socket, but that stopped working a while back, I guess due to a change in the implementation internals.

My recommendation at the moment would be to use a tool that works at the level of the network stack. iptables ... -j DROP type commands will do the trick, or if you want a level of automation over this you can use tools such as https://github.com/tomakehurst/saboteur or https://github.com/alexei-led/pumba.

He also goes on to explain that just stopping WireMock doesn't achieve the same thing:

shutting down WireMock won't have the same effect - when a port is not being listened on, you get a TCP RST (reset) packet back, whereas a connection timeout happens when you get nothing back from the server in the timeout window after your initial SYN packet.

Upvotes: 8

Tom
Tom

Reputation: 4149

Yes it is possible to do this with WireMock by calling addDelayBeforeProcessingRequests(300) against the Java API or posting the following to http://<host>:<port>/__admin/socket-delay:

{ "milliseconds": 300 }

(Obviously replacing 300 with however many milliseconds you'd like to delay by)

Upvotes: 11

Christopher Batey
Christopher Batey

Reputation: 684

Checkout https://github.com/tomakehurst/saboteur which allows you to simulate network issues. Or you can do it your self with iptables.

Upvotes: 4

Related Questions