Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing: Add pytest fixtures to discriminate between SQLAlchemy 1 and 2 #185

Merged
merged 1 commit into from
Jul 6, 2024
Merged
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
2 changes: 0 additions & 2 deletions cratedb_toolkit/cfr/systable.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,11 @@ def ddl(self, tablename_in: str, tablename_out: str, out_schema: str = None, wit


class PathProvider:

def __init__(self, path: t.Union[Path]):
self.path = path


class Archive:

def __init__(self, path_provider: PathProvider):
self.path_provider = path_provider
self.temp_dir = tempfile.TemporaryDirectory()
Expand Down
38 changes: 38 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

import pytest
import responses
import sqlalchemy as sa
from verlib2 import Version

from cratedb_toolkit.testing.testcontainers.cratedb import CrateDBTestAdapter
from cratedb_toolkit.util.common import setup_logging
Expand Down Expand Up @@ -114,4 +116,40 @@ def cloud_cluster_mock():
)


IS_SQLALCHEMY1 = Version(sa.__version__) < Version("2")
IS_SQLALCHEMY2 = Version(sa.__version__) >= Version("2")


@pytest.fixture(scope="module")
def needs_sqlalchemy1_module():
"""
Use this for annotating pytest test case functions testing subsystems which need SQLAlchemy 1.x.
"""
check_sqlalchemy1()


def check_sqlalchemy1(**kwargs):
"""
Skip pytest test cases or modules testing subsystems which need SQLAlchemy 1.x.
"""
if not IS_SQLALCHEMY1:
raise pytest.skip("This feature or subsystem needs SQLAlchemy 1.x", **kwargs)


@pytest.fixture
def needs_sqlalchemy2():
"""
Use this for annotating pytest test case functions testing subsystems which need SQLAlchemy 2.x.
"""
check_sqlalchemy2()


def check_sqlalchemy2(**kwargs):
"""
Skip pytest test cases or modules testing subsystems which need SQLAlchemy 2.x.
"""
if not IS_SQLALCHEMY2:
raise pytest.skip("This feature or subsystem needs SQLAlchemy 2.x", **kwargs)


setup_logging()
2 changes: 1 addition & 1 deletion tests/io/influxdb/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from influxio.adapter import InfluxDbApiAdapter


def test_influxdb2_load_table(caplog, cratedb, influxdb):
def test_influxdb2_load_table(caplog, cratedb, influxdb, needs_sqlalchemy2):
"""
CLI test: Invoke `ctk load table` for InfluxDB.
"""
Expand Down
3 changes: 3 additions & 0 deletions tests/io/mongodb/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import pytest

from tests.conftest import check_sqlalchemy2

logger = logging.getLogger(__name__)


Expand Down Expand Up @@ -53,6 +55,7 @@ def mongodb_service():
"""
Provide an MongoDB service instance to the test suite.
"""
check_sqlalchemy2()
db = MongoDBFixture()
db.reset()
yield db
Expand Down
9 changes: 9 additions & 0 deletions tests/io/mongodb/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,22 @@
from pueblo.testing.dataframe import DataFrameFactory

from cratedb_toolkit.cli import cli
from tests.conftest import check_sqlalchemy2

pytestmark = pytest.mark.mongodb

pymongo = pytest.importorskip("pymongo", reason="Skipping tests because pymongo is not installed")
pytest.importorskip("rich", reason="Skipping tests because rich is not installed")


@pytest.fixture(scope="module", autouse=True)
def check_prerequisites():
"""
This subsystem needs SQLAlchemy 2.x.
"""
check_sqlalchemy2()


def test_version():
"""
CLI test: Invoke `migr8 --version`.
Expand Down
15 changes: 13 additions & 2 deletions tests/io/mongodb/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,24 @@

import pytest

from tests.io.mongodb.conftest import RESET_DATABASES
from tests.conftest import check_sqlalchemy2

pytestmark = pytest.mark.mongodb

pymongo = pytest.importorskip("pymongo", reason="Skipping tests because pymongo is not installed")
pytest.importorskip("rich", reason="Skipping tests because rich is not installed")

from cratedb_toolkit.io.mongodb.core import gather_collections

@pytest.fixture(scope="module", autouse=True)
def check_prerequisites():
"""
This subsystem needs SQLAlchemy 2.x.
"""
check_sqlalchemy2()


from cratedb_toolkit.testing.testcontainers.mongodb import MongoDbContainerWithKeepalive
from tests.io.mongodb.conftest import RESET_DATABASES

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -65,6 +74,8 @@ def test_gather_collections(self):
"""
Verify if core method `gather_collections` works as expected.
"""
from cratedb_toolkit.io.mongodb.core import gather_collections

self.db.create_collection("foobar")
with mock.patch("builtins.input", return_value="unknown"):
collections = gather_collections(database=self.db)
Expand Down
4 changes: 2 additions & 2 deletions tests/io/test_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def test_import_csv_pandas(cratedb, dummy_csv):
assert result == [(2,)]


def test_import_csv_dask(cratedb, dummy_csv):
def test_import_csv_dask(cratedb, dummy_csv, needs_sqlalchemy2):
"""
Invoke convenience function `import_csv_dask`, and verify database content.
"""
Expand All @@ -36,7 +36,7 @@ def test_import_csv_dask(cratedb, dummy_csv):
assert result == [(2,)]


def test_import_csv_dask_with_progressbar(cratedb, dummy_csv):
def test_import_csv_dask_with_progressbar(cratedb, dummy_csv, needs_sqlalchemy2):
"""
Invoke convenience function `import_csv_dask`, and verify database content.
This time, use `progress=True` to make Dask display a progress bar.
Expand Down
3 changes: 2 additions & 1 deletion tests/retention/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from cratedb_toolkit.testing.testcontainers.azurite import ExtendedAzuriteContainer
from cratedb_toolkit.testing.testcontainers.minio import ExtendedMinioContainer
from cratedb_toolkit.util.database import DatabaseAdapter, run_sql
from tests.conftest import TESTDRIVE_DATA_SCHEMA, TESTDRIVE_EXT_SCHEMA
from tests.conftest import TESTDRIVE_DATA_SCHEMA, TESTDRIVE_EXT_SCHEMA, check_sqlalchemy2


@pytest.fixture()
Expand All @@ -26,6 +26,7 @@ def store(database, settings):
Provide a client database adapter, which is connected to the test database instance.
The retention policy database table schema has been established.
"""
check_sqlalchemy2()
setup_schema(settings=settings)
rps = RetentionPolicyStore(settings=settings)
yield rps
Expand Down
8 changes: 5 additions & 3 deletions tests/retention/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ def test_run_delete_dryrun(caplog, store, database, raw_metrics, policies):
assert database.count_records(raw_metrics) == 6


def test_run_delete_with_tags_match(store, database, sensor_readings, policies):
def test_run_delete_with_tags_match(store, database, sensor_readings, policies, needs_sqlalchemy2):
"""
Verify a basic DELETE retention policy through the CLI, with using correct (matching) tags.
"""
Expand All @@ -214,7 +214,7 @@ def test_run_delete_with_tags_match(store, database, sensor_readings, policies):
assert database.count_records(f'"{TESTDRIVE_DATA_SCHEMA}"."sensor_readings"') == 0


def test_run_delete_with_tags_unknown(caplog, store, database, sensor_readings, policies):
def test_run_delete_with_tags_unknown(caplog, store, database, sensor_readings, policies, needs_sqlalchemy2):
"""
Verify a basic DELETE retention policy through the CLI, with using wrong (not matching) tags.
"""
Expand Down Expand Up @@ -266,7 +266,9 @@ def test_run_reallocate(store, database, raw_metrics, raw_metrics_reallocate_pol
assert database.count_records(raw_metrics) == 6


def test_run_snapshot_aws_s3(caplog, store, database, sensor_readings, sensor_readings_snapshot_policy, minio):
def test_run_snapshot_aws_s3(
caplog, store, database, sensor_readings, sensor_readings_snapshot_policy, minio, needs_sqlalchemy2
):
"""
Verify the "SNAPSHOT" strategy using an object storage with AWS S3 API.
Invokes `cratedb-retention run --strategy=snapshot`.
Expand Down
2 changes: 1 addition & 1 deletion tests/retention/test_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import responses


def test_example_edit(store):
def test_example_edit(store, needs_sqlalchemy2):
"""
Verify that the program `examples/retention_edit.py` works.
"""
Expand Down
8 changes: 4 additions & 4 deletions tests/retention/test_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def test_list_tags(store):
assert tags == ["bar", "foo"]


def test_delete_by_tag(store):
def test_delete_by_tag(store, needs_sqlalchemy2):
"""
Verify deleting a retention policy by single tag.
"""
Expand Down Expand Up @@ -122,7 +122,7 @@ def test_delete_by_tag(store):
assert len(store.retrieve()) == 1


def test_delete_by_all_tags(store):
def test_delete_by_all_tags(store, needs_sqlalchemy2):
"""
Verify deleting a retention policy by multiple tags.

Expand Down Expand Up @@ -178,7 +178,7 @@ def test_delete_unknown(caplog, store):
assert "Retention policy not found with id: unknown" in caplog.messages


def test_delete_by_tag_unknown(caplog, store):
def test_delete_by_tag_unknown(caplog, store, needs_sqlalchemy2):
"""
Verify behavior when deleting items by unknown tag
"""
Expand All @@ -194,7 +194,7 @@ def test_delete_by_tag_unknown(caplog, store):
assert "No retention policies found with tags: ['unknown']" in caplog.messages


def test_delete_by_all_tags_unknown(caplog, store):
def test_delete_by_all_tags_unknown(caplog, store, needs_sqlalchemy2):
"""
Verify behavior when deleting items by unknown tag
"""
Expand Down
4 changes: 2 additions & 2 deletions tests/sqlalchemy/test_patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from tests.conftest import TESTDRIVE_DATA_SCHEMA


def test_inspector_vanilla(database):
def test_inspector_vanilla(database, needs_sqlalchemy2):
"""
Vanilla SQLAlchemy Inspector tests.
"""
Expand All @@ -28,7 +28,7 @@ def test_inspector_vanilla(database):
assert indexes == []


def test_inspector_patched(database):
def test_inspector_patched(database, needs_sqlalchemy2):
"""
Patched SQLAlchemy Inspector tests.

Expand Down
4 changes: 2 additions & 2 deletions tests/sqlalchemy/test_polyfill.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class FooBarComposite(Base):
return FooBarComposite


def test_autoincrement_vanilla(database):
def test_autoincrement_vanilla(database, needs_sqlalchemy2):
"""
When using a model including an autoincrement column, and not assigning a value, CrateDB will fail.
"""
Expand All @@ -77,7 +77,7 @@ def test_autoincrement_vanilla(database):
)


def test_autoincrement_polyfill(database):
def test_autoincrement_polyfill(database, needs_sqlalchemy2):
"""
When using a model including an autoincrement column, and the corresponding polyfill
is installed, the procedure will succeed.
Expand Down
4 changes: 2 additions & 2 deletions tests/testing/test_cratedb_sqlalchemy.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from tests.conftest import TESTDRIVE_DATA_SCHEMA


def test_cratedb_summits(cratedb):
def test_cratedb_summits(cratedb, needs_sqlalchemy2):
"""
Just to verify communication with CrateDB works.
"""
Expand All @@ -22,7 +22,7 @@ def test_cratedb_summits(cratedb):
]


def test_database_insert(cratedb):
def test_database_insert(cratedb, needs_sqlalchemy2):
"""
Verify that inserting two records and reading them back works well.
"""
Expand Down