Is WireMock thread safe?

1,391 views
Skip to first unread message

Ramez Moussa

unread,
Mar 10, 2017, 9:39:17 AM3/10/17
to wiremock-user
Hello,
Background
    I have a setup as follows, Integration test calls my service and configures wiremock stubs according to testcase, my service is configured to use nginx, nginx routes the calls after changing some path parameters to header parameters and adds more stuff to wiremock standalone instance. 
    Everything was working correctly sequentially, as soon as i enabled parallelism in the tests, wiremock fails on some requests but i couldn't see what's wrong because the standalone instance doesn't log in a file, so i ran it from a main class grammatically after adding slf4j and found the following error

WARN org.eclipse.jetty.servlet.ServletHandler - <MOCKED_PATH>
java.lang.NullPointerException
at com.github.tomakehurst.wiremock.matching.EqualToJsonPattern.getNode(EqualToJsonPattern.java:148)
at com.github.tomakehurst.wiremock.matching.EqualToJsonPattern.getNode(EqualToJsonPattern.java:150)
at com.github.tomakehurst.wiremock.matching.EqualToJsonPattern.getNode(EqualToJsonPattern.java:153)
at com.github.tomakehurst.wiremock.matching.EqualToJsonPattern.getNode(EqualToJsonPattern.java:150)
at com.github.tomakehurst.wiremock.matching.EqualToJsonPattern.getNode(EqualToJsonPattern.java:153)
at com.github.tomakehurst.wiremock.matching.EqualToJsonPattern.getNodeAtPath(EqualToJsonPattern.java:140)
at com.github.tomakehurst.wiremock.matching.EqualToJsonPattern.diffSize(EqualToJsonPattern.java:110)
at com.github.tomakehurst.wiremock.matching.EqualToJsonPattern.access$300(EqualToJsonPattern.java:36)
at com.github.tomakehurst.wiremock.matching.EqualToJsonPattern$1.getDistance(EqualToJsonPattern.java:94)
at com.github.tomakehurst.wiremock.matching.EqualToJsonPattern$1.isExactMatch(EqualToJsonPattern.java:85)
at com.github.tomakehurst.wiremock.matching.MatchResult$2.apply(MatchResult.java:82)
at com.github.tomakehurst.wiremock.matching.MatchResult$2.apply(MatchResult.java:79)
at com.google.common.collect.Iterators.all(Iterators.java:653)
at com.google.common.collect.Iterables.all(Iterables.java:654)
at com.github.tomakehurst.wiremock.matching.MatchResult$1.isExactMatch(MatchResult.java:51)
at com.github.tomakehurst.wiremock.matching.MatchResult$2.apply(MatchResult.java:82)
at com.github.tomakehurst.wiremock.matching.MatchResult$2.apply(MatchResult.java:79)
at com.google.common.collect.Iterators.all(Iterators.java:653)
at com.google.common.collect.Iterables.all(Iterables.java:654)
at com.github.tomakehurst.wiremock.matching.MatchResult$1.isExactMatch(MatchResult.java:51)
at com.github.tomakehurst.wiremock.stubbing.InMemoryStubMappings$2.apply(InMemoryStubMappings.java:181)
at com.github.tomakehurst.wiremock.stubbing.InMemoryStubMappings$2.apply(InMemoryStubMappings.java:179)
at com.google.common.collect.Iterators$6.computeNext(Iterators.java:617)
at com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:145)
at com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:140)
at com.google.common.collect.Iterators.getNext(Iterators.java:818)
at com.google.common.collect.Iterators.find(Iterators.java:688)
at com.google.common.collect.Iterables.find(Iterables.java:686)
at com.github.tomakehurst.wiremock.stubbing.InMemoryStubMappings.serveFor(InMemoryStubMappings.java:64)
at com.github.tomakehurst.wiremock.core.WireMockApp.serveStubFor(WireMockApp.java:157)
at com.github.tomakehurst.wiremock.http.StubRequestHandler.handleRequest(StubRequestHandler.java:50)
at com.github.tomakehurst.wiremock.http.AbstractRequestHandler.handle(AbstractRequestHandler.java:44)
at com.github.tomakehurst.wiremock.servlet.WireMockHandlerDispatchingServlet.service(WireMockHandlerDispatchingServlet.java:100)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:808)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669)
at org.eclipse.jetty.servlets.UserAgentFilter.doFilter(UserAgentFilter.java:83)
at org.eclipse.jetty.servlets.GzipFilter.doFilter(GzipFilter.java:300)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.eclipse.jetty.server.Server.handle(Server.java:499)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
at java.lang.Thread.run(Thread.java:745)


    Then i found this https://github.com/tomakehurst/wiremock/issues/273, and it suggests that wiremock isn't thread safe?

    I register stubs by using 
    WireMock.register(stub) and the WireMock is also connected to nginx that routes the mapping to wiremock

    The problem is definitely not nginx and the mappings are not overlapping, each mapping has a lot of unique fields and i also use inScenario(testCaseName);

So after all this background, the question is, is wiremock matching thread safe, can my setup work in parallel?

Best Regards


Tom Akehurst

unread,
Mar 10, 2017, 10:00:04 AM3/10/17
to wiremock-user
WireMock is intended to be threadsafe - that GH issue is a bit misleading (it's saying there are cases where your thread model can affect the correctness of your tests, which isn't quite the same thing and is avoidable).

However, if you're only seeing this particular error when you're running in parallel, that suggests that the JSON equality code might have a thread safety problem. Would you be able to post example code + test that replicates this over in GitHub? If I have that I'll be able to debug and confirm whether this is the case. 

Ramez Moussa

unread,
Mar 10, 2017, 11:38:22 AM3/10/17
to wiremock-user
Hello, 
Thanks for the prompt response.
I tried to reproduce it by creating a sample service with the same setup (nginx, wiremock), and same code of registering and unregistering stubs, but it worked fine in parallel.

Is there some other way for you to help me, the trick is I have a lot of stubs, maybe at least 10 per test case, and I have 250 testcases in 25 test classes, and I'm running the test classes in parallel, the failing stubs include request headers matching, body matching (parts of it) it is json, the lenient wiremock matching is awesome by the way, and it returns some response. Maybe the problem is in the lenient matching?

Best Regards

Tom Akehurst

unread,
Mar 10, 2017, 12:16:45 PM3/10/17
to wiremock-user
It's going to be hard for me to find the time to replicate this from scratch based on what you've given me so far. You're welcome to log it as a GH issue, but I probably won't get to it for a while unless there's a reliably failing test case to start with.
Reply all
Reply to author
Forward
0 new messages