This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a commit to branch WW-5539
in repository https://gitbox.apache.org/repos/asf/struts.git

commit 47e992d2005bd2ac287ada7a3c7407d6d1039328
Author: Lukasz Lenart <[email protected]>
AuthorDate: Tue Jul 21 17:58:36 2026 +0200

    WW-5539 Make the validator concurrency test race a cold cache
    
    The test computed its expected count with a getValidators call before
    starting the threads, which warmed the cache and left all 16 workers on
    the fast path - never exercising first-build contention, the race the
    test is named for.
    
    Also drops an unused import and awaits executor termination.
---
 .../org/apache/struts2/conversion/impl/XWorkConverterTest.java   | 1 -
 .../struts2/validator/DefaultActionValidatorManagerTest.java     | 9 +++++++--
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git 
a/core/src/test/java/org/apache/struts2/conversion/impl/XWorkConverterTest.java 
b/core/src/test/java/org/apache/struts2/conversion/impl/XWorkConverterTest.java
index 14aeb3905..74e8176bd 100644
--- 
a/core/src/test/java/org/apache/struts2/conversion/impl/XWorkConverterTest.java
+++ 
b/core/src/test/java/org/apache/struts2/conversion/impl/XWorkConverterTest.java
@@ -37,7 +37,6 @@ import org.apache.struts2.util.ValueStack;
 import org.apache.struts2.util.reflection.ReflectionContextState;
 import ognl.OgnlRuntime;
 import org.apache.struts2.conversion.TypeConverter;
-import org.apache.struts2.conversion.TypeConverterHolder;
 import org.apache.struts2.conversion.StrutsTypeConverterHolder;
 
 import java.io.IOException;
diff --git 
a/core/src/test/java/org/apache/struts2/validator/DefaultActionValidatorManagerTest.java
 
b/core/src/test/java/org/apache/struts2/validator/DefaultActionValidatorManagerTest.java
index 041ca7647..af388c495 100644
--- 
a/core/src/test/java/org/apache/struts2/validator/DefaultActionValidatorManagerTest.java
+++ 
b/core/src/test/java/org/apache/struts2/validator/DefaultActionValidatorManagerTest.java
@@ -388,7 +388,9 @@ public class DefaultActionValidatorManagerTest extends 
XWorkTestCase {
         CountDownLatch start = new CountDownLatch(1);
         List<Future<Integer>> futures = new ArrayList<>();
 
-        int expectedCount = 
actionValidatorManager.getValidators(SimpleAction.class, alias).size();
+        // actionValidatorManager is freshly injected in setUp(), so 
validatorCache is cold here -
+        // all 16 threads below race the first build for this key, which is 
the interesting
+        // contention this test exists to cover.
         // ActionContext is a plain (non-inheritable) ThreadLocal, so each 
pool thread needs its
         // own context bound - with its own ValueStack - before it can call 
getValidators(),
         // mirroring what XWorkTestCaseHelper does for the main test thread.
@@ -404,10 +406,13 @@ public class DefaultActionValidatorManagerTest extends 
XWorkTestCase {
         }
 
         start.countDown();
+        int firstSize = futures.get(0).get(60, TimeUnit.SECONDS);
+        assertThat(firstSize).isGreaterThan(0);
         for (Future<Integer> future : futures) {
-            assertThat(future.get(60, 
TimeUnit.SECONDS)).isEqualTo(expectedCount);
+            assertThat(future.get(60, TimeUnit.SECONDS)).isEqualTo(firstSize);
         }
         pool.shutdown();
+        assertThat(pool.awaitTermination(60, TimeUnit.SECONDS)).isTrue();
     }
 
     public void testCachedValidatorConfigsAreUnmodifiable() {

Reply via email to