Skip to content

[DefaultPathProcessor] Implementation-dependent tests in testVanityUrl and testVanityConfig #2989

@kabo87777

Description

@kabo87777

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:

  1. Run NonDex on the test: mvn edu.illinois:nondex-maven-plugin:2.1.7:nondex -Dtest=DefaultPathProcessorTest#testVanityUrl
  2. 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 ResourceResolver instances
  • 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:

  1. Deterministic test design - Tests should not rely on service registration order
  2. Proper dependency setup - Explicitly ensure required services are available before component instantiation
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions