aa75f1546ac259ecc0e32a45477b3af01dfd30fa
java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/MasterDataImportTest.java
| ... | ... | @@ -35,6 +35,7 @@ import javax.ws.rs.core.StreamingOutput; |
| 35 | 35 | import org.apache.shiro.SecurityUtils; |
| 36 | 36 | import org.apache.shiro.mgt.SecurityManager; |
| 37 | 37 | import org.apache.shiro.subject.Subject; |
| 38 | +import org.apache.shiro.util.ThreadContext; |
|
| 38 | 39 | import org.junit.jupiter.api.AfterEach; |
| 39 | 40 | import org.junit.jupiter.api.Assertions; |
| 40 | 41 | import org.junit.jupiter.api.BeforeEach; |
| ... | ... | @@ -194,6 +195,8 @@ public class MasterDataImportTest { |
| 194 | 195 | |
| 195 | 196 | @AfterEach |
| 196 | 197 | public void tearDown() { |
| 198 | + ThreadContext.unbindSecurityManager(); |
|
| 199 | + ThreadContext.unbindSubject(); |
|
| 197 | 200 | deleteAllDataFromDatabase(); |
| 198 | 201 | } |
| 199 | 202 | |
| ... | ... | @@ -205,8 +208,16 @@ public class MasterDataImportTest { |
| 205 | 208 | securityService = Mockito.mock(SecurityService.class); |
| 206 | 209 | SecurityManager securityManager = Mockito.mock(org.apache.shiro.mgt.SecurityManager.class); |
| 207 | 210 | Subject fakeSubject = Mockito.mock(Subject.class); |
| 208 | - SecurityUtils.setSecurityManager(securityManager); |
|
| 211 | + // Stub the mock BEFORE installing it as the global SecurityManager to avoid a race |
|
| 212 | + // condition: SecurityUtils.setSecurityManager() sets a JVM-wide static singleton. |
|
| 213 | + // Any thread that calls SecurityUtils.getSubject() (when no Subject is bound to its |
|
| 214 | + // ThreadContext) will trigger securityManager.createSubject(). If that happens between |
|
| 215 | + // the .when(securityManager) call (which sets pending doAnswer-style answers on the |
|
| 216 | + // mock's InvocationContainer) and the .createSubject() call (which completes the |
|
| 217 | + // stubbing), the other thread's call consumes the pending answers first, causing an |
|
| 218 | + // AssertionError in InvocationContainerImpl.setMethodForStubbing (line 123). |
|
| 209 | 219 | Mockito.doReturn(fakeSubject).when(securityManager).createSubject(Mockito.any()); |
| 220 | + SecurityUtils.setSecurityManager(securityManager); |
|
| 210 | 221 | Mockito.doReturn(defaultTenant).when(securityService).getServerGroup(); |
| 211 | 222 | Mockito.doReturn(currentUser).when(securityService).getCurrentUser(); |
| 212 | 223 | Mockito.doReturn(true).when(securityService).hasCurrentUserReadPermission(Mockito.any()); |
java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/SearchServiceTest.java
| ... | ... | @@ -20,6 +20,8 @@ import java.util.UUID; |
| 20 | 20 | import org.apache.shiro.SecurityUtils; |
| 21 | 21 | import org.apache.shiro.mgt.SecurityManager; |
| 22 | 22 | import org.apache.shiro.subject.Subject; |
| 23 | +import org.apache.shiro.util.ThreadContext; |
|
| 24 | +import org.junit.jupiter.api.AfterEach; |
|
| 23 | 25 | import org.junit.jupiter.api.BeforeEach; |
| 24 | 26 | import org.junit.jupiter.api.Test; |
| 25 | 27 | import org.mockito.Mockito; |
| ... | ... | @@ -114,6 +116,12 @@ public class SearchServiceTest { |
| 114 | 116 | private DynamicTrackedRace aalOrcTrackedR2; |
| 115 | 117 | private SecurityService securityService; |
| 116 | 118 | |
| 119 | + @AfterEach |
|
| 120 | + public void tearDown() { |
|
| 121 | + ThreadContext.unbindSecurityManager(); |
|
| 122 | + ThreadContext.unbindSubject(); |
|
| 123 | + } |
|
| 124 | + |
|
| 117 | 125 | @BeforeEach |
| 118 | 126 | public void setUp() { |
| 119 | 127 | UserGroupImpl defaultTenant = new UserGroupImpl(new UUID(0, 1), "defaultTenant"); |
| ... | ... | @@ -121,8 +129,16 @@ public class SearchServiceTest { |
| 121 | 129 | securityService = Mockito.mock(SecurityService.class); |
| 122 | 130 | SecurityManager securityManager = Mockito.mock(org.apache.shiro.mgt.SecurityManager.class); |
| 123 | 131 | Subject fakeSubject = Mockito.mock(Subject.class); |
| 124 | - SecurityUtils.setSecurityManager(securityManager); |
|
| 132 | + // Stub the mock BEFORE installing it as the global SecurityManager to avoid a race |
|
| 133 | + // condition: SecurityUtils.setSecurityManager() sets a JVM-wide static singleton. |
|
| 134 | + // Any thread that calls SecurityUtils.getSubject() (when no Subject is bound to its |
|
| 135 | + // ThreadContext) will trigger securityManager.createSubject(). If that happens between |
|
| 136 | + // the .when(securityManager) call (which sets pending doAnswer-style answers on the |
|
| 137 | + // mock's InvocationContainer) and the .createSubject() call (which completes the |
|
| 138 | + // stubbing), the other thread's call consumes the pending answers first, causing an |
|
| 139 | + // AssertionError in InvocationContainerImpl.setMethodForStubbing (line 123). |
|
| 125 | 140 | Mockito.doReturn(fakeSubject).when(securityManager).createSubject(Mockito.any()); |
| 141 | + SecurityUtils.setSecurityManager(securityManager); |
|
| 126 | 142 | Mockito.doReturn(defaultTenant).when(securityService).getServerGroup(); |
| 127 | 143 | Mockito.doReturn(currentUser).when(securityService).getCurrentUser(); |
| 128 | 144 | Mockito.doReturn(true).when(securityService).hasCurrentUserReadPermission(Mockito.any()); |