我在并行执行测试时遇到了一些问题,看起来我设置 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>
我想知道是不是我的设置有问题导致了这个问题。