Support parallel test execution with @AutoConfigureMockMvc
Previously, the deferred line writing that is used, to print MockMvc results to the console assumed that each DeferredLinesWriter would only be used by a single thread at a time. This assumption does not hold true when using JUnit 5's parallel test exection if the tests running in parallel share an application context. This resulted in a concurrent modification exception if one thread was adding lines to the output while another was iterating over them. This commit updates DeferredLinesWriter so that it uses thread local storage for the deferred lines. This ensures that each List of lines is only ever accessed by a single thread. Closes gh-16179
This commit is contained in:
@@ -226,7 +226,7 @@ public class SpringBootMockMvcBuilderCustomizer implements MockMvcBuilderCustomi
|
||||
|
||||
private final LinesWriter delegate;
|
||||
|
||||
private final List<String> lines = new ArrayList<>();
|
||||
private final ThreadLocal<List<String>> lines = ThreadLocal.withInitial(ArrayList::new);
|
||||
|
||||
DeferredLinesWriter(WebApplicationContext context, LinesWriter delegate) {
|
||||
Assert.state(context instanceof ConfigurableApplicationContext,
|
||||
@@ -237,11 +237,11 @@ public class SpringBootMockMvcBuilderCustomizer implements MockMvcBuilderCustomi
|
||||
|
||||
@Override
|
||||
public void write(List<String> lines) {
|
||||
this.lines.addAll(lines);
|
||||
this.lines.get().addAll(lines);
|
||||
}
|
||||
|
||||
void writeDeferredResult() {
|
||||
this.delegate.write(this.lines);
|
||||
this.delegate.write(this.lines.get());
|
||||
}
|
||||
|
||||
static DeferredLinesWriter get(ApplicationContext applicationContext) {
|
||||
@@ -254,7 +254,7 @@ public class SpringBootMockMvcBuilderCustomizer implements MockMvcBuilderCustomi
|
||||
}
|
||||
|
||||
void clear() {
|
||||
this.lines.clear();
|
||||
this.lines.get().clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user