|
15 | 15 | */
|
16 | 16 | package org.springframework.boot.test.autoconfigure.web.servlet;
|
17 | 17 |
|
| 18 | +import java.util.ArrayList; |
| 19 | +import java.util.Arrays; |
18 | 20 | import java.util.List;
|
| 21 | +import java.util.concurrent.CountDownLatch; |
| 22 | +import java.util.concurrent.TimeUnit; |
19 | 23 |
|
20 | 24 | import javax.servlet.Filter;
|
21 | 25 | import javax.servlet.FilterChain;
|
|
26 | 30 |
|
27 | 31 | import org.junit.jupiter.api.Test;
|
28 | 32 |
|
| 33 | +import org.springframework.boot.test.autoconfigure.web.servlet.SpringBootMockMvcBuilderCustomizer.DeferredLinesWriter; |
| 34 | +import org.springframework.boot.test.autoconfigure.web.servlet.SpringBootMockMvcBuilderCustomizer.LinesWriter; |
29 | 35 | import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
30 | 36 | import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
|
31 | 37 | import org.springframework.context.annotation.Bean;
|
@@ -65,6 +71,55 @@ void customizeShouldAddFilters() {
|
65 | 71 | assertThat(filters).containsExactlyInAnyOrder(testFilter, otherTestFilter);
|
66 | 72 | }
|
67 | 73 |
|
| 74 | + @Test |
| 75 | + void whenCalledInParallelDeferredLinesWriterSeparatesOutputByThread() throws Exception { |
| 76 | + AnnotationConfigServletWebApplicationContext context = new AnnotationConfigServletWebApplicationContext(); |
| 77 | + MockServletContext servletContext = new MockServletContext(); |
| 78 | + context.setServletContext(servletContext); |
| 79 | + context.register(ServletConfiguration.class, FilterConfiguration.class); |
| 80 | + context.refresh(); |
| 81 | + |
| 82 | + CapturingLinesWriter delegate = new CapturingLinesWriter(); |
| 83 | + new DeferredLinesWriter(context, delegate); |
| 84 | + CountDownLatch latch = new CountDownLatch(10); |
| 85 | + for (int i = 0; i < 10; i++) { |
| 86 | + Thread thread = new Thread(() -> { |
| 87 | + for (int j = 0; j < 1000; j++) { |
| 88 | + DeferredLinesWriter writer = DeferredLinesWriter.get(context); |
| 89 | + writer.write(Arrays.asList("1", "2", "3", "4", "5")); |
| 90 | + writer.writeDeferredResult(); |
| 91 | + writer.clear(); |
| 92 | + } |
| 93 | + latch.countDown(); |
| 94 | + }); |
| 95 | + thread.start(); |
| 96 | + } |
| 97 | + latch.await(60, TimeUnit.SECONDS); |
| 98 | + |
| 99 | + assertThat(delegate.allWritten).hasSize(10000); |
| 100 | + assertThat(delegate.allWritten) |
| 101 | + .allSatisfy((written) -> assertThat(written).containsExactly("1", "2", "3", "4", "5")); |
| 102 | + } |
| 103 | + |
| 104 | + private static final class CapturingLinesWriter implements LinesWriter { |
| 105 | + |
| 106 | + List<List<String>> allWritten = new ArrayList<>(); |
| 107 | + |
| 108 | + private final Object monitor = new Object(); |
| 109 | + |
| 110 | + @Override |
| 111 | + public void write(List<String> lines) { |
| 112 | + List<String> written = new ArrayList<>(); |
| 113 | + for (String line : lines) { |
| 114 | + written.add(line); |
| 115 | + } |
| 116 | + synchronized (this.monitor) { |
| 117 | + this.allWritten.add(written); |
| 118 | + } |
| 119 | + } |
| 120 | + |
| 121 | + } |
| 122 | + |
68 | 123 | @Configuration(proxyBeanMethods = false)
|
69 | 124 | static class ServletConfiguration {
|
70 | 125 |
|
|
0 commit comments