Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions .github/workflows/driver-smoke.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Copyright (c) 2025-2026 ADBC Drivers Contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Run the driver-facing statement tests against real, released ADBC drivers
# to make sure changes to the validation suite keep working against actual
# driver implementations, not just the framework's own unit tests.

name: Driver Smoke Test

on:
pull_request: {}
push:
branches:
- main

defaults:
run:
shell: bash

permissions:
contents: read

jobs:
sqlite:
name: "SQLite"
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false

- name: Install uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0

- name: Install
run: |
uv venv
uv pip install -p .venv/bin/python pytest pyarrow adbc-driver-manager adbc-driver-sqlite .

- name: Test
env:
SMOKE_DRIVER: sqlite
ADBC_SQLITE_TEST_URI: "file:${{ runner.temp }}/smoke.db"
run: |
.venv/bin/python -m pytest -c smoke/pytest.ini smoke/tests/test_statement.py -v

postgresql:
name: "PostgreSQL"
runs-on: ubuntu-latest

services:
postgres:
image: postgres:18
env:
POSTGRES_PASSWORD: password
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5

steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false

- name: Install uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0

- name: Install
run: |
uv venv
uv pip install -p .venv/bin/python pytest pyarrow adbc-driver-manager adbc-driver-postgresql .

- name: Test
env:
SMOKE_DRIVER: postgresql
ADBC_POSTGRESQL_TEST_URI: "postgresql://postgres:password@localhost:5432/postgres"
run: |
.venv/bin/python -m pytest -c smoke/pytest.ini smoke/tests/test_statement.py -v
1 change: 1 addition & 0 deletions .rat-excludes
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@
adbc_drivers_validation/queries/*/*.json
adbc_drivers_validation/queries/*/*.sql
pixi.lock
smoke/queries/.gitkeep
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ dependencies = [
requires = ["setuptools >= 82.0.1"]
build-backend = "setuptools.build_meta"

[tool.setuptools.packages.find]
# Only ship the package itself; smoke/ holds the CI-only driver smoke tests.
include = ["adbc_drivers_validation*"]

[dependency-groups]
dev = [
"ruff>=0.15.20",
Expand Down
4 changes: 4 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
# limitations under the License.

[pytest]
# The driver smoke tests in smoke/ have their own configuration
# (smoke/pytest.ini) and are not collected by default.
testpaths = tests

junit_suite_name = validation
junit_duration_report = call
xfail_strict = true
Expand Down
21 changes: 21 additions & 0 deletions smoke/pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright (c) 2025-2026 ADBC Drivers Contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

[pytest]
markers =
feature: test for a driver-specific feature
requires_features: driver features required for the test to run

filterwarnings =
ignore:Cannot disable autocommit; conn will not be DB-API 2.0 compliant:adbc_driver_manager._lib.Warning
Empty file added smoke/queries/.gitkeep
Empty file.
13 changes: 13 additions & 0 deletions smoke/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright (c) 2025-2026 ADBC Drivers Contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
44 changes: 44 additions & 0 deletions smoke/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Copyright (c) 2025-2026 ADBC Drivers Contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Pytest configuration for the driver smoke tests."""

import importlib

import pytest

from adbc_drivers_validation import model
from adbc_drivers_validation.tests.conftest import ( # noqa: F401
conn,
conn_factory,
db_kwargs,
manual_test,
noci,
pytest_addoption,
pytest_collection_modifyitems,
)

from . import quirks


@pytest.fixture(scope="session")
def driver(request: pytest.FixtureRequest) -> model.DriverQuirks:
selected = quirks.selected_quirks()
assert request.param == f"{selected.name}:{selected.short_version}"
return selected


@pytest.fixture(scope="session")
def driver_path(driver: model.DriverQuirks) -> str:
return importlib.import_module(driver.driver)._driver_path()
106 changes: 106 additions & 0 deletions smoke/tests/quirks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Copyright (c) 2025-2026 ADBC Drivers Contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Minimal driver quirks for the CI smoke tests.

These quirks are intentionally small: they define only what is needed to
run the statement-level validation tests against real, released drivers.
They are not shipped as part of the package.
"""

import os
import re
from pathlib import Path

from adbc_drivers_validation import model

_QUERIES_PATH = Path(__file__).parent.parent / "queries"


class SQLiteQuirks(model.DriverQuirks):
name = "sqlite"
driver = "adbc_driver_sqlite"
driver_name = "ADBC SQLite Driver"
vendor_name = "SQLite"
vendor_version = "3"
short_version = "3"
features = model.DriverFeatures(
connection_transactions=True,
statement_bind=True,
# The released driver raises NOT_IMPLEMENTED for execute_schema.
statement_execute_schema=False,
statement_get_parameter_schema=True,
statement_prepare=True,
statement_rows_affected=True,
statement_rows_affected_ddl=True,
)
setup = model.DriverSetup(
database={"uri": model.FromEnv("ADBC_SQLITE_TEST_URI")},
connection={},
statement={},
)

@property
def queries_paths(self) -> tuple[Path]:
return (_QUERIES_PATH,)

def is_table_not_found(self, table_name: str | None, error: Exception) -> bool:
return "no such table" in str(error).lower()


class PostgreSQLQuirks(model.DriverQuirks):
name = "postgresql"
driver = "adbc_driver_postgresql"
driver_name = "ADBC PostgreSQL Driver"
vendor_name = "PostgreSQL"
vendor_version = re.compile(r"18[0-9]{4}")
short_version = "18"
features = model.DriverFeatures(
connection_transactions=True,
statement_bind=True,
statement_execute_schema=True,
statement_get_parameter_schema=True,
statement_prepare=True,
statement_rows_affected=True,
statement_rows_affected_ddl=False,
)
setup = model.DriverSetup(
database={"uri": model.FromEnv("ADBC_POSTGRESQL_TEST_URI")},
connection={},
statement={},
)

@property
def queries_paths(self) -> tuple[Path]:
return (_QUERIES_PATH,)

def bind_parameter(self, index: int) -> str:
"""PostgreSQL uses $1, $2, $3, etc. for parameter placeholders."""
return f"${index}"

def is_table_not_found(self, table_name: str | None, error: Exception) -> bool:
message = str(error).lower()
if table_name is not None and table_name.lower() not in message:
return False
return "does not exist" in message or "undefined_table" in message


def selected_quirks() -> model.DriverQuirks:
"""Return the quirks selected by the SMOKE_DRIVER environment variable."""
name = os.environ.get("SMOKE_DRIVER", "sqlite")
if name == "sqlite":
return SQLiteQuirks()
elif name == "postgresql":
return PostgreSQLQuirks()
raise ValueError(f"Unknown SMOKE_DRIVER: {name!r}")
30 changes: 30 additions & 0 deletions smoke/tests/test_statement.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright (c) 2025-2026 ADBC Drivers Contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Run the statement-level validation tests against a real driver."""

import pytest

import adbc_drivers_validation.tests.statement
from adbc_drivers_validation.tests.statement import (
TestStatement, # noqa: F401
)

from . import quirks


def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
adbc_drivers_validation.tests.statement.generate_tests(
[quirks.selected_quirks()], metafunc
)