Skip to content

Add ConnectionFactory + connection-state/transaction negative suites (PR 5a/8)#1528

Merged
sreekanth-db merged 1 commit into
comparator-v2from
comparator-connection-factory
Jul 3, 2026
Merged

Add ConnectionFactory + connection-state/transaction negative suites (PR 5a/8)#1528
sreekanth-db merged 1 commit into
comparator-v2from
comparator-connection-factory

Conversation

@sreekanth-db

Copy link
Copy Markdown
Collaborator

What

Introduces the fresh-connection mechanism for negative suites whose cases mutate or destroy connection/session state, plus the first two such suites. Builds on #1524#1527.

Splits the planned PR 5 into 5a (this — mechanism + the two lower-risk suites) and 5b (later — NEGATIVE_CONNECTION, NEGATIVE_CANCEL_TIMEOUT, NEGATIVE_VOLUME). The series is now 8 PRs.

Mechanism

  • config/ConnectionFactory.openFresh(side) — a dedicated, uncached connection
  • ConnectionManager.openUncached(url)DriverManager.getConnection, not cached
  • SuiteProvider: backward-compatible default 5-arg execute(conn1, conn2, ConnectionFactory, tc, label) delegating to the 4-arg form — only isolation suites override it; the 12 existing providers are untouched
  • JDBCDriverComparisonTest builds a per-config factory bound to the resolved LEFT/RIGHT URLs and calls the 5-arg form

Suites

Each opens its own fresh connections and closes them in a finally, so they never poison the shared connections:

  • NEGATIVE_CONNECTION_STATEsetCatalog/setSchema/setClientInfo/USE to a nonexistent target
  • NEGATIVE_TRANSACTION — commit/rollback with autocommit on; DDL inside a manual transaction (throwaway table dropped in a finally)

Included fix: one-sided diff mis-filing

ErrorDiffs.compare returns a flat list, so callers that dumped it into dataDifferences mis-filed one-sided diffs (which belong in metadataDifferences) and dropped them from the CSV summary — surfaced live as an empty summary on the transaction case. New ErrorDiffs.foldInto(result, ...) preserves the metadata/data split; migrated all five negative providers (the two new + DDL/DML/Batch from #1527) to it. Kept compare() for the DML/Volume positive suites with a javadoc warning. Added foldInto unit tests.

Live validation

Ran against the peco serverless warehouse (Thrift-vs-SEA, ERROR_COMPARISON_MODE=shadow). Positive suites run in the same JVM after the state-mutating negatives and still PASS — no shared-connection poisoning. Surfaced a real one-sided divergence: DDL inside a manual transaction returns false on one side and throws 42P07 on the other.

Testing

ErrorComparatorTest — 20/20 (added foldInto coverage); two live shadow runs; 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.

…(PR 5a/8)

Introduces the fresh-connection mechanism for negative suites whose cases
mutate or destroy connection/session state, plus the first two such suites.
(Splits the planned PR 5 into 5a here + 5b later — CONNECTION, CANCEL_TIMEOUT,
VOLUME — so the count is now 8.)

Mechanism:
- config/ConnectionFactory.openFresh(side) — a dedicated, uncached connection
- ConnectionManager.openUncached(url) — DriverManager.getConnection, not cached
- SuiteProvider: backward-compatible default 5-arg execute(conn1, conn2,
  ConnectionFactory, tc, label) delegating to the 4-arg form; only isolation
  suites override it, the 12 existing providers are untouched
- JDBCDriverComparisonTest builds a per-config factory bound to the resolved
  LEFT/RIGHT URLs and calls the 5-arg form

Suites (each opens its own fresh connections and closes them in a finally, so
they never poison the shared connections):
- NEGATIVE_CONNECTION_STATE: setCatalog/setSchema/setClientInfo/USE to a
  nonexistent target
- NEGATIVE_TRANSACTION: commit/rollback with autocommit on; DDL inside a manual
  transaction (throwaway table dropped in a finally)

Also fixes one-sided-diff mis-filing exposed by these suites: ErrorDiffs.compare
returns a FLAT list, so callers that dumped it into dataDifferences mis-filed
one-sided diffs (which belong in metadataDifferences) and dropped them from the
CSV summary. New ErrorDiffs.foldInto(result, ...) preserves the metadata/data
split; migrated all five negative providers (the two new + DDL/DML/Batch from
PR 4) to it. Kept compare() for the DML/Volume positive suites with a javadoc
warning. Added foldInto unit tests.

Validated live against the peco serverless warehouse (Thrift-vs-SEA, shadow):
positive suites run in the same JVM AFTER the state-mutating negatives and still
PASS (no shared-connection poisoning). Surfaced a real one-sided divergence:
DDL-in-transaction returns false on one side, throws 42P07 on the other.
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 f803778 into comparator-v2 Jul 3, 2026
1 check failed
@sreekanth-db sreekanth-db deleted the comparator-connection-factory branch July 3, 2026 12:04
sreekanth-db added a commit that referenced this pull request Jul 3, 2026
## 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_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.

## 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.

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