Wiremock version: 2.1.11
I have a simple test like this
@Rule
public final WireMockRule service = new WireMockRule(wireMockConfig().httpsPort(8443));
@Before
public void setup() {
service.stubFor(post(urlEqualTo("/some/endpoint"))
.willReturn(aResponse().withStatus(200)
.withHeader("Content-Type", "application/json")));
}
@Test
public void test() {
// sending request to https://myserver.com:8443/some/endpoint
Response response = client.request();
Assert.assertEquals(200, response.getStatus());
}
However, the test hangs forever at the requesting step.
The test will eventually timeout with this stacktrace
testSendMessage(com.opower.dyn.TestSendApi) Time elapsed: 75.409 sec <<< ERROR!
javax.ws.rs.ProcessingException: java.net.ConnectException: Operation timed out
at org.glassfish.jersey.client.HttpUrlConnector.apply(HttpUrlConnector.java:184)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:227)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:655)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:652)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:422)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:652)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:412)
at org.glassfish.jersey.client.JerseyInvocation$Builder.post(JerseyInvocation.java:321)
at com.opower.dyn.SendApi.sendMessage(SendApi.java:55)
at com.opower.dyn.TestSendApi.testSendMessage(TestSendApi.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at com.github.tomakehurst.wiremock.junit.WireMockRule$1.evaluate(WireMockRule.java:72)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: java.net.ConnectException: Operation timed out
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
Can you post the code for your client setup? Or ideally a project I can clone so I can run the test?
I had similar issue and fixed by using @ClassRule:
@ClassRule
public static WireMockClassRule wireMockRule = new WireMockClassRule(options()
.port(8080)
.bindAddress("localhost"));
@Rule
public WireMockClassRule instanceRule = wireMockRule;
Thanks a lot it fixed my issue
Hi,
Are you planning to fix the cause of this issue, it still reproducible on wiremock version 2.15.0
comment from @esoaresfusion fix the issue.
moreover
Configuration:
private static WireMockServer wireMockServer;
@BeforeClass
public static void setUp() throws Exception {
wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig().port(PORT).notifier(new ConsoleNotifier(true)));
wireMockServer.start();
}
@AfterClass
public static void tearDownClass() throws Exception {
wireMockServer.stop();
}
@After
public void tearDown() throws Exception {
wireMockServer.resetAll();
}
and creating stubs like:
wireMockServer.stubFor(get(urlEqualTo("/route/)...
works pretty fine.
But still, Wiremock rules seems hangs.
Blocked Thread:
"qtp543679168-47-acceptor-1@6ce22ada-NetworkTrafficServerConnector@23ec71fb{HTTP/1.1,[http/1.1]}{0.0.0.0:8087}" #47 prio=3 os_prio=0 tid=0x00007f7d295b5800 nid=0x5a8e waiting for monitor entry [0x00007f7d0c97b000]
java.lang.Thread.State: BLOCKED (on object monitor)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:234)
- waiting to lock <0x000000079408c318> (a java.lang.Object)
at org.eclipse.jetty.server.ServerConnector.accept(ServerConnector.java:373)
at org.eclipse.jetty.server.AbstractConnector$Acceptor.run(AbstractConnector.java:601)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)
at java.lang.Thread.run(Thread.java:748)
Thanks, in advance.
I'll happily re-open and look at it if someone will post a full test case that reproduces it.
However, I suspect the problem is with your HTTP client setup, rather than WireMock. If you're running your app (and therefore client connection pool) at the class scope, but WireMock at the test case scope, then you're going to end up with dead connections. That's the reason moving WireMock to the class scope fixes the problem.
Hi Tom,
Moving to class isn't enough if use as @Rule or @ClassRule only.
Example works fine only when using same object under both rule annotations.
I'll try to prepare simple app little bit later.
Hi Tom,
Unfortunately, I'm unable to create the simple app with repo scenario, and I could not share the example I faced issue with.
If I'll able to create simple app I'll post it here.
The solution suggested by @esoaresfusion solved my issue with hanging HTTP:
@ClassRule
public static WireMockClassRule wireMockRule = new WireMockClassRule(8081);
However, after introduction of a new integration test using the same port and having the same WireMock class rule _in a new class_, the tests started to fail randomly when executed together (mvn clean verify) complaining that they are not able to connect to the mocked server. Somehow it looks like the port is closed after the first test is finished but while the second before the second is finished.
2018-03-05 14:42:25 [main] INFO AbstractConnector - Started NetworkTrafficServerConnector@6a278ca8{HTTP/1.1,[http/1.1]}{0.0.0.0:8081}
2018-03-05 14:42:25 [main] INFO Server - Started @34240ms
2018-03-05 14:43:25 [qtp171795207-67] INFO ContextHandler$Context - RequestHandlerClass from context returned com.github.tomakehurst.wiremock.http.StubRequestHandler. Normalized mapped under returned 'null'
2018-03-05 14:43:25 [main] INFO AbstractConnector - Stopped NetworkTrafficServerConnector@6a278ca8{HTTP/1.1,[http/1.1]}{0.0.0.0:8081}
2018-03-05 14:43:25 [main] INFO ContextHandler - Stopped o.e.j.s.ServletContextHandler@721c608c{/,null,UNAVAILABLE}
2018-03-05 14:43:25 [main] INFO ContextHandler - Stopped o.e.j.s.ServletContextHandler@52ac729c{/__admin,null,UNAVAILABLE}
Tests run: 4, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 60.193 sec <<< FAILURE! - in com.example.FooServiceTest
getFoo(com.example.FooServiceTest) Time elapsed: 60.063 sec <<< ERROR!
feign.RetryableException: Read timed out executing GET http://localhost:8081/foo
Setting the reuseForks configuration flag of maven-surefire-plugin to false in pom.xml seems to fix the issue with randomly failing tests:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<reuseForks>false</reuseForks>
</configuration>
</plugin>
I also came across this kind of problem where Wiremock starts to hang when multiple tests are ran in a suite. I realized at some point that the stub definition of my responses didn't include the Connection: Close http header. I tried adding it and it seems to have fixed the issue.
Since I'm lazy and don't want to forget adding it somewhere, I wrote a simple extension that I add to my WireMockRule:
public class MyTestClass {
@Rule
public WireMockRule getWireMockRule() {
return WireMockRule(wireMockConfig()
.dynamicPort()
.extensions(new ConnectionCloseExtension()));
}
}
public class ConnectionCloseExtension extends ResponseTransformer {
@Override
public Response transform(Request request, Response response, FileSource files, Parameters parameters) {
return Response.Builder
.like(response)
.headers(HttpHeaders.copyOf(response.getHeaders())
.plus(new HttpHeader("Connection", "Close")))
.build();
}
@Override
public String getName() {
return "ConnectionCloseExtension";
}
}
I hope this helps!
Thanks @bernyfox, that resolved the thread blocking issue instantly!
I ran into this problem in Kotlin with several test classes, and I had do do all these to fix it:
WireMockRules into @ClassRules as described above.ConnectionCloseExtension as described above.WireMockClassRules from all test classes into a single abstract base class.Faced similar issue in release 2.18.0, despite doing above mentioned steps.
This issued was fixed when downgrading to version 2.14.0(didn't check b/w releases though)
@sathishchet are you able to provide a test case that works with 2.14.0 but breaks with 2.18.0?
I found the similar issue and resolved with increasing the thread count. Cheers!
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<includes>
<reuseForks>false</reuseForks>
<forkCount>1</forkCount>
</includes>
<threadCount>20</threadCount>
</configuration>
</plugin>
All of the above workarounds failed for my use-case with a Spring WebFlux based WebClient (which is in turn based on reactor-netty) connecting to a WireMock based stub.
I was able to workaround it by using:
WebClient.builder().clientConnector(new ReactorClientHttpConnector(HttpClient.create())
which effectively disables the client from sending the accept-encoding: gzip header. I'm not sure if this a reactor-netty side issue but perhaps it helps tracing this issue as well or others strungling with similar problems.
Thanks @Robbert1, your solution got me on the right track. Specifying a connection timeout on the ReactorClientHttpConnector resolved my issues.
I'm using Spring WebFlux with functional endpoints and I'm also seeing a similar problem occasionally when running a test suite. WebTestClient times out after some time while waiting for a response from the mock server, who never responds. It doesn't generally happen when executing a single test.
I'm initializing the client like this:
WebTestClient.bindToRouterFunction(routerFn).build()
The suggestion from @bernyfox seems to be working for me too.
EDIT: I tried switching to mockwebserver and my test suite runs without any workaround. I'm sorry that I couldn't help more here!
Changing from :
@Rule public WireMockRule wireMockRule = new WireMockRule(9091);
to
@ClassRule public static WireMockRule wireMockRule = new WireMockRule(9091);
helped me.
Most helpful comment
I also came across this kind of problem where Wiremock starts to hang when multiple tests are ran in a suite. I realized at some point that the stub definition of my responses didn't include the
Connection: Closehttp header. I tried adding it and it seems to have fixed the issue.Since I'm lazy and don't want to forget adding it somewhere, I wrote a simple extension that I add to my WireMockRule:
I hope this helps!