Skip to content

test(testing-drivers): isolate pre-aggregations schema per run to fix shared-cloud races#11151

Merged
paveltiunov merged 3 commits into
masterfrom
claude/driver-test-preagg-schema-rd6gyd
Jun 24, 2026
Merged

test(testing-drivers): isolate pre-aggregations schema per run to fix shared-cloud races#11151
paveltiunov merged 3 commits into
masterfrom
claude/driver-test-preagg-schema-rd6gyd

Conversation

@paveltiunov

Copy link
Copy Markdown
Member

Parallel CI legs (use_tesseract_sql_planner false/true) for the same
shared-cloud database pointed at the same hardcoded pre-aggregations
schema, so they raced building, refreshing, and dropping the same
pre-agg tables non-deterministically (confirmed on BigQuery; athena and
databricks-jdbc have the identical latent race).

Make the schema overridable via docker-compose interpolation, defaulting
to each fixture's existing value so local/other runs are unaffected. The
companion cube-runtime workflow sets
DRIVERS_TESTS_CUBEJS_PRE_AGGREGATIONS_SCHEMA per matrix leg so each
concurrent leg gets its own pre-aggregations schema.

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_015MhpNg5eCmC34941RWYvnw

… shared-cloud races

Parallel CI legs (use_tesseract_sql_planner false/true) for the same
shared-cloud database pointed at the same hardcoded pre-aggregations
schema, so they raced building, refreshing, and dropping the same
pre-agg tables non-deterministically (confirmed on BigQuery; athena and
databricks-jdbc have the identical latent race).

Make the schema overridable via docker-compose interpolation, defaulting
to each fixture's existing value so local/other runs are unaffected. The
companion cube-runtime workflow sets
DRIVERS_TESTS_CUBEJS_PRE_AGGREGATIONS_SCHEMA per matrix leg so each
concurrent leg gets its own pre-aggregations schema.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015MhpNg5eCmC34941RWYvnw
@paveltiunov paveltiunov requested a review from a team as a code owner June 23, 2026 20:30
@claude

claude Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Claude finished @paveltiunov's task in 25s —— View job


Code Review

Verdict: LGTM ✅ — Targeted, minimal fix. 0 high, 0 medium, 1 low.

Details

Summary

The change swaps a hardcoded CUBEJS_PRE_AGGREGATIONS_SCHEMA value for a ${DRIVERS_TESTS_CUBEJS_PRE_AGGREGATIONS_SCHEMA:-<old default>} interpolation in three fixtures (athena, bigquery, databricks-jdbc). docker-compose ${VAR:-default} syntax is supported, so when the env var is unset behavior is identical to before — preserves local/other runs. The companion workflow can now set a unique schema per matrix leg to eliminate the shared-cloud race.

Correctness

  • BigQuery default preserved as dev_pre_aggregations; athena/databricks-jdbc preserved as drivers_tests_preaggs. ✅
  • No quoting issues — the entire value is a single JSON string consumed by compose interpolation.
  • Three fixtures touched are exactly the shared-cloud DBs susceptible to the race; local engines (postgres/mysql/clickhouse/etc.) intentionally not changed since each spawns its own container.

Low-severity observations

  • Cleanup responsibility unchanged. If a leg crashes before teardown, the per-run schema may leak in the shared cloud account. Worth a follow-up to periodically reap stale drivers_tests_preaggs_* schemas (e.g. older than 24h) on BigQuery/Athena/Databricks. Not a blocker for this PR.
  • The fix relies on the companion cube-runtime workflow setting DRIVERS_TESTS_CUBEJS_PRE_AGGREGATIONS_SCHEMA uniquely per leg. Worth double-checking that PR ensures uniqueness across concurrent legs and across concurrent PRs (e.g. include run id + matrix index, not just leg name).

Testing

No unit-test changes needed — this is CI infra. Validation is the green/non-flaky CI matrix itself.

• [Branch](https://github.com/cube-js/cube/tree/claude/driver-test-preagg-schema-rd6gyd)

Redshift also runs the use_tesseract_sql_planner false/true matrix
against the same cloud cluster and shared export bucket, but had no
explicit CUBEJS_PRE_AGGREGATIONS_SCHEMA, so both legs fell back to the
same default schema and raced on the same pre-agg tables.

Add the overridable schema (default dev_pre_aggregations) so each
concurrent leg gets its own pre-aggregations schema via
DRIVERS_TESTS_CUBEJS_PRE_AGGREGATIONS_SCHEMA.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015MhpNg5eCmC34941RWYvnw
@claude

claude Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Claude finished @paveltiunov's task in 28s —— View job


Code Review

Verdict: LGTM ✅ — Minimal, targeted CI fix. 0 high, 0 medium, 1 low.

Details
  • Read PR diff
  • Review correctness, security, performance
  • Post review

Summary

This iteration extends the original fix (athena/bigquery/databricks-jdbc) to redshift, which was previously inheriting whatever default CUBEJS_PRE_AGGREGATIONS_SCHEMA Cube uses and was equally vulnerable to the same shared-cloud race between parallel use_tesseract_sql_planner legs. Now redshift gets an explicit ${DRIVERS_TESTS_CUBEJS_PRE_AGGREGATIONS_SCHEMA:-dev_pre_aggregations} entry consistent with the other three fixtures.

Correctness

  • ${VAR:-default} interpolation is valid docker-compose syntax; when the env var is unset, behavior matches prior runs. ✅
  • Defaults preserved per fixture: athena/databricks drivers_tests_preaggs, bigquery/redshift dev_pre_aggregations. ✅
  • Only the four shared-cloud DBs touched; local-container DBs intentionally untouched.
  • Redshift entry is correctly inserted into the environment block alongside the other CUBEJS_DB_* vars (packages/cubejs-testing-drivers/fixtures/redshift.json:25).

Security / Performance

  • No secret-handling, query path, or runtime behavior change. N/A.

Low

  • Schema-leak risk in shared accounts. If a leg crashes before teardown, per-run schemas leak in BigQuery/Athena/Databricks/Redshift. Not a regression introduced here, but the per-run schemes increase cardinality of leaked schemas. Worth a follow-up reaper job (e.g. drop drivers_tests_preaggs_* / dev_pre_aggregations_* older than 24h).
  • Effectiveness still depends on the companion workflow setting DRIVERS_TESTS_CUBEJS_PRE_AGGREGATIONS_SCHEMA uniquely across concurrent PRs as well as legs — recommend including run id + matrix index.

Testing

CI-infra change; validation is a green non-flaky matrix.

• [Branch](https://github.com/cube-js/cube/tree/claude/driver-test-preagg-schema-rd6gyd)

@codecov

codecov Bot commented Jun 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 58.80%. Comparing base (6a640a6) to head (9a83fb6).

❗ There is a different number of reports uploaded between BASE (6a640a6) and HEAD (9a83fb6). Click for more details.

HEAD has 1 upload less than BASE
Flag BASE (6a640a6) HEAD (9a83fb6)
cubesql 1 0
Additional details and impacted files
@@             Coverage Diff             @@
##           master   #11151       +/-   ##
===========================================
- Coverage   79.18%   58.80%   -20.38%     
===========================================
  Files         474      217      -257     
  Lines       96895    17511    -79384     
  Branches     3563     3563               
===========================================
- Hits        76727    10298    -66429     
+ Misses      19650     6695    -12955     
  Partials      518      518               
Flag Coverage Δ
cube-backend 58.80% <ø> (ø)
cubesql ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…e env

The fixture env pre-pass in runEnvironment resolved only bare ${VAR} and
treated the whole inner string as the variable name, so the new
${DRIVERS_TESTS_CUBEJS_PRE_AGGREGATIONS_SCHEMA:-dev_pre_aggregations}
values threw 'Env variable ...:-dev_pre_aggregations must be defined' and
failed every shared-cloud driver test.

Parse an optional ':-default' suffix (docker-compose semantics): use the
env var when set, otherwise the default. Bare ${VAR} still throws when
undefined, preserving required-secret validation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015MhpNg5eCmC34941RWYvnw
@github-actions github-actions Bot added the javascript Pull requests that update Javascript code label Jun 24, 2026
@claude

claude Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Claude finished @paveltiunov's task in 48s —— View job


Code Review

Verdict: LGTM ✅ — 0 high, 0 medium, 2 low.

Details
  • Read PR diff (4 fixtures + parser)
  • Review new ${VAR:-default} parser in runEnvironment.ts
  • Check for dup/stale review threads (none)
  • Post review

Summary

New commit 9a83fb6 adds the actual parser support that the fixtures depend on: runEnvironment.ts now recognizes docker-compose-style ${VAR:-default} in fixture env values. Previously only bare ${VAR} was supported, so prior iterations would have failed in any local/forked run that didn't export DRIVERS_TESTS_CUBEJS_PRE_AGGREGATIONS_SCHEMA. Closes that gap.

Correctness — runEnvironment.ts:125-146

  • ${VAR} form: unchanged behavior — uses env value, throws if missing. ✅
  • ${VAR:-default} form: uses env value if set & non-empty, otherwise the default. ✅
  • Empty-string env var falls through to default — matches compose :- semantics (the :- form fires on null OR empty, unlike : which fires only on null). ✅
  • Empty default ${VAR:-} yields '' — also matches compose. ✅
  • Outer guard val.indexOf('${') === 0 && val.indexOf('}') === length - 1 still safely rejects multi-interpolation or mid-string interpolation since indexOf('}') returns the first match. So ${A}${B} is left untouched (preserving prior behavior, not new functionality). 👍
  • Fixture parity: athena/databricks drivers_tests_preaggs, bigquery/redshift dev_pre_aggregations. Defaults preserve pre-change behavior. ✅

Security / Performance

N/A — CI infra only.

Low-severity observations

  • name is trimmed but fallback is not (runEnvironment.ts:136-137). Compose itself doesn't trim the default either, so this is consistent — but it does mean a typo like ${VAR:- foo} would silently apply a leading-space default. Not worth fixing unless it bites someone; flagging only because the trimming asymmetry is easy to miss.
  • Schema-leak risk in shared accounts (carried over from prior iterations). If a leg crashes before teardown, per-run schemas accumulate in BigQuery/Athena/Databricks/Redshift. Cardinality is now higher with the per-run scheme. Worth a follow-up reaper job (e.g. drop drivers_tests_preaggs_* / dev_pre_aggregations_* older than 24h).

Testing

CI-infra change; validation is a green non-flaky matrix across both use_tesseract_sql_planner legs.

• [Branch](https://github.com/cube-js/cube/tree/claude/driver-test-preagg-schema-rd6gyd)

@paveltiunov paveltiunov merged commit 2530d1e into master Jun 24, 2026
119 of 120 checks passed
@paveltiunov paveltiunov deleted the claude/driver-test-preagg-schema-rd6gyd branch June 24, 2026 11:01
@ovr

ovr commented Jun 24, 2026

Copy link
Copy Markdown
Member

@claude Question, does anyone setup DRIVERS_TESTS_CUBEJS_PRE_AGGREGATIONS_SCHEMA on CI? Could you point me to exact place where it's done

@claude

claude Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Claude finished @ovr's task in 46s —— View job


Answer

Short version: DRIVERS_TESTS_CUBEJS_PRE_AGGREGATIONS_SCHEMA is not set anywhere in this repository. A repo-wide search turns it up in exactly four places, all consumers (the fixtures), and zero producers:

packages/cubejs-testing-drivers/fixtures/athena.json:9
packages/cubejs-testing-drivers/fixtures/bigquery.json:10
packages/cubejs-testing-drivers/fixtures/databricks-jdbc.json:76
packages/cubejs-testing-drivers/fixtures/redshift.json:25

It is not referenced anywhere under .github/ (grep over .github returns no matches).

Where it's supposed to be set

Per this PR's description, the value is set by the companion cube-runtime workflow, per matrix leg — that workflow lives in a separate (private) repo, not in cube-js/cube, which is why you can't find it here.

For comparison, the analogous knob that is wired up in this repo is DRIVERS_TESTS_CUBEJS_TESSERACT_SQL_PLANNER, set per matrix leg in the Run tests step:

.github/workflows/drivers-tests.yml:378

      - name: Run tests
        ...
        env:
          DRIVERS_TESTS_CUBEJS_TRANSPILATION_NATIVE: false
          DRIVERS_TESTS_CUBEJS_TESSERACT_SQL_PLANNER: ${{ (github.event_name == 'workflow_dispatch' && github.event.inputs.use_tesseract_sql_planner) || matrix.use_tesseract_sql_planner }}

DRIVERS_TESTS_CUBEJS_PRE_AGGREGATIONS_SCHEMA is absent from that same env: block.

Practical implications

  • In cube-js/cube's own drivers-tests.yml runs, the var is currently unset → the fixtures fall back to their ${VAR:-default} defaults (dev_pre_aggregations for bigquery/redshift, drivers_tests_preaggs for athena/databricks-jdbc). Behavior is identical to before this PR.
  • The race this PR targets is therefore only actually fixed once the cube-runtime workflow sets the var uniquely per leg. If that wiring isn't in place (or doesn't guarantee uniqueness across concurrent legs and concurrent PRs — e.g. run id + matrix index), the shared-cloud race remains.

If you'd like, I can add a DRIVERS_TESTS_CUBEJS_PRE_AGGREGATIONS_SCHEMA entry to the Run tests step's env: block in .github/workflows/drivers-tests.yml so it's set per leg directly in this repo — though note my GitHub App permissions don't allow modifying files under .github/workflows, so that change would need to be made by a human.
Branch

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

Labels

javascript Pull requests that update Javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants