-
Notifications
You must be signed in to change notification settings - Fork 766
Description
Bug Report
Current Behavior
The DefaultPathProcessorTest#testVanityUrl and DefaultPathProcessorTest#testVanityConfig methods exhibit flaky behavior when execution order is non-deterministic (e.g., when using NonDex for testing). The tests fail intermittently with different error patterns:
testVanityUrl failures:
org.apache.sling.testing.mock.osgi.ReferenceViolationException: Unable to inject mandatory reference 'externalizer' (com.day.cq.commons.Externalizer) for class com.adobe.cq.wcm.core.components.internal.link.DefaultPathProcessor : no matching services were found.
testVanityConfig failures:
org.opentest4j.AssertionFailedError: expected: </content/site1/en.html> but was: </links/site1/en.html>
org.opentest4j.AssertionFailedError: expected: https://example.org/links/site1/en.html but was: https://example.org/content/links/site1/en.html
Steps to reproduce:
- Run NonDex on the test:
mvn edu.illinois:nondex-maven-plugin:2.1.7:nondex -Dtest=DefaultPathProcessorTest#testVanityUrl - Observe intermittent failures across different seeds (e.g., fails on seeds 933178, 974622 but passes on 1016066)
Expected behavior/code
Tests should pass consistently regardless of execution order or service registration timing. The tests should be deterministic and not depend on implementation-specific ordering of:
- OSGi service registration and dependency injection
- Resource resolver path mapping behavior
Environment
- AEM Core Components version: 2.30.3-SNAPSHOT
- Test framework: JUnit 5 with AEM Mocks
- Build tool: Maven with NonDex plugin 2.1.7
- JRE version: OpenJDK 64-Bit Server VM
Possible Solution
For testVanityUrl:
// Ensure Externalizer service is available before registering DefaultPathProcessor
Externalizer externalizer = context.getService(Externalizer.class);
if (externalizer == null) {
// Fallback: register a mock externalizer if not already present
externalizer = mock(Externalizer.class);
when(externalizer.publishLink(any(ResourceResolver.class), anyString()))
.thenAnswer(invocation -> "https://example.org" + invocation.getArgument(1, String.class));
context.registerService(Externalizer.class, externalizer);
}For testVanityConfig:
- Replaced hardcoded path assertions with controlled mock
ResourceResolverinstances - Eliminated dependency on non-deterministic path mapping behavior
- Used explicit mocking to ensure predictable test outcomes
Additional context / Screenshots
This issue highlights the importance of:
- Deterministic test design - Tests should not rely on service registration order
- Proper dependency setup - Explicitly ensure required services are available before component instantiation
- NonDex integration - Regular flaky test detection in CI/CD pipelines
The flaky behavior would cause intermittent CI failures and reduce confidence in the test suite, potentially masking real regressions.