mirror of
https://github.com/apache/superset.git
synced 2026-09-01 13:01:33 +00:00
The oceanbase driver install step reported success but never actually installed oceanbase_py: --no-deps applied to `-e .[oceanbase]` blocks pip from installing anything the extras marker pulls in, including oceanbase_py itself, not just its conflicting transitive dependency. Installing oceanbase_py as its own standalone package instead means --no-deps only skips *its* dependencies, which is what was actually intended. Confirmed via a manual workflow_dispatch run (nightly_only dialects don't run on pull_request, so this needed a manual trigger to catch at all). Vertica dropped from this PR: the same workflow_dispatch run found `vertica/vertica-ce` doesn't exist on Docker Hub. The only actively maintained official image (`opentext/vertica-k8s`) is built to run under the Vertica Kubernetes operator's orchestration, not as a standalone single-container database -- a bare `docker run` likely won't bootstrap a working instance on its own. Needs real investigation before it's worth another attempt, same as Solr/IoTDB/TDengine/Parseable/Dremio earlier in this series.
189 lines
8.1 KiB
YAML
189 lines
8.1 KiB
YAML
# db_engine_specs tests against real databases (testcontainers)
|
|
name: Testcontainers
|
|
|
|
# Spins up real Docker containers (see tests/testcontainers/ for the current
|
|
# dialect list) via testcontainers-python, which catches real dialect/driver
|
|
# regressions -- the kind mocked db_engine_specs unit tests structurally
|
|
# cannot, e.g. apache/superset#42899 (Trino emitting OFFSET before LIMIT).
|
|
# Runs on a nightly cron (catches drift from a driver's own releases, not
|
|
# just from Superset's changes) and on pull_request, scoped via `paths` to
|
|
# only PRs that actually touch this test suite or the workflow itself, so
|
|
# unrelated PRs across the repo are never affected.
|
|
#
|
|
# A matrix entry can set `nightly_only: true` to run only on the cron (or a
|
|
# manual workflow_dispatch), never on pull_request -- for a dialect whose
|
|
# image is too heavy (a multi-service cluster, a many-GB image, a slow
|
|
# licensed installer) to justify adding its wall-clock/resource cost to
|
|
# every PR that merely touches this suite. Omit the field entirely for a
|
|
# normal dialect; it isn't nightly-only by default.
|
|
permissions:
|
|
contents: read
|
|
|
|
on:
|
|
schedule:
|
|
- cron: "0 5 * * *"
|
|
workflow_dispatch: {}
|
|
pull_request:
|
|
paths:
|
|
- ".github/workflows/testcontainers.yml"
|
|
- "tests/testcontainers/**"
|
|
- "superset/db_engine_specs/**"
|
|
- "pyproject.toml"
|
|
- "requirements/development.in"
|
|
- "requirements/development.txt"
|
|
|
|
concurrency:
|
|
# Scoped by ref, not just workflow name -- otherwise every PR run and the
|
|
# nightly cron share one group, and starting the workflow on another PR
|
|
# (or the nightly firing mid-PR-run) cancels an unrelated in-progress run.
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
testcontainers:
|
|
runs-on: ubuntu-26.04
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
# One job per dialect rather than one job for the whole suite: a
|
|
# single slow container would otherwise inflate the wall-clock
|
|
# time for every dialect, not just its own. Running in parallel
|
|
# means the suite's total time is bounded by the slowest dialect,
|
|
# not the sum of all of them. Db2's first-boot init is documented
|
|
# upstream as notably slow (a real instance bring-up, not just a
|
|
# process start) and untested locally here (no arm64 image), so
|
|
# it gets a wider timeout margin than the rest until real CI data
|
|
# says otherwise.
|
|
- dialect: cockroachdb
|
|
timeout: 10
|
|
- dialect: crate
|
|
timeout: 10
|
|
- dialect: trino
|
|
timeout: 10
|
|
- dialect: mssql
|
|
timeout: 10
|
|
- dialect: elasticsearch
|
|
timeout: 10
|
|
- dialect: oracle
|
|
timeout: 15
|
|
- dialect: db2
|
|
timeout: 25
|
|
- dialect: mariadb
|
|
timeout: 10
|
|
- dialect: timescaledb
|
|
timeout: 10
|
|
- dialect: yugabytedb
|
|
timeout: 10
|
|
- dialect: monetdb
|
|
timeout: 10
|
|
- dialect: mongodb
|
|
timeout: 10
|
|
- dialect: postgres
|
|
timeout: 10
|
|
- dialect: mysql
|
|
timeout: 10
|
|
- dialect: clickhouse
|
|
timeout: 10
|
|
# StarRocks' allin1-ubuntu image brings up both FE and BE in one
|
|
# container, which is a heavier bring-up than a single-process
|
|
# database -- wider margin until real CI data says otherwise.
|
|
- dialect: starrocks
|
|
timeout: 15
|
|
- dialect: databend
|
|
timeout: 10
|
|
- dialect: risingwave
|
|
timeout: 10
|
|
- dialect: firebird
|
|
timeout: 10
|
|
- dialect: ydb
|
|
timeout: 10
|
|
# OceanBase bootstraps a distributed-style cluster even in
|
|
# single-node MODE=MINI -- too heavy for every PR's CI budget, so
|
|
# it runs on the nightly cron / manual dispatch only.
|
|
- dialect: oceanbase
|
|
timeout: 20
|
|
nightly_only: true
|
|
timeout-minutes: ${{ matrix.timeout }}
|
|
env:
|
|
PYTHONPATH: ${{ github.workspace }}
|
|
SUPERSET_TESTENV: true
|
|
SUPERSET_SECRET_KEY: not-a-secret
|
|
# This job's matrix installs exactly one dialect's testcontainers
|
|
# driver for exactly this job, so treat that driver as required: a
|
|
# broken/missing import should fail the job, not silently skip to a
|
|
# misleadingly green, zero-tests-run result. See _driver.py.
|
|
SUPERSET_TESTCONTAINERS_STRICT: true
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- name: Setup Python
|
|
uses: ./.github/actions/setup-backend/
|
|
with:
|
|
python-version: current
|
|
- name: Install db2 driver (ibm-db-sa)
|
|
# ibm-db (the db2 DBAPI) ships no Linux arm64 wheel, so it's kept out
|
|
# of the baseline dev install (requirements/development.in) to avoid
|
|
# breaking the multi-platform dev Docker image build. Install it here
|
|
# instead, only for this leg of the matrix.
|
|
if: matrix.dialect == 'db2'
|
|
run: uv pip install --system -e .[db2]
|
|
- name: Install oceanbase driver (oceanbase_py)
|
|
# oceanbase_py pins sqlalchemy-utils>=0.38.3,<0.39, which conflicts
|
|
# outright with Superset's own sqlalchemy-utils==0.42.1 pin -- kept
|
|
# out of the baseline dev install for the same reason as db2 above.
|
|
# Installed as its own standalone package (not via `-e .[oceanbase]`)
|
|
# so --no-deps only skips *oceanbase_py's* dependencies -- applied
|
|
# to `-e .[oceanbase]` instead, --no-deps blocks pip from installing
|
|
# anything the extras marker pulls in, including oceanbase_py
|
|
# itself, which "succeeds" without actually installing it
|
|
# (confirmed on real CI: the install step reported success, but the
|
|
# module was still missing). This job only needs oceanbase_py's
|
|
# dialect module importable, not its sqlalchemy-utils dependency
|
|
# satisfied, since nothing here calls into it.
|
|
if: matrix.dialect == 'oceanbase'
|
|
run: uv pip install --system --no-deps "oceanbase_py>=0.0.1.2"
|
|
- name: Install Firebird client library (libfbclient2)
|
|
# sqlalchemy-firebird's driver (firebird-driver) is a pure-Python
|
|
# ctypes wrapper (its wheel is py3-none-any) that dynamically loads
|
|
# the native Firebird client library from the host at import time
|
|
# -- it doesn't bundle that library itself, so it has to come from
|
|
# the system package manager, only for this leg of the matrix.
|
|
if: matrix.dialect == 'firebird'
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y libfbclient2
|
|
- name: Run testcontainers db_engine_specs tests (${{ matrix.dialect }})
|
|
# A job-level `if:` can't reference `matrix` (only github/inputs/
|
|
# needs/vars are available there), so the nightly_only skip has to
|
|
# live on the step instead. A dialect without `nightly_only` set
|
|
# evaluates the left side true (unset is null, and `null != true`
|
|
# is true) and always runs; one WITH it set only runs on the cron
|
|
# or a manual dispatch, never on pull_request.
|
|
if: >-
|
|
matrix.nightly_only != true ||
|
|
github.event_name == 'schedule' ||
|
|
github.event_name == 'workflow_dispatch'
|
|
run: |
|
|
pytest --durations-min=2 -v -m testcontainers \
|
|
./tests/testcontainers/db_engine_specs/test_${{ matrix.dialect }}.py \
|
|
--junit-xml=test-results/junit-testcontainers-${{ matrix.dialect }}.xml
|
|
- name: Upload JUnit test results
|
|
if: always()
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
|
with:
|
|
name: junit-results-testcontainers-${{ matrix.dialect }}
|
|
path: test-results/
|
|
retention-days: 7
|
|
|
|
actions-timeline:
|
|
needs: [testcontainers]
|
|
if: always()
|
|
runs-on: ubuntu-26.04
|
|
permissions:
|
|
actions: read
|
|
steps:
|
|
- uses: Kesin11/actions-timeline@57fc93f20c6da7fbc14063c6d24a2a5627c799ad # v3.2.0
|