Compare commits

...

3 Commits

Author SHA1 Message Date
stijndcl b4a3a87e6e Use alembic in tests again? 2022-06-29 00:25:51 +02:00
stijndcl 5c1732d119 Fix env 2022-06-29 00:20:50 +02:00
stijndcl 5f2e26f154 Add test container 2022-06-29 00:14:44 +02:00
7 changed files with 43 additions and 38 deletions

View File

@ -27,16 +27,17 @@ jobs:
services: services:
postgres: postgres:
image: postgres:14 image: postgres:14
env:
POSTGRES_DB: didier_action
POSTGRES_PASSWORD: postgres
options: >- options: >-
--health-cmd pg_isready --health-cmd pg_isready
--health-interval 10s --health-interval 10s
--health-timeout 5s --health-timeout 5s
--health-retries 5 --health-retries 5
ports: ports:
- 5432:5432 - 5433:5432
env:
POSTGRES_DB: didier_pytest
POSTGRES_USER: pytest
POSTGRES_PASSWORD: pytest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Setup Python - name: Setup Python
@ -54,10 +55,6 @@ jobs:
run: pip3 install -r requirements.txt -r requirements-dev.txt run: pip3 install -r requirements.txt -r requirements-dev.txt
- name: Run Pytest - name: Run Pytest
run: pytest tests run: pytest tests
env:
DB_TEST_SQLITE: false
DB_NAME: didier_action
DB_PASSWORD: postgres
linting: linting:
needs: [dependencies] needs: [dependencies]
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@ -68,4 +68,10 @@ async def run_migrations_online() -> None:
if context.is_offline_mode(): if context.is_offline_mode():
run_migrations_offline() run_migrations_offline()
else: 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())

View File

@ -6,27 +6,17 @@ from sqlalchemy.orm import sessionmaker
import settings import settings
# Run local tests against SQLite instead of Postgres encoded_password = quote_plus(settings.DB_PASSWORD)
if settings.TESTING and settings.DB_TEST_SQLITE: engine = create_async_engine(
engine = create_async_engine( URL.create(
URL.create( drivername="postgresql+asyncpg",
drivername="sqlite+aiosqlite", username=settings.DB_USERNAME,
database="tests.db", password=encoded_password,
), host=settings.DB_HOST,
connect_args={"check_same_thread": False}, port=settings.DB_PORT,
) database=settings.DB_NAME,
else: ),
encoded_password = quote_plus(settings.DB_PASSWORD) pool_pre_ping=True,
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) DBSession = sessionmaker(autocommit=False, autoflush=False, bind=engine, class_=AsyncSession, expire_on_commit=False)

View File

@ -12,5 +12,15 @@ services:
- "${DB_PORT:-5432}:${DB_PORT:-5432}" - "${DB_PORT:-5432}:${DB_PORT:-5432}"
volumes: volumes:
- db:/var/lib/postgresql/data - 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: volumes:
db: db:

View File

@ -24,9 +24,10 @@ good-names = ["i", "dt"]
[tool.pytest.ini_options] [tool.pytest.ini_options]
asyncio_mode = "auto" asyncio_mode = "auto"
env = [ env = [
"TESTING = true", "DB_NAME = didier_pytest",
"DB_NAME = didier_action", "DB_USERNAME = pytest",
"DB_USERNAME = postgres", "DB_PASSWORD = pytest",
"DB_HOST = localhost", "DB_HOST = localhost",
"DB_PORT = 5433",
"DISC_TOKEN = token" "DISC_TOKEN = token"
] ]

View File

@ -9,7 +9,6 @@ env.read_env()
"""General config""" """General config"""
SANDBOX: bool = env.bool("SANDBOX", True) SANDBOX: bool = env.bool("SANDBOX", True)
LOGFILE: str = env.str("LOGFILE", "didier.log") LOGFILE: str = env.str("LOGFILE", "didier.log")
TESTING: bool = env.bool("TESTING", False)
"""Database""" """Database"""
DB_NAME: str = env.str("DB_NAME", "didier") 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_PASSWORD: str = env.str("DB_PASSWORD", "")
DB_HOST: str = env.str("DB_HOST", "localhost") DB_HOST: str = env.str("DB_HOST", "localhost")
DB_PORT: int = env.int("DB_PORT", "5432") DB_PORT: int = env.int("DB_PORT", "5432")
DB_TEST_SQLITE: bool = env.bool("DB_TEST_SQLITE", True)
"""Discord""" """Discord"""
DISCORD_TOKEN: str = env.str("DISC_TOKEN") DISCORD_TOKEN: str = env.str("DISC_TOKEN")

View File

@ -5,6 +5,7 @@ from unittest.mock import MagicMock
import pytest import pytest
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from alembic import config, command
from database.engine import engine from database.engine import engine
from database.models import Base from database.models import Base
from didier import Didier from didier import Didier
@ -20,8 +21,10 @@ def event_loop() -> Generator:
@pytest.fixture(scope="session") @pytest.fixture(scope="session")
async def tables(event_loop): async def tables(event_loop):
"""Initialize a database before the tests, and then tear it down again""" """Initialize a database before the tests, and then tear it down again"""
async with engine.begin() as connection: alembic_config: config.Config = config.Config("alembic.ini")
await connection.run_sync(Base.metadata.create_all) command.upgrade(alembic_config, "head")
yield
command.downgrade(alembic_config, "base")
@pytest.fixture @pytest.fixture