对 wiremock 的并行调用不返回存根值

问题描述 投票:0回答:1

我在并行执行测试时遇到了一些问题,看起来我设置 wiremock (v2.27.2) 的方式可能有问题,或者 wiremock 内部存在竞争条件。

这里有一个在固定线程池上运行 100 个线程的例子。

public class WiremockTest {
  private static final String BODY = "body";
  private static WireMockServer wireMockServer;

  @BeforeAll
  public static void setup() {
    wireMockServer = new WireMockServer(wireMockConfig().dynamicPort());
    wireMockServer.start();
  }

  @Test
  void concurrentWireMock() throws InterruptedException {
    final var wiremock = new WireMock("localhost", wireMockServer.port());
    final var okHttp = new OkHttpClient.Builder().build();

    var exec = Executors.newFixedThreadPool(12);
    for (int i = 0; i < 100; i++) {
      exec.submit(() -> execute(wiremock, okHttp));
    }

    exec.shutdown();
    exec.awaitTermination(5, TimeUnit.SECONDS);
  }

  void execute(WireMock wiremock, OkHttpClient okHttp) {
    UUID uuid = UUID.randomUUID();
    var url = String.format("/v1/item/%s", uuid);

    wiremock.register(get(url)
        .willReturn(
            aResponse()
                .withStatus(HttpStatus.OK.value())
                .withBody(BODY)
        ));

    var getRequest = new Request.Builder()
        .url(wireMockServer.baseUrl() + url)
        .get()
        .build();
    try {
      var response = okHttp.newCall(getRequest).execute();
      String actualBody = response.body().string();
      if (!actualBody.equals(BODY)) {
        System.out.printf("Body didn't match. Expected:\n%s\nActual:\n%s\n", BODY, actualBody);
      }
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }
}

运行上面的代码,在 Wiremock 抛出 NPE 的 100 次运行中,我通常会得到 1 或 2 个错误。例如,这是一个错误输出的总结:

Body didn't match. Expected:
body
Actual:
<html>
<head>
[...]
<tr><th>URI:</th><td>/v1/item/e318684f-e061-4fee-9acb-36027aa88c5b</td></tr>
<tr><th>STATUS:</th><td>500</td></tr>
<tr><th>MESSAGE:</th><td>java.lang.NullPointerException</td></tr>
<tr><th>SERVLET:</th><td>com.github.tomakehurst.wiremock.servlet.WireMockHandlerDispatchingServlet-2a87176b</td></tr>
<tr><th>CAUSED BY:</th><td>java.lang.NullPointerException</td></tr>
</table>
<h3>Caused by:</h3><pre>java.lang.NullPointerException
    at com.github.tomakehurst.wiremock.servlet.WireMockHandlerDispatchingServlet.service(WireMockHandlerDispatchingServlet.java:120)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:779)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:760)
[...]
</body>
</html>

我想知道是不是我的设置有问题导致了这个问题。

wiremock
1个回答
0
投票

我确实在错误跟踪器中找到了答案。问题似乎是

WireMockServer.start()
返回太早,wiremock 无法开始接听电话。

有一个解决方法

我们现在有一个解决方法并添加一个简单的例如/readiness/wiremock 存根在启动 WireMockServer 后立即尝试使用简单的重试机制来命中它,一旦 HTTP 状态 200 返回,我们将继续我们的设置。

还有一个提议在wiremock上添加一个健康端点,这将消除对上面存根的需要,但仍然需要等到wiremock完全加载并准备好接收请求。

© www.soinside.com 2019 - 2024. All rights reserved.