|
16 | 16 |
|
17 | 17 | package org.springframework.web.context.request;
|
18 | 18 |
|
19 |
| -import java.util.concurrent.CountDownLatch; |
20 |
| -import java.util.concurrent.TimeUnit; |
21 | 19 | import java.util.concurrent.atomic.AtomicReference;
|
22 | 20 | import java.util.stream.Stream;
|
23 | 21 |
|
24 | 22 | import io.micrometer.context.ContextRegistry;
|
25 | 23 | import io.micrometer.context.ContextSnapshot;
|
26 | 24 | import io.micrometer.context.ContextSnapshot.Scope;
|
27 | 25 | import io.micrometer.context.ContextSnapshotFactory;
|
28 |
| -import org.junit.jupiter.api.AfterEach; |
29 | 26 | import org.junit.jupiter.params.ParameterizedTest;
|
30 | 27 | import org.junit.jupiter.params.provider.Arguments;
|
31 | 28 | import org.junit.jupiter.params.provider.MethodSource;
|
32 | 29 |
|
33 |
| -import org.springframework.lang.Nullable; |
34 |
| - |
35 | 30 | import static org.assertj.core.api.Assertions.assertThat;
|
36 | 31 | import static org.mockito.Mockito.mock;
|
37 | 32 |
|
38 | 33 | /**
|
39 | 34 | * Tests for {@link RequestAttributesThreadLocalAccessor}.
|
40 | 35 | *
|
41 | 36 | * @author Tadaya Tsuyukubo
|
| 37 | + * @author Rossen Stoyanchev |
42 | 38 | */
|
43 | 39 | class RequestAttributesThreadLocalAccessorTests {
|
44 | 40 |
|
45 |
| - private final ContextRegistry registry = new ContextRegistry() |
46 |
| - .registerThreadLocalAccessor(new RequestAttributesThreadLocalAccessor()); |
| 41 | + private final ContextRegistry registry = |
| 42 | + new ContextRegistry().registerThreadLocalAccessor(new RequestAttributesThreadLocalAccessor()); |
| 43 | + |
47 | 44 |
|
48 |
| - @AfterEach |
49 |
| - void cleanUp() { |
50 |
| - RequestContextHolder.resetRequestAttributes(); |
| 45 | + private static Stream<Arguments> propagation() { |
| 46 | + RequestAttributes previous = mock(RequestAttributes.class); |
| 47 | + RequestAttributes current = mock(RequestAttributes.class); |
| 48 | + return Stream.of(Arguments.of(null, current), Arguments.of(previous, current)); |
51 | 49 | }
|
52 | 50 |
|
53 | 51 | @ParameterizedTest
|
54 | 52 | @MethodSource
|
55 | 53 | @SuppressWarnings({ "try", "unused" })
|
56 |
| - void propagation(@Nullable RequestAttributes previous, RequestAttributes current) throws Exception { |
57 |
| - RequestContextHolder.setRequestAttributes(current); |
58 |
| - ContextSnapshot snapshot = ContextSnapshotFactory.builder() |
59 |
| - .contextRegistry(this.registry) |
60 |
| - .clearMissing(true) |
61 |
| - .build() |
62 |
| - .captureAll(); |
63 |
| - |
64 |
| - AtomicReference<RequestAttributes> previousHolder = new AtomicReference<>(); |
65 |
| - AtomicReference<RequestAttributes> currentHolder = new AtomicReference<>(); |
66 |
| - CountDownLatch latch = new CountDownLatch(1); |
67 |
| - new Thread(() -> { |
68 |
| - RequestContextHolder.setRequestAttributes(previous); |
| 54 | + void propagation(RequestAttributes previousRequest, RequestAttributes currentRequest) throws Exception { |
| 55 | + |
| 56 | + ContextSnapshot snapshot = getSnapshotFor(currentRequest); |
| 57 | + |
| 58 | + AtomicReference<RequestAttributes> requestInScope = new AtomicReference<>(); |
| 59 | + AtomicReference<RequestAttributes> requestAfterScope = new AtomicReference<>(); |
| 60 | + |
| 61 | + Thread thread = new Thread(() -> { |
| 62 | + RequestContextHolder.setRequestAttributes(previousRequest); |
69 | 63 | try (Scope scope = snapshot.setThreadLocals()) {
|
70 |
| - currentHolder.set(RequestContextHolder.getRequestAttributes()); |
| 64 | + requestInScope.set(RequestContextHolder.getRequestAttributes()); |
71 | 65 | }
|
72 |
| - previousHolder.set(RequestContextHolder.getRequestAttributes()); |
73 |
| - latch.countDown(); |
74 |
| - }).start(); |
| 66 | + requestAfterScope.set(RequestContextHolder.getRequestAttributes()); |
| 67 | + }); |
| 68 | + |
| 69 | + thread.start(); |
| 70 | + thread.join(1000); |
75 | 71 |
|
76 |
| - latch.await(1, TimeUnit.SECONDS); |
77 |
| - assertThat(previousHolder).hasValueSatisfying(value -> assertThat(value).isSameAs(previous)); |
78 |
| - assertThat(currentHolder).hasValueSatisfying(value -> assertThat(value).isSameAs(current)); |
| 72 | + assertThat(requestInScope).hasValueSatisfying(value -> assertThat(value).isSameAs(currentRequest)); |
| 73 | + assertThat(requestAfterScope).hasValueSatisfying(value -> assertThat(value).isSameAs(previousRequest)); |
79 | 74 | }
|
80 | 75 |
|
81 |
| - private static Stream<Arguments> propagation() { |
82 |
| - RequestAttributes previous = mock(RequestAttributes.class); |
83 |
| - RequestAttributes current = mock(RequestAttributes.class); |
84 |
| - return Stream.of( |
85 |
| - Arguments.of(null, current), |
86 |
| - Arguments.of(previous, current) |
87 |
| - ); |
| 76 | + private ContextSnapshot getSnapshotFor(RequestAttributes request) { |
| 77 | + RequestContextHolder.setRequestAttributes(request); |
| 78 | + try { |
| 79 | + return ContextSnapshotFactory.builder() |
| 80 | + .contextRegistry(this.registry).clearMissing(true).build() |
| 81 | + .captureAll(); |
| 82 | + } |
| 83 | + finally { |
| 84 | + RequestContextHolder.resetRequestAttributes(); |
| 85 | + } |
88 | 86 | }
|
89 | 87 |
|
90 | 88 | }
|
0 commit comments