mock-server / mockserver

MockServer enables easy mocking of any system you integrate with via HTTP or HTTPS with clients written in Java, JavaScript and Ruby. MockServer also includes a proxy that introspects all proxied traffic including encrypted SSL traffic and supports Port Forwarding, Web Proxying (i.e. HTTP proxy), HTTPS Tunneling Proxying (using HTTP CONNECT) and SOCKS Proxying (i.e. dynamic port forwarding).
http://mock-server.com
Apache License 2.0
4.59k stars 1.07k forks source link

Mocking request fails with 'Connection refused' #498

Closed masher82 closed 5 years ago

masher82 commented 6 years ago

I try to mock an external request that fails with the following stacktrace

org.mockserver.client.netty.SocketConnectionException: Unable to connect to socket localhost/127.0.0.1:1080
    at org.mockserver.client.netty.NettyHttpClient.sendRequest(NettyHttpClient.java:97)
    at org.mockserver.client.MockServerClient.sendRequest(MockServerClient.java:137)
    at org.mockserver.client.MockServerClient.sendExpectation(MockServerClient.java:514)
    at org.mockserver.client.ForwardChainExpectation.respond(ForwardChainExpectation.java:32)
    at com....mock()
    at java.lang.Thread.run(Thread.java:748)
Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: localhost/127.0.0.1:1080
    at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
    at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:717)
    at io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:325)
    at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:340)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:633)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    ... 1 common frames omitted
Caused by: java.net.ConnectException: Connection refused
    ... 11 common frames omitted

The mockserver will be used as a proxy (by setting system properties 'http.proxyHost' and 'http.proxyPort') and should answer the requests to external resources that have been mocked but forward everything else.

For me it seems that the mockserver is not so good in dealing with concurrent requests?! Normally we use concurrent JUnit test execution (on class and suite level) and I had to revert the external resource tests to become sequentially executed because of similar issues as mentioned above.

Is it possible to enable debug log to get more insights to what happen within the mockserver.

jamesdbloom commented 5 years ago

The issue is not due to any problem with MockServer not handling concurrent request because it is proven to scale to thousands of concurrent request. I suspect it is to do with the order the test in being executed. Can you please provide you code so that I can help resolve your issue.

jamesdbloom commented 5 years ago

there is no response to request for more information so closing this ticket, if you can provide more information please re-open or raise a new ticket.

Frontrider commented 5 years ago

I can provide some info, at least in my case:

What I found, that it could be caused by an another mocked server that has not yet stopped is still running, and you're using that stopped mockserver, which will of course will reject connections.

My suggested solution: put a stopAndWait() method on the server, that explicitly makes the current thread wait until the server has fully stopped, and has cleaned up after itself.

haitao086 commented 4 years ago

I met this problem too. I know it's not the plugin issue. Caused I am not so pro in Java. In order to make it work. You should use below code, let ClientAndServer tell the sever which port would be used ClientAndServer.startClientAndServer(1080); then you could use the example code to mock.

isandow commented 4 years ago

Had the same problem running it in my spring boot integration tests. If the test container is created as a junit @ClassRule, you have to override its stop() method with an empty block. Otherwise the containers stop method will be called after a test class has finished, and thus the container wont accept any new incoming requests after that.

klerisson commented 4 years ago

Just faced similar issue. I've Junit 5 spring boot integration test, where "@AfterEach" method is being called, thus shutdown MockWebServer, before the test is executed. I still don't know why.

harpaal commented 4 years ago

Faced Similar issue when used with MockServerContainer( TestContainer) . @isandow suggestion worked for me.

harpaal commented 4 years ago

@isandow Found the issue , its not an issue with MockServer . I was using MockServerContainer (i.e. TestContainer ) for my integration testing. As per testcontainer documentation "Containers declared as static fields will be shared between test methods. They will be started only once before any test method is executed and stopped after the last test method has executed. Containers declared as instance fields will be started and stopped for every test method."

Inshort, just declare your MockServerContainer as static if you want to use same container for multiple test .

ThierryCasanova commented 3 years ago

@klerisson: I think I had similar issue with a Parent Junit Class using a static Mockserver as Proxy. This mockproxy is used in several child Test Classes. This Parent IntegrationTest Class start and stop this mock proxy in a static method @AfterAll

This created test failure between the Test Classes because the MockServer was not completly stopped and restarted.

I found a workaround in my parent method in order to wait the stop complete :


    @AfterAll
   public static void stopProxy() {
      mockServer.stop();
      while (!mockServer.hasStopped(3,100L, TimeUnit.MILLISECONDS)){}
   }

The ".hasStopped() method did the job

VeridianDynamics commented 3 years ago

I faced the same issue and discovered that for some reason, I cannot use any other port numbers besides 1080. Hope this helps someone.

anilkumarmyla commented 2 years ago

Echo the same by @VeridianDynamics . Another workaround is to explicitly pass command: -serverPort 8080 and do - 8080:8080 port mapping

tara-9 commented 2 years ago

@ThierryCasanova answer worked for me with a little change -> mockServer.stop(true); basically it will always shutdown ignoring failures.

jocull commented 1 year ago

This can appear as a side-effect of Spring bean wiring. Here is an example:

@Bean
public MockServerClient mockServerClient() {
    return mockServerClient; // or whatever you have here
}

Default Spring behavior is to call the destroyMethod of any beans when the config cleans itself up. In the case of MockServerClient, this finds the close() method, which then calls stop(). That seems to shut down the remote server in our case.

You can address this by manually specifying the destroyMethod of the bean to be nothing:

@Bean(destroyMethod = "")
public MockServerClient mockServerClient() {
    return mockServerClient; // or whatever you have here
}