Skip to content

Commit

Permalink
fix CI failures.
Browse files Browse the repository at this point in the history
  • Loading branch information
DanCardin committed Apr 15, 2024
1 parent 577597f commit a8c9dbe
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 38 deletions.
10 changes: 10 additions & 0 deletions src/pytest_mock_resources/compat/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import importlib.resources
import sys

from pytest_mock_resources.compat.import_ import ImportAdaptor

# isort: split
Expand Down Expand Up @@ -70,6 +73,13 @@
pymysql = ImportAdaptor("pymysql", "mysql")


def get_resource(package: str) -> str:
if sys.version_info >= (3, 9):
return str(importlib.resources.files(package))

return str(importlib.resources.path(package, "").__enter__())


__all__ = [
"sqlalchemy",
"psycopg2",
Expand Down
4 changes: 3 additions & 1 deletion src/pytest_mock_resources/container/postgres.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,9 @@ def detect_driver(drivername: Optional[str] = None, async_: bool = False) -> str
if any(Distribution.discover(name="asyncpg")):
return "postgresql+asyncpg"
else:
if any(Distribution.discover(name="psycopg2")) or any(Distribution.discover(name="psycopg2-binary")):
if any(Distribution.discover(name="psycopg2")) or any(
Distribution.discover(name="psycopg2-binary")
):
return "postgresql+psycopg2"

raise ValueError( # pragma: no cover
Expand Down
61 changes: 34 additions & 27 deletions src/pytest_mock_resources/fixture/postgresql.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import importlib.resources
import inspect
import logging
from typing import cast
from typing import cast, TYPE_CHECKING

import pytest
import sqlalchemy
from sqlalchemy import text
from sqlalchemy.engine import Connection, Engine

from pytest_mock_resources.compat import get_resource
from pytest_mock_resources.container.base import (
async_retry,
DEFAULT_RETRIES,
Expand All @@ -29,6 +29,9 @@
normalize_actions,
)

if TYPE_CHECKING:
from sqlalchemy.ext.asyncio import AsyncEngine

log = logging.getLogger(__name__)


Expand Down Expand Up @@ -118,6 +121,8 @@ def create_postgres_fixture(
name=scope_fixture_name,
cleanup_databases=cleanup_databases,
async_=async_,
container_fixture="pmr_postgres_container",
config_fixture="pmr_postgres_config",
)

if async_:
Expand All @@ -127,8 +132,9 @@ async def _async(*_, pmr_postgres_container, pmr_postgres_config, request):
engine_manager_kwargs,
engine_kwargs=engine_kwargs_,
cleanup_databases=cleanup_databases,
config_fixture="pmr_postgres_config",
)
async for template_database, engine_manager in fixture_scope(pmr_postgres_config):
async for template_database, engine_manager in fixture_scope(request):
fixture = _async_fixture(
pmr_postgres_config,
engine_kwargs_,
Expand Down Expand Up @@ -167,6 +173,8 @@ def register_scope_fixture(
name,
cleanup_databases: bool = False,
async_: bool = False,
container_fixture: str,
config_fixture: str,
):
if async_:
scope_fixture = _async_scope_fixture
Expand All @@ -177,38 +185,42 @@ def register_scope_fixture(

caller_globals = find_caller_globals()
if name not in caller_globals:
caller_globals[name] = fixture_fn(
fixture = fixture_fn(
scope_fixture(
engine_manager_kwargs,
engine_kwargs=engine_kwargs,
cleanup_databases=cleanup_databases,
config_fixture=config_fixture,
),
scope="session",
name=name,
)
fixture_uses = pytest.mark.usefixtures(container_fixture, config_fixture)
caller_globals[name] = fixture_uses(fixture)


def _sync_scope_fixture(
engine_manager_kwargs,
*,
engine_kwargs: dict,
config_fixture: str,
cleanup_databases: bool = False,
name="postgres",
):
def fixture(pmr_postgres_config):
def fixture(request):
pmr_config = request.getfixturevalue(config_fixture)

root_engine = cast(
Engine,
get_sqlalchemy_engine(pmr_postgres_config, pmr_postgres_config.root_database),
get_sqlalchemy_engine(pmr_config, pmr_config.root_database),
)
conn = retry(root_engine.connect, retries=DEFAULT_RETRIES)
conn.close()
root_engine.dispose()

root_engine = cast(
Engine,
get_sqlalchemy_engine(
pmr_postgres_config, pmr_postgres_config.root_database, autocommit=True
),
get_sqlalchemy_engine(pmr_config, pmr_config.root_database, autocommit=True),
)
with root_engine.connect() as root_conn:
with root_conn.begin() as trans:
Expand All @@ -225,7 +237,7 @@ def fixture(pmr_postgres_config):

template_engine = cast(
Engine,
get_sqlalchemy_engine(pmr_postgres_config, template_database, **engine_kwargs),
get_sqlalchemy_engine(pmr_config, template_database, **engine_kwargs),
)
with template_engine.connect() as conn:
with conn.begin() as trans:
Expand Down Expand Up @@ -277,17 +289,18 @@ def _async_scope_fixture(
engine_manager_kwargs,
*,
engine_kwargs: dict,
config_fixture: str,
cleanup_databases: bool = False,
name="postgres",
):
from sqlalchemy.ext.asyncio import AsyncEngine
async def fixture(request):
pmr_config = request.getfixturevalue(config_fixture)

async def fixture(pmr_postgres_config):
root_engine = cast(
AsyncEngine,
"AsyncEngine",
get_sqlalchemy_engine(
pmr_postgres_config,
pmr_postgres_config.root_database,
pmr_config,
pmr_config.root_database,
async_=True,
autocommit=True,
),
Expand All @@ -314,10 +327,8 @@ async def fixture(pmr_postgres_config):
assert template_database

engine = cast(
AsyncEngine,
get_sqlalchemy_engine(
pmr_postgres_config, template_database, **engine_kwargs, async_=True
),
"AsyncEngine",
get_sqlalchemy_engine(pmr_config, template_database, **engine_kwargs, async_=True),
)
async with engine.begin() as conn:
await conn.run_sync(template_manager.run_static_actions)
Expand All @@ -342,10 +353,8 @@ async def _async_fixture(
engine_manager: EngineManager,
cleanup_databases: bool = False,
):
from sqlalchemy.ext.asyncio import AsyncEngine

root_engine = cast(
AsyncEngine,
"AsyncEngine",
get_sqlalchemy_engine(
pmr_config,
pmr_config.root_database,
Expand Down Expand Up @@ -480,13 +489,11 @@ def _sync_drop_database(conn: Connection, database_name: str):


def find_caller_globals():
ignore_paths = (
str(importlib.resources.files("pytest_mock_resources")),
str(importlib.resources.files("pdb")),
)
"""Return the stackframe of the calling function of the `create_<x_fixture` call."""
ignore_path = get_resource("pytest_mock_resources")
stack = inspect.stack()
for item in stack:
if item.filename.startswith(ignore_paths):
if item.filename.startswith(ignore_path) or item.filename.endswith("pdb.py"):
continue

frame = item.frame
Expand Down
5 changes: 4 additions & 1 deletion src/pytest_mock_resources/fixture/redshift/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ def create_redshift_fixture(
name=scope_fixture_name,
cleanup_databases=cleanup_databases,
async_=async_,
container_fixture="pmr_redshift_container",
config_fixture="pmr_redshift_container",
)

if async_:
Expand All @@ -113,8 +115,9 @@ async def _async(*_, pmr_redshift_container, pmr_redshift_config, request):
engine_manager_kwargs,
engine_kwargs=engine_kwargs_,
cleanup_databases=cleanup_databases,
config_fixture="pmr_redshift_config",
)
async for template_database, engine_manager in fixture_scope(pmr_redshift_config):
async for template_database, engine_manager in fixture_scope(request):
fixture = _async_fixture(
pmr_redshift_config,
engine_kwargs_,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import os

from pytest_mock_resources import create_postgres_fixture
import pytest

from pytest_mock_resources import create_postgres_fixture, PostgresConfig

should_clean = bool(os.environ.get("CLEAN", False))
port = int(os.environ["PMR_POSTGRES_PORT"])


@pytest.fixture(scope="session")
def pmr_postgres_config():
return PostgresConfig(port=port, ci_port=port)


pg = create_postgres_fixture(session=True, cleanup_databases=should_clean)
14 changes: 6 additions & 8 deletions tests/test_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def pmr_postgres_config():


@pytest.mark.postgres
def test_postgres_template_database_cleanup(pytester, pg):
def test_postgres_template_database_cleanup(pytester, pg, pmr_postgres_config):
"""Execute two tests in a subprocess and assert they clean up their databases.
Normally, two tests sharing a fixture would share a template database and leave
Expand All @@ -50,21 +50,19 @@ def test_postgres_template_database_cleanup(pytester, pg):

databases_before = get_databases(pg)

port = pg.connection().engine.url.port
port = pmr_postgres_config.port
assert port

with patch("os.environ", new={"PMR_POSTGRES_PORT": port, "CLEAN": "1"}):
result = pytester.inline_run(
*args,
)
result = pytester.inline_run(*args)
result.assertoutcome(passed=2, skipped=0, failed=0)

databases_after = get_databases(pg)
assert databases_before == databases_after

# Re-run it after, without cleaning turned on to make sure this isn't a false positive
with patch("os.environ", new={"PMR_POSTGRES_PORT": port}):
result = pytester.inline_run(
*args,
)
result = pytester.inline_run(*args)

result.assertoutcome(passed=2, skipped=0, failed=0)

Expand Down

0 comments on commit a8c9dbe

Please sign in to comment.