Skip to content

Commit

Permalink
Retry createdb failures.
Browse files Browse the repository at this point in the history
  • Loading branch information
DanCardin committed Feb 23, 2023
1 parent 5ab728b commit a14de4a
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 31 deletions.
3 changes: 0 additions & 3 deletions src/pytest_mock_resources/compat/sqlalchemy.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@

version = getattr(sqlalchemy, "__version__", "")

# Support starting at 1.2.X, and we declare a minimum version of 1.0
has_pool_pre_ping = not version.startswith("1.1") and not version.startswith("1.0")

if version.startswith("1.4") or version.startswith("2."):
from sqlalchemy.ext import asyncio
from sqlalchemy.orm import declarative_base, DeclarativeMeta
Expand Down
10 changes: 7 additions & 3 deletions src/pytest_mock_resources/container/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@
import pathlib
import socket
import time
from typing import Awaitable, Callable, TypeVar
import types
from typing import Awaitable, Callable, Optional, TypeVar

from pytest_mock_resources.hooks import get_pytest_flag, use_multiprocess_safe_mode

try:
import responses
import responses as _responses

responses: Optional[types.ModuleType] = _responses
del _responses
except ImportError:
responses = None # type: ignore
responses = None


DEFAULT_RETRIES = 40
Expand Down
5 changes: 1 addition & 4 deletions src/pytest_mock_resources/container/postgres.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import sqlalchemy
import sqlalchemy.exc

from pytest_mock_resources.compat.sqlalchemy import has_pool_pre_ping, URL
from pytest_mock_resources.compat.sqlalchemy import URL
from pytest_mock_resources.config import DockerContainerConfig, fallback
from pytest_mock_resources.container.base import ContainerCheckFailed

Expand Down Expand Up @@ -107,9 +107,6 @@ def get_sqlalchemy_engine(
database=database_name,
)

if has_pool_pre_ping and "pool_pre_ping" not in engine_kwargs:
engine_kwargs["pool_pre_ping"] = True

if getattr(url.get_dialect(), "is_async"):
from sqlalchemy.ext.asyncio import create_async_engine

Expand Down
53 changes: 34 additions & 19 deletions src/pytest_mock_resources/fixture/postgresql.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import logging
from typing import cast

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

from pytest_mock_resources.container.base import async_retry, DEFAULT_RETRIES, get_container, retry
from pytest_mock_resources.container.postgres import get_sqlalchemy_engine, PostgresConfig
Expand Down Expand Up @@ -107,28 +108,34 @@ async def _async(*_, pmr_postgres_container, pmr_postgres_config):


def _sync_fixture(pmr_config, engine_manager_kwargs, engine_kwargs):
root_engine = get_sqlalchemy_engine(pmr_config, pmr_config.root_database)
root_engine = cast(Engine, get_sqlalchemy_engine(pmr_config, pmr_config.root_database))
retry(root_engine.connect, retries=DEFAULT_RETRIES)

with root_engine.connect() as root_conn:
template_database, template_manager, engine_manager = create_engine_manager(
root_conn, **engine_manager_kwargs
)
root_conn.execute(text("commit"))
with root_conn.begin() as trans:
template_database, template_manager, engine_manager = create_engine_manager(
root_conn, **engine_manager_kwargs
)
trans.commit()

if template_manager:
assert template_database

template_engine = get_sqlalchemy_engine(pmr_config, template_database, **engine_kwargs)
with template_engine.begin() as conn:
template_manager.run_static_actions(conn)
conn.execute(text("commit"))
template_engine = cast(
Engine, get_sqlalchemy_engine(pmr_config, template_database, **engine_kwargs)
)
with template_engine.connect() as conn:
with conn.begin() as trans:
template_manager.run_static_actions(conn)
trans.commit()
template_engine.dispose()

# Everything below is normal per-test context. We create a brand new database/engine/manager
# distinct from what might have been used for the template database.
with root_engine.connect() as root_conn:
database_name = _produce_clean_database(root_conn, createdb_template=template_database)
with root_conn.begin() as trans:
database_name = _produce_clean_database(root_conn, createdb_template=template_database)
trans.commit()

engine = get_sqlalchemy_engine(pmr_config, database_name, **engine_kwargs)
yield from engine_manager.manage_sync(engine)
Expand All @@ -141,10 +148,11 @@ async def _async_fixture(pmr_config, engine_manager_kwargs, engine_kwargs):
await root_conn.close()

async with root_engine.connect() as root_conn:
template_database, template_manager, engine_manager = await root_conn.run_sync(
create_engine_manager, **engine_manager_kwargs
)
await root_conn.execute(text("commit"))
async with root_conn.begin() as trans:
template_database, template_manager, engine_manager = await root_conn.run_sync(
create_engine_manager, **engine_manager_kwargs
)
await trans.commit()

if template_manager:
assert template_database
Expand All @@ -158,9 +166,11 @@ async def _async_fixture(pmr_config, engine_manager_kwargs, engine_kwargs):
# Everything below is normal per-test context. We create a brand new database/engine/manager
# distinct from what might have been used for the template database.
async with root_engine.connect() as root_conn:
database_name = await root_conn.run_sync(
_produce_clean_database, createdb_template=template_database
)
async with root_conn.begin() as trans:
database_name = await root_conn.run_sync(
_produce_clean_database, createdb_template=template_database
)
await trans.commit()

await root_engine.dispose()

Expand Down Expand Up @@ -224,7 +234,12 @@ def create_engine_manager(


def _produce_clean_database(
root_conn: Connection, createdb_template="template1", database_name=None, ignore_failure=False
root_conn: Connection,
*,
trans=None,
createdb_template="template1",
database_name=None,
ignore_failure=False,
):
if not database_name:
database_name = _generate_database_name(root_conn)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
from pytest_mock_resources import create_postgres_fixture
import pytest

from pytest_mock_resources import create_postgres_fixture, PostgresConfig


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


pg = create_postgres_fixture()
10 changes: 9 additions & 1 deletion tests/examples/test_multiprocess_redis_database/conftest.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
from pytest_mock_resources import create_redis_fixture
import pytest

from pytest_mock_resources import create_redis_fixture, RedisConfig


@pytest.fixture(scope="session")
def pmr_redis_config():
return RedisConfig(port=6380)


redis = create_redis_fixture()

0 comments on commit a14de4a

Please sign in to comment.