Skip to content

test(csharp): stop hardcoding protocol in CloudFetch/CloseOperation E2E tests#508

Open
eric-wang-1990 wants to merge 4 commits into
mainfrom
csharp/e2e-protocol-not-hardcoded
Open

test(csharp): stop hardcoding protocol in CloudFetch/CloseOperation E2E tests#508
eric-wang-1990 wants to merge 4 commits into
mainfrom
csharp/e2e-protocol-not-hardcoded

Conversation

@eric-wang-1990
Copy link
Copy Markdown
Collaborator

@eric-wang-1990 eric-wang-1990 commented Jun 2, 2026

What & why

Several E2E tests hardcoded the connection protocol in the test body. Because Connect-level options take precedence over the Open-level config protocol (DatabricksDatabase.cs:91-95), a protocol: rest matrix job still opened Thrift sessions for those tests — which fail with ENDPOINT_NOT_FOUND … (HTTP 404) against a REST-only warehouse (e.g. the Reyden nightly). This PR removes the incidental hardcoding so tests follow the matrix/config protocol, and makes the genuinely protocol-specific test branch on protocol instead of pinning.

Changes

CloudFetchE2ETest — de-hardcoded

Removed the in-test protocols = { "thrift", "rest" } dimension. The CI matrix already runs rest and thrift as separate jobs, so the dimension both duplicated coverage and forced Thrift inside the rest job. Each case now runs once under the configured protocol; the REST-only result-disposition setup keys off TestConfiguration.Protocol. 20 cases → 10.

CloseOperationE2ETest — protocol-aware

DisposeEmitsCloseOperationEvent no longer pins Thrift. It inherits the configured protocol and branches the assertion to match how each protocol releases the server-side operation:

  • Thrift: composite_reader.close_operation emitted by DatabricksCompositeReader.Dispose.
  • REST/SEA: statement.dispose emitted by StatementExecutionStatement.Dispose, which brackets the CloseStatementAsync (HTTP DELETE) that releases the server statement. (There is no composite reader on the REST path.)

DisposeCloseOperation_..._Issue489 stays Thrift-pinned by design — it measures the Thrift TCloseOperationReq RPC latency via a started/completed event pair, which has no SEA equivalent (the REST close is a single DELETE).

StatementExecutionStatement.Dispose() (driver) — own span

To make the SEA branch's signal observable, Dispose() now starts its own span via this.TraceActivity(...) instead of annotating Activity.Current. Dispose typically runs outside any ambient activity (e.g. connection pooling), so the prior Activity.Current?.AddEvent was usually dropped — in tests and in production. This mirrors DatabricksCompositeReader.Dispose on the Thrift path and fixes a latent telemetry gap for statement.dispose / statement.dispose.error.

Validation

E2E run on this branch (commit f62dd55) against the dual-protocol warehouse — both jobs green:

  • E2E Tests (thrift)
  • E2E Tests (rest) ✅ — 1453 passed / 0 failed / 178 skipped.
  • CloseOperationE2ETest: failed under REST when Thrift-pinned in an earlier revision; now passes under REST via the statement.dispose branch.
  • CloudFetchE2ETest: all 10 cases pass under REST.

Out of scope (intentionally unchanged)

  • Genuine Thrift-vs-SEA parity tests that open both connections in one test: SeaMetadataE2ETests, IntervalValueTests.
  • REST/SEA-specific tests that pin "rest" by design and pass today: ServerSidePropertyE2ETest, StatementExecutionDriverE2ETests.

This pull request and its description were written by Isaac.

…2E tests

These tests pinned the connection protocol in the test body, overriding the
protocol selected by the connection config / CI matrix. Because Connect-level
options take precedence over the Open-level config protocol
(DatabricksDatabase.cs), a "rest" matrix job still opened Thrift sessions —
which fail with ENDPOINT_NOT_FOUND against a REST-only warehouse (e.g. Reyden).

- CloseOperationE2ETest: drop the hardcoded [Protocol] = "thrift" in both test
  bodies. The CloseOperation code path is protocol-agnostic (per the class
  docstring), so it now runs under whatever protocol the matrix selects.
- CloudFetchE2ETest: remove the in-test protocols = { "thrift", "rest" }
  dimension (the CI matrix already runs rest and thrift as separate jobs, so it
  was duplicating coverage and forcing Thrift even in the rest job). Each case
  now runs once under the configured protocol; the REST-only result-disposition
  setup keys off TestConfiguration.Protocol. 20 cases -> 10.

Genuine cross-protocol parity tests (SeaMetadataE2ETests, IntervalValueTests)
and REST/SEA-specific tests are intentionally left unchanged.

Co-authored-by: Isaac
@eric-wang-1990 eric-wang-1990 added the e2e-test Trigger E2E tests on this PR label Jun 2, 2026
@eric-wang-1990 eric-wang-1990 enabled auto-merge June 2, 2026 20:47
Reverts the CloseOperationE2ETest change from the previous commit. The E2E run
showed all 4 of these tests fail under REST: the assertion targets the
composite_reader.close_operation trace event emitted by
DatabricksCompositeReader.Dispose, which only exists on the Thrift path. The
REST path (StatementExecutionConnection) has no composite reader, so the event
is never emitted. This test is Thrift-specific by design, so the [Protocol] =
"thrift" pin is correct; added a comment explaining why. Skipping it on
REST-only warehouses is tracked separately.

The CloudFetchE2ETest de-hardcoding is kept — validated passing under both the
rest and thrift matrix jobs.

Co-authored-by: Isaac
@eric-wang-1990 eric-wang-1990 added e2e-test Trigger E2E tests on this PR and removed e2e-test Trigger E2E tests on this PR labels Jun 2, 2026
@eric-wang-1990 eric-wang-1990 changed the title test(csharp): stop hardcoding protocol in CloudFetch/CloseOperation E2E tests test(csharp): stop hardcoding protocol in CloudFetchE2ETest Jun 2, 2026
…ment.dispose on SEA)

DisposeEmitsCloseOperationEvent no longer hardcodes Thrift — it inherits the
configured protocol and branches the assertion to match how each protocol
releases the server-side operation:
- Thrift: composite_reader.close_operation emitted by DatabricksCompositeReader.Dispose.
- REST/SEA: statement.dispose emitted by StatementExecutionStatement.Dispose,
  which brackets the CloseStatementAsync (HTTP DELETE).

To make the SEA event observable, StatementExecutionStatement.Dispose now starts
its own span via this.TraceActivity (named StatementExecutionStatement.Dispose)
instead of annotating Activity.Current. Dispose typically runs outside any
ambient activity (e.g. connection pooling), so the prior Activity.Current?.AddEvent
was usually dropped — in tests and in production. This mirrors
DatabricksCompositeReader.Dispose on the Thrift path, which owns its own span.

DisposeCloseOperation_..._Issue489 stays Thrift-pinned: it measures the Thrift
TCloseOperationReq RPC latency via a started/completed event pair, which has no
SEA equivalent (the REST close is a single DELETE).

Co-authored-by: Isaac
@eric-wang-1990 eric-wang-1990 added e2e-test Trigger E2E tests on this PR and removed e2e-test Trigger E2E tests on this PR labels Jun 2, 2026
@eric-wang-1990 eric-wang-1990 changed the title test(csharp): stop hardcoding protocol in CloudFetchE2ETest test(csharp): stop hardcoding protocol in CloudFetch/CloseOperation E2E tests Jun 2, 2026
@eric-wang-1990 eric-wang-1990 added this pull request to the merge queue Jun 4, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jun 4, 2026
@eric-wang-1990 eric-wang-1990 added this pull request to the merge queue Jun 4, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jun 4, 2026
@eric-wang-1990 eric-wang-1990 added this pull request to the merge queue Jun 5, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jun 5, 2026
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.

2 participants