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() {
