Skip to content

Commit 2585016

Browse files
authored
Enable integration testing with postgres and check in failing test with secondary relationship (#20)
* Adds postgres to .devcontainer/Dockerfile and to unit test setup. * Postgres doesn't work on Windows on Github Actions, unfortunately, so tests are linux only for now.
1 parent 8341ab5 commit 2585016

File tree

9 files changed

+316
-33
lines changed

9 files changed

+316
-33
lines changed

.devcontainer/Dockerfile

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,27 @@ FROM mcr.microsoft.com/vscode/devcontainers/python:${VARIANT}
33

44
RUN pip3 install poetry pre-commit
55
RUN poetry config virtualenvs.in-project true
6+
ARG PGVERSION=14
7+
8+
# Setup apt repo for Postgres
9+
RUN if [ "${PGVERSION}" != "none" ]; then \
10+
echo "deb [signed-by=/usr/share/keyrings/postgresql.gpg] http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" \
11+
| tee /etc/apt/sources.list.d/pgdg.list \
12+
&& curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc \
13+
| gpg --dearmor --yes -o /usr/share/keyrings/postgresql.gpg; \
14+
fi
15+
16+
# Install Postgres packages
17+
ARG TARGETPLATFORM
18+
RUN --mount=type=cache,target=/var/cache/apt,id=apt-${TARGETPLATFORM} \
19+
export DEBIAN_FRONTEND=noninteractive \
20+
&& export PGPACKAGES=$(if [ "${PGVERSION}" != "none" ]; then echo "postgresql-${PGVERSION} postgresql-client-${PGVERSION} postgresql-server-dev-${PGVERSION}"; fi) \
21+
&& apt-get remove man-db --purge -y \
22+
&& apt-get update \
23+
&& apt-get -y install --no-install-recommends ${PGPACKAGES}
24+
25+
# Trust postgres connections from localhost and local port.
26+
RUN if [ "$PGVERSION" != "none" ]; then \
27+
sed -i -E 's/local(\s+)all(\s+)postgres(\s+)peer/local\1all\2all\3trust/g' /etc/postgresql/${PGVERSION}/main/pg_hba.conf && \
28+
sed -i -E 's/host(\s+)all(\s+)all(\s+)(\S+)(\s+)(\S+)/host\1all\2all\3\4\5trust/g' /etc/postgresql/${PGVERSION}/main/pg_hba.conf; \
29+
fi

.devcontainer/devcontainer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@
2323

2424
"extensions": ["ms-python.python", "ms-python.vscode-pylance", "eamodio.gitlens"],
2525
"postCreateCommand": "sh ./.devcontainer/post-install.sh",
26+
"postStartCommand": "sh ./.devcontainer/post-start.sh",
2627
}

.devcontainer/post-start.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
service postgresql status
2+
if [ "$?" -eq "1" ]; then
3+
echo "Postgres not installed. Postgres integration tests will fail for now."
4+
else
5+
sudo service postgresql start
6+
fi

.github/workflows/test.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ jobs:
5151

5252
steps:
5353
- uses: actions/checkout@v3
54+
- uses: ikalnytskyi/action-setup-postgres@v4
5455
- uses: wntrblm/nox@main
5556
with:
5657
python-versions: "3.8, 3.9, 3.10, 3.11, 3.12"
@@ -97,11 +98,11 @@ jobs:
9798
- uses: actions/setup-python@v4
9899
id: setup-python
99100
with:
100-
python-version: "3.12.0-beta.3"
101+
python-version: "3.12.0-rc.2"
101102
architecture: x64
102103
cache: "poetry"
103104

104-
- run: poetry env use 3.12.0-beta.3
105+
- run: poetry env use 3.12.0-rc.2
105106
- run: poetry run pip install --upgrade pip setuptools wheel
106107
- run: poetry install
107108
if: steps.setup-python.outputs.cache-hit != 'true'

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ Don't forget to tell your contributors to also install and use pre-commit.
222222
pip install -r requirements.txt
223223
```
224224

225+
Install [PostgreSQL 14+](https://www.postgresql.org/download/)
226+
225227
### Test
226228

227229
```bash

poetry.lock

Lines changed: 95 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ importlib-metadata = "^4.11.1"
5151
mypy = "1.5.1"
5252
nox = "^2023.4.22"
5353
nox-poetry = "^1.0.2"
54+
packaging = ">=23.1"
55+
pg8000 = ">=1.30.1"
56+
psycopg2 = ">=2.9.7"
5457
pytest = "^7.2"
5558
pytest-asyncio = ">=0.20.3,<0.22.0"
5659
pytest-codspeed = "^2.0.1"
@@ -59,6 +62,7 @@ pytest-emoji = "^0.2.0"
5962
pytest-mypy-plugins = ">=1.10,<4.0"
6063
pytest-xdist = {extras = ["psutil"], version = "^3.1.0"}
6164
setuptools = ">=67.8.0"
65+
"testing.postgresql" = ">=1.3.0"
6266

6367
[tool.black]
6468
line-length = 88

tests/conftest.py

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,77 @@
11
"""
2-
Dummy conftest.py for strawberry_sqlalchemy_mapper.
2+
conftest.py for strawberry_sqlalchemy_mapper.
33
44
If you don't know what this is for, just leave it empty.
55
Read more about conftest.py under:
66
- https://docs.pytest.org/en/stable/fixture.html
77
- https://docs.pytest.org/en/stable/writing_plugins.html
88
"""
99

10-
# import pytest
10+
import contextlib
11+
import logging
12+
import platform
13+
import socket
14+
15+
import pytest
16+
import sqlalchemy
17+
from packaging import version
18+
from sqlalchemy import orm
19+
from sqlalchemy.engine import Engine
20+
from testing.postgresql import Postgresql, PostgresqlFactory
21+
22+
SQLA_VERSION = version.parse(sqlalchemy.__version__)
23+
SQLA2 = SQLA_VERSION >= version.parse("2.0")
24+
25+
26+
def _pick_unused_port():
27+
with contextlib.closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
28+
s.bind(("", 0))
29+
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
30+
return s.getsockname()[1]
31+
32+
33+
@pytest.fixture(scope="session")
34+
def postgresql_factory() -> PostgresqlFactory:
35+
factory = PostgresqlFactory(cache_initialized_db=True, port=_pick_unused_port())
36+
yield factory
37+
factory.clear_cache()
38+
39+
40+
@pytest.fixture
41+
def postgresql(postgresql_factory) -> Postgresql:
42+
db = postgresql_factory()
43+
yield db
44+
db.stop()
45+
46+
47+
if platform.system() == "Windows":
48+
# Our windows test pipeline doesn't play nice with postgres because
49+
# Github Actions doesn't support containers on windows.
50+
# It would probably be nicer if we chcked if postgres is installed
51+
logging.info("Skipping postgresql tests on Windows OS")
52+
SUPPORTED_DBS = []
53+
else:
54+
SUPPORTED_DBS = ["postgresql"] # TODO: Add sqlite and mysql.
55+
56+
57+
@pytest.fixture(params=SUPPORTED_DBS)
58+
def engine(request) -> Engine:
59+
if request.param == "postgresql":
60+
url = request.getfixturevalue("postgresql").url()
61+
else:
62+
raise ValueError("Unsupported database: %s", request.param)
63+
kwargs = {}
64+
if not SQLA2:
65+
kwargs["future"] = True
66+
engine = sqlalchemy.create_engine(url, **kwargs)
67+
return engine
68+
69+
70+
@pytest.fixture
71+
def sessionmaker(engine) -> orm.sessionmaker:
72+
return orm.sessionmaker(autocommit=False, autoflush=False, bind=engine)
73+
74+
75+
@pytest.fixture
76+
def Base():
77+
return orm.declarative_base()

0 commit comments

Comments
 (0)