Skip to content

test(csharp): retry EnableMultipleCatalogSupport metadata query on transient server 500 - #615

Open
eric-wang-1990 wants to merge 1 commit into
mainfrom
fix/flaky-multicatalog-metadata-retry
Open

test(csharp): retry EnableMultipleCatalogSupport metadata query on transient server 500#615
eric-wang-1990 wants to merge 1 commit into
mainfrom
fix/flaky-multicatalog-metadata-retry

Conversation

@eric-wang-1990

Copy link
Copy Markdown
Collaborator

Summary

De-flakes StatementTests.EnableMultipleCatalogSupportAffectsMetadataQueries, which intermittently fails the merge-queue E2E run with a server-side error:

DatabricksException : Statement Execution API request failed with status code 500 (InternalServerError).
Error Code: INTERNAL_ERROR, Message: The result files are not available in the result metadata.

The 500 is raised inside ExecuteMetadataSqlAsync (from GetTables / GetColumns) — a SEA backend result-staging race, not a driver or test-logic defect:

Fix

Wrap the metadata query in ExecuteMetadataQueryWithRetryAsync: up to 4 attempts with exponential backoff (0.5s / 1s / 2s), each on a fresh statement, retrying only when the exception text contains "result files are not available in the result metadata". Any other exception — and all the schema-comparison and row-count assertions in TestMetadataQuery — propagate unchanged, so genuine regressions still fail.

Verification

  • Local (SEA): EnableMultipleCatalogSupportAffectsMetadataQueries 2/2 passed (retry is a no-op on the happy path).

Follow-up (not in this PR)

The more general fix is a driver-side retry of this transient 500 in StatementExecutionClient.EnsureSuccessStatusCodeAsync — real PowerBI clients hit the same server race, not just this test. That is a higher-risk driver change (needs careful scoping of which 500s are safe to retry) and is intentionally left as a separate follow-up; this PR only stabilizes the test / merge queue.

This pull request and its description were written by Isaac.

…ansient server 500

EnableMultipleCatalogSupportAffectsMetadataQueries intermittently fails the
merge-queue E2E run with a server-side HTTP 500 INTERNAL_ERROR "The result files
are not available in the result metadata" on a metadata query (GetTables /
GetColumns via ExecuteMetadataSqlAsync). This is a SEA backend result-staging
race, not a driver or test-logic defect: it is always the API-level 500 (never an
assertion mismatch), the identical query succeeds on retry, and it hit whichever
PR happened to be live on the shared warehouse (observed on both #614 and #604
merge_group runs at the same time).

Fix: wrap the metadata query in ExecuteMetadataQueryWithRetryAsync — up to 4
attempts with exponential backoff (0.5/1/2s), each on a fresh statement, retrying
ONLY on that specific transient error string. Every other exception and all the
schema/row assertions propagate unchanged, so genuine regressions still fail.

Note: the more general fix is a driver-side retry of this transient 500 in
StatementExecutionClient (PowerBI users hit the same server race); that is a
separate, higher-risk driver change and is left as a follow-up. This PR de-flakes
the test so the merge queue stabilizes.

Local: EnableMultipleCatalogSupportAffectsMetadataQueries 2/2 passed.

Co-authored-by: Isaac
@eric-wang-1990 eric-wang-1990 added the e2e-test Trigger E2E tests on this PR label Aug 3, 2026

@peco-review-bot peco-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verdict: 1 Low

Looks good — a clean, well-reasoned test-only de-flake. Retry logic is correct (backoff sequence, attempt < maxAttempts stop condition, and narrow transient-marker matching all check out); one low note about not disposing failed statements across retry attempts.


for (int attempt = 1; ; attempt++)
{
var statement = connection.CreateStatement();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Low — The retry loop creates a fresh statement on every attempt but never disposes the failed ones. On a transient 500 the current statement is abandoned (the catch filter delays, then the loop continues and allocates a new statement) so up to 3 statements — each holding a server-side handle / HTTP resources — leak per invocation until GC. Much of this test file uses using var statement = connection.CreateStatement(); (e.g. lines 78, 840, 1321) for exactly this reason. Consider disposing the statement per attempt, e.g. wrap the body in using var statement = connection.CreateStatement(); inside the loop so each failed attempt is released before the backoff/retry.

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

Labels

e2e-test Trigger E2E tests on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant