Hi - I am using version 1.42, and am using JUnit 4 and the SpringJUnit4ClassRunner.
I have a JUnit test case in which I have created a number of test cases that establish GET mappings, all of which work when the test class is run. However, when I add a PUT mapping (the URL is very similar but not identical to the GETs) it often fails with a read connect timeout. Although other times it succeeds quite rapidly. What I've found is that if I do a Thread.sleep(5000) at the beginning of the test method, it works consistently.
Could the start-up of the server not be fully complete when the test method begins? Maybe the SpringJUnit4ClassRunner is not waiting for the rule to be fully initialized.
Have you ever encountered an issue like this?
This isn't something I've seen. I don't use Spring so I don't know how its test runner behaves with respect to rules. The default JUnit runner always ensures that the server has started before the tests are run in my experience.
Could the Spring runner be spawning additional threads?
Do you have a small sample project that reproduces this?
I will try to reproduce without spring, and try to make a sample with spring. Thanks! I seriously doubt it has anything to do with the PUT on the server side and has everything to do wit homing on the client side.
On Feb 12, 2014, at 7:38 AM, yogurtearl [email protected] wrote:
Do you have a small sample project that reproduces this?
—
Reply to this email directly or view it on GitHub.
I have prepared a small sample that illustrates the problem. The issue occurs even without the SpringJUnit4TestRunner - I am just using the regular JUnit runner.
The key factors for me seem to be:
The test has 3 test methods, two of which perform a GET and the third of which performs a PUT. If I run the PUT test case by itself, or as the first test case (depending on your test environment there are various ways to do this), it works. But when it runs after a GET test case, it never response - I put a timeout on the test so that it will fail after a while..
I am using Spring's restTemplate to execute all of the requests. When I use Apache's HttpClient, the test works without error. Also, if I put a Thread.sleep for 5 seconds before making the PUT request, it works even after the prior GET test cases.
Could there be some timing-related issue exposed by the the particular way the restTemplate and its collaborators read the response? I have debugged into both the restTemplate and the WireMockServer and haven't had much luck.
I love WireMock and really want to use it for all kinds of things, but my organization makes heavy use of the restTemplate and these intermittent failures will likely prevent our using it.
Here is the test case:
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertThat;
public class WireMockRestTemplateTest {
private final RestTemplate restTemplate = new RestTemplate();
@Rule
public WireMockRule wireMockRule = new WireMockRule(51080);
@Test
public void testA() throws IOException {
stubFor(get(urlEqualTo("/cars/1"))
.willReturn(aResponse()
.withStatus(200)
.withBody("{ \"name\": \"Subaru Outback\" }")));
final ResponseEntity<String> response = restTemplate.getForEntity("http://localhost:51080/cars/1", String.class);
assertThat(response.getBody(), containsString("Subaru"));
}
@Test
public void testB() throws IOException {
stubFor(get(urlEqualTo("/cars?nameLike=Subaru"))
.willReturn(aResponse()
.withStatus(200)
.withBody("[ { \"name\": \"Subaru Outback\" } ]")));
final ResponseEntity<String> response = restTemplate.getForEntity("http://localhost:51080/cars?nameLike=Subaru", String.class);
assertThat(response.getBody(), containsString("Subaru"));
}
// without the timeout the test will never end
// however, running this test alone or before the others works
@Test(timeout = 10000)
public void testC() throws IOException, InterruptedException {
// uncommenting this will make the test work
// Thread.sleep(5000);
stubFor(put(urlEqualTo("/cars/1"))
.withRequestBody(containing("Nissan"))
.willReturn(aResponse()
.withStatus(200)
.withFixedDelay(0)
.withBody("{ \"name\\\": \"Nissan Maxima\" }")));
restTemplate.put("http://localhost:51080/cars/1", "{ \"name\": \"Nissan\"}");
}
}
Here are the maven dependencies I used:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock</artifactId>
<version>1.42</version>
<scope>test</scope>
</dependency>
</dependencies>
When I upgrade spring-web to 3.2.8.RELEASE, this works without issue. Maybe it was an issue with the restTemplate that was addressed in a later version, or I suppose it still could be an issue with WireMock that some shift in the restTemplate performance profile has avoided. Well it's progress so I think I'm all set
Glad you found a fix. I'll keep an eye out for a recurrence of this with other types of client.
It turns out this is still happening with Spring 3.2.8 and I've tried it with WireMock 1.44 as well. The particular sample I shared above seems to work, but other test classes fail with the same type of error. It seems to be affected by the test cases that have executed before it. For me it primarily happens on PUT, though some of my colleagues have seen it on POST.
Could you provide a code sample for where it's still failing?
Are you running with any parallelism?
I seem to be hitting the same error, and I'm not using Spring. When I do a put as part of a test run (total 20 seconds) it fails every time, but when I run the test by itself, it passes every time. Also adding the Thread.sleep(5000) solves the problem. Using WireMock 1.45, and no parallelism.
java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:258)
at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:709)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:652)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:674)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1218)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:379)
at com.google.api.client.http.javanet.NetHttpResponse.<init>(NetHttpResponse.java:36)
at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:94)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:965)
at com.knewton.api.client.KnewtonUserContext.executeAndDisconnect(KnewtonUserContext.java:205)
at com.knewton.api.client.KnewtonUserContext.doPut(KnewtonUserContext.java:180)
at com.knewton.api.client.operations.LearningInstanceOperations.update(LearningInstanceOperations.java:45)
at com.knewton.api.client.operations.LearningInstanceOperationsTest.updateLearningInstance(LearningInstanceOperationsTest.java:123)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at com.github.tomakehurst.wiremock.junit.WireMockRule$1.evaluate(WireMockRule.java:74)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
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$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
We found that this was due to using the java http client. We switched to apache's and the issue went away.
On Apr 25, 2014, at 12:41 PM, Shawn Lauzon [email protected] wrote:
I seem to be hitting the same error, and I'm not using Spring. When I do a put as part of a test run (total 20 seconds) it fails every time, but when I run the test by itself, it passes every time. Also adding the Thread.sleep(5000) solves the problem. Using WireMock 1.45, and no parallelism.
java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:258)
at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:709)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:652)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:674)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1218)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:379)
at com.google.api.client.http.javanet.NetHttpResponse.(NetHttpResponse.java:36)
at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:94)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:965)
at com.knewton.api.client.KnewtonUserContext.executeAndDisconnect(KnewtonUserContext.java:205)
at com.knewton.api.client.KnewtonUserContext.doPut(KnewtonUserContext.java:180)
at com.knewton.api.client.operations.LearningInstanceOperations.update(LearningInstanceOperations.java:45)
at com.knewton.api.client.operations.LearningInstanceOperationsTest.updateLearningInstance(LearningInstanceOperationsTest.java:123)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at com.github.tomakehurst.wiremock.junit.WireMockRule$1.evaluate(WireMockRule.java:74)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
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$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
—
Reply to this email directly or view it on GitHub.
That doesn't really answer why it doesn't work; I assume that WireMock doesn't require usage of the Apache client, does it?
Yeah I know what you mean - it could be a subtle bug in WireMock, but the
consensus among a few other developers I've talked to is that the Java http
client is notoriously unreliable about losing connections. We standardized
on the Apache one after having encountered these issues with normal HTTP
servers, and the issue with WireMock went away at the same time. I suspect
WireMock is just behaving in a way that exposes the issue more often than
with other servers.
Wondering if upgrading Jetty (from 6 where it currently is) might help here. I'm working through this at the moment, but it's going to take a while as the fault injection stuff couples quite tightly to stuff that no longer exists in Jetty 9.
Jetty 9 won't work on dalvik with android API 15... :/
If I remember correctly, Joakim ( one of the jetty developers ) said Jetty 8 would work.
Ah, thanks for the heads-up.
I hadn't realised anyone had WireMock working on Android at all TBH. Is there a fork somewhere for this, or just an alternative build target?
I think I'm also experiencing this problem, with Apache HttpClient 4.3.4, WireMock 1.46, Sun Java 1.7.0_45-b18, using RestTemplate from Spring 4.0.5. It just hangs. Adding Thread.sleep(5000) DOES NOT help, it still hangs.
Here are stack traces of the two threads that seem to be relevant:
"1060382216@qtp-129682241-1" prio=10 tid=0x00007f4f7549c000 nid=0x6861 runnable [0x00007f4f6cec7000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:152)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at org.mortbay.io.ByteArrayBuffer.readFrom(ByteArrayBuffer.java:382)
at org.mortbay.io.bio.StreamEndPoint.fill(StreamEndPoint.java:114)
at org.mortbay.jetty.bio.SocketConnector$Connection.fill(SocketConnector.java:198)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:290)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228)
at com.github.tomakehurst.wiremock.jetty.DelayableSocketConnector$1.run(DelayableSocketConnector.java:49)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
"main" prio=10 tid=0x00007f4f74008800 nid=0x682e runnable [0x00007f4f7c865000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:152)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:136)
at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:152)
at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:270)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:140)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:260)
at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:161)
at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:153)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:271)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:123)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:254)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:87)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:52)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:542)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:503)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:445)
Thanks for the info. I saw something similar when I tried replicating this problem.
As I mentioned above, I'm pretty sure it's a Jetty bug, and I'm planning some work to upgrade the Jetty version, hopefully over the next few weeks.
In the meantime, have you tried switching to @ClassRule so there's no web server restart between test cases?
Thanks! With @ClassRule it seems to work.
I can also confirm that @ClassRule works.
I think problem is not related only to PUT request. I'm using WireMock for tests in conjunction with RetroFit, and for me it seems that first POST request after series of GET requests fails with "Connection reset" error.
As I mentioned above, I'm pretty certain this is a web server problem. We're working on upgrading this at the moment, so hopefully that'll fix it.
Is there any update about this issue? I'm using the latest version of WireMock with JUnit 4.11 and I see the same error with PUT calls.
Thanks!
@Mahoney has been working on abstracting the web server interfaces and adding Jetty 9 support (which we believe will fix this issue).
Still some work to do to get fault responses working though I think.
In the meantime, are you able to switch to class level JUnit rules? This has worked around the issue for some people.
I'm also facing this hang issue with wiremock 1.52. Using class level rule doesn't resolve the issue. I noticed that the issue only happens within a test case which has "GET" prior to the "PUT". Finally, I changed the "Connection" recorded in the JSON from "keep-alive" to "close". It resolves my issue. FYI
Thanks for the tip. There's a jetty 9 upgrade in the works, which should fix this.
Unfortunately, I've used Wiremock standalone v1.55 and the issue still occurs. I was able to workaround it by sleeping for some time. Switching to ClassRule did not solve it.
Hi Tom,
Unfortunately, I am using WireMock standalone V1.56 but the issue is still exists. Tom can you please provide me the solutions. Please find my below scenario:
I have recorded some soap web services and now I want to do load testing on my application using Wiremock response. When I put 100 users then it is giving me IO exceptions because most of the thread does wait for the IO operations and CPU usage is just 10% only.
Could you please suggest what I need to do?
Without seeing a few more details about your setup it's difficult to say whether the problems you're having are related to this bug (although it sound like they're not from the details you've given).
Can I suggest that you post some details of your test setup, code and output to the mailing list? It'll get more eyeballs that way.
Hi Tom,
Thanks for your quick response. Please find below more details if it help you to understand my problem which I am facing.
I have executed the test with 100 users after increasing the concurrent threads, container threads and queue size to 400. There were no CPU increase, it uses mainly 5% to 10%. I have seen thread dump, more threads are waiting for I/O operations.
Thread dump analysis:
"[ACTIVE] ExecuteThread: '99' for queue: 'weblogic.kernel.Default (self-tuning)'" daemon prio=10 tid=0x00007ffa64099800 nid=0x12d0 runnable [0x00007ffa2aeaa000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:258)
at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
- locked <0x00000007e04be7e0> (a java.io.BufferedInputStream)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:690)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:633)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1195)
- locked <0x00000007e045b118> (a sun.net.www.protocol.http.HttpURLConnection)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:379)
at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.getResponseCode(URLConnectionHTTPConduit.java:266)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1555)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1525)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1330)
at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:56)
at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:215)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:638)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
- locked <0x00000007e0437e00> (a org.apache.cxf.phase.PhaseInterceptorChain)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:514)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:423)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:326)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:279)
I am running WireMock server with below command:
java -jar wiremock-1.56-standalone.jar --port=9089 --verbose --jetty-accept-queue-size=400 --jetty-acceptor-threads=400 --container-threads=400
Thanks
Anil
As I mentioned, please can you post on the mailing list rather than here. There are at least a couple of people on there who may be able to provide some insight.
could you please provide me the mailing list so that I can mail with all the details ?
https://groups.google.com/forum/#!forum/wiremock-user (linked to from the docs and the README for future reference)
hello,
I am running in a similar issue using wiremock with cucumber. If i run the tests individiually I almost never run into any problems but running them all after another I have a loads of failure due to wiremock not having enough time to initialise apparently.
Is there a method where we can interrogate wiremock to make sure it has initialised properly (other than mocking a ping and testing it respond)?
Thanks
Have you tried the 2.x-beta version?
Nope, we are on 1.58. Would 2.x-beta require some refactoring on our side?
My actual workaround is to start all wiremock right up front in the cucumber feature file, but its a bit brittle.
It probably won't require any refactoring. There are a few breaking changes around the edges e.g. the extensibility API, but even there the change isn't big.
Ok thanks we will give it a go then
I am having the same problem on Wiremock 2.1.9:
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:170)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
- locked <0x00000007862d2ae8> (a java.io.BufferedInputStream)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:704)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:647)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1536)
- locked <0x00000007862cbf40> (a sun.net.www.protocol.http.HttpURLConnection)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441)
- locked <0x00000007862cbf40> (a sun.net.www.protocol.http.HttpURLConnection)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
at org.springframework.http.client.SimpleClientHttpResponse.getRawStatusCode(SimpleClientHttpResponse.java:52)
at org.springframework.http.client.AbstractClientHttpResponse.getStatusCode(AbstractClientHttpResponse.java:33)
at org.springframework.security.oauth2.client.http.OAuth2ErrorHandler.hasError(OAuth2ErrorHandler.java:77)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:655)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:620)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.doExecute(OAuth2RestTemplate.java:128)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:595)
at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:423)
I am running Wiremock as a @ClassRule with Spring Boot. I only seem to observe this with Spring Boot 1.4.0, I did not not have this problem with Spring Boot 1.3.x. The issue is not reliably reproducible.
We have had this problem and lost a lot of time messing with versions of Spring and Wiremock, to no avail. I ultimately wrote what feels like a hacky solution that kept us moving. Interestingly, seems to add almost no time to the test runs, which suggests to me that once you did the wiremock endpoint and have it fail once, it's ready to go on the next call.
While I don't endorse this as a long-term solution, here is that hacky code:
private void waitForWireMockToBeReadyForPutCall(String urlPath, int port) {
boolean ready = false;
while (ready == false) {
try {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
restTemplate.put("http://localhost:" + port + urlPath, "");
ready = true;
} catch (ResourceAccessException e) {
ready = false;
}
}
}
We placed this after the call to mock the PUT endpoint. Hope it helps anyone stuck.
Is this of any help to anybody?
https://github.com/tomakehurst/wiremock/issues/132#issuecomment-253150133
RestTemplate with HttpURLConnection seems to be the common factor.
I observed similar situation when I upgraded from Apache HttpClient 4.3 to 4.5 (Spring Boot 1.2 to 1.4.).
Errors org.apache.http.NoHttpResponseException: <<SomeIP>> failed to respond were non deterministic. Issue was caused by managing persistent connections by Apache HttpClient - feature introduced in version 4.4 (http://archive.apache.org/dist/httpcomponents/httpclient/RELEASE_NOTES-4.4.x.txt). My solution is to close idle connections between tests.
On the other hand disabling persistent connections in Wiremock would be a nice feature,
I managed to resolve random Read timed out problems by using org.springframework.cloud.contract.wiremock.WireMockSpring.options from Spring cloud contract when setting up WireMockRule for tests.
Test execution speed was reduced significantly as it seems that Spring creates another Spring container for wiremock, but at least test haven't failed after that.
I'm using Spring boot 1.4.1, Spring cloud Camden.SR1 and spring-cloud-contract-wiremock 1.0.1.
@lidkowiak, How did you close idle connections between tests? I need the same fix. Thank you.
@tehjakey I use PoolingHttpClientConnectionManager :
java
@After
public void closeIdleConnections() {
// Close expired connections
connectionManager.closeExpiredConnections();
// Close connections
connectionManager.closeIdleConnections(0, TimeUnit.SECONDS);
}
I observe same problems on my integration tests.
I'm working with wiremock 2.4.1, spring-boot 1.4.1, jetty 9.3.14, org.apache.httpcomponents.httpclient 4.5.2.
If test are executed on local machine my tests are rarely (maybe 1 of 30 tests) failing.
1.1. If I use SimpleHttpClient (Standard Java Http Client) failing test hangs (eventually due to unlimited timeout) and waiting for a response.
1.2. If I use Apaches Http Client failing tests fails immediately with an NoHttpResponseException ( I/O exception (org.apache.http.NoHttpResponseException) caught when processing request to {}->http://localhost:15000: The target server failed to respond)
If tests are executed on our Jenkins instance tests are failing more frequently.
If I put a sleep statement between stubFor and service call, my tests are failing more frequently. Quite interestingly. (P.S: The difference is significant after putting sleep with 500ms I didn't see any successful test execution, I have 22 test in a single class, always at least a single test fails)
wireMockRule.stubFor(get(urlPathEqualTo(expectedURLPath)).willReturn( aResponse() .withStatus(500) .withHeader("Content-Type", "text/html;charset=ISO-8859-1") .withBodyFile(responseBodyFile))); sleep(); // when service.call();
And this is WireMock initialisation code:
@Rule public WireMockRule wireMockRule; @PostConstruct public void init() { wireMockRule = new WireMockRule(wireMockConfig().bindAddress( wiremockHost).port(wiremockPort).usingFilesUnderClasspath("path")); }
How can a thread sleep after stubFor call can make the problem worser?
Thank you.
I think this issue (along with https://github.com/tomakehurst/wiremock/issues/132) has become a dumping ground for any problem loosely associated with timing/synchronisation. I've made a couple of attempts to replicate the problems described here and #132 with no success.
I'm happy to keep investigating, but only only if someone is willing to post a fully-working project to GH with a test case that reliably reproduces the problem.
@tomakehurst thank you for quick feedback. I will try to setup a small project for you and push it into Github. Give me a couple of days please.
I was receiving random 500 errors from wiremock. The problem was caused by stale http connections in my application. The solution was to prevent the application from reusing connections. For applications using RestTemplate we configured the apache HttpClient to not reuse connections.
Full example...
@Bean
public RestTemplate restTemplate() {
return new RestTemplate(httpRequestFactory());
}
public HttpComponentsClientHttpRequestFactory httpRequestFactory() {
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory(httpClient());
requestFactory.setConnectTimeout(defaultConnectionTimeout);
requestFactory.setReadTimeout(defaultReadTimeout);
return requestFactory;
}
public HttpClient httpClient() {
HttpClientBuilder httpClient = HttpClients.custom().useSystemProperties();
LOGGER.warn("disabling connection reuse strategy on http client");
httpClient.setConnectionReuseStrategy(NoConnectionReuseStrategy.INSTANCE);
return httpClient.build();
}
We also had a springboot application using a thirdparty proxy which instantiated PoolingHttpClientConnectionManager directly and had to be configured via system property. We did this via static block in the test suite.
static {
// These properties configure the
// PoolingHttpClientConnectionManager. Setting keepAlive to false results in the connections being closed and
// thus prevents stale connection issues when interacting with wiremock stubs.
System.setProperty("http.keepAlive", "false");
System.setProperty("http.maxConnections", "1");
}
@tomakehurst Unfortunately, i can't share my code and haven't built a small example to share. I can tell you we've struggled with the random 500s and stale connections for several months. We saw the problems go away with 2 second sleeps, but the issue returned after some upgrades. Finally after debugging into the http client code in our application it was clearly stale connections causing the problem.
@tehjakey your workaround works in my case. thx :)
Great news. @im-bob-loucans worked on this with me. He found the origin of the problem and the first solution. Props to Bob.
Any idea why reusing connections caused the problem? It should be fine - if the WireMock server is kept running for multiple tests then the connections should continue to work, and if it's shut down then the connections should be closed off cleanly and new ones opened the next time.
@tomakehurst as I promised the demo project is here : https://github.com/selimok/wiremock-bug-example
Thanks for posting this. I'll take a look.
Interested in hearing outcome of this. I'm having a really weird but very consistent failure situation. When I run my tests through Bamboo I get a failure on the first test in my test class every time, there are 14 wire mock tests in the class. When I run it locally it never fails. The error appears to be timeout related, see messages below.
build 14-Dec-2016 14:12:33 INFO : / - RequestHandlerClass from context returned com.github.tomakehurst.wiremock.http.StubRequestHandler. Normalized mapped under returned 'null'
build 14-Dec-2016 14:13:39 INFO : org.eclipse.jetty.server.ServerConnector - Stopped ServerConnector@3c57f3e9{HTTP/1.1}{0.0.0.0:3080}
build 14-Dec-2016 14:13:39 INFO : org.eclipse.jetty.server.handler.ContextHandler - Stopped o.e.j.s.ServletContextHandler@7c447c76{/,null,UNAVAILABLE}
build 14-Dec-2016 14:13:39 INFO : org.eclipse.jetty.server.handler.ContextHandler - Stopped o.e.j.s.ServletContextHandler@118102ee{/__admin,null,UNAVAILABLE}
build 14-Dec-2016 14:13:39 WARN : org.eclipse.jetty.util.thread.QueuedThreadPool - qtp896852376{STOPPING,8<=8<=30,i=2,q=2} Couldn't stop Thread[qtp896852376-12,5,]
build 14-Dec-2016 14:13:39 WARN : org.eclipse.jetty.util.thread.QueuedThreadPool - qtp896852376{STOPPING,8<=8<=30,i=0,q=1} Couldn't stop Thread[qtp896852376-13,5,]
build 14-Dec-2016 14:13:39 Tests run: 14, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 77.364 sec <<< FAILURE! - in com.conorgriffin.apie.synapse.prism.hystrix.TestServiceCallHystrixCommand
build 14-Dec-2016 14:13:39 testPostCallViaServiceCallHystrixCommand(com.conorgriffin.apie.synapse.prism.hystrix.TestServiceCallHystrixCommand) Time elapsed: 7.069 sec <<< ERROR!
build 14-Dec-2016 14:13:39 com.netflix.hystrix.exception.HystrixRuntimeException: localhost:3080 timed-out and no fallback available.
I'm setting up all my stubs with @Before and I'm using the @ClassRule. I've even put a Thread.sleep(5000L) at the end of the @Before
Any updated with this issue? I am using Wiremock 2.4.1, Spring 1.4.1 and Maven 3.3.9
I am facing miscellaneous issues:-
Many times test fail for read time out from wiremock. This doesn't happen when I run test individually but does happen when all tests are run.
When I run the whole build (mvn clean install) on jenkins, the build hangs forever. This issue is reproducible rarely on local machines (at least my team's)
Particularly, first test of every test suite fails for read timeout.
I am running wiremock at 5001 port.
Caused by: org.apache.http.NoHttpResponseException: localhost:5001 failed to respond
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:143)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259)
at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163)
at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:167)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:271)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55)
at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:91)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:619)
... 47 more
@tomakehurst
Worked fine with a single test in a class but started hitting localhost:6666 failed to respond as soon as I've added the second test. Using 2.4.1 here.
So I managed to solve this by just waiting longer for a response. It seems that in my case when Bamboo runs the tests the jetty server doesn't come up quick enough. I was using Hystrix in my client and it as an execution timeout default of 1000ms. I bumped this to 5000ms and that solved the issue for me. So I guess it would be nice to have some way to block on running tests with clients until the server initialisation has completed.
@lidkowiak, where is the connectionManager come from?
@huangbowen521 connectionManager is injected by Spring in my case but it's a instance I use for constructing httpClient and then RestTemplate from Spring:
java
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
...
CloseableHttpClient httpClient = HttpClientBuilder.create()
.setConnectionManager(connectionManager)
...
.build();
RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpClient));
I wrote a small reproducer for this issue, which I think has also the same cause as #132 : https://github.com/sylvainlaurent/wiremock-issue-97-reproducer
IMHO the issue is in Jetty which does not properly close all resources when asked by Wiremock to stop itself. I'll file an issue with jetty later to explain the problem, but in the meantime, I think the workaround is simple : in com.github.tomakehurst.wiremock.jetty9.JettyHttpServer.finalizeSetup() the call to jettyServer.setStopTimeout(0); should be with some value like 30000 instead of 0.
This forces jetty to wait a little for its resources to shutdown properly.
In my experience this change did not perceivably slow tests but fixed them at last.
@sylvainlaurent thanks for this. I'll try and confirm this with my own testing.
I'm having the same issues. Interestingly it happens ~only~ more often on Windows and than in Linux.
I'm facing the same issues. Problems appeared when i switched my project from spring-boot 1.3.7.RELEASE, spring-cloud Camden.SR3 to spring-boot 1.5.2.RELEASE and spring-cloud Camden.SR6. I'm using feign-client to make http calls. Tests started to fail through one with "org.apache.http.NoHttpResponseException: localhost:4567 failed to respond" exception. Placing sleep(2000) or using @ClassRule fixes the problem. But i'm interested, are there any drawbacks in using @ClassRule instead of @Rule?
@ARnikev The issue you describe is very similar to what I experienced. @tehjakey's diagnostic was correct in my case : be sure that the HttpClient that is configured has the setting setConnectionReuseStrategy(NoConnectionReuseStrategy.INSTANCE).
It turned out that placing @ClassRule annotation in every test class doesn't solve the problem. If we run all test classes together then test cases in first running class finish correctly, but in every subsequent class the very first test case always fails with "org.apache.http.NoHttpResponseException: localhost:4567 failed to respond".
Did we find the fix for this issue? We are facing the same in our team with a DELETE stub?
@Vishal-Joshi, as workaround i've placed sleep(2000) in failing test method, after configuring actual stub (stubFor()), but before making requests to this stub.
For those who are still wrestling with this problem, although I dont know what is the real issue that is causing this behaviour when a test class contains a lot of unit tests (it's random sometimes it works other it doesnt).
As @sylvainlaurent suggested I ended up creating a custom clone JettyHttpserver and CustomHttpServerFactory to override the finalizeSetup() function. Setting the setStopTimeout to more than 0.
protected void finalizeSetup() {
this.jettyServer.setStopTimeout(1000L);
}
you might need to increase this amount for your case. I tried all the other suggested solutions it didnt work.
@hghammoud Would you mind posting details of exactly how you did that? It would really help me out.
+1 test runs fine on it's own, but fails if more than one test.
I created a CustomJettyHttpServer class just for my unit tests (copy the wiremock jetty server class) and change the finalizeSetup().
Then in the class
public WireMockRule wsMockendpoint = new WireMockRule(wireMockConfig().httpServerFactory(new HttpServerFactory() {
@Override
//We use a custom JettyServer to override the stopTimeout and solve read timeout exception in wiremock
public HttpServer buildHttpServer(Options options, AdminRequestHandler adminRequestHandler, StubRequestHandler stubRequestHandler) {
return new CustomJettyHttpServer(options, adminRequestHandler, stubRequestHandler);
}
}).port(8080));
Also having this problem with a bog standard GET request and would prefer something more robust than a "sleep 5 seconds" workaround.
I think I had the same problem.
I fixed it by marking the Spring Context as dirty.
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class Test { ... }
@dra14825 I'm facing similar issues and your solution helped a little bit but didn't solve the problem at all. It now just occurs less often.
It looks like the effect is similar to putting a Thread.sleep() call into each test method. With this configuration there is basically more time between running test methods as a new Spring context is being set-up before and then destroyed after each of them.
IMHO, putting Thread.sleep() calls or having the mentioned Spring configuration is still just a workaround for a bug which lies somewhere inside Wiremock. It looks like it is connected with setting up web-servers on the same address one after another.
Is there a timeline for when this is supposed to be fixed? Would a donation speed things up?
As is, wiremock is completely unusable for us. Apart from the fact that Thread.sleep doesn't reliably work and builds still fail randomly, If you have hundreds of tests in a project you easily add an hour to the build time.
There seem to be a lot of people stuck with this. Just in case it helps, the solution posted by @tehjakey above solved this issue for me, which is specifically to set the connection reuse to false for apache http client:
HttpClients.custom().setConnectionReuseStrategy(NoConnectionReuseStrategy.INSTANCE)/*other configs*/.build();
I used wiremock with Spring and JUnit, and had the same issue, when run the tests for a single class it never fails but while running test cases for whole project or during build also test cases failed giving error status 500/503. Found the root cause that only first test fails in the test class and that test is randomly picked by wiremock among all the test cases that is why for some people this issue raised in either POST/PUT/DELETE methods. I analyzed and what i found is that(it's my guess only) actually wiremock takes around 1900ms to start up and the test which is first selected for run results in fail.
For that i found a consistent solution (In my cases) that i used @Classrule in which WiremockClassRule instead of WiremockRule so that the wiremock starts only once for whole test class not for every test which happens when we use @Rule. Then used @BeforeClass annotation and used Thread.sleep(2000) in that so that wiremock start only once then wait of 2000ms and then all the test cases will start running.
Eureka 😃... worked for me.
Hopefully my solution helps others as well as @tomakehurst to debug.
Did you try this https://github.com/tomakehurst/wiremock/issues/97#issuecomment-288983671 ?
hi, this seems still to be an issue. it cost me something like 2 days to finally solve it. this is what i've done:
i got SocketTimeoutExceptions from time to time... very random. most of the time (running tests in IDE) it didn't occur at all, whereas on the build server (jenkins) it ALWAYS occured...
my setup:
Have you tried the Spring Cloud WireMock integration: http://cloud.spring.io/spring-cloud-static/spring-cloud-contract/1.1.2.RELEASE/#_spring_cloud_contract_wiremock
Built specifically for Spring Boot, so should avoid these problems.
Seeing this same issue in my Android unit tests. They all pass when ran individually but if I run them as a group both of my POST tests fail w/ the connection timeout error.
I'm in the process of converting over to OKHttp's networking library. I will update this post on whether or not that causes the tests to all pass when ran as a whole.
Update:
Upgrading my networking code to OKHttp resolved this issue. Seems like this has something to do with Apache, might not be a bug in Wiremock.
Like those above, seems to be a remaining issue.
For me, the switch to
@ClassRule public static WireMockClassRule wireMockClassRule = new WireMockClassRule(16000);
did the trick.
Specs:
JDK 1.8.0_144
Jetty 9.4.6.v20170531
Spring 5.0.0.RELASE (using WebClient rather than RestTemplate)
Wiremock-Standalone 2.10.1
Ran into the same issue using POST stub.
Spring-Boot 2.0.0.RC1
Wiremock 2.15.0
@kevcodez are you using the Spring team's WireMock integration?
@tomakehurst thx for the hint, fixed by using Spring Cloud Contract rather than the standalone wiremock dependency.
See docs at https://cloud.spring.io/spring-cloud-contract/ - there is a section about wiremock.
I replaced my wiremock test dependency with testCompile "org.springframework.cloud:spring-cloud-contract-wiremock:1.2.3.RELEASE".
Also, I added the @AutoConfigureWireMock(port = xxx) annotation on my test class.
Same issue using Spring boot 2.0.0-RELEASE. Using @ClassRule also fixed it
I'm hitting this too, but ClassRule didn't fix it for me. Or rather, it fixed some tests, but others started failing. So I have some tests that pass if I'm using @ Rule and a WireMockRule, and others that pass if I use @ ClassRule and WireMockClassRule.
Spring Boot 2.0.0, wiremock-standalone 2.15.0.
Edit: Forgot to mention that my tests pass if I run them as individual JUnit tests in Eclipse, but they fail when doing a maven build that runs tests.
Sounds like you are changing state of the WireMockRule (or something else) within tests and not resetting it in your @Before / @After test methods
How would that cause a recv failed? That's a socket level error. Besides, our use doesn't have any state with wiremock.
OK, here's some great insanity...
I have two test classes that perform an identical @Before block, but one was failing and one was succeeding. The only thing I could see that as different was the number of @Test cases...the one that was failing only had one, while the other had several. So I just cloned the exact same test 4 more times, for a total of 5 @Test methods...and the @Before stopped failing. Clearly there's some kind of race condition...but what? And how to fix?
Got it working, sort of. I took the init piece out of the Before block and moved it into the test. It still failed. I then added a sleep at the beginning of the method...and it worked.
Edit: This strategy has now fixed other tests experiencing the same problem.
More weirdness: Changing from wiremock-standalone to wiremock changes the error from "recv failed" to "read timed out", and also makes the sleep "fix" stop working.
I also tried 2.16.0 (up from 2.15.0) and it still fails the same way.
I found failed test from time to time when run many test case using WireMock. Then i just found that the problem is all tests are using same Wiremock port number. So my change is:
@Rule
public WireMockRule wireMockRule = new WireMockRule(8888);
@Rule
public WireMockRule wireMockRule = new WireMockRule(wireMockConfig().dynamicPort());
...
int port= wireMockRule.port();
@toopa2002 We already were using dynamicPort.
Same problem here, test fails randomly with a socket timeout.
Recently found same issues as above.
Originally used @Rule with Thread.sleep(2000) in @Before.
Switched to @ClassRule with Thread.sleep(2000) in @BeforeClass. This was to prevent first test in test class failing.
Attempted to used spring-cloud-contract-wiremock as part of refactor. I was unable to get going with it. Will attempt again future. Thanks for all opinions in this thread.
Same here. I'am using wiremock version 2.18.0, and the following keeps showing up:
Caused by: com.ctc.wstx.exc.WstxEOFException: Unexpected EOF in prolog
at [row,col {unknown-source}]: [1,0]
at com.ctc.wstx.sr.StreamScanner.throwUnexpectedEOF(StreamScanner.java:687)
at com.ctc.wstx.sr.BasicStreamReader.handleEOF(BasicStreamReader.java:2220)
at com.ctc.wstx.sr.BasicStreamReader.nextFromProlog(BasicStreamReader.java:2126)
at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1181)
at com.ctc.wstx.sr.BasicStreamReader.nextTag(BasicStreamReader.java:1204)
at org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor.handleMessage(ReadHeadersInterceptor.java:173)
at org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor.handleMessage(ReadHeadersInterceptor.java:70)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:797)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1680)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1557)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1358)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:658)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:516)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:425)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:326)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:279)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:139)
... 31 common frames omitted
, I'am using @ClassRule, and trying to initialize 2 stubs. As a alternative I added a Thread.sleep(1000) right after stubs being initialized and it worked for me.
My question is, isn't there a proper fix for this issue? Or a better workaround?
Thanks.
Same here. I'am using wiremock version 2.18.0, and the following keeps showing up:
Caused by: com.ctc.wstx.exc.WstxEOFException: Unexpected EOF in prolog at [row,col {unknown-source}]: [1,0] at com.ctc.wstx.sr.StreamScanner.throwUnexpectedEOF(StreamScanner.java:687) at com.ctc.wstx.sr.BasicStreamReader.handleEOF(BasicStreamReader.java:2220) at com.ctc.wstx.sr.BasicStreamReader.nextFromProlog(BasicStreamReader.java:2126) at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1181) at com.ctc.wstx.sr.BasicStreamReader.nextTag(BasicStreamReader.java:1204) at org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor.handleMessage(ReadHeadersInterceptor.java:173) at org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor.handleMessage(ReadHeadersInterceptor.java:70) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:797) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1680) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1557) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1358) at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56) at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:658) at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:516) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:425) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:326) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:279) at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96) at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:139) ... 31 common frames omitted
, I'am using @ClassRule, and trying to initialize 2 stubs. As a alternative I added a Thread.sleep(1000) right after stubs being initialized and it worked for me.My question is, isn't there a proper fix for this issue? Or a better workaround?
Thanks.
Same here, need some guidance please.
Also facing the same issue. I'm using a @ClassRule and I only get these failures when running all my tests together and on the first test in each class that follows another class. It seems like switching test classes tears down the old wiremock and sets up a new one. And it's not ready in the first test.
So as a work around in my beforeClass I retry over and over to communicate with wiremock, then continue after the first successful communication (effectively a dynamic thread.sleep).
It would be really great if there was a util that would just allow me to say WireMock.waitForReady().
@workmanw you're right in that ClassRule creates a new WireMock instance per class, but that shouldn't be a problem depending how your HTTP client library is configured.
Often this type of problem is triggered by your client library not cleaning up pooled connections properly. Which HTTP client library are you using i.e. which one is the underlying implementation actually doing the HTTP communication?
@tomakehurst Thanks for the quick response! We're interfacing with Spring's RestTemplate which is configured to use Apache's HttpClient under the covers.
Edit: We recently disabled automatic retries and that's when the issue surfaced. With automatic retry enabled it still fails the first few times, but by the 3rd or 4th attempt it's ready. Just wanted to call that out because no one else had really mentioned the auto retry thing. I've found different libraries to have different values for retries which could explain the variations that some users have reported.
@workmanw Have you tried turning off connection reuse in the HTTP client?
@tomakehurst you really need to fix it or add some method to your api to allow checking if all mappings are loaded.
We are having this issue when having a lot of mappings need to be loaded using #loadMappingsUsing(), sometimes they are not loaded before http client sends the request and response is 500 instead of the expected one.
Currently we are using Thread#sleep to wait 2 seconds, but it's gonna be better to have some solution from your side.
@20fps loadMappingsUsing() is synchronous. It sounds like you're having a different problem.
Suggest you post the details (code, error traces, config) over on the mailing list.
As a work around you can set in your connection pool validateAfterInactivity to some low number (e.g: 1)
(in case of apache httpclient)
For those who still encounter the behavior regarding "the first request fails".
The issue is related to Jetty lazy servlet loading. To fix your tests do the following:
server.stubFor(WireMock.get(urlPathEqualTo("/__health"))
.willReturn(WireMock.okJson("{\"status\" : \"running\"}")));
in your method annotated with @BeforeClass just call this endpoint like this (for Java11 you can use HttpClient ):
@BeforeClass
public static void beforeClass() throws Exception {
...........
URL url = new URL(serverUrl + "/__health");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setConnectTimeout(30_000);
con.setReadTimeout(30_000);
List<String> lines = org.apache.commons.io.IOUtils.readLines(con.getInputStream(), Charset.forName("UTF-8"));
con.disconnect();
}
This should trigger the loading of the WireMockHandlerDispatchingServlet. With this code, your tests should pass without any problem.
I use @ClassRule and started to get timeouts from wiremock every time I added a new stub on my tests. I downgraded java from 11 to 8 and now all works fine
Hi,
I tested that code only on Java 8.
@tavyy
The issue is related to Jetty lazy servlet loading. To fix your tests do the following:
This is interesting. I guess you mean that in some cases the servlet is taking so long to initialise that the call is timing out? Is there a log message or some clue you saw that indicated when this was happening?
One option might be just to enable eager loading in WireMock's startup code.
Hi,
The best way to see this, is to look after this message:
context.log(RequestHandler.HANDLER_CLASS_KEY + " from context returned " + handlerClassName +
". Normalized mapped under returned '" + mappedUnder + "'");
This line of code is from the init method of WireMockHandlerDispatchingServlet.java. The init method is executed only once when the servlet is loaded. If you start the wiremock server you will not see that message unless you make a first call.
Regarding enabling the eager loading of the servlet, from my investigation debugging the Jetty source code, I didn't find any option to do this.
One way to fix this issue, is to add my code regarding the first call after you start the jetty server.
still same issue when running all Junit togother or maven build it fail, if running only 1 class its working fine
any good solution instead of thread.sleep...?
also if i will move to use spring contract will not face this issue?
We are also still running into that issue.
Any progress on a fix?
Java version: 8
Wiremock version 2.19.0
Spring Boot version: 2.1.2.RELEASE
This seems to happen when using @Rule instead of @ClassRule
Hi guys, it happened to me too.
My tests were working running separate, but when i tried to run all together (mvn build) i've got several read time out exceptions.
solution in my case:
I'm using Httpclient to do the requests, I just simple start to call the releaseConnection() on the client and the problem was solved.
HttpGet _get = null;
try {
_get = new HttpGet(builder.build());
HttpResponse _response = client.execute(_get);
return responseHandler.read(_response);
}finally {
if(_get != null)
_get.releaseConnection(); // thats whats work for me
}
Hope this be usefull for someone. =)
Btw,
I'm using cucumber and I'm also using @ClassRule annotation to create the WireMockRule.
Please read if none of the fixes already described on this thread have worked for you
The most recent WireMock release includes a configuration parameter to determine whether responses are chunk encoded or sent with a Content-Length header. See here for details: http://wiremock.org/docs/configuration/#transfer-encoding
In previous versions of WM, all responses have been chunked. Some recent testing has shown that that this causes intermittent timeouts with some HTTP clients, so switching the transfer encoding policy in your setup to either NEVER or BODY_FILE may solve this problem.
Hi @tomakehurst , neither ChunkedEncodingPolicy.BODY_FILE nor ChunkedEncodingPolicy.NEVER fixes the issue.
Only Thread.sleep(2000); fixes it in the test. :(
We also had this issue and we managed to fix it by setting validateAfterInactivity to 1 ms when using the Apache httpClient. This seems to fix to problem. It looks like the client keeps an open connection to the wireMock, so when wireMock restarts between tests the new test still reuses the old connection, hance the issue. I am not sure if this can be fixed by WireMock, as it is rather a problem of the client connecting to the wiremock instance.
We are still facing the same issue and even setting validateAfterInactivity to 1 ms, the issue is not getting resolved. Is there any probable solution to the issue yet?
Any update on this @tomakehurst?
Solved the problem by using spring-cloud-contract-wiremock. Migration was easy:
@AutoConfigureWireMock for dynamic port or @AutoConfigureWireMock(port = 27015) for fixed port to the TestWireMock.stubFor I'm going to close this issue down, as I believe it's ended up as a catch-all for a number of loosely related problems, at least some of which are entirely due to HTTP client bugs or configuration.
If you're experiencing this problem, the following tweaks have all worked for somebody at some point:
@ClassRule in JUnit rather than @Rule with the WireMockRule.HttpURLConnection as an HTTP client, as it has buggy connection pool handling in some circumstances. Note: many HTTP clients, including Spring's RestTemplate and the Jersey client will use this under the hood by default.HttpClient or something that wraps it such as Spring's reactive WebClient, ensure you have the latest version of the Netty dependency. See https://github.com/tomakehurst/wiremock/issues/914#issuecomment-492711200org.springframework.cloud:spring-cloud-contract-wiremock (as described in the previous comment). See https://cloud.spring.io/spring-cloud-contract/multi/multi__spring_cloud_contract_wiremock.htmlIf none of these work for you, then I'd love to get my hands on a reproducible test case, so if you could open a new issue and share a test project that fails reliably I'd be very grateful.
Please note though, that I'm not going to be able to help if all you can share is a high-level description of the problem.
Does you know why Thread.sleep(2000); helps?
It’s not related to wiremock.
It’s related to your application server, which is calling wiremock. Today it’s common, to reuse a connection to improve the performance in a micro service infrastructure. So connection-close-header, RequestScoped client, etc. is not useful.
Check the apache http client:
httpclient-4.5.2 - PoolingHttpClientConnectionManager
documentation
_The handling of stale connections was changed in version 4.4. Previously, the code would check every connection by default before re-using it. The code now only checks the connection if the elapsed time since the last use of the connection exceeds the timeout that has been set. The default timeout is set to 2000ms_
Each time a wiremock-endpoint was destroyed and a new one is created for a new test class, it takes 2 seconds, until the application detects, that the previous connection is broken and a new one has to be opened.
If you don’t wait 2 seconds, such a NoHttpResponseException could be thrown, depends on the last use.
PS: When overwriting the default PoolingHttpClientConnectionManager, then this parameter can be changed. But should you do this?
In case someone lands on this I resolved for Spring and RestTemplate . I was able to resolve with no sleep() by using PoolingHttpClientConnectionManager#setValidateAfterInactivity(10).
@donhill doesn't work for me :(
Try this:
System.setProperty("http.keepAlive", "false");
System.setProperty("http.maxConnections", "1");
@mkopylec this doesn't work as well
I've found a very simple solution for the problem that has fixed it for me.
In my stubFor().willReturn(), simply overriding the default keep-alive connection behavior for every stub did the trick:
.withHeader("Connection", "close")
or when using spring-web:
.withHeader(HttpHeaders.CONNECTION, "close")
Full example (EXPECTED_ENDPOINT, objectMapper and responseObject being known vars in the context) :
stubFor(withAuth(get(urlEqualTo(EXPECTED_ENDPOINT))).willReturn(aResponse()
.withStatus(HttpStatus.OK.value())
.withHeader(HttpHeaders.CONNECTION, "close")
.withBody(objectMapper.writeValueAsString(responseObject))
));
EDIT:
Also possible to do 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(HttpHeaders.CONNECTION, "close")
.build();
}
@Override
public String getName() {
return "keep-alive-disabler";
}
}
.withHeader("Connection", "close") will finally close the connection after each call. The client will each time create a new fresh connection. This is not fine for production, but for simple integration-test with Wiremock why not. I will test it, cool idea.
--> now I have tested it on our projects, it works perfect 👌
Setting Connection: close response header helps, but first request to wiremock server takes a long time to finish. Therefore I get a timeout exception in my first test, the rest of them runs fine.
I've found a very simple solution for the problem that has fixed it for me.
In my stubFor().willReturn(), simply overriding the default keep-alive connection behavior for every stub did the trick:
.withHeader("Connection", "close")
or when using spring-web:
.withHeader(HttpHeaders.CONNECTION, "close")Full example (EXPECTED_ENDPOINT, objectMapper and responseObject being known vars in the context) :
stubFor(withAuth(get(urlEqualTo(EXPECTED_ENDPOINT))).willReturn(aResponse() .withStatus(HttpStatus.OK.value()) .withHeader(HttpHeaders.CONNECTION, "close") .withBody(objectMapper.writeValueAsString(responseObject)) ));EDIT:
Also possible to do 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(HttpHeaders.CONNECTION, "close") .build(); } @Override public String getName() { return "keep-alive-disabler"; } }
This is great solution. Works perfectly for me 👍
In spring you can inject WireMockServer into your class and do the stubbings from there.
Most helpful comment
I've found a very simple solution for the problem that has fixed it for me.
In my stubFor().willReturn(), simply overriding the default keep-alive connection behavior for every stub did the trick:
.withHeader("Connection", "close")or when using spring-web:
.withHeader(HttpHeaders.CONNECTION, "close")Full example (EXPECTED_ENDPOINT, objectMapper and responseObject being known vars in the context) :
EDIT:
Also possible to do globally using a transformer: