47c1355c876c06f26b772a6c2b2b152f3c7b9bec
java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/MasterDataImportTest.java
| ... | ... | @@ -209,12 +209,13 @@ public class MasterDataImportTest { |
| 209 | 209 | SecurityManager securityManager = Mockito.mock(org.apache.shiro.mgt.SecurityManager.class); |
| 210 | 210 | Subject fakeSubject = Mockito.mock(Subject.class); |
| 211 | 211 | // Stub the mock BEFORE installing it as the global SecurityManager to avoid a race |
| 212 | - // condition where a background thread (from RacingEventServiceImpl's static |
|
| 213 | - // ScheduledExecutorService) calls SecurityUtils.getSubject(), which triggers |
|
| 214 | - // createSubject() on the mock while Mockito is still in the middle of setting up |
|
| 215 | - // the doReturn().when() stubbing. The background thread consumes/corrupts |
|
| 216 | - // Mockito's doAnswer-style answers on the mock's InvocationContainer, causing |
|
| 217 | - // an AssertionError in InvocationContainerImpl.setMethodForStubbing. |
|
| 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). |
|
| 218 | 219 | Mockito.doReturn(fakeSubject).when(securityManager).createSubject(Mockito.any()); |
| 219 | 220 | SecurityUtils.setSecurityManager(securityManager); |
| 220 | 221 | Mockito.doReturn(defaultTenant).when(securityService).getServerGroup(); |
java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/SearchServiceTest.java
| ... | ... | @@ -130,12 +130,13 @@ public class SearchServiceTest { |
| 130 | 130 | SecurityManager securityManager = Mockito.mock(org.apache.shiro.mgt.SecurityManager.class); |
| 131 | 131 | Subject fakeSubject = Mockito.mock(Subject.class); |
| 132 | 132 | // Stub the mock BEFORE installing it as the global SecurityManager to avoid a race |
| 133 | - // condition where a background thread (from RacingEventServiceImpl's static |
|
| 134 | - // ScheduledExecutorService) calls SecurityUtils.getSubject(), which triggers |
|
| 135 | - // createSubject() on the mock while Mockito is still in the middle of setting up |
|
| 136 | - // the doReturn().when() stubbing. The background thread consumes/corrupts |
|
| 137 | - // Mockito's doAnswer-style answers on the mock's InvocationContainer, causing |
|
| 138 | - // an AssertionError in InvocationContainerImpl.setMethodForStubbing. |
|
| 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). |
|
| 139 | 140 | Mockito.doReturn(fakeSubject).when(securityManager).createSubject(Mockito.any()); |
| 140 | 141 | SecurityUtils.setSecurityManager(securityManager); |
| 141 | 142 | Mockito.doReturn(defaultTenant).when(securityService).getServerGroup(); |