From 5f2e26f154cb94d55d139adb7fd546d98cb1f614 Mon Sep 17 00:00:00 2001 From: stijndcl Date: Wed, 29 Jun 2022 00:14:44 +0200 Subject: [PATCH 1/3] Add test container --- .github/workflows/python.yml | 9 +-------- database/engine.py | 34 ++++++++++++---------------------- docker-compose.yml | 10 ++++++++++ pyproject.toml | 7 ++++--- settings.py | 2 -- 5 files changed, 27 insertions(+), 35 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 382bc76..a309a71 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -27,16 +27,13 @@ jobs: services: postgres: image: postgres:14 - env: - POSTGRES_DB: didier_action - POSTGRES_PASSWORD: postgres options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 ports: - - 5432:5432 + - 5433:5432 steps: - uses: actions/checkout@v3 - name: Setup Python @@ -54,10 +51,6 @@ jobs: run: pip3 install -r requirements.txt -r requirements-dev.txt - name: Run Pytest run: pytest tests - env: - DB_TEST_SQLITE: false - DB_NAME: didier_action - DB_PASSWORD: postgres linting: needs: [dependencies] runs-on: ubuntu-latest diff --git a/database/engine.py b/database/engine.py index 70c70fe..fbdbfd2 100644 --- a/database/engine.py +++ b/database/engine.py @@ -6,27 +6,17 @@ from sqlalchemy.orm import sessionmaker import settings -# Run local tests against SQLite instead of Postgres -if settings.TESTING and settings.DB_TEST_SQLITE: - engine = create_async_engine( - URL.create( - drivername="sqlite+aiosqlite", - database="tests.db", - ), - connect_args={"check_same_thread": False}, - ) -else: - encoded_password = quote_plus(settings.DB_PASSWORD) - engine = create_async_engine( - URL.create( - drivername="postgresql+asyncpg", - username=settings.DB_USERNAME, - password=encoded_password, - host=settings.DB_HOST, - port=settings.DB_PORT, - database=settings.DB_NAME, - ), - pool_pre_ping=True, - ) +encoded_password = quote_plus(settings.DB_PASSWORD) +engine = create_async_engine( + URL.create( + drivername="postgresql+asyncpg", + username=settings.DB_USERNAME, + password=encoded_password, + host=settings.DB_HOST, + port=settings.DB_PORT, + database=settings.DB_NAME, + ), + pool_pre_ping=True, +) DBSession = sessionmaker(autocommit=False, autoflush=False, bind=engine, class_=AsyncSession, expire_on_commit=False) diff --git a/docker-compose.yml b/docker-compose.yml index d34f4a7..25cd531 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,5 +12,15 @@ services: - "${DB_PORT:-5432}:${DB_PORT:-5432}" volumes: - db:/var/lib/postgresql/data + db-pytest: + image: postgres:14 + container_name: didier-pytest + restart: always + environment: + - POSTGRES_DB=didier_pytest + - POSTGRES_USER=pytest + - POSTGRES_PASSWORD=pytest + ports: + - "5433:5432" volumes: db: diff --git a/pyproject.toml b/pyproject.toml index bfc1ced..5263a7b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,9 +24,10 @@ good-names = ["i", "dt"] [tool.pytest.ini_options] asyncio_mode = "auto" env = [ - "TESTING = true", - "DB_NAME = didier_action", - "DB_USERNAME = postgres", + "DB_NAME = didier_pytest", + "DB_USERNAME = pytest", + "DB_PASSWORD = pytest", "DB_HOST = localhost", + "DB_PORT = 5433", "DISC_TOKEN = token" ] diff --git a/settings.py b/settings.py index 797b052..d850eb8 100644 --- a/settings.py +++ b/settings.py @@ -9,7 +9,6 @@ env.read_env() """General config""" SANDBOX: bool = env.bool("SANDBOX", True) LOGFILE: str = env.str("LOGFILE", "didier.log") -TESTING: bool = env.bool("TESTING", False) """Database""" DB_NAME: str = env.str("DB_NAME", "didier") @@ -17,7 +16,6 @@ DB_USERNAME: str = env.str("DB_USERNAME", "postgres") DB_PASSWORD: str = env.str("DB_PASSWORD", "") DB_HOST: str = env.str("DB_HOST", "localhost") DB_PORT: int = env.int("DB_PORT", "5432") -DB_TEST_SQLITE: bool = env.bool("DB_TEST_SQLITE", True) """Discord""" DISCORD_TOKEN: str = env.str("DISC_TOKEN") From 5c1732d1199f125100d80559b9163f0c9008bc36 Mon Sep 17 00:00:00 2001 From: stijndcl Date: Wed, 29 Jun 2022 00:20:50 +0200 Subject: [PATCH 2/3] Fix env --- .github/workflows/python.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index a309a71..7f17dd0 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -34,6 +34,10 @@ jobs: --health-retries 5 ports: - 5433:5432 + env: + POSTGRES_DB: didier_pytest + POSTGRES_USER: pytest + POSTGRES_PASSWORD: pytest steps: - uses: actions/checkout@v3 - name: Setup Python From b4a3a87e6e15c1724f1861f4fe41f893156cc62d Mon Sep 17 00:00:00 2001 From: stijndcl Date: Wed, 29 Jun 2022 00:25:51 +0200 Subject: [PATCH 3/3] Use alembic in tests again? --- alembic/env.py | 8 +++++++- tests/conftest.py | 7 +++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/alembic/env.py b/alembic/env.py index f28faf3..82eae2b 100644 --- a/alembic/env.py +++ b/alembic/env.py @@ -68,4 +68,10 @@ async def run_migrations_online() -> None: if context.is_offline_mode(): run_migrations_offline() else: - asyncio.run(run_migrations_online()) + # Wonky way to use the Pytest event loop instead of another one + try: + loop = asyncio.get_running_loop() + if loop and loop.is_running(): + loop.create_task(run_migrations_online()) + except RuntimeError: + asyncio.run(run_migrations_online()) diff --git a/tests/conftest.py b/tests/conftest.py index 799c3bc..ded04d5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -5,6 +5,7 @@ from unittest.mock import MagicMock import pytest from sqlalchemy.ext.asyncio import AsyncSession +from alembic import config, command from database.engine import engine from database.models import Base from didier import Didier @@ -20,8 +21,10 @@ def event_loop() -> Generator: @pytest.fixture(scope="session") async def tables(event_loop): """Initialize a database before the tests, and then tear it down again""" - async with engine.begin() as connection: - await connection.run_sync(Base.metadata.create_all) + alembic_config: config.Config = config.Config("alembic.ini") + command.upgrade(alembic_config, "head") + yield + command.downgrade(alembic_config, "base") @pytest.fixture