dotCMS / dotCMS/core

test: decouple ContentletIndexAPIImplTest from ElasticSearch internals (phase-aware, vendor-neutral) - Make it possible to run MainSuite Tests in all 3 phases

Open
#36,320 1 comment 0 reactions 1 assignee View on GitHub

@fabrizzio-dotCMS is already working on this.

Since Jun 26, 2026.

Team : Scout
Dominant language
Java
Stars
970
Forks
486
Avg merge
3d 33m
Merged PRs (30d)
170

Description

Description

ContentletIndexAPIImpl is the vendor-neutral router of the ES→OpenSearch migration, but its integration test ContentletIndexAPIImplTest (dotcms-integration/src/test/java/com/dotcms/content/elasticsearch/business/ContentletIndexAPIImplTest.java, 1261 lines, 14 @Test) is still coupled to ElasticSearch internals.

Running the suite under a non-zero migration phase (verified at phase 3 via the new opensearch-phase-suite profile) makes 6 of 14 tests fail — most of them purely because of ES-specific assertions/helpers, not product defects.

./mvnw verify -pl :dotcms-integration -Dcoreit.test.skip=false \
  -Dopensearch.phase=3 \
  -Dit.test=ContentletIndexAPIImplTest

In scope (test decoupling — fix here):

  1. Replace the ES-direct search helper indexSearch() (~L1088-1110: RestHighLevelClientProvider + SearchRequest/QueryBuilders/SearchSourceBuilder/SearchResponse/SearchHits) with the vendor-neutral read path (SearchAPI / ContentletAPI.search / ContentSearchResponse) so the read-back hits whichever store the active phase routes to.
  2. Replace @Test(expected = ElasticsearchStatusException.class) (~L1257, testGetIndexDocumentCountWithInvalidIndexNameFails) with the neutral exception the router throws (DotRuntimeException wrapping the OS index-not-found). Observed under phase 3: expected ElasticsearchStatusException but was DotRuntimeException.
  3. Make the .os naming assertion in activateDeactivateIndex phase-aware (observed ComparisonFailure: expected:<live_…[.os]> but was:<live_…[]>).
  4. Re-evaluate testGetIndexDocumentCountSuccess and createContentIndexAndDelete (AssertionError) against the store the active phase uses.
  5. Remove the 8 org.elasticsearch.* imports (L80-87) once neutralized.

Out of scope (genuine product gaps — file as separate bug issues):

  • optimizeindex_not_found_exception looking up the index without the .os suffix (optimize-path routing/naming gap under phase 3).
  • testSearchMissingRequiredPropertyException: 'Builder.<variant kind>' parsing sitesearch index settings (OpenSearch client deserialization).
  • Test_TrackHits_SearchCount (in ESContentFactoryImplTest) → expected:<60> but was:<30>: the OS search path doesn't honor ES_TRACK_TOTAL_HITS like ES.

Acceptance Criteria

  • ContentletIndexAPIImplTest passes under phase 0 (normal profile, ES) and phase 3 (-Dopensearch.phase=3).
  • No org.elasticsearch.* imports remain in the file.
  • Read-back and exception/naming assertions are vendor-neutral / phase-aware.
  • The 3 out-of-scope product gaps are filed as separate issues and linked here.

Additional Context

Blast-radius experiment (local, phase 3 / OS-only, opensearch-phase-suite): ContentletIndexAPIImplTest 8/14; rest of the high-level flow ~93% pass (ContentletCheckInTest 11/11, ESContentletAPIImplTest 87/89, ESContentFactoryImplTest 39/42) — confirming ES coupling is concentrated in this one class, not spread across the suite.

Related: PR #36268 / issue #36266 (added the opensearch-phase-suite profile and the phase-aware test bootstrap).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.