Skip to content

fix(data-quality): don't fail logical-suite adds when revisions don't read back - #31640

Closed
mohityadav766 wants to merge 1 commit into
mainfrom
fix/logical-suite-revision-readback
Closed

fix(data-quality): don't fail logical-suite adds when revisions don't read back#31640
mohityadav766 wants to merge 1 commit into
mainfrom
fix/logical-suite-revision-readback

Conversation

@mohityadav766

@mohityadav766 mohityadav766 commented Aug 17, 2026

Copy link
Copy Markdown
Member

Describe your changes

TestCaseRepository.prepareLogicalSuiteRelationshipChange advanced the testSuitesRevision entity_extension rows for the added test cases and the suite, immediately re-read them, and threw IllegalStateException("Failed to persist every test suite relationship revision") if the read-back returned fewer rows than were advanced.

That read-back is a snapshot read issued inside the flushInOneTransaction transaction. Under concurrent writers on the same revision rows it can come up short — MySQL's default REPEATABLE READ far more readily than Postgres' READ COMMITTED (nothing in conf/ or the Jdbi setup overrides either default). The throw then rolled back the entity_relationship rows that had persisted correctly and answered the caller with a 500.

The guard was never load-bearing. Revisions only order concurrent search writes, and every consumer already tolerates one it wasn't handed:

  • EntityUpdateContext.forEntity returns EMPTY for an absent id
  • SearchIndexHandler falls back to the ungated onEntityUpdated path
  • TestCaseIndex / TestSuiteIndex re-read the revision themselves, defaulting to 0L

So this logs the unresolved ids at WARN and carries on. An unresolved revision now costs one extra read at index time instead of losing the user's write.

Also:

  • LogicalSuiteRelationshipChange.relationshipRevision becomes nullable, and updateLogicalTestSuite passes EntityUpdateContext.empty() rather than a bogus 0L that would gate the suite's own index update.
  • addAllTestCasesToLogicalTestSuite skips null revisions when building its per-batch map — EntityUpdateContext's Map.copyOf rejects null values.

Why this matters

This has been turning integration-tests-mysql-elasticsearch red intermittently on unrelated PRs (#31526, #31527, #31540 all hit it; #31538 and #31543 didn't). integration-tests-postgres-opensearch stays green throughout. In the #31526 run all six concurrent PUT /api/v1/dataQuality/testCases/logicalTestCases calls from test_concurrentLogicalSuiteTestAddsPreserveEverySearchTest returned 500 inside the same 30 ms window, with no deadlock, lock-wait timeout, or pool error in the log.

Affected tests:

  • TestSuiteResourceIT.test_createLogicalTestSuiteAndAddTestCases
  • TestSuiteResourceIT.test_deleteLogicalTestSuiteKeepsTestCases
  • TestSuiteResourceIT.test_summaryTotalIncludesUnexecutedAndExcludesDeletedTests
  • TestCaseResourceIT.test_concurrentLogicalSuiteTestAddsPreserveEverySearchTest
  • TestCaseResourceIT.test_bulkAddTestCasesToLogicalTestSuiteByIds
  • TestCaseResourceIT.test_bulkAddAllTestCasesWithExcludeIds

Introduced by #30120.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Tests

TestCaseRepositoryTest.unresolvedRevisionsKeepTheMembershipChange drives prepareLogicalSuiteRelationshipChange with a deliberately short test-case read-back and a missing suite revision, and asserts the change still carries the membership references plus the revisions that did resolve.

Verified RED → GREEN — with the two throws restored the new test reproduces the exact CI error:

[ERROR] TestCaseRepositoryTest.unresolvedRevisionsKeepTheMembershipChange
        » IllegalState Failed to persist every test suite relationship revision

and with the fix:

Tests run: 66, Failures: 0, Errors: 0, Skipped: 0
  TestCaseRepositoryTest, TestSuiteRepositoryTest, TestCaseResolutionStatusRepositoryTest,
  EntityLifecycleEventDispatcherTest, SearchIndexHandlerTest

mvn -pl openmetadata-service spotless:check clean.

The existing ITs above are the end-to-end check — they should stop flaking on the MySQL lane.

🤖 Generated with Claude Code

Greptile Summary

This PR prevents logical-suite membership writes from rolling back when transactional revision read-backs are incomplete.

  • Logs unresolved test-case and suite revision IDs instead of throwing.
  • Omits unresolved test-case revisions from update contexts and uses an empty context for a missing suite revision.
  • Adds a regression test covering partial and absent revision read-backs.

Confidence Score: 5/5

The PR appears safe to merge, with no actionable correctness or security failures identified.

Missing revisions flow through existing index-time re-reads and relationship-preserving or revision-gated search updates, while transactional revision upserts continue to surface genuine persistence failures.

Important Files Changed

Filename Overview
openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/TestCaseRepository.java Converts incomplete revision read-backs from request-failing exceptions into logged fallback behavior while retaining search relationship ordering safeguards.
openmetadata-service/src/test/java/org/openmetadata/service/jdbi3/TestCaseRepositoryTest.java Adds regression coverage confirming partial test-case revisions and an absent suite revision no longer discard the membership change.

Sequence Diagram

sequenceDiagram
  participant API as Logical-suite API
  participant DB as Relational DB
  participant Repo as TestCaseRepository
  participant Events as Lifecycle Dispatcher
  participant Search as Search Index
  API->>DB: Commit membership and increment revisions
  DB-->>Repo: Partial revision read-back
  Repo->>Repo: Warn and retain resolved revisions
  Repo->>Events: Publish committed membership snapshot
  Events->>DB: Re-read omitted revisions as needed
  Events->>Search: Preserve or revision-gate relationship fields
Loading

Reviews (1): Last reviewed commit: "fix(data-quality): don't fail logical-su..." | Re-trigger Greptile

Context used:

… read back

prepareLogicalSuiteRelationshipChange advanced the testSuitesRevision rows
for the added test cases and the suite, then re-read them and threw
IllegalStateException if the read-back was short. That read-back is a
snapshot read inside the flush transaction, so concurrent writers on the
same rows can make it return fewer rows than were just advanced — MySQL's
default REPEATABLE READ far more readily than Postgres' READ COMMITTED.
The throw rolled back membership rows that had persisted correctly and
answered the caller with a 500.

Revisions only order concurrent search writes, and every consumer already
tolerates one it wasn't handed: EntityUpdateContext.forEntity falls back to
empty, and TestCaseIndex/TestSuiteIndex re-read the revision at index time.
So log the unresolved ids and carry on instead of failing the request.

Turned integration-tests-mysql-elasticsearch red intermittently across
unrelated PRs, e.g. TestSuiteResourceIT.test_createLogicalTestSuiteAndAddTestCases
and TestCaseResourceIT.test_concurrentLogicalSuiteTestAddsPreserveEverySearchTest,
where all six concurrent PUTs to /dataQuality/testCases/logicalTestCases
returned 500 in the same 30ms window.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@mohityadav766
mohityadav766 requested a review from a team as a code owner August 17, 2026 13:19
Copilot AI lite review requested due to automatic review settings August 17, 2026 13:19
@github-actions

Copy link
Copy Markdown
Contributor

❌ PR checklist incomplete

This PR cannot be merged until the following are addressed on its linked issue:

  • No GitHub issue is linked. Link an issue in the Development section of the PR (or add Fixes #12345 to the description). For a same-org cross-repo issue, add Fixes open-metadata/<repo>#123 to the description.

The fields live on the linked issue in the Shipping project (open the issue → right sidebar → Projects). After you set them, re-run this check (or push a commit) — issue/project changes do not re-trigger it automatically.

Maintainers can bypass this check by adding the skip-pr-checks label.

@github-actions github-actions Bot added backend safe to test Add this label to run secure Github workflows on PRs labels Aug 17, 2026
@gitar-bot

gitar-bot Bot commented Aug 17, 2026

Copy link
Copy Markdown
Code Review ✅ Approved

Removes the restrictive read-back validation in TestCaseRepository.prepareLogicalSuiteRelationshipChange to prevent spurious 500 errors during concurrent logical suite test additions on MySQL. No issues found.

Options

Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes intermittent failures when adding test cases to logical test suites by removing strict “revision read-back must match” guards that can fail under concurrent writers (especially on MySQL REPEATABLE READ). Instead of throwing and rolling back otherwise-correct relationship writes (causing 500s), the repository now logs unresolved revision IDs and continues, relying on existing search-index behavior that can re-read missing relationship revisions.

Changes:

  • Stop throwing on incomplete revision read-back in prepareLogicalSuiteRelationshipChange; log WARNs instead.
  • Make the logical-suite relationship revision nullable and avoid passing a bogus 0L gate to indexing (EntityUpdateContext.empty() when unresolved).
  • Add a unit test covering the “missing read-back rows” scenario to ensure membership changes still proceed.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/TestCaseRepository.java Removes revision read-back hard-fail, makes suite relationship revision nullable, and avoids null revision entries when building update contexts.
openmetadata-service/src/test/java/org/openmetadata/service/jdbi3/TestCaseRepositoryTest.java Adds a unit test asserting unresolved revisions don’t prevent membership-change publication and don’t gate indexing.
Suppressed comments (1)

openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/TestCaseRepository.java:1468

  • This record was widened from private to package-private for test access. Marking it as VisibleForTesting would document that it is not intended as part of the repository's public surface area.
  record LogicalSuiteRelationshipChange(

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +1357 to 1358
LogicalSuiteRelationshipChange prepareLogicalSuiteRelationshipChange(
UUID testSuiteId, List<EntityReference> testCaseReferences) {
@mohityadav766

Copy link
Copy Markdown
Member Author

closing as covered by #31569

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend safe to test Add this label to run secure Github workflows on PRs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants