Skip to content

Add connection/cancel-timeout/volume negative suites (PR 5b/8)#1529

Merged
sreekanth-db merged 1 commit into
comparator-v2from
comparator-negative-connection-cancel-volume
Jul 3, 2026
Merged

Add connection/cancel-timeout/volume negative suites (PR 5b/8)#1529
sreekanth-db merged 1 commit into
comparator-v2from
comparator-negative-connection-cancel-volume

Conversation

@sreekanth-db

Copy link
Copy Markdown
Collaborator

What

Completes the isolation-heavy negative suites, on top of the ConnectionFactory mechanism from #1528. Builds on #1524#1528.

ConnectionFactory extension

NEGATIVE_CONNECTION needs to build deliberately-broken connections, so the factory now also exposes urlFor(side), token(), and open(url, token) (an uncached open with an arbitrary URL/token). Backed by ConnectionManager.openUncached(url, token) + getToken().

Suites

  • NEGATIVE_CONNECTION — opening is the test: starts from a side's healthy URL/token and corrupts one piece (bad token, unknown host, malformed httpPath, bad warehouse id, bad ConnCatalog/ConnSchema), then compares the connect failure. Closes any connection that unexpectedly opens.
  • NEGATIVE_CANCEL_TIMEOUTcancel() mid slow query / after completion / on an already-cancelled statement, and setQueryTimeout(1) on a slow query. Own fresh connections; the slow query is a bounded range cross-join (~5s, no server-side sleep) to keep load and flakiness low.
  • NEGATIVE_VOLUME — GET/PUT/REMOVE failures + op-after-close. Runs under the VOLUME_OPERATIONS config (needs VolumeOperationAllowedLocalPaths), so it is excluded from DEFAULT_PARAMS like the positive VOLUME_OPERATIONS suite.

Live validation

Ran against the peco serverless warehouse (Thrift-vs-SEA, ERROR_COMPARISON_MODE=shadow). Positive suites run in the same JVM after the isolation-heavy negatives and still PASS — no shared-connection poisoning.

  • NEGATIVE_CONNECTION surfaced real error-shape divergences (bad token/host/warehouse).
  • NEGATIVE_CANCEL_TIMEOUT surfaced two one-sided findings: cancel-after-complete and double-cancel throw STATEMENT_CLOSED on one side and return normally on the other.
  • NEGATIVE_VOLUME is all-PASS — confirmed meaningful (not vacuous) via a throwaway probe: every case genuinely throws DatabricksVolumeOperationException / statement-closed identically on both endpoints, so PASS is real agreement.

Testing

ErrorComparatorTest — 20/20; live shadow runs (two, + volume probe); clean compile; Isaac Review (/review --uncommitted) — 0 findings.

NO_CHANGELOG=true (test-only comparator tooling, no driver behavior change).

This pull request and its description were written by Isaac.

Completes the isolation-heavy negative suites on top of the ConnectionFactory
mechanism from PR 5a.

ConnectionFactory extension — NEGATIVE_CONNECTION needs to build deliberately
broken connections, so the factory now also exposes urlFor(side), token(), and
open(url, token) (an uncached open with an arbitrary URL/token). Backed by
ConnectionManager.openUncached(url, token) + getToken().

Suites:
- NEGATIVE_CONNECTION: opening is the test — starts from a side's healthy URL/
  token and corrupts one piece (bad token, unknown host, malformed httpPath,
  bad warehouse id, bad ConnCatalog/ConnSchema), then compares the connect
  failure. Closes any connection that unexpectedly opens.
- NEGATIVE_CANCEL_TIMEOUT: cancel() mid slow query / after completion / on an
  already-cancelled statement, and setQueryTimeout(1) on a slow query. Own fresh
  connections; the slow query is a bounded range cross-join (~5s, no server-side
  sleep) to keep load and flakiness low.
- NEGATIVE_VOLUME: GET/PUT/REMOVE failures + op-after-close. Runs under the
  VOLUME_OPERATIONS config (needs VolumeOperationAllowedLocalPaths), so it is
  excluded from DEFAULT_PARAMS like the positive VOLUME_OPERATIONS suite.

Validated live against the peco serverless warehouse (Thrift-vs-SEA, shadow):
positive suites run in the same JVM after the isolation-heavy negatives and
still PASS. NEGATIVE_CONNECTION surfaced real error-shape divergences (bad
token/host/warehouse); NEGATIVE_CANCEL_TIMEOUT surfaced two one-sided findings
(cancel-after-complete and double-cancel throw STATEMENT_CLOSED on one side).
NEGATIVE_VOLUME is all-PASS — confirmed meaningful (not vacuous) via a throwaway
probe: every case throws DatabricksVolumeOperationException / statement-closed
identically on both endpoints.

ErrorComparatorTest: 20/20. Isaac Review: 0 findings.

NO_CHANGELOG=true (test-only comparator tooling).

Co-authored-by: Isaac
Signed-off-by: Sreekanth Vadigi <sreekanth.vadigi@databricks.com>
@sreekanth-db sreekanth-db merged commit fec170a into comparator-v2 Jul 3, 2026
1 check failed
@sreekanth-db sreekanth-db deleted the comparator-negative-connection-cancel-volume branch July 3, 2026 12:44
sreekanth-db added a commit that referenced this pull request Jul 3, 2026
…8) (#1530)

## What

The final batch of negative suites — row-limit rejection, ResultSet
misuse, and the Databricks async extension API. Builds on #1524#1529.

| Suite | Cases |
|---|---|
| `NEGATIVE_STATEMENT_SELECT_TRUNCATED` | invalid
`setMaxRows`/`setLargeMaxRows` values (negative, `MIN_VALUE`) —
set-then-execute captured together since the failure may originate at
either point |
| `NEGATIVE_RESULTSET` | `next()`/`getObject()` after the ResultSet or
Statement is closed; out-of-range column index |
| `NEGATIVE_ASYNC` | `getExecutionResult()` before any async execution;
`executeAsync()` on invalid SQL; `getExecutionResult()` after the
statement is closed |

### Notes on scope
- **`NEGATIVE_RESULTSET`**: the originally-planned CloudFetch
link-expiry / chunk-download failure is **intentionally omitted** — it
can't be provoked deterministically from a client test (links are valid
for the query's lifetime; expiry is time/infra dependent), and would
require server-side fault injection out of scope for this harness.
Documented in the provider javadoc.
- **`NEGATIVE_ASYNC`**: uses `stmt.unwrap(IDatabricksStatement.class)`.
The invalid-SQL case **polls `getExecutionResult`** so the async failure
is actually captured — `executeAsync` only submits; the syntax error
surfaces on result retrieval.

## Live validation

Ran against the peco serverless warehouse (Thrift-vs-SEA,
`ERROR_COMPARISON_MODE=shadow`). Positive `STATEMENT_SELECT` runs in the
same JVM and still **PASSes**.

Each case was **probe-verified to hit a real error path** (not vacuous
PASS):
- `setMaxRows(-1)` → `DatabricksValidationException: Invalid input for
maxRows`
- `getExecutionResult()` before exec → `DatabricksSQLException: No
execution available`
- next-after-close → `Operation not allowed - ResultSet is closed`
- `getObject(999)` → real 3-field error mismatch (DIFF)

The all-PASS cases are genuine agreement (both endpoints throw
identically), confirmed via a throwaway probe. Also **caught and fixed a
vacuous first cut** of the async invalid-SQL case that captured only the
successful submit rather than the eventual failure.

## Testing

`ErrorComparatorTest` — 20/20; live shadow runs + probe; clean compile;
Isaac Review (`/review --uncommitted`) — 0 findings.

NO_CHANGELOG=true (test-only comparator tooling, no driver behavior
change).

This pull request and its description were written by Isaac.

Signed-off-by: Sreekanth Vadigi <sreekanth.vadigi@databricks.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant