Skip to content

test(cli): fix default-language test env state, not just retry (#35780)#35813

Merged
dsilvam merged 1 commit into
mainfrom
issue-35780-cli-fix-default-language
May 22, 2026
Merged

test(cli): fix default-language test env state, not just retry (#35780)#35813
dsilvam merged 1 commit into
mainfrom
issue-35780-cli-fix-default-language

Conversation

@dsolistorres
Copy link
Copy Markdown
Member

@dsolistorres dsolistorres commented May 22, 2026

Summary

Follow-up to PR #35803 (the retry workaround). After that PR merged, the CLI tests in SiteAPIIT were still failing. Diagnosing the latest run (26301904102) showed this is not a timing race — it is deterministic test-environment state.

What the diagnosis showed

  • dotCMS finished startup at 17:55:44. First failing test ran at 17:56:05 — 21 seconds later. Cache fully populated by then.
  • The existing warmLanguageCacheIfNeeded() warmup succeeded on its first attempt (HTTP 200).
  • The retryOnLanguageNull retry from test(cli): retry SiteAPIIT.create on transient 'Language cannot be null' (#35780) #35803 did fire (test elapsed went from ~250ms → ~1100ms = 3 attempts × ~250ms backoff). All three attempts hit the same 500 error.

But look at what the warmup response actually contains:

{
  "entity": [
    {"language": "LANG__404", "id": -1, "defaultLanguage": true},
    {"language": "English",   "id":  1, "defaultLanguage": false}
  ]
}

The "default language" is permanently the LANG__404 sentinel (id=-1). English exists with id=1 but is not marked default. So:

  1. SiteResource.create() calls getDefaultLanguage().getId() → gets -1
  2. The Host contentlet is saved with languageId = -1
  3. UniqueFieldCriteria calls getLanguage(-1) → returns null
  4. Objects.requireNonNull(language, "Language cannot be null") → NPE → HTTP 500

The existing warmup passed because it only verified that any language had id > 0 (English does). It did not verify that the default language had id > 0.

What this PR changes

LanguageAPI.java (CLI interface) — adds:

@PUT
@Path("/{languageId}/_makedefault")
ResponseEntityView<Language> makeDefault(@PathParam("languageId") String languageId,
        Map<String, Boolean> form);

SiteAPIIT.warmLanguageCacheIfNeeded() — strengthens the warmup:

  1. List languages.
  2. If the entry marked defaultLanguage=true has id > 0, we are done.
  3. Otherwise pick the first language with id > 0 (English in starter data) and call PUT /api/v2/languages/{id}/_makedefault with fireTransferAssetsJob=false to fix the broken default.
  4. Re-list to confirm the fix before declaring success.
  5. Up to 3 attempts with 200 ms backoff (unchanged loop shape).

The retryOnLanguageNull workaround from #35803 is preserved as defense-in-depth around the 4 .create(...) call sites — if the warmup somehow doesn't fix the state, the retry will still try. But it should not be needed.

Why this works when retries do not

Retries assume a transient state that will clear if we wait. The CI evidence shows the state is stable — getDefaultLanguage() returns LANG__404 every time, indefinitely. Only an actionable fix (forcing a real language as the default) changes that state.

_makedefault is the same endpoint the dotCMS admin UI uses for "switch default language". fireTransferAssetsJob=false skips the heavy background job, so the call is a fast metadata update — appropriate for test setup.

What this PR does NOT do

Test plan

🤖 Generated with Claude Code

This PR fixes: #35780

Diagnosis of the latest CLI failure showed the SiteAPIIT failure is
deterministic, not a timing race. The CI dotCMS instance returns:

  {"language":"LANG__404", "id":-1, "defaultLanguage": true},
  {"language":"English",   "id": 1, "defaultLanguage": false}

Bumping retries or backoff cannot fix this — the default is permanently
the LANG__404 sentinel (id=-1). The existing warmup passed because it
only verified that ANY language had id>0 (English does), not that the
DEFAULT language had id>0.

This strengthens the warmup:

- After listing, check whether the entry marked defaultLanguage=true
  actually has id>0. If yes, we are done.
- If not, pick the first language with id>0 (English in starter data)
  and call PUT /api/v2/languages/{id}/_makedefault with
  fireTransferAssetsJob=false to fix the broken state.
- Re-list to confirm before declaring success.

Adds the corresponding makeDefault() method to the CLI LanguageAPI
interface so the warmup can call the endpoint via the existing
Quarkus REST client.

The retry-on-language-null workaround from #35803 is preserved as
defense-in-depth, but should not be needed if the warmup succeeds.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented May 22, 2026

Claude finished @dsolistorres's task in 2m 31s —— View job


dotCMS Backend Review

  • Load dotCMS conventions (CLAUDE.md + docs)
  • Get Java diff for this PR
  • Run 4 specialized sub-agents in parallel (Security, Database, Java Standards, REST API)
  • Consolidate findings
  • Post review comment

All four sub-agents (Security, Database, Java Standards, REST API) returned NO_FINDINGS. The PR is scoped entirely to tools/dotcms-cli/ — a CLI client interface addition (LanguageAPI.makeDefault) plus integration-test setup hardening in SiteAPIIT. No production server code, no SQL, no cache writes, no security-sensitive paths, and the file is in the CLI module where Java 21 syntax is allowed.

Posted the clean review marker comment: #issuecomment-4521705371.

Note: I'm unable to submit a formal PR approval review due to permission restrictions on the bot account. See the FAQ for context. The pipeline's automatic --approve step was blocked, but no Critical/High findings need resolving.
· Branch: issue-35780-cli-fix-default-language

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented May 22, 2026

dotCMS Backend Review: no issues found.

@dsilvam dsilvam enabled auto-merge May 22, 2026 19:15
@dsilvam dsilvam added this pull request to the merge queue May 22, 2026
Merged via the queue into main with commit b3e0081 May 22, 2026
34 checks passed
@dsilvam dsilvam deleted the issue-35780-cli-fix-default-language branch May 22, 2026 20:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI: Safe To Rollback Area : CLI PR changes dotCMS CLI code

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Flaky Postman tests: WorkflowResource silently defaults missing languageId to -1L causing FK violation

2 participants