adobe / adobe/aem-core-wcm-components

[DefaultPathProcessor] Implementation-dependent tests in testVanityUrl and testVanityConfig

Open
#2,989 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
795
Forks
775
Avg merge
3d 22h
Merged PRs (30d)
8

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: but was:
org.opentest4j.AssertionFailedError: expected: but was:

**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:**
```java
// 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.

Contributor guide

Open the contributing guide

Research direction

Find DefaultPathProcessorTest and start by reading testVanityUrl and testVanityConfig, then run the provided NonDex Maven command across different seeds. Trace the Externalizer setup and resource resolver path mapping used by those tests. Done means both tests pass consistently regardless of execution order or service registration timing.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
testing-qa
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.